Friday, May 6, 2011

Generic BizTalk Patterns: Message Broker with Dynamic Transformation

This time we'll combine loosely-typed BizTalk messaging concept with dynamic mapping to create generic transformation orchestration. Then we'll add it to the message broker created in the first article to make it even more powerful.
Quite often message dispatching task must be combined with some content adaptation: data mapping, filtering, calculation, etc. Generally, maps are used in BizTalk to achieve that. Since maps are based on source and destination schemas we need to find a way to abstract transformation process from specific schema type to common XmlDocument. What makes it possible is XLANGs transform command. This command accepts output message as argument and uses System.Type of BizTalk map. It allows us dynamically load and apply any map type to any message type.
First, we have to author schemas and maps. I created two input schemas for this project: NewEmployee.xsd, NewOrder.xml; two output schemas: Employee.xsd, Order.xsd; and two corresponding maps: NewEmployee_to_Employee, NewOrder_to_Order.I did some changes in DispatchMessage orchestration to integrate with TransformMessage.odx. I added new message variable msgTransformed which is an output from transformation orchestration. Then I simply added Decide shape to check if transformation required for incoming fie. If yes, we pass map key and input message to the TransformMessage.odx using CallOrchestration shape. If no mapping provided then we simply copy incoming message content to msgTransformed:
Again, to retrieve required map name at runtime, we're going to use the same key-value pairs in the configuration file. In our example we used file name as the key so let's follow this trend. If we're gonna store these keys in the same configuration file we need to modify them to keep unique, for example by adding ".MAP" prefix, i.e. .
To keep things clean and reusable I factored out mapping functionality in separate TransformMessage.odx. orchestration. This orchestration contains three parameters: msgInput, mapKey, out msgOutput which are self explanatory. Notice, all message parameters are of XmlDocument type again. The orchestration id very simple itself. Read fully qualified map name by passed in key and get Type of this map:
mapTypeQName = System.Configuration.ConfigurationManager.AppSettings[mapKey];
mapType = System.Type.GetType(mapTypeQName);
Then in ConstructMessage shape just apply transformation:
transform(msgOutput) = mapType(msgInput);
That's how it looks in designer:
I did some changes in DispatchMessage.odx to integrate with TransformMessage.odx. There is new message variable msgTransformed which is going to be an output from transformation. Also, I added Decide shape to check if mapping required. If yes, then input message and map key is passed into TransformMessage.odx through CallOrchestration shape. Ohterwise, input message simply copied to msgTransformed:

Now, all we need is to make sure there're proper entries in the configuration file:
At some point, configuration file can get quite large, that's why I prefer to keep group of settings in individual configuration files, like destinations.config, maps.config, etc., but that's a topic for another article. So far, we've seen how generic messaging concept can help creating flexible agile BizTalk applications. [Source code is availableThanks Paul Petrov

No comments:

Post a Comment

FEEDJIT Live Traffic Map