Container for the parameters to the RespondActivityTaskCompleted operation.

Used by workers to tell the service that the ActivityTask identified by the taskToken completed successfully with a result (if provided). The result appears in the ActivityTaskCompleted event in the workflow history.

IMPORTANT: If the requested task does not complete successfully, use RespondActivityTaskFailed instead. If the worker finds that the task is canceled through the canceled flag returned by RecordActivityTaskHeartbeat, it should cancel the task, clean up and then call RespondActivityTaskCanceled.

A task is considered open from the time that it is scheduled until it is closed. Therefore a task is reported as open while a worker is processing it. A task is closed after it has been specified in a call to RespondActivityTaskCompleted, RespondActivityTaskCanceled, RespondActivityTaskFailed, or the task has timed out .

Access Control

You can use IAM policies to control this action's access to Amazon SWF resources as follows:

  • Use a Resource element with the domain name to limit the action to only specified domains.
  • Use an Action element to allow or deny permission to call this action.
  • You cannot use an IAM policy to constrain this action's parameters.

If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified constraints, the action fails by throwing OperationNotPermitted . For details and example IAM policies, see Using IAM to Manage Access to Amazon SWF Workflows .

Inheritance: Amazon.Runtime.AmazonWebServiceRequest
 async void CompleteTaskAsync(String taskToken)
 {
     RespondActivityTaskCompletedRequest request = new RespondActivityTaskCompletedRequest()
     {
         TaskToken = taskToken
     };
     RespondActivityTaskCompletedResponse response = await this._swfClient.RespondActivityTaskCompletedAsync(request);
     Logger.LogMessage("{0} Activity task completed.", this.ActivityType);
 }
Exemplo n.º 2
0
 /// <summary>
 /// Initiates the asynchronous execution of the RespondActivityTaskCompleted operation.
 /// <seealso cref="Amazon.SimpleWorkflow.AmazonSimpleWorkflow.RespondActivityTaskCompleted"/>
 /// </summary>
 /// 
 /// <param name="respondActivityTaskCompletedRequest">Container for the necessary parameters to execute the RespondActivityTaskCompleted
 ///          operation on AmazonSimpleWorkflow.</param>
 /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param>
 /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback
 ///          procedure using the AsyncState property.</param>
 public IAsyncResult BeginRespondActivityTaskCompleted(RespondActivityTaskCompletedRequest respondActivityTaskCompletedRequest, AsyncCallback callback, object state)
 {
     return invokeRespondActivityTaskCompleted(respondActivityTaskCompletedRequest, callback, state, false);
 }
Exemplo n.º 3
0
 IAsyncResult invokeRespondActivityTaskCompleted(RespondActivityTaskCompletedRequest respondActivityTaskCompletedRequest, AsyncCallback callback, object state, bool synchronized)
 {
     IRequest irequest = new RespondActivityTaskCompletedRequestMarshaller().Marshall(respondActivityTaskCompletedRequest);
     var unmarshaller = RespondActivityTaskCompletedResponseUnmarshaller.GetInstance();
     AsyncResult result = new AsyncResult(irequest, callback, state, synchronized, signer, unmarshaller);
     Invoke(result);
     return result;
 }
