Enabling SessionId on Azure Service Bus Endpoints for Business Events
The Problem
Business Events have become the norm for communicating events happening in Dynamics 365 Finance and Operations to the outside world. One type of business event endpoint is the Azure Service Bus where you can use Topics or Queues.
An external system (such as an Azure Function) can then listen to a Queue or Subscribe to a Topic and perform actions based on the message.
The issue is that the listener system can have many parallel instances and subsequently process many messages at the same time.
What happens if a Business Event generates multiple messages, and these messages need to be processed sequentially?
This blog: Ordered queue processing in Azure Functions with Sessions perfectly describes the solution. Messages that have a Session Id are processed in the order that they are placed in the service bus if:
- The message has a session id
- The Queue or Subscription is Session Enabled
- The listener function is set be Session Enabled
The issue is that the Business Events framework, as of version 10.0.9 at least, does not put a SessionId on the message.
The Solution
Adding a SessionId to a Service Bus Message can be easily added via extensions:
Step 1:
Extend class
BusinessEventsServiceBusAdapterfor chain of command ex:
[ExtensionOf(classstr(BusinessEventsServiceBusAdapter))] public final class ADYBusinessEventsServiceBusAdapter_Extension {}
Step 2:
using Microsoft.ServiceBus.Messaging;
Step 3:
Lastly extend method addProperties()
to add the sessionid based on the SessionId of the current execution:
protected void addProperties(BrokeredMessage _message, BusinessEventsEndpointPayloadContext _context)
{
next addProperties(_message, _context);
_message.SessionId = int2Str(SessionId());
}
The Full Class:
using Microsoft.ServiceBus.Messaging;
[ExtensionOf(classstr(BusinessEventsServiceBusAdapter))]
public final class ADYBusinessEventsServiceBusAdapter_Extension
{
protected void addProperties(BrokeredMessage _message, BusinessEventsEndpointPayloadContext _context)
{
next addProperties(_message, _context);
_message.SessionId = int2Str(SessionId());
}
}
Conclusion
I hope this helps. I look forward to hearing from you if you have found other creative ways to solve this!
Comments
-
Please note, if you are using a Tier 2 environment connected with PowerApps this will no longer work. If you want to reenable it, please upvote my suggestion here: experience.dynamics.com/.../
*This post is locked for comments