Skip to main content

Elements of a Routing Production

In the ENSDEMO namespace, Ensemble provides a simple HL7 Version 3.0 message routing production in the package Demo.HL7v3. The production diagram for this example is shown below.

generated description: routing production

Business Services

Each business service in an HL7 Version 3.0 message routing production receives an incoming data stream from a specific source application. The business service generates an XML document from the incoming data stream. It extracts from this document the information it needs to route and transform the message.

The sample classes Demo.HL7v3.Service.FileInOpens in a new tab and Demo.HL7v3.Service.SOAPInOpens in a new tab are business services. You can find these classes in the ENSDEMO namespace. Demo.HL7v3.Service.FileInOpens in a new tab is shown below.

Class Demo.HL7v3.Service.FileIn Extends Ens.BusinessService
{

Parameter ADAPTER = "EnsLib.File.InboundAdapter";

Method OnProcessInput(pInput As %FileCharacterStream,
                      pOutput As Ens.Response) As %Status
{
  Set $ZTrap = "OnProcessInputET"

  Set tStatus =
  ##class(%XML.XPATH.Document).CreateFromStream(pInput, .tDocument)
  Set tStatus = tDocument.EvaluateExpression("/*", "name()", .tResults)
  Set tStatus = pInput.Rewind()

  If (tResults.Count() > 0) Set tRoot = tResults.GetAt(1).Value
  Else  Set tRoot = "<errorNoRootElement>"

  Set tRequest = ##class(Demo.HL7v3.Message).%New()
  Set tRequest.Name    = tRoot
  Set tRequest.DocType  = ""
  Set tRequest.Source     = pInput.Attributes("Filename")
  Do tRequest.Content.CopyFrom(pInput)

  Set tStatus =
  ..SendRequestSync("Route and Transform Message", tRequest, .tResponse)

  Quit $$$OK

OnProcessInputET
  Set $ZTrap = ""

  Quit $$$ERROR($$$GeneralError,"Error in OnProcessInput():  "_$ZError)
}

}

Upon encountering an input file, Demo.HL7v3.Service.FileInOpens in a new tab calls the CreateFromStream() method to create an XML document from the incoming character stream.

This document is an object of type %XML.XPATH.DocumentOpens in a new tab. As such, it has a method called EvaluateExpression(). The business service calls this method to evaluate the XPath context ("/*") and expression ("name()"). The context selects the initial nodeset from the document and the expression further filters the node set. If EvaluateExpression() succeeds, it returns a list of results (.tResult) which can be queried for their types and values. The business service does this, accepting the name of the first XML element in the input stream as the message Name.

Tip:

For full details of XPath syntax and usage, see the web site https://www.w3.org/TR/xpathOpens in a new tab

Demo.HL7v3.Service.FileInOpens in a new tab completes creation of an Ensemble message by recording the name of the input file and copying the message data into an appropriate stream object.

The business service sends the message to its designated routing process, using the configured name of the routing process in a call to SendRequestSync().

You can create a business service host class for an HL7 Version 3.0 message routing production by copying and customizing the sample classes in the Demo.HL7v3 package, or by creating your own subclass of Ens.BusinessServiceOpens in a new tab. After you create the class, add the business service to the production.

The Management Portal provides a New Business Service wizard with an HL7 option. This option creates an HL7 Version 2.x business service that is not suitable for use with HL7 Version 3.0.

Messages

In designing an HL7 Version 3.0 message routing production, it can be convenient to define a message type that is suitable for both requests and responses. This is the case in the sample production in the Demo.HL7v3 package in the ENSDEMO namespace.

The sample message class Demo.HL7v3.MessageOpens in a new tab contains the minimum properties required to achieve the goal of routing, transforming, and time-stamping an HL7 Version 3.0 message that originated in a external file. Demo.HL7v3.MessageOpens in a new tab is shown below.

Class Demo.HL7v3.Message Extends (%Persistent, %XML.Adaptor)
{
Property Content As %GlobalCharacterStream;

Property Name As %String;

Property DocType As %String;

Property Source As %String;

}

Content is the data stream.

Name and DocType are properties expected by the HL7 routing process; both must be present in the message class. In the sample production, Name is the property used to route the message.

Source is used in the business operation to provide the timestamp. It varies depending on which business service originated the message data. It identifies either the input file, or the name of the web service that relayed the data into the SOAP business service.

