This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 7aea258  CAMEL-15731: Add support for InOnly exchange pattern to 
camel-mllp (#4552)
7aea258 is described below

commit 7aea258261fcf791227d3872faf44d6f017ab4d9
Author: rafaljaw <42240185+rafal...@users.noreply.github.com>
AuthorDate: Tue Nov 3 07:24:14 2020 +0100

    CAMEL-15731: Add support for InOnly exchange pattern to camel-mllp (#4552)
    
    * CAMEL-15731: Add support for InOnly exchange pattern to camel-mllp
    
    * CAMEL-15731: Code review changes
    
    * CAMEL-15731: Regenerate documentation for camel-mllp
    
    Co-authored-by: Rafal Jaworski <rafal.jawor...@inveox.com>
---
 .../apache/camel/catalog/docs/mllp-component.adoc  |   7 +-
 .../camel-mllp/src/main/docs/mllp-component.adoc   |   7 +-
 .../component/mllp/MllpTcpClientProducer.java      |   7 +-
 .../component/mllp/MllpTcpServerConsumer.java      |  35 ++++----
 .../MllpProducerConsumerLoopbackInOnlyTest.java    |  91 +++++++++++++++++++
 ...wledgementWithBridgeErrorHandlerInOnlyTest.java | 100 +++++++++++++++++++++
 ...cpServerConsumerAcknowledgementTestSupport.java |  11 ++-
 .../modules/ROOT/pages/mllp-component.adoc         |   7 +-
 8 files changed, 239 insertions(+), 26 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
index a0a558d..099ff34 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mllp-component.adoc
@@ -146,7 +146,9 @@ HL7 Acknowledgement (HL7 Application Acknowledgements only 
- AA, AE and
 AR), or the acknowledgement can be specified using
 the CamelMllpAcknowledgement exchange property.  Additionally, the type
 of acknowledgement that will be generated can be controlled by setting
-the CamelMllpAcknowledgementType exchange property.
+the CamelMllpAcknowledgementType exchange property. The MLLP Consumer
+can read messages without sending any HL7 Acknowledgement if the
+automatic acknowledgement is disabled and exchange pattern is InOnly.
 
 == *Message Headers*
 
@@ -204,7 +206,8 @@ The MLLP Producer supports sending MLLP-framed messages and 
receiving
 HL7 Acknowledgements.  The MLLP Producer interrogates the HL7
 Acknowledgments and raises exceptions if a negative acknowledgement is
 received.  The received acknowledgement is interrogated and an exception
-is raised in the event of a negative acknowledgement.
+is raised in the event of a negative acknowledgement. The MLLP Producer
+can ignore acknowledgements when configured with InOnly exchange pattern.
 
 == *Message Headers*
 
diff --git a/components/camel-mllp/src/main/docs/mllp-component.adoc 
b/components/camel-mllp/src/main/docs/mllp-component.adoc
index a0a558d..099ff34 100644
--- a/components/camel-mllp/src/main/docs/mllp-component.adoc
+++ b/components/camel-mllp/src/main/docs/mllp-component.adoc
@@ -146,7 +146,9 @@ HL7 Acknowledgement (HL7 Application Acknowledgements only 
- AA, AE and
 AR), or the acknowledgement can be specified using
 the CamelMllpAcknowledgement exchange property.  Additionally, the type
 of acknowledgement that will be generated can be controlled by setting
-the CamelMllpAcknowledgementType exchange property.
+the CamelMllpAcknowledgementType exchange property. The MLLP Consumer
+can read messages without sending any HL7 Acknowledgement if the
+automatic acknowledgement is disabled and exchange pattern is InOnly.
 
 == *Message Headers*
 
@@ -204,7 +206,8 @@ The MLLP Producer supports sending MLLP-framed messages and 
receiving
 HL7 Acknowledgements.  The MLLP Producer interrogates the HL7
 Acknowledgments and raises exceptions if a negative acknowledgement is
 received.  The received acknowledgement is interrogated and an exception
-is raised in the event of a negative acknowledgement.
+is raised in the event of a negative acknowledgement. The MLLP Producer
+can ignore acknowledgements when configured with InOnly exchange pattern.
 
 == *Message Headers*
 
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 c247ee7..160ee6a 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
@@ -29,6 +29,7 @@ import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
 import org.apache.camel.Message;
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedOperation;
@@ -193,7 +194,11 @@ public class MllpTcpClientProducer extends DefaultProducer 
implements Runnable {
                     mllpBuffer.resetSocket(socket);
                 }
             }
-
+            if (getConfiguration().getExchangePattern() == 
ExchangePattern.InOnly) {
+                log.debug("process({}) [{}] - not checking acknowledgement 
from external system",
+                        exchange.getExchangeId(), socket);
+                return;
+            }
             if (exchange.getException() == null) {
                 log.debug("process({}) [{}] - reading acknowledgement from 
external system", exchange.getExchangeId(), socket);
                 try {
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 0702678..d43c356 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
@@ -411,22 +411,25 @@ public class MllpTcpServerConsumer extends 
DefaultConsumer {
 
             boolean autoAck = 
exchange.getProperty(MllpConstants.MLLP_AUTO_ACKNOWLEDGE, true, boolean.class);
             if (!autoAck) {
-                Object acknowledgementBytesProperty = 
exchange.getProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT);
-                Object acknowledgementStringProperty = 
exchange.getProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING);
-                final String exceptionMessage = (acknowledgementBytesProperty 
== null && acknowledgementStringProperty == null)
-                        ? "Automatic Acknowledgement is disabled and the "
-                          + MllpConstants.MLLP_ACKNOWLEDGEMENT + " and " + 
MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING
-                          + " exchange properties are null"
-                        : "Automatic Acknowledgement is disabled and neither 
the "
-                          + MllpConstants.MLLP_ACKNOWLEDGEMENT + "(type = "
-                          + 
acknowledgementBytesProperty.getClass().getSimpleName() + ") nor the"
-                          + MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING + "(type 
= "
-                          + 
acknowledgementBytesProperty.getClass().getSimpleName()
-                          + ") exchange properties can be converted to byte[]";
-                MllpInvalidAcknowledgementException invalidAckEx = new 
MllpInvalidAcknowledgementException(
-                        exceptionMessage, originalHl7MessageBytes, 
acknowledgementMessageBytes);
-                
exchange.setProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT_EXCEPTION, 
invalidAckEx);
-                getExceptionHandler().handleException(invalidAckEx);
+                if (getConfiguration().getExchangePattern() == 
ExchangePattern.InOut) {
+                    Object acknowledgementBytesProperty = 
exchange.getProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT);
+                    Object acknowledgementStringProperty = 
exchange.getProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING);
+                    final String exceptionMessage
+                            = (acknowledgementBytesProperty == null && 
acknowledgementStringProperty == null)
+                                    ? "Automatic Acknowledgement is disabled 
and the "
+                                      + MllpConstants.MLLP_ACKNOWLEDGEMENT + " 
and " + MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING
+                                      + " exchange properties are null"
+                                    : "Automatic Acknowledgement is disabled 
and neither the "
+                                      + MllpConstants.MLLP_ACKNOWLEDGEMENT + 
"(type = "
+                                      + 
acknowledgementBytesProperty.getClass().getSimpleName() + ") nor the"
+                                      + 
MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING + "(type = "
+                                      + 
acknowledgementBytesProperty.getClass().getSimpleName()
+                                      + ") exchange properties can be 
converted to byte[]";
+                    MllpInvalidAcknowledgementException invalidAckEx = new 
MllpInvalidAcknowledgementException(
+                            exceptionMessage, originalHl7MessageBytes, 
acknowledgementMessageBytes);
+                    
exchange.setProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT_EXCEPTION, 
invalidAckEx);
+                    getExceptionHandler().handleException(invalidAckEx);
+                }
             } else {
                 String acknowledgmentTypeProperty = 
exchange.getProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT_TYPE, String.class);
                 String msa3 = 
