/// <summary> /// Defines the entry point of the application. /// </summary> /// <param name="args">The arguments.</param> private static void Main(string[] args) { var connectionString = ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString"]; var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); if (!namespaceManager.QueueExists(QueueName)) { namespaceManager.CreateQueue(QueueName); } var client = QueueClient.CreateFromConnectionString(connectionString, QueueName); var hostQueueMessage = new HostQueueMessage { IsBookmark = false, WorkflowIdentifier = Guid.NewGuid(), PersistentPayload = new Dictionary<string, string> { ["container"] = "rawfiles" } }; var message = new BrokeredMessage(hostQueueMessage); message.Properties.Add("workflowName", "CopyDocsToContainer"); client.Send(message); }
/// <summary> /// Adds the bookmark message. /// </summary> /// <param name="workflowId">The workflow identifier.</param> private void AddBookmarkMessage(Guid workflowId) { var hostQueueMessage = new HostQueueMessage { IsBookmark = true, WorkflowIdentifier = workflowId, PersistentPayload = this.arrivedMessage.PersistentPayload, ItemList = this.arrivedMessage.ItemList }; var message = new BrokeredMessage(hostQueueMessage); message.Properties.Add("workflowName", "CopyDocsToContainer"); this.Client.Send(message); }
/// <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(); }