In my previous articles we started analyzing data integration design patterns [1] and message queueing [2] in Dynamics 365. In this article we’ll focus on implementing the Publish / Subscribe [3] pattern in Dynamics 365 with Azure Service Bus [4]. The Publish / Subscribe design pattern allows for:

  • Message Queueing: Each system can submit a message to the ESB and get it dispatched to another system.
  • Topic Subscription: A system “subscribes” to a specific topic and receives data only from other systems that publish messages in the same topic.

As seen in the previous article about Message Queueing [2], leveraging the power of message queueing in Azure Service Bus is guarantee of message delivery, but still not enough for implementing the entire Publish / Subscribe pattern. In this context, the process of receiving a message from the ESB goes under the name of Topic Subscription.

Topic Subscription

In an ESB context, applications subscribe to a specific topic in order to receive relevant messages posted by other applications to that topic. Azure Service Bus provisions a Topic for accepting incoming messages and processing them as soon as possible. A topic is identified by a name and size (at time of writing, up to 5 GB). Additional settings, related to the lifecycle of the message in the topic, include:

  • Persistency of a message in the topic before it is removed, if no applications receive it.
  • Lock duration, that is how long a message is locked within the topic for other receivers.
  • Duplicate detection (the topic won’t accept duplicate messages).
  • Other settings about session and partitioning management that are more related to the performance of the topic itself.

Dynamics 365 customizations can benefit of topic subscription in Azure Service Bus by implementing the Publish / Subscribe pattern. Before being able to send a message, it is necessary to allocate a to a topic in Azure Service Bus. From the Azure portal:

  1. Create a new Azure Service Bus namespace, if not already done. More information is available on the Azure Service Bus web site [5].
  2. Create a Topic and assign it a name. Details about the several settings available on the Azure Service Bus web site [6].
  3. Obtain a connection string to the Azure Service Bus, for a specific policy (access profile), from Shared access policies > Primary Connection String.

Assuming your customization includes an XRM plug-in, and you want to send some entity data to the ESB from within the plug-in, the sequence of tasks to implement are straightforward:

  1. In a Visual Studio solution, add an XRM plug-in project. Make sure the project references the Microsoft.Xrm.Sdk package, otherwise easily obtainable from NuGet.
  2. From NuGet:
    1. Add the WindowsAzure.ServiceBus package to the project. This package contains the class library necessary to connect to Azure Service Bus with managed .NET code;
    2. Add the Newtonsoft.Json package to the project. This package contains the class library necessary to serialize and deserialize entities in JSON format.
  3. In your project, add a XRM plug-in class. In the Executemethod, which is invoked when the plug-in is triggered:
    1. Obtain a connection to the Service Bus Topic by specifying the connection string and the Topic name;
    2. Serialize the entity data that you want to send to the Service Bus in JSON format;
    3. Send, asynchronously, the message to the ESB by wrapping it in a BrokeredMessage object.

The following code snippet implements sending a brokered message to a Topic, using the TopicClient class.

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        Entity entity = (Entity)context.InputParameters["Target"];
        Task.Run(async () => {
            var client = TopicClient.CreateFromConnectionString(connectionString, topicName);
            var message = new BrokeredMessage(JsonConvert.SerializeObject(entity));
            await client.SendAsync(message);
        });
    }


When receiving a message, for example from within a Workflow:

The OnMessage event handler will have to obtain a connection to a specific Subscription, identified by connection string, Topic name and Subscription name.

We can now control the lifecycle of a message within a Topic. Whereas a message in a Queue follows the FIFO principle (first in, first out), a message in a Topic remains available to any other applications that subscribe to that Topic. To remove a message from a Topic, we can intentionally specify the AutoComplete property in the OnMessageProperties settings.

The code below implements receiving that message from a specific Subscription within a Topic, using the SubscriptionClient class.

public class MyWorkflow : CodeActivity
{
    protected override void Execute(CodeActivityContext executionContext)
    {
        Entity entity = null;
        var client = SubscriptionClient.CreateFromConnectionString(connectionString, topicName, subscriptionName);

        client.OnMessage(message =>
        {
            entity = JsonConvert.DeserializeObject<Entity>(message.GetBody<string>());
        },
        onMessageOptions: new OnMessageOptions
        {
            AutoComplete = false
        });
    }

The entire solution is available free to download from my GitHub repository [7].

In summary, sending to and receiving a message from a Topic is similar to what we have seen before for a Queue, with the obvious differences that:

  • Instead of using a QueueClient object, we now need a TopicClient for sending messages to the Topic. It is possible to obtain a connection to a Topic in Azure Service Bus by its connection string and name.
  • Within the Topic, we add a Subscription and connect to it by name to subscribe to the specific Topic. Typically, the Subscription name is a reserved name known only to the applications that are allowed to receive messages from this Topic.

References

[1] Integration Design Patterns for Dynamics 365, “XRM and Beyond” blog, Stefano Tempesta
https://community.dynamics.com/enterprise/b/xrmandbeyond/archive/2017/11/02/integration-design-patterns-for-dynamics-365

[2] Message Queueing in Dynamics 365 with Azure Service Bus, “XRM and Beyond” blog, Stefano Tempesta
https://community.dynamics.com/enterprise/b/xrmandbeyond/archive/2017/11/11/message-queueing-in-dynamics-365-with-azure-service-bus

[3] Publish / Subscribe Pattern, WIkipedia
https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern

[4] Azure Service Bus, Microsoft Web Site
https://azure.microsoft.com/en-in/services/service-bus/

[5] Create a Service Bus namespace using the Azure portal, Microsoft Web Site
https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-create-namespace-portal

[6] Get started with Service Bus topics, Microsoft Web Site
https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-how-to-use-topics-subscriptions

[7] Dynamics365 repository, GitHub, Stefano Tempesta
https://github.com/stefanotempesta/dynamics365