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();
}
-
+
}