You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2008/08/10 13:01:37 UTC

svn commit: r684455 - in /activemq/camel/trunk/components/camel-hl7/src: main/java/org/apache/camel/dataformat/hl7/ test/java/org/apache/camel/component/hl7/ test/java/org/apache/camel/dataformat/hl7/

Author: davsclaus
Date: Sun Aug 10 04:01:36 2008
New Revision: 684455

URL: http://svn.apache.org/viewvc?rev=684455&view=rev
Log:
CAMEL-805: hl7 MSH fields is added as camel message headers for much easier routing etc. Added route unit test with wiki sample.

Added:
    activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7RouteTest.java   (with props)
Modified:
    activemq/camel/trunk/components/camel-hl7/src/main/java/org/apache/camel/dataformat/hl7/HL7DataFormat.java
    activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/dataformat/hl7/HL7DataFormatTest.java

Modified: activemq/camel/trunk/components/camel-hl7/src/main/java/org/apache/camel/dataformat/hl7/HL7DataFormat.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-hl7/src/main/java/org/apache/camel/dataformat/hl7/HL7DataFormat.java?rev=684455&r1=684454&r2=684455&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-hl7/src/main/java/org/apache/camel/dataformat/hl7/HL7DataFormat.java (original)
+++ activemq/camel/trunk/components/camel-hl7/src/main/java/org/apache/camel/dataformat/hl7/HL7DataFormat.java Sun Aug 10 04:01:36 2008
@@ -24,6 +24,7 @@
 import org.apache.camel.util.ExchangeHelper;
 
 import ca.uhn.hl7v2.model.Message;
