Tag Archives: HL7

Test tool MllpSend.exe blocks SQL Server?

1
Filed under BPI
Tagged as ,

I’m using MllpSend for simulating my HL7 ADT system. When I use this tool and wait for an ACK (which I don’t get in a particular test scenario), then my BizTalk Server 2009 Administration Console gives no response (except for this message box ;-) :

image

I’m using the command:

“C:\Program Files\Microsoft BizTalk 2009 Accelerator for HL7\SDK\MLLP Utilities\MllpSend.exe" /I 127.0.0.1 /P 11001 /TWOWAY /F "C:\temp\BizTalk\validHL7Message.txt" /sb 11 /eb 28 /cr 13

Probably it has to do with the Mllp adapter, because the MllpSend is just listening to a socket.

Do you have any idea?

  • Share/Bookmark

BTAHL7 2.X Assembler – strange behavior

0
Filed under BPI
Tagged as ,

I have an HL7 scenario where an ADT-system stub is transmitting a non-valid HL7 message into BizTalk. In BizTalk this message is transformed to a valid HL7 message. The MessageHeader is created as message part in an Orchestration. This MSH looks like:

image

In the first place this looks fine, but my flatfile (created by the pipeline component BTAHL7 2.X Assembler) doesn’t look very well:

image

A new row is created with four spaces. When validating the MSH (Xml variant) against the schema MSH_25_GLO_DEF.xsd I received the message:

error BEC2004: The ‘MSH.13_SequenceNumber’ element is invalid – The value ‘
    ‘ is invalid according to its datatype ‘http://microsoft.com/HealthCare/HL7/2X:NM’ – The Pattern constraint failed.

That makes sense (except for the four spaces :-) ). I didn’t receive any warning or error message in the EventLog, so the header is not validated against the schema in the pipeline component. To fix this, I had to enter a valid number for the sequence number and the output looks like:

image

That’s better.

  • Share/Bookmark

Can the Healthcare take benefits of an ESB?

0
Filed under BPI
Tagged as , ,

In an Enterprise Service Bus you have several services which are loosely connected via several transport mechanisms. The Healthcare uses the standard HL7 for communication between systems, hardware and software. Most of the time MLLP (Minimal Lower Layer Protocol) is used for transport. Because in an ESB architecture systems are loosely coupled, some challenges can arise when messages must be processed sequentially.

For example: consider the next 3 ADT messages: with A01 (patient admit), A02 (patient transfer) and A03 (patient discharge). This is also the sequence/order the messages must be delivered to other systems. You can’t discharge (A03) a patient if the patient is not admitted (A01).

In an Spoke and Hub or Enterprise Application Integration architecture you can connect the systems with each other and make the process sequential. BizTalk Server works asynchronous, so messages are dropped in the MessageBox and processed by a subscriber, which can be an Orchestration or Send port. Example: if the Send port process the second message (A03) faster as the first message (A01) which is used in an Orchestration, then the backend system will return an error (BizTalk processing is also known as: first-in, fastest out). To make this process synchronously BizTalk Server and the MLLP adapter offers some techniques which can be used:

  • Ordered Delivery on the receive port.
  • Listen-shape in an Orchestration together with a correlation set based on the Patient ID.
  • Make use of guaranteed delivery.
  • Wait for ACK/NACK response from the backend, before continuing to the next message.

But how to solve this in an ESB architecture? How to solve this with BizTalk Server ESB Toolkit 2.0?

My answer to this question in the title is: yes it can. How? The ESB Toolkit makes use of BizTalk Server, and is therefore based on rules prescribed by BizTalk. The Itinerary will become just a context property on a message for routing thru the BizTalk system. So you can still make the process synchronously. The Orchestration must use a “request” / “response” mechanism to send the message to the backend system, and wait for an ACK before processing the next message. Some blogs from my this month can help to make this happen, also for a generic solution.

Let me know how you think about this or if you have already experience with HL7, MLLP and the ESB Toolkit.

  • Share/Bookmark

How to dynamically route a message in the ESB to a static port

5
Filed under BPI
Tagged as , ,

