diff --git a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java index 680c4245ee688..7b94b130cfee5 100644 --- a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java +++ b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7Converter.java @@ -16,13 +16,13 @@ */ package org.apache.camel.component.hl7; +import org.apache.camel.Converter; + import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.parser.Parser; import ca.uhn.hl7v2.parser.PipeParser; -import org.apache.camel.Converter; - /** * HL7 converters. */ @@ -32,7 +32,7 @@ public final class HL7Converter { private HL7Converter() { // Helper class } - + @Converter public static String toString(Message message) throws HL7Exception { return encode(message, new PipeParser()); @@ -43,11 +43,11 @@ public static Message toMessage(String body) throws HL7Exception { return parse(body, new PipeParser()); } - static Message parse(String body, Parser parser) throws HL7Exception { + public static Message parse(String body, Parser parser) throws HL7Exception { return parser.parse(body); } - static String encode(Message message, Parser parser) throws HL7Exception { + public static String encode(Message message, Parser parser) throws HL7Exception { return parser.encode(message); } diff --git a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java index 391facc887af1..8afdbd4c2638c 100644 --- a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java +++ b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7DataFormat.java @@ -16,21 +16,6 @@ */ package org.apache.camel.component.hl7; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - -import ca.uhn.hl7v2.model.Message; -import ca.uhn.hl7v2.parser.GenericParser; -import ca.uhn.hl7v2.parser.Parser; -import ca.uhn.hl7v2.util.Terser; -import ca.uhn.hl7v2.validation.impl.NoValidation; - -import org.apache.camel.Exchange; -import org.apache.camel.spi.DataFormat; -import org.apache.camel.util.ExchangeHelper; - import static org.apache.camel.component.hl7.HL7Constants.HL7_MESSAGE_CONTROL; import static org.apache.camel.component.hl7.HL7Constants.HL7_MESSAGE_TYPE; import static org.apache.camel.component.hl7.HL7Constants.HL7_PROCESSING_ID; @@ -43,6 +28,21 @@ import static org.apache.camel.component.hl7.HL7Constants.HL7_TRIGGER_EVENT; import static org.apache.camel.component.hl7.HL7Constants.HL7_VERSION_ID; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.spi.DataFormat; +import org.apache.camel.util.ExchangeHelper; + +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.parser.GenericParser; +import ca.uhn.hl7v2.parser.Parser; +import ca.uhn.hl7v2.util.Terser; +import ca.uhn.hl7v2.validation.impl.NoValidation; + /** * HL7 DataFormat (supports v2.x of the HL7 protocol). *

@@ -79,60 +79,60 @@ */ public class HL7DataFormat implements DataFormat { - private static final Map HEADER_MAP = new HashMap(); - - private Parser parser = new GenericParser(); - - static { - HEADER_MAP.put(HL7_SENDING_APPLICATION, "MSH-3"); - HEADER_MAP.put(HL7_SENDING_FACILITY, "MSH-4"); - HEADER_MAP.put(HL7_RECEIVING_APPLICATION, "MSH-5"); - HEADER_MAP.put(HL7_RECEIVING_FACILITY, "MSH-6"); - HEADER_MAP.put(HL7_TIMESTAMP, "MSH-7"); - HEADER_MAP.put(HL7_SECURITY, "MSH-8"); - HEADER_MAP.put(HL7_MESSAGE_TYPE, "MSH-9-1"); - HEADER_MAP.put(HL7_TRIGGER_EVENT, "MSH-9-2"); - HEADER_MAP.put(HL7_MESSAGE_CONTROL, "MSH-10"); - HEADER_MAP.put(HL7_PROCESSING_ID, "MSH-11"); - HEADER_MAP.put(HL7_VERSION_ID, "MSH-12"); - } - - public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws Exception { - Message message = ExchangeHelper.convertToMandatoryType(exchange, Message.class, body); - String encoded = HL7Converter.encode(message, parser); - outputStream.write(encoded.getBytes()); - } - - public Object unmarshal(Exchange exchange, InputStream inputStream) throws Exception { - String body = ExchangeHelper.convertToMandatoryType(exchange, String.class, inputStream); - Message message = HL7Converter.parse(body, parser); - - // add MSH fields as message out headers - Terser terser = new Terser(message); - for (Map.Entry entry : HEADER_MAP.entrySet()) { - exchange.getOut().setHeader(entry.getKey(), terser.get(entry.getValue())); - } - return message; - } - - public boolean isValidate() { - return parser.getValidationContext() instanceof NoValidation; - } - - public void setValidate(boolean validate) { - if (!validate) { - parser.setValidationContext(new NoValidation()); - } - } - - public Parser getParser() { - return parser; - } - - public void setParser(Parser parser) { - this.parser = parser; - } - - + private static final Map HEADER_MAP = new HashMap(); + + private Parser parser = new GenericParser(); + + static { + HEADER_MAP.put(HL7_SENDING_APPLICATION, "MSH-3"); + HEADER_MAP.put(HL7_SENDING_FACILITY, "MSH-4"); + HEADER_MAP.put(HL7_RECEIVING_APPLICATION, "MSH-5"); + HEADER_MAP.put(HL7_RECEIVING_FACILITY, "MSH-6"); + HEADER_MAP.put(HL7_TIMESTAMP, "MSH-7"); + HEADER_MAP.put(HL7_SECURITY, "MSH-8"); + HEADER_MAP.put(HL7_MESSAGE_TYPE, "MSH-9-1"); + HEADER_MAP.put(HL7_TRIGGER_EVENT, "MSH-9-2"); + HEADER_MAP.put(HL7_MESSAGE_CONTROL, "MSH-10"); + HEADER_MAP.put(HL7_PROCESSING_ID, "MSH-11"); + HEADER_MAP.put(HL7_VERSION_ID, "MSH-12"); + } + + public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws Exception { + Message message = ExchangeHelper.convertToMandatoryType(exchange, Message.class, body); + String encoded = HL7Converter.encode(message, parser); + String charsetName = exchange.getProperty(Exchange.CHARSET_NAME, String.class); + outputStream.write(charsetName != null ? encoded.getBytes(charsetName) : encoded.getBytes()); + } + + public Object unmarshal(Exchange exchange, InputStream inputStream) throws Exception { + String body = ExchangeHelper.convertToMandatoryType(exchange, String.class, inputStream); + Message message = HL7Converter.parse(body, parser); + + // add MSH fields as message out headers + Terser terser = new Terser(message); + for (Map.Entry entry : HEADER_MAP.entrySet()) { + exchange.getOut().setHeader(entry.getKey(), terser.get(entry.getValue())); + } + return message; + } + + public boolean isValidate() { + return parser.getValidationContext() instanceof NoValidation; + } + + public void setValidate(boolean validate) { + if (!validate) { + parser.setValidationContext(new NoValidation()); + } + } + + public Parser getParser() { + return parser; + } + + public void setParser(Parser parser) { + this.parser = parser; + } + } diff --git a/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7DataFormatTest.java b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7DataFormatTest.java index 950f08629a4a8..53d7eb4b123c7 100644 --- a/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7DataFormatTest.java +++ b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7DataFormatTest.java @@ -16,108 +16,189 @@ */ package org.apache.camel.component.hl7; -import ca.uhn.hl7v2.model.Message; -import ca.uhn.hl7v2.model.v24.message.ADR_A19; -import ca.uhn.hl7v2.model.v24.segment.MSA; -import ca.uhn.hl7v2.model.v24.segment.MSH; -import ca.uhn.hl7v2.model.v24.segment.QRD; +import static org.apache.camel.Exchange.CHARSET_NAME; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.junit4.CamelTestSupport; import org.junit.Test; +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.model.v24.message.ADR_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 DataFormat. */ public class HL7DataFormatTest extends CamelTestSupport { - @Test - public void testMarshal() throws Exception { - MockEndpoint mock = getMockEndpoint("mock:marshal"); - mock.expectedMessageCount(1); - mock.message(0).body().isInstanceOf(byte[].class); - mock.message(0).body(String.class).contains("MSA|AA|123"); - mock.message(0).body(String.class).contains("QRD|20080805120000"); - - Message message = createHL7AsMessage(); - template.sendBody("direct:marshal", message); - - assertMockEndpointsSatisfied(); - } - - @Test - public void testUnmarshal() throws Exception { - MockEndpoint mock = getMockEndpoint("mock:unmarshal"); - mock.expectedMessageCount(1); - mock.message(0).body().isInstanceOf(Message.class); - - mock.expectedHeaderReceived(HL7Constants.HL7_SENDING_APPLICATION, "MYSENDER"); - mock.expectedHeaderReceived(HL7Constants.HL7_SENDING_FACILITY, "MYSENDERAPP"); - mock.expectedHeaderReceived(HL7Constants.HL7_RECEIVING_APPLICATION, "MYCLIENT"); - mock.expectedHeaderReceived(HL7Constants.HL7_RECEIVING_FACILITY, "MYCLIENTAPP"); - mock.expectedHeaderReceived(HL7Constants.HL7_TIMESTAMP, "200612211200"); - mock.expectedHeaderReceived(HL7Constants.HL7_SECURITY, null); - mock.expectedHeaderReceived(HL7Constants.HL7_MESSAGE_TYPE, "QRY"); - mock.expectedHeaderReceived(HL7Constants.HL7_TRIGGER_EVENT, "A19"); - mock.expectedHeaderReceived(HL7Constants.HL7_MESSAGE_CONTROL, "1234"); - mock.expectedHeaderReceived(HL7Constants.HL7_PROCESSING_ID, "P"); - mock.expectedHeaderReceived(HL7Constants.HL7_VERSION_ID, "2.4"); - - String body = createHL7AsString(); - template.sendBody("direct:unmarshal", body); - - assertMockEndpointsSatisfied(); - - Message msg = mock.getExchanges().get(0).getIn().getBody(Message.class); - assertEquals("2.4", msg.getVersion()); - QRD qrd = (QRD) msg.get("QRD"); - assertEquals("0101701234", qrd.getWhoSubjectFilter(0).getIDNumber().getValue()); - } - - protected RouteBuilder createRouteBuilder() throws Exception { - 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|MYSENDERAPP|MYCLIENT|MYCLIENTAPP|200612211200||QRY^A19|1234|P|2.4"; - String line2 = "QRD|200612211200|R|I|GetPatient|||1^RD|0101701234|DEM||"; - - StringBuilder body = new StringBuilder(); - body.append(line1); - body.append("\r"); - body.append(line2); - return body.toString(); - } - - private static Message createHL7AsMessage() 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(); - } + @Test + public void testMarshal() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:marshal"); + mock.expectedMessageCount(1); + mock.message(0).body().isInstanceOf(byte[].class); + mock.message(0).body(String.class).contains("MSA|AA|123"); + mock.message(0).body(String.class).contains("QRD|20080805120000"); + + Message message = createHL7AsMessage(); + template.sendBody("direct:marshal", message); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testMarshalISO8859() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:marshal"); + mock.expectedMessageCount(1); + mock.message(0).body().isInstanceOf(byte[].class); + mock.message(0).body(String.class).contains("MSA|AA|123"); + mock.message(0).body(String.class).contains("QRD|20080805120000"); + mock.message(0).body(String.class).not().contains("ÀÈÌÒÙŐ"); + + Message message = createHL7AsMessage(); + template.sendBodyAndProperty("direct:marshal", message, CHARSET_NAME, "ISO-8859-1"); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testMarshalUTF8() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:marshal"); + mock.expectedMessageCount(1); + mock.message(0).body().isInstanceOf(byte[].class); + mock.message(0).body(String.class).contains("MSA|AA|123"); + mock.message(0).body(String.class).contains("QRD|20080805120000"); + mock.message(0).body(String.class).contains("ÀÈÌÒÙŐ"); + + Message message = createHL7AsMessage(); + template.sendBodyAndProperty("direct:marshal", message, CHARSET_NAME, "UTF-8"); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testUnmarshal() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:unmarshal"); + mock.expectedMessageCount(1); + mock.message(0).body().isInstanceOf(Message.class); + + mock.expectedHeaderReceived(HL7Constants.HL7_SENDING_APPLICATION, "MYSENDER"); + mock.expectedHeaderReceived(HL7Constants.HL7_SENDING_FACILITY, "MYSENDERAPP"); + mock.expectedHeaderReceived(HL7Constants.HL7_RECEIVING_APPLICATION, "MYCLIENT"); + mock.expectedHeaderReceived(HL7Constants.HL7_RECEIVING_FACILITY, "MYCLIENTAPP"); + mock.expectedHeaderReceived(HL7Constants.HL7_TIMESTAMP, "200612211200"); + mock.expectedHeaderReceived(HL7Constants.HL7_SECURITY, null); + mock.expectedHeaderReceived(HL7Constants.HL7_MESSAGE_TYPE, "QRY"); + mock.expectedHeaderReceived(HL7Constants.HL7_TRIGGER_EVENT, "A19"); + mock.expectedHeaderReceived(HL7Constants.HL7_MESSAGE_CONTROL, "1234"); + mock.expectedHeaderReceived(HL7Constants.HL7_PROCESSING_ID, "P"); + mock.expectedHeaderReceived(HL7Constants.HL7_VERSION_ID, "2.4"); + + String body = createHL7AsString(); + template.sendBody("direct:unmarshal", body); + + assertMockEndpointsSatisfied(); + + Message msg = mock.getExchanges().get(0).getIn().getBody(Message.class); + assertEquals("2.4", msg.getVersion()); + QRD qrd = (QRD) msg.get("QRD"); + assertEquals("0101701234", qrd.getWhoSubjectFilter(0).getIDNumber().getValue()); + } + + @Test + public void testUnmarshalUTF8() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:unmarshal"); + mock.expectedMessageCount(1); + mock.message(0).body().isInstanceOf(Message.class); + + String body = createHL7AsStringWithNotISO8859Char(); + template.sendBodyAndProperty("direct:unmarshal", body, CHARSET_NAME, "UTF-8"); + + assertMockEndpointsSatisfied(); + + Message msg = mock.getExchanges().get(0).getIn().getBody(Message.class); + assertEquals("2.4", msg.getVersion()); + PID pid = (PID) msg.get("PID"); + assertEquals("ÀÈÌÒÙŐ", pid.getPid5_PatientName(0).getXpn1_FamilyName().getFn1_Surname().getValue()); + } + + @Test + public void testUnmarshalISO8859() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:unmarshal"); + mock.expectedMessageCount(1); + mock.message(0).body().isInstanceOf(Message.class); + + String body = createHL7AsStringWithNotISO8859Char(); + template.sendBodyAndProperty("direct:unmarshal", body, CHARSET_NAME, "ISO-8859-1"); + + assertMockEndpointsSatisfied(); + + Message msg = mock.getExchanges().get(0).getIn().getBody(Message.class); + assertEquals("2.4", msg.getVersion()); + PID pid = (PID) msg.get("PID"); + assertNotEquals("ÀÈÌÒÙŐ", pid.getPid5_PatientName(0).getXpn1_FamilyName().getFn1_Surname().getValue()); + } + + protected RouteBuilder createRouteBuilder() throws Exception { + 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|MYSENDERAPP|MYCLIENT|MYCLIENTAPP|200612211200||QRY^A19|1234|P|2.4"; + String line2 = "QRD|200612211200|R|I|GetPatient|||1^RD|0101701234|DEM||"; + + StringBuilder body = new StringBuilder(); + body.append(line1); + body.append("\r"); + body.append(line2); + return body.toString(); + } + + private static String createHL7AsStringWithNotISO8859Char() { + String line1 = "MSH|^~\\&|EPIC|EPICADT|SMS|SMSADT|199912271408|CHARRIS|ADT^A04|1817457|D|2.4"; + String line2 = "PID||0493575^^^2^ID 1|454721||ÀÈÌÒÙŐ^JOHN^^^^|ÀÈÌÒÙŐ^JOHN^^^^|19480203|M||B|254 MYSTREET AVE^^MYTOWN^OH^44123^USA||(216)123-4567|||M|NON|400003403~1129086|NK1||ROE^MARIE^^^^|SPO||(216)123-4567||EC|||||||||||||||||||||||||||"; + String line3 = "PV1||O|168 ~219~C~PMA^^^^^^^^^||||277^ALLEN MYLASTNAME^BONNIE^^^^|||||||||| ||2688684|||||||||||||||||||||||||199912271408||||||002376853"; + + StringBuilder body = new StringBuilder(); + body.append(line1); + body.append("\r"); + body.append(line2); + body.append("\r"); + body.append(line3); + return body.toString(); + } + + private static Message createHL7AsMessage() 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"); + msa.getMsa3_TextMessage().setValue("ÀÈÌÒÙŐ"); + + QRD qrd = adr.getQRD(); + qrd.getQueryDateTime().getTimeOfAnEvent().setValue("20080805120000"); + + return adr.getMessage(); + } }