ESB Toolkit: Executing Multiple Maps In Sequence

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.

Technorati Tags: ,

Author: Richard Seroter

Richard Seroter is Director of Developer Relations and Outbound Product Management at Google Cloud. He’s also an instructor at Pluralsight, a frequent public speaker, the author of multiple books on software design and development, and a former editor plus former 12-time Microsoft MVP for cloud. As Director of Developer Relations and Outbound Product Management, Richard leads an organization of Google Cloud developer advocates, engineers, platform builders, and outbound product managers that help customers find success in their cloud journey. Richard maintains a regularly updated blog on topics of architecture and solution design and can be found on Twitter as @rseroter.

9 thoughts

  1. Great post as always Richard!

    Can you confirm to me that the actual place where the two maps are applied in this scenario is in the ItinerarySelectReceiveXml pipeline in the receive location?


  2. Hey Thiago,

    Both maps are actually associated with the off-ramp, and from my tests, are executed in the SEND pipeline. When I was using the standard pass-through pipeline, the messaging service was getting executed (maybe because it was the first thing and got read at the on-ramp layer?), but no maps. Not until I used the itinerary send pipeline did the transforms get applied.

  3. Hi Richard,

    Thanks for clarifying, I see now the two maps associated with the off-ramp. I was thinking for canonical message scenario where two maps are needed to get the canonical message you could haev both transformations as the on-ramp receive handlers.

    1. Yes, I thought about putting them both in the receiver as well. But, assuming we wanted to get the original message onto the bus for other consumers to grab, applying maps on the sender would have the least chance of negative impact on existing subscribers.

  4. Yup, I see your point. It depends on the solution being build pretty much. It’s great to have the option though, and how easy it would be to change it around if required.

  5. this is really awesome! i’ve needed to do a similar thing countless times before an have always gone the “orchestration with multiple sequential maps” route before.

    this is so much better!


  6. Hi Richard,

    First of all I would like to thank you for this very helpful article, I actually use this as a guide with what I’m doing now.

    I have a flatfile which I transform to a xml format (like a canonical format) and then transform it again to another format that I use to route thru wcf-custom (sql).

    Now here come’s the problem, during testing I noticed in sql profiler that instead of 1 sql sp insert there are actually 4! 2 of the exec sp are identical and has null arguments while the two which has the correct arguments but also duplicated.

    do you have any idea what could be the reason why this is happening? I already check the map and it’s only producing 1 format. pls note that im using BRE resolvers for resolving the two maps and the endpoint config.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.