+import ca.uhn.hl7v2.util.Terser;
 
 /**
  * HL7 DataFormat (supports v2.x of the HL7 protocol).
@@ -31,15 +32,34 @@
  * This data format supports two operations:
  * <ul>
  *   <li>marshal = from Message to String (can be used when returning as response using the HL7 MLLP codec)</li>
- *   <li>unmarshal = from String to Message (can be used when receiving streamed data from the HL7 MLLP codec)</li>
+ *   <li>unmarshal = from String to Message (can be used when receiving streamed data from the HL7 MLLP codec).
+ *   This operation will also enrich the message by adding the MSH fields (MSH-3 to MSH-12) as headers on the message.</li>
  * </ul>
  * <p/>
  * Uses the <a href="http://hl7api.sourceforge.net/index.html">HAPI (HL7 API)</a> for HL7 parsing.
  * <p/>
  * Uses the default PipeParser from the HAPI API. This DataFormat <b>only</b> supports the EDI based HL7
  * messages and not the XML based (their are not commonly used).
+ * <p/>
+ * The <tt>unmarshal</tt> operation adds these MSH fields as headers on the Camel message (key, MSH-field):
+ * <ul>
+ *   <li>hl7.msh.sendingApplication = MSH-3</li>
+ *   <li>hl7.msh.sendingFacility = MSH-4</li>
+ *   <li>hl7.msh.receivingApplication = MSH-5</li>
+ *   <li>hl7.msh.receivingFacility = MSH-6</li>
+ *   <li>hl7.msh.timestamp = MSH-7</li>
+ *   <li>hl7.msh.security = MSH-8</li>
+ *   <li>hl7.msh.messageType = MSH-9-1</li>
+ *   <li>hl7.msh.triggerEvent = MSH-9-2</li>
+ *   <li>hl7.msh.messageControl = MSH-10</li>
+ *   <li>hl7.msh.processingId = MSH-11</li>
+ *   <li>hl7.msh.versionId = MSH-12</li>
+ * </ul>
+ * All headers are String types.
+ * <p/>
+ * The <a href="http://www.hl7.org/Special/IG/final.pdf">HL7 spec</a> can be downloaded as a pdf at
  *
- * @see org.apache.camel.component.mina.HL7MLLPCodec
+ * @see org.apache.camel.component.hl7.HL7MLLPCodec
  */
 public class HL7DataFormat implements DataFormat {
 
@@ -52,6 +72,20 @@
     public Object unmarshal(Exchange exchange, InputStream inputStream) throws Exception {
         String body = ExchangeHelper.convertToMandatoryType(exchange, String.class, inputStream);
         Message message = HL7Converter.toMessage(body);
+
+        // add MSH fields as message out headers
+        Terser terser = new Terser(message);
+        exchange.getOut().setHeader("hl7.msh.sendingApplication", terser.get("MSH-3"));
+        exchange.getOut().setHeader("hl7.msh.sendingFacility", terser.get("MSH-4"));
+        exchange.getOut().setHeader("hl7.msh.receivingApplication", terser.get("MSH-5"));
+        exchange.getOut().setHeader("hl7.msh.receivingFacility", terser.get("MSH-6"));
+        exchange.getOut().setHeader("hl7.msh.timestamp", terser.get("MSH-7"));
+        exchange.getOut().setHeader("hl7.msh.security", terser.get("MSH-8"));
+        exchange.getOut().setHeader("hl7.msh.messageType", terser.get("MSH-9-1"));
+        exchange.getOut().setHeader("hl7.msh.triggerEvent", terser.get("MSH-9-2"));
+        exchange.getOut().setHeader("hl7.msh.messageControl", terser.get("MSH-10"));
+        exchange.getOut().setHeader("hl7.msh.processingId", terser.get("MSH-11"));
+        exchange.getOut().setHeader("hl7.msh.versionId", terser.get("MSH-12"));
         return message;
     }
 

Added: activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7RouteTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7RouteTest.java?rev=684455&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7RouteTest.java (added)
+++ activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7RouteTest.java Sun Aug 10 04:01:36 2008
@@ -0,0 +1,196 @@
+package org.apache.camel.component.hl7;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.hl7.HL7DataFormat;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.spi.DataFormat;
+
+import ca.uhn.hl7v2.model.Message;
+import ca.uhn.hl7v2.model.v24.message.ADR_A19;
+import ca.uhn.hl7v2.model.v24.message.ADT_A01;
+import ca.uhn.hl7v2.model.v24.message.QRY_A19;
+import ca.uhn.hl7v2.model.v24.segment.MSA;
+import ca.uhn.hl7v2.model.v24.segment.MSH;
+import ca.uhn.hl7v2.model.v24.segment.PID;
+import ca.uhn.hl7v2.model.v24.segment.QRD;
+
+/**
+ * Unit test for HL7 routing.
+ */
+public class HL7RouteTest extends ContextTestSupport {
+
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+
+        HL7MLLPCodec codec = new HL7MLLPCodec();
+        codec.setCharset("iso-8859-1");
+
+        jndi.bind("hl7codec", codec);
+
+        MyHL7BusinessLogic logic = new MyHL7BusinessLogic();
+        jndi.bind("hl7service", logic);
+
+        return jndi;
+    }
+
+    public void testSendA19() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:a19");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Message.class);
+
+        String line1 = "MSH|^~\\&|MYSENDER|MYSENDERAPP|MYCLIENT|MYCLIENTAPP|200612211200||QRY^A19|1234|P|2.4";
+        String line2 = "QRD|200612211200|R|I|GetPatient|||1^RD|0101701234|DEM||";
+
+        StringBuffer in = new StringBuffer();
+        in.append(line1);
+        in.append("\n");
+        in.append(line2);
+
+        String out = (String) template.requestBody("mina:tcp://localhost:8888?sync=true&codec=hl7codec", in.toString());
+
+        String[] lines = out.split("\r");
+        assertEquals("MSH|^~\\&|MYSENDER||||200701011539||ADR^A19||||123", lines[0]);
+        assertEquals("MSA|AA|123", lines[1]);
+
+        assertMockEndpointsSatisifed();
+    }
+
+    public void testSendA01() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:a01");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Message.class);
+
+        String line1 = "MSH|^~\\&|MYSENDER|MYSENDERAPP|MYCLIENT|MYCLIENTAPP|200612211200||ADT^A01|1234|P|2.4";
+        String line2 = "PID|||123456||Doe^John";
+
+        StringBuffer in = new StringBuffer();
+        in.append(line1);
+        in.append("\n");
+        in.append(line2);
+
+        String out = (String) template.requestBody("mina:tcp://localhost:8888?sync=true&codec=hl7codec", in.toString());
+        String[] lines = out.split("\r");
+        assertEquals("MSH|^~\\&|MYSENDER||||200701011539||ADT^A01||||123", lines[0]);
+        assertEquals("PID|||123456||Doe^John", lines[1]);
+
+        assertMockEndpointsSatisifed();
+    }
+
+    public void testSendUnknown() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:unknown");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Message.class);
+
+        String line1 = "MSH|^~\\&|MYSENDER|MYSENDERAPP|MYCLIENT|MYCLIENTAPP|200612211200||ADT^A02|1234|P|2.4";
+        String line2 = "PID|||123456||Doe^John";
+
+        StringBuffer in = new StringBuffer();
+        in.append(line1);
+        in.append("\n");
+        in.append(line2);
+
+        template.requestBody("mina:tcp://localhost:8888?sync=true&codec=hl7codec", in.toString());
+
+        assertMockEndpointsSatisifed();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                // START SNIPPET: e1
+                DataFormat hl7 = new HL7DataFormat();
+                // we setup or HL7 listener on port 8888 (using the hl7codec) and in sync mode so we can return a response
+                from("mina:tcp://localhost:8888?sync=true&codec=hl7codec")
+                    // we use the HL7 data format to unmarshal from HL7 stream to the HAPI Message model
+                    // this ensures that the camel message has been enriched with hl7 specific headers to
+                    // make the routing much easier (see below)
+                    .unmarshal(hl7)
+                    // using choice as the content base router
+                    .choice()
+                        // where we choose that A19 queries so go to mock:a19
+                        .when(header("hl7.msh.triggerEvent").isEqualTo("A19"))
+                            .beanRef("hl7service", "handleA19")
+                            .to("mock:a19")
+                        // and A01 should go to mock:a01
+                        .when(header("hl7.msh.triggerEvent").isEqualTo("A01")).to("mock:a01")
+                            .beanRef("hl7service", "handleA01")
+                            .to("mock:a19")
+                        // other types should go to unknown
+                        .otherwise()
+                            .to("mock:unknown")
+                    // end choice block
+                    .end()
+                    // marhsal response back
+                    .marshal(hl7);
+                // END SNIPPET: e1
+            }
+        };
+    }
+
+    public static class MyHL7BusinessLogic {
+
+        public Message handleA19(Message msg) throws Exception {
+            // here you can have your business logic for A19 messages
+            assertTrue(msg instanceof QRY_A19);
+            // just return the same dummy response
+            return createADR19Message();
+        }
+
+        public Message handleA01(Message msg) throws Exception {
+            // here you can have your business logic for A01 messages
+            assertTrue(msg instanceof ADT_A01);
+            // just return the same dummy response
+            return createADT01Message();
+        }
+    }
+
+    private static Message createADR19Message() throws Exception {
+        ADR_A19 adr = new ADR_A19();
+
+        // Populate the MSH Segment
+        MSH mshSegment = adr.getMSH();
+        mshSegment.getFieldSeparator().setValue("|");
+        mshSegment.getEncodingCharacters().setValue("^~\\&");
+        mshSegment.getDateTimeOfMessage().getTimeOfAnEvent().setValue("200701011539");
+        mshSegment.getSendingApplication().getNamespaceID().setValue("MYSENDER");
+        mshSegment.getSequenceNumber().setValue("123");
+        mshSegment.getMessageType().getMessageType().setValue("ADR");
+        mshSegment.getMessageType().getTriggerEvent().setValue("A19");
+
+        // Populate the PID Segment
+        MSA msa = adr.getMSA();
+        msa.getAcknowledgementCode().setValue("AA");
+        msa.getMessageControlID().setValue("123");
+
+        QRD qrd = adr.getQRD();
+        qrd.getQueryDateTime().getTimeOfAnEvent().setValue("20080805120000");
+
+        return adr.getMessage();
+    }
+
+    private static Message createADT01Message() throws Exception {
+        ADT_A01 adt = new ADT_A01();
+
+        // Populate the MSH Segment
+        MSH mshSegment = adt.getMSH();
+        mshSegment.getFieldSeparator().setValue("|");
+        mshSegment.getEncodingCharacters().setValue("^~\\&");
+        mshSegment.getDateTimeOfMessage().getTimeOfAnEvent().setValue("200701011539");
+        mshSegment.getSendingApplication().getNamespaceID().setValue("MYSENDER");
+        mshSegment.getSequenceNumber().setValue("123");
+        mshSegment.getMessageType().getMessageType().setValue("ADT");
+        mshSegment.getMessageType().getTriggerEvent().setValue("A01");
+
+        // Populate the PID Segment
+        PID pid = adt.getPID();
+        pid.getPatientName(0).getFamilyName().getSurname().setValue("Doe");
+        pid.getPatientName(0).getGivenName().setValue("John");
+        pid.getPatientIdentifierList(0).getID().setValue("123456");
+
+        return adt.getMessage();
+    }
+
+}

