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

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


The following commit(s) were added to refs/heads/main by this push:
     new 0cbdb9b67088 CAMEL-26090: camel-hl7 - add a maxFrameLength option to 
the HL7 MLLP Netty decoder (#28758)
0cbdb9b67088 is described below

commit 0cbdb9b670883f0f0cc1443b290cbdc8c3ebc194
Author: allthingssecurity <[email protected]>
AuthorDate: Sat Oct 31 15:32:40 2026 +0530

    CAMEL-26090: camel-hl7 - add a maxFrameLength option to the HL7 MLLP Netty 
decoder (#28758)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../apache/camel/catalog/docs/hl7-dataformat.adoc  |  19 +++
 .../camel-hl7/src/main/docs/hl7-dataformat.adoc    |  19 +++
 .../apache/camel/component/hl7/HL7MLLPConfig.java  |  18 +++
 .../camel/component/hl7/HL7MLLPNettyDecoder.java   |   9 +-
 .../component/hl7/HL7MLLPNettyDecoderFactory.java  |  15 ++
 .../hl7/HL7MLLPNettyDecoderMaxFrameLengthTest.java | 158 +++++++++++++++++++++
 .../hl7/HL7MLLPNettyMaxFrameLengthRouteTest.java   | 130 +++++++++++++++++
 7 files changed, 362 insertions(+), 6 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hl7-dataformat.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hl7-dataformat.adoc
index 9787b933bc6d..bdbf5edf75b8 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hl7-dataformat.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hl7-dataformat.adoc
@@ -69,6 +69,13 @@ the HL7 message content.
 
 |`convertLFtoCR` |`false` |Will convert `\n` to `\r` (`0x0d`, 13 decimal) as 
HL7 stipulates `\r` as
 segment terminators. The HAPI library requires the use of `\r`.
+
+|`maxFrameLength` |`2147483647` |Netty decoder (`HL7MLLPNettyDecoderFactory`) 
only: the maximum length in bytes of
+a message, counted from the start of the data up to the end bytes (the start 
byte included, the end bytes not). A
+longer message is discarded and fails with a `TooLongFrameException`: the 
Netty consumer reports it to its exception
+handler and closes the connection. The decoder fails as soon as more bytes 
than the limit have arrived without both end
+bytes, so a message of exactly this length fails when its first end byte 
arrives without the second; set the limit
+with some margin over the largest message you expect. The default 
(`Integer.MAX_VALUE`) means no limit.
 |===
 
 === Exposing an HL7 listener using Mina
@@ -161,6 +168,18 @@ The beans can be set in the Spring XML file:
 <bean id="hl7encoder" 
class="org.apache.camel.component.hl7.HL7MLLPNettyEncoderFactory"/>
 ----
 
+By default the decoder accepts messages of any size. To limit the size of a 
message, set `maxFrameLength` (in bytes)
+on the decoder factory; a longer message fails with a `TooLongFrameException` 
and the connection is closed (see
+`maxFrameLength` in the options above):
+
+._XML-only: Spring bean declaration for an HL7 Netty decoder with a message 
size limit_
+[source,xml]
+----
+<bean id="hl7decoder" 
class="org.apache.camel.component.hl7.HL7MLLPNettyDecoderFactory">
+  <property name="maxFrameLength" value="1048576"/>
+</bean>
+----
+
 The endpoint *hl7NettyListener* can then be used in a route as a
 consumer, as this Java DSL example illustrates:
 
diff --git a/components/camel-hl7/src/main/docs/hl7-dataformat.adoc 
b/components/camel-hl7/src/main/docs/hl7-dataformat.adoc
index 9787b933bc6d..bdbf5edf75b8 100644
--- a/components/camel-hl7/src/main/docs/hl7-dataformat.adoc
+++ b/components/camel-hl7/src/main/docs/hl7-dataformat.adoc
@@ -69,6 +69,13 @@ the HL7 message content.
 
 |`convertLFtoCR` |`false` |Will convert `\n` to `\r` (`0x0d`, 13 decimal) as 
HL7 stipulates `\r` as
 segment terminators. The HAPI library requires the use of `\r`.
+
+|`maxFrameLength` |`2147483647` |Netty decoder (`HL7MLLPNettyDecoderFactory`) 
only: the maximum length in bytes of
+a message, counted from the start of the data up to the end bytes (the start 
byte included, the end bytes not). A
+longer message is discarded and fails with a `TooLongFrameException`: the 
Netty consumer reports it to its exception
+handler and closes the connection. The decoder fails as soon as more bytes 
than the limit have arrived without both end
+bytes, so a message of exactly this length fails when its first end byte 
arrives without the second; set the limit
+with some margin over the largest message you expect. The default 
(`Integer.MAX_VALUE`) means no limit.
 |===
 
 === Exposing an HL7 listener using Mina
@@ -161,6 +168,18 @@ The beans can be set in the Spring XML file:
 <bean id="hl7encoder" 
class="org.apache.camel.component.hl7.HL7MLLPNettyEncoderFactory"/>
 ----
 
+By default the decoder accepts messages of any size. To limit the size of a 
message, set `maxFrameLength` (in bytes)
+on the decoder factory; a longer message fails with a `TooLongFrameException` 
and the connection is closed (see
+`maxFrameLength` in the options above):
+
+._XML-only: Spring bean declaration for an HL7 Netty decoder with a message 
size limit_
+[source,xml]
+----
+<bean id="hl7decoder" 
class="org.apache.camel.component.hl7.HL7MLLPNettyDecoderFactory">
+  <property name="maxFrameLength" value="1048576"/>
+</bean>
+----
+
 The endpoint *hl7NettyListener* can then be used in a route as a
 consumer, as this Java DSL example illustrates:
 
diff --git 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPConfig.java
 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPConfig.java
index fdc28a6bc21d..8e7a0aed356b 100644
--- 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPConfig.java
+++ 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPConfig.java
@@ -46,6 +46,8 @@ public class HL7MLLPConfig {
 
     private CodingErrorAction unmappableCharacterErrorAction = 
CodingErrorAction.REPORT;
 
+    private int maxFrameLength = Integer.MAX_VALUE;
+
     public Charset getCharset() {
         return charset;
     }
@@ -134,4 +136,20 @@ public class HL7MLLPConfig {
     public void setUnmappableCharacterErrorAction(CodingErrorAction 
unmappableCharacterErrorAction) {
         this.unmappableCharacterErrorAction = unmappableCharacterErrorAction;
     }
+
+    public int getMaxFrameLength() {
+        return maxFrameLength;
+    }
+
+    /**
+     * The maximum length in bytes of a message that the Netty decoder reads, 
counted from the start of the data up to
+     * the end bytes (the start byte included, the end bytes not). A longer 
message is discarded and fails with a
+     * {@code TooLongFrameException}. The default is {@link Integer#MAX_VALUE} 
(no limit).
+     */
+    public void setMaxFrameLength(int maxFrameLength) {
+        if (maxFrameLength <= 0) {
+            throw new IllegalArgumentException("maxFrameLength must be a 
positive number: " + maxFrameLength);
+        }
+        this.maxFrameLength = maxFrameLength;
+    }
 }
diff --git 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoder.java
 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoder.java
index 286fa16406c0..a60d1dc1a3d2 100644
--- 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoder.java
+++ 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoder.java
@@ -16,8 +16,6 @@
  */
 package org.apache.camel.component.hl7;
 
-import java.nio.charset.Charset;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
@@ -32,7 +30,6 @@ import org.slf4j.LoggerFactory;
 class HL7MLLPNettyDecoder extends DelimiterBasedFrameDecoder {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(HL7MLLPNettyDecoder.class);
-    private static final int MAX_FRAME_LENGTH = Integer.MAX_VALUE;
     private final HL7MLLPConfig config;
 
     /**
@@ -49,9 +46,9 @@ class HL7MLLPNettyDecoder extends DelimiterBasedFrameDecoder {
      * @throws java.lang.NullPointerException is config is null
      */
     HL7MLLPNettyDecoder(HL7MLLPConfig config) {
-        super(MAX_FRAME_LENGTH, true, Unpooled.copiedBuffer(
-                new char[] { config.getEndByte1(), config.getEndByte2() },
-                Charset.defaultCharset()));
+        // the delimiter must be the exact bytes the encoder writes ((byte) 
char), so it is not encoded with a charset
+        super(config.getMaxFrameLength(), true, Unpooled.wrappedBuffer(
+                new byte[] { (byte) config.getEndByte1(), (byte) 
config.getEndByte2() }));
         this.config = config;
     }
 
diff --git 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoderFactory.java
 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoderFactory.java
index 5740516a4e1b..72acede6f808 100644
--- 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoderFactory.java
+++ 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoderFactory.java
@@ -23,6 +23,21 @@ import io.netty.channel.ChannelHandler;
  */
 public class HL7MLLPNettyDecoderFactory extends 
HL7MLLPConfigAwareChannelHandlerFactory {
 
+    public int getMaxFrameLength() {
+        return config.getMaxFrameLength();
+    }
+
+    /**
+     * The maximum length in bytes of a message that the decoder reads, 
counted from the start of the data up to the end
+     * bytes (the start byte included, the end bytes not). A longer message is 
discarded and fails with a
+     * {@code TooLongFrameException}; a netty consumer reports it to its 
exception handler and closes the connection.
+     * The decoder fails as soon as more bytes than the limit have arrived 
without both end bytes, so leave some margin
+     * over the largest expected message. The default is {@link 
Integer#MAX_VALUE} (no limit).
+     */
+    public void setMaxFrameLength(int maxFrameLength) {
+        config.setMaxFrameLength(maxFrameLength);
+    }
+
     @Override
     public ChannelHandler newChannelHandler() {
         return new HL7MLLPNettyDecoder(config);
diff --git 
a/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoderMaxFrameLengthTest.java
 
b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoderMaxFrameLengthTest.java
new file mode 100644
index 000000000000..80a50a9fed93
--- /dev/null
+++ 
b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7MLLPNettyDecoderMaxFrameLengthTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.hl7;
+
+import java.nio.charset.StandardCharsets;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.embedded.EmbeddedChannel;
+import io.netty.handler.codec.TooLongFrameException;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Tests the maxFrameLength option of the HL7 MLLP Netty decoder.
+ */
+class HL7MLLPNettyDecoderMaxFrameLengthTest {
+
+    private static final String START = "\u000b";
+    private static final String END = "\u001c\r";
+
+    @Test
+    void messageAtTheLimitIsDecoded() {
+        // the start byte and 49 bytes of message: 50 bytes before the end 
bytes
+        String message = "A".repeat(49);
+        EmbeddedChannel channel = new EmbeddedChannel(decoder(50));
+
+        channel.writeInbound(Unpooled.copiedBuffer(START + message + END, 
StandardCharsets.ISO_8859_1));
+
+        assertEquals(message, channel.readInbound());
+        assertFalse(channel.finish());
+    }
+
+    @Test
+    void messageOverTheLimitFails() {
+        String message = "A".repeat(50);
+        EmbeddedChannel channel = new EmbeddedChannel(decoder(50));
+
+        TooLongFrameException e = assertThrows(TooLongFrameException.class,
+                () -> channel.writeInbound(Unpooled.copiedBuffer(START + 
message + END, StandardCharsets.ISO_8859_1)));
+
+        assertTrue(e.getMessage().startsWith("frame length exceeds 50"), 
e.getMessage());
+        assertNull(channel.readInbound());
+        assertFalse(channel.finish());
+    }
+
+    @Test
+    void dataWithoutEndBytesFailsOnceOverTheLimitAndTheNextMessageIsDecoded() {
+        EmbeddedChannel channel = new EmbeddedChannel(decoder(50));
+
+        // a peer that sends more than the limit without the end bytes: the 
decoder does not wait for them
+        TooLongFrameException e = assertThrows(TooLongFrameException.class,
+                () -> channel.writeInbound(Unpooled.copiedBuffer(START + 
"B".repeat(60), StandardCharsets.ISO_8859_1)));
+        assertTrue(e.getMessage().startsWith("frame length exceeds 50"), 
e.getMessage());
+        assertNull(channel.readInbound());
+
+        // the rest of the long message is discarded up to its end bytes, and 
the next message is decoded
+        channel.writeInbound(Unpooled.copiedBuffer("B".repeat(20) + END + 
START + "next" + END,
+                StandardCharsets.ISO_8859_1));
+        assertEquals("next", channel.readInbound());
+        assertNull(channel.readInbound());
+        assertFalse(channel.finish());
+    }
+
+    @Test
+    void factoryAppliesTheLimitToItsDecoders() {
+        HL7MLLPNettyDecoderFactory factory = new HL7MLLPNettyDecoderFactory();
+        factory.setMaxFrameLength(50);
+        assertEquals(50, factory.getMaxFrameLength());
+
+        EmbeddedChannel channel = new 
EmbeddedChannel(factory.newChannelHandler());
+        channel.writeInbound(Unpooled.copiedBuffer(START + "A".repeat(49) + 
END, StandardCharsets.ISO_8859_1));
+        assertEquals("A".repeat(49), channel.readInbound());
+
+        assertThrows(TooLongFrameException.class,
+                () -> channel.writeInbound(Unpooled.copiedBuffer(START + 
"A".repeat(50) + END, StandardCharsets.ISO_8859_1)));
+        assertNull(channel.readInbound());
+        assertFalse(channel.finish());
+    }
+
+    @Test
+    void defaultIsNoLimit() {
+        assertEquals(Integer.MAX_VALUE, new 
HL7MLLPConfig().getMaxFrameLength());
+        assertEquals(Integer.MAX_VALUE, new 
HL7MLLPNettyDecoderFactory().getMaxFrameLength());
+
+        String message = "C".repeat(1024 * 1024);
+        EmbeddedChannel channel = new EmbeddedChannel(new 
HL7MLLPNettyDecoderFactory().newChannelHandler());
+        channel.writeInbound(Unpooled.copiedBuffer(START + message + END, 
StandardCharsets.ISO_8859_1));
+
+        assertEquals(message, channel.readInbound());
+        assertFalse(channel.finish());
+    }
+
+    @Test
+    void highStartAndEndBytesAreMatchedAsTheBytesTheEncoderWrites() {
+        // the encoder writes each start and end byte as one byte: the decoder 
must look for that byte too, and not
+        // for its encoding in the default charset (two bytes in UTF-8), or 
with a limit every message is too long
+        HL7MLLPConfig config = new HL7MLLPConfig();
+        config.setCharset(StandardCharsets.ISO_8859_1);
+        config.setStartByte('\u008c');
+        config.setEndByte1('\u00ff');
+        config.setMaxFrameLength(50);
+        EmbeddedChannel encoder = new EmbeddedChannel(new 
HL7MLLPNettyEncoder(config));
+        EmbeddedChannel decoder = new EmbeddedChannel(new 
HL7MLLPNettyDecoder(config));
+
+        String message = "A".repeat(49);
+        assertTrue(encoder.writeOutbound(message));
+        ByteBuf frame = encoder.readOutbound();
+        try {
+            assertEquals(52, frame.readableBytes());
+            assertEquals((byte) 0x8c, frame.getByte(frame.readerIndex()));
+            assertEquals((byte) 0xff, frame.getByte(frame.writerIndex() - 2));
+            decoder.writeInbound(frame.retain());
+        } finally {
+            frame.release();
+        }
+
+        assertEquals(0, frame.refCnt());
+        assertEquals(message, decoder.readInbound());
+        assertFalse(encoder.finish());
+        assertFalse(decoder.finish());
+    }
+
+    @Test
+    void maxFrameLengthMustBePositive() {
+        HL7MLLPConfig config = new HL7MLLPConfig();
+        assertThrows(IllegalArgumentException.class, () -> 
config.setMaxFrameLength(0));
+        assertThrows(IllegalArgumentException.class, () -> 
config.setMaxFrameLength(-1));
+        assertEquals(Integer.MAX_VALUE, config.getMaxFrameLength());
+    }
+
+    private static ChannelHandler decoder(int maxFrameLength) {
+        HL7MLLPConfig config = new HL7MLLPConfig();
+        config.setCharset(StandardCharsets.ISO_8859_1);
+        config.setMaxFrameLength(maxFrameLength);
+        return new HL7MLLPNettyDecoder(config);
+    }
+}
diff --git 
a/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7MLLPNettyMaxFrameLengthRouteTest.java
 
b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7MLLPNettyMaxFrameLengthRouteTest.java
new file mode 100644
index 000000000000..b1428509a95e
--- /dev/null
+++ 
b/components/camel-hl7/src/test/java/org/apache/camel/component/hl7/HL7MLLPNettyMaxFrameLengthRouteTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.hl7;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.netty.handler.codec.TooLongFrameException;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.ExceptionHandler;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * A Netty HL7 listener with a maxFrameLength refuses a longer message and 
keeps serving other connections.
+ */
+class HL7MLLPNettyMaxFrameLengthRouteTest extends HL7TestSupport {
+
+    private static final String MESSAGE = 
"MSH|^~\\&|MYSENDER|MYRECEIVER|MYAPPLICATION||200612211200||QRY^A19|1234|P|2.4";
+
+    private final CountDownLatch handled = new CountDownLatch(1);
+    private final AtomicReference<Throwable> handledException = new 
AtomicReference<>();
+
+    @BindToRegistry("hl7decoder")
+    HL7MLLPNettyDecoderFactory addDecoder() {
+        HL7MLLPNettyDecoderFactory decoder = new HL7MLLPNettyDecoderFactory();
+        decoder.setMaxFrameLength(1024);
+        return decoder;
+    }
+
+    @BindToRegistry("hl7encoder")
+    HL7MLLPNettyEncoderFactory addEncoder() {
+        return new HL7MLLPNettyEncoderFactory();
+    }
+
+    @BindToRegistry("recordingHandler")
+    ExceptionHandler addExceptionHandler() {
+        return new ExceptionHandler() {
+            @Override
+            public void handleException(Throwable exception) {
+                handleException(null, null, exception);
+            }
+
+            @Override
+            public void handleException(String message, Throwable exception) {
+                handleException(message, null, exception);
+            }
+
+            @Override
+            public void handleException(String message, Exchange exchange, 
Throwable exception) {
+                handledException.compareAndSet(null, exception);
+                handled.countDown();
+            }
+        };
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("netty:tcp://127.0.0.1:" + getPort()
+                     + 
"?sync=true&decoders=#hl7decoder&encoders=#hl7encoder&exceptionHandler=#recordingHandler")
+                        .to("mock:result")
+                        .setBody(constant("ACK"));
+            }
+        };
+    }
+
+    @Test
+    void messageOverTheLimitClosesItsConnectionAndOtherMessagesAreServed() 
throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived(MESSAGE);
+
+        try (Socket socket = new Socket("127.0.0.1", getPort())) {
+            socket.setSoTimeout(10000);
+            OutputStream out = socket.getOutputStream();
+            // a message of 2000 bytes without the end bytes: the listener 
does not wait for them
+            out.write(0x0b);
+            out.write("A".repeat(2000).getBytes(StandardCharsets.ISO_8859_1));
+            out.flush();
+            assertEquals(-1, readUntilClosed(socket.getInputStream()));
+        }
+
+        assertTrue(handled.await(10, TimeUnit.SECONDS), "the exception handler 
was not called");
+        assertInstanceOf(TooLongFrameException.class, handledException.get());
+
+        String reply = template.requestBody(
+                "netty:tcp://127.0.0.1:" + getPort() + 
"?sync=true&decoders=#hl7decoder&encoders=#hl7encoder", MESSAGE,
+                String.class);
+        assertEquals("ACK", reply);
+
+        mock.assertIsSatisfied();
+    }
+
+    private static int readUntilClosed(InputStream in) throws IOException {
+        try {
+            return in.read();
+        } catch (SocketException e) {
+            // connection reset by the listener
+            return -1;
+        }
+    }
+}

Reply via email to