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 2016/04/14 07:43:26 UTC
[3/5] camel git commit: CAMEL-9876 - fix IndexOutOfBounds exception
when MSH-18 isn't in message
CAMEL-9876 - fix IndexOutOfBounds exception when MSH-18 isn't in message
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/57f9f49c
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/57f9f49c
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/57f9f49c
Branch: refs/heads/camel-2.17.x
Commit: 57f9f49c2292aeecf0c38c7005a1ffea9d91bd8f
Parents: f043e47
Author: Quinn Stevenson <qu...@pronoia-solutions.com>
Authored: Wed Apr 13 11:40:22 2016 -0600
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Apr 14 07:42:47 2016 +0200
----------------------------------------------------------------------
.../component/mllp/MllpTcpServerConsumer.java | 113 ++++++++++--------
...llpTcpServerConsumerAcknowledgementTest.java | 114 +++++++++++++++++++
2 files changed, 181 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/57f9f49c/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java
index 95a2d22..c025f80 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpServerConsumer.java
@@ -543,7 +543,6 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
private void populateHl7DataHeaders(Exchange exchange, Message message, byte[] hl7MessageBytes) {
// Find the end of the MSH and indexes of the fields in the MSH to populate message headers
final byte fieldSeparator = hl7MessageBytes[3];
- final byte componentSeparator = hl7MessageBytes[4];
int endOfMSH = -1;
List<Integer> fieldSeparatorIndexes = new ArrayList<>(10); // We need at least 10 fields to create the acknowledgment
@@ -551,11 +550,16 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
if (fieldSeparator == hl7MessageBytes[i]) {
fieldSeparatorIndexes.add(i);
} else if (SEGMENT_DELIMITER == hl7MessageBytes[i]) {
+ // If the MSH Segment doesn't have a trailing field separator, add one so the field can be extracted into a header
+ if (fieldSeparator != hl7MessageBytes[i - 1]) {
+ fieldSeparatorIndexes.add(i);
+ }
endOfMSH = i;
break;
}
}
+ String messageBodyForDebugging = new String(hl7MessageBytes);
if (-1 == endOfMSH) {
// TODO: May want to throw some sort of an Exception here
log.error("Population of message headers failed - unable to find the end of the MSH segment");
@@ -563,54 +567,71 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
log.debug("Populating the message headers");
Charset charset = Charset.forName(IOHelper.getCharsetName(exchange));
- // MSH-3
- message.setHeader(MLLP_SENDING_APPLICATION, new String(hl7MessageBytes, fieldSeparatorIndexes.get(1) + 1,
- fieldSeparatorIndexes.get(2) - fieldSeparatorIndexes.get(1) - 1, charset));
- // MSH-4
- message.setHeader(MLLP_SENDING_FACILITY, new String(hl7MessageBytes, fieldSeparatorIndexes.get(2) + 1,
- fieldSeparatorIndexes.get(3) - fieldSeparatorIndexes.get(2) - 1, charset));
- // MSH-5
- message.setHeader(MLLP_RECEIVING_APPLICATION, new String(hl7MessageBytes, fieldSeparatorIndexes.get(3) + 1,
- fieldSeparatorIndexes.get(4) - fieldSeparatorIndexes.get(3) - 1,
- charset));
- // MSH-6
- message.setHeader(MLLP_RECEIVING_FACILITY, new String(hl7MessageBytes, fieldSeparatorIndexes.get(4) + 1,
- fieldSeparatorIndexes.get(5) - fieldSeparatorIndexes.get(4) - 1,
- charset));
- // MSH-7
- message.setHeader(MLLP_TIMESTAMP, new String(hl7MessageBytes, fieldSeparatorIndexes.get(5) + 1,
- fieldSeparatorIndexes.get(6) - fieldSeparatorIndexes.get(5) - 1, charset));
- // MSH-8
- message.setHeader(MLLP_SECURITY, new String(hl7MessageBytes, fieldSeparatorIndexes.get(6) + 1,
- fieldSeparatorIndexes.get(7) - fieldSeparatorIndexes.get(6) - 1, charset));
- // MSH-9
- message.setHeader(MLLP_MESSAGE_TYPE, new String(hl7MessageBytes, fieldSeparatorIndexes.get(7) + 1,
- fieldSeparatorIndexes.get(8) - fieldSeparatorIndexes.get(7) - 1, charset));
- // MSH-10
- message.setHeader(MLLP_MESSAGE_CONTROL, new String(hl7MessageBytes, fieldSeparatorIndexes.get(8) + 1,
- fieldSeparatorIndexes.get(9) - fieldSeparatorIndexes.get(8) - 1, charset));
- // MSH-11
- message.setHeader(MLLP_PROCESSING_ID, new String(hl7MessageBytes, fieldSeparatorIndexes.get(9) + 1,
- fieldSeparatorIndexes.get(10) - fieldSeparatorIndexes.get(9) - 1, charset));
- // MSH-12
- message.setHeader(MLLP_VERSION_ID, new String(hl7MessageBytes, fieldSeparatorIndexes.get(10) + 1,
- fieldSeparatorIndexes.get(11) - fieldSeparatorIndexes.get(10) - 1, charset));
- // MSH-18
- message.setHeader(MLLP_CHARSET, new String(hl7MessageBytes, fieldSeparatorIndexes.get(16) + 1,
- fieldSeparatorIndexes.get(17) - fieldSeparatorIndexes.get(16) - 1, charset));
-
- for (int i = fieldSeparatorIndexes.get(7) + 1; i < fieldSeparatorIndexes.get(8); ++i) {
- if (componentSeparator == hl7MessageBytes[i]) {
- // MSH-9.1
- message.setHeader(MLLP_EVENT_TYPE, new String(hl7MessageBytes, fieldSeparatorIndexes.get(7) + 1,
- i - fieldSeparatorIndexes.get(7) - 1, charset));
- // MSH-9.2
- message.setHeader(MLLP_TRIGGER_EVENT, new String(hl7MessageBytes, i + 1,
- fieldSeparatorIndexes.get(8) - i - 1, charset));
- break;
+ for (int i = 2; i < fieldSeparatorIndexes.size(); ++i) {
+ int startingFieldSeparatorIndex = fieldSeparatorIndexes.get(i - 1);
+ int endingFieldSeparatorIndex = fieldSeparatorIndexes.get(i);
+
+ // Only populate the header if there's data in the HL7 field
+ if (endingFieldSeparatorIndex - startingFieldSeparatorIndex > 1) {
+ String headerName = null;
+ switch (i) {
+ case 2: // MSH-3
+ headerName = MLLP_SENDING_APPLICATION;
+ break;
+ case 3: // MSH-4
+ headerName = MLLP_SENDING_FACILITY;
+ break;
+ case 4: // MSH-5
+ headerName = MLLP_RECEIVING_APPLICATION;
+ break;
+ case 5: // MSH-6
+ headerName = MLLP_RECEIVING_FACILITY;
+ break;
+ case 6: // MSH-7
+ headerName = MLLP_TIMESTAMP;
+ break;
+ case 7: // MSH-8
+ headerName = MLLP_SECURITY;
+ break;
+ case 8: // MSH-9
+ headerName = MLLP_MESSAGE_TYPE;
+ break;
+ case 9: // MSH-10
+ headerName = MLLP_MESSAGE_CONTROL;
+ break;
+ case 10: // MSH-11
+ headerName = MLLP_PROCESSING_ID;
+ break;
+ case 11: // MSH-12
+ headerName = MLLP_VERSION_ID;
+ break;
+ case 17: // MSH-18
+ headerName = MLLP_CHARSET;
+ break;
+ default:
+ // Not processing this field
+ continue;
+ }
+
+ String headerValue = new String(hl7MessageBytes, startingFieldSeparatorIndex + 1,
+ endingFieldSeparatorIndex - startingFieldSeparatorIndex - 1,
+ charset);
+ message.setHeader(headerName, headerValue);
+
+ // For MSH-9, set a couple more headers
+ if (i == 8) {
+ // final byte componentSeparator = hl7MessageBytes[4];
+ String componentSeparator = new String(hl7MessageBytes, 4, 1, charset);
+ String[] components = headerValue.split(String.format("\\Q%s\\E", componentSeparator), 3);
+ message.setHeader(MLLP_EVENT_TYPE, components[0]);
+ if (2 <= components.length) {
+ message.setHeader(MLLP_TRIGGER_EVENT, components[1]);
+ }
+ }
}
}
}
+
}
@Override
http://git-wip-us.apache.org/repos/asf/camel/blob/57f9f49c/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerAcknowledgementTest.java
----------------------------------------------------------------------
diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerAcknowledgementTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerAcknowledgementTest.java
new file mode 100644
index 0000000..33ce3c8
--- /dev/null
+++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerAcknowledgementTest.java
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.mllp;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.builder.NotifyBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.test.AvailablePortFinder;
+import org.apache.camel.test.junit.rule.mllp.MllpClientResource;
+import org.apache.camel.test.junit.rule.mllp.MllpJUnitResourceException;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.camel.component.mllp.MllpConstants.MLLP_EVENT_TYPE;
+import static org.apache.camel.component.mllp.MllpConstants.MLLP_RECEIVING_APPLICATION;
+import static org.apache.camel.component.mllp.MllpConstants.MLLP_RECEIVING_FACILITY;
+import static org.apache.camel.component.mllp.MllpConstants.MLLP_SENDING_APPLICATION;
+import static org.apache.camel.component.mllp.MllpConstants.MLLP_SENDING_FACILITY;
+import static org.apache.camel.component.mllp.MllpConstants.MLLP_TRIGGER_EVENT;
+import static org.apache.camel.component.mllp.MllpConstants.MLLP_VERSION_ID;
+import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage;
+
+public class MllpTcpServerConsumerAcknowledgementTest extends CamelTestSupport {
+ @Rule
+ public MllpClientResource mllpClient = new MllpClientResource();
+
+ @EndpointInject(uri = "mock://result")
+ MockEndpoint result;
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ DefaultCamelContext context = (DefaultCamelContext) super.createCamelContext();
+
+ context.setUseMDCLogging(true);
+ context.setName(this.getClass().getSimpleName());
+
+ return context;
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+
+ mllpClient.setMllpHost("localhost");
+ mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable());
+
+ return new RouteBuilder() {
+ int connectTimeout = 500;
+ int responseTimeout = 5000;
+
+ @Override
+ public void configure() throws Exception {
+ String routeId = "mllp-test-receiver-route";
+
+ onCompletion()
+ .toF("log:%s?level=INFO&showAll=true", routeId)
+ .log(LoggingLevel.INFO, routeId, "Test route complete");
+
+ fromF("mllp://%s:%d?autoAck=true&connectTimeout=%d&receiveTimeout=%d",
+ mllpClient.getMllpHost(), mllpClient.getMllpPort(), connectTimeout, responseTimeout)
+ .routeId(routeId)
+ .to(result);
+
+ }
+ };
+ }
+
+ @Test
+ public void testReceiveSingleMessage() throws Exception {
+ final String testMessage = "MSH|^~\\&|APP_A|FAC_A|^org^sys||||ADT^A04^ADT_A04|||2.6" + '\r'
+ + "PID|1||1100832^^^^PI||TEST^FIG||98765432|U||R|435 MAIN STREET^^LONGMONT^CO^80503||123-456-7890|||S" + '\r'
+ + '\r' + '\n';
+
+ final String expectedAcknowledgement = "MSH|^~\\&|^org^sys||APP_A|FAC_A|||ACK^A04^ADT_A04|||2.6" + '\r' + "MSA|AA|" + '\r' + '\n';
+
+ result.expectedMessageCount(1);
+ result.expectedHeaderReceived(MLLP_SENDING_APPLICATION, "APP_A");
+ result.expectedHeaderReceived(MLLP_SENDING_FACILITY, "FAC_A");
+ result.expectedHeaderReceived(MLLP_RECEIVING_APPLICATION, "^org^sys");
+ result.expectedHeaderReceived(MLLP_EVENT_TYPE, "ADT");
+ result.expectedHeaderReceived(MLLP_TRIGGER_EVENT, "A04");
+ result.expectedHeaderReceived(MLLP_VERSION_ID, "2.6");
+
+ mllpClient.connect();
+
+ String acknowledgement = mllpClient.sendMessageAndWaitForAcknowledgement(testMessage, 10000);
+
+ assertEquals("Unexpected Acknowledgement", expectedAcknowledgement, acknowledgement);
+
+ assertMockEndpointsSatisfied(10, TimeUnit.SECONDS);
+ }
+
+}
+