This post describes how to implement a recursive BizTalk orchestration using correlation sets. Using a recursive orchestration came up as a possible solution during one of my previous projects, where a message needed to be resubmitted with a changed status code, so that a new instance of the same orchestration type could pick it up for processing. Next to that, it’s a fun excersize!
You can’t recurse orchestrations using the Call Orchestration or Start Orchestration shapes, because the Orchestration designer just doesn’t let you select the same orchestration type as the one you’re trying to start/call from. I haven’t tried fooling the orchestration editor by editing the .odx file in the xml editor, but I can’t imagine any other result than a compile-time error. From the BizTalk Server 2006 R2 Documentation:
Caution BizTalk Server 2006 does not support recursive orchestrations. If Orchestration A calls or starts Orchestration B, then Orchestration B cannot call or start Orchestration A directly, nor can it call or start any orchestration that directly or indirectly calls Orchestration A.
So assuming we have to rule out the use of the Call/Start orchestration shapes, we have to use another way to do the correlation. In come the correlation sets. The BizTalk documentation uses orchestration A and B in examples for orchestration communication (as in the example above), often assuming that orchestrations A and B are of different types. In the example below, I have used a standard way of correlation where orchestration A’s type equals orchestration B’s type:
It breaks down into 3 parts, where each part has two branches. The first part is where the request message gets received, the second part is where the child orchestration gets ‘called’ (using direct bound ports and correlation sets), and the third part is where the response gets sent. The correlation type used consists of only a guid (ctInstandeId), and the orchestration uses two correlation sets, both based on that one correlation type (csInstanceId1, csInstanceId2).
The key point is to understand what using correlation sets does to the message context and subscriptions. The BizTalk documentation is more accurate (ms-help://MS.BTS.2006/BTS06CoreDocs/html/528dcd6c-d364-4bb8-8deb-cd4a0791867f.htm), but in my own words:
- An initializing receive creates ‘Exists’ subscription criteria on all correlation type properties. In the example orchestration, we create this ‘Exists’ subscription manually by using the filter expression on the RCVRECREQ receive shape.
- An initializing send promotes the correlation type properties to the message context as promoted properties. In the example orchestration, we do this on the SNDRECREQ send shape.
- A following receive creates an instance subscription based on the correlation type properties. In the example orchestration, we do this on the RCVRECRESP receive shape.
- A following send promotes the correlation type properties to the message context as promoted properties. In the example orchestration, we don’t use this.
This is what the subscriptions look like.
RCVRECREQ (activation subscription):
http://schemas.microsoft.com/BizTalk/2003/system-properties.MessageType == http://RecursiveOrch.Request#Request And http://RecursiveOrch.Properties.InstanceId Exists
RCVRECRESP (instance subscription):
http://RecursiveOrch.Properties.InstanceId == c1c86b9c-4d01-4176-9a19-3908f46fe053 And http://schemas.microsoft.com/BizTalk/2003/system-properties.MessageType == http://RecursiveOrch.Response#Response
00000000 0.00000000  RCVINITREQ, id=1, count=0. 00000001 0.00035004  SNDRECREQ, id=1, count=1. 00000002 0.24793179  RCVRECREQ, id=1, count=1. 00000003 0.25474858  SNDRECREQ, id=1, count=2. 00000004 0.75415730  RCVRECREQ, id=1, count=2. 00000005 0.75665259  SNDRECREQ, id=1, count=3. 00000006 1.26953459  RCVRECREQ, id=1, count=3. 00000007 1.27350295  RecursiveOrch - Recursion terminated for request, id=1, count=3. 00000008 1.92181325  SNDRECRESP, id=1, count=3. 00000009 2.32890010  RCVRECRESP, id=1, count=3. 00000010 2.33078957  SNDRECRESP, id=1, count=3. 00000011 2.53953433  RCVRECRESP, id=1, count=3. 00000012 2.54006386  SNDRECRESP, id=1, count=3. 00000013 3.03803825  RCVRECRESP, id=1, count=3. 00000014 3.04450655  SNDFINALRESP, id=1, count=3.
You can download the solution here.