You can create a message class for an HL7 Version 3.0 message routing production by copying and customizing the sample class Demo.HL7v3.MessageOpens in a new tab, or by creating your own class.

Routing Processes

The routing process for an HL7 Version 3.0 message routing production validates the XML document that it receives from its associated business service. If validation fails, the routing process sends the XML document to its bad message handler. If validation succeeds, the routing process invokes its routing rule set to determine what to do with the XML document.

Upon finding a matching rule, the routing process carries out the instructions for that rule. It may invoke a data transformation class Transform() method or send an Ensemble message to a business operation (or both, in sequence).

The sample class Demo.HL7v3.MsgRouter.RoutingEngineOpens in a new tab has an empty OnValidate() method. You can find Demo.HL7v3.MsgRouter.RoutingEngineOpens in a new tab in the ENSDEMO namespace. If you copy this class to create a routing process class for an HL7 Version 3.0 message routing production, you should put meaningful code into the OnValidate() method.

Demo.HL7v3.MsgRouter.RoutingEngineOpens in a new tab performs a simple, implicit validation test by calling CreateFromStream() to convert the stream Contents of the message into an XML document. If this call fails, the routing process invokes its bad message handler. Otherwise, it invokes its routing rule set.

You can create a routing process class for an HL7 Version 3.0 message routing production by copying and customizing the sample class Demo.HL7v3.MsgRouter.RoutingEngineOpens in a new tab, or by creating your own subclass of EnsLib.MsgRouter.RoutingEngineOpens in a new tab. After you create the class, add the routing process to the production.

The Management Portal provides a New Business Process wizard with an HL7 Message Router option. This option creates an HL7 Version 2.x routing process that is not suitable for use with HL7 Version 3.0.

Routing Rule Sets

A routing rule set provides the logic that determines:

  • Where to send the message

  • Whether to transform, and if so, how to transform the message before sending it

For details, see “Defining Routing Rule Sets for HL7” in the Ensemble HL7v2 Development Guide.

Everything about routing rule sets for HL7 Version 3.0 message routing productions is the same as for HL7 Version 2.x, except that for Version 3.0 the Message Class is whatever class the business service sends to the routing process. In the sample code, this class is Demo.HL7v3.MessageOpens in a new tab. You can find it in the ENSDEMO namespace.

The full name of the sample routing rule set in the Demo.HL7v3 package is Demo.HL7v3.Rule.RouteAndTransformOpens in a new tab. The following figure shows this rule definition as seen in the Ensemble Rule Editor page. (To access this page in the Management Portal, click Ensemble > Build > Business Rules.)

generated description: routing rule editor

This rule definition takes different actions depending on the type of message. The Demo.HL7v3 sample expects each message to be one of two types, MFMT_IN002101 or QUPA_IN101103. Both of the sample business services contain code that determines the type of the incoming message based on the structure of the data stream. The business services then place the appropriate string in the Name property of the Demo.HL7v3.MessageOpens in a new tab that they send to the routing process. This is how the message type, MFMT_IN002101 or QUPA_IN101103, becomes available to the routing rule set.

The sample data that you use to run the sample production must actually contain HL7 Version 3.0 messages of type MFMT_IN002101 or QUPA_IN101103, or no messages will be routed. A sample of each type of message is provided as an appendix to this book. If you are viewing the book online, you can copy the text of each appendix into a file and use that as your sample data to run the Demo.HL7v3.Production.InterfaceEngineOpens in a new tab production.

Data Transformations

Data transformations for HL7 Version 3.0 message routing productions do not use the Ensemble Data Transformation Language (DTL). Data transformations for HL7 Version 3.0 messages use XPath and XSLT to create a valid XML document.

The sample data transformation classes Demo.HL7v3.Transformation.MFMTIN002101Opens in a new tab and Demo.HL7v3.Transformation.QUPAIN101103Opens in a new tab provide detailed code and comments. You can find these classes in the ENSDEMO namespace. An overview of the Transform() method follows:

  1. Get the message structure from an XData block contained in the class.

  2. Get a stream of XSL from an XData block contained in the class.

  3. Create an XML document from the input stream.

  4. Set up the XSL transformation. For each operation in the transformation:

    • Use an XPath expression to obtain data to be transformed.

    • Transform the data, for example using ObjectScript string functions.

    • Bind this transformation to an XSL parameter.

  5. Write the transformed data stream into the target message.

