public WorkflowTests() { _decisionTask = Substitute.For <DecisionTask>(); _decisionTask.WorkflowType = new WorkflowType { Name = "TestWorkflow", Version = "TestVersion" }; _decisionTask.WorkflowExecution = new WorkflowExecution { RunId = "TestRunId", WorkflowId = "" }; var results = new ConcurrentDictionary <int, string>(); results.AddOrUpdate(1, "TestResult", (index, value) => $"{value} - {index}"); _executionContext = WorkflowStateSerializer.Serialize(new WorkflowState() { CurrentStepNumber = 1, NumberOfActions = 1, Results = results }); _pollforDecisionTaskRequest = Substitute.For <PollForDecisionTaskRequest>(); _pollforDecisionTaskRequest.Domain = "TestDomain"; _amazonSwf = Substitute.For <IAmazonSimpleWorkflow>(); _workflow = Substitute.For <WorkflowBase>("domain", _defaultWorkflowName, "version", "taskList", _amazonSwf); }
public MakeDecisionTests() { _decisionTask = Substitute.For <DecisionTask>(); _decisionTask.WorkflowType = new WorkflowType { Name = "TestWorkflow", Version = "TestVersion" }; _decisionTask.WorkflowExecution = new WorkflowExecution { RunId = "TestRunId", WorkflowId = "" }; var results = new ConcurrentDictionary <int, string>(); results.AddOrUpdate(1, "TestResult", (key, value) => $"{key} - {value}"); WorkflowStateSerializer.Serialize(new WorkflowState() { CurrentStepNumber = 1, NumberOfActions = 1, Results = results }); _pollforDecisionTaskRequest = Substitute.For <PollForDecisionTaskRequest>(); _pollforDecisionTaskRequest.Domain = "TestDomain"; _amazonSwf = Substitute.For <IAmazonSimpleWorkflow>(); _workflowBase = Substitute.For <WorkflowBase>("domain", "workflowName", "version", "taskList", _amazonSwf); var describeWorkflowExecutionRequest = Substitute.For <DescribeWorkflowExecutionRequest>(); describeWorkflowExecutionRequest.Domain = _pollforDecisionTaskRequest.Domain; describeWorkflowExecutionRequest.Execution = _decisionTask.WorkflowExecution; }
/// <summary> /// Initialize constructor parameters /// </summary> public WorkflowEventsProcessorConstructorTest() { _decisionTask = Substitute.For <DecisionTask>(); _pollforDecisionTaskRequest = Substitute.For <PollForDecisionTaskRequest>(); _amazonSwf = Substitute.For <IAmazonSimpleWorkflow>(); _workflowBase = Substitute.For <WorkflowBase>("domain", "workflowName", "version", "taskList", _amazonSwf); }
ActivityTask startActivity(string runId) { var pollDeciderRequest = new PollForDecisionTaskRequest() { Domain = DOMAIN, TaskList = TASKLIST, Identity = "testdecider" }; var pollDeciderResponse = Client.PollForDecisionTask(pollDeciderRequest); var task = pollDeciderResponse.DecisionTask; var respondRequest = new RespondDecisionTaskCompletedRequest() { TaskToken = task.TaskToken, Decisions = new List <Decision>() { new Decision() { DecisionType = "ScheduleActivityTask", ScheduleActivityTaskDecisionAttributes = new ScheduleActivityTaskDecisionAttributes() { ActivityType = ACTIVITY_TYPE, ActivityId = DateTime.Now.Ticks.ToString(), TaskList = TASKLIST } } } }; Client.RespondDecisionTaskCompleted(respondRequest); return(pollActivity()); }
public WorkflowEventsIteratorTest() { _decisionTask = Substitute.For <DecisionTask>(); _pollforDecisionTaskRequest = Substitute.For <PollForDecisionTaskRequest>(); _amazonSwf = Substitute.For <IAmazonSimpleWorkflow>(); var workflowExecutionStartedEventAttributes = Substitute.For <WorkflowExecutionStartedEventAttributes>(); workflowExecutionStartedEventAttributes.Input = "Input"; var workflowExecutionCompletedEventAttributes = Substitute.For <WorkflowExecutionCompletedEventAttributes>(); workflowExecutionCompletedEventAttributes.Result = "Output"; var historyEvent1 = Substitute.For <HistoryEvent>(); historyEvent1.EventId = event1ID; historyEvent1.WorkflowExecutionStartedEventAttributes = workflowExecutionStartedEventAttributes; historyEvent1.EventType = EventType.WorkflowExecutionStarted; var historyEvent2 = Substitute.For <HistoryEvent>(); historyEvent2.EventId = event2ID; historyEvent2.WorkflowExecutionCompletedEventAttributes = Substitute.For <WorkflowExecutionCompletedEventAttributes>(); historyEvent2.EventType = EventType.ChildWorkflowExecutionCompleted; _decisionTask.Events = new List <HistoryEvent> { historyEvent1, historyEvent2 }; }
public override void Invoke(AWSCredentials creds, RegionEndpoint region, int maxItems) { AmazonSimpleWorkflowConfig config = new AmazonSimpleWorkflowConfig(); config.RegionEndpoint = region; ConfigureClient(config); AmazonSimpleWorkflowClient client = new AmazonSimpleWorkflowClient(creds, config); DecisionTask resp = new DecisionTask(); do { PollForDecisionTaskRequest req = new PollForDecisionTaskRequest { NextPageToken = resp.NextPageToken , MaximumPageSize = maxItems }; resp = client.PollForDecisionTask(req); CheckError(resp.HttpStatusCode, "200"); foreach (var obj in resp.Events) { AddObject(obj); } }while (!string.IsNullOrEmpty(resp.NextPageToken)); }
/// <summary> /// Retrieves the next page of history from /// </summary> /// <returns>The next page of history events.</returns> private List <HistoryEvent> GetNextPage() { var request = new PollForDecisionTaskRequest { Domain = _request.Domain, NextPageToken = _lastResponse.NextPageToken, TaskList = _request.TaskList, MaximumPageSize = _request.MaximumPageSize }; const int retryCount = 10; int currentTry = 1; bool pollFailed; do { pollFailed = false; try { _lastResponse = _swfClient.PollForDecisionTaskAsync(request).Result.DecisionTask; } catch (Exception ex) { Console.Error.WriteLine("Poll request failed with exception: " + ex); pollFailed = true; } currentTry += 1; } while (pollFailed && currentTry <= retryCount); return(_lastResponse.Events); }
/// <summary> /// Constructor for the workflow event processor. /// </summary> /// <param name="decisionTask">Decision task passed in from SWF as decision task response.</param> /// <param name="workflow">IEnumerable set of string for workflow name and Type for workflow class.</param> /// <param name="request">The request used to retrieve <paramref name="decisionTask"/>, which will be used to retrieve subsequent history event pages.</param> /// <param name="swfClient">An SWF client.</param> public WorkflowEventsProcessor(DecisionTask decisionTask, WorkflowBase workflow, PollForDecisionTaskRequest request, IAmazonSimpleWorkflow swfClient) { if (decisionTask == null) { throw new ArgumentNullException(nameof(decisionTask)); } if (workflow == null) { throw new ArgumentNullException(nameof(workflow)); } if (request == null) { throw new ArgumentNullException(nameof(request)); } if (swfClient == null) { throw new ArgumentNullException(nameof(swfClient)); } // Store the decision task and allocate a new decision context and event dictionary which // we will use as we walk through the chain of events _decisionTask = decisionTask; _request = request; _decisionContext = new WorkflowDecisionContext(); _swfClient = swfClient; _workflow = workflow; // Set up our events data structure. Events = new WorkflowEventsIterator(ref decisionTask, _request, _swfClient); }
/// <summary> /// Initializes a new instance of the <see cref="WorkflowEventsIterator"/> class. /// </summary> /// <param name="decisionTask">Reference to the decision task passed in from </param> /// <param name="request">The request used to retrieve <paramref name="decisionTask"/>, which will be used to retrieve subsequent history event pages.</param> /// <param name="swfClient">An SWF client.</param> public WorkflowEventsIterator(ref DecisionTask decisionTask, PollForDecisionTaskRequest request, IAmazonSimpleWorkflow swfClient) { _lastResponse = decisionTask; _request = request; _swfClient = swfClient; _historyEvents = decisionTask.Events; }
public WorkflowEventsProcessorTests() { _decisionTask = Substitute.For <DecisionTask>(); _decisionTask.WorkflowType = new WorkflowType { Name = "TestWorkflow", Version = "TestVersion" }; _decisionTask.WorkflowExecution = new WorkflowExecution { RunId = "TestRunId", WorkflowId = "" }; var results = new ConcurrentDictionary <int, string>(); results.AddOrUpdate(1, "TestResult", UpdateValueFactory); _executionContext = WorkflowStateSerializer.Serialize(new WorkflowState() { CurrentStepNumber = 1, NumberOfActions = 1, Results = results }); _pollforDecisionTaskRequest = Substitute.For <PollForDecisionTaskRequest>(); _pollforDecisionTaskRequest.Domain = "TestDomain"; _amazonSwf = Substitute.For <IAmazonSimpleWorkflow>(); _workflowBase = Substitute.For <WorkflowBase>("domain", "workflowName", "version", "taskList", _amazonSwf); var describeWorkflowExecutionRequest = Substitute.For <DescribeWorkflowExecutionRequest>(); describeWorkflowExecutionRequest.Domain = _pollforDecisionTaskRequest.Domain; describeWorkflowExecutionRequest.Execution = _decisionTask.WorkflowExecution; //_amazonSwf.DescribeWorkflowExecution(describeWorkflowExecutionRequest) // .ReturnsForAnyArgs( // info => // new DescribeWorkflowExecutionResponse() // { // HttpStatusCode = HttpStatusCode.OK, // WorkflowExecutionDetail = new WorkflowExecutionDetail() {LatestExecutionContext = _executionContext} // }); SDK.Workflow.WorkflowEventsProcessor processor = Substitute.For <SDK.Workflow.WorkflowEventsProcessor>(_decisionTask, _workflowBase, _pollforDecisionTaskRequest, _amazonSwf); processor.GetLastExecContext().ReturnsForAnyArgs(info => WorkflowStateSerializer.Deserialize(_executionContext)); //_workflowEventsIterator = Substitute.For<WorkflowEventsIterator>(_decisionTask, _pollforDecisionTaskRequest, // _amazonSwf); }
DecisionTask Poll() { Logger.LogMessage("Polling for Decision task ..."); PollForDecisionTaskRequest request = new PollForDecisionTaskRequest() { Domain = Constants.SWF_DOMAIN, TaskList = new TaskList() { Name = Constants.SWF_DECIDER_TASKLIST } }; PollForDecisionTaskResponse response = _swfClient.PollForDecisionTaskAsync(request).Result; return(response.DecisionTask); }
private async Task <DecisionTask> Poll() { this.EmrJobLogger.PrintInfo(SwfResources.Info_PollingDecisionTask); PollForDecisionTaskRequest request = new PollForDecisionTaskRequest() { Domain = this.SwfConfiguration.DomainName, TaskList = new TaskList() { Name = this.SwfConfiguration.DecisionTasksList } }; PollForDecisionTaskResponse response = await this.SwfClient.PollForDecisionTaskAsync(request); return(response.DecisionTask); }
/// <summary> /// Constructor for the workflow event processor. /// </summary> /// <param name="decisionTask">Decision task passed in from SWF as decision task response.</param> /// <param name="workflows">IEnumerable set of string for workflow name and Type for workflow class.</param> /// <param name="request">The request used to retrieve <paramref name="decisionTask"/>, which will be used to retrieve subsequent history event pages.</param> /// <param name="swfClient">An SWF client.</param> public WorkflowEventsProcessor(DecisionTask decisionTask, IEnumerable <KeyValuePair <string, Type> > workflows, PollForDecisionTaskRequest request, IAmazonSimpleWorkflow swfClient) { // Decision task can't be null. if (decisionTask == null) { throw new ArgumentNullException("decisionTask"); } if (request == null) { throw new ArgumentNullException("request"); } // Store the decision task and allocate a new decision context and event dictionary which // we will use as we walk through the chain of events _decisionTask = decisionTask; _request = request; _decisionContext = new WorkflowDecisionContext(); _swfClient = swfClient; // Set up our events data structure _events = new WorkflowEventsIterator(ref decisionTask, _request, _swfClient); _workflows = (Dictionary <string, Type>)workflows; }
public void Decider() { int activityCount = 0; while (true) { Console.WriteLine("Decider: Polling for decision task ..."); PollForDecisionTaskRequest request = new PollForDecisionTaskRequest() { Domain = domainName, TaskList = new TaskList() { Name = deciderPollingKey } }; PollForDecisionTaskResponse response = swfClient.PollForDecisionTaskAsync(request).Result; if (response.DecisionTask.TaskToken == null) { Console.WriteLine("Decider: NULL"); continue; } int completedActivityTaskCount = 0, totalActivityTaskCount = 0; foreach (HistoryEvent e in response.DecisionTask.Events) { Console.WriteLine("Decider: EventType - " + e.EventType + ", EventId - " + e.EventId); if (e.EventType == "ActivityTaskCompleted") { completedActivityTaskCount++; } if (e.EventType.Value.StartsWith("Activity")) { totalActivityTaskCount++; } } Console.WriteLine(".... completedCount=" + completedActivityTaskCount); List <Decision> decisions = new List <Decision>(); if (totalActivityTaskCount == 0) { ScheduleActivity("Activity1", decisions); activityCount = 4; } else if (completedActivityTaskCount == activityCount) { Decision decision = new Decision() { DecisionType = DecisionType.CompleteWorkflowExecution, CompleteWorkflowExecutionDecisionAttributes = new CompleteWorkflowExecutionDecisionAttributes { Result = "{\"Result\":\"WF Complete!\"}" } }; decisions.Add(decision); Console.WriteLine("Worflow Complete"); } RespondDecisionTaskCompletedRequest respondDecisionTaskCompletedRequest = new RespondDecisionTaskCompletedRequest() { Decisions = decisions, TaskToken = response.DecisionTask.TaskToken }; swfClient.RespondDecisionTaskCompletedAsync(respondDecisionTaskCompletedRequest); } }
protected override async Task <Workflow> GetCurrentContext() { Workflow workflow = null; IList <Activity> activityList = new List <Activity>(); PollForDecisionTaskResponse decisionTaskResponse = null; List <HistoryEvent> historyEvents = new List <HistoryEvent>(); string taskToken = null; string nextPageToken = null; do { var decisionTaskRequest = new PollForDecisionTaskRequest { Domain = Constants.LAMBDA_BIZ_DOMAIN, Identity = Guid.NewGuid().ToString(), TaskList = new TaskList { Name = Constants.LAMBDA_BIZ_TASK_LIST + _orchestrationId }, NextPageToken = nextPageToken }; decisionTaskResponse = await _amazonSimpleWorkflowClient.PollForDecisionTaskAsync(decisionTaskRequest); taskToken = decisionTaskResponse.DecisionTask.TaskToken; if (!string.IsNullOrEmpty(taskToken)) { var decisionTask = decisionTaskResponse.DecisionTask; foreach (HistoryEvent historyEvent in decisionTask.Events) { historyEvents.Add(historyEvent); } } }while (!string.IsNullOrEmpty(nextPageToken = decisionTaskResponse.DecisionTask.NextPageToken)); if (historyEvents.Count > 0) { if (workflow == null) { workflow = new Workflow(); workflow.ReferenceToken = taskToken; if (_store != null) { if (!await _store.StoreExistsAsync()) { await _store.CreateStoreAsync(); } } } foreach (HistoryEvent historyEvent in historyEvents) { if (historyEvent.EventType == EventType.WorkflowExecutionSignaled) { var activity = FindActivity(Model.ActivityType.Event, historyEvent.WorkflowExecutionSignaledEventAttributes.SignalName, activityList); if (activity == null) { activity = new Activity { Result = historyEvent.WorkflowExecutionSignaledEventAttributes.Input, Status = Status.SUCCEEDED, ActivityType = Model.ActivityType.Event, Name = historyEvent.WorkflowExecutionSignaledEventAttributes.SignalName, ScheduledId = historyEvent.WorkflowExecutionSignaledEventAttributes.SignalName, UniqueId = historyEvent.WorkflowExecutionSignaledEventAttributes.SignalName, SucceededDateTime = historyEvent.EventTimestamp }; activityList.Add(activity); } } if (historyEvent.EventType == EventType.WorkflowExecutionStarted) { workflow.Status = Status.STARTED; workflow.OrchestrationId = historyEvent.WorkflowExecutionStartedEventAttributes.TaskList.Name.Replace(Constants.LAMBDA_BIZ_TASK_LIST, string.Empty); workflow.StartedDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.WorkflowExecutionFailed) { workflow.Status = Status.FAILED; workflow.FailedDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.WorkflowExecutionCompleted) { workflow.Status = Status.SUCCEEDED; workflow.SucceededDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.LambdaFunctionScheduled) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.LambdaFunctionScheduledEventAttributes.Id.ToString(), activityList); if (activity == null) { activity = new Activity { ActivityType = Model.ActivityType.Task, Name = historyEvent.LambdaFunctionScheduledEventAttributes.Name, ScheduledId = historyEvent.EventId.ToString(), UniqueId = historyEvent.LambdaFunctionScheduledEventAttributes.Control, Status = Status.SCHEDULED, ScheduledDateTime = historyEvent.EventTimestamp }; activityList.Add(activity); } } if (historyEvent.EventType == EventType.StartLambdaFunctionFailed) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.StartLambdaFunctionFailedEventAttributes.ScheduledEventId.ToString(), activityList); activity.Result = historyEvent.StartLambdaFunctionFailedEventAttributes.Message; activity.FailureDetails = historyEvent.StartLambdaFunctionFailedEventAttributes.Cause; activity.Status = Status.FAILED; activity.FailedDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.LambdaFunctionStarted) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.LambdaFunctionStartedEventAttributes.ScheduledEventId.ToString(), activityList); activity.Status = Status.STARTED; activity.StartedDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.LambdaFunctionCompleted) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.LambdaFunctionCompletedEventAttributes.ScheduledEventId.ToString(), activityList); activity.Result = historyEvent.LambdaFunctionCompletedEventAttributes.Result; activity.Status = Status.SUCCEEDED; activity.SucceededDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.LambdaFunctionFailed) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.LambdaFunctionFailedEventAttributes.ScheduledEventId.ToString(), activityList); activity.Result = historyEvent.LambdaFunctionFailedEventAttributes.Details; activity.FailureDetails = historyEvent.LambdaFunctionFailedEventAttributes.Reason; activity.Status = Status.FAILED; activity.FailedDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.LambdaFunctionTimedOut) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.LambdaFunctionTimedOutEventAttributes.ScheduledEventId.ToString(), activityList); activity.Status = Status.TIMEOUT; activity.TmedOutDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.TimerStarted) { var activity = new Activity { ActivityType = Model.ActivityType.Timer, Name = historyEvent.TimerStartedEventAttributes.TimerId, ScheduledId = historyEvent.EventId.ToString(), UniqueId = historyEvent.TimerStartedEventAttributes.TimerId, Status = Status.STARTED, StartedDateTime = historyEvent.EventTimestamp }; activityList.Add(activity); } if (historyEvent.EventType == EventType.TimerFired) { var activity = FindActivity(Model.ActivityType.Timer, historyEvent.TimerFiredEventAttributes.StartedEventId.ToString(), activityList); activity.Status = Status.SUCCEEDED; activity.SucceededDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.ActivityTaskScheduled) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.ActivityTaskScheduledEventAttributes.ActivityId, activityList); if (activity == null) { activity = new Activity { ActivityType = Model.ActivityType.Task, Name = historyEvent.ActivityTaskScheduledEventAttributes.ActivityType.Name, ScheduledId = historyEvent.EventId.ToString(), UniqueId = historyEvent.ActivityTaskScheduledEventAttributes.Control, Status = Status.SCHEDULED, ScheduledDateTime = historyEvent.EventTimestamp }; activityList.Add(activity); } } if (historyEvent.EventType == EventType.ActivityTaskStarted) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.ActivityTaskStartedEventAttributes.ScheduledEventId.ToString(), activityList); activity.Status = Status.STARTED; activity.StartedDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.ActivityTaskFailed) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.ActivityTaskFailedEventAttributes.ScheduledEventId.ToString(), activityList); activity.Result = historyEvent.ActivityTaskFailedEventAttributes.Details; activity.Status = Status.FAILED; activity.FailedDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.ActivityTaskCompleted) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.ActivityTaskCompletedEventAttributes.ScheduledEventId.ToString(), activityList); activity.Result = historyEvent.ActivityTaskCompletedEventAttributes.Result; activity.Status = Status.SUCCEEDED; activity.SucceededDateTime = historyEvent.EventTimestamp; } if (historyEvent.EventType == EventType.ActivityTaskTimedOut) { var activity = FindActivity(Model.ActivityType.Task, historyEvent.ActivityTaskTimedOutEventAttributes.ScheduledEventId.ToString(), activityList); activity.Status = Status.TIMEOUT; activity.TmedOutDateTime = historyEvent.EventTimestamp; } } workflow.Activities = activityList; Task loggingTask = _store.LogStateAsync(workflow); } return(workflow); }
/// <summary> /// Constructor for the workflow event processor. /// </summary> /// <param name="decisionTask">Decision task passed in from SWF as decision task response.</param> /// <param name="workflow">IEnumerable set of string for workflow name and Type for workflow class.</param> /// <param name="request">The request used to retrieve <paramref name="decisionTask"/>, which will be used to retrieve subsequent history event pages.</param> /// <param name="swfClient">An SWF client.</param> /// <param name="storageManager">IStorageManager</param> public WorkflowEventsProcessor(DecisionTask decisionTask, WorkflowBase workflow, PollForDecisionTaskRequest request, IAmazonSimpleWorkflow swfClient, IStorageManager storageManager) : this(decisionTask, workflow, request, swfClient) { _storageClient = storageManager; _decisionContext = new WorkflowDecisionContext(_storageClient); }
/// <summary> /// Polls for descision tasks and decides what decisions to make. /// </summary> internal void PollAndDecide() { Debug.Assert(_workflow != null); while (!_cancellationToken.IsCancellationRequested) { var taskTolken = ""; try { var decisionTaskRequest = new PollForDecisionTaskRequest { Domain = _workflow.Options.Domain, //Identity = _workflow.WorkflowId, TaskList = _workflow.TaskList // This could be a specific TaskList instead of default value from context. }; Logger.Debug("TaskList: {0}", _workflow.TaskList.Name); PollForDecisionTaskResponse decisionTaskResponse = _swfClient.PollForDecisionTaskAsync(decisionTaskRequest).Result; DecisionTask decisionTask = decisionTaskResponse.DecisionTask; taskTolken = decisionTask.TaskToken; if (!string.IsNullOrEmpty(decisionTask.TaskToken)) { Logger.Debug("Get Decision."); // Define a new WorkflowEventsProcessor object and let it make the decision! var workflowProcessor = new WorkflowEventsProcessor(decisionTask, _workflow, decisionTaskRequest, _swfClient, _storageClient); var decisionRequest = workflowProcessor.Decide(); //var decisionRequest = _workflow.Decide(decisionTask, decisionTaskRequest); Logger.Debug("RespondDecisionTaskCompleted."); // We have our decision, send it away and do something more productive with the response _swfClient.RespondDecisionTaskCompletedAsync(decisionRequest).Wait(); } //Sleep to avoid aggressive polling Thread.Sleep(200); } /*catch (AmazonSimpleWorkflowException ex) * { * Logger.Error(ex, ""); * * //if (_workflow != null) * // _workflow.StopWorkers(); * * //if (!string.IsNullOrEmpty(taskTolken)) * //{ * // var respond = _workflow.FailWorkflowRespond(ex.Message, ""); * // respond.TaskToken = taskTolken; * // try * // { * // // Just try to stop workflow. * // _swfClient.RespondDecisionTaskCompleted(respond); * // } * // catch * // { * // } * //} * //Console.WriteLine("Caught Exception: " + ex.Message); * //Console.WriteLine("Response Status Code: " + ex.StatusCode); * //Console.WriteLine("Error Code: " + ex.ErrorCode); * //Console.WriteLine("Error Type: " + ex.ErrorType); * //Console.WriteLine("Request ID: " + ex.RequestId); * //Console.WriteLine("Data: " + ex.Data); * //Console.WriteLine("Stacktrace: " + ex.StackTrace); * }*/ catch (Exception e) { Logger.Error(e, ""); //if (_workflow != null) // _workflow.StopWorkers(); //if (!string.IsNullOrEmpty(taskTolken)) //{ // var respond = _workflow.FailWorkflowRespond(e.Message, ""); // respond.TaskToken = taskTolken; // try // { // // Just try to stop workflow. // _swfClient.RespondDecisionTaskCompleted(respond); // } // catch // { // } //} } } Logger.Info("Exit from Workflow Worker."); }
public void TestPollDecider() { string workflowId = DateTime.Now.Ticks.ToString(); var startRequest = new StartWorkflowExecutionRequest() { Domain = DOMAIN, WorkflowId = workflowId, ChildPolicy = "TERMINATE", TaskList = TASKLIST, Input = "ImportantKeyId", WorkflowType = WORKFLOW_TYPE }; var startResponse = Client.StartWorkflowExecution(startRequest); var pollDeciderRequest = new PollForDecisionTaskRequest() { Domain = DOMAIN, TaskList = TASKLIST, Identity = "testdecider" }; var pollDeciderResponse = Client.PollForDecisionTask(pollDeciderRequest); Assert.IsNotNull(pollDeciderResponse.DecisionTask); Assert.IsTrue(pollDeciderResponse.DecisionTask.Events.Count > 0); Assert.IsNotNull(pollDeciderResponse.DecisionTask.Events[0].EventId); Assert.IsNotNull(pollDeciderResponse.DecisionTask.Events[0].EventType); Assert.AreEqual(DateTime.Today, pollDeciderResponse.DecisionTask.Events[0].EventTimestamp.ToLocalTime().Date); var task = pollDeciderResponse.DecisionTask; var respondRequest = new RespondDecisionTaskCompletedRequest() { TaskToken = task.TaskToken, Decisions = new List <Decision>() { new Decision() { DecisionType = "ScheduleActivityTask", ScheduleActivityTaskDecisionAttributes = new ScheduleActivityTaskDecisionAttributes() { ActivityType = ACTIVITY_TYPE, ActivityId = DateTime.Now.Ticks.ToString(), TaskList = TASKLIST } } } }; Client.RespondDecisionTaskCompleted(respondRequest); var pollActivityRequest = new PollForActivityTaskRequest() { Domain = DOMAIN, TaskList = TASKLIST, Identity = "testactivity" }; var pollActivityResponse = Client.PollForActivityTask(pollActivityRequest); Assert.IsNotNull(pollActivityResponse.ResponseMetadata.RequestId); Assert.AreEqual(ACTIVITY_TYPE.Name, pollActivityResponse.ActivityTask.ActivityType.Name); Assert.AreEqual(ACTIVITY_TYPE.Version, pollActivityResponse.ActivityTask.ActivityType.Version); var signalRequest = new SignalWorkflowExecutionRequest() { Domain = DOMAIN, RunId = startResponse.Run.RunId, WorkflowId = startRequest.WorkflowId, SignalName = "TestSignal" }; var signalResponse = Client.SignalWorkflowExecution(signalRequest); Assert.IsNotNull(signalResponse.ResponseMetadata.RequestId); }
public static void Main(string[] args) { // Define the workflows that we know of that event processor will be handling var workflows = new Dictionary <string, Type> { { "CustomerOrderWorkflow", typeof(CustomerOrderWorkflow) }, { "VerifyCustomerWorkflow", typeof(VerifyCustomerWorkflow) } }; // Stopwatch to see how well we are performing var stopwatch = new Stopwatch(); // We will use this ID as our decision task ID and activity task ID to identify ourselves when polling for // decision and activity tasks. var workflowWorkerIdentity = Guid.NewGuid(); // Print out our AWS SWF domains, workflows and activities Console.Write(GetServiceOutput()); var loop = true; do { // Our super simple application menu Console.WriteLine(""); Console.WriteLine("============="); Console.WriteLine("| Main Menu |"); Console.WriteLine("============="); Console.WriteLine("[1] Submit a new workflow"); Console.WriteLine("[2] Wait for decide using a decision task"); Console.WriteLine("[3] Wait for and do some work for an activity task"); Console.WriteLine("[4] Quit"); Console.Write("\nChoice: "); var key = Console.ReadLine(); if (String.IsNullOrEmpty(key)) { continue; } switch (key) { // Initiate a workflow execution case "1": { Console.WriteLine("Option [1] selected - Submit a new workflow"); // SWF client is disposable, so dispose it using (var swfClient = new AmazonSimpleWorkflowClient(RegionEndpoint.USWest2)) { // Our simple property bag: we just need to the email for the account var propertyBag = new Dictionary <string, object> { { "SampleOrderNumber", "12345" } }; // Setup the workflow request var workflowRequest = new StartWorkflowExecutionRequest { Domain = "demo-domain", WorkflowId = Guid.NewGuid().ToString(), WorkflowType = new WorkflowType { Name = "CustomerOrderWorkflow", Version = "1.0" }, Input = JsonConvert.SerializeObject(propertyBag) }; try { // Call AWS SWF and submit the workflow request swfClient.StartWorkflowExecution(workflowRequest); } catch (AmazonSimpleWorkflowException ex) { Console.WriteLine("Caught Exception: " + ex.Message); Console.WriteLine("Response Status Code: " + ex.StatusCode); Console.WriteLine("Error Code: " + ex.ErrorCode); Console.WriteLine("Error Type: " + ex.ErrorType); Console.WriteLine("Request ID: " + ex.RequestId); Console.WriteLine("Data: " + ex.Data); Console.WriteLine("Stacktrace: " + ex.StackTrace); } } } break; // Poll for decision task case "2": { Console.WriteLine("Option [2] selected - Wait for decide using a decision task"); Console.WriteLine("Waiting..."); // SWF client is disposable, so dispose it using (var swfClient = new AmazonSimpleWorkflowClient(RegionEndpoint.USWest2)) { try { // Setup the decision request var decisionTaskRequest = new PollForDecisionTaskRequest { Domain = "demo-domain", Identity = workflowWorkerIdentity.ToString(), TaskList = new TaskList { Name = "DeciderTaskList-Default" } }; // Call AWS SWF and wait for (default timeout: 60 secs) a decision task var decisionTaskResponse = swfClient.PollForDecisionTask(decisionTaskRequest); // Task token being an empty string means there are no tasks available and // we are past the 60 seconds that AWS holds a connection in case a task // becomes available. If this is the case, we simply retry. var taskToken = decisionTaskResponse.DecisionTask.TaskToken; if (!String.IsNullOrEmpty(taskToken)) { // We have a valid task, do something... var decisionTask = decisionTaskResponse.DecisionTask; switch (decisionTask.WorkflowType.Name) { case "CustomerOrderWorkflow": case "VerifyCustomerWorkflow": { Debug.Assert(decisionTask.WorkflowType.Version == "1.0"); } break; default: Console.WriteLine("ERROR: Unknown workflow."); break; } // Define a new WorkflowEventsProcessor object and let it make the decision! stopwatch.Start(); var workflowProcessor = new WorkflowEventsProcessor(decisionTask, workflows, decisionTaskRequest, swfClient); var decisionRequest = workflowProcessor.Decide(); stopwatch.Stop(); Console.WriteLine(">>> Decision(s) made in " + stopwatch.ElapsedMilliseconds + "ms"); // We have our decision, send it away and do something // more productive with the response swfClient.RespondDecisionTaskCompleted(decisionRequest); } } catch (AmazonSimpleWorkflowException ex) { Console.WriteLine("Caught Exception: " + ex.Message); Console.WriteLine("Response Status Code: " + ex.StatusCode); Console.WriteLine("Error Code: " + ex.ErrorCode); Console.WriteLine("Error Type: " + ex.ErrorType); Console.WriteLine("Request ID: " + ex.RequestId); Console.WriteLine("Data: " + ex.Data); Console.WriteLine("Stacktrace: " + ex.StackTrace); } } } break; // Poll for activity task case "3": { Console.WriteLine("Option [3] selected - Wait for decide using a activity task"); Console.WriteLine("Waiting..."); // SWF client is disposable, so dispose it using (var swfClient = new AmazonSimpleWorkflowClient(RegionEndpoint.USWest2)) { try { // Setup the activity request var activityTaskRequest = new PollForActivityTaskRequest { Domain = "demo-domain", Identity = workflowWorkerIdentity.ToString(), TaskList = new TaskList { Name = "ActivityTaskList-Default" } }; // Call AWS SWF and wait for (default timeout: 60 secs) a activity task var activityTaskResponse = swfClient.PollForActivityTask(activityTaskRequest); // Task token being an empty string means there are no tasks available and // we are past the 60 seconds that AWS holds a connection in case a task // becomes available. If this is the case, we simply retry. var taskToken = activityTaskResponse.ActivityTask.TaskToken; if (!String.IsNullOrEmpty(taskToken)) { // We have a valid task, do something... var activityTask = activityTaskResponse.ActivityTask; Console.WriteLine("\n"); Console.WriteLine(">>> Activity: " + activityTask.ActivityType.Name); // In the real world we would define the activity code in a separate object // and fire off a thread to actually work on it but in this case we are just // testing the workflow so this suffices switch (activityTask.ActivityType.Name) { // CustomerOrderWorkflow activities case "VerifyOrder": case "ShipOrder": { Debug.Assert(activityTask.ActivityType.Version == "1.0"); } break; // VerifyCustomerWorkflow activities case "VerifyCustomerAddress": case "CheckFraudDB": case "ChargeCreditCard": { Debug.Assert(activityTask.ActivityType.Version == "1.0"); } break; default: Console.WriteLine("ERROR: Unknown activity."); break; } var activityCompletedRequest = new RespondActivityTaskCompletedRequest { TaskToken = activityTask.TaskToken, Result = activityTask.Input }; // Completion request setup complete, send it away. NOTE: Do something more // productive with the response swfClient.RespondActivityTaskCompleted(activityCompletedRequest); //var activityFailedRequest = new RespondActivityTaskFailedRequest // { // TaskToken = activityTask.TaskToken, // Details = "Test failure." // }; //// Completion request setup complete, send it away. NOTE: Do something more //// productive with the response //swfClient.RespondActivityTaskFailed(activityFailedRequest); } } catch (AmazonSimpleWorkflowException ex) { Console.WriteLine("Caught Exception: " + ex.Message); Console.WriteLine("Response Status Code: " + ex.StatusCode); Console.WriteLine("Error Code: " + ex.ErrorCode); Console.WriteLine("Error Type: " + ex.ErrorType); Console.WriteLine("Request ID: " + ex.RequestId); Console.WriteLine("Data: " + ex.Data); Console.WriteLine("Stacktrace: " + ex.StackTrace); } } } break; case "4": // Quit loop = false; break; default: Console.WriteLine("ERROR: Unknown command."); break; } } while (loop); }
// Simple logic // Creates four activities at the begining // Waits for them to complete and completes the workflow static void Decider() { int activityCount = 0; // This refers to total number of activities per workflow IAmazonSimpleWorkflow swfClient = AWSClientFactory.CreateAmazonSimpleWorkflowClient(); while (true) { Console.WriteLine("Decider: Polling for decision task ..."); PollForDecisionTaskRequest request = new PollForDecisionTaskRequest() { Domain = domainName, TaskList = new TaskList() { Name = "HelloWorld" } }; PollForDecisionTaskResponse response = swfClient.PollForDecisionTask(request); if (response.DecisionTask.TaskToken == null) { Console.WriteLine("Decider: NULL"); continue; } int completedActivityTaskCount = 0, totalActivityTaskCount = 0; foreach (HistoryEvent e in response.DecisionTask.Events) { Console.WriteLine("Decider: EventType - " + e.EventType + ", EventId - " + e.EventId); if (e.EventType == "ActivityTaskCompleted") { completedActivityTaskCount++; } if (e.EventType.Value.StartsWith("Activity")) { totalActivityTaskCount++; } } Console.WriteLine(".... completedCount=" + completedActivityTaskCount); List <Decision> decisions = new List <Decision>(); if (totalActivityTaskCount == 0) // Create this only at the begining { ScheduleActivity("Activity1A", decisions); ScheduleActivity("Activity1B", decisions); ScheduleActivity("Activity2", decisions); ScheduleActivity("Activity2", decisions); activityCount = 4; } else if (completedActivityTaskCount == activityCount) { Decision decision = new Decision() { DecisionType = DecisionType.CompleteWorkflowExecution, CompleteWorkflowExecutionDecisionAttributes = new CompleteWorkflowExecutionDecisionAttributes { Result = "{\"Result\":\"WF Complete!\"}" } }; decisions.Add(decision); Console.WriteLine("Decider: WORKFLOW COMPLETE!!!!!!!!!!!!!!!!!!!!!!"); } RespondDecisionTaskCompletedRequest respondDecisionTaskCompletedRequest = new RespondDecisionTaskCompletedRequest() { Decisions = decisions, TaskToken = response.DecisionTask.TaskToken }; swfClient.RespondDecisionTaskCompleted(respondDecisionTaskCompletedRequest); } }
// Simple logic // Creates four activities at the begining // Waits for them to complete and completes the workflow static void Decider() { int activityCount = 0; // This refers to total number of activities per workflow while (true) { Console.WriteLine("DECIDER: Polling for decision task ..."); var request = new PollForDecisionTaskRequest() { Domain = domainName, TaskList = new TaskList() { Name = "SwfDemo" } }; var response = SwfDeciderClient.PollForDecisionTask(request); if (response.DecisionTask.TaskToken == null) { Console.WriteLine("DECIDER: NULL"); continue; } int completedActivityTaskCount = 0, totalActivityTaskCount = 0; foreach (HistoryEvent e in response.DecisionTask.Events) { Console.WriteLine($"DECIDER: EventType - {e.EventType}" + $", EventId - {e.EventId}"); if (e.EventType == "ActivityTaskCompleted") { completedActivityTaskCount++; } if (e.EventType.Value.StartsWith("Activity")) { totalActivityTaskCount++; } } Console.WriteLine($"completedCount={completedActivityTaskCount}"); var decisions = new List <Decision>(); if (totalActivityTaskCount == 0) // Create this only at the begining { ScheduleActivity("Activity1A", decisions); ScheduleActivity("Activity1B", decisions); ScheduleActivity("Activity2", decisions); ScheduleActivity("Activity2", decisions); activityCount = 4; } else if (completedActivityTaskCount == activityCount) { var decision = new Decision() { DecisionType = DecisionType.CompleteWorkflowExecution, CompleteWorkflowExecutionDecisionAttributes = new CompleteWorkflowExecutionDecisionAttributes { Result = "{\"Result\":\"WF Complete!\"}" } }; decisions.Add(decision); Console.WriteLine("DECIDER: WORKFLOW COMPLETE"); } var respondDecisionTaskCompletedRequest = new RespondDecisionTaskCompletedRequest() { Decisions = decisions, TaskToken = response.DecisionTask.TaskToken }; SwfDeciderClient.RespondDecisionTaskCompleted(respondDecisionTaskCompletedRequest); } }