I’ve been thinking about a problem for a few weeks and managed to figure it out last week, the requirement was for all messages coming into BizTalk on a particular port to be put through a form of pre-processing implemented by an Orchestration.
This is fine, the Pre-Processing orchestrations subscribes to the message and away we go, however the problem we have then is how to pass the message on to the processing orchestration. If we have one or two orchestrations then we could make use of the Start Orchestration (Asynchronous) or Call Orchestration (Synchronous) shapes, however if we have n Processing Orchestrations you could end up with a large number of if/else branches which identify the type of message and call the relevant orchestration.
This would work fine, but is a maintenance nightmare – and really goes against the BizTalk grain, I tried a number of ideas out but none solved the issue properly, and as ever I ended up going back to my initial idea which I could get working first time round but a fresh set of eyes sorted it.
Basically you want to be able to “post” the message back to the Message Box once you’ve finished the pre-processing (or not perhaps if it’s failed), that way you can then have the other Processing orchestrations pick it up and to the work, this way you don’t have any clunky custom routing in your Pre Processing orchestration – you effectively leveraging the built in routing, which is a good thing.
You can post messages back to the Message Box by creating a Send Port on your Orchestration, and configure the Port Binding as DIRECT and ensure the “Routing between ports will be defined by filter expressions on incoming messages in the Message Box database” radio button is enabled. This takes the messages and pushes it into the Message Box.
Once the message has arrived back into the Message Box you must have Orchestrations waiting for this message via Subscriptions (these are created automatically for you under the covers when you create your Receive ports and specify the message schema your interested in). However these Processing Orchestrations should only process the messages once they’ve been processed by the Pre-Processing Orchestration.
To flag that this work has been done you need a form of “Processing Status” flag in your message, this can be optional so the client doesn’t send it, but the PreProcessing orchestration will add the element to the message once it’s completed its work – As I’m writing this I’m wondering if I could create some form of “Context” variable so I can keep this processing instruction out of the business message – need to think about this.
This “Processing Status” flag should be promoted in the Schema as a Property Field (visible both in BTS and the Transport for routing); this enables us to configure the Processing Orchestrations to only process messages that been processed – you can do this by adding a Filter expression to the Receive shape on your Processing Orchestration.
If you have more than one Processing Orchestration, you’ll need a way of determining which messages go to which Processing Orchestration, I did this by using an already present “Message Type” field, this was promoted and added to the Processing Orchestrations filter expression, ultimately meaning it will only get messages that are pre-processed and have a Message Type == “MessageType1” for example.
This then works fine, except you’ll end up with a recursive loop of messages been received, this (after some head scratching) is because the PreProcessing orchestration subscribes to all messages of a certain schema, once a message has been preprocessed it’s sent back to the MessageBox, at which point the Processing Orchestratoin picks it up AND the PreProcessing orchestration as it matches the schema. To get around this you have to add a Filter expression to the Receive shape on the PreProcessing Orchestration to only retrieve messages that haven’t been PreProcessed (which you can identify by the Processing Status flag).
Phew! – I’ve got a sample to demonstrate this if you can’t work out my ramblings, email me if you want a copy.