Monday, May 20, 2013

Using ESB 2.1 with HL7 messages


Using ESB 2.1 with HL7 messages

I assume at this point you have your HL7 messages and its Message header and other schemas deployed in BizTalk. The scenario discussed here is where you receive a HL7 message and you return an ACK back in response to sender of message and send the message to MSMQ.

Using MLLP adapter Or ESB On-Ramp Services

In both cases, we are going to use Request-Response port because that is most typical HL7 message interchange scenario. As part of the sample I created an itinerary which will route the message to MSMQ based on the type of message. Also I have used BRE to resolve itinerary. The following steps I followed to make it work:

Create a new Receive pipeline

This most important step is to create a Receive Pipeline using ESB pipelines and HL7 Disassembler pipeline because none of the off the shelf ESB pipeline uses HL7 Disassembler component. Design the receive pipeline as shown in diagram below:
There are two other components used in addition to HL7 Disassembler component, ESB Itinerary Select, and ESB Dispatcher. These two components are required for ESB to select Itinerary and then execute the itinerary.

               



Create a new Send pipeline

Similar to receive pipeline, create a send pipeline which we will use on Receive port response side. Notice the two ESB pipeline components ESB and ESB Itinerary Cache which are in addition to HL7 Assembler component.




Create an Itinerary Select Rule

Create Itinerary Select Rules which is used by ESB Itinerary Select component to load the itinerary in message context. Please see a sample of Rule. You can use ESB Vocabulary to check for message type and set the required itinerary name and version.


 
Please note the OR condition is required otherwise your condition will not work. The reason for this is HL7 Disassembler component generates two messages if you have configured ACK and this rule will be executed for each of those messages and if you don’t have condition for ACK message then itinerary selection will fail and you will get an error like:
Reason: Procedure or function 'Itinerary_getitinerary' expects parameter '@name', which was not supplied. 
You might now question why do we have Itinerary Select Pipeline component in receive pipeline after HL7 Disassembler component and create our rule based on some other properties rather than message type?
The question is valid and ideally that’s where we should have it unless you want to use message context properties to create rules, however, this approach with HL7 Disassemble component does not work. The problem is when it generates ACK message it does not populate all the original message context properties and as a result your itinerary selection fails.

Create an End Point Set Rule

In this policy, we set the End point of message based on its message type. Since we want to send it to MSMQ we will set the end point accordingly, see the rule below:

Please note, there is no off-the-shelf MSMQ adapter provider, you can follow this article to create this, it’s very simple or you can use some other end point:

Setup Receive Location and Dynamic Send Port

MLLP Recieve Port

For MLLP adapter, setup a request response MLLP port and location and use your Receive pipeline on Receive pipeline properties as follows:

 
Note you use Itinerary Select Policy here for ESB load itinerary dynamically
There is no specific configuration required for send side.

WCF Generic Receive Port

For WCF Generic On-Ramp, use the ESB.ItineraryServices.Generic.Response.WCF receive location under Microsoft.Practices.ESB application and change it’s receive and send pipeline to your newly created pipelines and configure the receive side as shown above for MLLP.

Dynamic Send Port


Create the Dynamic send port as required by Itinerary offramp, setting filters for servicename, servicestate and servicetype, isrequestresponse.
 

Create Itinerary

Now the last part, Create your itinerary as it’s a simple scenario to route messages, I created a simple itinerary which takes message using On-Ramp one of your receive port (MLLP or OnRamp.Itinerary.Response) resolves the endpoint using our BRE policy using BRE resolver and routes the message accordingly. Now export and deploy your itinerary to Itinerary Db. Make sure you keep the name same as you have it in your Itinerary select rule.

Wednesday, May 1, 2013

BizTalk ESB Toolkit Custom AdapterProvider and Endpoint Configuration

In my current project assignment, I needed MSMQ AdapterProvider for BizTalk ESB Toolkit and as usual before implementing myself I first searched it on bing and found the link of ESB extension which contains not only MSMQ adapter provider but also others adapter providers. The ESB extension is available on codeplex for ESB 2.0. I started browing the source code of the MSMQ adapter provider and realized that due to some issue MSMQ adapter endpoint configuration are not set if we use BaseAdapterProvider implementation and as a result certain methods were re-implemented in MSMQ provider. In order to find the root cause I started writing a new adapter provider for MSMQ. I thought of documenting this here. Following are the steps you need to follow to create the adapter provider, the amount of code you write is nothing, its all implemented in BaseAdapterProvider. Its all about configuration.


  1. Create a new C# project and add a reference to Microsoft.Practices.ESB.Adapter assembly which you can find in Microsoft ESB ToolKit 2.1\bin folder.
  2. Created a new class AdapterProvider and extended it from BaseAdapterProvider. BaseAdapterProvider class is abstract implementation of IAdapterProvider interface and provides all basic functionality.
  3. Override property AdapterName and return adapter name from it e.g. MSMQ
  4. Sign and Build your project and install the assembly in GAC
  5. Register your new adapter provider in ESB.Config file as follows:  adapterProvider name="MSMQ" type="ESB.Adapter.MSMQ.AdapterProvider, ESB.Adapter.MSMQ, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8c284297668e995a" moniker="MSMQ"
  6. At first you think that's it and now you can see your adapter provider in your resolver under the TransportName.
  7. If you just need the default basic properties on your adapter provider e.g. Transport Name, Transport Location then you do not need anything else. However if you click now on Endpoint Configuration option then you get an error as shown below: