You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by al...@apache.org on 2020/09/11 10:57:14 UTC

[ignite] branch master updated: IGNITE-13401 Java thin client: Fix unmarshalling failure when cache configuration message or binary type message start with byte 103 - Fixes #8216.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new eff5393  IGNITE-13401 Java thin client: Fix unmarshalling failure when cache configuration message or binary type message start with byte 103 - Fixes #8216.
eff5393 is described below

commit eff5393b8b09985b4147ce8022411ea8b11515cb
Author: Aleksey Plekhanov <pl...@gmail.com>
AuthorDate: Fri Sep 11 13:53:25 2020 +0300

    IGNITE-13401 Java thin client: Fix unmarshalling failure when cache configuration message or binary type message start with byte 103 - Fixes #8216.
    
    Signed-off-by: Aleksey Plekhanov <pl...@gmail.com>
---
 .../client/thin/ClientCacheAffinityMapping.java    |  2 +-
 .../client/thin/ClientClusterGroupImpl.java        | 23 +++++----
 .../internal/client/thin/ClientClusterImpl.java    |  5 +-
 .../ignite/internal/client/thin/ClientUtils.java   | 21 +++++++-
 .../internal/client/thin/TcpClientChannel.java     |  4 +-
 .../internal/client/thin/TcpIgniteClient.java      |  2 +-
 .../client/ClientCacheConfigurationTest.java       | 56 +++++++++++++++++-----
 .../org/apache/ignite/client/IgniteBinaryTest.java | 25 ++++++++++
 8 files changed, 106 insertions(+), 32 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientCacheAffinityMapping.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientCacheAffinityMapping.java
