Overstanding the ESB Itinerary Cache

Overstanding the ESB Itinerary Cache

If you Google-Bing the ESB Itinerary Cache you come across a definition of the likes: “ The itinerary cachingpipeline component for use in Solicit-Response send ports.”

and…

Messages submitted through the ESB itinerary on-ramp can be either a one-way or two-way (request-response) itinerary. To support request-response itineraries, the itinerary mechanism must provide caching for BizTalk dynamic Solicit-Response send ports.

The Itinerary Cache pipeline component persists the itinerary stored in the outbound message and reapplies it to the response message returned to the send port after the service call is complete. This allows the itinerary service to process and execute other services defined after the current service in the itinerary.

The ESB Itinerary Cache pipeline component caches the itinerary during the period that the message is in the Send Transmit pipeline process cycle. The component then retrieves the itinerary and writes it to a BizTalk context property in the inbound message after receipt during the Send Receive process cycle.”

The above definitions are taken directly from MSDN…

There is no need to further explain what this component is used for as the above definitions handle this nicely…

Question: How does this thingy-magiggy work???

Answer:Under the hood, the ESB ItineraryCache is a pipeline component that caches the Itinerary into a cache object defined the the Enterprise Library 4.1 caching application block mechanism upon sending the message, and retrieves the itinerary from the cache upon receiving the the message. Thus this component functions differently upon if the component is executed from a Send pipeline versus a Receive Pipeline.

The Default Mechanism:

By default this caching is done in memory and only caches your itinerary for 5 minutes. The Itinerary is stored and retrieved through the Cache object collection using the CorrelationContextPropertyName property which is set on the pipeline component property sheet. Again, by default the value for this property is the TransmitWorkID context property which can be found as a BizTalk system property.

What is interesting to note here, is that for every itinerary that is transmitted or received, this property must be promoted in order to write or read to the caching collection; along with the fact that the value for this property must be unique within a 5 minute time span, otherwise an non-unique key argument exception will be thrown. Also by default, this property is only promoted by BizTalk when the message is received from a 2-way Receive Port. This property is usually used in conjunction with the IsRequestResponse , the IsSolictResponse, the WasSolicitResponse , and the RouteDirectToTP BizTalk system properties to help correlate 2-way synchronous responses within BizTalk 2 way adapters, orchestrations, and other 2 way patterns. Thus, if you are not using a 2 way receive port, 2-way Receive Adapter, or Correlated 2 way design pattern, these properties, including the TransmitWorkID will not be promoted. This means that by default you won’t be able to use the itinerary caching component.

Another note to take interest in is that when using this caching component, upon transmission (sending) of the message, the component will only write the itinerary into the cache if a few conditions are met:

  1. The ESB determines that the direction of the message flow is a true “SendTransmit”. How the ESB Determines this condition is using two branches. The first branch checks to see if the IsRequestResponse property is true. If so, the ESB continues to check for conditions that do not satisfy the Receive Transmit (the sending side of a 2 way receive port), or Receive Inbound (the receiving side of the 2-way receive port). The Receiving Transmit conditions are simply checked against the Send Port Name being promoted and WasSolicitResponse containing any value; whereas the Receiving Inbound conditions are checked against the Receive Port Name being promoted. If these cases are not true, ESB checks for the IsSolicitResponse = true , which determines that the message direction is a true “SendTransmit”. The second branch checks for the case of IsRequestResponse = false. If the Receive Port Name, and Send Port Names are not promoted, nor is the WasSolicitResponse = true, then the ESB checks for the Send Port ID property to be promoted, in which signals the message direction to be a true “SendTransmit”
  2. BizTalk has properly promoted the BTS.IsRequestResponse or the ESB Itinerary.IsRequestResponse properties to true. This is done again by using a 2 -way Receive Port, or using an Itinerary, Itinerary Routing shape, Off Ramp or Off Ramp extender and setting its IsRequestResponse property to “ true”, and in some cases, all of the shapes in question must have these properties to “true”.

  3. When writing the Itinerary to the cache, the CorrelationContextPropertyName value exists.

  4. When writing the Itinerary to the cache, a duplicate does not already exist for the CorrelationContextPropertyName value.

Upon receiving the message, the same type of checks are also evaluated when trying to retrieve the itinerary from the cache:

  1. When reading from the cache, the CorrelationContextPropertyName value must exist.

  2. The ESB determines that the direction of the message flow is a true “SendInbound”. How the ESB Determines this condition is also using two branches. The first branch is exactly like the “SendTransmit” logic, the only exception being ESB does NOT check for the IsSolicitResponse = true; however does check to see if the Send Port Name is promoted, which determines that the message direction is a true “SendInbound”. The second branch is also similar to the “SendTransmit” with the only exception being the if the Send Port Name is promoted, the message direction is considered a true “SendInbound” .

If you don’t want to be subjected to using 2-way receive ports, or you want to use this Caching mechanism outside the scopes of a 2-way Send port (i.e. a 2-way Asynchronous design pattern), you can use a custom CorrelationContextPropertyName , and Namespace setting, and override the default IsRequestResponse , WasSolicitResponse , and optionally RouteDirectToTP (for sending back to the original caller), system properties. If you’ve read above, you should have a basic overstanding of how the Itinerary Cache works, which should allow you to be dangerous in how to model 2 way Itineraries. See a future post on this…

Extending the Default Caching Mechanism:

Extending the default Itinerary Caching component is as simple as changing the default CorrelationContextPropertyName , or changing the Timeout property, Creating a custom Itinerary Caching component, or even the default Caching manager.

If you don’t want to be subjected to using 2-way receive ports, or you want to use this Caching mechanism outside the scopes of a 2-way Send port (i.e. a 2-way Asynchronous design pattern), you can use a custom CorrelationContextPropertyName , and Namespace setting, and override the default IsRequestResponse , WasSolicitResponse , and optionally RouteDirectToTP (for sending back to the original caller), system properties. If you’ve read above, you should have a basic overstanding of how the Itinerary Cache works, which should allow you to be dangerous in how to model 2 way Itineraries. See a future post on this…