Wednesday, 12 October 2011

Delivery Notification in BizTalk Orchestration

         The Biztalk engine has the notion of publishing system level (positive) Acknowledgments (ACK’s) which indicate a successful message transmission and Negative Acknowledgments (NACK’s) which indicate the suspension of a message.

         Orchestrations can use delivery notification to subscribe to these acknowledgments for the messages that they send


         These are extremely powerful and can be used for handling the outcomes of asynchronous operations in the engine.

         For example, consider the scenario whereby an Orchestration transmits a one-way message over HTTP, the Orchestration will publish the message to the Message Box which will route it to the appropriate send port. The transmission of the message is completely decoupled from the Orchestration publishing to the Message Box, so the Orchestration has no notion of whether the transmission actually succeeded or not, instead the Orchestration only knows whether the message was successfully published to the Message Box. Perhaps the back end web server was down which caused the message to be suspended by the Biztalk engine. The Orchestration would have no way to determine the message was never delivered without some higher level message exchange in the form of a business Acknowledgment. Enter ACK’s and NACK’s.

         If an Orchestration port is marked with Delivery Notification = Transmitted, and the Send shape in the Orchestration is in a synchronized scope, the Orchestration will wait until it either receives an ACK or a NACK for the message that was transmitted.


         In the case that the message was successfully transmitted, the engine will publish an ACK ensuring that it is routed back to that Orchestration instance, once the Orchestration receives the ACK it will leave the scope and continue processing.


         If however the transmission failed and the message was suspended, the engine will publish a NACK which again will be routed back to the Orchestration instance, the Orchestration will throw a DeliveryFailureException which can of course be caught and handled as appropriate in the Orchestration.

         The system context property “AckRequired” is written on the message that was sent and it is set to true.  All these settings are happening in the background we need not to worry.

Both ACK’s and NACK’s have the following system context properties promoted which can therefore be used in filter expressions for routing:

         AckType: set to ACK or NACK
         AckID: set to the message ID of the message that this ACK/NACK is for
         AckOwnerID: set to the instance ID that this ACK/NACK is for
         CorrelationToken: flowed from the message to the ACK/NACK
         AckSendPortName: the name of the send port that this message was being sent over
         AckOutboundTransportLocation: the outbound url that this message was being sent over
         AckReceivePortName: the name of the receive port that the message was received over
         AckInboundTransportLocation: the inbound url that the message was received over


         The publication of ACK’s/NACK’s is a little bit special in that if there are no active subscriptions for them, the ACK/NACK will be discarded. The ACK/NACK is published atomically with the appropriate message, for example, the suspension of a message and the publication of its NACK are in the same transaction within the engine, similarly the publication of an ACK is performed in the same transaction as the deletion of the message from the application queue. Further the engine does not suspend ACK’s/NACK’s.


         When a message is sent through a send port with Delivery Notification set to transmitted, a correlation set is initialized.  A correlation token is assigned to the outbound message.  A subscription is started based on this correlation token.  This token is stored in the context property of the ACK/NACK and promoted.  When the ACK/NACK is returned, it is routed back to the calling Orchestration.  You get all this just by setting a little property to “Transmitted”!

No comments:

Post a Comment