Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Acknowledgments (Part 1)
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;
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 o 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.
ACK’s are published when the Messaging Engine successfully transmits a message
over the ‘wire’ and the system context property “AckRequired” is written on the
message that was sent and it is set to true. Providing the port in the Orchestration is
mark as above the context property is automatically written by the engine so thee is
no need to worry about setting it. NACK’s are published when ever the engine
suspends a message. Both ACK’s and NACK’s have the following system context
properties promoted which can therefore be used in filter expressions for routing:
<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>C:\Foo\DeliveryNotification\out\%MessageID%.xml</faultactor
>
<detail>
<ns0:NACK Type="NACK"
xmlns:ns0="http://schema.microsoft.com/BizTalk/2003/NACKMessage.xsd">
<NAckID>{BD6682EE-1741-4856-8CC7-
B2EE36B7874E}</NAckID>
<ErrorCode>0xc0c01c10</ErrorCode>
<ErrorCategory>0</ErrorCategory>
<ErrorDescription>The FILE send adapter cannot
open file C:\Foo\DeliveryNotification\out\{505A3211-9081-4720-827B-
A0DE2BD124FD}.xml for writing.</ErrorDescription>
</ns0:NACK>
</detail>
</SOAP:Fault>
</SOAP:Body>
</SOAP:Envelope>
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.
If the processing of a request-response message exchange pair fails after the receive
adapter has successfully submitted the request message and the message is
subsequently suspended, a NACK will be routed back to the waiting two-way receive
adapter, the receive adapter may then transmit the fault message back to the client.
Of course this means that the client would receive a SOAP Fault, what if the client
doesn’t understand SOAP Faults? For these scenarios the SOAP Fault maybe mapped
changing the format to one that the client is expecting and can handle. Also, once
the initial request message is accepted, a processing failure anywhere in the engine
resulting in the message being suspended will result in the NACK being routed back
to the adapter as its response.
By now you are hopefully starting to appreciate the power of ACK’s and NACK’s,
aside from the Orchestration delivery notification and the request-response scenarios
above there are many scenarios where they are extremely useful. For example,
suppose we have a scenario whereby we use a specific send port to transmit PO’s
over a million dollars while all other PO’s are transmitted using a different send port.
We could use a filter expression on a send port to route any NACK’s published for
messages that are suspended whilst being transmitted on that send port which could
subsequently be processed by some backend system.
Set-up is easy, just unzip the SampleNACK folder and put it on your C: drive. Then, build and deploy the
SampleNACK project. You will need to manually create a Send Port. I set up a File Send Port going to
c:\some_location_that_does_not_exist. Set retries to 0. To run it, drop the StartFile.xml message into
c:\SampleNACK\In. Your NACK will show up in c:\SampleNACK\Out. Do not forget to look inside the
expressions shapes inside the Orchestration for comments. If all else fails, read the ReadMe.txt file.
CRITICAL: Getting at the HTTP error using Delivery Notification will not work for transport type of HTTP or
SOAP due to an “issue”. For more information please see Microsoft KB840008.
Ok, so you ask what is BizTalk doing inside the little Delivery Notification property? Keep in mind this is my
interpretation.
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”! Cool!
Take Away: Delivery Notification is an easy way to catch exceptions as long as you understand how to get
at the error message.