exchange.getProperty(MllpConstants.MLLP_ACKNOWLEDGEMENT_MSA_TEXT, String.class);
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackInOnlyTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackInOnlyTest.java
new file mode 100644
index 0000000..cc30aa8
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpProducerConsumerLoopbackInOnlyTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.ProducerTemplate;
+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.junit5.CamelTestSupport;
+import org.apache.camel.test.mllp.Hl7TestMessageGenerator;
+import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class MllpProducerConsumerLoopbackInOnlyTest extends CamelTestSupport {
+
+    @EndpointInject("direct://source")
+    ProducerTemplate source;
+
+    @EndpointInject("mock://received-and-processed")
+    MockEndpoint receivedAndProcessed;
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        DefaultCamelContext context = (DefaultCamelContext) 
super.createCamelContext();
+
+        context.setUseMDCLogging(false);
+        context.setName(this.getClass().getSimpleName());
+
+        return context;
+    }
+
+    @Override
+    protected RouteBuilder[] createRouteBuilders() throws Exception {
+        String mllpHost = "localhost";
+        int mllpPort = AvailablePortFinder.getNextAvailable();
+
+        return new RouteBuilder[] {
+                new RouteBuilder() {
+
+                    @Override
+                    public void configure() {
+                        
fromF("mllp://%s:%d?autoAck=false&exchangePattern=InOnly", mllpHost, mllpPort)
+                                .convertBodyTo(String.class)
+                                .to(receivedAndProcessed);
+                    }
+                },
+
+                new RouteBuilder() {
+
+                    @Override
+                    public void configure() {
+                        from(source.getDefaultEndpoint())
+                                .toF("mllp://%s:%d?exchangePattern=InOnly", 
mllpHost, mllpPort)
+                                
.setBody(header(MllpConstants.MLLP_ACKNOWLEDGEMENT));
+                    }
+                }
+        };
+    }
+
+    @Test
+    public void testLoopbackWithOneMessage() throws Exception {
+        String testMessage = Hl7TestMessageGenerator.generateMessage();
+        receivedAndProcessed.expectedBodiesReceived(testMessage);
+
+        String acknowledgement = source.requestBody((Object) testMessage, 
String.class);
+        assertThat("Should receive no acknowledgment for message 1", 
acknowledgement, CoreMatchers.nullValue());
+
+        assertMockEndpointsSatisfied(60, TimeUnit.SECONDS);
+    }
+}
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerManualAcknowledgementWithBridgeErrorHandlerInOnlyTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerManualAcknowledgementWithBridgeErrorHandlerInOnlyTest.java
new file mode 100644
index 0000000..a9e4a91
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerManualAcknowledgementWithBridgeErrorHandlerInOnlyTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class 
MllpTcpServerConsumerManualAcknowledgementWithBridgeErrorHandlerInOnlyTest
+        extends TcpServerConsumerAcknowledgementTestSupport {
+
+    @Override
+    protected boolean isBridgeErrorHandler() {
+        return true;
+    }
+
+    @Override
+    protected boolean isAutoAck() {
+        return false;
+    }
+
+    @Override
+    protected ExchangePattern exchangePattern() {
+        return ExchangePattern.InOnly;
+    }
+
+    @Test
+    public void testReceiveSingleMessage() throws Exception {
+        result.expectedBodiesReceived(TEST_MESSAGE);
+        complete.expectedBodiesReceived(TEST_MESSAGE);
+
+        receiveSingleMessage();
+
+        Exchange completeExchange = complete.getReceivedExchanges().get(0);
+
+        
assertNull(completeExchange.getIn().getHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT));
+        
assertNull(completeExchange.getIn().getHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING));
+    }
+
+    @Test
+    public void testUnparsableMessage() throws Exception {
+        final String testMessage = "MSH" + TEST_MESSAGE;
+
+        result.expectedBodiesReceived(testMessage);
+        complete.expectedMessageCount(1);
+
+        unparsableMessage(testMessage);
+
+        
assertNull(result.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT),
+                "Should not have the exception in the exchange property");
+        
assertNull(complete.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT),
+                "Should not have the exception in the exchange property");
+    }
+
+    @Test
+    public void testMessageWithEmptySegment() throws Exception {
+        final String testMessage = TEST_MESSAGE.replace("\rPID|", "\r\rPID|");
+
+        result.expectedBodiesReceived(testMessage);
+        complete.expectedMessageCount(1);
+
+        unparsableMessage(testMessage);
+
+        
assertNull(result.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT),
+                "Should not have the exception in the exchange property");
+        
assertNull(complete.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT),
+                "Should not have the exception in the exchange property");
+    }
+
+    @Test
+    public void testMessageWithEmbeddedNewlines() throws Exception {
+        final String testMessage = TEST_MESSAGE.replace("\rPID|", 
"\r\n\rPID|\n");
+
+        result.expectedBodiesReceived(testMessage);
+        complete.expectedMessageCount(1);
+
+        unparsableMessage(testMessage);
+
+        
assertNull(result.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT),
+                "Should not have the exception in the exchange property");
+        
assertNull(complete.getReceivedExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT),
+                "Should not have the exception in the exchange property");
+    }
+}
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/TcpServerConsumerAcknowledgementTestSupport.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/TcpServerConsumerAcknowledgementTestSupport.java
index a83e9e5..2dad764 100644
--- 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/TcpServerConsumerAcknowledgementTestSupport.java
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/TcpServerConsumerAcknowledgementTestSupport.java
@@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.EndpointInject;
+import org.apache.camel.ExchangePattern;
 import org.apache.camel.LoggingLevel;
 import org.apache.camel.builder.NotifyBuilder;
 import org.apache.camel.builder.RouteBuilder;
