I lost quite some time last week trying to figure out why my itinerary services were processed out of order. I created a simple solution based on the A-B-C scenario I wrote about last week. Difference was there that I am using a common data model in the middle, so I need to transform my incoming message to a common model, and my outgoing messages as well, just like the return messages.

So I created an itinerary with the following sequence:

  1. On-Ramp (file)
  2. Message Transform service (to common request)
  3. Message Route service
  4. Off-Ramp extender
  5. Message Transform (to outgoing request)
  6. Off-Ramp (using the itinerary forwarder pipeline)
  7. Message Transform (to common response)
  8. Message Route back
  9. Off-Ramp extender
  10. Message Transform (to imcoming response)
  11. Off-Ramp (file)

If you export this using the default setting, each ESB pipeline will process as much as it can, until it finds an off-ramp service. Depending on some other configurations (two-way,  request response, putting the route on send or receive side, changing the pipelines on the ports) this resulted in different orders or processing, none of which were what I wanted. Mostly, the send pipeline in the first off-ramp would try to do both the send and receive transform in the send. Looking at the exported XML indeed I could not see how the pipeline would ‘guess’ the order that I indicated so carefully in my DSL.

Turns out you need to set the “Export Model” option to strict. The default setting was intenede for compatibility with V1 of the guidance. On the ESB forum, this is what Brian Birdoes says about the export model:

The strict mode supports new features such as stage and the broker.  As mentioned in the docs the stage attribute is output and utilized by the ESB Dispatcher in On-Ramps and Off-Ramps.  Without it, the engine basically processes as many steps as it can until it ends or hits an orchestration or off-ramp step.  With the stage attribute the engine can skip a step and not execute it until the correct pipeline direction.  For example, if you want a transform to run on a request-response (service pass-through) scenario on the Off-Ramp’s receive pipeline, the only way to do this is to have the stage attribute.  This could be a common scenario since the original requestor may not expect the message in the format returned by the service.  In default mode the transform would always execute on the Off-Ramp’s send pipeline.

The broker capability utilizes the id and next id to work correctly.  In V1 the steps are processed sequentially.  For more advanced routing like the broker the engine needed a way to jump to steps.  The pattern was basically to use a linked list within the itinerary.  The outcome of these filters really is to determine the correct id to jump to for the next step.

Simply put, Default mode is for backward compatibility with V1 itineraries.  Strict mode is required for many of the new V2 features.  For itineraries that I build I generally use Strict mode.

So hope I can prevent you from making the same mistake. Make ‘strict’ your new default.