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

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


The following commit(s) were added to refs/heads/master by this push:
     new 1f0bf0c77 [ISSUE #4701]Fix use tcp protocol client send message, it 
throw a DecoderException (#4702)
1f0bf0c77 is described below

commit 1f0bf0c7722fe220f01b0fd01feaa2a8a41e818f
Author: mxsm <[email protected]>
AuthorDate: Wed Jan 10 09:07:53 2024 +0800

    [ISSUE #4701]Fix use tcp protocol client send message, it throw a 
DecoderException (#4702)
    
    * [ISSUE #4701]fix use tcp protocol client send message, it throw a 
DecoderException
    
    * optmize code
    
    * refactor with LengthFieldBasedFrameDecoder
    
    * fix code style
    
    * optimize code
    
    * fix log print
    
    * optimize code and add some comments
---
 .../eventmesh/common/protocol/tcp/codec/Codec.java | 85 +++++++++++++---------
 .../common/protocol/tcp/codec/CodecTest.java       | 14 ++--
 .../eventmesh/client/tcp/common/TcpClient.java     |  2 +-
 3 files changed, 59 insertions(+), 42 deletions(-)

diff --git 
a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/codec/Codec.java
 
b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/codec/Codec.java
index cded7d67e..2417021b6 100644
--- 
a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/codec/Codec.java
+++ 
b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/tcp/codec/Codec.java
@@ -31,14 +31,11 @@ import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
-import java.util.List;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageCodec;
+import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
 import io.netty.handler.codec.MessageToByteEncoder;
-import io.netty.handler.codec.ReplayingDecoder;
-
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.google.common.base.Preconditions;
@@ -46,25 +43,16 @@ import com.google.common.base.Preconditions;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
-public class Codec extends ByteToMessageCodec<Package> {
+public class Codec {
 
     private static final int FRAME_MAX_LENGTH = 1024 * 1024 * 4;
 
     private static final byte[] CONSTANT_MAGIC_FLAG = 
serializeBytes("EventMesh");
     private static final byte[] VERSION = serializeBytes("0000");
 
-    private Encoder encoder = new Encoder();
-    private Decoder decoder = new Decoder();
+    private static final int PREFIX_LENGTH = CONSTANT_MAGIC_FLAG.length + 
VERSION.length; //13
 
-    @Override
-    protected void encode(ChannelHandlerContext ctx, Package pkg, ByteBuf out) 
throws Exception {
-        encoder.encode(ctx, pkg, out);
-    }
-
-    @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 
out) throws Exception {
-        decoder.decode(ctx, in, out);
-    }
+    private static final int PACKAGE_BYTES_FIELD_LENGTH = 4;
 
     public static class Encoder extends MessageToByteEncoder<Package> {
 
@@ -89,7 +77,7 @@ public class Codec extends ByteToMessageCodec<Package> {
             int headerLength = ArrayUtils.getLength(headerData);
             int bodyLength = ArrayUtils.getLength(bodyData);
 
-            final int length = CONSTANT_MAGIC_FLAG.length + VERSION.length + 
headerLength + bodyLength;
+            final int length = PREFIX_LENGTH + headerLength + bodyLength;
 
             if (length > FRAME_MAX_LENGTH) {
                 throw new IllegalArgumentException("message size is exceed 
limit!");
@@ -116,31 +104,62 @@ public class Codec extends ByteToMessageCodec<Package> {
         }
     }
 
-    public static class Decoder extends ReplayingDecoder<Package> {
+    public static class Decoder extends LengthFieldBasedFrameDecoder {
+
+        public Decoder() {
+            /**
+             * lengthAdjustment value = -9 explain:
+             * Header + Body, Format:
+             * <pre>
+             * 
┌───────────────┬─────────────┬──────────────────┬──────────────────┬──────────────────┬─────────────────┐
+             * │   MAGIC_FLAG  │   VERSION   │ package length   │   Header 
length  │      Header      │      body       │
+             * │    (9bytes)   │  (4bytes)   │    (4bytes)      │      
(4bytes)    │   (header bytes) │   (body bytes)  │
+             * 
└───────────────┴─────────────┴──────────────────┴──────────────────┴──────────────────┴─────────────────┘
+             * </pre>
+             * package length = MAGIC_FLAG + VERSION + Header length + Body 
length,Currently,
+             * adding MAGIC_FLAG + VERSION + package length field (4 bytes) 
actually adds 17 bytes.
+             * However, the value of the package length field is only reduced 
by the four bytes of
+             * the package length field itself and the four bytes of the 
header length field.
+             * Therefore, the compensation value to be added to the length 
field value is -9,
+             * which means subtracting the extra 9 bytes.
+             * Refer to the encoding in the {@link Encoder}
+             */
+            super(FRAME_MAX_LENGTH, PREFIX_LENGTH, PACKAGE_BYTES_FIELD_LENGTH, 
-9, 0);
+        }
 
         @Override
-        public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 
out) throws Exception {
+        protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws 
Exception {
+
+            ByteBuf target = null;
+
             try {
-                if (null == in) {
-                    return;
+                target = (ByteBuf) super.decode(ctx, in);
+                if (null == target) {
+                    return null;
                 }
-
-                byte[] flagBytes = parseFlag(in);
-                byte[] versionBytes = parseVersion(in);
+                byte[] flagBytes = parseFlag(target);
+                byte[] versionBytes = parseVersion(target);
                 validateFlag(flagBytes, versionBytes, ctx);
 
-                final int length = in.readInt();
-                final int headerLength = in.readInt();
-                final int bodyLength = length - CONSTANT_MAGIC_FLAG.length - 
VERSION.length - headerLength;
-                Header header = parseHeader(in, headerLength);
-                Object body = parseBody(in, header, bodyLength);
+                final int length = target.readInt();
+                final int headerLength = target.readInt();
+                final int bodyLength = length - PREFIX_LENGTH - headerLength;
+                Header header = parseHeader(target, headerLength);
+                Object body = parseBody(target, header, bodyLength);
 
                 Package pkg = new Package(header, body);
-                out.add(pkg);
-            } catch (Exception e) {
-                log.error("decode error| received data: {}.", 
deserializeBytes(in.array()), e);
-                throw e;
+                return pkg;
+
+            } catch (Exception ex) {
+                log.error("decode error", ex);
+                ctx.channel().close();
+            } finally {
+                if (target != null) {
+                    target.release();
+                }
             }
+
+            return null;
         }
 
         private byte[] parseFlag(ByteBuf in) {
diff --git 
a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/tcp/codec/CodecTest.java
 
b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/tcp/codec/CodecTest.java
index 29724e9b6..19907ffd2 100644
--- 
a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/tcp/codec/CodecTest.java
+++ 
b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/tcp/codec/CodecTest.java
@@ -20,8 +20,8 @@ package org.apache.eventmesh.common.protocol.tcp.codec;
 import org.apache.eventmesh.common.protocol.tcp.Command;
 import org.apache.eventmesh.common.protocol.tcp.Header;
 import org.apache.eventmesh.common.protocol.tcp.Package;
-
-import java.util.ArrayList;
+import org.apache.eventmesh.common.protocol.tcp.codec.Codec.Decoder;
+import org.apache.eventmesh.common.protocol.tcp.codec.Codec.Encoder;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -37,14 +37,12 @@ public class CodecTest {
         header.setCmd(Command.HELLO_REQUEST);
         Package testP = new Package(header);
         testP.setBody(new Object());
-        Codec.Encoder ce = new Codec.Encoder();
+        Encoder ce = new Codec.Encoder();
         ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer();
         ce.encode(null, testP, buf);
-        Codec.Decoder cd = new Codec.Decoder();
-        ArrayList<Object> result = new ArrayList<>();
-        cd.decode(null, buf, result);
-        Assertions.assertNotNull(result.get(0));
-        Assertions.assertEquals(testP.getHeader(), ((Package) 
result.get(0)).getHeader());
+        Decoder cd = new Codec.Decoder();
+        final Package decode = (Package) cd.decode(null, buf);
+        Assertions.assertEquals(testP.getHeader(), decode.getHeader());
     }
 
 }
diff --git 
a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java
 
b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java
index fed4af541..74a88945d 100644
--- 
a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java
+++ 
b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java
@@ -110,7 +110,7 @@ public abstract class TcpClient implements Closeable {
 
             @Override
             public void initChannel(SocketChannel ch) {
-                ch.pipeline().addLast(new Codec())
+                ch.pipeline().addLast(new Codec.Encoder(), new Codec.Decoder())
                     .addLast(handler, newExceptionHandler());
             }
         });


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to