You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by qu...@apache.org on 2018/02/15 22:22:59 UTC

[camel] branch master updated: CAMEL-12265 - reduce logging caused by load-balancers, and fix NPE with charset handling

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

quinn 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 0b7fb51  CAMEL-12265 - reduce logging caused by load-balancers, and fix NPE with charset handling
0b7fb51 is described below

commit 0b7fb515b5f09ab5ce5f5fa269474415070c2f6a
Author: Quinn Stevenson <qu...@apache.org>
AuthorDate: Thu Feb 15 15:22:50 2018 -0700

    CAMEL-12265 - reduce logging caused by load-balancers, and fix NPE with charset handling
---
 .../camel-mllp/src/main/docs/mllp-component.adoc   |   7 +-
 .../apache/camel/component/mllp/MllpComponent.java |  65 ++++++++-
 .../camel/component/mllp/MllpConfiguration.java    |  97 ++++++++++++-
 .../apache/camel/component/mllp/MllpEndpoint.java  |  75 ++---------
 .../component/mllp/MllpProtocolConstants.java      |  17 ++-
 .../component/mllp/MllpTcpClientProducer.java      |  17 +--
 .../component/mllp/MllpTcpServerConsumer.java      |  36 ++---
 .../camel/component/mllp/internal/Hl7Util.java     | 101 +++++++-------
 .../component/mllp/internal/MllpSocketBuffer.java  |  53 +++++---
 .../mllp/internal/TcpSocketConsumerRunnable.java   |   3 +-
 .../camel/component/mllp/MllpEndpointTest.java     |  93 -------------
 .../camel/component/mllp/MllpExceptionTest.java    |   4 +-
 .../component/mllp/MllpTcpServerCharsetTest.java   | 150 +++++++++++++++++++++
 .../camel/component/mllp/internal/Hl7UtilTest.java |  54 ++++----
 .../springboot/MllpComponentConfiguration.java     |  16 ++-
 15 files changed, 485 insertions(+), 303 deletions(-)

diff --git a/components/camel-mllp/src/main/docs/mllp-component.adoc b/components/camel-mllp/src/main/docs/mllp-component.adoc
index 0382475..75f52cb 100644
--- a/components/camel-mllp/src/main/docs/mllp-component.adoc
+++ b/components/camel-mllp/src/main/docs/mllp-component.adoc
@@ -1,7 +1,7 @@
 [[mllp-component]]
 == MLLP Component
 
-*Available as of Camel version 2.17*
+*Available as of Camel version *
 
 The MLLP component is specifically designed to handle the nuances of the
 MLLP protocol and provide the functionality required by Healthcare
@@ -41,7 +41,7 @@ for this component:
 
 
 // component options: START
-The MLLP component supports 4 options which are listed below.
+The MLLP component supports 5 options which are listed below.
 
 
 
@@ -50,6 +50,7 @@ The MLLP component supports 4 options which are listed below.
 | Name | Description | Default | Type
 | *logPhi* (advanced) | Set the component to log PHI data. | true | Boolean
 | *logPhiMaxBytes* (advanced) | Set the maximum number of bytes of PHI that will be logged in a log entry. | 5120 | Integer
+| *defaultCharset* (advanced) | Set the default character set to use for byte to/from String conversions. | ISO-8859-1 | String
 | *configuration* (common) | Sets the default configuration to use when creating MLLP endpoints. |  | MllpConfiguration
 | *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
 |===
@@ -89,7 +90,7 @@ with the following path and query parameters:
 | *bufferWrites* (common) | *Deprecated* Enable/Disable the buffering of HL7 payloads before writing to the socket. | false | boolean
 | *hl7Headers* (common) | Enable/Disable the automatic generation of message headers from the HL7 Message MLLP Consumers only | true | boolean
 | *requireEndOfData* (common) | Enable/Disable strict compliance to the MLLP standard. The MLLP standard specifies START_OF_BLOCKhl7 payloadEND_OF_BLOCKEND_OF_DATA however some systems do not send the final END_OF_DATA byte. This setting controls whether or not the final END_OF_DATA byte is required or optional. | true | boolean