Exemplo n.º 4
0
 /// <summary>
 /// <para> Used by workers to tell the service that the ActivityTask identified by the <c>taskToken</c> completed successfully with a
 /// <c>result</c> (if provided). </para> <para> The <c>result</c> appears in the <c>ActivityTaskCompleted</c> event in the workflow history.
 /// </para> <para><b>IMPORTANT:</b> If the requested task does not complete successfully, use RespondActivityTaskFailed instead. If the worker
 /// finds that the task is canceled through the canceled flag returned by RecordActivityTaskHeartbeat, it should cancel the task, clean up and
 /// then call RespondActivityTaskCanceled. </para>
 /// </summary>
 /// 
 /// <param name="respondActivityTaskCompletedRequest">Container for the necessary parameters to execute the RespondActivityTaskCompleted service
 ///          method on AmazonSimpleWorkflow.</param>
 /// 
 /// <exception cref="OperationNotPermittedException"/>
 /// <exception cref="UnknownResourceException"/>
 public RespondActivityTaskCompletedResponse RespondActivityTaskCompleted(RespondActivityTaskCompletedRequest respondActivityTaskCompletedRequest)
 {
     IAsyncResult asyncResult = invokeRespondActivityTaskCompleted(respondActivityTaskCompletedRequest, null, null, true);
     return EndRespondActivityTaskCompleted(asyncResult);
 }
        /// <summary>
        /// <para> Used by workers to tell the service that the ActivityTask identified by the <c>taskToken</c> completed successfully with a
        /// <c>result</c> (if provided). The <c>result</c> appears in the <c>ActivityTaskCompleted</c> event in the workflow history. </para>
        /// <para><b>IMPORTANT:</b> If the requested task does not complete successfully, use RespondActivityTaskFailed instead. If the worker finds
        /// that the task is canceled through the canceled flag returned by RecordActivityTaskHeartbeat, it should cancel the task, clean up and then
        /// call RespondActivityTaskCanceled. </para> <para> A task is considered open from the time that it is scheduled until it is closed. Therefore
        /// a task is reported as open while a worker is processing it. A task is closed after it has been specified in a call to
        /// RespondActivityTaskCompleted, RespondActivityTaskCanceled, RespondActivityTaskFailed, or the task has <a href="http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-basic.html#swf-dev-timeout-types">timed out</a> .
        /// </para> <para> <b>Access Control</b> </para> <para>You can use IAM policies to control this action's access to Amazon SWF resources as
        /// follows:</para>
        /// <ul>
        /// <li>Use a <c>Resource</c> element with the domain name to limit the action to only specified domains.</li>
        /// <li>Use an <c>Action</c> element to allow or deny permission to call this action.</li>
        /// <li>You cannot use an IAM policy to constrain this action's parameters.</li>
        /// 
        /// </ul>
        /// <para>If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified
        /// constraints, the action fails by throwing <c>OperationNotPermitted</c> . For details and example IAM policies, see <a href="http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dev-iam.html">Using IAM to Manage Access to Amazon SWF Workflows</a>
        /// .</para>
        /// </summary>
        /// 
        /// <param name="respondActivityTaskCompletedRequest">Container for the necessary parameters to execute the RespondActivityTaskCompleted service
        /// method on AmazonSimpleWorkflow.</param>
        /// 
        /// <exception cref="T:Amazon.SimpleWorkflow.Model.OperationNotPermittedException" />
        /// <exception cref="T:Amazon.SimpleWorkflow.Model.UnknownResourceException" />
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
		public Task<RespondActivityTaskCompletedResponse> RespondActivityTaskCompletedAsync(RespondActivityTaskCompletedRequest respondActivityTaskCompletedRequest, CancellationToken cancellationToken = default(CancellationToken))
        {
            var marshaller = new RespondActivityTaskCompletedRequestMarshaller();
            var unmarshaller = RespondActivityTaskCompletedResponseUnmarshaller.GetInstance();
            return Invoke<IRequest, RespondActivityTaskCompletedRequest, RespondActivityTaskCompletedResponse>(respondActivityTaskCompletedRequest, marshaller, unmarshaller, signer, cancellationToken);
        }
		internal RespondActivityTaskCompletedResponse RespondActivityTaskCompleted(RespondActivityTaskCompletedRequest request)
        {
            var task = RespondActivityTaskCompletedAsync(request);
            try
            {
                return task.Result;
            }
            catch(AggregateException e)
            {
                ExceptionDispatchInfo.Capture(e.InnerException).Throw();
                return null;
            }
        }
        /// <summary>
        /// Initiates the asynchronous execution of the RespondActivityTaskCompleted operation.
        /// <seealso cref="Amazon.SimpleWorkflow.IAmazonSimpleWorkflow"/>
        /// </summary>
        /// 
        /// <param name="request">Container for the necessary parameters to execute the RespondActivityTaskCompleted operation.</param>
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
        /// <returns>The task object representing the asynchronous operation.</returns>
        public Task<RespondActivityTaskCompletedResponse> RespondActivityTaskCompletedAsync(RespondActivityTaskCompletedRequest request, System.Threading.CancellationToken cancellationToken = default(CancellationToken))
        {
            var marshaller = new RespondActivityTaskCompletedRequestMarshaller();
            var unmarshaller = RespondActivityTaskCompletedResponseUnmarshaller.Instance;

            return InvokeAsync<RespondActivityTaskCompletedRequest,RespondActivityTaskCompletedResponse>(request, marshaller, 
                unmarshaller, cancellationToken);
        }
        /// <summary>
        /// Used by workers to tell the service that the <a>ActivityTask</a> identified by the
        /// <code>taskToken</code> completed successfully with a <code>result</code> (if provided).
        /// The <code>result</code> appears in the <code>ActivityTaskCompleted</code> event in
        /// the workflow history. 
        /// 
        ///  <important> If the requested task does not complete successfully, use <a>RespondActivityTaskFailed</a>
        /// instead. If the worker finds that the task is canceled through the <code>canceled</code>
        /// flag returned by <a>RecordActivityTaskHeartbeat</a>, it should cancel the task, clean
        /// up and then call <a>RespondActivityTaskCanceled</a>. </important> 
        /// <para>
        ///  A task is considered open from the time that it is scheduled until it is closed.
        /// Therefore a task is reported as open while a worker is processing it. A task is closed
        /// after it has been specified in a call to RespondActivityTaskCompleted, <a>RespondActivityTaskCanceled</a>,
        /// <a>RespondActivityTaskFailed</a>, or the task has <a href="http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-basic.html#swf-dev-timeout-types">timed
        /// out</a>. 
        /// </para>
        ///  
        /// <para>
        /// <b>Access Control</b>
        /// </para>
        ///  
        /// <para>
        /// You can use IAM policies to control this action's access to Amazon SWF resources as
        /// follows:
        /// </para>
        ///  <ul> <li>Use a <code>Resource</code> element with the domain name to limit the action
        /// to only specified domains.</li> <li>Use an <code>Action</code> element to allow or
        /// deny permission to call this action.</li> <li>You cannot use an IAM policy to constrain
        /// this action's parameters.</li> </ul> 
        /// <para>
        /// If the caller does not have sufficient permissions to invoke the action, or the parameter
        /// values fall outside the specified constraints, the action fails by throwing <code>OperationNotPermitted</code>.
        /// For details and example IAM policies, see <a href="http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dev-iam.html">Using
        /// IAM to Manage Access to Amazon SWF Workflows</a>.
        /// </para>
        /// </summary>
        /// <param name="request">Container for the necessary parameters to execute the RespondActivityTaskCompleted service method.</param>
        /// 
        /// <returns>The response from the RespondActivityTaskCompleted service method, as returned by SimpleWorkflow.</returns>
        /// <exception cref="OperationNotPermittedException">
        /// Returned when the caller does not have sufficient permissions to invoke the action.
        /// </exception>
        /// <exception cref="UnknownResourceException">
        /// Returned when the named resource cannot be found with in the scope of this operation
        /// (region or domain). This could happen if the named resource was never created or is
        /// no longer available for this operation.
        /// </exception>
        public RespondActivityTaskCompletedResponse RespondActivityTaskCompleted(RespondActivityTaskCompletedRequest request)
        {
            var marshaller = new RespondActivityTaskCompletedRequestMarshaller();
            var unmarshaller = RespondActivityTaskCompletedResponseUnmarshaller.Instance;

            return Invoke<RespondActivityTaskCompletedRequest,RespondActivityTaskCompletedResponse>(request, marshaller, unmarshaller);
        }
        /// <summary>
        /// Initiates the asynchronous execution of the RespondActivityTaskCompleted operation.
        /// </summary>
        /// 
        /// <param name="request">Container for the necessary parameters to execute the RespondActivityTaskCompleted operation on AmazonSimpleWorkflowClient.</param>
        /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param>
        /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback
        ///          procedure using the AsyncState property.</param>
        /// 
        /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndRespondActivityTaskCompleted
        ///         operation.</returns>
        public IAsyncResult BeginRespondActivityTaskCompleted(RespondActivityTaskCompletedRequest request, AsyncCallback callback, object state)
        {
            var marshaller = new RespondActivityTaskCompletedRequestMarshaller();
            var unmarshaller = RespondActivityTaskCompletedResponseUnmarshaller.Instance;

            return BeginInvoke<RespondActivityTaskCompletedRequest>(request, marshaller, unmarshaller,
                callback, state);
        }
        /// <summary>
        /// <para> Used by workers to tell the service that the ActivityTask identified by the <c>taskToken</c> completed successfully with a
        /// <c>result</c> (if provided). The <c>result</c> appears in the <c>ActivityTaskCompleted</c> event in the workflow history. </para>
        /// <para><b>IMPORTANT:</b> If the requested task does not complete successfully, use RespondActivityTaskFailed instead. If the worker finds
        /// that the task is canceled through the canceled flag returned by RecordActivityTaskHeartbeat, it should cancel the task, clean up and then
        /// call RespondActivityTaskCanceled. </para> <para> A task is considered open from the time that it is scheduled until it is closed. Therefore
        /// a task is reported as open while a worker is processing it. A task is closed after it has been specified in a call to
        /// RespondActivityTaskCompleted, RespondActivityTaskCanceled, RespondActivityTaskFailed, or the task has <a href="http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-basic.html#swf-dev-timeout-types">timed out</a> .
        /// </para> <para> <b>Access Control</b> </para> <para>You can use IAM policies to control this action's access to Amazon SWF resources as
        /// follows:</para>
        /// <ul>
        /// <li>Use a <c>Resource</c> element with the domain name to limit the action to only specified domains.</li>
        /// <li>Use an <c>Action</c> element to allow or deny permission to call this action.</li>
        /// <li>You cannot use an IAM policy to constrain this action's parameters.</li>
        /// 
        /// </ul>
        /// <para>If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified
        /// constraints, the action fails by throwing <c>OperationNotPermitted</c> . For details and example IAM policies, see <a href="http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dev-iam.html">Using IAM to Manage Access to Amazon SWF Workflows</a>
        /// .</para>
        /// </summary>
        /// 
        /// <param name="respondActivityTaskCompletedRequest">Container for the necessary parameters to execute the RespondActivityTaskCompleted service
        /// method on AmazonSimpleWorkflow.</param>
        /// 
        /// <exception cref="T:Amazon.SimpleWorkflow.Model.OperationNotPermittedException" />
        /// <exception cref="T:Amazon.SimpleWorkflow.Model.UnknownResourceException" />
        /// <param name="cancellationToken">
        ///     A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
		public async Task<RespondActivityTaskCompletedResponse> RespondActivityTaskCompletedAsync(RespondActivityTaskCompletedRequest respondActivityTaskCompletedRequest, CancellationToken cancellationToken = default(CancellationToken))
        {
            var marshaller = new RespondActivityTaskCompletedRequestMarshaller();
            var unmarshaller = RespondActivityTaskCompletedResponseUnmarshaller.GetInstance();
            var response = await Invoke<IRequest, RespondActivityTaskCompletedRequest, RespondActivityTaskCompletedResponse>(respondActivityTaskCompletedRequest, marshaller, unmarshaller, signer, cancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false);
            return response;
        }
		internal RespondActivityTaskCompletedResponse RespondActivityTaskCompleted(RespondActivityTaskCompletedRequest request)
        {
            var task = RespondActivityTaskCompletedAsync(request);
            try
            {
                return task.Result;
            }
            catch(AggregateException e)
            {
                throw e.InnerException;
            }
        }
