http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMessageValidationTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMessageValidationTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMessageValidationTest.java
new file mode 100644
index 0000000..5c431e6
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerMessageValidationTest.java
@@ -0,0 +1,317 @@
+/**
+ * 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.CamelContext;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.builder.NotifyBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.test.AvailablePortFinder;
+import org.apache.camel.test.junit.rule.mllp.MllpClientResource;
+import org.apache.camel.test.junit.rule.mllp.MllpJUnitResourceException;
+import org.apache.camel.test.junit.rule.mllp.MllpJUnitResourceTimeoutException;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_BLOCK;
+import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
+import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage;
+
+public class MllpTcpServerConsumerMessageValidationTest extends 
CamelTestSupport {
+    @Rule
+    public MllpClientResource mllpClient = new MllpClientResource();
+
+    @EndpointInject(uri = "mock://result")
+    MockEndpoint result;
+
+    @EndpointInject(uri = "mock://timeout-ex")
+    MockEndpoint timeout;
+
+    @EndpointInject(uri = "mock://invalid-ex")
+    MockEndpoint invalid;
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        DefaultCamelContext context = (DefaultCamelContext) 
super.createCamelContext();
+
+        context.setUseMDCLogging(true);
+        context.setName(this.getClass().getSimpleName());
+
+        return context;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+
+        mllpClient.setMllpHost("localhost");
+        mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable());
+
+        return new RouteBuilder() {
+            int connectTimeout = 500;
+            int responseTimeout = 5000;
+
+            @Override
+            public void configure() throws Exception {
+                String routeId = "mllp-test-receiver-route";
+
+                onException(MllpTimeoutException.class)
+                        .to(timeout);
+
+                onException(MllpInvalidMessageException.class)
+                        .to(invalid);
+
+                
fromF("mllp://%s:%d?validatePayload=true&autoAck=true&connectTimeout=%d&receiveTimeout=%d",
+                        mllpClient.getMllpHost(), mllpClient.getMllpPort(), 
connectTimeout, responseTimeout)
+                        .routeId(routeId)
+                        .log(LoggingLevel.INFO, routeId, "Test route received 
message")
+                        .to(result);
+
+            }
+        };
+    }
+
+    @Test
+    public void testReceiveSingleMessage() throws Exception {
+        result.expectedMessageCount(1);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(0);
+
+        mllpClient.connect();
+
+        mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(), 
10000);
+
+        assertMockEndpointsSatisfied(10, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testReceiveSingleMessageWithDelayAfterConnection() throws 
Exception {
+        result.expectedMinimumMessageCount(1);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(0);
+
+        mllpClient.connect();
+
+        Thread.sleep(5000);
+        mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(), 
10000);
+
+        assertMockEndpointsSatisfied(10, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testReceiveMultipleMessages() throws Exception {
+        int sendMessageCount = 5;
+        result.expectedMinimumMessageCount(5);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(0);
+
+        mllpClient.connect();
+
+        for (int i = 1; i <= sendMessageCount; ++i) {
+            
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(i));
+        }
+
+        assertMockEndpointsSatisfied(10, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testOpenMllpEnvelopeWithReset() throws Exception {
+        result.expectedMessageCount(4);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(1);
+        invalid.expectedMessageCount(0);
+
+        NotifyBuilder notify1 = new 
NotifyBuilder(context).whenDone(2).create();
+        NotifyBuilder notify2 = new 
NotifyBuilder(context).whenDone(5).create();
+
+        mllpClient.connect();
+        mllpClient.setSoTimeout(10000);
+
+        log.info("Sending TEST_MESSAGE_1");
+        String acknowledgement1 = 
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(1));
+
+        log.info("Sending TEST_MESSAGE_2");
+        String acknowledgement2 = 
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(2));
+
+        assertTrue("First two normal exchanges did not complete", 
notify1.matches(10, TimeUnit.SECONDS));
+
+        log.info("Sending TEST_MESSAGE_3");
+        mllpClient.setSendEndOfBlock(false);
+        mllpClient.setSendEndOfData(false);
+        // Acknowledgement won't come here
+        try {
+            
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(3));
+        } catch (MllpJUnitResourceException resourceEx) {
+            log.info("Expected exception reading response");
+        }
+        mllpClient.disconnect();
+        Thread.sleep(1000);
+        mllpClient.connect();
+
+        log.info("Sending TEST_MESSAGE_4");
+        mllpClient.setSendEndOfBlock(true);
+        mllpClient.setSendEndOfData(true);
+        String acknowledgement4 = 
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(4));
+
+        log.info("Sending TEST_MESSAGE_5");
+        String acknowledgement5 = 
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(5));
+
+        assertTrue("Remaining exchanges did not complete", notify2.matches(10, 
TimeUnit.SECONDS));
+
+        assertMockEndpointsSatisfied(10, TimeUnit.SECONDS);
+
+        assertTrue("Should be acknowledgment for message 1", 
acknowledgement1.contains("MSA|AA|00001"));
+        assertTrue("Should be acknowledgment for message 2", 
acknowledgement2.contains("MSA|AA|00002"));
+        // assertTrue("Should be acknowledgment for message 3", 
acknowledgement3.contains("MSA|AA|00003"));
+        assertTrue("Should be acknowledgment for message 4", 
acknowledgement4.contains("MSA|AA|00004"));
+        assertTrue("Should be acknowledgment for message 5", 
acknowledgement5.contains("MSA|AA|00005"));
+    }
+
+    @Test
+    public void testMessageReadTimeout() throws Exception {
+        result.expectedMessageCount(0);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(1);
+        invalid.expectedMessageCount(0);
+
+        NotifyBuilder notify = new NotifyBuilder(context).whenDone(1).create();
+
+        mllpClient.setSendEndOfBlock(false);
+        mllpClient.setSendEndOfData(false);
+
+        mllpClient.sendFramedData(generateMessage());
+
+        assertTrue("One exchange should have completed", notify.matches(15, 
TimeUnit.SECONDS));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testInvalidMessage() throws Exception {
+        result.expectedMessageCount(0);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(1);
+
+        mllpClient.sendFramedData("INVALID PAYLOAD");
+
+        assertMockEndpointsSatisfied(15, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testNthInvalidMessage() throws Exception {
+        int messageCount = 10;
+
+        result.expectedMessageCount(messageCount - 1);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(1);
+
+        for (int i = 0; i < messageCount; ++i) {
+            if (i == messageCount / 2) {
+                try {
+                    mllpClient.sendMessageAndWaitForAcknowledgement("INVALID 
PAYLOAD");
+                    fail("An acknowledgement should not be received for an 
invalid HL7 message");
+                } catch (MllpJUnitResourceTimeoutException timeoutEx) {
+                    // expected - eat this
+                }
+            } else {
+                
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(i + 1));
+            }
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testMessageContainingEmbeddedStartOfBlock() throws Exception {
+        result.expectedMessageCount(0);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(1);
+
+        
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage().replaceFirst("EVN",
 "EVN" + START_OF_BLOCK));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testNthMessageContainingEmbeddedStartOfBlock() throws 
Exception {
+        int messageCount = 10;
+
+        result.expectedMessageCount(messageCount - 1);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(1);
+
+        for (int i = 0; i < messageCount; ++i) {
+            String message = (i == (messageCount/2))
+                    ? generateMessage(i + 1).replaceFirst("EVN", "EVN" + 
START_OF_BLOCK)
+                    : generateMessage(i + 1);
+
+            log.debug("Sending message {}", 
MllpComponent.covertToPrintFriendlyString(message));
+
+            mllpClient.sendMessageAndWaitForAcknowledgement(message);
+        }
+
+        assertMockEndpointsSatisfied(15, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testMessageContainingEmbeddedEndOfBlock() throws Exception {
+        result.expectedMessageCount(0);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(1);
+
+        
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage().replaceFirst("EVN",
 "EVN" + END_OF_BLOCK));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testInvalidMessageContainingEmbeddedEndOfBlock() throws 
Exception {
+        int messageCount = 10;
+
+        result.expectedMessageCount(messageCount - 1);
+        result.setAssertPeriod(1000);
+        timeout.expectedMessageCount(0);
+        invalid.expectedMessageCount(1);
+
+        for (int i = 0; i < messageCount; ++i) {
+            String message = (i == (messageCount/2))
+                    ? generateMessage(i + 1).replaceFirst("EVN", "EVN" + 
END_OF_BLOCK)
+                    : generateMessage(i + 1);
+
+            log.debug("Sending message {}", 
MllpComponent.covertToPrintFriendlyString(message));
+
+            mllpClient.sendMessageAndWaitForAcknowledgement(message);
+        }
+
+        assertMockEndpointsSatisfied(15, TimeUnit.SECONDS);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java
index eb6a463..6d05883 100644
--- 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerConsumerTest.java
@@ -30,10 +30,15 @@ import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.test.AvailablePortFinder;
 import org.apache.camel.test.junit.rule.mllp.MllpClientResource;
 import org.apache.camel.test.junit.rule.mllp.MllpJUnitResourceException;
+import org.apache.camel.test.junit.rule.mllp.MllpJUnitResourceTimeoutException;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.junit.Rule;
 import org.junit.Test;
 
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_BLOCK;
+import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
 import static org.apache.camel.test.mllp.Hl7MessageGenerator.generateMessage;
 
 public class MllpTcpServerConsumerTest extends CamelTestSupport {
@@ -43,6 +48,9 @@ public class MllpTcpServerConsumerTest extends 
CamelTestSupport {
     @EndpointInject(uri = "mock://result")
     MockEndpoint result;
 
+    @EndpointInject(uri = "mock://timeout-ex")
+    MockEndpoint timeout;
+
     @Override
     protected CamelContext createCamelContext() throws Exception {
         DefaultCamelContext context = (DefaultCamelContext) 
super.createCamelContext();
@@ -67,9 +75,8 @@ public class MllpTcpServerConsumerTest extends 
CamelTestSupport {
             public void configure() throws Exception {
                 String routeId = "mllp-test-receiver-route";
 
-                onCompletion()
-                        .toF("log:%s?level=INFO&showAll=true", routeId)
-                        .log(LoggingLevel.INFO, routeId, "Test route 
complete");
+                onException(MllpTimeoutException.class)
+                        .to(timeout);
 
                 
fromF("mllp://%s:%d?autoAck=true&connectTimeout=%d&receiveTimeout=%d",
                         mllpClient.getMllpHost(), mllpClient.getMllpPort(), 
connectTimeout, responseTimeout)
@@ -84,6 +91,7 @@ public class MllpTcpServerConsumerTest extends 
CamelTestSupport {
     @Test
     public void testReceiveSingleMessage() throws Exception {
         result.expectedMessageCount(1);
+        timeout.expectedMessageCount(0);
 
         mllpClient.connect();
 
@@ -95,6 +103,7 @@ public class MllpTcpServerConsumerTest extends 
CamelTestSupport {
     @Test
     public void testReceiveSingleMessageWithDelayAfterConnection() throws 
Exception {
         result.expectedMinimumMessageCount(1);
+        timeout.expectedMessageCount(0);
 
         mllpClient.connect();
 
@@ -108,6 +117,7 @@ public class MllpTcpServerConsumerTest extends 
CamelTestSupport {
     public void testReceiveMultipleMessages() throws Exception {
         int sendMessageCount = 5;
         result.expectedMinimumMessageCount(5);
+        timeout.expectedMessageCount(0);
 
         mllpClient.connect();
 
@@ -121,6 +131,7 @@ public class MllpTcpServerConsumerTest extends 
CamelTestSupport {
     @Test
     public void testOpenMllpEnvelopeWithReset() throws Exception {
         result.expectedMessageCount(4);
+        timeout.expectedMessageCount(1);
         NotifyBuilder notify1 = new 
NotifyBuilder(context).whenDone(2).create();
         NotifyBuilder notify2 = new 
NotifyBuilder(context).whenDone(5).create();
 
@@ -167,5 +178,114 @@ public class MllpTcpServerConsumerTest extends 
CamelTestSupport {
         assertTrue("Should be acknowledgment for message 5", 
acknowledgement5.contains("MSA|AA|00005"));
     }
 
+    @Test
+    public void testMessageReadTimeout() throws Exception {
+        result.expectedMessageCount(0);
+        timeout.expectedMessageCount(1);
+
+        NotifyBuilder notify = new NotifyBuilder(context).whenDone(1).create();
+
+        mllpClient.setSendEndOfBlock(false);
+        mllpClient.setSendEndOfData(false);
+
+        mllpClient.sendFramedData(generateMessage());
+
+        assertTrue("One exchange should have completed", notify.matches(15, 
TimeUnit.SECONDS));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testInvalidMessage() throws Exception {
+        result.expectedMessageCount(1);
+        timeout.expectedMessageCount(0);
+
+        mllpClient.sendFramedData("INVALID PAYLOAD");
+
+        assertMockEndpointsSatisfied(15, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testNthInvalidMessage() throws Exception {
+        int messageCount = 10;
+
+        result.expectedMessageCount(messageCount);
+        timeout.expectedMessageCount(0);
+
+        for (int i = 0; i < messageCount; ++i) {
+            if (i == messageCount / 2) {
+                try {
+                    mllpClient.sendMessageAndWaitForAcknowledgement("INVALID 
PAYLOAD");
+                    fail("An acknowledgement should not be received for an 
invalid HL7 message");
+                } catch (MllpJUnitResourceTimeoutException timeoutEx) {
+                    // expected - eat this
+                }
+            } else {
+                
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage(i + 1));
+            }
+        }
+
+        assertMockEndpointsSatisfied(15, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testMessageContainingEmbeddedStartOfBlock() throws Exception {
+        result.expectedMessageCount(1);
+        timeout.expectedMessageCount(0);
+
+        
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage().replaceFirst("EVN",
 "EVN" + START_OF_BLOCK));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testNthMessageContainingEmbeddedStartOfBlock() throws 
Exception {
+        int messageCount = 10;
+
+        result.expectedMessageCount(messageCount);
+        timeout.expectedMessageCount(0);
+
+        for (int i = 0; i < messageCount; ++i) {
+            String message = (i == (messageCount/2))
+                    ? generateMessage(i + 1).replaceFirst("EVN", "EVN" + 
START_OF_BLOCK)
+                    : generateMessage(i + 1);
+
+            log.debug("Sending message {}", 
MllpComponent.covertToPrintFriendlyString(message));
+
+            mllpClient.sendMessageAndWaitForAcknowledgement(message);
+        }
+
+        assertMockEndpointsSatisfied(15, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testMessageContainingEmbeddedEndOfBlock() throws Exception {
+        result.expectedMessageCount(1);
+        timeout.expectedMessageCount(0);
+
+        
mllpClient.sendMessageAndWaitForAcknowledgement(generateMessage().replaceFirst("EVN",
 "EVN" + END_OF_BLOCK));
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testInvalidMessageContainingEmbeddedEndOfBlock() throws 
Exception {
+        int messageCount = 10;
+
+        result.expectedMessageCount(messageCount);
+        timeout.expectedMessageCount(0);
+
+        for (int i = 0; i < messageCount; ++i) {
+            String message = (i == (messageCount/2))
+                    ? generateMessage(i + 1).replaceFirst("EVN", "EVN" + 
END_OF_BLOCK)
+                    : generateMessage(i + 1);
+
+            log.debug("Sending message {}", 
MllpComponent.covertToPrintFriendlyString(message));
+
+            mllpClient.sendMessageAndWaitForAcknowledgement(message);
+        }
+
+        assertMockEndpointsSatisfied(15, TimeUnit.SECONDS);
+    }
 }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java
deleted file mode 100644
index dc796a5..0000000
--- 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerProducerBlueprintTest.java
+++ /dev/null
@@ -1,35 +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;
-
-import org.apache.camel.EndpointInject;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
-import org.junit.Ignore;
-
-@Ignore(value = "Not Yet Implemented")
-// TODO: Implement this
-public class MllpTcpServerProducerBlueprintTest extends 
CamelBlueprintTestSupport {
-    @EndpointInject(uri = "mock://target")
-    MockEndpoint target;
-
-    @Override
-    protected String getBlueprintDescriptor() {
-        return "OSGI-INF/blueprint/mllp-tcp-server-producer.xml";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTimeoutExceptionTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTimeoutExceptionTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTimeoutExceptionTest.java
deleted file mode 100644
index da4ceb7..0000000
--- 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTimeoutExceptionTest.java
+++ /dev/null
@@ -1,101 +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;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class MllpTimeoutExceptionTest {
-    static final String EXCEPTION_MESSAGE = "Test Timeoute 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\tHL7 Message: %s",
-                    EXCEPTION_MESSAGE,
-                    new String(HL7_MESSAGE).replaceAll("\r", 
"<CR>").replaceAll("\n", "<LF>"))
-            );
-
-    Exception exception;
-
-    @Before
-    public void setUp() throws Exception {
-        exception = new MllpTimeoutException(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\tHL7 Message: 
null", EXCEPTION_MESSAGE);
-
-        exception = new MllpTimeoutException(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.MllpTimeoutException: "
-                        + "{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>"
-                        + "}";
-
-        assertEquals(expectedString, exception.toString());
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpWriteExceptionTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpWriteExceptionTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpWriteExceptionTest.java
deleted file mode 100644
index daf7fe9..0000000
--- 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpWriteExceptionTest.java
+++ /dev/null
@@ -1,101 +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;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class MllpWriteExceptionTest {
-    static final String EXCEPTION_MESSAGE = "Test Write 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 MllpWriteException(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 MllpWriteException(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.MllpWriteException: "
-                        + "{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/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/Hl7UtilTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/Hl7UtilTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/Hl7UtilTest.java
new file mode 100644
index 0000000..e7d443c
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/Hl7UtilTest.java
@@ -0,0 +1,126 @@
+/**
+ * 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.ByteArrayOutputStream;
+
+import org.junit.Test;
+
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_BLOCK;
+import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class Hl7UtilTest {
+    static final String TEST_MESSAGE =
+        
"MSH|^~\\&|ADT|EPIC|JCAPS|CC|20161206193919|RISTECH|ADT^A08|00001|D|2.3^^|||||||"
 + '\r'
+            + 
"EVN|A08|20150107161440||REG_UPDATE_SEND_VISIT_MESSAGES_ON_PATIENT_CHANGES|RISTECH^RADIOLOGY^TECHNOLOGIST^^^^^^UCLA^^^^^RRMC||"
 + '\r'
+            + 
"PID|1|2100355^^^MRN^MRN|2100355^^^MRN^MRN||MDCLS9^MC9||19700109|F||U|111 HOVER 
STREET^^LOS ANGELES^CA^90032^USA^P^^LOS ANGELE|"
+                + "LOS 
ANGELE|(310)725-6952^P^PH^^^310^7256952||ENGLISH|U||60000013647|565-33-2222|||U||||||||N||"
 + '\r'
+            + "PD1|||UCLA HEALTH 
SYSTEM^^10|10002116^ADAMS^JOHN^D^^^^^EPIC^^^^PROVID||||||||||||||" + '\r'
+            + 
"NK1|1|DOE^MC9^^|OTH|^^^^^USA|(310)888-9999^^^^^310^8889999|(310)999-2222^^^^^310^9992222|Emergency
 Contact 1|||||||||||||||||||||||||||" + '\r'
+            + "PV1|1|OUTPATIENT|RR 
CT^^^1000^^^^^^^DEPID|EL|||017511^TOBIAS^JONATHAN^^^^^^EPIC^^^^PROVID|017511^TOBIAS^JONATHAN^^^^^^EPIC^^^^PROVID||||||"
+                + 
"CLR|||||60000013647|SELF|||||||||||||||||||||HOV_CONF|^^^1000^^^^^^^||20150107161438||||||||||"
 + '\r'
+            + "PV2||||||||20150107161438||||CT BRAIN W WO 
CONTRAST||||||||||N|||||||||||||||||||||||||||" + '\r'
+            + "ZPV||||||||||||20150107161438|||||||||" + '\r'
+            + "AL1|1||33361^NO KNOWN ALLERGIES^^NOTCOMPUTRITION^NO KNOWN 
ALLERGIES^EXTELG||||||" + '\r'
+            + "DG1|1|DX|784.0^Headache^DX|Headache||VISIT" + '\r'
+            + "GT1|1|1000235129|MDCLS9^MC9^^||111 HOVER STREET^^LOS 
ANGELES^CA^90032^USA^^^LOS 
ANGELE|(310)725-6952^^^^^310^7256952||19700109|F|P/F|SLF|"
+                + 
"565-33-2222|||||^^^^^USA|||UNKNOWN|||||||||||||||||||||||||||||" + '\r'
+            + "UB2||||||||" + '\r'
+            + '\n';
+
+    @Test
+    public void testGenerateInvalidPayloadExceptionMessage() throws Exception {
+        String message = 
Hl7Util.generateInvalidPayloadExceptionMessage(TEST_MESSAGE.getBytes());
+
+        assertNull("Valid payload should result in a null message", message);
+    }
+
+    @Test
+    public void 
testGenerateInvalidPayloadExceptionMessageWithLengthLargerThanArraySize() 
throws Exception {
+        byte[] payload = TEST_MESSAGE.getBytes();
+        String message = 
Hl7Util.generateInvalidPayloadExceptionMessage(payload, payload.length * 2);
+
+        assertNull("Valid payload should result in a null message", message);
+    }
+
+    @Test
+    public void 
testGenerateInvalidPayloadExceptionMessageWithLengthSmallerThanArraySize() 
throws Exception {
+        byte[] payload = TEST_MESSAGE.getBytes();
+        String message = 
Hl7Util.generateInvalidPayloadExceptionMessage(payload, 10);
+
+        assertEquals("The HL7 payload terminating bytes [0x7c, 0x41] are 
incorrect - expected [0xd, 0xa]  {ASCII [<CR>, <LF>]}", message);
+    }
+
+    @Test
+    public void testGenerateInvalidPayloadExceptionMessageWithNullPayload() 
throws Exception {
+        assertEquals("HL7 payload is null", 
Hl7Util.generateInvalidPayloadExceptionMessage(null));
+    }
+
+    @Test
+    public void 
testGenerateInvalidPayloadExceptionMessageWithInvalidStartingSegment() throws 
Exception {
+        byte[] invalidStartingSegment = "MSA|AA|00001|\r".getBytes();
+        byte[] basePayload = TEST_MESSAGE.getBytes();
+
+        ByteArrayOutputStream payloadStream = new 
ByteArrayOutputStream(invalidStartingSegment.length + basePayload.length);
+        payloadStream.write(invalidStartingSegment);
+        payloadStream.write(basePayload.length);
+
+        assertEquals("The first segment of the HL7 payload {MSA} is not an MSH 
segment", 
Hl7Util.generateInvalidPayloadExceptionMessage(payloadStream.toByteArray()));
+    }
+
+    @Test
+    public void testGenerateInvalidPayloadExceptionMessageWithEmptyPayload() 
throws Exception {
+        byte[] payload = new byte[0];
+
+        assertEquals("HL7 payload is empty", 
Hl7Util.generateInvalidPayloadExceptionMessage(payload));
+        assertEquals("HL7 payload is empty", 
Hl7Util.generateInvalidPayloadExceptionMessage(payload, payload.length));
+    }
+
+    @Test
+    public void 
testGenerateInvalidPayloadExceptionMessageWithEmbeddedStartOfBlock() throws 
Exception {
+        byte[] basePayload = TEST_MESSAGE.getBytes();
+
+        ByteArrayOutputStream payloadStream = new 
ByteArrayOutputStream(basePayload.length + 1);
+
+        int embeddedStartOfBlockIndex = basePayload.length / 2;
+        payloadStream.write(basePayload, 0, embeddedStartOfBlockIndex);
+        payloadStream.write(START_OF_BLOCK);
+        payloadStream.write(basePayload, embeddedStartOfBlockIndex, 
basePayload.length - embeddedStartOfBlockIndex);
+
+        String expected = "HL7 payload contains an embedded START_OF_BLOCK 
{0xb, ASCII <VT>} at index " + embeddedStartOfBlockIndex;
+
+        assertEquals(expected, 
Hl7Util.generateInvalidPayloadExceptionMessage(payloadStream.toByteArray()));
+    }
+
+    @Test
+    public void 
testGenerateInvalidPayloadExceptionMessageWithEmbeddedEndOfBlock() throws 
Exception {
+        byte[] basePayload = TEST_MESSAGE.getBytes();
+
+        ByteArrayOutputStream payloadStream = new 
ByteArrayOutputStream(basePayload.length + 1);
+
+        int embeddedEndOfBlockIndex = basePayload.length / 2;
+        payloadStream.write(basePayload, 0, embeddedEndOfBlockIndex);
+        payloadStream.write(END_OF_BLOCK);
+        payloadStream.write(basePayload, embeddedEndOfBlockIndex, 
basePayload.length - embeddedEndOfBlockIndex);
+
+        String expected = "HL7 payload contains an embedded END_OF_BLOCK 
{0x1c, ASCII <FS>} at index " + embeddedEndOfBlockIndex;
+
+        assertEquals(expected, 
Hl7Util.generateInvalidPayloadExceptionMessage(payloadStream.toByteArray()));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketAcknowledgementWriterTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketAcknowledgementWriterTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketAcknowledgementWriterTest.java
new file mode 100644
index 0000000..41fa6e5
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketAcknowledgementWriterTest.java
@@ -0,0 +1,125 @@
+/**
+ * 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 org.apache.camel.component.mllp.MllpAcknowledgementDeliveryException;
+import org.apache.camel.test.util.PayloadBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_BLOCK;
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_DATA;
+import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MllpBufferedSocketAcknowledgementWriterTest extends 
MllpSocketWriterTestSupport {
+    MllpSocketWriter mllpSocketWriter;
+
+    @Before
+    public void setUp() throws Exception {
+        mllpSocketWriter = new MllpBufferedSocketWriter(fakeSocket, true);
+    }
+
+    @Test
+    public void testWriteAcknowledgement() throws Exception {
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, 
TEST_ACKNOWLEDGEMENT, END_OF_BLOCK, END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test
+    public void testWriteNullAcknowledgement() throws Exception {
+        byte[] acknowledgement = null;
+
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, END_OF_BLOCK, 
END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
acknowledgement);
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test
+    public void testWriteEmptyAcknowledgement() throws Exception {
+        byte[] acknowledgement = new byte[0];
+
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, END_OF_BLOCK, 
END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
acknowledgement);
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testGetOutputStreamFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream = null;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteToUnconnectedSocket() throws Exception {
+        fakeSocket.connected = false;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteToClosedSocket() throws Exception {
+        fakeSocket.closed = true;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteAcknowledgementFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream.failOnWriteArray = true;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    private void verifyException(MllpAcknowledgementDeliveryException 
expectedEx) throws Exception {
+        assertNotNull(expectedEx.getMessage());
+        assertArrayEquals(TEST_MESSAGE.getBytes(), expectedEx.getHl7Message());
+        assertArrayEquals(TEST_ACKNOWLEDGEMENT.getBytes(), 
expectedEx.getHl7Acknowledgement());
+        assertArrayEquals(TEST_ACKNOWLEDGEMENT.getBytes(), 
expectedEx.getMllpPayload());
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketMessageWriterTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketMessageWriterTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketMessageWriterTest.java
new file mode 100644
index 0000000..1f2c7bf
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpBufferedSocketMessageWriterTest.java
@@ -0,0 +1,126 @@
+/**
+ * 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 org.apache.camel.component.mllp.MllpWriteException;
+import org.apache.camel.test.util.PayloadBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_BLOCK;
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_DATA;
+import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class MllpBufferedSocketMessageWriterTest extends 
MllpSocketWriterTestSupport {
+    MllpSocketWriter mllpSocketWriter;
+
+    @Before
+    public void setUp() throws Exception {
+        mllpSocketWriter = new MllpBufferedSocketWriter(fakeSocket, false);
+    }
+
+    @Test
+    public void testWriteMessage() throws Exception {
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, TEST_MESSAGE, 
END_OF_BLOCK, END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), null);
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test
+    public void testWriteNullMessage() throws Exception {
+        byte[] message = null;
+
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, END_OF_BLOCK, 
END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(message, null);
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test
+    public void testWriteEmptyMessage() throws Exception {
+        byte[] message = new byte[0];
+
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, END_OF_BLOCK, 
END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(message, null);
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test(expected = MllpWriteException.class)
+    public void testGetOutputStreamFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream = null;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
null);
+        } catch (MllpWriteException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpWriteException.class)
+    public void testWriteToUnconnectedSocket() throws Exception {
+        fakeSocket.connected = false;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
null);
+        } catch (MllpWriteException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpWriteException.class)
+    public void testWriteToClosedSocket() throws Exception {
+        fakeSocket.closed = true;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
null);
+        } catch (MllpWriteException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpWriteException.class)
+    public void testWriteFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream.failOnWriteArray = true;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
null);
+        } catch (MllpWriteException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+
+    private void verifyException(MllpWriteException expectedEx) throws 
Exception {
+        assertNotNull(expectedEx.getMessage());
+        assertArrayEquals(TEST_MESSAGE.getBytes(), expectedEx.getHl7Message());
+        assertNull(expectedEx.getHl7Acknowledgement());
+        assertArrayEquals(TEST_MESSAGE.getBytes(), 
expectedEx.getMllpPayload());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementReaderTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementReaderTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementReaderTest.java
new file mode 100644
index 0000000..fa3b687
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementReaderTest.java
@@ -0,0 +1,533 @@
+/**
+ * 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.SocketException;
+import java.net.SocketTimeoutException;
+
+import org.apache.camel.component.mllp.MllpAcknowledgementException;
+import org.apache.camel.component.mllp.MllpAcknowledgementTimeoutException;
+import org.apache.camel.component.mllp.MllpReceiveAcknowledgementException;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.camel.component.mllp.MllpEndpoint.SEGMENT_DELIMITER;
+import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+public class MllpSocketAcknowledgementReaderTest extends 
MllpSocketReaderTestSupport {
+    MllpSocketReader mllpSocketReader;
+
+    @Before
+    public void setUp() throws Exception {
+        mllpSocketReader = new MllpSocketReader(fakeSocket, 5000, 1000, true);
+    }
+
+    @Test
+    public void testReadMessage() throws Exception {
+        byte[] expected = TEST_ACKNOWLEDGEMENT.getBytes();
+
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, expected, 
END_PACKET);
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testReadMessageWithSeparateEnvelopingAndMessagePackets() 
throws Exception {
+        byte[] expected = TEST_MESSAGE.getBytes();
+
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
TEST_MESSAGE.getBytes(), END_PACKET);
+
+        byte[] actual = mllpSocketReader.readEnvelopedPayload();
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testReadMessageWithMultipleMessagePackets() throws Exception {
+        byte[] expected = TEST_MESSAGE.getBytes();
+
+        fakeSocket.fakeSocketInputStream
+                .addPacket(START_PACKET)
+                .addPackets(TEST_MESSAGE, SEGMENT_DELIMITER)
+                .addPacket(END_PACKET);
+
+        byte[] actual = mllpSocketReader.readEnvelopedPayload();
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testReadEmptyMessage() throws Exception {
+        byte[] expected = new byte[0];
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, END_PACKET);
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testReadEmptyMessageWithSeparateEnvelopingPackets() throws 
Exception {
+        byte[] expected = new byte[0];
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, END_PACKET);
+
+        byte[] actual = mllpSocketReader.readEnvelopedPayload();
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test()
+    public void testGetInputStreamFailure() throws Exception {
+        fakeSocket.fakeSocketInputStream = null;
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause(), instanceOf(IOException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testEndOfStreamOnInitialRead() throws Exception {
+        fakeSocket.fakeSocketInputStream.addPackets(EMPTY_PACKET, 
TEST_MESSAGE);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNull(expectedEx.getCause());
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testTimeoutOnInitialRead() throws Exception {
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpAcknowledgementTimeoutException.class);
+        } catch (MllpAcknowledgementTimeoutException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketTimeoutException.class));
+            assertSocketOpen();
+        }
+    }
+
+    @Test
+    public void testTimeoutOnInitialReadWithStartOfBlock() throws Exception {
+        fakeSocket.fakeSocketInputStream.addPacket(START_OF_BLOCK);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpAcknowledgementTimeoutException.class);
+        } catch (MllpAcknowledgementTimeoutException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketTimeoutException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testSocketExceptionOnInitialRead() throws Exception {
+        fakeSocket.fakeSocketInputStream.addPacket(EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testIOExceptionOnInitialRead() throws Exception {
+        fakeSocket.fakeSocketInputStream.useSocketExceptionOnNullPacket = 
false;
+        fakeSocket.fakeSocketInputStream.addPacket(EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(IOException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testEndOfStreamOnFirstAdditionalRead() throws Exception {
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
EMPTY_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNull(expectedEx.getCause());
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testEndOfStreamOnFirstAdditionalReadWithPartialPayload() 
throws Exception {
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes()).addPacket(EMPTY_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNull(expectedEx.getCause());
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testTimeoutOnFirstAdditionalRead() throws Exception {
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpAcknowledgementTimeoutException.class);
+        } catch (MllpAcknowledgementTimeoutException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketTimeoutException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testTimeoutOnFirstAdditionalReadWithPartialPayload() throws 
Exception {
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes());
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpAcknowledgementTimeoutException.class);
+        } catch (MllpAcknowledgementTimeoutException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketTimeoutException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testSocketExceptionOnFirstAdditionalRead() throws Exception {
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testSocketExceptionOnFirstAdditionalReadWithPartialPayload() 
throws Exception {
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes()).addPacket(EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testIOExceptionOnFirstAdditionalRead() throws Exception {
+        fakeSocket.fakeSocketInputStream.useSocketExceptionOnNullPacket = 
false;
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertEmptyExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(IOException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testIOExceptionOnFirstAdditionalReadWithPartialPayload() 
throws Exception {
+        fakeSocket.fakeSocketInputStream.useSocketExceptionOnNullPacket = 
false;
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes()).addPacket(EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(IOException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testEndOfStreamOnSecondAdditionalReadWithPartialPayload() 
throws Exception {
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes(), EMPTY_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNull(expectedEx.getCause());
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testTimeoutOnSecondAdditionalReadWithPartialPayload() throws 
Exception {
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes());
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpAcknowledgementTimeoutException.class);
+        } catch (MllpAcknowledgementTimeoutException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketTimeoutException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testSocketExceptionOnSecondAdditionalReadWithPartialPayload() 
throws Exception {
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes(), EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(SocketException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testIOExceptionOnSecondAdditionalReadWithPartialPayload() 
throws Exception {
+        fakeSocket.fakeSocketInputStream.useSocketExceptionOnNullPacket = 
false;
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, 
TEST_ACKNOWLEDGEMENT.getBytes(), EXCEPTION_PACKET);
+
+        try {
+            mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+            
expectedExceptionFailure(MllpReceiveAcknowledgementException.class);
+        } catch (MllpReceiveAcknowledgementException expectedEx) {
+            assertExpectedException(expectedEx);
+            assertNotNull(expectedEx.getCause());
+            assertThat(expectedEx.getCause().getClass(), 
sameInstance(IOException.class));
+            assertSocketReset();
+        }
+    }
+
+    @Test
+    public void testLeadingOutOfBandBytes() throws Exception {
+        byte[] expected = TEST_ACKNOWLEDGEMENT.getBytes();
+
+        fakeSocket.fakeSocketInputStream.addPacket("Junk".getBytes(), 
START_PACKET, expected, END_PACKET);
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testLeadingOutOfBandBytesWithEmptyMessage() throws Exception {
+        byte[] expected = new byte[0];
+        fakeSocket.fakeSocketInputStream.addPacket("Junk".getBytes(), 
START_PACKET, END_PACKET);
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void 
testLeadingOutOfBandBytesWithEmptyMessageWithSeparateEnvelopingPackets() throws 
Exception {
+        byte[] expected = new byte[0];
+        fakeSocket.fakeSocketInputStream.addPackets("Junk".getBytes(), 
START_PACKET, END_PACKET);
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testLeadingOutOfBandBytesSeparateEnvelopingAndMessagePackets() 
throws Exception {
+        byte[] expected = TEST_ACKNOWLEDGEMENT.getBytes();
+
+        fakeSocket.fakeSocketInputStream.addPackets("Junk".getBytes(), 
START_PACKET, expected, END_PACKET);
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testLeadingOutOfBandBytesWithMultipleMessagePackets() throws 
Exception {
+        byte[] expected = TEST_ACKNOWLEDGEMENT.getBytes();
+
+        fakeSocket.fakeSocketInputStream
+                .addPacket("Junk")
+                .addPacket(START_PACKET)
+                .addPackets(TEST_ACKNOWLEDGEMENT, SEGMENT_DELIMITER)
+                .addPacket(END_PACKET);
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testTrailingOutOfBandBytes() throws Exception {
+        byte[] expected = TEST_ACKNOWLEDGEMENT.getBytes();
+
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, expected, 
END_PACKET, "Junk".getBytes());
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testTrailingOutOfBandBytesWithEmptyMessage() throws Exception {
+        byte[] expected = new byte[0];
+        fakeSocket.fakeSocketInputStream.addPacket(START_PACKET, END_PACKET, 
"Junk".getBytes());
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void 
testTrailingOutOfBandBytesWithEmptyMessageWithSeparateEnvelopingPackets() 
throws Exception {
+        byte[] expected = new byte[0];
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, END_PACKET, 
"Junk".getBytes());
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void 
testTrailingOutOfBandBytesSeparateEnvelopingAndMessagePackets() throws 
Exception {
+        byte[] expected = TEST_ACKNOWLEDGEMENT.getBytes();
+
+        fakeSocket.fakeSocketInputStream.addPackets(START_PACKET, expected, 
END_PACKET, "Junk".getBytes());
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    @Test
+    public void testTrailingOutOfBandBytesWithMultipleMessagePackets() throws 
Exception {
+        byte[] expected = TEST_ACKNOWLEDGEMENT.getBytes();
+
+        fakeSocket.fakeSocketInputStream
+                .addPacket(START_PACKET)
+                .addPackets(TEST_ACKNOWLEDGEMENT, SEGMENT_DELIMITER)
+                .addPacket(END_PACKET)
+                .addPacket("Junk");
+
+        byte[] actual = 
mllpSocketReader.readEnvelopedPayload(TEST_MESSAGE.getBytes());
+
+        assertArrayEquals(expected, actual);
+        assertSocketOpen();
+    }
+
+    private void assertEmptyExpectedException(MllpAcknowledgementException 
expectedEx) {
+        assertNotNull(expectedEx);
+        assertNotNull(expectedEx.getMessage());
+        assertArrayEquals(TEST_MESSAGE.getBytes(), expectedEx.getHl7Message());
+        assertNull(expectedEx.getHl7Acknowledgement());
+        assertArrayEquals(TEST_MESSAGE.getBytes(), 
expectedEx.getMllpPayload());
+    }
+
+    private void assertExpectedException(MllpAcknowledgementException 
expectedEx) {
+        assertNotNull(expectedEx);
+        assertNotNull(expectedEx.getMessage());
+        assertArrayEquals(TEST_MESSAGE.getBytes(), expectedEx.getHl7Message());
+        assertArrayEquals(TEST_ACKNOWLEDGEMENT.getBytes(), 
expectedEx.getHl7Acknowledgement());
+        assertArrayEquals(TEST_ACKNOWLEDGEMENT.getBytes(), 
expectedEx.getMllpPayload());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/e6d58b67/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementWriterTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementWriterTest.java
 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementWriterTest.java
new file mode 100644
index 0000000..9c218a7
--- /dev/null
+++ 
b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/impl/MllpSocketAcknowledgementWriterTest.java
@@ -0,0 +1,150 @@
+/**
+ * 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 org.apache.camel.component.mllp.MllpAcknowledgementDeliveryException;
+import org.apache.camel.test.util.PayloadBuilder;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_BLOCK;
+import static org.apache.camel.component.mllp.MllpEndpoint.END_OF_DATA;
+import static org.apache.camel.component.mllp.MllpEndpoint.START_OF_BLOCK;
+import static 
org.apache.camel.component.mllp.impl.MllpSocketWriter.PAYLOAD_TERMINATOR;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MllpSocketAcknowledgementWriterTest extends 
MllpSocketWriterTestSupport {
+    MllpSocketWriter mllpSocketWriter;
+
+    @Before
+    public void setUp() throws Exception {
+        mllpSocketWriter = new MllpSocketWriter(fakeSocket, true);
+    }
+
+    @Test
+    public void testWriteAcknowledgement() throws Exception {
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, 
TEST_ACKNOWLEDGEMENT, END_OF_BLOCK, END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test
+    public void testWriteNullAcknowledgement() throws Exception {
+        byte[] acknowledgement = null;
+
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, END_OF_BLOCK, 
END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
acknowledgement);
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test
+    public void testWriteEmptyAcknowledgement() throws Exception {
+        byte[] acknowledgement = new byte[0];
+
+        byte[] expected = PayloadBuilder.build(START_OF_BLOCK, END_OF_BLOCK, 
END_OF_DATA);
+
+        mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
acknowledgement);
+
+        assertArrayEquals(expected, fakeSocket.payload());
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testGetOutputStreamFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream = null;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteToUnconnectedSocket() throws Exception {
+        fakeSocket.connected = false;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteToClosedSocket() throws Exception {
+        fakeSocket.closed = true;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteStartOfBlockFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream.writeFailOn = new Byte((byte) 
START_OF_BLOCK);
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteAcknowledgementFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream.writeArrayFailOn = 
TEST_ACKNOWLEDGEMENT.getBytes();
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    @Test(expected = MllpAcknowledgementDeliveryException.class)
+    public void testWriteEndOfMessageFailure() throws Exception {
+        fakeSocket.fakeSocketOutputStream.writeArrayFailOn = 
PAYLOAD_TERMINATOR;
+
+        try {
+            mllpSocketWriter.writeEnvelopedPayload(TEST_MESSAGE.getBytes(), 
TEST_ACKNOWLEDGEMENT.getBytes());
+        } catch (MllpAcknowledgementDeliveryException expectedEx) {
+            verifyException(expectedEx);
+            throw expectedEx;
+        }
+    }
+
+    private void verifyException(MllpAcknowledgementDeliveryException 
expectedEx) throws Exception {
+        assertNotNull(expectedEx.getMessage());
+        assertArrayEquals(TEST_MESSAGE.getBytes(), expectedEx.getHl7Message());
+        assertArrayEquals(TEST_ACKNOWLEDGEMENT.getBytes(), 
expectedEx.getHl7Acknowledgement());
+        assertArrayEquals(TEST_ACKNOWLEDGEMENT.getBytes(), 
expectedEx.getMllpPayload());
+    }
+
+
+}
\ No newline at end of file

Reply via email to