Propchange: activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7RouteTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7RouteTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/dataformat/hl7/HL7DataFormatTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/dataformat/hl7/HL7DataFormatTest.java?rev=684455&r1=684454&r2=684455&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/dataformat/hl7/HL7DataFormatTest.java (original)
+++ activemq/camel/trunk/components/camel-hl7/src/test/java/org/apache/camel/dataformat/hl7/HL7DataFormatTest.java Sun Aug 10 04:01:36 2008
@@ -52,6 +52,20 @@
         mock.expectedMessageCount(1);
         mock.message(0).body().isInstanceOf(Message.class);
 
+        mock.expectedHeaderReceived("hl7.msh.sendingApplication", "MYSERVER");
+        mock.expectedHeaderReceived("hl7.msh.sendingFacility", "MYSENDERAPP");
+        mock.expectedHeaderReceived("hl7.msh.receivingApplication", "MYCLIENT");
+        mock.expectedHeaderReceived("hl7.msh.receivingFacility", "MYCLIENTAPP");
+        mock.expectedHeaderReceived("hl7.msh.timestamp", "200612211200");
+        mock.expectedHeaderReceived("hl7.msh.security", null);
+        mock.expectedHeaderReceived("hl7.msh.messageType", "QRY");
+        mock.expectedHeaderReceived("hl7.msh.triggerEvent", "A19");
+        mock.expectedHeaderReceived("hl7.msh.messageType", "QRY");
+        mock.expectedHeaderReceived("hl7.msh.triggerEvent", "A19");
+        mock.expectedHeaderReceived("hl7.msh.messageControl", "1234");
+        mock.expectedHeaderReceived("hl7.msh.processingId", "P");
+        mock.expectedHeaderReceived("hl7.msh.versionId", "2.4");
+
         String body = createHL7AsString();
         template.sendBody("direct:unmarshal", body);
 
