Part 1: ESB ToolKit Itineraries
Like many of them, BizTalk Itineraries was a nightmare for me until few months before. I hope these posts will clear all the doubts that any one has with Itineraries. I will be doing a series of blog posts on these.
In this post I would like to give a different view of BizTalk Itineraries. Hope this helps all.
Environment: BizTalk 2010 with Visual Studio 2010
- In my words, Itineraries & their components are like Custom Pipeline Components with several out of box features.
- Itineraries (Out of Box) always work with Dynamic Send Ports. However there is one blog post which shows how to use Itineraries with Static Send Ports.
- Itineraries are not designed for Complex work flows (at least in my world) involving correlations.
- Can be used for 1 way or 2 way calls.
- Itineraries are mainly useful in situations
- When you need to select the map to be applied on a message dynamically (by reading from BRE / UDDI etc.) and would like change the map without re-deploying the BizTalk Application & just by restarting host instances.
- When you need to select the outbound transport (Protocol, Address, Other options like Custom behaviors) details dynamically.
For example – if you would like to apply different custom behaviors on different message going through same send port dynamically, Itineraries are a good choice)
- Everything that can be done with Itineraries can also be done without that.
- Itineraries can work with every adapter – not just WCF / SOAP.
I always try to learn new stuff with examples. In this introductory port, I will start with a simple example.
Read a file from folder, transform it and save it another folder.
- Develop the map & deploy it to an application.
- Create a Receive Port & Location with XML Receive Pipeline. Specify the map as inbound map.
- Create a send port with a filter as the Receive Port Name.
Develop the map & deploy it to an application
• Develop the Itinerary: This is the complex stuff. Step by Step Below.
1. Create a new Itinerary. Click on empty area -> Properties -> Set the below values.
i. Set Require Encryption to False (or give True and give an encryption certificate to encrypt the data in Itinerary)
ii. Set Model Exporter to “Exporter|Database Itinerary Exporter” & Provide Itinerary Database. You can export Itinerary to XML / Database. I prefer database.
iii. Set Is Request Response to False (default)
2. In Admin Console create a new Receive Port & Receive Location (FILE Adapter) pointing to some “In” Folder. Select XML Receive as Pipeline. We will change it later.
3. Drag an On Ramp and set the extender to On-Ramp ESB Extender.
4. Additional properties will now show up. Select the BizTalk Application & Receive Port you just created.
So far, this on-ramp does not do anything. It just resembles your receive port & a starting point in Itinerary diagram.
Once the itinerary is deployed, you can change your receive port name. It does not have any effect anywhere.
5. My next step is to Transform the message.
6. Everything in Itinerary world is called Itinerary Service. Now we have the message. We need to transform it. Drop an Itinerary Service and change Itinerary Service Extender to Messaging. Set the Is Request Response to “False” (Default). “Messaging” hear means that this component will execute as part of the Pipeline.
7. Now this Messaging component (like a pipeline component) should run in some Port. It can be Receive / Send Port. I want this message component to run in my Receive Port (On-Ramp). So Change the Container to use “OnRamp1”
8. It shows two handlers, Receive & Send. OnRamp1, can be used for 1 way & 2 way Receive Ports.
Receive Handler can be imagined as Receive Pipeline of a One way Receive. Send Handler is the Send Pipeline of the Two way Receive
In this example, I am using one way Receive and I want the messaging component to run in the Receive Pipeline of the 1 way receive. So, select Receive Handler.
9. You will notice that, “Itinerary Service 1” is now added to Receive handler.
10. Rename the “Itinerary Service 1” to Transform.
11. So far we selected that we will be doing some messaging operation on the incoming message. But we didn’t specify anywhere that we would like to apply a map to transform the incoming message.
12. So, update the Service Name of the component to “Microsoft.Practices.ESB.Services.Transform”
13. Now we have to specify the name of the transform. This is where “Resolvers” in Itineraries come into picture.
Resolver looks into BRE / UDDI (like a configuration store) / Context / Hardcode and get the map name and provides the name of the map to the Transform Component.
14. Like every other example, I am going to use Static Resolver (Hardcode the map name in Itinerary). Right click the Transform -> Resolver -> New Resolver -> Change the Resolver Implementation to “Static”
15. Since we are going to use this messaging component for Transform, we need to provide the Transform Name. If we are going to use it for Routing, we need to provide Transport details. Select the map from drop down menu.
16. Rename the Resolver to Static.
17. Now we need to route the message to some destination. Please note: Itineraries work with Dynamic Send Port. For dynamic send port to work, we need to promote some context properties like Adapter (FILE / FTP etc.), URL and additional properties.
18. Now we need a component to promote the Transport details. Drag an Itinerary Service and change the Itinerary Service Extender to “Messaging Extender”
19. Rename the component to “Route”
20. Select the Container to OnRamp1 -> Receive Handler. This means that this component will execute in the Receive Port’s Receive Pipeline. Then you will see that “Route” will be under On-Ramps, Receive Handler.
21. Now change the Service name to “Routing” which means that this is going to provide the routing information (Adapter, URL) to the message.
22. So far we specified that, we will have a Routing component and we didn’t specify the actual adapter name or URL. These are provided by your resolver. As said earlier resolver can look into BRE / UDDI (like a configuration store) / Context / Hardcode and get the Adapter Name/URL/Additional properties and provides these transport details to the Component. Component will then promote them to the Message’s context.
For simplicity, I am going to use a Static Resolver (Hardcode the transport details in Itinerary)
23. Right click the Resolver -> Add new resolver -> rename it to Static -> Change the Resolver Implementation to “Static”
24. Provide the Transport Location & Transport Name
25. Recap – So far
i. Received a message (On-Ramp)
ii. Transformed it (Transform -> Microsoft.Practices.ESB.Services.Transform)
iii. Provided Routing Information ( Route -> Microsoft.Practices.ESB.Services.Routing)
All of the above will happen in the Receive Pipeline of the Receive Port (which can also have a send pipeline in case of 2 way receive port).
26. Next step is to publish the message to the Message Box.
27. Drag an Itinerary Service, rename it to publish and change the Service Extender to “Off Ramp Extender” (Although this component does not publish anything, it is an easy way to remember / understand)
28. Now we need to push the message to a send port. This is done by your off ramp. Drag an Off Ramp and change the extender to “Off Ramp Extender”
29. Go to Admin Console, Add a reference to Microsoft.Practices.ESB. This will provide the required promoted properties in the Target Application.
30. Create a new Dynamic Send Port. Leave the Pipeline as Pass Through. Add the Below Filters.
31. Select the newly created port in the Off Ramp. You can see the “Service Name, type and state populated”
33. Done. Join everything using the Connector Tool.
34. Click save. It should not show you any validation errors if you have followed all the steps.
35. Right click the free space -> properties -> change the Itinerary Status to “Deployed”. Change the name of the Itinerary to “SimpleTransformAndRoute “.
36. Right click and select Export Model. Itinerary is now ready to be consumed.
• So far, we developed & deployed a map and constructed Itinerary and deployed it.
• Where is this Itinerary executed? Answer is Pipeline. To use this itinerary, follow below steps.
1. Create a Custom Receive Pipeline to be used in our “Receive Port”.
2. Load the Itinerary. Within your solution you can have multiple Itineraries. You can chose a particular itinerary (using BRE) based on some properties. Or always load one itinerary by hardcoding a name.
3. For simplicity I am going to hard code the Itinerary.
4. Drag ESB Itinerary Selector into the Decode Stage. Fill Itinerary Fact name to Resolver.Itinerary & Connection String to “ITINERARY:\\name=SimpleTransformAndRoute”
5. The above step will load the Itinerary with a name “SimpleTransformAndRoute”
6. Optionally, in the Disassembler stage -> use XML Disassembler.
7. In the validate / resolve party use “ESB Dispatcher”. ESB Dispatcher is the component which will execute the Itinerary’s Receive Handler Components.
Note: When we use this custom pipeline in our Receive Port, this ESB Dispatcher component will execute only the “Receive Handler Components”. In our itinerary, it will execute Transform & Route.
8. Deploy the Pipeline and use it in File Receive Location.
9. Restart host instances and test.
10. When you drop a file you should see an output which is transformed.
Note: If you would like to send messages to multiple locations, you need to use
1. Orchestration extender instead of messaging extender for the “Route”
2. Use the out of box Orchestration Service “Microsoft.Practices.ESB.Services.Routing” as the service name.
3. Remove the offramp & offramp extender. This will call the orchestration which internally loops and finds each resolver and publishes the message with each resolver’s transport properties. (You can refer ESB Labs for more details.)
Hope this gives good idea on Itineraries.