CAMEL-10303 - added ability to detect when the consumer fails to deliver the MLLP acknowledgement
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/62715117 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/62715117 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/62715117 Branch: refs/heads/master Commit: 62715117184b01d52b261bfda3c19e7f95fc6698 Parents: 8a11d47 Author: Quinn Stevenson <qu...@pronoia-solutions.com> Authored: Mon Sep 12 12:47:10 2016 -0600 Committer: Andrea Cosentino <anco...@gmail.com> Committed: Thu Sep 15 09:23:22 2016 +0200 ---------------------------------------------------------------------- .../MllpAcknowledgementDeliveryException.java | 32 +++ .../mllp/MllpAcknowledgementException.java | 43 +++- .../MllpAcknowledgementTimoutException.java | 16 +- ...pplicationErrorAcknowledgementException.java | 16 +- ...plicationRejectAcknowledgementException.java | 16 +- ...MllpCommitErrorAcknowledgementException.java | 16 +- ...llpCommitRejectAcknowledgementException.java | 16 +- .../camel/component/mllp/MllpComponent.java | 2 +- .../camel/component/mllp/MllpConstants.java | 2 + .../mllp/MllpCorruptFrameException.java | 40 ---- .../camel/component/mllp/MllpException.java | 25 +-- .../component/mllp/MllpFrameException.java | 60 ++++++ .../MllpInvalidAcknowledgementException.java | 16 +- .../component/mllp/MllpTcpClientProducer.java | 19 +- .../component/mllp/MllpTcpServerConsumer.java | 132 +----------- .../component/mllp/MllpTimeoutException.java | 34 ++- .../component/mllp/MllpWriteException.java | 34 ++- .../AcknowledgmentSynchronizationAdapter.java | 212 +++++++++++++++++++ .../camel/component/mllp/impl/MllpUtil.java | 28 +-- .../mllp/MllpAcknowledgementExceptionTest.java | 127 +++++++++++ .../component/mllp/MllpFrameExceptionTest.java | 101 +++++++++ .../mllp/MllpProducerConsumerLoopbackTest.java | 8 +- .../mllp/MllpTcpClientProducerTest.java | 10 +- ...llpTcpServerConsumerAcknowledgementTest.java | 97 +++++++-- .../mllp/MllpTimeoutExceptionTest.java | 101 +++++++++ .../component/mllp/MllpWriteExceptionTest.java | 101 +++++++++ .../junit/rule/mllp/MllpClientResource.java | 51 +++-- .../blueprint/mllp-tcp-client-producer-test.xml | 2 +- 28 files changed, 1026 insertions(+), 331 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementDeliveryException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementDeliveryException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementDeliveryException.java new file mode 100644 index 0000000..4ac46c9 --- /dev/null +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementDeliveryException.java @@ -0,0 +1,32 @@ +/** + * 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; + +/** + * Raised when a MLLP Consumer cannot deliver the MLLP Acknowledgement + */ +public class MllpAcknowledgementDeliveryException extends MllpAcknowledgementException { + static final String EXCEPTION_MESSAGE = "HL7 Acknowledgment Delivery Failed"; + + public MllpAcknowledgementDeliveryException(byte[] hl7Message, byte[] hl7Acknowledgement) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement); + } + + public MllpAcknowledgementDeliveryException(byte[] hl7Message, byte[] hl7Acknowledgement, Throwable cause) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement, cause); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementException.java index 624745c..992d506 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementException.java @@ -20,20 +20,49 @@ package org.apache.camel.component.mllp; * Base class for HL7 Application Acknowledgement Exceptions */ public abstract class MllpAcknowledgementException extends MllpException { - public MllpAcknowledgementException(String message) { + private final byte[] hl7Message; + private final byte[] hl7Acknowledgement; + + public MllpAcknowledgementException(String message, byte[] hl7Message, byte[] hl7Acknowledgement) { super(message); + this.hl7Message = hl7Message; + this.hl7Acknowledgement = hl7Acknowledgement; } - public MllpAcknowledgementException(String message, byte[] mllpPayload) { - super(message, mllpPayload); + public MllpAcknowledgementException(String message, byte[] hl7Message, byte[] hl7Acknowledgement, Throwable cause) { + super(message, cause); + this.hl7Message = hl7Message; + this.hl7Acknowledgement = hl7Acknowledgement; } - public MllpAcknowledgementException(String message, Throwable cause) { - super(message, cause); + public byte[] getHl7Message() { + return hl7Message; + } + + public byte[] getHl7Acknowledgement() { + return hl7Acknowledgement; } - public MllpAcknowledgementException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + @Override + public String getMessage() { + if (isLogPhi()) { + return String.format("%s:\n\tHL7 Message: %s\n\tHL7 Acknowledgement: %s", + super.getMessage(), covertBytesToPrintFriendlyString(hl7Message), covertBytesToPrintFriendlyString(hl7Acknowledgement)); + } else { + return super.getMessage(); + } } + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(this.getClass().getName()); + + stringBuilder.append(": {hl7Message=") + .append(covertBytesToPrintFriendlyString(hl7Message)) + .append(", hl7Acknowledgement=") + .append(covertBytesToPrintFriendlyString(hl7Acknowledgement)) + .append("}"); + + return stringBuilder.toString(); + } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementTimoutException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementTimoutException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementTimoutException.java index 9288a14..a1cf147 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementTimoutException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpAcknowledgementTimoutException.java @@ -20,19 +20,11 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer does not receive a HL7 acknowledgement within the configured timespan */ public class MllpAcknowledgementTimoutException extends MllpTimeoutException { - public MllpAcknowledgementTimoutException(String message) { - super(message); + public MllpAcknowledgementTimoutException(String message, byte[] hl7Message) { + super(message, hl7Message); } - public MllpAcknowledgementTimoutException(String message, byte[] mllpPayload) { - super(message, mllpPayload); - } - - public MllpAcknowledgementTimoutException(String message, Throwable cause) { - super(message, cause); - } - - public MllpAcknowledgementTimoutException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + public MllpAcknowledgementTimoutException(String message, byte[] hl7Message, Throwable cause) { + super(message, hl7Message, cause); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationErrorAcknowledgementException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationErrorAcknowledgementException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationErrorAcknowledgementException.java index 7d7ecd2..5b6fed1 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationErrorAcknowledgementException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationErrorAcknowledgementException.java @@ -20,19 +20,13 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer receives a HL7 Application Error Acknowledgement */ public class MllpApplicationErrorAcknowledgementException extends MllpAcknowledgementException { - public MllpApplicationErrorAcknowledgementException(String message) { - super(message); - } - - public MllpApplicationErrorAcknowledgementException(String message, byte[] mllpPayload) { - super(message, mllpPayload); - } + static final String EXCEPTION_MESSAGE = "HL7 Application Error Acknowledgment Received"; - public MllpApplicationErrorAcknowledgementException(String message, Throwable cause) { - super(message, cause); + public MllpApplicationErrorAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement); } - public MllpApplicationErrorAcknowledgementException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + public MllpApplicationErrorAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement, Throwable cause) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement, cause); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationRejectAcknowledgementException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationRejectAcknowledgementException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationRejectAcknowledgementException.java index ef2a39d..76cbf2c 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationRejectAcknowledgementException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpApplicationRejectAcknowledgementException.java @@ -20,19 +20,13 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer receives a HL7 Application Reject Acknowledgement */ public class MllpApplicationRejectAcknowledgementException extends MllpAcknowledgementException { - public MllpApplicationRejectAcknowledgementException(String message) { - super(message); - } - - public MllpApplicationRejectAcknowledgementException(String message, byte[] mllpPayload) { - super(message, mllpPayload); - } + static final String EXCEPTION_MESSAGE = "HL7 Application Reject Acknowledgment Received"; - public MllpApplicationRejectAcknowledgementException(String message, Throwable cause) { - super(message, cause); + public MllpApplicationRejectAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement); } - public MllpApplicationRejectAcknowledgementException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + public MllpApplicationRejectAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement, Throwable cause) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement, cause); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitErrorAcknowledgementException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitErrorAcknowledgementException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitErrorAcknowledgementException.java index 1269c56..aef1a27 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitErrorAcknowledgementException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitErrorAcknowledgementException.java @@ -20,19 +20,13 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer receives a HL7 Commit Error Acknowledgement */ public class MllpCommitErrorAcknowledgementException extends MllpAcknowledgementException { - public MllpCommitErrorAcknowledgementException(String message) { - super(message); - } - - public MllpCommitErrorAcknowledgementException(String message, byte[] mllpPayload) { - super(message, mllpPayload); - } + static final String EXCEPTION_MESSAGE = "HL7 Commit Error Acknowledgment Received"; - public MllpCommitErrorAcknowledgementException(String message, Throwable cause) { - super(message, cause); + public MllpCommitErrorAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement); } - public MllpCommitErrorAcknowledgementException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + public MllpCommitErrorAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement, Throwable cause) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement, cause); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitRejectAcknowledgementException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitRejectAcknowledgementException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitRejectAcknowledgementException.java index 99043a9..3907694 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitRejectAcknowledgementException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCommitRejectAcknowledgementException.java @@ -20,19 +20,13 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer receives a HL7 Commit Reject Acknowledgement */ public class MllpCommitRejectAcknowledgementException extends MllpAcknowledgementException { - public MllpCommitRejectAcknowledgementException(String message) { - super(message); - } - - public MllpCommitRejectAcknowledgementException(String message, byte[] mllpPayload) { - super(message, mllpPayload); - } + static final String EXCEPTION_MESSAGE = "HL7 Commit Reject Acknowledgment Received"; - public MllpCommitRejectAcknowledgementException(String message, Throwable cause) { - super(message, cause); + public MllpCommitRejectAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement); } - public MllpCommitRejectAcknowledgementException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + public MllpCommitRejectAcknowledgementException(byte[] hl7Message, byte[] hl7Acknowledgement, Throwable cause) { + super(EXCEPTION_MESSAGE, hl7Message, hl7Acknowledgement, cause); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java index 3a67dd3..b23a421 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java @@ -26,7 +26,7 @@ import org.apache.camel.impl.UriEndpointComponent; * Represents the component that manages {@link MllpEndpoint}. */ public class MllpComponent extends UriEndpointComponent { - public static final String MLLP_LOG_PHI_PROPERTY = "org.apache.camel.mllp.logPHI"; + public static final String MLLP_LOG_PHI_PROPERTY = "org.apache.camel.component.mllp.logPHI"; public MllpComponent() { super(MllpEndpoint.class); http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java index da5eb77..8275a0e 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConstants.java @@ -23,6 +23,8 @@ public final class MllpConstants { public static final String MLLP_ACKNOWLEDGEMENT = "CamelMllpAcknowledgement"; public static final String MLLP_ACKNOWLEDGEMENT_TYPE = "CamelMllpAcknowledgementType"; + public static final String MLLP_ACKNOWLEDGEMENT_EXCEPTION = "CamelMllpAcknowledgementException"; + public static final String MLLP_AUTO_ACKNOWLEDGE = "CamelMllpAutoAcknowledge"; /* Connection Control Exchange Properties - For Consumers, "SEND" => ACKNOWLEDGEMENT http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCorruptFrameException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCorruptFrameException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCorruptFrameException.java deleted file mode 100644 index 0310530..0000000 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpCorruptFrameException.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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; - -/** - * Raised when a MLLP Producer or consumer encounters a corrupt MLLP Frame while attempting - * to read or write a MLLP payload. - */ -public class MllpCorruptFrameException extends MllpException { - public MllpCorruptFrameException(String message) { - super(message); - } - - public MllpCorruptFrameException(String message, byte[] mllpPayload) { - super(message, mllpPayload); - } - - public MllpCorruptFrameException(String message, Throwable cause) { - super(message, cause); - } - - public MllpCorruptFrameException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); - } - -} http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpException.java index a1bb182..f0d5e84 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpException.java @@ -20,30 +20,25 @@ package org.apache.camel.component.mllp; * Base class for all MLLP Exceptions, and also used as a generic MLLP exception */ public class MllpException extends Exception { - private final byte[] mllpPayload; - public MllpException(String message) { super(message); - this.mllpPayload = null; - } - - public MllpException(String message, byte[] mllpPayload) { - super(message); - this.mllpPayload = mllpPayload; } public MllpException(String message, Throwable cause) { super(message, cause); - this.mllpPayload = null; } - public MllpException(String message, byte[] mllpPayload, Throwable cause) { - super(message, cause); - this.mllpPayload = mllpPayload; + public boolean isLogPhi() { + String logPhiProperty = System.getProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "true"); + return Boolean.valueOf(logPhiProperty); } - public byte[] getMllpPayload() { - return mllpPayload; + protected String covertBytesToPrintFriendlyString(byte[] hl7Bytes) { + if (null == hl7Bytes) { + return "null"; + } else if (hl7Bytes.length == 0) { + return ""; + } + return new String(hl7Bytes).replaceAll("\r", "<CR>").replaceAll("\n", "<LF>"); } - } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpFrameException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpFrameException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpFrameException.java new file mode 100644 index 0000000..43b1281 --- /dev/null +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpFrameException.java @@ -0,0 +1,60 @@ +/** + * 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; + +/** + * Raised when a MLLP Producer or consumer encounters a corrupt MLLP Frame while attempting + * to read or write a MLLP payload. + */ +public class MllpFrameException extends MllpException { + private final byte[] mllpPayload; + + public MllpFrameException(String message, byte[] mllpPayload) { + super(message); + this.mllpPayload = mllpPayload; + } + + public MllpFrameException(String message, byte[] mllpPayload, Throwable cause) { + super(message, cause); + this.mllpPayload = mllpPayload; + } + + public byte[] getMllpPayload() { + return mllpPayload; + } + + @Override + public String getMessage() { + if (isLogPhi()) { + return String.format("%s:\n\tMLLP Payload: %s", super.getMessage(), covertBytesToPrintFriendlyString(mllpPayload)); + } else { + return super.getMessage(); + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(this.getClass().getName()); + + stringBuilder.append(": {mllpPayload=") + .append(covertBytesToPrintFriendlyString(mllpPayload)) + .append("}"); + + return stringBuilder.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpInvalidAcknowledgementException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpInvalidAcknowledgementException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpInvalidAcknowledgementException.java index 495cfae..67d5316 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpInvalidAcknowledgementException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpInvalidAcknowledgementException.java @@ -20,19 +20,11 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer receives a HL7 Acknowledgement for which the HL7 Acknowledgement type cannot be determined. */ public class MllpInvalidAcknowledgementException extends MllpAcknowledgementException { - public MllpInvalidAcknowledgementException(String message) { - super(message); + public MllpInvalidAcknowledgementException(String message, byte[] hl7Message, byte[] hl7Acknowledgement) { + super(message, hl7Message, hl7Acknowledgement); } - public MllpInvalidAcknowledgementException(String message, byte[] mllpPayload) { - super(message, mllpPayload); - } - - public MllpInvalidAcknowledgementException(String message, Throwable cause) { - super(message, cause); - } - - public MllpInvalidAcknowledgementException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + public MllpInvalidAcknowledgementException(String message, byte[] hl7Message, byte[] hl7Acknowledgement, Throwable cause) { + super(message, hl7Message, hl7Acknowledgement, cause); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpClientProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpClientProducer.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpClientProducer.java index da04286..5793aea 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpClientProducer.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTcpClientProducer.java @@ -19,7 +19,6 @@ package org.apache.camel.component.mllp; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; -import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketTimeoutException; @@ -111,7 +110,7 @@ public class MllpTcpClientProducer extends DefaultProducer { acknowledgementBytes = MllpUtil.closeFrame(socket, endpoint.receiveTimeout, endpoint.readTimeout); } } catch (SocketTimeoutException timeoutEx) { - exchange.setException(new MllpAcknowledgementTimoutException("Acknowledgement timout", timeoutEx)); + exchange.setException(new MllpAcknowledgementTimoutException("Acknowledgement timout", hl7MessageBytes, timeoutEx)); return; } catch (MllpException mllpEx) { exchange.setException(mllpEx); @@ -146,14 +145,14 @@ public class MllpTcpClientProducer extends DefaultProducer { // Found the beginning of the MSA - the next two bytes should be our acknowledgement code msaStartIndex = i + 1; if (bA != acknowledgementBytes[i + 5] && bC != acknowledgementBytes[i + 5]) { - exchange.setException(new MllpInvalidAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpInvalidAcknowledgementException(new String(acknowledgementBytes, i + 5, 2), hl7MessageBytes, acknowledgementBytes)); } else { String acknowledgemenTypeString; switch (acknowledgementBytes[i + 6]) { case bA: // We have an AA or CA- make sure that's the end of the field if (fieldDelim != acknowledgementBytes[i + 7]) { - exchange.setException(new MllpInvalidAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpInvalidAcknowledgementException(new String(acknowledgementBytes, i + 5, 3), hl7MessageBytes, acknowledgementBytes)); } if (bA == acknowledgementBytes[i + 5]) { message.setHeader(MLLP_ACKNOWLEDGEMENT_TYPE, "AA"); @@ -165,24 +164,24 @@ public class MllpTcpClientProducer extends DefaultProducer { // We have an AE or CE if (bA == acknowledgementBytes[i + 5]) { message.setHeader(MLLP_ACKNOWLEDGEMENT_TYPE, "AE"); - exchange.setException(new MllpApplicationErrorAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpApplicationErrorAcknowledgementException(hl7MessageBytes, acknowledgementBytes)); } else { message.setHeader(MLLP_ACKNOWLEDGEMENT_TYPE, "CE"); - exchange.setException(new MllpCommitErrorAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpCommitErrorAcknowledgementException(hl7MessageBytes, acknowledgementBytes)); } break; case bR: // We have an AR or CR if (bA == acknowledgementBytes[i + 5]) { message.setHeader(MLLP_ACKNOWLEDGEMENT_TYPE, "AR"); - exchange.setException(new MllpApplicationRejectAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpApplicationRejectAcknowledgementException(hl7MessageBytes, acknowledgementBytes)); } else { message.setHeader(MLLP_ACKNOWLEDGEMENT_TYPE, "CR"); - exchange.setException(new MllpCommitRejectAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpCommitRejectAcknowledgementException(hl7MessageBytes, acknowledgementBytes)); } break; default: - exchange.setException(new MllpInvalidAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpInvalidAcknowledgementException(new String(acknowledgementBytes, i + 5, 2), hl7MessageBytes, acknowledgementBytes)); } } @@ -194,7 +193,7 @@ public class MllpTcpClientProducer extends DefaultProducer { } if (-1 == msaStartIndex) { // Didn't find an MSA - exchange.setException(new MllpInvalidAcknowledgementException(new String(acknowledgementBytes))); + exchange.setException(new MllpInvalidAcknowledgementException("MSA Not found in acknowledgement", hl7MessageBytes, acknowledgementBytes)); } } // Check AFTER_SEND Properties http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/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 61f29db..1648b8a 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 @@ -33,18 +33,14 @@ import org.apache.camel.Exchange; import org.apache.camel.ExchangePattern; import org.apache.camel.Message; import org.apache.camel.Processor; +import org.apache.camel.component.mllp.impl.AcknowledgmentSynchronizationAdapter; import org.apache.camel.component.mllp.impl.MllpUtil; -import org.apache.camel.converter.IOConverter; import org.apache.camel.impl.DefaultConsumer; -import org.apache.camel.processor.mllp.Hl7AcknowledgementGenerationException; import org.apache.camel.processor.mllp.Hl7AcknowledgementGenerator; import org.apache.camel.util.IOHelper; -import static org.apache.camel.component.mllp.MllpConstants.MLLP_ACKNOWLEDGEMENT; -import static org.apache.camel.component.mllp.MllpConstants.MLLP_ACKNOWLEDGEMENT_TYPE; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_AUTO_ACKNOWLEDGE; import static org.apache.camel.component.mllp.MllpConstants.MLLP_CHARSET; -import static org.apache.camel.component.mllp.MllpConstants.MLLP_CLOSE_CONNECTION_AFTER_SEND; -import static org.apache.camel.component.mllp.MllpConstants.MLLP_CLOSE_CONNECTION_BEFORE_SEND; import static org.apache.camel.component.mllp.MllpConstants.MLLP_EVENT_TYPE; import static org.apache.camel.component.mllp.MllpConstants.MLLP_LOCAL_ADDRESS; import static org.apache.camel.component.mllp.MllpConstants.MLLP_MESSAGE_CONTROL; @@ -53,8 +49,6 @@ import static org.apache.camel.component.mllp.MllpConstants.MLLP_PROCESSING_ID; 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_REMOTE_ADDRESS; -import static org.apache.camel.component.mllp.MllpConstants.MLLP_RESET_CONNECTION_AFTER_SEND; -import static org.apache.camel.component.mllp.MllpConstants.MLLP_RESET_CONNECTION_BEFORE_SEND; import static org.apache.camel.component.mllp.MllpConstants.MLLP_SECURITY; import static org.apache.camel.component.mllp.MllpConstants.MLLP_SENDING_APPLICATION; import static org.apache.camel.component.mllp.MllpConstants.MLLP_SENDING_FACILITY; @@ -428,128 +422,20 @@ public class MllpTcpServerConsumer extends DefaultConsumer { message.setHeader(MLLP_LOCAL_ADDRESS, clientSocket.getLocalAddress().toString()); message.setHeader(MLLP_REMOTE_ADDRESS, clientSocket.getRemoteSocketAddress()); + message.setHeader(MLLP_AUTO_ACKNOWLEDGE, endpoint.autoAck); populateHl7DataHeaders(exchange, message, hl7MessageBytes); + exchange.addOnCompletion(new AcknowledgmentSynchronizationAdapter(clientSocket, hl7MessageBytes)); log.debug("Calling processor"); try { getProcessor().process(exchange); - // processed the message - send the acknowledgement - - // Check BEFORE_SEND Properties - if (exchange.getProperty(MLLP_RESET_CONNECTION_BEFORE_SEND, boolean.class)) { - MllpUtil.resetConnection(clientSocket); - return; - } else if (exchange.getProperty(MLLP_CLOSE_CONNECTION_BEFORE_SEND, boolean.class)) { - MllpUtil.closeConnection(clientSocket); - } - - // Find the acknowledgement body - byte[] acknowledgementMessageBytes = exchange.getProperty(MLLP_ACKNOWLEDGEMENT, byte[].class); - String acknowledgementMessageType = null; - if (null == acknowledgementMessageBytes) { - if (!endpoint.autoAck) { - exchange.setException(new MllpInvalidAcknowledgementException("Automatic Acknowledgement is disabled and the " - + MLLP_ACKNOWLEDGEMENT + " exchange property is null or cannot be converted to byte[]")); - return; - } - - String acknowledgmentTypeProperty = exchange.getProperty(MLLP_ACKNOWLEDGEMENT_TYPE, String.class); - try { - if (null == acknowledgmentTypeProperty) { - if (null == exchange.getException()) { - acknowledgementMessageType = "AA"; - acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationAcceptAcknowledgementMessage(hl7MessageBytes); - } else { - acknowledgementMessageType = "AE"; - acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationErrorAcknowledgementMessage(hl7MessageBytes); - } - } else { - switch (acknowledgmentTypeProperty) { - case "AA": - acknowledgementMessageType = "AA"; - acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationAcceptAcknowledgementMessage(hl7MessageBytes); - break; - case "AE": - acknowledgementMessageType = "AE"; - acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationErrorAcknowledgementMessage(hl7MessageBytes); - break; - case "AR": - acknowledgementMessageType = "AR"; - acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationRejectAcknowledgementMessage(hl7MessageBytes); - break; - default: - exchange.setException(new Hl7AcknowledgementGenerationException("Unsupported acknowledgment type: " + acknowledgmentTypeProperty)); - return; - } - } - } catch (Hl7AcknowledgementGenerationException ackGenerationException) { - exchange.setException(ackGenerationException); - } - } else { - final byte bM = 77; - final byte bS = 83; - final byte bA = 65; - final byte bE = 69; - final byte bR = 82; - - final byte fieldSeparator = hl7MessageBytes[3]; - // Acknowledgment is specified in exchange property - determine the acknowledgement type - for (int i = 0; i < hl7MessageBytes.length; ++i) { - if (SEGMENT_DELIMITER == i) { - if (i + 7 < hl7MessageBytes.length // Make sure we don't run off the end of the message - && bM == hl7MessageBytes[i + 1] && bS == hl7MessageBytes[i + 2] && bA == hl7MessageBytes[i + 3] && fieldSeparator == hl7MessageBytes[i + 4]) { - if (fieldSeparator != hl7MessageBytes[i + 7]) { - log.warn("MSA-1 is longer than 2-bytes - ignoring trailing bytes"); - } - // Found MSA - pull acknowledgement bytes - byte[] acknowledgmentTypeBytes = new byte[2]; - acknowledgmentTypeBytes[0] = hl7MessageBytes[i + 5]; - acknowledgmentTypeBytes[1] = hl7MessageBytes[i + 6]; - acknowledgementMessageType = IOConverter.toString(acknowledgmentTypeBytes, exchange); - - // Verify it's a valid acknowledgement code - if (bA != acknowledgmentTypeBytes[0]) { - switch (acknowledgementMessageBytes[1]) { - case bA: - case bR: - case bE: - break; - default: - log.warn("Invalid acknowledgement type [" + acknowledgementMessageType + "] found in message - should be AA, AE or AR"); - } - } - - // if the MLLP_ACKNOWLEDGEMENT_TYPE property is set on the exchange, make sure it matches - String acknowledgementTypeProperty = exchange.getProperty(MLLP_ACKNOWLEDGEMENT_TYPE, String.class); - if (null != acknowledgementTypeProperty && !acknowledgementTypeProperty.equals(acknowledgementMessageType)) { - log.warn("Acknowledgement type found in message [" + acknowledgementMessageType + "] does not match " - + MLLP_ACKNOWLEDGEMENT_TYPE + " exchange property value [" + acknowledgementTypeProperty + "] - using value found in message"); - } - } - } - } - } - - // Send the acknowledgement - log.debug("Writing Acknowledgement"); - MllpUtil.writeFramedPayload(clientSocket, acknowledgementMessageBytes); - exchange.getIn().setHeader(MLLP_ACKNOWLEDGEMENT, acknowledgementMessageBytes); - exchange.getIn().setHeader(MLLP_ACKNOWLEDGEMENT_TYPE, acknowledgementMessageType); - exchange.setProperty(MLLP_ACKNOWLEDGEMENT, acknowledgementMessageBytes); - exchange.setProperty(MLLP_ACKNOWLEDGEMENT_TYPE, acknowledgementMessageType); - - // Check AFTER_SEND Properties - if (exchange.getProperty(MLLP_RESET_CONNECTION_AFTER_SEND, boolean.class)) { - MllpUtil.resetConnection(clientSocket); - return; - } else if (exchange.getProperty(MLLP_CLOSE_CONNECTION_AFTER_SEND, boolean.class)) { - MllpUtil.closeConnection(clientSocket); - } - - } catch (Exception e) { - exchange.setException(e); + } catch (RuntimeException runtimeEx) { + throw runtimeEx; + } catch (Exception ex) { + log.error("Unexpected exception processing exchange", ex); + throw new RuntimeException("Unexpected exception processing exchange", ex); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTimeoutException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTimeoutException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTimeoutException.java index 0e54772..7c2014a 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTimeoutException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpTimeoutException.java @@ -20,20 +20,40 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer or Consumer encounter a timeout reading a message */ public class MllpTimeoutException extends MllpException { - public MllpTimeoutException(String message) { + private final byte[] hl7Message; + + public MllpTimeoutException(String message, byte[] hl7Message) { super(message); + this.hl7Message = hl7Message; } - public MllpTimeoutException(String message, byte[] mllpPayload) { - super(message, mllpPayload); + public MllpTimeoutException(String message, byte[] hl7Message, Throwable cause) { + super(message, cause); + this.hl7Message = hl7Message; } - public MllpTimeoutException(String message, Throwable cause) { - super(message, cause); + public byte[] getHl7Message() { + return hl7Message; } - public MllpTimeoutException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + @Override + public String getMessage() { + if (isLogPhi()) { + return String.format("%s:\n\tHL7 Message: %s", super.getMessage(), covertBytesToPrintFriendlyString(hl7Message)); + } else { + return super.getMessage(); + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(this.getClass().getName()); + + stringBuilder.append(": {hl7Message=") + .append(covertBytesToPrintFriendlyString(hl7Message)) + .append("}"); + + return stringBuilder.toString(); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpWriteException.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpWriteException.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpWriteException.java index 43fe740..dd5bf42 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpWriteException.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpWriteException.java @@ -20,20 +20,40 @@ package org.apache.camel.component.mllp; * Raised when a MLLP Producer or consumer encounter an error transmitting data */ public class MllpWriteException extends MllpException { - public MllpWriteException(String message) { - super(message); - } + private final byte[] mllpPayload; public MllpWriteException(String message, byte[] mllpPayload) { - super(message, mllpPayload); + super(message); + this.mllpPayload = mllpPayload; } - public MllpWriteException(String message, Throwable cause) { + public MllpWriteException(String message, byte[] mllpPayload, Throwable cause) { super(message, cause); + this.mllpPayload = mllpPayload; } - public MllpWriteException(String message, byte[] mllpPayload, Throwable cause) { - super(message, mllpPayload, cause); + public byte[] getMllpPayload() { + return mllpPayload; + } + + @Override + public String getMessage() { + if (isLogPhi()) { + return String.format("%s:\n\tMLLP Payload: %s", super.getMessage(), covertBytesToPrintFriendlyString(mllpPayload)); + } else { + return super.getMessage(); + } + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(this.getClass().getName()); + + stringBuilder.append(": {mllpPayload=") + .append(covertBytesToPrintFriendlyString(mllpPayload)) + .append("}"); + + return stringBuilder.toString(); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/AcknowledgmentSynchronizationAdapter.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/AcknowledgmentSynchronizationAdapter.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/AcknowledgmentSynchronizationAdapter.java new file mode 100644 index 0000000..6d4b76c --- /dev/null +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/AcknowledgmentSynchronizationAdapter.java @@ -0,0 +1,212 @@ +/** + * 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.impl; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.Route; +import org.apache.camel.component.mllp.MllpAcknowledgementDeliveryException; +import org.apache.camel.component.mllp.MllpException; +import org.apache.camel.component.mllp.MllpInvalidAcknowledgementException; +import org.apache.camel.converter.IOConverter; +import org.apache.camel.processor.mllp.Hl7AcknowledgementGenerationException; +import org.apache.camel.processor.mllp.Hl7AcknowledgementGenerator; +import org.apache.camel.support.SynchronizationAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.camel.component.mllp.MllpConstants.MLLP_ACKNOWLEDGEMENT; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_ACKNOWLEDGEMENT_EXCEPTION; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_ACKNOWLEDGEMENT_TYPE; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_AUTO_ACKNOWLEDGE; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_CLOSE_CONNECTION_AFTER_SEND; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_CLOSE_CONNECTION_BEFORE_SEND; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_RESET_CONNECTION_AFTER_SEND; +import static org.apache.camel.component.mllp.MllpConstants.MLLP_RESET_CONNECTION_BEFORE_SEND; +import static org.apache.camel.component.mllp.MllpEndpoint.SEGMENT_DELIMITER; + +public class AcknowledgmentSynchronizationAdapter extends SynchronizationAdapter { + Logger log = LoggerFactory.getLogger(this.getClass()); + final byte[] originalHl7MessageBytes; + Hl7AcknowledgementGenerator acknowledgementGenerator = new Hl7AcknowledgementGenerator(); + private Socket clientSocket; + + public AcknowledgmentSynchronizationAdapter(Socket clientSocket, byte[] hl7MessageBytes) { + this.clientSocket = clientSocket; + this.originalHl7MessageBytes = hl7MessageBytes; + } + + @Override + public int getOrder() { + return HIGHEST; + } + + @Override + public void onAfterRoute(Route route, Exchange exchange) { + log.info("onAfterRoute"); + + // Check BEFORE_SEND Properties + if (exchange.getProperty(MLLP_RESET_CONNECTION_BEFORE_SEND, boolean.class)) { + MllpUtil.resetConnection(clientSocket); + return; + } else if (exchange.getProperty(MLLP_CLOSE_CONNECTION_BEFORE_SEND, boolean.class)) { + MllpUtil.closeConnection(clientSocket); + return; + } + + // Find the acknowledgement body + // TODO: Enhance this to say whether or not the acknowlment is missing or just of an uncovertable type + byte[] acknowledgementMessageBytes = exchange.getProperty(MLLP_ACKNOWLEDGEMENT, byte[].class); + String acknowledgementMessageType = null; + if (null == acknowledgementMessageBytes) { + boolean autoAck = exchange.getProperty(MLLP_AUTO_ACKNOWLEDGE, true, boolean.class); + if (!autoAck) { + exchange.setException(new MllpInvalidAcknowledgementException("Automatic Acknowledgement is disabled and the " + + MLLP_ACKNOWLEDGEMENT + " exchange property is null or cannot be converted to byte[]", originalHl7MessageBytes, acknowledgementMessageBytes)); + return; + } + + String acknowledgmentTypeProperty = exchange.getProperty(MLLP_ACKNOWLEDGEMENT_TYPE, String.class); + try { + if (null == acknowledgmentTypeProperty) { + if (null == exchange.getException()) { + acknowledgementMessageType = "AA"; + acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationAcceptAcknowledgementMessage(originalHl7MessageBytes); + } else { + acknowledgementMessageType = "AE"; + acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationErrorAcknowledgementMessage(originalHl7MessageBytes); + } + } else { + switch (acknowledgmentTypeProperty) { + case "AA": + acknowledgementMessageType = "AA"; + acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationAcceptAcknowledgementMessage(originalHl7MessageBytes); + break; + case "AE": + acknowledgementMessageType = "AE"; + acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationErrorAcknowledgementMessage(originalHl7MessageBytes); + break; + case "AR": + acknowledgementMessageType = "AR"; + acknowledgementMessageBytes = acknowledgementGenerator.generateApplicationRejectAcknowledgementMessage(originalHl7MessageBytes); + break; + default: + exchange.setException(new Hl7AcknowledgementGenerationException("Unsupported acknowledgment type: " + acknowledgmentTypeProperty)); + return; + } + } + } catch (Hl7AcknowledgementGenerationException ackGenerationException) { + exchange.setProperty(MLLP_ACKNOWLEDGEMENT_EXCEPTION, ackGenerationException); + exchange.setException(ackGenerationException); + } + } else { + final byte bM = 77; + final byte bS = 83; + final byte bA = 65; + final byte bE = 69; + final byte bR = 82; + + final byte fieldSeparator = originalHl7MessageBytes[3]; + // Acknowledgment is specified in exchange property - determine the acknowledgement type + for (int i = 0; i < originalHl7MessageBytes.length; ++i) { + if (SEGMENT_DELIMITER == i) { + if (i + 7 < originalHl7MessageBytes.length // Make sure we don't run off the end of the message + && bM == originalHl7MessageBytes[i + 1] && bS == originalHl7MessageBytes[i + 2] + && bA == originalHl7MessageBytes[i + 3] && fieldSeparator == originalHl7MessageBytes[i + 4]) { + if (fieldSeparator != originalHl7MessageBytes[i + 7]) { + log.warn("MSA-1 is longer than 2-bytes - ignoring trailing bytes"); + } + // Found MSA - pull acknowledgement bytes + byte[] acknowledgmentTypeBytes = new byte[2]; + acknowledgmentTypeBytes[0] = originalHl7MessageBytes[i + 5]; + acknowledgmentTypeBytes[1] = originalHl7MessageBytes[i + 6]; + try { + acknowledgementMessageType = IOConverter.toString(acknowledgmentTypeBytes, exchange); + } catch (IOException ioEx) { + throw new RuntimeException("Failed to convert acknowledgement message to string", ioEx); + } + + // Verify it's a valid acknowledgement code + if (bA != acknowledgmentTypeBytes[0]) { + switch (acknowledgementMessageBytes[1]) { + case bA: + case bR: + case bE: + break; + default: + log.warn("Invalid acknowledgement type [" + acknowledgementMessageType + "] found in message - should be AA, AE or AR"); + } + } + + // if the MLLP_ACKNOWLEDGEMENT_TYPE property is set on the exchange, make sure it matches + String acknowledgementTypeProperty = exchange.getProperty(MLLP_ACKNOWLEDGEMENT_TYPE, String.class); + if (null != acknowledgementTypeProperty && !acknowledgementTypeProperty.equals(acknowledgementMessageType)) { + log.warn("Acknowledgement type found in message [" + acknowledgementMessageType + "] does not match " + + MLLP_ACKNOWLEDGEMENT_TYPE + " exchange property value [" + acknowledgementTypeProperty + "] - using value found in message"); + } + } + } + } + } + + Message message; + if (exchange.hasOut()) { + message = exchange.getOut(); + } else { + message = exchange.getIn(); + } + message.setHeader(MLLP_ACKNOWLEDGEMENT, acknowledgementMessageBytes); + message.setHeader(MLLP_ACKNOWLEDGEMENT_TYPE, acknowledgementMessageType); + + // Send the acknowledgement + log.debug("Sending Acknowledgement"); + try { + MllpUtil.writeFramedPayload(clientSocket, acknowledgementMessageBytes); + } catch (MllpException mllpEx) { + log.error("MLLP Acknowledgement failure: {}", mllpEx); + MllpAcknowledgementDeliveryException deliveryException = new MllpAcknowledgementDeliveryException(originalHl7MessageBytes, acknowledgementMessageBytes, mllpEx); + exchange.setProperty(MLLP_ACKNOWLEDGEMENT_EXCEPTION, deliveryException); + exchange.setException(deliveryException); + } + + // Check AFTER_SEND Properties + if (exchange.getProperty(MLLP_RESET_CONNECTION_AFTER_SEND, boolean.class)) { + MllpUtil.resetConnection(clientSocket); + return; + } else if (exchange.getProperty(MLLP_CLOSE_CONNECTION_AFTER_SEND, boolean.class)) { + MllpUtil.closeConnection(clientSocket); + } + + super.onAfterRoute(route, exchange); + } + + @Override + public void onComplete(Exchange exchange) { + log.info("onComplete"); + super.onComplete(exchange); + + } + + @Override + public void onFailure(Exchange exchange) { + log.warn("onFailure"); + super.onFailure(exchange); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/MllpUtil.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/MllpUtil.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/MllpUtil.java index 276d3ae..20315e7 100644 --- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/MllpUtil.java +++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/impl/MllpUtil.java @@ -26,8 +26,8 @@ import java.net.SocketException; import java.net.SocketTimeoutException; import org.apache.camel.component.mllp.MllpComponent; -import org.apache.camel.component.mllp.MllpCorruptFrameException; import org.apache.camel.component.mllp.MllpException; +import org.apache.camel.component.mllp.MllpFrameException; import org.apache.camel.component.mllp.MllpTimeoutException; import org.apache.camel.component.mllp.MllpWriteException; import org.slf4j.Logger; @@ -65,10 +65,10 @@ public final class MllpUtil { * @param socket the Socket to read * @throws SocketTimeoutException thrown if a timeout occurs while looking for the beginning of the MLLP frame, but * nothing is yet available - this is NOT an error condition - * @throws MllpCorruptFrameException if the MLLP Frame is corrupted in some way + * @throws MllpFrameException if the MLLP Frame is corrupted in some way * @throws MllpException for other unexpected error conditions */ - public static boolean openFrame(Socket socket, int receiveTimeout, int readTimeout) throws SocketTimeoutException, MllpCorruptFrameException, MllpException { + public static boolean openFrame(Socket socket, int receiveTimeout, int readTimeout) throws SocketTimeoutException, MllpFrameException, MllpException { if (socket.isConnected() && !socket.isClosed()) { InputStream socketInputStream = MllpUtil.getInputStream(socket); @@ -125,7 +125,7 @@ public final class MllpUtil { } resetConnection(socket); - throw new MllpCorruptFrameException("END_OF_STREAM read while looking for the beginning of the MLLP frame", outOfFrameData.toByteArray()); + throw new MllpFrameException("END_OF_STREAM read while looking for the beginning of the MLLP frame", outOfFrameData.toByteArray()); case START_OF_BLOCK: if (isLogPHIEnabled(LOG)) { LOG.warn("The beginning of the MLLP frame was preceded by out-of-frame data - eating data: {}", outOfFrameData.toString().replace('\r', '\n')); @@ -133,7 +133,7 @@ public final class MllpUtil { LOG.warn("The beginning of the MLLP frame was preceded by out-of-frame data - eating data"); } - throw new MllpCorruptFrameException("The beginning of the MLLP frame was preceded by out-of-frame data", outOfFrameData.toByteArray()); + throw new MllpFrameException("The beginning of the MLLP frame was preceded by out-of-frame data", outOfFrameData.toByteArray()); default: // still reading out-of-frame data outOfFrameData.write(readByte); @@ -150,7 +150,7 @@ public final class MllpUtil { resetConnection(socket); - throw new MllpCorruptFrameException("Timeout looking for the beginning of the MLLP frame, and out-of-frame data had been read", outOfFrameData.toByteArray()); + throw new MllpFrameException("Timeout looking for the beginning of the MLLP frame, and out-of-frame data had been read", outOfFrameData.toByteArray()); } catch (IOException e) { if (isLogPHIEnabled(LOG)) { LOG.error("Exception encountered looking for the beginning of the MLLP frame, and out-of-frame data had been read - resetting connection and eating out-of-frame data: {}", @@ -161,7 +161,7 @@ public final class MllpUtil { resetConnection(socket); - throw new MllpCorruptFrameException("Exception encountered looking for the beginning of the MLLP frame, and out-of-frame data had been read", outOfFrameData.toByteArray()); + throw new MllpFrameException("Exception encountered looking for the beginning of the MLLP frame, and out-of-frame data had been read", outOfFrameData.toByteArray()); } } @@ -182,10 +182,10 @@ public final class MllpUtil { * @param socket the Socket to be read * @return the payload of the MLLP-Enveloped message as a byte[] * @throws MllpTimeoutException thrown if a timeout occurs while closing the MLLP frame - * @throws MllpCorruptFrameException if the MLLP Frame is corrupted in some way + * @throws MllpFrameException if the MLLP Frame is corrupted in some way * @throws MllpException for other unexpected error conditions */ - public static byte[] closeFrame(Socket socket, int receiveTimeout, int readTimeout) throws MllpTimeoutException, MllpCorruptFrameException, MllpException { + public static byte[] closeFrame(Socket socket, int receiveTimeout, int readTimeout) throws MllpTimeoutException, MllpFrameException, MllpException { if (socket.isConnected() && !socket.isClosed()) { InputStream socketInputStream = MllpUtil.getInputStream(socket); // TODO: Come up with an intelligent way to size this stream @@ -204,7 +204,7 @@ public final class MllpUtil { resetConnection(socket); - throw new MllpCorruptFrameException("END_OF_STREAM read while looking for the end of the MLLP frame", payload.size() > 0 ? payload.toByteArray() : null); + throw new MllpFrameException("END_OF_STREAM read while looking for the end of the MLLP frame", payload.size() > 0 ? payload.toByteArray() : null); case START_OF_BLOCK: if (isLogPHIEnabled(LOG)) { LOG.error("A new MLLP frame was opened before the previous frame was closed - resetting connection and eating data: {}", payload.toString().replace('\r', '\n')); @@ -214,7 +214,7 @@ public final class MllpUtil { resetConnection(socket); - throw new MllpCorruptFrameException("A new MLLP frame was opened before the previous frame was closed", payload.size() > 0 ? payload.toByteArray() : null); + throw new MllpFrameException("A new MLLP frame was opened before the previous frame was closed", payload.size() > 0 ? payload.toByteArray() : null); case END_OF_BLOCK: if (END_OF_DATA != socketInputStream.read()) { if (isLogPHIEnabled(LOG)) { @@ -226,7 +226,7 @@ public final class MllpUtil { resetConnection(socket); - throw new MllpCorruptFrameException("The MLLP frame was partially closed - END_OF_BLOCK was not followed by END_OF_DATA", + throw new MllpFrameException("The MLLP frame was partially closed - END_OF_BLOCK was not followed by END_OF_DATA", payload.size() > 0 ? payload.toByteArray() : null); } socket.setSoTimeout(receiveTimeout); @@ -249,7 +249,7 @@ public final class MllpUtil { resetConnection(socket); - throw new MllpCorruptFrameException("Timeout looking for the end of the MLLP frame", payload.size() > 0 ? payload.toByteArray() : null, timeoutEx); + throw new MllpFrameException("Timeout looking for the end of the MLLP frame", payload.size() > 0 ? payload.toByteArray() : null, timeoutEx); } catch (IOException ioEx) { if (0 < payload.size()) { if (isLogPHIEnabled(LOG)) { @@ -263,7 +263,7 @@ public final class MllpUtil { resetConnection(socket); - throw new MllpException("Exception encountered looking for the end of the MLLP frame", payload.size() > 0 ? payload.toByteArray() : null, ioEx); + throw new MllpFrameException("Exception encountered looking for the end of the MLLP frame", payload.size() > 0 ? payload.toByteArray() : null, ioEx); } } http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpAcknowledgementExceptionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpAcknowledgementExceptionTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpAcknowledgementExceptionTest.java new file mode 100644 index 0000000..439a3c9 --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpAcknowledgementExceptionTest.java @@ -0,0 +1,127 @@ +/** + * 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 org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.assertEquals; + +public class MllpAcknowledgementExceptionTest { + static final String HL7_MESSAGE = "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'; + + static final String HL7_ACKNOWLEDGEMENT = "MSH|^~\\&|^org^sys||APP_A|FAC_A|||ACK^A04^ADT_A04|||2.6" + '\r' + "MSA|AA|" + '\r' + '\n'; + + static final String EXCEPTION_MESSAGE_WITH_LOG_PHI_DISABLED = MllpAcknowledgementDeliveryException.EXCEPTION_MESSAGE; + static final String EXCEPTION_MESSAGE_WITH_LOG_PHI_ENABLED = + String.format("%s:\n\tHL7 Message: %s\n\tHL7 Acknowledgement: %s", + MllpAcknowledgementDeliveryException.EXCEPTION_MESSAGE, + new String(HL7_MESSAGE).replaceAll("\r", "<CR>").replaceAll("\n", "<LF>"), + new String(HL7_ACKNOWLEDGEMENT).replaceAll("\r", "<CR>").replaceAll("\n", "<LF>") + ); + + Exception exception; + + Logger log = LoggerFactory.getLogger(this.getClass()); + + @Before + public void setUp() throws Exception { + exception = new MllpAcknowledgementDeliveryException(HL7_MESSAGE.getBytes(), HL7_ACKNOWLEDGEMENT.getBytes()); + } + + @After + public void tearDown() throws Exception { + System.clearProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY); + } + + + @Test + public void testLogPhiDefault() throws Exception { + String exceptionMessage = exception.getMessage(); + + assertEquals(EXCEPTION_MESSAGE_WITH_LOG_PHI_ENABLED, exceptionMessage); + } + + @Test + public void testLogPhiDisabled() throws Exception { + System.setProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "false"); + + String exceptionMessage = exception.getMessage(); + + assertEquals(EXCEPTION_MESSAGE_WITH_LOG_PHI_DISABLED, exceptionMessage); + } + + @Test + public void testLogPhiEnabled() throws Exception { + System.setProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "true"); + + String exceptionMessage = exception.getMessage(); + + assertEquals(EXCEPTION_MESSAGE_WITH_LOG_PHI_ENABLED, exceptionMessage); + } + + @Test + public void testNullMessage() throws Exception { + final String expectedMessage = + String.format("%s:\n\tHL7 Message: null\n\tHL7 Acknowledgement: %s", + MllpAcknowledgementDeliveryException.EXCEPTION_MESSAGE, + new String(HL7_ACKNOWLEDGEMENT).replaceAll("\r", "<CR>").replaceAll("\n", "<LF>") + ); + + exception = new MllpAcknowledgementDeliveryException(null, HL7_ACKNOWLEDGEMENT.getBytes()); + + System.setProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "true"); + String exceptionMessage = exception.getMessage(); + + assertEquals(expectedMessage, exceptionMessage); + } + + @Test + public void testNullAcknowledgement() throws Exception { + final String expectedMessage = + String.format("%s:\n\tHL7 Message: %s\n\tHL7 Acknowledgement: null", + MllpAcknowledgementDeliveryException.EXCEPTION_MESSAGE, + new String(HL7_MESSAGE).replaceAll("\r", "<CR>").replaceAll("\n", "<LF>") + ); + + exception = new MllpAcknowledgementDeliveryException(HL7_MESSAGE.getBytes(), null); + + System.setProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "true"); + String exceptionMessage = exception.getMessage(); + + assertEquals(expectedMessage, exceptionMessage); + } + + @Test + public void testToString() throws Exception { + final String expectedString = + "org.apache.camel.component.mllp.MllpAcknowledgementDeliveryException: " + + "{hl7Message=" + + "MSH|^~\\&|APP_A|FAC_A|^org^sys||||ADT^A04^ADT_A04|||2.6<CR>" + + "PID|1||1100832^^^^PI||TEST^FIG||98765432|U||R|435 MAIN STREET^^LONGMONT^CO^80503||123-456-7890|||S<CR><CR><LF>" + + ", hl7Acknowledgement=" + + "MSH|^~\\&|^org^sys||APP_A|FAC_A|||ACK^A04^ADT_A04|||2.6<CR>MSA|AA|<CR><LF>" + + "}"; + + assertEquals(expectedString, exception.toString()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpFrameExceptionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpFrameExceptionTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpFrameExceptionTest.java new file mode 100644 index 0000000..ca713dc --- /dev/null +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpFrameExceptionTest.java @@ -0,0 +1,101 @@ +/** + * 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 org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class MllpFrameExceptionTest { + static final String EXCEPTION_MESSAGE = "Test Frame Exception"; + + static final String HL7_MESSAGE = + "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'; + + static final String EXCEPTION_MESSAGE_WITH_LOG_PHI_DISABLED = EXCEPTION_MESSAGE; + static final String EXCEPTION_MESSAGE_WITH_LOG_PHI_ENABLED = + String.format(String.format("%s:\n\tMLLP Payload: %s", + EXCEPTION_MESSAGE, + new String(HL7_MESSAGE).replaceAll("\r", "<CR>").replaceAll("\n", "<LF>")) + ); + + Exception exception; + + @Before + public void setUp() throws Exception { + exception = new MllpFrameException(EXCEPTION_MESSAGE, HL7_MESSAGE.getBytes()); + } + + @After + public void tearDown() throws Exception { + System.clearProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY); + } + + @Test + public void testLogPhiDefault() throws Exception { + String exceptionMessage = exception.getMessage(); + + assertEquals(EXCEPTION_MESSAGE_WITH_LOG_PHI_ENABLED, exceptionMessage); + } + + @Test + public void testLogPhiDisabled() throws Exception { + System.setProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "false"); + + String exceptionMessage = exception.getMessage(); + + assertEquals(EXCEPTION_MESSAGE_WITH_LOG_PHI_DISABLED, exceptionMessage); + } + + @Test + public void testLogPhiEnabled() throws Exception { + System.setProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "true"); + + String exceptionMessage = exception.getMessage(); + + assertEquals(EXCEPTION_MESSAGE_WITH_LOG_PHI_ENABLED, exceptionMessage); + } + + @Test + public void testNullPayload() throws Exception { + final String expectedMessage = String.format("%s:\n\tMLLP Payload: null", EXCEPTION_MESSAGE); + + exception = new MllpFrameException(EXCEPTION_MESSAGE, null); + + System.setProperty(MllpComponent.MLLP_LOG_PHI_PROPERTY, "true"); + String exceptionMessage = exception.getMessage(); + + assertEquals(expectedMessage, exceptionMessage); + } + @Test + public void testToString() throws Exception { + final String expectedString = + "org.apache.camel.component.mllp.MllpFrameException: " + + "{mllpPayload=" + + "MSH|^~\\&|APP_A|FAC_A|^org^sys||||ADT^A04^ADT_A04|||2.6<CR>" + + "PID|1||1100832^^^^PI||TEST^FIG||98765432|U||R|435 MAIN STREET^^LONGMONT^CO^80503||123-456-7890|||S<CR><CR><LF>" + + "}"; + + assertEquals(expectedString, exception.toString()); + } + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackTest.java index d96b24d..116e67c 100644 --- a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackTest.java +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackTest.java @@ -30,12 +30,12 @@ import org.apache.camel.test.junit4.CamelTestSupport; import org.apache.camel.test.mllp.PassthroughProcessor; import org.hamcrest.CoreMatchers; import org.junit.Assert; -import org.junit.Ignore; +import org.junit.BeforeClass; import org.junit.Test; import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage; +import static org.junit.Assume.assumeTrue; -@Ignore("Fails sometimes on CI server with address already in use") public class MllpProducerConsumerLoopbackTest extends CamelTestSupport { int mllpPort = AvailablePortFinder.getNextAvailable(); String mllpHost = "localhost"; @@ -56,6 +56,10 @@ public class MllpProducerConsumerLoopbackTest extends CamelTestSupport { return context; } + @BeforeClass + public static void setUpClass() throws Exception { + assumeTrue("Skipping test running in CI server - Fails sometimes on CI server with address already in use", System.getenv("BUILD_ID") == null); + } @Override protected RouteBuilder[] createRouteBuilders() throws Exception { http://git-wip-us.apache.org/repos/asf/camel/blob/62715117/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java ---------------------------------------------------------------------- diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java index 2dcd40b..6edc48c 100644 --- a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java +++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpClientProducerTest.java @@ -67,7 +67,6 @@ public class MllpTcpClientProducerTest extends CamelTestSupport { @Override protected RouteBuilder createRouteBuilder() { - return new RouteBuilder() { int connectTimeout = 1000; int responseTimeout = 1000; @@ -76,34 +75,27 @@ public class MllpTcpClientProducerTest extends CamelTestSupport { public void configure() throws Exception { errorHandler( defaultErrorHandler().allowRedeliveryWhileStopping(false)); - - onException(MllpCorruptFrameException.class) + onException(MllpFrameException.class) .handled(true) .logHandled(false) .to(frame); - onException(MllpTimeoutException.class) .handled(true) .logHandled(false) .to(timeout); - onCompletion() .onFailureOnly().log(LoggingLevel.ERROR, "Processing Failed"); - from(source.getDefaultEndpoint()) .routeId("mllp-sender-test-route") .log(LoggingLevel.INFO, "Sending Message: $simple{header[CamelHL7MessageControl]}") .toF("mllp://%s:%d?connectTimeout=%d&receiveTimeout=%d", mllpServer.getListenHost(), mllpServer.getListenPort(), connectTimeout, responseTimeout) .to(acknowledged); - from("direct://handle-timeout") .log(LoggingLevel.ERROR, "Response Timeout") .rollback(); - } }; - } @Test