You can create a data transformation for an HL7 Version 3.0 message routing production by copying and customizing the sample classes Demo.HL7v3.Transformation.MFMTIN00210 or Demo.HL7v3.Transformation.QUPAIN101103Opens in a new tab, or by creating your own subclass of Ens.DataTransformOpens in a new tab, providing appropriate XData sections, and calling appropriate methods from classes in the %XML package.

To deploy a data transformation within your production, name it as the Transform action for a rule in a routing rule set.

Transforming an Attribute

The previously mentioned examples show how to transform elements in an HL7 V 3.0 message. To modify the MFMTIN00210 example so that it also transforms an attribute, add the following to the Transform() method:

// Get creation date/time, change to the current date, and bind to XSL parameter
Set tStatus=tDocument.EvaluateExpression("//MFMT_IN002101/creationTime", "@value",.tResults)
Set tParams("creationTime") = "'" _ $ZD($H,3) _ " " _ $P(tResults.GetAt(1).Value," ",2) _"'"

And add the following to the XData that defines the XSL transform:

<xsl:param name="creationTime"/>
<xsl:template match="//MFMT_IN002101/creationTime/@value">
 <xsl:attribute name="value">
  <xsl:value-of select="$creationTime"/>
 </xsl:attribute>
</xsl:template> 

Business Operations

Each business operation in an HL7 Version 3.0 message routing production uses the routing properties of the Ensemble message to direct the new XML document to the target application as an outgoing data stream.

The sample classes Demo.HL7v3.Service.FileOut and Demo.HL7v3.Service.SOAPOut are business operations. You can find these classes in the ENSDEMO namespace. Demo.HL7v3.Service.FileOut is shown below.

Class Demo.HL7v3.Operation.FileOut Extends Ens.BusinessOperation
{

Parameter ADAPTER = "EnsLib.File.OutboundAdapter";

Parameter INVOCATION = "Queue";

Parameter SETTINGS = "Filename";

Property Filename As %String;

Method WriteToFile(pRequest As Demo.HL7v3.Message,
                   Output pResponse As Ens.Response) As %Status
{
  Do pRequest.Content.Rewind()
  Set tFilename=
  ..Adapter.CreateTimestamp(##class(%File).GetFilename(
     $Piece(pRequest.Source, $Char(13))),
     ..Filename)

   Set $ZTrap = "WriteToFileET"
  Set tStatus = ..Adapter.PutStream(tFilename, pRequest.Content)

  Quit $$$OK

WriteToFileET
  Set $ZTrap = ""

  Quit $$$ERROR($$$GeneralError,"WriteToFile("_tFilename_"):  "_$ZError)
}

XData MessageMap
{
<MapItems>
  <MapItem MessageType="Demo.HL7v3.Message">
    <Method>WriteToFile</Method>
  </MapItem>
</MapItems>
}

}

Demo.HL7v3.Service.FileOut uses the Source property from the Demo.HL7v3.MessageOpens in a new tab to create a time stamp for the outgoing file.

You can create a business operation host class for an HL7 Version 3.0 message routing production by copying and customizing the sample classes from the Demo.HL7v3 package in the ENSDEMO namespace, or by creating your own subclass of Ens.BusinessOperationOpens in a new tab. After you create the class, add the business operation to the production.

The Management Portal provides a New Business Operation wizard with an HL7 option. This option creates an HL7 Version 2.x business operation that is not suitable for use with HL7 Version 3.0.

Bad Message Handlers

A bad message handler is simply a business operation that does something useful with any HL7 Version 3.0 message that fails validation by the routing process. Often, a bad message handler saves the bad message to a file, using a timestamp and a file naming convention to make the source of the bad message easy to identify. The sample class Demo.HL7v3.MsgRouter.RoutingEngineOpens in a new tab (in the ENSDEMO namespace) has a BadMessageHandler property that appears in the configuration display on the Production Configuration page so that the user can specify the name of a configured business operation. The sample production leaves this field blank, so bad messages are simply ignored.

Alert Handlers

Alert handling for HL7 Version 3.0 message routing productions is the same as for HL7 Version 2.x. The following references provide detailed information:

FeedbackOpens in a new tab