Exemplo n.º 1
0
        /// <summary>
        /// Runs this instance.
        /// </summary>
        public override void Run()
        {
            Trace.WriteLine("Starting processing of messages");
            // Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
            this.Client.OnMessage(
                receivedMessage =>
            {
                try
                {
                    this.resetEvent = new ManualResetEvent(false);
                    // Process the message
                    Trace.WriteLine(
                        "Processing Service Bus message: " + receivedMessage.SequenceNumber.ToString());

                    // Name of workflow to trigger.
                    var workflowToTrigger = receivedMessage.Properties["workflowName"];
                    // Prepare input message for Workflow.
                    var channelData = new ChannelData {
                        Payload = receivedMessage.GetBody <HostQueueMessage>()
                    };
                    this.arrivedMessage = channelData.Payload;
                    // You can save the workflow xaml externally (usually database). See this.
                    var workflowXaml = File.ReadAllText($"{workflowToTrigger}.txt");
                    if (!string.IsNullOrWhiteSpace(workflowXaml))
                    {
                        //// 5. Compose WF Application.
                        var workflowApplication =
                            new WorkflowApplication(
                                Routines.CreateWorkflowActivityFromXaml(workflowXaml, this.GetType().Assembly),
                                new Dictionary <string, object> {
                            { "ChannelData", channelData }
                        });

                        //// 6. Extract Request Identifier to set it as identifier of workflow.
                        this.SetupWorkflowEnvironment(
                            workflowApplication,
                            channelData.Payload.WorkflowIdentifier);

                        //// 7. Test whether this is a resumed bookmark or a fresh message.
                        if (channelData.Payload.IsBookmark)
                        {
                            //// 8.1. Make sure there is data for this request identifier in storage to avoid errors due to transient errors.
                            if (null
                                != this.repository.GetById(
                                    "WorkflowInstanceStoreData",
                                    channelData.Payload.WorkflowIdentifier.ToString()))
                            {
                                //// Prepare a new workflow instance as we need to resume bookmark.
                                var bookmarkedWorkflowApplication =
                                    new WorkflowApplication(
                                        Routines.CreateWorkflowActivityFromXaml(
                                            workflowXaml,
                                            this.GetType().Assembly));
                                this.SetupWorkflowEnvironment(
                                    bookmarkedWorkflowApplication,
                                    channelData.Payload.WorkflowIdentifier);

                                //// 9. Resume bookmark and supply input as is from channel data.
                                bookmarkedWorkflowApplication.Load(channelData.Payload.WorkflowIdentifier);

                                //// 9.1. If workflow got successfully completed, remove the host message.
                                if (BookmarkResumptionResult.Success
                                    == bookmarkedWorkflowApplication.ResumeBookmark(
                                        bookmarkedWorkflowApplication.GetBookmarks().Single().BookmarkName,
                                        channelData,
                                        TimeSpan.FromDays(7)))
                                {
                                    Trace.Write(
                                        Routines.FormatStringInvariantCulture("Bookmark successfully resumed."));
                                    this.resetEvent.WaitOne();
                                    this.Client.Complete(receivedMessage.LockToken);
                                    return;
                                }
                            }
                            else
                            {
                                //// This was a transient error.
                                Trace.Write(Routines.FormatStringInvariantCulture("Error"));
                            }
                        }

                        //// 10. Run workflow in case of normal execution.
                        workflowApplication.Run(TimeSpan.FromDays(7));
                        Trace.Write(
                            Routines.FormatStringInvariantCulture(
                                "Workflow for request id has started execution"));
                        this.resetEvent.WaitOne();
                    }
                }
                catch
                {
                    // Handle any message processing specific exceptions here
                }
            });

            this.CompletedEvent.WaitOne();
        }