Exemplo n.º 12
0
 /// <summary>
 /// Respond back to SWF that the activity task is complete
 /// </summary>
 /// <param name="taskToken"></param>
 /// <param name="activityState"></param>
 void CompleteTask(String taskToken, Common.ActivityTaskCompletedResult activityState)
 {
     RespondActivityTaskCompletedRequest request = new RespondActivityTaskCompletedRequest()
     {
         Result = Common.Utils.SerializeToJSON<Common.ActivityTaskCompletedResult>(activityState),
         TaskToken = taskToken
     };
     RespondActivityTaskCompletedResponse response = swfClient.RespondActivityTaskCompleted(request);
     Console.WriteLine("Activity task completed. RequestActionId " + activityState.RequestActionId);
 }
Exemplo n.º 13
0
        static void Worker(string tasklistName)
        {
            string prefix = string.Format("Worker{0}:{1:x} ", tasklistName,
                            System.Threading.Thread.CurrentThread.ManagedThreadId);
              while (true)
              {
            Console.WriteLine(prefix + ": Polling for activity task ...");
            PollForActivityTaskRequest pollForActivityTaskRequest =
            new PollForActivityTaskRequest() {
                                      Domain = domainName,
                                      TaskList = new TaskList()
                                      {
                                          // Poll only the tasks assigned to me
                                        Name = tasklistName
                                      }
                                };
            PollForActivityTaskResponse pollForActivityTaskResponse =
                        swfClient.PollForActivityTask(pollForActivityTaskRequest);

            RespondActivityTaskCompletedRequest respondActivityTaskCompletedRequest =
                    new RespondActivityTaskCompletedRequest() {
                              Result = "{\"activityResult1\":\"Result Value1\"}",
                              TaskToken = pollForActivityTaskResponse.ActivityTask.TaskToken
                            };
            if (pollForActivityTaskResponse.ActivityTask.ActivityId == null)
            {
              Console.WriteLine(prefix + ": NULL");
            }
            else
            {
              RespondActivityTaskCompletedResponse respondActivityTaskCompletedResponse =
              swfClient.RespondActivityTaskCompleted(respondActivityTaskCompletedRequest);
              Console.WriteLine(prefix + ": Activity task completed. ActivityId - " +
              pollForActivityTaskResponse.ActivityTask.ActivityId);
            }
              }
        }
 /// <summary>
 /// <para> Used by workers to tell the service that the ActivityTask identified by the <c>taskToken</c> completed successfully with a
 /// <c>result</c> (if provided). </para> <para> The <c>result</c> appears in the <c>ActivityTaskCompleted</c> event in the workflow history.
 /// </para> <para><b>IMPORTANT:</b> If the requested task does not complete successfully, use RespondActivityTaskFailed instead. If the worker
 /// finds that the task is canceled through the canceled flag returned by RecordActivityTaskHeartbeat, it should cancel the task, clean up and
 /// then call RespondActivityTaskCanceled. </para>
 /// </summary>
 /// 
 /// <param name="respondActivityTaskCompletedRequest">Container for the necessary parameters to execute the RespondActivityTaskCompleted service
 ///           method on AmazonSimpleWorkflow.</param>
 /// 
 /// <exception cref="OperationNotPermittedException"/>
 /// <exception cref="UnknownResourceException"/>
 public RespondActivityTaskCompletedResponse RespondActivityTaskCompleted(RespondActivityTaskCompletedRequest respondActivityTaskCompletedRequest)
 {
     IRequest<RespondActivityTaskCompletedRequest> request = new RespondActivityTaskCompletedRequestMarshaller().Marshall(respondActivityTaskCompletedRequest);
     RespondActivityTaskCompletedResponse response = Invoke<RespondActivityTaskCompletedRequest, RespondActivityTaskCompletedResponse> (request, this.signer, RespondActivityTaskCompletedResponseUnmarshaller.GetInstance());
     return response;
 }
Exemplo n.º 15
0
        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);
        }