bool IsRunCompleted(WorkflowRun run) { return(run.WorkflowRunStatus_Enum != WorkflowRunState_Enumeration.WorkflowRunPaused && run.WorkflowRunStatus_Enum != WorkflowRunState_Enumeration.WorkflowRunSuspended && run.WorkflowRunStatus_Enum != WorkflowRunState_Enumeration.WorkflowRunStarted && run.WorkflowRunStatus_Enum != WorkflowRunState_Enumeration.WorkflowRunQueued); }
/// <summary> /// Get the request context this workflow will be running as, taking into account triggering user and owner. /// </summary> private RequestContextData GetEffectiveSecurityContext(WorkflowRun run, WorkflowMetadata metaData) { var effectiveUser = GetEffectiveUser(run, metaData); var triggeringUser = GetTriggeringUser(run); // Error! The caller will deal with the missing info. We can't throw becasue RunState is needed for the error reporting if (effectiveUser == null) { return(null); } if (metaData.WfRunAsOwner && metaData.WfSecurityOwner == null) { return(null); } var identityInfo = new IdentityInfo(effectiveUser.Id, effectiveUser.Name); var context = RequestContext.GetContext(); var effectiveSecurityContext = new RequestContextData(context); effectiveSecurityContext.Identity = identityInfo; // If we are running as someone other than the triggerer, set the secondary identity to the triggerer. // NOTE: This could potentially cause a problem in the case where a wf triggering another wf scenario. // It's possible that the user will see stale data. The risk should be quite low. if (triggeringUser != null && triggeringUser.Id != effectiveUser.Id) { effectiveSecurityContext.SecondaryIdentity = new IdentityInfo(triggeringUser.Id, triggeringUser.Name); } return(effectiveSecurityContext); }
private void ValidateWorkflowRun1(WorkflowRun workflowRun) { Assert.Equal("/subscriptions/66666666-6666-6666-6666-666666666666/resourceGroups/rgName/providers/Microsoft.Logic/workflows/wfName/runs/run87646872399558047", workflowRun.Id); Assert.Equal("run87646872399558047", workflowRun.Name); Assert.Equal("Microsoft.Logic/workflows/runs", workflowRun.Type); Assert.Equal(2015, workflowRun.StartTime.Value.Year); Assert.Equal(06, workflowRun.StartTime.Value.Month); Assert.Equal(23, workflowRun.StartTime.Value.Day); Assert.Equal(21, workflowRun.StartTime.Value.Hour); Assert.Equal(47, workflowRun.StartTime.Value.Minute); Assert.Equal(00, workflowRun.StartTime.Value.Second); Assert.Equal(00, workflowRun.StartTime.Value.Millisecond); Assert.Equal(DateTimeKind.Utc, workflowRun.StartTime.Value.Kind); Assert.Equal(2015, workflowRun.EndTime.Value.Year); Assert.Equal(06, workflowRun.EndTime.Value.Month); Assert.Equal(23, workflowRun.EndTime.Value.Day); Assert.Equal(21, workflowRun.EndTime.Value.Hour); Assert.Equal(47, workflowRun.EndTime.Value.Minute); Assert.Equal(30, workflowRun.EndTime.Value.Second); Assert.Equal(130, workflowRun.EndTime.Value.Millisecond); Assert.Equal(DateTimeKind.Utc, workflowRun.EndTime.Value.Kind); Assert.Equal(WorkflowStatus.Succeeded, workflowRun.Status.Value); Assert.Equal("a04da054-a1ae-409d-80ff-b09febefc357", workflowRun.CorrelationId); Assert.Equal("/subscriptions/66666666-6666-6666-6666-666666666666/resourceGroups/rgName/providers/Microsoft.Logic/workflows/wfName/versions/ver87717906782501130", workflowRun.Workflow.Id); Assert.Equal("Microsoft.Logic/workflows/versions", workflowRun.Workflow.Type); Assert.Equal("wfName/ver87717906782501130", workflowRun.Workflow.Name); Assert.Equal("6A65DA9E-CFF8-4D3E-B5FB-691739C7AD61", workflowRun.Trigger.Name); Assert.Equal(0, workflowRun.Outputs.Count); }
private string ResumeWorkflowAsync_old(WorkflowRun workflowRun, IWorkflowEvent resumeEvent) { Action runAction = () => { using (new WorkflowRunContext { RunTriggersInCurrentThread = true }) { ResumeWorkflow(workflowRun, resumeEvent); } }; Factory.WorkflowRunTaskManager.RegisterStart(workflowRun.TaskId); HandleDiagnostics(workflowRun, "Queued"); if (WorkflowRunContext.Current.RunTriggersInCurrentThread) { // Ignore the Asyn and process it syncronously runAction(); } else // Async { WorkflowRunContext.Current.QueueAction(() => { runAction(); }); } return(workflowRun.TaskId); }
public void GetWorkflowDescriptionTest_Empty() { var run = new WorkflowRun(); var runState = new TestRunState(new WorkflowMetadata(), run); Assert.That(runState.GetSafeWorkflowDescription(), Is.StringContaining(run.Id.ToString())); }
public void TestTimeout( ) { var dummyTimeoutHelper = new DummyTimeoutHelper(); using (var scope = Factory.Current.BeginLifetimeScope(builder => { builder.Register(ctx => dummyTimeoutHelper).As <ITimeoutActivityHelper>(); })) using (Factory.SetCurrentScope(scope)) { Workflow displayFormWf = CreateDisplayFormTestWf(null, null, null, 5); WorkflowRun run = RunWorkflow(displayFormWf); dummyTimeoutHelper.Timeout(); run = Entity.Get <WorkflowRun>(run); Assert.AreEqual(WorkflowRunState_Enumeration.WorkflowRunCompleted, run.WorkflowRunStatus_Enum); var exitPoint = run.GetExitPoint(); Assert.AreEqual("Time-out", exitPoint.Name, "Workflow exited at a time-out"); // Need to figure out how to test the exit point. } }
public string ResumeWorkflowAsync_new(WorkflowRun workflowRun, IWorkflowEvent resumeEvent) { Factory.WorkflowRunTaskManager.RegisterStart(workflowRun.TaskId); bool runInForeground = WorkflowRunContext.Current.RunTriggersInCurrentThread; var queueEvent = resumeEvent as IWorkflowQueuedEvent; if (queueEvent == null) { EventLog.Application.WriteError("Attempted to queue a resume task that cannot be queued, running it on the foreground thread instead. EventType: {resumeEvent.GetType()}"); runInForeground = true; } if (runInForeground) { ResumeWorkflow(workflowRun, resumeEvent); } else { var task = ResumeWorkflowHandler.CreateBackgroundTask(workflowRun, queueEvent); Factory.BackgroundTaskManager.EnqueueTask(task); HandleDiagnostics(workflowRun, "Queued"); } return(workflowRun.TaskId); }
public RunState(WorkflowMetadata metaData, WorkflowRun workflowRun, RequestContextData effectiveSecurityContext) : base(metaData, workflowRun, effectiveSecurityContext) { ownerAccountRuntimeArgName = Entity.GetName(new EntityRef("workflowOwnerAccount").Id); triggeringUserRuntimeArgName = Entity.GetName(new EntityRef("triggeringUserAccount").Id); triggeringPersonRuntimeArgName = Entity.GetName(new EntityRef("triggeringPerson").Id); }
void ProcessResult(IRunState context, WorkflowRun run) { if (run.WorkflowRunStatus_Enum != WorkflowRunState_Enumeration.WorkflowRunCompleted) { throw new InnerWorkflowFailedException(string.Format("Inner workflow '{0}' failed", run.WorkflowBeingRun.Name)); } var proxyExitPoint = run.GetExitPoint(); var matchingExitPoint = context.Metadata.GetExitpointsForActivity(ActivityInstance.Id).SingleOrDefault(ep => ep.Name == proxyExitPoint.Name); if (matchingExitPoint == null) { throw new WorkflowRunException("Workflow proxy returned using an exit point that doesn't match anything in the parent"); } context.ExitPointId = matchingExitPoint; var outputs = run.GetOutput(); var outArgs = ActivityInstance.GetOutputArguments(); // copy the values from the results into the arguments witht eh same name foreach (var arg in outArgs) { var name = arg.Name; object value = null; if (outputs.TryGetValue(name, out value)) { context.SetArgValue(ActivityInstance, arg, value); } } }
private void ValidateRun1(WorkflowRun run) { Assert.True(this.ValidateIdFormat(id: run.Id, entityTypeName: "workflows", entitySubtypeName: "runs")); Assert.Equal("08587692861242198730", run.Name); Assert.Equal("Microsoft.Logic/workflows/runs", run.Type); Assert.Equal(2015, run.StartTime.Value.Year); Assert.Equal(06, run.StartTime.Value.Month); Assert.Equal(23, run.StartTime.Value.Day); Assert.Equal(21, run.StartTime.Value.Hour); Assert.Equal(47, run.StartTime.Value.Minute); Assert.Equal(00, run.StartTime.Value.Second); Assert.Equal(DateTimeKind.Utc, run.StartTime.Value.Kind); Assert.Equal(2015, run.EndTime.Value.Year); Assert.Equal(06, run.EndTime.Value.Month); Assert.Equal(23, run.EndTime.Value.Day); Assert.Equal(21, run.EndTime.Value.Hour); Assert.Equal(47, run.EndTime.Value.Minute); Assert.Equal(30, run.EndTime.Value.Second); Assert.Equal(DateTimeKind.Utc, run.EndTime.Value.Kind); Assert.Equal(WorkflowStatus.Succeeded, run.Status); Assert.Equal("4701405c-1543-4127-adb9-a396717a4ffb", run.CorrelationId); Assert.Equal("/subscriptions/66666666-6666-6666-6666-666666666666/resourceGroups/rgName/providers/Microsoft.Logic/workflows/wfName/versions/08587717906782501130", run.Workflow.Id); Assert.Equal("wfName/08587717906782501130", run.Workflow.Name); Assert.Equal("Microsoft.Logic/workflows/versions", run.Workflow.Type); Assert.Equal("https://someurl.blob.core.windows.net/someurl", run.Trigger.OutputsLink.Uri); Assert.Equal("\"0x8D262D79DE77699\"", run.Trigger.OutputsLink.ContentVersion); Assert.Equal(2080, run.Trigger.OutputsLink.ContentSize); Assert.Equal("md5", run.Trigger.OutputsLink.ContentHash.Algorithm); Assert.Equal("4Ikl8rJkAg3bN8C9I6nKFQ==", run.Trigger.OutputsLink.ContentHash.Value); }
public void SuspendRestore() { using (new SecurityBypassContext()) { var handler = new ResumeWorkflowHandler(); var run = new WorkflowRun() { WorkflowRunStatus_Enum = WorkflowRunState_Enumeration.WorkflowRunSuspended }; run.Save(); var task = ResumeWorkflowHandler.CreateBackgroundTask(run, new WorkflowRestoreEvent()); var taskEntity = handler.CreateSuspendedTask(task).As <SuspendedRun>(); taskEntity.Save(); taskEntity.Should().NotBeNull(); taskEntity.SrRun.Should().NotBeNull(); taskEntity.SrRun.Id.Should().Be(run.Id); var bgTasks = handler.RestoreSuspendedTasks(); bgTasks.Should().HaveCount(1); var runParam = bgTasks.First().GetData <ResumeWorkflowParams>(); runParam.WorkflowRunId.ShouldBeEquivalentTo(run.Id); Assert.That(runParam.WorkflowRunId, Is.EqualTo(run.Id)); } }
public void ScheduleTimeout(IResumableActivity activityInstance, WorkflowRun workflowRun, decimal timeoutMinutes) { timeoutAction = () => { var workflowEvent = new TimeoutEvent(); WorkflowRunner.Instance.ResumeWorkflow(workflowRun, workflowEvent); }; }
private void cancel_Click(object sender, EventArgs e) { if (guidBox.Text != "") { loadBTN_Click(sender, e); } workflowRun?.Cancel(); workflowRun = null; }
public static TestRunState CreateDummyState(Workflow workflow) { var workflowRun = new WorkflowRun() { WorkflowBeingRun = workflow }; return(new TestRunState(new WorkflowMetadata(workflow), workflowRun)); }
private void loadBTN_Click(object sender, EventArgs e) { if (guidBox.Text == "") { return; } workflowRun?.Dispose(); workflowRun = new WorkflowRun(guidBox.Text, UpdateControls); }
private UserAccount GetEffectiveUser(WorkflowRun run, WorkflowMetadata metaData) { if (metaData != null && metaData.WfRunAsOwner) { return(metaData.WfSecurityOwner); } return(GetTriggeringUser(run)); }
Notification RunNotify(IEntity person, TwilioNotifier notifier, bool waitForReplies, IEntity linkTo = null, string replyWorkflowString = null, Workflow replyWorkflow = null) { var inputs = new Dictionary <string, object> { { "People", person.ToEnumerable() }, { "LinkToRecord", linkTo }, }; var wf = new Workflow { Name = "RunNotify " + DateTime.UtcNow.ToString() }; wf .AddDefaultExitPoint() .AddInput <ResourceListArgument>("People", Person.Person_Type) .AddInput <ResourceArgument>("LinkToRecord", UserResource.UserResource_Type) .AddOutput <ResourceArgument>("NotificationRecord", Notification.Notification_Type) .AddNotify( "Notify", "People", "'Test'", waitForReplies, linkToRecordExpression: "LinkToRecord", replyMap: replyWorkflowString == null ? null : new Dictionary <string, Workflow> { { replyWorkflowString, replyWorkflow } }) .AddAssignToVar("Assign", "[Notify_Notification Record]", "NotificationRecord"); wf.Save(); ToDelete.Add(wf.Id); using (var scope = Factory.Current.BeginLifetimeScope(builder => { builder.Register(c => new TenantSmsNotifier(notifier.Id)).As <INotifier>(); })) using (Factory.SetCurrentScope(scope)) { WorkflowRun run = null; using (new TestWfRunContext()) { run = RunWorkflow(wf, inputs); run.Save(); } Thread.Sleep(1000); Assert.That(run.WorkflowRunStatus_Enum, Is.EqualTo(WorkflowRunState_Enumeration.WorkflowRunCompleted)); var results = run.GetOutput(); Assert.That(results.Keys, Has.Member("NotificationRecord")); var entity = (IEntity)results["NotificationRecord"]; return(entity.As <Notification>()); } }
bool ShouldDelete(WorkflowRun run, DateTime deleteOlderThan) { DateTime runCompletedAt = run.RunCompletedAt ?? DateTime.MinValue; return (runCompletedAt < deleteOlderThan && ( run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunFailed || run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunCompleted )); }
public void CancelTimeout(WorkflowRun workflowRun) { try { SchedulingHelper.Instance.DeleteJob(GetJobId(workflowRun)); } catch (Exception ex) { EventLog.Application.WriteError($"Unable to cancel timeout: Job may not have been created. RunId: {workflowRun.Id} Exception: {ex}"); } }
/// <summary> /// Resume a workflow. The workflow will run async unless it is in a RunTriggersInCurrentThread WorkflowContext. /// </summary> /// <param name="workflowRun"></param> /// <param name="resumeEvent"></param> public string ResumeWorkflowAsync(WorkflowRun workflowRun, IWorkflowEvent resumeEvent) { if (Factory.FeatureSwitch.Get("longRunningWorkflow")) { return(ResumeWorkflowAsync_new(workflowRun, resumeEvent)); } else { return(ResumeWorkflowAsync_old(workflowRun, resumeEvent)); } }
private static WorkflowRun CreateWorkflowRun(WorkflowRunTrigger trigger) { var correlation = new Correlation(BogusGenerator.Random.String().OrNull(BogusGenerator)).OrNull(BogusGenerator); var workflowRun = new WorkflowRun( name: BogusGenerator.Internet.DomainWord(), startTime: BogusGenerator.Date.Recent(), status: GenerateStatus(), error: BogusGenerator.Random.Bytes(10).OrNull(BogusGenerator), correlation: correlation, trigger: trigger); return(workflowRun); }
public static BackgroundTask CreateBackgroundTask(WorkflowRun run, IWorkflowQueuedEvent resumeEvent) { if (resumeEvent == null) { throw new ArgumentNullException(nameof(resumeEvent)); } var runParams = new ResumeWorkflowParams { WorkflowRunId = run.Id }; return(BackgroundTask.Create(HandlerKey, runParams)); }
public RunStateBase(WorkflowMetadata metaData, WorkflowRun _workflowRun, RequestContextData effectiveSecurityContext) : this(metaData) { WorkflowInvoker = new WorkflowInvoker(); WorkflowRun = _workflowRun; StepsTakenInSession = 0; EffectiveSecurityContext = effectiveSecurityContext; ExitPointId = _workflowRun.WorkflowRunExitPoint; HasTimeout = _workflowRun.HasTimeout ?? false; PendingActivity = _workflowRun.PendingActivity; RunStatus = _workflowRun.WorkflowRunStatus_Enum; CompletedAt = _workflowRun.RunCompletedAt; }
/// <summary> /// Send the notifications on a background thread. /// </summary> void SendMessagesInBackground(IRunState context, long notificationId, List <long> userIds, bool waitForReplies) { context.SetPostRunAction(() => { var runId = context.WorkflowRunId; WorkflowRunContext.Current.QueueAction(() => SecurityBypassContext.Elevate(() => { var workflowRunner = Factory.Current.Resolve <IWorkflowRunner>(); WorkflowRun run = Entity.Get <WorkflowRun>(runId);; try { var notification = Entity.Get <Notification>(notificationId); var users = Entity.Get(userIds); Factory.Current.Resolve <INotifier>().Send(notification, users, true); var sends = notification.SendRecords; var sentWithoutError = sends.Where(r => r.SrErrorMessage == null); // update the notification bool resume = true; if (waitForReplies) { notification = notification.AsWritable <Notification>(); notification.NPendingRun = run; notification.Save(); resume = notification.Complete(); // Just in case all the replies were completed while we were sending. } if (resume && run != null) { workflowRunner.ResumeWorkflow(run, new NotifyResumeEvent()); } } catch { if (run != null) { workflowRunner.ResumeWorkflow(run, new NotifyResumeFailedEvent()); } throw; } })); }); }
/// <summary> /// Handles the diagnostics. /// </summary> /// <param name="workflowRun">The workflow run.</param> /// <param name="status">The status.</param> private void HandleDiagnostics(WorkflowRun workflowRun, string status) { if (DiagnosticsEnabled) { if (DateTime.UtcNow - DiagnosticsLastUpdated > TimeSpan.FromMinutes(5)) { DiagnosticsEnabled = false; } else { SendDiagnostics(workflowRun, status); } } }
public void GetWorkflowDescriptionTest_MissingActivity() { var workflow = new Workflow() { Name = "wfName" }; var workflowRun = new WorkflowRun() { WorkflowBeingRun = workflow }; var runState = new TestRunState(new WorkflowMetadata(workflow), workflowRun); Assert.That(runState.GetSafeWorkflowDescription(), Is.StringContaining(workflowRun.Id.ToString())); }
public void DeferSave(WorkflowRun run) { if (this == _rootContext) { throw new ArgumentException("run"); } if (HandleDeferred || _parentContext == null) { _deferredRuns.Enqueue(run); } else { _parentContext.DeferSave(run); } }
private static UserAccount EnsureTriggeringUser(WorkflowRun workflowRun) { if (!workflowRun.IsTemporaryId || workflowRun.TriggeringUser != null) { return(null); } var deferredRun = workflowRun as WorkflowRunDeferred; if (deferredRun != null && deferredRun.TriggeringUserId > 0) { return(deferredRun.GetTriggeringUser()); } return(null); }
/// <summary> /// Create a run state /// </summary> /// <returns>A run state - note the security information will be missing if it has been set incorrectly in the workflow</returns> public IRunState CreateRunState(WorkflowMetadata metaData, WorkflowRun workflowRun) { using (Profiler.Measure("DefaultRunStateFactory.CreateRunState")) { var run = workflowRun; if (!run.IsTemporaryId) { run = run.AsWritable <WorkflowRun>(); } //var effectiveUser = GetEffectiveUser(run, metaData); var effectiveSecurityContext = GetEffectiveSecurityContext(run, metaData); return(new RunState(metaData, run, effectiveSecurityContext)); } }
private UserAccount GetTriggeringUser(WorkflowRun run) { if (run != null && run.TriggeringUser == null) { var deferredRun = run as WorkflowRunDeferred; if (deferredRun != null) { return(deferredRun.GetTriggeringUser()); } } if (run != null) { return(run.TriggeringUser); } return(null); }