What is the problem? Consider the next Itinerary:

image

A message is received on the on-ramp, it is transformed to our HL7 message and after that send to an Orchestration. In the Orchestration the message parts MSHSegment (Header information) and ZSegments are added as part in a multipart message. This Orchestration is a generic process (service as you wish) for extending HL7 messages. After that the multipart messages must be routed to the off-ramp, which must be connected to the MLLP Adapter (from the Microsoft BizTalk Server HL7 Accelerator).

But, the MLLP Adapter is a static adapter and not dynamic. This means that no property schema is available for the MLLP transport settings (and if it was, the MLLP send adapter is not programmed that way). This means that no custom ESB adapter provider can be created and this means that you can’t use the MLLP Adapter in an ESB solution. You can’t use the MLLP Adapter in the Itinerary, because you can only use dynamic ports, and the MLLP Adapter has no possibilities to configure it dynamically (setting context properties for the transport).

I would like to see that Microsoft add some new features to the HL7 Accelerator: use it in a dynamic solution. But till that time, I’ve to use another way to get the benefits of the ESB Toolkit and thus my Itinerary (which can be successfully validated). Below I will describe my solution.

Because the MLLP Adapter can only be used in a static scenario, I created a static send port. For this solution I used an one-way port, and I don’t care for the ACK and NACK right now (will be a next blog). Because I want to use the power of the ESB Toolkit, I added a filter to my port:

image

I’m using my custom send pipeline with the ESB Dispatcher component, HTAHL7 2.x Assembler component (TrailingDelimiterAllowed on True!) and the ESB Itinerary Cache component:

image

As I mentioned above, you can only use dynamic ports in the off-ramp. So I created a dummy send port (or use an existing one). This dummy port I’m using in my itinerary:

image

Because my off-ramp has now the wrong values for Service Name, Service State and Service Type, I’ve to overwrite them so the filter is working correctly. Because I want to change my routing easily I define those settings in UDDI. I created a service ‘sendfilterformedicalsystemx’ and a binding ‘MyMLLPBackendSystem’:

image

Notice that I only added one instance info. I gave the binding a meaningful name so I can use it in the Itinerary:

image

Don’t forget to add a Category to this binding, else you will receive an exception during testing (see a blog from my earlier this month). It really doesn’t matter now what is in here so I added the transporttype:

image

And as latest in UDDI I add only one Instance Info: microsoft-com:esb:runtimeresolution:endpointconfig . This property has the next values:

image

As you can see, this property contains my filter keys and values for my send port. Now my UDDI service is registered (only for filter properties) I can finish my Itinerary. I can fill in the binding key in my UDDIResolver: uddi:esb:systemx

image

To continue the Itinerary in the ESB the right properties must be set in the Orchestration (note: Itinerary processing takes plance in receive- and send pipelines and Orchestrations). Some are basic and described on the site of Microsoft.

First I execute the next statements to retrieve the Itinerary and the current step:

itinerary = new Microsoft.Practices.ESB.Itinerary.SerializableItineraryWrapper();
itineraryStep = new Microsoft.Practices.ESB.Itinerary.SerializableItineraryStepWrapper();

itinerary.Itinerary = Microsoft.Practices.ESB.Itinerary.ItineraryOMFactory.Create(InboundMsg);
itineraryStep.ItineraryStep = itinerary.Itinerary.GetItineraryStep(InboundMsg);

Because the next service in the Itinerary can be used, the next step must be retrieved:

itinerary.Itinerary.Advance(msgPharma, itineraryStep.ItineraryStep);
//itinerary.Itinerary.Write(msgPharma);

For my scenario the Write is not necessary. From the current service (my UDDI Resolver) I can retrieve my endpoint settings from UDDI and put them on the context of my message, so it will be published to my static send MLLP send port:

resolverDict = Microsoft.Practices.ESB.Resolver.ResolverMgr.Resolve(InboundMsg, itineraryStep.ItineraryStep.ResolverCollection[0]);
filterKeys = resolverDict.Item("Resolver.EndpointConfig");