@@ -110,9 +111,9 @@ public abstract class 
TcpServerConsumerAcknowledgementTestSupport extends CamelT
                         .log(LoggingLevel.INFO, routeId, "Test route complete")
                         .to("mock://on-failure-only");
 
-                
fromF("mllp://%s:%d?bridgeErrorHandler=%b&autoAck=%b&connectTimeout=%d&receiveTimeout=%d",
-                        mllpClient.getMllpHost(), mllpClient.getMllpPort(), 
isBridgeErrorHandler(), isAutoAck(), connectTimeout,
-                        responseTimeout)
+                
fromF("mllp://%s:%d?bridgeErrorHandler=%b&autoAck=%b&exchangePattern=%s&connectTimeout=%d&receiveTimeout=%d",
+                        mllpClient.getMllpHost(), mllpClient.getMllpPort(), 
isBridgeErrorHandler(), isAutoAck(),
+                        exchangePattern(), connectTimeout, responseTimeout)
                                 .routeId(routeId)
                                 .to(result);
             }
@@ -123,6 +124,10 @@ public abstract class 
TcpServerConsumerAcknowledgementTestSupport extends CamelT
 
     protected abstract boolean isAutoAck();
 
+    protected ExchangePattern exchangePattern() {
+        return ExchangePattern.InOut;
+    }
+
     public void receiveSingleMessage() throws Exception {
         NotifyBuilder done = new NotifyBuilder(context).whenDone(1).create();
 
diff --git a/docs/components/modules/ROOT/pages/mllp-component.adoc 
b/docs/components/modules/ROOT/pages/mllp-component.adoc
index 27b3c6b..d282b74 100644
--- a/docs/components/modules/ROOT/pages/mllp-component.adoc
+++ b/docs/components/modules/ROOT/pages/mllp-component.adoc
@@ -148,7 +148,9 @@ HL7 Acknowledgement (HL7 Application Acknowledgements only 
- AA, AE and
 AR), or the acknowledgement can be specified using
 the CamelMllpAcknowledgement exchange property.  Additionally, the type
 of acknowledgement that will be generated can be controlled by setting
-the CamelMllpAcknowledgementType exchange property.
+the CamelMllpAcknowledgementType exchange property. The MLLP Consumer
+can read messages without sending any HL7 Acknowledgement if the
+automatic acknowledgement is disabled and exchange pattern is InOnly.
 
 == *Message Headers*
 
@@ -206,7 +208,8 @@ The MLLP Producer supports sending MLLP-framed messages and 
receiving
 HL7 Acknowledgements.  The MLLP Producer interrogates the HL7
 Acknowledgments and raises exceptions if a negative acknowledgement is
 received.  The received acknowledgement is interrogated and an exception
-is raised in the event of a negative acknowledgement.
+is raised in the event of a negative acknowledgement. The MLLP Producer
+can ignore acknowledgements when configured with InOnly exchange pattern.
 
 == *Message Headers*
 

Reply via email to