-| *stringPayload* (common) | Enable/Disable converting the payload to a String. If enabled HL7 Payloads received from external systems will be validated converted to a String. If the charsetName property is set that character set will be used for the conversion. If the charsetName property is not set the value of MSH-18 will be used to determine th appropriate character set. If MSH-18 is not set then the default ASCII character set will be use. | true | boolean
+| *stringPayload* (common) | Enable/Disable converting the payload to a String. If enabled HL7 Payloads received from external systems will be validated converted to a String. If the charsetName property is set that character set will be used for the conversion. If the charsetName property is not set the value of MSH-18 will be used to determine th appropriate character set. If MSH-18 is not set then the default ISO-8859-1 character set will be use. | true | boolean
 | *validatePayload* (common) | Enable/Disable the validation of HL7 Payloads If enabled HL7 Payloads received from external systems will be validated (see Hl7Util.generateInvalidPayloadExceptionMessage for details on the validation). If and invalid payload is detected a MllpInvalidMessageException (for consumers) or a MllpInvalidAcknowledgementException will be thrown. | false | boolean
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler which mean any exceptions occurred while the consumer is trying to receive incoming messages or the likes will now be processed as a message and handled by the routing Error Handler. If disabled the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions by logging them at WARN or ERROR level and ignored. | true | boolean
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this options is not in use. By default the consumer will deal with exceptions that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java
index acd5da5..0eebada 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpComponent.java
@@ -17,12 +17,13 @@
 
 package org.apache.camel.component.mllp;
 
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.DefaultComponent;
-import org.apache.camel.impl.UriEndpointComponent;
 import org.apache.camel.spi.Metadata;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory;
 public class MllpComponent extends DefaultComponent {
     public static final String MLLP_LOG_PHI_PROPERTY = "org.apache.camel.component.mllp.logPHI";
     public static final String MLLP_LOG_PHI_MAX_BYTES_PROPERTY = "org.apache.camel.component.mllp.logPHI.maxBytes";
+    public static final String MLLP_DEFAULT_CHARSET_PROPERTY = "org.apache.camel.component.mllp.charset.default";
     public static final boolean DEFAULT_LOG_PHI = true;
     public static final int DEFAULT_LOG_PHI_MAX_BYTES = 5120;
 
@@ -42,6 +44,8 @@ public class MllpComponent extends DefaultComponent {
     static Boolean logPhi;
     @Metadata(label = "advanced", defaultValue = "5120")
     static Integer logPhiMaxBytes;
+    @Metadata(label = "advanced", defaultValue = "ISO-8859-1")
+    static Charset defaultCharset;
 
     MllpConfiguration configuration;
 
@@ -133,6 +137,65 @@ public class MllpComponent extends DefaultComponent {
     }
 
 
+    public static boolean hasDefaultCharset() {
+        return defaultCharset != null;
+    }
+
+    public static Charset getDefaultCharset() {
+        if (hasDefaultCharset()) {
+            return defaultCharset;
+        }
+
+        String defaultCharacterSetNamePropertyValue = System.getProperty(MllpComponent.MLLP_DEFAULT_CHARSET_PROPERTY);
+
+        if (defaultCharacterSetNamePropertyValue != null && !defaultCharacterSetNamePropertyValue.isEmpty()) {
+            try {
+                if (Charset.isSupported(defaultCharacterSetNamePropertyValue)) {
+                    defaultCharset = Charset.forName(defaultCharacterSetNamePropertyValue);
+                } else {
+                    defaultCharset = StandardCharsets.ISO_8859_1;
+                    log.warn("Unsupported character set name '{}' in system property {} - using character set {} as default",
+                        defaultCharacterSetNamePropertyValue, MllpComponent.MLLP_DEFAULT_CHARSET_PROPERTY, defaultCharset);
+                }
+            } catch (Exception charsetEx) {
+                defaultCharset = StandardCharsets.ISO_8859_1;
+                log.warn("Exception encountered determining character set for '{}' found in  system property {} - using default value of {}",
+                    defaultCharacterSetNamePropertyValue, MllpComponent.MLLP_DEFAULT_CHARSET_PROPERTY, defaultCharset);
+            }
+        } else {
+            defaultCharset = StandardCharsets.ISO_8859_1;
+        }
+
+        return defaultCharset;
+    }
+
+    /**
+     * Set the default character set to use for byte[] to/from String conversions.
+     *
+     * @param defaultCharacterSetName the name of the Java Charset.
+     */
+    public static void setDefaultCharset(String defaultCharacterSetName) {
+        if (defaultCharacterSetName != null && !defaultCharacterSetName.isEmpty()) {
+            try {
+                if (Charset.isSupported(defaultCharacterSetName)) {
+                    MllpComponent.defaultCharset = Charset.forName(defaultCharacterSetName);
+                } else {
+                    log.warn("Unsupported character set name '{}' in system property {} - continuing to use character set {} as default",
+                        defaultCharacterSetName, defaultCharset);
+                }
+            } catch (Exception charsetEx) {
+                MllpComponent.defaultCharset = StandardCharsets.ISO_8859_1;
+                log.warn("Exception encountered determining character set for '{}' - continuing to use character set {} as default",
+                    defaultCharacterSetName, defaultCharset);
+            }
+        }
+    }
+
+    public static void setDefaultCharset(Charset defaultCharset) {
+        if (defaultCharset != null) {
+            MllpComponent.defaultCharset = defaultCharset;
+        }
+    }
 
     public boolean hasConfiguration() {
         return configuration != null;
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConfiguration.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConfiguration.java
index 6d48925..3bce5be 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConfiguration.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpConfiguration.java
@@ -17,12 +17,16 @@
 
 package org.apache.camel.component.mllp;
 
+import java.nio.charset.Charset;
 import java.util.Objects;
 
+import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
+import org.apache.camel.component.mllp.internal.Hl7Util;
 import org.apache.camel.spi.ExceptionHandler;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriParams;
+import org.apache.camel.util.IOHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -213,7 +217,96 @@ public class MllpConfiguration implements Cloneable {
     }
 
     public String getCharsetName() {
-        return charsetName;
+        if (hasCharsetName()) {
+            try {
+                if (Charset.isSupported(charsetName)) {
+                    return charsetName;
+                }
+                LOG.warn("Unsupported character set name '{}' configured for the MLLP Endpoint  - returning default charset name {}",
+                    charsetName, MllpComponent.getDefaultCharset());
+            } catch (Exception charsetEx) {
+                LOG.warn("Ignoring exception determining character set for name '{}' configured for the MLLP Endpoint - returning default charset name {}",
+                    charsetName, MllpComponent.getDefaultCharset(), charsetEx);
+            }
+        }
+
+        return MllpComponent.getDefaultCharset().name();
+    }
+
+    public Charset getCharset() {
+        if (hasCharsetName()) {
+            try {
+                if (Charset.isSupported(charsetName)) {
+                    return Charset.forName(charsetName);
+                }
+                LOG.warn("Unsupported character set name '{}' configured for the MLLP Endpoint - returning default charset {}", charsetName, MllpComponent.getDefaultCharset());
+            } catch (Exception charsetEx) {
+                LOG.warn("Ignoring exception determining character set for name '{}' configured for the MLLP Endpoint - returning default charset {}",
+                    charsetName, MllpComponent.getDefaultCharset(), charsetEx);
+            }
+        }
+
+        return MllpComponent.getDefaultCharset();
+    }
+
+    public Charset getCharset(Exchange exchange) {
+        String exchangeCharsetName = IOHelper.getCharsetName(exchange, false);
+        if (exchangeCharsetName != null && !exchangeCharsetName.isEmpty()) {
+            try {
+                if (Charset.isSupported(exchangeCharsetName)) {
+                    return Charset.forName(exchangeCharsetName);
+                }
+                LOG.warn("Unsupported character set name '{}' specified in the Exchange - checking for configured character set", exchangeCharsetName);
+            } catch (Exception charsetEx) {
+                LOG.warn("Ignoring exception determining character set for name '{}' specified in the Exchange - checking for configured character set", exchangeCharsetName, charsetEx);
+            }
+        }
+
+        return getCharset();
+    }
+
+    public Charset getCharset(Exchange exchange, byte[] hl7Bytes) {
+        String exchangeCharsetName = IOHelper.getCharsetName(exchange, false);
+        if (exchangeCharsetName != null && !exchangeCharsetName.isEmpty()) {
+            try {
+                if (Charset.isSupported(exchangeCharsetName)) {
+                    return Charset.forName(exchangeCharsetName);
+                }
+                LOG.warn("Unsupported character set name '{}' specified in the Exchange - checking for configured character set", exchangeCharsetName);
+            } catch (Exception charsetEx) {
+                LOG.warn("Ignoring exception determining character set for name '{}' specified in the Exchange - checking for configured character set", exchangeCharsetName, charsetEx);
+            }
+        }
+
+        if (hasCharsetName()) {
+            try {
+                if (Charset.isSupported(charsetName)) {
+                    return Charset.forName(charsetName);
+                }
+                LOG.warn("Unsupported character set name '{}' configured for the MLLP Endpoint - checking for character set in payload", charsetName);
+            } catch (Exception charsetEx) {
+                LOG.warn("Ignoring exception determining character set for name '{}' configured for the MLLP Endpoint - checking for character set in payload", charsetName, charsetEx);
+            }
+        }
+
+        String msh18 = Hl7Util.findMsh18(hl7Bytes);
+        if (msh18 != null  && !msh18.isEmpty()) {
+            if (MllpProtocolConstants.MSH18_VALUES.containsKey(msh18)) {
+                return MllpProtocolConstants.MSH18_VALUES.get(msh18);
+            }
+            try {
+                if (Charset.isSupported(msh18)) {
+                    return Charset.forName(msh18);
+                }
+                LOG.info("Unsupported character set name '{}' found in MSH-18 - using default character set {}",
+                    msh18, MllpComponent.getDefaultCharset());
+            } catch (Exception charsetEx) {
+                LOG.info("Ignoring exception encountered determining character set for for name '{}' found in MSH-18 - using default character set {}",
+                    msh18, MllpComponent.getDefaultCharset(), charsetEx);
+            }
+        }
+
+        return MllpComponent.getDefaultCharset();
     }
 
     /**
@@ -548,7 +641,7 @@ public class MllpConfiguration implements Cloneable {
      *
      * If the charsetName property is set, that character set will be used for the conversion.  If the charsetName property is
      * not set, the value of MSH-18 will be used to determine th appropriate character set.  If MSH-18 is not set, then
-     * the default ASCII character set will be use.
+     * the default ISO-8859-1 character set will be use.
      *
      * @param stringPayload enabled if true, otherwise disabled
      */
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java
index 18db7f2..d91e456 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpEndpoint.java
@@ -34,11 +34,13 @@ import org.apache.camel.Producer;
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.component.mllp.internal.Hl7Util;
+import org.apache.camel.component.mllp.internal.MllpSocketBuffer;
 import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
+import org.apache.camel.util.IOHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,7 +53,7 @@ import org.slf4j.LoggerFactory;
  * <p/>
  */
 @ManagedResource(description = "MLLP Endpoint")
-@UriEndpoint(scheme = "mllp", firstVersion = "2.17.0", title = "MLLP", syntax = "mllp:hostname:port", consumerClass = MllpTcpServerConsumer.class, label = "mllp")
+@UriEndpoint(scheme = "mllp", title = "MLLP", syntax = "mllp:hostname:port", consumerClass = MllpTcpServerConsumer.class, label = "mllp")
 public class MllpEndpoint extends DefaultEndpoint {
     // Use constants from MllpProtocolConstants
     @Deprecated()
@@ -67,8 +69,8 @@ public class MllpEndpoint extends DefaultEndpoint {
     @Deprecated()
     public static final char MESSAGE_TERMINATOR = MllpProtocolConstants.MESSAGE_TERMINATOR;
 
-    @Deprecated // Use constants from MllpProtocolConstants
-    public static final Charset DEFAULT_CHARSET = MllpProtocolConstants.DEFAULT_CHARSET;
+    @Deprecated // Use MllpComponent.getDefaultCharset()
+    public static final Charset DEFAULT_CHARSET = MllpComponent.getDefaultCharset();
 
     private static final Logger LOG = LoggerFactory.getLogger(MllpEndpoint.class);
 
@@ -229,54 +231,6 @@ public class MllpEndpoint extends DefaultEndpoint {
         }
     }
 
-    public Charset determineCharset(byte[] hl7Bytes, String msh18) {
-        Charset answer = MllpProtocolConstants.DEFAULT_CHARSET;
-
-        if (configuration.hasCharsetName()) {
-            String charsetName = configuration.getCharsetName();
-            if (Charset.isSupported(charsetName)) {
-                answer = Charset.forName(charsetName);
-            } else {
-                LOG.warn("Unsupported Character Set {} configured for component - using default character set {}", charsetName, MllpProtocolConstants.DEFAULT_CHARSET);
-            }
-        } else if (msh18 != null && !msh18.isEmpty()) {
-            if (MllpProtocolConstants.MSH18_VALUES.containsKey(msh18)) {
-                answer = MllpProtocolConstants.MSH18_VALUES.get(msh18);
-            } else {
-                LOG.warn("Unsupported Character Set {} specified for MSH-18 - using default character set {}", msh18, MllpProtocolConstants.DEFAULT_CHARSET);
-            }
-        } else {
-            String foundMsh18 = Hl7Util.findMsh18(hl7Bytes);
-            if (foundMsh18 != null && !foundMsh18.isEmpty()) {
-                if (MllpProtocolConstants.MSH18_VALUES.containsKey(foundMsh18)) {
-                    answer = MllpProtocolConstants.MSH18_VALUES.get(foundMsh18);
-                } else {
-                    LOG.warn("Unsupported Character Set {} found in MSH-18 - using default character set {}", foundMsh18, MllpProtocolConstants.DEFAULT_CHARSET);
-                }
-            } else {
-                LOG.debug("Character Set not specified and no Character Set found in MSH-18 - using default character set {}", MllpProtocolConstants.DEFAULT_CHARSET);
-            }
-        }
-
-        return answer;
-    }
-
-    public String createNewString(byte[] hl7Bytes, String msh18) {
-        if (hl7Bytes == null) {
-            return null;
-        } else if (hl7Bytes.length == 0) {
-            return "";
-        }
-
-        Charset charset = determineCharset(hl7Bytes, msh18);
-
-        LOG.debug("Creating new String using Charset {}", charset);
-
-        return new String(hl7Bytes, charset);
-    }
-
-
-
     // Pass-through configuration methods
     public void setBacklog(Integer backlog) {
         configuration.setBacklog(backlog);
@@ -370,17 +324,16 @@ public class MllpEndpoint extends DefaultEndpoint {
     // Utility methods for producers and consumers
 
     public boolean checkBeforeSendProperties(Exchange exchange, Socket socket, Logger log) {
+        final String logMessageFormat = "Exchange property {} = {} - {} connection";
         boolean answer = true;
 
         if (exchange.getProperty(MllpConstants.MLLP_RESET_CONNECTION_BEFORE_SEND, boolean.class)) {
-            log.warn("Exchange property " + MllpConstants.MLLP_RESET_CONNECTION_BEFORE_SEND + " = "
-                + exchange.getProperty(MllpConstants.MLLP_RESET_CONNECTION_BEFORE_SEND) + " - resetting connection");
-            doConnectionClose(socket, true, log);
+            log.warn(logMessageFormat, MllpConstants.MLLP_RESET_CONNECTION_BEFORE_SEND, exchange.getProperty(MllpConstants.MLLP_RESET_CONNECTION_BEFORE_SEND), "resetting");
+            doConnectionClose(socket, true, null);
             answer = false;
         } else if (exchange.getProperty(MllpConstants.MLLP_CLOSE_CONNECTION_BEFORE_SEND, boolean.class)) {
-            log.warn("Exchange property " + MllpConstants.MLLP_CLOSE_CONNECTION_BEFORE_SEND + " = "
-                + exchange.getProperty(MllpConstants.MLLP_CLOSE_CONNECTION_BEFORE_SEND) + " - closing connection");
-            doConnectionClose(socket, false, log);
+            log.warn(logMessageFormat, MllpConstants.MLLP_CLOSE_CONNECTION_BEFORE_SEND, exchange.getProperty(MllpConstants.MLLP_CLOSE_CONNECTION_BEFORE_SEND), "closing");
+            doConnectionClose(socket, false, null);
             answer = false;
         }
 
@@ -388,16 +341,15 @@ public class MllpEndpoint extends DefaultEndpoint {
     }
 
     public boolean checkAfterSendProperties(Exchange exchange, Socket socket, Logger log) {
+        final String logMessageFormat = "Exchange property {} = {} - {} connection";
         boolean answer = true;
 
         if (exchange.getProperty(MllpConstants.MLLP_RESET_CONNECTION_AFTER_SEND, boolean.class)) {
-            log.warn("Exchange property " + MllpConstants.MLLP_RESET_CONNECTION_AFTER_SEND + " = "
-                + exchange.getProperty(MllpConstants.MLLP_RESET_CONNECTION_AFTER_SEND) + " - resetting connection");
+            log.warn(logMessageFormat, MllpConstants.MLLP_RESET_CONNECTION_AFTER_SEND, exchange.getProperty(MllpConstants.MLLP_RESET_CONNECTION_AFTER_SEND), "resetting");
             doConnectionClose(socket, true, log);
             answer = false;
         } else if (exchange.getProperty(MllpConstants.MLLP_CLOSE_CONNECTION_AFTER_SEND, boolean.class)) {
-            log.warn("Exchange property " + MllpConstants.MLLP_CLOSE_CONNECTION_AFTER_SEND + " = "
-                + exchange.getProperty(MllpConstants.MLLP_CLOSE_CONNECTION_AFTER_SEND) + " - closing connection");
+            log.warn(logMessageFormat, MllpConstants.MLLP_CLOSE_CONNECTION_AFTER_SEND, exchange.getProperty(MllpConstants.MLLP_CLOSE_CONNECTION_AFTER_SEND), "closing");
             doConnectionClose(socket, false, log);
             answer = false;
         }
@@ -424,6 +376,7 @@ public class MllpEndpoint extends DefaultEndpoint {
                     log.debug(ignoringCallLogFormat, reset ? "Reset" : "Close", "Socket is already closed", localSocketAddress, remoteSocketAddress);
                 }
             } else {
+                this.updateLastConnectionTerminatedTicks();
                 final String ignoringExceptionStringFormat = "Ignoring %s encountered calling %s on Socket: localAddress=%s remoteAddress=%s";
                 if (!socket.isInputShutdown()) {
                     if (log != null) {
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpProtocolConstants.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpProtocolConstants.java
index 8529637..1d52b05 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpProtocolConstants.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/MllpProtocolConstants.java
@@ -35,7 +35,6 @@ public final class MllpProtocolConstants {
 
     public static final byte[] PAYLOAD_TERMINATOR;
 
-    public static final Charset DEFAULT_CHARSET = StandardCharsets.US_ASCII;
     public static final Map<String, Charset> MSH18_VALUES;
 
     static {
@@ -56,15 +55,15 @@ public final class MllpProtocolConstants {
         MSH18_VALUES.put("8859/8", Charset.forName("ISO-8859-8"));
         MSH18_VALUES.put("8859/9", Charset.forName("ISO-8859-9"));
 
-    /*
-      // These are defined in the HL7 Spec, but I don't know how to map them to Java charset names
+        /*
+          // These are defined in the HL7 Spec, but I don't know how to map them to Java charset names
 
-      MSH18_VALUES.put("JAS2020", "????");
-      MSH18_VALUES.put("JIS X 0202", "????");
-      MSH18_VALUES.put("JIS X 0201-1976", "????");
-      MSH18_VALUES.put("JIS X 0208-1990", "????");
-      MSH18_VALUES.put("JIS X 0212-1990", "????");
-    */
+          MSH18_VALUES.put("JAS2020", "????");
+          MSH18_VALUES.put("JIS X 0202", "????");
+          MSH18_VALUES.put("JIS X 0201-1976", "????");
+          MSH18_VALUES.put("JIS X 0208-1990", "????");
+          MSH18_VALUES.put("JIS X 0212-1990", "????");
+        */
     }
 
     private MllpProtocolConstants() {
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 929c332..8cbb492 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
@@ -151,15 +151,9 @@ public class MllpTcpClientProducer extends DefaultProducer implements Runnable {
                 hl7MessageBytes = (byte[]) messageBody;
             } else if (messageBody instanceof String) {
                 String stringBody = (String) messageBody;
-                byte[] tmpHl7MessageBytes = stringBody.getBytes(MllpProtocolConstants.DEFAULT_CHARSET);
-                Charset tmpCharset = getEndpoint().determineCharset(tmpHl7MessageBytes, null);
-                exchange.setProperty(Exchange.CHARSET_NAME, tmpCharset.name());
-                if (tmpCharset != null && tmpCharset != MllpProtocolConstants.DEFAULT_CHARSET) {
-                    hl7MessageBytes = stringBody.getBytes(tmpCharset);
-                    exchange.setProperty(Exchange.CHARSET_NAME, tmpCharset.name());
-                } else {
-                    hl7MessageBytes = tmpHl7MessageBytes;
-                    exchange.setProperty(Exchange.CHARSET_NAME, MllpProtocolConstants.DEFAULT_CHARSET.name());
+                hl7MessageBytes = stringBody.getBytes(getConfiguration().getCharset(exchange));
+                if (getConfiguration().hasCharsetName()) {
+                    exchange.setProperty(Exchange.CHARSET_NAME, getConfiguration().getCharsetName());
                 }
             }
 
@@ -247,8 +241,7 @@ public class MllpTcpClientProducer extends DefaultProducer implements Runnable {
                         log.debug("Populating message headers with the acknowledgement from the external system");
                         message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT, acknowledgementBytes);
                         if (acknowledgementBytes != null && acknowledgementBytes.length > 0) {
-                            message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING,
-                                getEndpoint().createNewString(acknowledgementBytes, message.getHeader(MllpConstants.MLLP_CHARSET, String.class)));
+                            message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING, new String(acknowledgementBytes, getConfiguration().getCharset(exchange, acknowledgementBytes)));
                         } else {
                             message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING, "");
                         }
@@ -272,7 +265,7 @@ public class MllpTcpClientProducer extends DefaultProducer implements Runnable {
                             getEndpoint().checkAfterSendProperties(exchange, socket, log);
                         }
                     } else {
-                        exchange.setException(new MllpInvalidAcknowledgementException("Invalid acknowledgement received", hl7MessageBytes, mllpBuffer.toByteArray()));
+                        exchange.setException(new MllpInvalidAcknowledgementException("Invalid acknowledgement received", hl7MessageBytes, mllpBuffer.toByteArrayAndReset()));
                     }
                 }
             }
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 7d00711..c1ee5dc 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
@@ -18,7 +18,6 @@
 package org.apache.camel.component.mllp;
 
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.net.BindException;
 import java.net.ServerSocket;
 import java.net.Socket;
@@ -216,7 +215,7 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
             consumerExecutor.submit(client);
         } catch (RejectedExecutionException rejectedExecutionEx) {
             log.warn("Cannot start consumer - max consumers already active");
-            getEndpoint().doConnectionClose(clientSocket, true, null);
+            mllpBuffer.resetSocket(clientSocket);
         }
     }
 
@@ -226,8 +225,9 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
         // Send the message on to Camel for processing and wait for the response
         log.debug("Populating the exchange with received message");
         Exchange exchange = getEndpoint().createExchange(ExchangePattern.InOut);
-        // TODO: Evaluate the CHARSET handling - may not be correct
-        exchange.setProperty(Exchange.CHARSET_NAME, getEndpoint().determineCharset(hl7MessageBytes, null));
+        if (getConfiguration().hasCharsetName()) {
+            exchange.setProperty(Exchange.CHARSET_NAME, getConfiguration().getCharsetName());
+        }
         try {
             createUoW(exchange);
             Message message = exchange.getIn();
@@ -254,7 +254,7 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
 
             if (getConfiguration().isStringPayload()) {
                 if (hl7MessageBytes != null && hl7MessageBytes.length > 0) {
-                    message.setBody(getEndpoint().createNewString(hl7MessageBytes, message.getHeader(MllpConstants.MLLP_CHARSET, String.class)), String.class);
+                    message.setBody(new String(hl7MessageBytes, getConfiguration().getCharset(exchange, hl7MessageBytes)));
                 } else {
                     message.setBody("", String.class);
                 }
@@ -308,7 +308,7 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
                 log.error("Population of message headers failed - unable to find the end of the MSH segment");
             } else if (getConfiguration().isHl7Headers()) {
                 log.debug("Populating the HL7 message headers");
-                Charset charset = Charset.forName(IOHelper.getCharsetName(exchange));
+                Charset charset = getConfiguration().getCharset(exchange);
 
                 for (int i = 2; i < fieldSeparatorIndexes.size(); ++i) {
                     int startingFieldSeparatorIndex = fieldSeparatorIndexes.get(i - 1);
@@ -356,9 +356,10 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
                             continue;
                         }
 
-                        String headerValue = new String(hl7MessageBytes, startingFieldSeparatorIndex + 1,
-                            endingFieldSeparatorIndex - startingFieldSeparatorIndex - 1,
-                            charset);
+                        String headerValue = (i == 17 && getConfiguration().hasCharsetName())
+                            ? getConfiguration().getCharsetName()
+                            : new String(hl7MessageBytes, startingFieldSeparatorIndex + 1, endingFieldSeparatorIndex - startingFieldSeparatorIndex - 1, charset);
+
                         message.setHeader(headerName, headerValue);
 
                         // For MSH-9, set a couple more headers
@@ -498,10 +499,12 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
             message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_TYPE, acknowledgementMessageType);
         }
 
+        Charset charset = getConfiguration().getCharset(exchange);
+
         if (consumerRunnable.getMllpBuffer().hasCompleteEnvelope()) {
             // The mllpBuffer will be used if bufferWrites is set or if auto acknowledgement is used
             message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT, consumerRunnable.getMllpBuffer().toMllpPayload());
-            message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING, consumerRunnable.getMllpBuffer().toHl7String(IOHelper.getCharsetName(exchange, false)));
+            message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING, consumerRunnable.getMllpBuffer().toHl7String(charset));
 
             // Send the acknowledgement
             if (log.isDebugEnabled()) {
@@ -519,18 +522,7 @@ public class MllpTcpServerConsumer extends DefaultConsumer {
             }
         } else if (acknowledgementMessageBytes != null && acknowledgementMessageBytes.length > 0) {
             message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT, acknowledgementMessageBytes);
-            String acknowledgementMessageString = "";
-            String exchangeCharset = IOHelper.getCharsetName(exchange, false);
-            if (exchangeCharset != null && !exchangeCharset.isEmpty()) {
-                try {
-                    acknowledgementMessageString = new String(acknowledgementMessageBytes, exchangeCharset);
-                } catch (UnsupportedEncodingException e) {
-                    log.warn("Failed to covert acknowledgment to string using {} charset - falling back to default charset {}", exchange, MllpProtocolConstants.DEFAULT_CHARSET);
-                    acknowledgementMessageString = new String(acknowledgementMessageBytes, MllpProtocolConstants.DEFAULT_CHARSET);
-                }
-            } else {
-                acknowledgementMessageString = new String(acknowledgementMessageBytes, MllpProtocolConstants.DEFAULT_CHARSET);
-            }
+            String acknowledgementMessageString = new String(acknowledgementMessageBytes, charset);
             message.setHeader(MllpConstants.MLLP_ACKNOWLEDGEMENT_STRING, acknowledgementMessageString);
 
             // Send the acknowledgement
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/Hl7Util.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/Hl7Util.java
index 67f86cb..432ae5c 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/Hl7Util.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/Hl7Util.java
@@ -17,10 +17,13 @@
 
 package org.apache.camel.component.mllp.internal;
 
+import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.camel.component.mllp.MllpComponent;
 import org.apache.camel.component.mllp.MllpProtocolConstants;
@@ -29,22 +32,52 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class Hl7Util {
-    public static final String START_OF_BLOCK_REPLACEMENT_VALUE = "<VT>";      // VT (vertical tab)        - decimal 11, octal 013
-    public static final String END_OF_BLOCK_REPLACEMENT_VALUE = "<FS>";        // FS (file separator)      - decimal 28, octal 034
-    public static final String SEGMENT_DELIMITER_REPLACEMENT_VALUE = "<CR>";   // CR (carriage return)     - decimal 13, octal 015
-    public static final String MESSAGE_TERMINATOR_REPLACEMENT_VALUE = "<LF>";  // LF (line feed, new line) - decimal 10, octal 012
-    // Some other non-printable characters
-    public static final String TAB_REPLACEMENT_VALUE = "<TAB>";      // TAB (tab)        - decimal 9, octal 011
-    public static final String BACKSPACE_REPLACEMENT_VALUE = "<BS>";      // BS (backspace)        - decimal 8, octal 010
-    public static final String FORMFEED_REPLACEMENT_VALUE = "<FF>";      // FF (tab)        - decimal 12, octal 014
-
     public static final String NULL_REPLACEMENT_VALUE = "<null>";
     public static final String EMPTY_REPLACEMENT_VALUE = "<>";
 
+    public static final Map<Character, String> CHARACTER_REPLACEMENTS;
+
     static final int STRING_BUFFER_PAD_SIZE = 100;
 
     static final Logger LOG = LoggerFactory.getLogger(Hl7Util.class);
 
+    static {
+        CHARACTER_REPLACEMENTS = new HashMap<>();
+        CHARACTER_REPLACEMENTS.put((char)0x00, "<0x00 NUL>");
+        CHARACTER_REPLACEMENTS.put((char)0x01, "<0x01 SOH>");
+        CHARACTER_REPLACEMENTS.put((char)0x02, "<0x02 STX>");
+        CHARACTER_REPLACEMENTS.put((char)0x03, "<0x03 ETX>");
+        CHARACTER_REPLACEMENTS.put((char)0x04, "<0x04 EOT>");
+        CHARACTER_REPLACEMENTS.put((char)0x05, "<0x05 ENQ>");
+        CHARACTER_REPLACEMENTS.put((char)0x06, "<0x06 ACK>");
+        CHARACTER_REPLACEMENTS.put((char)0x07, "<0x07 BEL>");
+        CHARACTER_REPLACEMENTS.put((char)0x08, "<0x08 BS>");
+        CHARACTER_REPLACEMENTS.put((char)0x09, "<0x09 TAB>");
+        CHARACTER_REPLACEMENTS.put((char)0x0A, "<0x0A LF>");
+        CHARACTER_REPLACEMENTS.put((char)0x0B, "<0x0B VT>");
+        CHARACTER_REPLACEMENTS.put((char)0x0C, "<0x0C FF>");
+        CHARACTER_REPLACEMENTS.put((char)0x0D, "<0x0D CR>");
+        CHARACTER_REPLACEMENTS.put((char)0x0E, "<0x0E SO>");
+        CHARACTER_REPLACEMENTS.put((char)0x0F, "<0x0F SI>");
+        CHARACTER_REPLACEMENTS.put((char)0x10, "<0x10 DLE>");
+        CHARACTER_REPLACEMENTS.put((char)0x11, "<0x11 DC1>");
+        CHARACTER_REPLACEMENTS.put((char)0x12, "<0x12 DC2>");
+        CHARACTER_REPLACEMENTS.put((char)0x13, "<0x13 DC3>");
+        CHARACTER_REPLACEMENTS.put((char)0x14, "<0x14 DC4>");
+        CHARACTER_REPLACEMENTS.put((char)0x15, "<0x15 NAK>");
+        CHARACTER_REPLACEMENTS.put((char)0x16, "<0x16 SYN>");
+        CHARACTER_REPLACEMENTS.put((char)0x17, "<0x17 ETB>");
+        CHARACTER_REPLACEMENTS.put((char)0x18, "<0x18 CAN>");
+        CHARACTER_REPLACEMENTS.put((char)0x19, "<0x19 EM>");
+        CHARACTER_REPLACEMENTS.put((char)0x1A, "<0x1A SUB>");
+        CHARACTER_REPLACEMENTS.put((char)0x1B, "<0x1B ESC>");
+        CHARACTER_REPLACEMENTS.put((char)0x1C, "<0x1C FS>");
+        CHARACTER_REPLACEMENTS.put((char)0x1D, "<0x1D GS>");
+        CHARACTER_REPLACEMENTS.put((char)0x1E, "<0x1E RS>");
+        CHARACTER_REPLACEMENTS.put((char)0x1F, "<0x1F US>");
+        CHARACTER_REPLACEMENTS.put((char)0x7F, "<0x7F DEL>");
+    }
+
     private Hl7Util() {
         //utility class, never constructed
     }
@@ -133,11 +166,11 @@ public final class Hl7Util {
     }
 
     /**
-     * Find the String value of MSH-19 (Character set).
+     * Find the String value of MSH-18 (Character set).
      *
      * @param hl7Message the HL7 binary data to search
      *
-     * @return the String value of MSH-19, or an empty String if not found.
+     * @return the String value of MSH-18, or an empty String if not found.
      */
     public static String findMsh18(byte[] hl7Message) {
         String answer = "";
@@ -146,12 +179,12 @@ public final class Hl7Util {
 
             List<Integer> fieldSeparatorIndexes = findFieldSeparatorIndicesInSegment(hl7Message, 0);
 
-            if (fieldSeparatorIndexes.size() > 18) {
-                int startOfMsh19 = fieldSeparatorIndexes.get(17) + 1;
-                int length = fieldSeparatorIndexes.get(18) - fieldSeparatorIndexes.get(17) - 1;
+            if (fieldSeparatorIndexes.size() > 17) {
+                int startOfMsh19 = fieldSeparatorIndexes.get(16) + 1;
+                int length = fieldSeparatorIndexes.get(17) - fieldSeparatorIndexes.get(16) - 1;
 
                 if (length > 0) {
-                    answer = new String(hl7Message, startOfMsh19, length, StandardCharsets.US_ASCII);
+                    answer = new String(hl7Message, startOfMsh19, length, MllpComponent.getDefaultCharset());
                 }
             }
         }
@@ -348,43 +381,19 @@ public final class Hl7Util {
     }
 
     static void appendCharacterAsPrintFriendlyString(StringBuilder builder, char c) {
-        switch (c) {
-        case MllpProtocolConstants.START_OF_BLOCK:
-            builder.append(START_OF_BLOCK_REPLACEMENT_VALUE);
-            break;
-        case MllpProtocolConstants.END_OF_BLOCK:
-            builder.append(END_OF_BLOCK_REPLACEMENT_VALUE);
-            break;
-        case MllpProtocolConstants.SEGMENT_DELIMITER:
-            builder.append(SEGMENT_DELIMITER_REPLACEMENT_VALUE);
-            break;
-        case MllpProtocolConstants.MESSAGE_TERMINATOR:
-            builder.append(MESSAGE_TERMINATOR_REPLACEMENT_VALUE);
-            break;
-        default:
+        if (CHARACTER_REPLACEMENTS.containsKey(c)) {
+            builder.append(CHARACTER_REPLACEMENTS.get(c));
+        } else {
             builder.append(c);
         }
     }
 
     public static String getCharacterAsPrintFriendlyString(char c) {
-        switch (c) {
-        case MllpProtocolConstants.START_OF_BLOCK:
-            return START_OF_BLOCK_REPLACEMENT_VALUE;
-        case MllpProtocolConstants.END_OF_BLOCK:
-            return END_OF_BLOCK_REPLACEMENT_VALUE;
-        case MllpProtocolConstants.SEGMENT_DELIMITER:
-            return SEGMENT_DELIMITER_REPLACEMENT_VALUE;
-        case MllpProtocolConstants.MESSAGE_TERMINATOR:
-            return MESSAGE_TERMINATOR_REPLACEMENT_VALUE;
-        case '\t':
-            return TAB_REPLACEMENT_VALUE;
-        case '\b':
-            return BACKSPACE_REPLACEMENT_VALUE;
-        case '\f':
-            return FORMFEED_REPLACEMENT_VALUE;
-        default:
-            return String.valueOf(c);
+        if (CHARACTER_REPLACEMENTS.containsKey(c)) {
+            return CHARACTER_REPLACEMENTS.get(c);
         }
+
+        return String.valueOf(c);
     }
 
     /**
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/MllpSocketBuffer.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/MllpSocketBuffer.java
index cef5044..020ec74 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/MllpSocketBuffer.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/MllpSocketBuffer.java
@@ -29,6 +29,7 @@ import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 
+import org.apache.camel.component.mllp.MllpComponent;
 import org.apache.camel.component.mllp.MllpEndpoint;
 import org.apache.camel.component.mllp.MllpProtocolConstants;
 import org.apache.camel.component.mllp.MllpSocketException;
@@ -39,7 +40,6 @@ import org.slf4j.LoggerFactory;
  * An OutputStream modeled after the ByteArrayOutputStream specifically for MLLP operations.
  */
 public class MllpSocketBuffer {
-    static final Charset DEFAULT_CHARSET = StandardCharsets.US_ASCII;
     static final int MIN_BUFFER_SIZE = 2048;
     static final int MAX_BUFFER_SIZE = 0x40000000;  // Approximately 1-GB
 
@@ -270,7 +270,7 @@ public class MllpSocketBuffer {
 
     @Override
     public synchronized String toString() {
-        return toString(DEFAULT_CHARSET);
+        return toString(MllpComponent.getDefaultCharset());
     }
 
     public synchronized String toString(Charset charset) {
@@ -283,14 +283,17 @@ public class MllpSocketBuffer {
 
     public synchronized String toString(String charsetName) {
         if (availableByteCount > 0) {
-            if (Charset.isSupported(charsetName)) {
-                Charset charset = Charset.forName(charsetName);
-                return toString(charset);
-            } else if (MllpProtocolConstants.MSH18_VALUES.containsKey(charsetName)) {
-                return toString(MllpProtocolConstants.MSH18_VALUES.get(charsetName));
-            } else {
-                return toString(DEFAULT_CHARSET);
+            try {
+                if (Charset.isSupported(charsetName)) {
+                    return toString(Charset.forName(charsetName));
+                }
+                log.warn("Unsupported character set name {} - using the MLLP default character set {}", charsetName, MllpComponent.getDefaultCharset());
+            } catch (Exception charsetEx) {
+                log.warn("Ignoring exception encountered determining character set for name {} - using the MLLP default character set {}",
+                    charsetName, MllpComponent.getDefaultCharset(), charsetEx);
             }
+
+            return toString(MllpComponent.getDefaultCharset());
         }
 
         return "";
@@ -335,7 +338,7 @@ public class MllpSocketBuffer {
     }
 
     public synchronized String toHl7String() {
-        return this.toHl7String(StandardCharsets.US_ASCII.name());
+        return this.toHl7String(MllpComponent.getDefaultCharset());
     }
 
     public String toHl7StringAndReset() {
@@ -347,27 +350,33 @@ public class MllpSocketBuffer {
     }
 
     public synchronized String toHl7String(String charsetName) {
-        String hl7String = null;
+        if (charsetName != null && !charsetName.isEmpty()) {
+            try {
+                if (Charset.isSupported(charsetName)) {
+                    return toHl7String(Charset.forName(charsetName));
+                }
+                log.warn("Unsupported character set name {} - using the MLLP default character set {}", charsetName, MllpComponent.getDefaultCharset());
+            } catch (Exception charsetEx) {
+                log.warn("Ignoring exception encountered determining character set for name {} - using the MLLP default character set {}",
+                    charsetName, MllpComponent.getDefaultCharset(), charsetEx);
+            }
+        }
+
+        return toHl7String(MllpComponent.getDefaultCharset());
+    }
 
+    public synchronized String toHl7String(Charset charset) {
         if (hasCompleteEnvelope()) {
             int offset = hasStartOfBlock() ? startOfBlockIndex + 1 : 1;
             int length = hasEndOfBlock() ? endOfBlockIndex - offset : availableByteCount - startOfBlockIndex - 1;
             if (length > 0) {
-                try {
-                    hl7String = new String(buffer,
-                        offset,
-                        length,
-                        charsetName);
-                } catch (UnsupportedEncodingException unsupportedEncodingEx) {
-                    log.warn("Failed to create string using {} charset - falling back to default charset {}", charsetName, MllpProtocolConstants.DEFAULT_CHARSET);
-                    hl7String = new String(buffer, offset, length, MllpProtocolConstants.DEFAULT_CHARSET);
-                }
+                return new String(buffer, offset, length, charset != null ? charset : MllpComponent.getDefaultCharset());
             } else {
-                hl7String = "";
+                return "";
             }
         }
 
-        return hl7String;
+        return null;
     }
 
     public String toHl7StringAndReset(String charsetName) {
diff --git a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/TcpSocketConsumerRunnable.java b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/TcpSocketConsumerRunnable.java
index a8159b0..5780d90 100644
--- a/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/TcpSocketConsumerRunnable.java
+++ b/components/camel-mllp/src/main/java/org/apache/camel/component/mllp/internal/TcpSocketConsumerRunnable.java
@@ -194,7 +194,8 @@ public class TcpSocketConsumerRunnable implements Runnable {
                             long lastReceivedMessageTicks = consumer.getConsumerRunnables().get(this);
                             long idleTime = currentTicks - lastReceivedMessageTicks;
                             if (idleTime >= consumer.getConfiguration().getIdleTimeout()) {
-                                consumer.getEndpoint().doConnectionClose(clientSocket, true, log);
+                                String resetMessage = String.format("Connection idle time {} exceeded idleTimeout {}", idleTime, consumer.getConfiguration().getIdleTimeout());
+                                mllpBuffer.resetSocket(clientSocket, resetMessage);
                             }
                         }
                         log.debug("No data received - ignoring timeout");
diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpEndpointTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpEndpointTest.java
index 304726b..2c68e7e 100644
--- a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpEndpointTest.java
+++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpEndpointTest.java
@@ -52,97 +52,4 @@ public class MllpEndpointTest {
         instance = new MllpEndpoint("mllp://dummy", new MllpComponent(), new MllpConfiguration());
     }
 
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithNullMessage() throws Exception {
-        assertNull(instance.createNewString(null, null));
-    }
-
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithEmptyMessage() throws Exception {
-        byte[] emptyMessage = new byte[0];
-
-        assertEquals("", instance.createNewString(emptyMessage, null));
-    }
-
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithBadMessage() throws Exception {
-        final String testMessage =
-            "MSH|^~\\&" + '\r' + '\n';
-
-        assertEquals(testMessage, instance.createNewString(testMessage.getBytes(StandardCharsets.ISO_8859_1), null));
-    }
-
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithBadCharsetSpecifiedAndNoMsh18InMessage() throws Exception {
-        instance.configuration.charsetName = "BAD-CHARSET";
-
-        assertEquals(TEST_MESSAGE, instance.createNewString(TEST_MESSAGE.getBytes(StandardCharsets.ISO_8859_1), null));
-    }
-
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithCharsetSpecifiedAndNoMsh18InMessage() throws Exception {
-        instance.configuration.charsetName = StandardCharsets.US_ASCII.name();
-
-        assertEquals(TEST_MESSAGE, instance.createNewString(TEST_MESSAGE.getBytes(StandardCharsets.ISO_8859_1), null));
-    }
-
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithoutCharsetSpecifiedAndNoMsh18InMessage() throws Exception {
-        assertEquals(TEST_MESSAGE, instance.createNewString(TEST_MESSAGE.getBytes(StandardCharsets.ISO_8859_1), null));
-    }
-
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithoutCharsetSpecifiedAndMsh18PassedToFunction() throws Exception {
-        final String testMessage = MSH_SEGMENT + "|||||||8859/1" + '\r' + REMAINING_SEGMENTS;
-
-        assertEquals(testMessage, instance.createNewString(testMessage.getBytes(StandardCharsets.ISO_8859_1), "8859/1"));
-    }
-
-    /**
-     * Description of test.
-     *
-     * @throws Exception in the event of a test error.
-     */
-    @Test
-    public void testCreateNewStringWithoutCharsetSpecifiedAndNoMsh18PassedToFunction() throws Exception {
-        final String testMessage = MSH_SEGMENT + "|||||||8859/1" + '\r' + REMAINING_SEGMENTS;
-
-        assertEquals(testMessage, instance.createNewString(testMessage.getBytes(StandardCharsets.ISO_8859_1), null));
-    }
-
 }
\ No newline at end of file
diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpExceptionTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpExceptionTest.java
index e09e8b8..6348ba6 100644
--- a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpExceptionTest.java
+++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpExceptionTest.java
@@ -176,7 +176,7 @@ public class MllpExceptionTest extends MllpExceptionTestSupport {
             expectedMessageBuilder.append("\n\t{hl7Message [")
                 .append(hl7Message.length())
                 .append("] = ")
-                .append(hl7Message.replaceAll("\r", "<CR>").replaceAll("\n", "<LF>"))
+                .append(hl7Message.replaceAll("\r", "<0x0D CR>").replaceAll("\n", "<0x0A LF>"))
                 .append("}");
         }
 
@@ -184,7 +184,7 @@ public class MllpExceptionTest extends MllpExceptionTestSupport {
             expectedMessageBuilder.append("\n\t{hl7Acknowledgement [")
                 .append(hl7Acknowledgment.length())
                 .append("] = ")
-                .append(hl7Acknowledgment.replaceAll("\r", "<CR>").replaceAll("\n", "<LF>"))
+                .append(hl7Acknowledgment.replaceAll("\r", "<0x0D CR>").replaceAll("\n", "<0x0A LF>"))
                 .append("}");
         }
 
diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerCharsetTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerCharsetTest.java
new file mode 100644
index 0000000..e48d6a5
--- /dev/null
+++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/MllpTcpServerCharsetTest.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;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.builder.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.junit4.CamelTestSupport;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class MllpTcpServerCharsetTest extends CamelTestSupport {
+    static final String TEST_MESSAGE = 
+        "MSH|^~\\&|KinetDx|UCLA Health System|||201801301506||ORU^R01|18030543772221|P|2.3^^||||||ISO_IR 100|" + '\r' 
+        + "PID|1||1117922||TESTER^MARY||19850627|F" + '\r'
+        + "OBR|1||55510818|ECH10^TRANSTHORACIC ECHO ADULT COMPLETE^IMGPROC|||20180126103542|||||||||029137^LEIBZON^ROMAN^^^^^^EPIC^^^^PROVID|||||Y|20180130150612|||F"
+        +     "|||||||029137^Leibzon^Roman^^MD^^^^EPIC^^^^PROVID" + '\r'
+        + "DG1|1|I10|^I10^ HTN (essential)^I10" + '\r'
+        + "DG1|2|I10|R94.31^Abnormal EKG^I10" + '\r'
+        + "OBX|1|FT|&GDT||  Thousand Oaks Cardiology||||||F" + '\r'
+        + "OBX|2|FT|&GDT|| 100 Moody Court, Suite 200||||||F" + '\r'
+        + "OBX|3|FT|&GDT||  Thousand Oaks, CA 91360||||||F" + '\r'
+        + "OBX|4|FT|&GDT||    Phone: 805-418-3500||||||F" + '\r'
+        + "OBX|5|FT|&GDT|| ||||||F" + '\r'
+        + "OBX|6|FT|&GDT||TRANSTHORACIC ECHOCARDIOGRAM REPORT||||||F" + '\r'
+        + "OBX|7|FT|&GDT|| ||||||F" + '\r'
+        + "OBX|8|FT|&GDT||Patient Name:              Date of Exam:   1/26/2018||||||F" + '\r'
+        + "OBX|9|FT|&GDT||Medical Rec #:                    Accession #:         ||||||F" + '\r'
+        + "OBX|10|FT|&GDT||Date of Birth:                   Height:         74 in||||||F" + '\r'
+        + "OBX|11|FT|&GDT||Age:                             Weight:         230 lbs||||||F" + '\r'
+        + "OBX|12|FT|&GDT||Gender:                          BSA:            2.31 m²||||||F" + '\r'
+        + "OBX|13|FT|&GDT||Referring Physician: 029137 ROMAN LEIBZON Blood Pressure: /||||||F" + '\r'
+        + "OBX|14|FT|&GDT||Diagnosis: I10- HTN (essential); R94.31-Abnormal EKG||||||F" + '\r'
+        + "OBX|15|FT|&GDT|| ||||||F" + '\r'
+        + "OBX|16|FT|&GDT||MEASUREMENTS:||||||F" + '\r'
+        + "OBX|17|FT|&GDT||LVIDd (2D)     5.16 cm LVIDs (2D)   3.14 cm||||||F" + '\r'
+        + "OBX|18|FT|&GDT||IVSd (2D)      0.93 cm LVPWd (2D)   1.10 cm||||||F" + '\r'
+        + "OBX|19|FT|&GDT||LA (2D)        4.00 cm Ao Root (2D) 3.00 cm||||||F" + '\r'
+        + "OBX|20|FT|&GDT||FINDINGS:||||||F" + '\r'
+        + "OBX|21|FT|&GDT||Left Ventricle: The left ventricular size is normal. Left ventricular wall thickness is normal. LV wall motion is normal. The ejection fraction by Simpson's "
+        +     "Biplane method is 60 %. Normal LV diastolic function. MV deceleration time is 127 msec.||||||F" + '\r'
+        + "OBX|22|FT|&GDT||MV E velocity is 0.77 m/s. MV A velocity is 0.56 m/s. E/A ratio is 1.36.||||||F" + '\r'
+        + "OBX|23|FT|&GDT||Lateral E/e' ratio is 6.0. Medial E/e' ratio is 8.7.||||||F" + '\r'
+        + "OBX|24|FT|&GDT||Left Atrium: The left atrium is mildly dilated in size. The LA Volume index is 30.8 ml/m².||||||F" + '\r'
+        + "OBX|25|FT|&GDT||Right Atrium: The right atrium is normal in size. RA area is 17 cm2. RA volume is 42 ml.||||||F" + '\r'
+        + "OBX|26|FT|&GDT||Right Ventricle: The right ventricular size is normal. Global RV systolic function is normal. TAPSE 24 mm. The RV free wall tissue Doppler S' wave measures 16.7 cm/s. "
+        +     "The right ventricle basal diameter measures 26 mm. The right ventricle mid cavity measures 23 mm. The right ventricle longitudinal diameter measures 65 mm.||||||F" + '\r'
+        + "OBX|27|FT|&GDT||Mitral Valve: Mitral annular calcification noted. Trace mitral valve regurgitation. There is no mitral stenosis.||||||F" + '\r'
+        + "OBX|28|FT|&GDT||Aortic Valve: The aortic valve appears trileaflet. Trace aortic valve regurgitation. The LVOT velocity is 1.16 m/s. The peak aortic valve velocity is 1.19 m/s. "
+        +     "No aortic valve stenosis.||||||F" + '\r'
+        + "OBX|29|FT|&GDT||Tricuspid Valve: The tricuspid valve appears normal in structure. Trace tricuspid regurgitation is present. The peak velocity of TR is 2.55 m/s.||||||F" + '\r'
+        + "OBX|30|FT|&GDT||Pulmonic Valve: Trivial pulmonary valve regurgitation. No evidence of pulmonary valve stenosis.||||||F" + '\r'
+        + "OBX|31|FT|&GDT||Pericardium: There is no pericardial effusion.||||||F" + '\r'
+        + "OBX|32|FT|&GDT||Aorta: The aortic root size is normal. The aortic valve annulus measures 25 mm. The sinus of Valsalva measures 33 mm. The sinotubular junction measures 30 mm. "
+        +     "The proximal ascending aorta measures 30 mm.||||||F" + '\r'
+        + "OBX|33|FT|&GDT||Pulmonary Artery: Based on the acceleration time in the RV outflow tract, the PA pressure is not likely to be elevated. The calculated pulmonary artery pressure "
+        +     "(or right ventricular systolic pressure) is 29 mmHg, if the right atrial pressure is 3 mmHg. Normal PA systolic pressure.||||||F" + '\r'
+        + "OBX|34|FT|&GDT||IVC: Normal inferior vena cava in diameter with respiratory variation consistent with normal right atrial pressure.||||||F" + '\r'
+        + "OBX|35|FT|&GDT|| ||||||F" + '\r'
+        + "OBX|36|FT|&GDT||IMPRESSION:||||||F" + '\r'
+        + "OBX|37|FT|&GDT|| 1. Normal left ventricular size.||||||F" + '\r'
+        + "OBX|38|FT|&GDT|| 2. The calculated ejection fraction (Simpson's) is 60 %.||||||F" + '\r'
+        + "OBX|39|FT|&GDT|| 3. Normal LV diastolic function.||||||F" + '\r'
+        + "OBX|40|FT|&GDT|| 4. Mildly dilated left atrium in size.||||||F" + '\r'
+        + "OBX|41|FT|&GDT||029137 Roman Leibzon MD||||||F" + '\r'
+        + "OBX|42|FT|&GDT||Electronically signed by 029137 Roman Leibzon MD on 1/30/2018 at 3:06:12 PM||||||F" + '\r'
+        + "OBX|43|FT|&GDT|| ||||||F" + '\r'
+        + "OBX|44|FT|&GDT||Sonographer: Liana Yenokyan||||||F" + '\r'
+        + "OBX|45|FT|&GDT|| ||||||F" + '\r'
+        + "OBX|46|FT|&GDT||*** Final ***||||||F\r";
+        
+    static final String TARGET_URI = "mock://target";
+
+    @Rule
+    public MllpClientResource mllpClient = new MllpClientResource();
+
+    @EndpointInject(uri = TARGET_URI)
+    MockEndpoint target;
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        mllpClient.setMllpHost("localhost");
+        mllpClient.setMllpPort(AvailablePortFinder.getNextAvailable());
+
+        DefaultCamelContext context = (DefaultCamelContext) super.createCamelContext();
+
+        context.setUseMDCLogging(true);
+        context.setName(this.getClass().getSimpleName());
+
+        return context;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            String routeId = "mllp-sender";
+
+            public void configure() {
+                fromF("mllp://%d?receiveTimeout=1000&readTimeout=500&charsetName=ISO-IR-100", mllpClient.getMllpPort())
+                    .log(LoggingLevel.INFO, routeId, "Sending Message")
+                    .to(target);
+            }
+        };
+    }
+
+
+    @Test
+    public void testReceiveMessageWithInvalidMsh18() throws Exception {
+        target.expectedMinimumMessageCount(1);
+
+        mllpClient.connect();
+
+        mllpClient.sendMessageAndWaitForAcknowledgement(TEST_MESSAGE);
+
+        assertMockEndpointsSatisfied(5, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void testReceiveMessageWithValidMsh18() throws Exception {
+        target.expectedMinimumMessageCount(1);
+
+        mllpClient.connect();
+
+        mllpClient.sendMessageAndWaitForAcknowledgement(TEST_MESSAGE.replace("ISO_IR 100", "ISO-IR-100"));
+
+        assertMockEndpointsSatisfied(5, TimeUnit.SECONDS);
+    }
+}
diff --git a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/internal/Hl7UtilTest.java b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/internal/Hl7UtilTest.java
index dcd7801..9ba18b4 100644
--- a/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/internal/Hl7UtilTest.java
+++ b/components/camel-mllp/src/test/java/org/apache/camel/component/mllp/internal/Hl7UtilTest.java
@@ -55,21 +55,21 @@ public class Hl7UtilTest {
             + MllpProtocolConstants.END_OF_BLOCK + MllpProtocolConstants.END_OF_DATA;
 
     static final String EXPECTED_MESSAGE =
-        "MSH|^~\\&|ADT|EPIC|JCAPS|CC|20161206193919|RISTECH|ADT^A08|00001|D|2.3^^|||||||" + "<CR>"
-            + "EVN|A08|20150107161440||REG_UPDATE_SEND_VISIT_MESSAGES_ON_PATIENT_CHANGES|RISTECH^RADIOLOGY^TECHNOLOGIST^^^^^^UCLA^^^^^RRMC||" + "<CR>"
+        "MSH|^~\\&|ADT|EPIC|JCAPS|CC|20161206193919|RISTECH|ADT^A08|00001|D|2.3^^|||||||" + "<0x0D CR>"
+            + "EVN|A08|20150107161440||REG_UPDATE_SEND_VISIT_MESSAGES_ON_PATIENT_CHANGES|RISTECH^RADIOLOGY^TECHNOLOGIST^^^^^^UCLA^^^^^RRMC||" + "<0x0D CR>"
             + "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||" + "<CR>"
-            + "PD1|||UCLA HEALTH SYSTEM^^10|10002116^ADAMS^JOHN^D^^^^^EPIC^^^^PROVID||||||||||||||" + "<CR>"
-            + "NK1|1|DOE^MC9^^|OTH|^^^^^USA|(310)888-9999^^^^^310^8889999|(310)999-2222^^^^^310^9992222|Emergency Contact 1|||||||||||||||||||||||||||" + "<CR>"
+            +     "||ENGLISH|U||60000013647|565-33-2222|||U||||||||N||" + "<0x0D CR>"
+            + "PD1|||UCLA HEALTH SYSTEM^^10|10002116^ADAMS^JOHN^D^^^^^EPIC^^^^PROVID||||||||||||||" + "<0x0D CR>"
+            + "NK1|1|DOE^MC9^^|OTH|^^^^^USA|(310)888-9999^^^^^310^8889999|(310)999-2222^^^^^310^9992222|Emergency Contact 1|||||||||||||||||||||||||||" + "<0x0D CR>"
             + "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||||||||||" + "<CR>"
-            + "PV2||||||||20150107161438||||CT BRAIN W WO CONTRAST||||||||||N|||||||||||||||||||||||||||" + "<CR>"
-            + "ZPV||||||||||||20150107161438|||||||||" + "<CR>"
-            + "AL1|1||33361^NO KNOWN ALLERGIES^^NOTCOMPUTRITION^NO KNOWN ALLERGIES^EXTELG||||||" + "<CR>"
-            + "DG1|1|DX|784.0^Headache^DX|Headache||VISIT" + "<CR>"
+            +     "|||||||||||||||||||||HOV_CONF|^^^1000^^^^^^^||20150107161438||||||||||" + "<0x0D CR>"
+            + "PV2||||||||20150107161438||||CT BRAIN W WO CONTRAST||||||||||N|||||||||||||||||||||||||||" + "<0x0D CR>"
+            + "ZPV||||||||||||20150107161438|||||||||" + "<0x0D CR>"
+            + "AL1|1||33361^NO KNOWN ALLERGIES^^NOTCOMPUTRITION^NO KNOWN ALLERGIES^EXTELG||||||" + "<0x0D CR>"
+            + "DG1|1|DX|784.0^Headache^DX|Headache||VISIT" + "<0x0D CR>"
             + "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"
-            +     "|||||||||||||||||||||||||||||" + "<CR>"
-            + "UB2||||||||" + "<CR>";
+            +     "|||||||||||||||||||||||||||||" + "<0x0D CR>"
+            + "UB2||||||||" + "<0x0D CR>";
     // @formatter:on
 
     static final String MSH_SEGMENT = "MSH|^~\\&|0|90100053675|JCAPS|CC|20131125122938|RISMD|ORM|28785|D|2.3";
@@ -381,7 +381,7 @@ public class Hl7UtilTest {
         assertEquals("", Hl7Util.bytesToPrintFriendlyStringBuilder(TEST_MESSAGE_BYTES, 1000000, -14).toString());
         assertEquals("", Hl7Util.bytesToPrintFriendlyStringBuilder(TEST_MESSAGE_BYTES, 1000000, 1000000).toString());
 
-        assertEquals("ADT^A08|00001|D|2.3^^|||||||<CR>EVN|A08|2015010716144", Hl7Util.bytesToPrintFriendlyStringBuilder(TEST_MESSAGE_BYTES, 50, 100).toString());
+        assertEquals("ADT^A08|00001|D|2.3^^|||||||<0x0D CR>EVN|A08|2015010716144", Hl7Util.bytesToPrintFriendlyStringBuilder(TEST_MESSAGE_BYTES, 50, 100).toString());
     }
 
     /**
@@ -562,7 +562,7 @@ public class Hl7UtilTest {
 
         builder = new StringBuilder();
         Hl7Util.appendBytesAsPrintFriendlyString(builder, TEST_MESSAGE_BYTES, 50, 100);
-        assertEquals("ADT^A08|00001|D|2.3^^|||||||<CR>EVN|A08|2015010716144", builder.toString());
+        assertEquals("ADT^A08|00001|D|2.3^^|||||||<0x0D CR>EVN|A08|2015010716144", builder.toString());
     }
 
     /**
@@ -583,28 +583,28 @@ public class Hl7UtilTest {
 
         builder = new StringBuilder();
         Hl7Util.appendCharacterAsPrintFriendlyString(builder, MllpProtocolConstants.START_OF_BLOCK);
-        assertEquals(Hl7Util.START_OF_BLOCK_REPLACEMENT_VALUE, builder.toString());
+        assertEquals("<0x0B VT>", builder.toString());
 
         builder = new StringBuilder();
         Hl7Util.appendCharacterAsPrintFriendlyString(builder, MllpProtocolConstants.END_OF_BLOCK);
-        assertEquals(Hl7Util.END_OF_BLOCK_REPLACEMENT_VALUE, builder.toString());
+        assertEquals("<0x1C FS>", builder.toString());
 
         builder = new StringBuilder();
         Hl7Util.appendCharacterAsPrintFriendlyString(builder, MllpProtocolConstants.SEGMENT_DELIMITER);
-        assertEquals(Hl7Util.SEGMENT_DELIMITER_REPLACEMENT_VALUE, builder.toString());
+        assertEquals("<0x0D CR>", builder.toString());
 
         builder = new StringBuilder();
         Hl7Util.appendCharacterAsPrintFriendlyString(builder, MllpProtocolConstants.MESSAGE_TERMINATOR);
-        assertEquals(Hl7Util.MESSAGE_TERMINATOR_REPLACEMENT_VALUE, builder.toString());
+        assertEquals("<0x0A LF>", builder.toString());
     }
 
     @Test
     public void testGetCharacterAsPrintFriendlyString() throws Exception {
-        assertEquals(Hl7Util.START_OF_BLOCK_REPLACEMENT_VALUE, Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.START_OF_BLOCK));
-        assertEquals(Hl7Util.END_OF_BLOCK_REPLACEMENT_VALUE, Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.END_OF_BLOCK));
-        assertEquals(Hl7Util.SEGMENT_DELIMITER_REPLACEMENT_VALUE, Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.SEGMENT_DELIMITER));
-        assertEquals(Hl7Util.MESSAGE_TERMINATOR_REPLACEMENT_VALUE, Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.MESSAGE_TERMINATOR));
-        assertEquals(Hl7Util.TAB_REPLACEMENT_VALUE, Hl7Util.getCharacterAsPrintFriendlyString('\t'));
+        assertEquals("<0x0B VT>", Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.START_OF_BLOCK));
+        assertEquals("<0x1C FS>", Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.END_OF_BLOCK));
+        assertEquals("<0x0D CR>", Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.SEGMENT_DELIMITER));
+        assertEquals("<0x0A LF>", Hl7Util.getCharacterAsPrintFriendlyString(MllpProtocolConstants.MESSAGE_TERMINATOR));
+        assertEquals("<0x09 TAB>", Hl7Util.getCharacterAsPrintFriendlyString('\t'));
     }
 
     /**
@@ -614,7 +614,7 @@ public class Hl7UtilTest {
      */
     @Test
     public void testFindMsh18WhenExistsWithoutTrailingPipe() throws Exception {
-        final String testMessage = MSH_SEGMENT + "|||||||8859/1" + '\r' + REMAINING_SEGMENTS;
+        final String testMessage = MSH_SEGMENT + "||||||8859/1" + '\r' + REMAINING_SEGMENTS;
 
         assertEquals("8859/1", Hl7Util.findMsh18(testMessage.getBytes()));
     }
@@ -626,7 +626,7 @@ public class Hl7UtilTest {
      */
     @Test
     public void testFindMsh18WhenExistsWithTrailingPipe() throws Exception {
-        final String testMessage = MSH_SEGMENT + "|||||||8859/1|" + '\r' + REMAINING_SEGMENTS;
+        final String testMessage = MSH_SEGMENT + "||||||8859/1|" + '\r' + REMAINING_SEGMENTS;
 
         assertEquals("8859/1", Hl7Util.findMsh18(testMessage.getBytes()));
     }
@@ -638,7 +638,7 @@ public class Hl7UtilTest {
      */
     @Test
     public void testFindMsh18WhenMissingWithoutTrailingPipe() throws Exception {
-        final String testMessage = MSH_SEGMENT + "|||||||" + '\r' + REMAINING_SEGMENTS;
+        final String testMessage = MSH_SEGMENT + "||||||" + '\r' + REMAINING_SEGMENTS;
 
         assertEquals("", Hl7Util.findMsh18(testMessage.getBytes()));
     }
@@ -650,7 +650,7 @@ public class Hl7UtilTest {
      */
     @Test
     public void testFindMsh18WhenMissingWithTrailingPipe() throws Exception {
-        final String testMessage = MSH_SEGMENT + "||||||||" + '\r' + REMAINING_SEGMENTS;
+        final String testMessage = MSH_SEGMENT + "|||||||" + '\r' + REMAINING_SEGMENTS;
 
         assertEquals("", Hl7Util.findMsh18(testMessage.getBytes()));
     }
diff --git a/platforms/spring-boot/components-starter/camel-mllp-starter/src/main/java/org/apache/camel/component/mllp/springboot/MllpComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-mllp-starter/src/main/java/org/apache/camel/component/mllp/springboot/MllpComponentConfiguration.java
index c29bf31..0ab3bf7 100644
--- a/platforms/spring-boot/components-starter/camel-mllp-starter/src/main/java/org/apache/camel/component/mllp/springboot/MllpComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-mllp-starter/src/main/java/org/apache/camel/component/mllp/springboot/MllpComponentConfiguration.java
@@ -45,6 +45,10 @@ public class MllpComponentConfiguration
      */
     private Integer logPhiMaxBytes = 5120;
     /**
+     * Set the default character set to use for byte to/from String conversions.
+     */
+    private String defaultCharset = "ISO-8859-1";
+    /**
      * Sets the default configuration to use when creating MLLP endpoints.
      */
     private MllpConfigurationNestedConfiguration configuration;
@@ -71,6 +75,14 @@ public class MllpComponentConfiguration
         this.logPhiMaxBytes = logPhiMaxBytes;
     }
 
+    public String getDefaultCharset() {
+        return defaultCharset;
+    }
+
+    public void setDefaultCharset(String defaultCharset) {
+        this.defaultCharset = defaultCharset;
+    }
+
     public MllpConfigurationNestedConfiguration getConfiguration() {
         return configuration;
     }
@@ -290,8 +302,8 @@ public class MllpComponentConfiguration
          * to a String. If the charsetName property is set, that character set
          * will be used for the conversion. If the charsetName property is not
          * set, the value of MSH-18 will be used to determine th appropriate
-         * character set. If MSH-18 is not set, then the default ASCII character
-         * set will be use.
+         * character set. If MSH-18 is not set, then the default ISO-8859-1
+         * character set will be use.
          * 
          * @param stringPayload
          *            enabled if true, otherwise disabled

-- 
To stop receiving notification emails like this one, please contact
quinn@apache.org.