ServiceName = OrchestrationHelper.GetConfigItem(filterKeys, "ServiceName");
ServiceState = OrchestrationHelper.GetConfigItem(filterKeys, "ServiceState");
ServiceType = OrchestrationHelper.GetConfigItem(filterKeys, "ServiceType");

msgPharma(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceName) = ServiceName;
msgPharma(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceState) = ServiceState;
msgPharma(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceType) = ServiceType;

ResolverMgr.Resolve will resolve my UDDI Service and retrieve all the information I defined. The resolver dictionary will contain my EndPointConfig. Now it is just a matter of getting the right values (split a string) and place them on the context.

As you can see it isn’t that difficult, but I’m still not quiet happy with this solution (dynamic MLLP Adapter is preferable). I hope it gave you an idea how to use UDDI, Itineraries and Static Ports. The next challenge will be to send a message to a MLLP system, receive an ACK/NACK (or nothing), and return this information to the calling system: all of course defined in an Itinerary. I hope to blog about this very soon.

If you have questions, remarks or other ideas please contact me. Thanks for reading.

  • Share/Bookmark

Cannot create a custom ESB Adapter for MLLP

0
Filed under BPI
Tagged as , ,

As you have noticed I’m working on HL7 and the ESB Toolkit. It is possible to extend the ESB Adapters with your own adapters by using the BaseAdapterProvider in Microsoft.Practices.ESB.Adapter. To use this it must be possible to dynamically configure your ‘normal’ BizTalk adapter (e.g.: by editing the properties in the propertyschema in an orchestration). The MLLP Adapter for HL7 messaging doesn’t support dynamically configuring from the send port. This is a real pity, because now I’ve to use the MLLP Adapter in a static way. (note: there is no property schema for MLLP on the system, and it is mentioned once on this site).

It would be nice if this will be a feature in the next release (or update) from the HL7 Accelerator.

  • Share/Bookmark

HL7 Serialization error: Trailing delimiter found

0
Filed under BPI
Tagged as ,

I received the next error in the EventLog:

Error # 1
Segment Id: EVN_EventType
Sequence Number: 1
Field Number: 2
Error Number: 207
Error Description: Application internal error
Encoding System: HL7nnnn
Alternate Error Number: Z100
Alternate Error Description: Trailing delimiter found
Alternate Encoding System: HL7-BTA

Error # 2
Segment Id: EVN_EventType
Sequence Number: 1
Field Number: 4
Error Number: 207
Error Description: Application internal error
Encoding System: HL7nnnn
Alternate Error Number: Z100
Alternate Error Description: Trailing delimiter found
Alternate Encoding System: HL7-BTA

etc

This can be easily solved by turning the property TrailingDelimiterAllowed to True (in the send pipeline component BTAHL7 2.X Assembler):

image

Note: if you have defined a party, then you can also configure this in the BTAHL7 Configuration Explorer:

image

  • Share/Bookmark

BTAHL7 2.X Assembler error

0
Filed under BPI
Tagged as ,

I created a send pipeline with the HL7 Accelerator pipeline component for assembling the Xml to flatfile (ignore my naming convention :-) :

A message sent to adapter "FILE" on send port "SendPort2" with URI "C:\temp\BizTalk\Demo (HL7)\_out\%MessageID%.txt" is suspended.
Error details: There was a failure executing the send pipeline: "BTAHL7Schemas.SendPipeline1, BTAHL7 Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9460acab21d7a82a" Source: "BTAHL7 2.X Assembler" Send Port: "SendPort2" URI: "C:\temp\BizTalk\Demo (HL7)\_out\%MessageID%.txt" Reason: Object reference not set to an instance of an object. 
MessageId:  {F75F302D-B8F0-411B-B99D-7FB31DBC6AFD}
InstanceID: {65E819F3-CE2E-4F5A-A4D2-AF16BDB72DF8}

After some searching I find that I was forgotten to set some context properties:

msgOutgoing(BTAHL7Schemas.MSH1) = 124;
msgOutgoing(BTAHL7Schemas.MSH2) = "^~\\&";
msgOutgoing(BTAHL7Schemas.ParseError) = false;
msgOutgoing(BTAHL7Schemas.SegmentDelimiter2Char) = true;
msgOutgoing(BTAHL7Schemas.ZPartPresent) = false;
msgOutgoing(BTAHL7Schemas.MessageEncoding) = 65001;

  • Share/Bookmark

HL7 v3.0 and standardization

1
Filed under BPI
Tagged as , ,

Today a colleague and I went to a potential customer, to discuss our tender. This upcoming project is also going to use HL7 v3.0 schema’s. In the documentation we received I noticed (again) that an organization made their own HL7 v3.0 Xsd implementation. So HL7 v3.0 is described as a standard, but all kinds of dialects arise. That’s a pity. Nothing learned from the past. But that’s my humble opinion.

  • Share/Bookmark

HL7 v3.0 (Dutch version) and BizTalk Server 2009

0
Filed under BPI
Tagged as , ,

I added all the HL7 v3.0 schemas to a BizTalk Server project as-is. When I try to build this project, I run into the next problem:

This schema is an invalid XSD Schema and has the following error(s):
1. Type ‘urn:hl7-org:v3:cs’ is not declared, or is not a simple type.
2. Type ‘urn:hl7-org:v3:cs’ is not declared, or is not a simple type.
3. Type ‘urn:hl7-org:v3:cs’ is not declared, or is not a simple type.
4. Type ‘urn:hl7-org:v3:cs’ is not declared, or is not a simple type.
5. Type ‘urn:hl7-org:v3:cs’ is not declared, or is not a simple type.
etc…

With some help from Nictiz it seems that voc.xsd needs a reference to datatypes.xsd.So:

<xs:include schemaLocation="datatypes.xsd"/>

After adding this line, these errors were gone. I ran into some other reference errors. I’ll blog about this in the near future, so stay tuned…

  • Share/Bookmark

HL7 v3.0 in BizTalk Server

0
Filed under BPI
Tagged as , ,

The latest HL7 version in BizTalk Server 2009 is 2.5. The newest version is v3.0 and is ‘official’ since 2005. Vendors however are not investing on the new standard, because they invested several years ago in the 2.x standard for their software. So it will take a long time before this new standard is adopted by the market.

The Dutch government implemented HL7 v3.0 standard for the Electronic Health Record (AKA ‘Aorta’). This is a subset from the official ‘standard’ and customized for the Dutch Healthcare (so ‘we’ created our own Xsd’s). Lately I was on the Dutch Health and IT event, and on a seminar there was told that the v3.0 (Xsd’s) is difficult to implement, because it will fail for code generation. Also for BizTalk Server 2009 I had problems with this, so more time has to be spend on this.

I hope to inform you very soon on my progress on this.

===============================

(Dutch version)

De laatste HL7 versie in BizTalk Server 2009 is 2.5. Zo ook in BizTalk Server 2009. De nieuwste versie is v3.0 en is ‘officieel’ sinds 2005. Leveranciers zijn echter niet happig op het investeren in deze nieuwe standaard, omdat ze een aantal jaren terug geïnvesteerd hebben in de 2.x standaard voor hun software. Het zal dus nog een tijdje duren voordat deze nieuwe standaard toegepast zal worden op de markt.

De Nederlandse overheid heeft voor het Electronisch Patiënten Dossier (EPD) HL7 v3.0 geïmplementeerd (ook wel bekend als ‘Aorta’). Dit is een subset van de officiële standaard en aangepast op de Nederlandse zorg (‘we’ hebben dus onze eigen Xsd’s gemaakt). Laatst heb ik de Zorg&ICT beurs bezocht, en daar werd tijdens een mini congres verteld dat v3.0 Xsd’s lastig zijn om te implementeren, omdat code generatie hierop niet zal werken. Ik heb dit zelf ook met BizTalk Server 2009 ondervonden. Daar zal dus meer tijd in gestoken moeten worden.

Ik hoop jullie binnenkort verder te informeren over mijn voortgang.

  • Share/Bookmark