BizTalk: To orchestrate or not to orchestrate
Even people not working with BizTalk has heard about it…In BizTalk there are these great mysterious things called Orchestrations! And….when building applications inside BizTalk we just can’t get enough of those…or can we?
Let me get this straight before really getting into this post…..I love Orchestrations. But having said that, I’m pretty sure that if you ask my colleagues and customers they will all say “Morten la Cour HATES Orchestrations, and always tries to do everything without using them”.
Well that couldn’t be further from the truth. The thing is; I use Orchestrations when they make sense and are useful, but in a lot of integration schemes in BizTalk they just ain’t the best answer.
Now there might not be a 100% right or wrong when it comes to using Orchestrations in your BizTalk application(s). This post will merely reflect how I use Orchestrations and how often.
When reading articles on the Internet, questions and answers on MSDN concerning BizTalk design, and speaking with other “BizTalk dudes”, I would say that too many BizTalk developers are under the impression that you cannot (or should not) do anything in BizTalk without using Orchestrations for doing it.
My approach is always the other way around: Let’s try to make the application without the use of an Orchestration, and let’s introduce them if needed.
Some basic rules:
- No you don’t, necessarily, need an Orchestration for executing a Pipeline. They are primarily meant for the Receive Locations and Send Ports.
- No you don’t, necessarily, need an Orchestration for executing a Map. They are also primarily meant for the Receive- and Send Ports (this is controversial I know!).
- No you don’t need an Orchestration for routing a message from a Receive Port to a Send Port. You do this by using the Filter on the Send Port.
A small example:
So lets say that we are receiving two types of documents in BizTalk (Loan requests and loan cancellations). What BizTalk needs to do is send all Loan requests to our ERP system, and all cancellations to both the ERP system and an Oracle database. We receive both document types in various formats (XML and flat files (FF)), and the ERP system will receive an ERP specific XML structure in a File folder.
So how do we do this? “By building lots and lots of Orchestrations of course!”….NOT.
Here is what I would do:
- Create two canonical Schemas (ILoanRequest and ILoanCancel)
- Create/generate/import Schemas for all of the various formats we are receiving the documents in.
- Create Maps from the incoming Schemas to the canonical Schemas.
- Create/generate/import Schemas for the ERP system and the Oracle tables/procedure.
- Create Maps from: ILoanRequest to the ERP loan Request Schema, ILoanCancel to ERP loan cancel Schema and ILoanCancel to the generated Oracle Schema.
- Create the flat file receive Pipelines needed.
- Create a Receive Port (RP1)
- Create the Receive Locations needed for receiving the various formats from the various source locations, all in RP1.
- Apply all incoming Maps on the Receive Port. (Note: A rule of thumb when designing BizTalk should be only to allow canonical formats to “hit” the MessageBox).
- Create a Send Port for the ERP System, apply the two ERP Maps and set the Filter to: “((ReceivePort == RP1) and (MessageType == ILoanRequest)) or ((ReceivePort == RP1) and (MessageType == ILoanCancel))
- Create a Send Port for Oracle, set the Soap Action Header directly without the use of action operations, apply the Oracle Map and set the Filter to: (ReceivePort == RP1) and (MessageType == ILoanCancel)
That’s it…Why would we create an Orchestration for something that BizTalk does great out-of-the-box?
Data manipulation (somebody sending incorrect XML where we need to append a closing Tag or a flat file that sometimes are missing the last carriage return) should be done using custom Pipeline Components implemented before the message hits the Disassemble stage on the Receive Port. Again: We don’t want to contaminate our MessageBox with badly formatted messages, but only want clean canonical formats inside BizTalk.
A final example where I believe that the Orchestration use is wrong:
You need to manipulate the FILE.ReceivedFileName Context Property, because one Send Port is using the %SourceFileName% macro and needs some custom File name, maybe even extracted from the message. IMO this should always be done in a custom Pipeline Component on the Send Port with the requirement, so that all the logic for that specific Send Port requirement is contained in the Port. If you create an Orchestration for doing the Context manipulation, that Orchestration will eventually submit the message to the MessageBox for sending it to the Send Port, and by that we have exposed some very specific logic that was meant for a single Send Port to potentially all other subscribers.
Now again; don’t think that Orchestrations are a bad thing. They should be used when:
- We have a more complex routing scheme, like waiting for an async response (Correlations).
- We have dependencies between actions (Send Port 2 cannot send the message until we know for sure that Send Port 1 successed) Note: In my example above, the two Send Ports were totally unaware of each other and will execute in different threads.
- Some data enrichment where Solicit-Response Ports are needed for getting the enrichment/translations data.
- Etc etc.
So I guess what I’m trying to say is: Use Orchestrations if needed otherwise don’t, and just take a second or two to think before choosing Add | New Item | BizTalk Orchestration inside your project.