@@ -59,7 +73,7 @@
 
         Message msg = mock.getExchanges().get(0).getIn().getBody(Message.class);
         assertEquals("2.4", msg.getVersion());
-        QRD qrd = (QRD)msg.get("QRD");
+        QRD qrd = (QRD) msg.get("QRD");
         assertEquals("0101701234", qrd.getWhoSubjectFilter(0).getIDNumber().getValue());
     }
 
@@ -67,14 +81,14 @@
         return new RouteBuilder() {
             public void configure() throws Exception {
                 from("direct:marshal").marshal(hl7).to("mock:marshal");
-                
+
                 from("direct:unmarshal").unmarshal(hl7).to("mock:unmarshal");
             }
         };
     }
 
     private static String createHL7AsString() {
-        String line1 = "MSH|^~\\&|MYSENDER|MYRECEIVER|MYAPPLICATION||200612211200||QRY^A19|1234|P|2.4";
+        String line1 = "MSH|^~\\&|MYSENDER|MYSENDERAPP|MYCLIENT|MYCLIENTAPP|200612211200||QRY^A19|1234|P|2.4";
         String line2 = "QRD|200612211200|R|I|GetPatient|||1^RD|0101701234|DEM||";
 
         StringBuffer body = new StringBuffer();
@@ -107,5 +121,5 @@
 
         return adr.getMessage();
     }
-    
+
 }