Friday, April 04, 2008
One of the things Microsoft introduced with BizTalk 2006 is failed message routing. Prior to this, developers had to come up with custom solutions to remove failed messages from the messagebox to prevent them from accumulating. Now all one has to do is enable routing for failed messages on the receive ports and create an orchestration to consume these failed messages. When a message comes into the messagebox, BizTalk tries to find a matching subscription based on the context properties of the message. If no matching subscriptions are found, the message is suspended. To demonstrate this we can create a receive location and drop in a XML file. Checking in the Group Hub we find the following:

These messages can be handled if failed message routing is enabled for the receive port that handled the message.

The other half of this solution is to create an orchestration to handle the failed messages. For this example we’ll write the failed messages out to the file system. The receive port is directly bound to the messagebox.

The properties of the message in this orchestration are shown below. Rather than specifying a schema for the message type, declaring a value of XmlDocument makes this orchestration flexible enough to consume all types of failed messages rather than restricting it to a particular schema.

The receive shape in this orchestration has a filter expression to limit it to messages with an ErrorType context property value of FailedMessage. There are a number of context properties that are included for all messages.

With this in place, messages that do not match any subscriptions are consumed by the orchestration and written to disk.
In one of the previous examples that talked about convoys within BizTalk, I had the following orchestration:In one of the previous examples that talked about convoys within BizTalk, I had the following orchestration:

The purpose of this map within the orchestration was to receive a message that followed the Claim schema, transform it into the ClaimValidation schema and set the Status to CONTRACT VALIDATION COMPLETED. It’ll see a bit contrived, but we can move the map so that it’s called on the receive port if required so that we’ll always be dealing with a ClaimValidation message inside of the orchestration.
We’ll also use the map from the previous example which determined the Pass/Fail Validation response based on whether or not the ClaimID is odd.

Within the orchestration we’ll still construct an outbound message and set the Status.

Since the inbound map (which we’ll discuss in a bit) happens before the orchestration runs, the receive port deals only with messages of the ClaimValidation schema.

After the orchestration is deployed, we can specify the inbound map on the physical receive port in BizTalk Administration Console.

With this in place, we can drop messages of the Claim and ClaimValidation schemas into the receive locations. If the message is of the Claim schema, it will first be transformed into the ClaimValidation schema, and if it’s of the ClaimValidation schema it will pass directly through to the orchestration.
\Source code for this example can be found here.
Taking decoupled orchestrations one step further, we’ll use it to do multiple concurrent tasks and then associate the output from those tasks. We’ll borrow our scenario for this example from the health care industry. When a claim is submitted, there are multiple types of validation that happens (and by no means is this a comprehensive list): is this a valid contract? Is the hospital part of the network? Is the procedure performed covered? We’ll take two of those for our scenario.

With decoupled orchestrations we can create an orchestration for each one of the steps above. In this case, both the Validate Hospital Information and Validate Contract Information receive shapes will have filters that are looking for messages matching the Claim schema with a status of CLAIM RECEIVED.
It’s worth discussing the messaging engine of BizTalk here. When an orchestration is deployed to the BizTalk database, it is necessary to enlist the orchestration and then start it. Enlisting the orchestration defines the subscription for the orchestration and BizTalk can form a queue of messages for the orchestration to consume. When the orchestration is started, it will then begin consuming the messages that are in the queue. When a message is received, BizTalk examines the message’s context properties and sees what subscriptions match them. Each orchestration with a subscription that matches the context properties, so when the ReceiveClaim orchestration writes a message to the messagebox with a Status of CLAIM RECEIVED, the message is placed in the queue for the ValidateHospitalInformation orchestration and in the queue for the ValidateContractInformation orchestration.
Rather than generating the same output for each claim, I’ve made the output for each of the Validation orchestrations dependant on the ClaimID: if the ClaimID is even, the validation will fail; if the ClaimID is odd, the validation will pass. I’m doing this logic in a map within the orchestration (I’ll use this as an example for inbound maps in a later post). The map takes in a message of the Claim and generates a message of the ClaimValidation schema. The validation orchestrations update the Status according to what was performed (CONTRACT VALIDATION COMPLETED for ValidateContractInformation and HOSPITAL VALIDATION COMPLETED for ValidateHospitalInformation) and proceed to send the outbound messages to the messagebox.
The ProcessClaim orchestration requires input from both the ValidateContractInformation and ValidateHospitalInformation orchestrations and needs to ensure that the results it uses are for the same claim. To accomplish this, we define a correlation set based on ValidationClaimID.

This is what ensures that BizTalk consumes both the contract and hospital validation results for claim 123 together rather than the contract validation result from claim 234 and the hospital validation result from claim 345. Correlation sets can only be based on promoted properties, so the ClaimValidation schema has two promoted properties – ValidationClaimID and ValidationStatus. The ValidationStatus is used for the filter condition of the two receive shapes shown below, and also note that both receive shapes reference the ClaimIDCorrelationSet.

Below are the properties for the two receive shapes.


Another benefit of the correlation set we defined is that should one of the validation orchestrations take longer than the other to run, the output from the completed validation orchestration will be held until it can be paired with the output from the other validation orchestration, though this will not affect other instances of the messages or orchestrations. To demonstrate this, I’ve stopped the ValidateContractInformation orchestration but the ValidateHospitalInformation is still running. After submitting a test claim, we can view the messages.

The output from the ValidateHospitalInformation orchestration is waiting to be paired with output from the ValidateContractInformation orchestration. When the ValidateContractInformation is started and the suspended instance is resumed, the ProcessClaim orchestration will consume both messages and output the result to the file system.
Source code for this example can be found here.