There are a few capabilities advertised in the Microsoft ESB Toolkit for BizTalk Server that I have yet to try out. One thing that seemed possible, although I hadn’t seen demonstrated, was the ability to sequentially call a set of BizTalk maps.
Let’s say that you have maps from “Format1 to Format2” and “Format2 to Format3.” These are already deployed and running live in production. Along comes a new scenario where a message comes in and must be transformed from Format1 to Format3.
There are a few “classic BizTalk” ways to handle this. First, you could apply one map on the receive port and another on the send. Not bad, but this definitely means that this particular receive port can’t be one reused from another solution as this could cause unintended side effects on others. Second, you could write an orchestration that takes the inbound message and applies consecutive maps. This is common, but also requires new bits to be deployed into production. Thirdly, you could write a new map that directly transforms from Format1 to Format3. This also requires new bits, and, may force you to consolidate transformation logic that was unique to each map.
So what’s the ESB way to do it? If we see BizTalk as now just a set of services, we can build up an itinerary that directs the bus to execute a countless set of consecutive maps, each as a distinct service. This is a cool paradigm that allows me to reuse existing content more freely than before by introducing new ways to connect components that weren’t originally chained together.
First, we make sure our existing maps are deployed. In my case, I have two maps that follow the example given above.
I’ve also gone ahead and created a new receive port/location and send port for this demonstration. Note that I could have also added a new receive location to an existing receive port. The ESB service execution is localized to the specific receive location, unlike the “classic BizTalk” model where maps are applied across all of the receive locations. My dynamic send port has a ESB-friendly subscription.
We’ll look at the receive location settings in a moment. First, let’s create the itinerary that makes this magic happen. The initial shape in our itinerary is the On-Ramp. Here, I tell the itinerary to use my new receive port.
Next, I set up a messaging service that the Off-Ramp will use to get its destination URI. In my case, I used a STATIC resolver that exploits the FILE adapter and specifies a valid file path.
Now the games begin. I next added a new messaging service which is used for transformation. I set another STATIC resolver, and chose the “Format1 to Format2” map deployed in my application.
Then we add yet another transformation messaging service, this time telling the STATIC resolver to apply the “Format2 to Format3” map.
Great. Finally, we need an Off-Ramp. We then associate the three previous shapes (messaging service and two transformation services) with this Off-Ramp. Be sure to verify that the order of transformation resolvers is correct in the Off-Ramp. You don’t want to accidentally execute the “Format2 to Format3” map first!
Once our itinerary is connected up and ready to roll, we switch the itinerary status to “deployed” in the itinerary’s property window. This ensures that ESB runtime can find this itinerary when it needs it. To publish the itinerary to the common database, simply chose “Export Model.”
Fantastic. Now let’s make sure our BizTalk messaging components are up to snuff. First, open the FILE receive location and make sure that the ItinerarySelectReceiveXml pipeline is chosen. Then open the pipeline configuration window and set the resolver key and resolver string. The itinerary factkey is usually “Resolver.Itinerary” (which tells the pipeline in which resolver object property to find the XML itinerary content) and the resolver connection string itself is ITINERARY-STATIC:\\name=DoubleMap; The ITINERARY-STATIC directive enables me to do server-side itinerary lookup. It’ll use the name provided to find my itinerary record in the database and yank out the XML content. Note that I used a FILE receive location here. These ESB pipeline components can be used with ANY inbound adapter which really increases the avenues for publishing itinerary-bound messages to the bus.
Finally, go to the dynamic send port and make sure the ItinerarySendPassthrough pipeline is chosen. We need to ensure that the ESB services (like transformation) have a context in which to run. If you only had the standard passthrough pipeline selected here, you’d be subtracting the environment (pipelines) in which the ESB components do much of their work.
That is it. If we drop a “Format1” message in, we get a “Format3” message out. And all of this, POTENTIALLY, without deploying a single new BizTalk component. That said, you may still need to create a new dynamic send port if you don’t already have one reuse, and would probably want to create a new receive location, OR, if the itinerary was being looked up via the business rules engine (BRI resolver), then you could just update the existing business rule. Either way, this is a pretty quick and easy way to do something that wasn’t quick and easy before.