index a7ae173..ac422d0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientCacheAffinityMapping.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientCacheAffinityMapping.java
@@ -144,7 +144,7 @@ public class ClientCacheAffinityMapping {
      * @param ch Input channel.
      */
     public static ClientCacheAffinityMapping readResponse(PayloadInputChannel ch) {
-        try (BinaryReaderExImpl in = new BinaryReaderExImpl(null, ch.in(), null, true)) {
+        try (BinaryReaderExImpl in = ClientUtils.createBinaryReader(null, ch.in())) {
             long topVer = in.readLong();
             int minorTopVer = in.readInt();
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterGroupImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterGroupImpl.java
index fd26025..0ee826a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterGroupImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterGroupImpl.java
@@ -38,8 +38,8 @@ import org.apache.ignite.client.ClientClusterGroup;
 import org.apache.ignite.client.ClientException;
 import org.apache.ignite.client.ClientFeatureNotSupportedByServerException;
 import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.binary.BinaryRawWriterEx;
 import org.apache.ignite.internal.binary.BinaryReaderExImpl;
-import org.apache.ignite.internal.binary.BinaryWriterExImpl;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -55,8 +55,8 @@ class ClientClusterGroupImpl implements ClientClusterGroup {
     /** Channel. */
     protected final ReliableChannel ch;
 
-    /** Binary marshaller. */
-    protected final ClientBinaryMarshaller marsh;
+    /** Marshaller utils. */
+    protected final ClientUtils utils;
 
     /** Projection filters. */
     private final ProjectionFilters projectionFilters;
@@ -75,7 +75,8 @@ class ClientClusterGroupImpl implements ClientClusterGroup {
      */
     ClientClusterGroupImpl(ReliableChannel ch, ClientBinaryMarshaller marsh) {
         this.ch = ch;
-        this.marsh = marsh;
+
+        utils = new ClientUtils(marsh);
 
         projectionFilters = ProjectionFilters.FULL_PROJECTION;
     }
@@ -83,10 +84,10 @@ class ClientClusterGroupImpl implements ClientClusterGroup {
     /**
      *
      */
-    private ClientClusterGroupImpl(ReliableChannel ch, ClientBinaryMarshaller marsh,
+    private ClientClusterGroupImpl(ReliableChannel ch, ClientUtils utils,
         ProjectionFilters projectionFilters) {
         this.ch = ch;
-        this.marsh = marsh;
+        this.utils = utils;
         this.projectionFilters = projectionFilters;
     }
 
@@ -230,7 +231,7 @@ class ClientClusterGroupImpl implements ClientClusterGroup {
      */
     private ClientClusterGroupImpl forProjectionFilters(ProjectionFilters projectionFilters) {
         return this.projectionFilters == projectionFilters ? this :
-            new ClientClusterGroupImpl(ch, marsh, projectionFilters);
+            new ClientClusterGroupImpl(ch, utils, projectionFilters);
     }
 
     /** {@inheritDoc} */
@@ -300,8 +301,7 @@ class ClientClusterGroupImpl implements ClientClusterGroup {
                     if (!req.clientChannel().protocolCtx().isFeatureSupported(ProtocolBitmaskFeature.CLUSTER_GROUPS))
                         throw new ClientFeatureNotSupportedByServerException(ProtocolBitmaskFeature.CLUSTER_GROUPS);
 
-                    try (BinaryWriterExImpl writer = new BinaryWriterExImpl(marsh.context(), req.out(), null,
-                        null)) {
+                    try (BinaryRawWriterEx writer = utils.createBinaryWriter(req.out())) {
                         writer.writeLong(cachedTopVer);
 
                         projectionFilters.write(writer);
@@ -385,8 +385,7 @@ class ClientClusterGroupImpl implements ClientClusterGroup {
                     }
                 },
                 res -> {
-                    try (BinaryReaderExImpl reader = new BinaryReaderExImpl(marsh.context(), res.in(), null,
-                        true)) {
+                    try (BinaryReaderExImpl reader = utils.createBinaryReader(res.in())) {
                         int nodesCnt = reader.readInt();
 
                         Collection<ClusterNode> nodes = new ArrayList<>();
@@ -766,7 +765,7 @@ class ClientClusterGroupImpl implements ClientClusterGroup {
         /**
          * @param writer Writer.
          */
-        void write(BinaryWriterExImpl writer) {
+        void write(BinaryRawWriterEx writer) {
             int size = (attrs == null ? 0 : attrs.size()) + (nodeType == null ? 0 : 1);
 
             writer.writeInt(size);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java
index dc35142ee..6dfc5bf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientClusterImpl.java
@@ -22,7 +22,6 @@ import org.apache.ignite.client.ClientException;
 import org.apache.ignite.client.ClientFeatureNotSupportedByServerException;
 import org.apache.ignite.cluster.ClusterState;
 import org.apache.ignite.internal.binary.BinaryRawWriterEx;
-import org.apache.ignite.internal.binary.BinaryWriterExImpl;
 
 /**
  * Implementation of {@link ClientCluster}.
@@ -94,7 +93,7 @@ class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster
                 req -> {
                     checkClusterApiSupported(req.clientChannel().protocolCtx());
 
-                    try (BinaryRawWriterEx writer = new BinaryWriterExImpl(marsh.context(), req.out(), null, null)) {
+                    try (BinaryRawWriterEx writer = utils.createBinaryWriter(req.out())) {
                         writer.writeString(cacheName);
                     }
                 },
@@ -116,7 +115,7 @@ class ClientClusterImpl extends ClientClusterGroupImpl implements ClientCluster
                 req -> {
                     checkClusterApiSupported(req.clientChannel().protocolCtx());
 
-                    try (BinaryRawWriterEx writer = new BinaryWriterExImpl(marsh.context(), req.out(), null, null)) {
+                    try (BinaryRawWriterEx writer = utils.createBinaryWriter(req.out())) {
                         writer.writeString(cacheName);
                         writer.writeBoolean(enable);
                     }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java
index fe866b8..1e62a5f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientUtils.java
@@ -49,6 +49,7 @@ import org.apache.ignite.cache.QueryIndex;
 import org.apache.ignite.cache.QueryIndexType;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.client.ClientCacheConfiguration;
+import org.apache.ignite.internal.binary.BinaryContext;
 import org.apache.ignite.internal.binary.BinaryFieldMetadata;
 import org.apache.ignite.internal.binary.BinaryMetadata;
 import org.apache.ignite.internal.binary.BinaryObjectImpl;
@@ -65,6 +66,7 @@ import org.apache.ignite.internal.binary.streams.BinaryOutputStream;
 import org.apache.ignite.internal.processors.platform.cache.expiry.PlatformExpiryPolicy;
 import org.apache.ignite.internal.util.MutableSingletonList;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.internal.client.thin.ProtocolVersionFeature.EXPIRY_POLICY;
 import static org.apache.ignite.internal.client.thin.ProtocolVersionFeature.QUERY_ENTITY_PRECISION_AND_SCALE;
@@ -164,7 +166,7 @@ final class ClientUtils {
 
     /** Deserialize binary type metadata from stream. */
     BinaryMetadata binaryMetadata(BinaryInputStream in) throws IOException {
-        try (BinaryReaderExImpl reader = new BinaryReaderExImpl(marsh.context(), in, null, true)) {
+        try (BinaryReaderExImpl reader = createBinaryReader(in)) {
             int typeId = reader.readInt();
             String typeName = reader.readString();
             String affKeyFieldName = reader.readString();
@@ -380,7 +382,7 @@ final class ClientUtils {
     /** Deserialize configuration from stream. */
     ClientCacheConfiguration cacheConfiguration(BinaryInputStream in, ProtocolContext protocolCtx)
         throws IOException {
-        try (BinaryReaderExImpl reader = new BinaryReaderExImpl(marsh.context(), in, null, true)) {
+        try (BinaryReaderExImpl reader = createBinaryReader(in)) {
             reader.readInt(); // Do not need length to read data. The protocol defines fixed configuration layout.
 
             return new ClientCacheConfiguration().setName("TBD") // cache name is to be assigned later
@@ -536,6 +538,21 @@ final class ClientUtils {
         return new BinaryWriterExImpl(marsh.context(), out, BinaryThreadLocalContext.get().schemaHolder(), null);
     }
 
+    /**
+     * @param in Input stream.
+     */
+    BinaryReaderExImpl createBinaryReader(BinaryInputStream in) {
+        return createBinaryReader(marsh.context(), in);
+    }
+
+    /**
+     * @param binaryCtx Binary context.
+     * @param in Input stream.
+     */
+    static BinaryReaderExImpl createBinaryReader(@Nullable BinaryContext binaryCtx, BinaryInputStream in) {
+        return new BinaryReaderExImpl(binaryCtx, in, null, null, true, true);
+    }
+
     /** Read Ignite binary object from input stream. */
     <T> T readObject(BinaryInputStream in, boolean keepBinary) {
         return readObject(in, keepBinary, null);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientChannel.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientChannel.java
index 91e5f0f..4e3bd63 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientChannel.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpClientChannel.java
@@ -385,7 +385,7 @@ class TcpClientChannel implements ClientChannel {
         else {
             resIn = new BinaryHeapInputStream(dataInput.read(msgSize - hdrSize));
 
-            String errMsg = new BinaryReaderExImpl(null, resIn, null, true).readString();
+            String errMsg = ClientUtils.createBinaryReader(null, resIn).readString();
 
             err = new ClientServerError(errMsg, status, resId);
         }
@@ -536,7 +536,7 @@ class TcpClientChannel implements ClientChannel {
 
         BinaryInputStream res = new BinaryHeapInputStream(dataInput.read(resSize));
 
-        try (BinaryReaderExImpl reader = new BinaryReaderExImpl(null, res, null, true)) {
+        try (BinaryReaderExImpl reader = ClientUtils.createBinaryReader(null, res)) {
             boolean success = res.readBoolean();
 
             if (success) {
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java
index 7fd0a1d..c6748aa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java
@@ -282,7 +282,7 @@ public class TcpIgniteClient implements IgniteClient {
     /** Deserialize string. */
     private String readString(BinaryInputStream in) throws BinaryObjectException {
         try {
-            try (BinaryReaderExImpl r = new BinaryReaderExImpl(marsh.context(), in, null, true)) {
+            try (BinaryReaderExImpl r = serDes.createBinaryReader(in)) {
                 return r.readString();
             }
         }
diff --git a/modules/core/src/test/java/org/apache/ignite/client/ClientCacheConfigurationTest.java b/modules/core/src/test/java/org/apache/ignite/client/ClientCacheConfigurationTest.java
index 350c0dc..bc6878e 100644
--- a/modules/core/src/test/java/org/apache/ignite/client/ClientCacheConfigurationTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/client/ClientCacheConfigurationTest.java
@@ -25,6 +25,8 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
 import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.stream.Collectors;
@@ -37,23 +39,17 @@ import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.cache.PartitionLossPolicy;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.testframework.GridTestUtils;
-import org.junit.Rule;
+import org.apache.ignite.internal.client.thin.AbstractThinClientTest;
+import org.apache.ignite.internal.util.typedef.F;
 import org.junit.Test;
-import org.junit.rules.Timeout;
-
-import static org.junit.Assert.assertTrue;
 
 /**
  * {@link ClientConfiguration} unit tests.
  */
-public class ClientCacheConfigurationTest {
-    /** Per test timeout */
-    @Rule
-    public Timeout globalTimeout = new Timeout((int) GridTestUtils.DFLT_TEST_TIMEOUT);
-
-    /** Serialization/deserialization. */
+public class ClientCacheConfigurationTest extends AbstractThinClientTest {
+    /** Java serialization/deserialization. */
     @Test
     public void testSerialization() throws IOException, ClassNotFoundException {
         ClientCacheConfiguration target = new ClientCacheConfiguration().setName("Person")
@@ -104,4 +100,42 @@ public class ClientCacheConfigurationTest {
 
         assertTrue(Comparers.equal(target, desTarget));
     }
+
+    /** Ignite serialization/deserialization of cache configurations with different sizes. */
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testDifferentSizeCacheConfiguration() throws Exception {
+        Collection<CacheConfiguration> cacheCfgs = new ArrayList<>();
+
+        Collection<QueryEntity> qryEntities = new ArrayList<>();
+
+        for (int i = 0; i < 5; i++) {
+            qryEntities.add(new QueryEntity(int.class.getName(), "QueryEntity" + i)
+                    .setTableName("ENTITY" + i)
+                    .setFields(new LinkedHashMap<>(
+                            F.asMap("id", Integer.class.getName(), "name", String.class.getName()))));
+        }
+
+        CacheConfiguration<?, ?> cfgTemplate = new CacheConfiguration<>()
+                .setGroupName("CacheGroupName")
+                .setQueryEntities(qryEntities);
+
+        String cacheName = "";
+
+        for (int i = 0; i < 256; i++) {
+            cacheName += 'a';
+
+            cacheCfgs.add(new CacheConfiguration<>(cfgTemplate).setName(cacheName));
+        }
+
+        startGrid(0).createCaches(cacheCfgs);
+
+        try (IgniteClient client = startClient(0)) {
+            for (CacheConfiguration igniteCacheCfg : cacheCfgs) {
+                ClientCacheConfiguration clientCacheCfg = client.cache(igniteCacheCfg.getName()).getConfiguration();
+
+                assertEquals(igniteCacheCfg.getName(), clientCacheCfg.getName());
+            }
+        }
+    }
 }
diff --git a/modules/core/src/test/java/org/apache/ignite/client/IgniteBinaryTest.java b/modules/core/src/test/java/org/apache/ignite/client/IgniteBinaryTest.java
index 9f93e2f..370e889 100644
--- a/modules/core/src/test/java/org/apache/ignite/client/IgniteBinaryTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/client/IgniteBinaryTest.java
@@ -30,6 +30,8 @@ import org.apache.ignite.binary.BinaryObjectBuilder;
 import org.apache.ignite.binary.BinaryType;
 import org.apache.ignite.configuration.BinaryConfiguration;
 import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.internal.binary.BinaryObjectImpl;
+import org.apache.ignite.internal.binary.GridBinaryMarshaller;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.junit.Rule;
 import org.junit.Test;
@@ -250,6 +252,29 @@ public class IgniteBinaryTest {
         }
     }
 
+    /**
+     * The purpose of this test is to check that message which begins with the same byte as marshaller header can
+     * be correctly unmarshalled.
+     */
+    @Test
+    public void testBinaryTypeWithIdOfMarshallerHeader() throws Exception {
+        try (Ignite ignite = Ignition.start(Config.getServerConfiguration())) {
+            try (IgniteClient client = Ignition.startClient(new ClientConfiguration().setAddresses(Config.SERVER))) {
+                int typeId = GridBinaryMarshaller.OBJ;
+
+                BinaryObjectImpl binObj = (BinaryObjectImpl)ignite.binary().builder(Character.toString((char)typeId))
+                        .setField("dummy", "dummy")
+                        .build();
+
+                assertEquals(typeId, binObj.typeId());
+
+                BinaryType type = client.binary().type(typeId);
+
+                assertEquals(binObj.type().typeName(), type.typeName());
+            }
+        }
+    }
+
     /** */
     private void assertBinaryTypesEqual(BinaryType exp, BinaryType actual) {
         assertEquals(exp.typeId(), actual.typeId());