Resolving a Dynamic Send Port in a BizTalk Orchestration using ESB Toolkit 2.0
One of the things I like best about using the ESB Toolkit and Itineraries in particular is that you can cut down on the number of orchestrations that are required in your solutions. But sometimes that’s just not possible–there are still quite a few things that orchestration is good at when it comes to building out your business processes. Fortunately, the ESB toolkit allows you connect orchestrations in an itinerary and to extend some of its capability into your orchestration as well.
For this example, we’re going to make use of an ESB Toolkit 2.0 BRE resolver to tell us how to route a message that will be sent through a dynamic send port from inside an orchestration.
For this to work, your Orchestration must be able to run as part of an itinerary. See my powerpoint presentation in a previous post to get some info on how to do this.
We’ll first start off with our itinerary. The one for our example is extremely simple–we’ll onboard a message, assigning it an itinerary, and then call the orchestration. We’ll use the ESB resolver to assign our dynamic binding properties. Here’s a picture:
In the itinerary designer, note that a resolver is added to the Orchestration service. This resolver will contain the information needed to route the service call that will be made from within the orchestration. For our purposes, we’re using the BRE resolver and a policy called EmployeeService.Routing.
Our business rule is pretty straightforward. If a message is of the correct type and has a specific value in the <location> field, we’ll route it to a specific service. Other rules would be created to handle other possibilities. Here’s a screen shot of our business rule:
At a minimum, the Transport Type and Transport Location must be set, since we’re going to be assigning properties for a dynamic port. A reference to these is stored in the ESB.EndPointInfo vocabulary that is deployed when the ESB toolkit is installed and configured. Further, like in our example, you may also want to set WCF Action as well as Target Namespace if you’re going to call a WCF service.
Inside your orchestration, you’ll need to capture the resolvers to extract this routing information from them. Here, we’re only using the one, so it’s a fairly simple process.
Capture the itinerary from the inbound message’s context. This is done by using an instance of the SerializableItineraryWrapper class in the Microsoft.Practices.ESB.Itinerary assembly. You’ll also need a SerializableItineraryStepWrapper from the same assembly. Below is some sample code that would be added to an expression shape early in the orchestration:
// Retrieve the current itinerary step
itinerary.Itinerary = Microsoft.Practices.ESB.Itinerary.ItineraryOMFactory.Create(InBoundMessage);
itineraryStep.ItineraryStep = itinerary.Itinerary.GetItineraryStep(InBoundMessage);
Next, the resolver will be captured. You’ll need a string, a ResolverDictionary (from Microsoft.Practices.ESB.Resolver) and a ResolverCollection (from Microsoft.Practices.ESB.Itinerary). The following code demonstrates:
//Retrieve the Resolvers associated with the itinerary
resolvers = itineraryStep.ItineraryStep.ResolverCollection;
// Move to retrieve first resolver
resolver = resolvers.Current;
// Pass the resolver configuration to the Resolver mgr for resolution
resolverDictionary = Microsoft.Practices.ESB.Resolver.ResolverMgr.Resolve(InBoundMessage, resolver);
Once we have the ResolverDictionary, we can use it to look up the values that are then set on our service call message and the dynamic send port inside the orchestration. Assign properties to the message and dynamic port as you would any other except retrieving the values from the Resolver Dictionary.
//Set Action and Transport Properties
OutboundMsg(WCF.Action) = resolverDictionary.Item("Resolver.Action");
SvcPort(Microsoft.XLANGs.BaseTypes.Address) = resolverDictionary.Item("Resolver.TransportLocation");
SvcPort(Microsoft.XLANGs.BaseTypes.TransportType) = resolverDictionary.Item("Resolver.TransportType");
The message should now be able to find its way to the correct service when it’s sent from the orchestration.