Geeks With Blogs
Nigel Parker BizTalk 2004 Developer - Auckland, New Zealand,

I was working on a project this week where we were invoicing for orders that we may or may not have received electronically. If we received the order electronically I wanted to correlate with the process that received the order and close off that process. If the order was not received electronically I want to attempt to correlate on the order number but ignore any correlation failure that may occur.

 

Easy you say? Well I was lucky enough to find this post http://sphear.demon.nl/weblogs/carlo/archive/2004/04/10/731.aspx (Thanks Carlo Poli). I downloaded the sample and it worked great. I then attempted to apply it to my project that looked a little like this:

 

 

 

The key being that I had one initialising correlation receive message “rmsgPurchaseOrder” and two following correlation receive messages “rmsgSupplierMessage” and “rmsgDuplicatePurchaseOrder”. “rmsgDuplicatePurchaseOrder” had the same message schema as “rmsgPurchaseOrder” but “rmsgSupplierMessage” had a different message schema linked through a promoted property “Order_Num” that was shared across the two messages.

 

When I separated the process into a separate orchestration using a direct port to handle the supplier message correlation, my solution would no longer compile see below:

 

 

The two errors I got were as below:

in a sequential convoy receive the ports must be identical.

in a sequential convoy receive the correlations must be identical unless the port is marked for OrderedDelivery.

 

The first one I understand because the two operations are no longer contained within the same port… but the second error had me a bit baffled as all the ports in the process included the direct ones were marked as OrderedDelivery.

 

The solution…

 

 

I needed to create a second correlation type “corMatchOrderNumSupMsg” that had the same correlation property as the first correlation type “Schemas.OrderNo”. I then had to initialise both correlation sets (‘on different receive messages’ see explaination in the conclusion below) and have the “rmsgDuplicatePurchaseOrder “ receive message follow the first correlation type “corOrderNum “ and the direct port I’d created to listen for supplier messages “rmsgSupplierMessage“ to follow the other correlation type “corMatchOrderNumSupMsg”.

 

This method worked a treat… but I was left wanting to know a bit more about what was going on here... so I did a bit of research on the subject…

 

From reading the BizTalk help on “Sequential Correlated Receives” (“ms-help://BTS_2004/SDK/htm/ebiz_prog_orch_zomc.htm”). I noticed two interesting points…

·                 The port for a receive that requires sequential convoy processing must be the same as the port for the receive initializing the convoy set. Cross-port convoys are not supported.

·                 Message types for a particular receive that require convoy processing must match the message type for the receive initializing the convoy set, unless the receive statement is operating on an Ordered Delivery port.

In addition to this in the BizTalk  help on “Working with Convoy Scenarios” (“ms-help://BTS_2004/SDK/htm/ebiz_prog_orch_iljk.htm”). I noticed another two interesting points…

·                 Concurrent and sequential convoys can coexist in an orchestration, but they cannot use any shared correlation sets.

·                 You cannot initialize two or more correlation sets with one receive to be used in separate convoys. For example, if receive r1 initializes correlation sets c1 and c2, receive r2 follows c1, and receive r3 follows c2, then the orchestration engine will not treat these as convoys. It is a valid convoy scenario if both r2 and r3 follow both c1 and c2, both follow c1 only, or both follow c2 only.

My initial example worked because there was a single correlation that was being treated as a “Sequential” convoy. Once I broke this into two separate receives ports, one being a direct port listening for supplier updates I in affect changed the patterns to having one “Concurrent” and one “Sequential” convoy in the same orchestration.

At this point the reasons for the errors became clear. I had two different conveys sharing one correlation set! Breaks rule number one above.

I was also attempting to initialise the correlation set on the same receive port. In my example I over came the second restriction by initialising my “corMatchOrderNumSupMsg” correlation when I sent out a Received Acknowledgement in the first step of the orchestration.

After all this I was getting routing failures messages created in HAT when messages failed to correlate (http://sphear.demon.nl/weblogs/carlo/archive/2004/04/20/770.aspx). I too have written a C# windows service that monitors for a series of conditions and surrounding Service Instances and performs appropriate actions. See below a snippet from the configuration file I created for the service. I think this is a good approach as it a fairly generic way of handling routing failures.

 

--

       ServiceClass

       {

              Orchestration,

              Tracking,

              Messaging,

              MSMQT,

              Other,

              IsolatedAdapter,

              RoutingFailureReport

       }

 

       ServiceInstanceStatus

       {

              ReadyToRun,

              Active,

              SuspendedResumable,

              Dehydrated,

              CompletedWithDiscardedMessages,

              SuspendedNotResumable,

              InBreakpoint,

       }

 

       ServiceInstanceAction

       {

              Resume,

              Suspend,

              Terminate

       }

       -->

 

  <actionServiceInstancesToMonitor>

       <checkConditions>

              <checkCondition

                     hostName="BizTalkServerApplication"

                     schemaName="Company.Client.Schemas.schSupplierMessageXML"

                     schemaAssemblyName="Company.Client.Schemas"

                     bizTalkHostRoot="root\MicrosoftBizTalkServer"

                     messageType="http://targetnamespace#rootnode"

                     serviceClass="RoutingFailureReport"

                     serviceInstanceStatus="SuspendedNotResumable"

                     serviceInstanceAction="Terminate" />

              <checkCondition

                     hostName="BizTalkServerApplication"

                     schemaName=" Company.Client.Schemas.schInvoiceTriggerXML"

                     schemaAssemblyName="Company.Client.Schemas"

                     bizTalkHostRoot="root\MicrosoftBizTalkServer"

                     messageType=" http://targetnamespace#rootnode"

                     serviceClass="RoutingFailureReport"

                     serviceInstanceStatus="SuspendedNotResumable"

                     serviceInstanceAction="Terminate" />

       </checkConditions>

  </actionServiceInstancesToMonitor>

 

Another approach would be use a product like MOM 2005 (http://www.microsoft.com/mom/) and subscribe to the routing failure event and then write a simple script to clear the routing messages when they occur.

More information on convoy processing in BizTalk can be found at:

http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20041014BizTalkEL/manifest.xml

Posted on Saturday, November 6, 2004 12:07 AM BizTalk Tips & Tricks | Back to top


Comments on this post: BizTalk messages that might correlate (or might not) and how this is related to “Concurrent” and “Sequential” convoys…

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Nigel Parker | Powered by: GeeksWithBlogs.net