When sending a message in BizTalk to a Send Port, we can use the Delivery Notification property to test whether the message was sent with success. However, this feature is not available if we are using Direct Binding. Recently, in one of our projects, we needed to have the acknowledge in a direct send port. Fortunately, there is someone who wrote the solution. So here is the step by step how to in a visual way.
- First of all, imagine that the there is an orchestration named ProcessMessage, which receives as parameters the message to send, the SendPort to use, and a boolean telling if the send port has delivery notification support.
where the rule is
- If the send port supports delivery notification, we will proceed as usual, catching the DeliveryNotificationException, and Suspending the Orchestration manually
- Now, let's do the hard part, when the send port does not support delivery notification out of the box. In this case, this first thing we must do, is to construct a new XmlDocument message, setting the promoted property of BTS.AckRequired to true, and initializing the BTS.CoorelationToken to new guid.
- Next, we will need to define three correlation types.
- The AckRequiredCorrelationType, which must use the property BTS.AckRequired
- The CorrelationTokenCorrelationType, which must use the property BTS.CorrelationToken
- The MessageCorrelationType, which must use the promoted properties that we will use to filter when the message arrives at the message box. In our case we defined two properties, the Channel and the Direction.
- Then, we define three correlation sets respectively
- Now, we can send the message to the direct send port, initializing the three correlation sets
-
Now we have to add two receive shapes, which must receive from a Receive Por Direct, and both have to follow de correlation set . Why two receive shapes? The first receive has a subscription to receive a copy of the original message. In the second receive shape we receive the message that we are searching, which must be a NACK or an ACK.
And that's it. When there is a NACK, the message we will receive is something like this.
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"
SOAP:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP:Body>
<SOAP:Fault>
<faultcode>Microsoft BizTalk Server Negative Acknowledgment </faultcode>
<faultstring>An error occurred while processing the message, refer to the details section for more information </faultstring>
<faultactor>SFTP://127.0.0.1:22/in/%SourceFileName%</faultactor>
<detail>
<ns0:NACK Type="NACK" xmlns:ns0="http://schema.microsoft.com/BizTalk/2003/NACKMessage.xsd">
<NAckID>{2EE4D577-313F-4840-8FB2-3DC60CF3B68B}</NAckID>
<ErrorCode>0xc0c0167a</ErrorCode>
<ErrorCategory>0</ErrorCategory>
<ErrorDescription>Server error (2): No such file</ErrorDescription>
</ns0:NACK>
</detail>
</SOAP:Fault>
</SOAP:Body>
</SOAP:Envelope>
We built an helper class to extract the ErrorCode the FaultActor to log the exception, send and email, and suspend the orchestration with a reason which can be understood by the BizTalk operator.
Now we have delivery notification in direct send ports.
Until next time.