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); }
/// <summary> /// This method starts the workflow execution. /// </summary> /// <param name="bucket"></param> /// <param name="filepath"></param> public void StartWorkflowExecution(int RequestId) { System.Threading.Tasks.Task.Run(() => { try { //IAmazonS3 s3Client = new AmazonS3Client(); IAmazonSimpleWorkflow swfClient = new AmazonSimpleWorkflowClient(); //this._console.WriteLine("Create bucket if it doesn't exist"); // Make sure bucket exists //s3Client.PutBucket(new PutBucketRequest //{ // BucketName = bucket, // UseClientRegion = true //}); //this._console.WriteLine("Uploading image to S3"); // Upload the image to S3 before starting the execution //PutObjectRequest putRequest = new PutObjectRequest //{ // BucketName = bucket, // FilePath = filepath, // Key = Path.GetFileName(filepath) //}; //// Add upload progress callback to print every increment of 10 percent uploaded to the console. //int currentPercent = -1; //putRequest.StreamTransferProgress = new EventHandler<Amazon.Runtime.StreamTransferProgressArgs>((x, args) => //{ // if (args.PercentDone == currentPercent) // return; // currentPercent = args.PercentDone; // if (currentPercent % 10 == 0) // { // this._console.WriteLine(string.Format("... Uploaded {0} %", currentPercent)); // } //}); //s3Client.PutObject(putRequest); // Setup the input for the workflow execution that tells the execution what bukcet and object to use. Common.WorkflowExecutionStartedInput input = new Common.WorkflowExecutionStartedInput { RequestId = RequestId }; Console.WriteLine("Start workflow execution"); // Start the workflow execution swfClient.StartWorkflowExecution(new StartWorkflowExecutionRequest() { //Serialize input to a string Input = Common.Utils.SerializeToJSON<Common.WorkflowExecutionStartedInput>(input), //Unique identifier for the execution WorkflowId = DateTime.Now.Ticks.ToString(), Domain = Common.Constants.WFDomain, WorkflowType = new WorkflowType() { Name = Shared.Constants.WFWorkflow, Version = Shared.Constants.WFWorkflowVersion } }); } catch (Exception e) { Console.WriteLine("Error starting workflow execution: " + e.Message); } }); }