Mikhail Petrov created IGNITE-20038:
---------------------------------------

             Summary: [Thin Client] Cache operations with PA enabled can fail 
with  BufferUnderflowException 
                 Key: IGNITE-20038
                 URL: https://issues.apache.org/jira/browse/IGNITE-20038
             Project: Ignite
          Issue Type: Task
         Environment: 

            Reporter: Mikhail Petrov


Cache operations with PA enabled can fail on thin clients with  
BufferUnderflowException due to broken ClientCachePartitionAwarenessGroup 
serialization.

Exception: 


{code:java}
 java.nio.BufferUnderflowException
        at java.nio.Buffer.nextGetIndex(Buffer.java:532)
        at java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:366)
        at 
org.apache.ignite.internal.binary.streams.BinaryByteBufferInputStream.readInt(BinaryByteBufferInputStream.java:111)
        at 
org.apache.ignite.internal.binary.BinaryReaderExImpl.readInt(BinaryReaderExImpl.java:746)
        at 
org.apache.ignite.internal.client.thin.ClientCacheAffinityMapping.readCacheKeyConfiguration(ClientCacheAffinityMapping.java:240)
        at 
org.apache.ignite.internal.client.thin.ClientCacheAffinityMapping.readResponse(ClientCacheAffinityMapping.java:197)
        at 
org.apache.ignite.internal.client.thin.ClientCacheAffinityContext.readPartitionsUpdateResponse(ClientCacheAffinityContext.java:154)
        at 
org.apache.ignite.internal.client.thin.TcpClientChannel.receive(TcpClientChannel.java:412)
        at 
org.apache.ignite.internal.client.thin.TcpClientChannel.service(TcpClientChannel.java:311)
        at 
org.apache.ignite.internal.client.thin.ThinClientAbstractPartitionAwarenessTest$TestTcpClientChannel.service(ThinClientAbstractPartitionAwarenessTest.java:345)
        at 
org.apache.ignite.internal.client.thin.ReliableChannel.lambda$affinityInfoIsUpToDate$6(ReliableChannel.java:423)
        at 
org.apache.ignite.internal.client.thin.ReliableChannel.applyOnNodeChannel(ReliableChannel.java:746)
        at 
org.apache.ignite.internal.client.thin.ReliableChannel.affinityInfoIsUpToDate(ReliableChannel.java:422)
        at 
org.apache.ignite.internal.client.thin.ReliableChannel.affinityService(ReliableChannel.java:316)
        at 
org.apache.ignite.internal.client.thin.TcpClientCache.txAwareService(TcpClientCache.java:1139)
        at 
org.apache.ignite.internal.client.thin.TcpClientCache.cacheSingleKeyOperation(TcpClientCache.java:1198)
        at 
org.apache.ignite.internal.client.thin.TcpClientCache.get(TcpClientCache.java:146)
        at 
org.apache.ignite.internal.client.thin.ThinClientPartitionAwarenessStableTopologyTest.lambda$testMultipleCacheGroupPartitionsRequest$8(ThinClientPartitionAwarenessStableTopologyTest.java:250)
        at 
org.apache.ignite.testframework.GridTestUtils.lambda$runAsync$4(GridTestUtils.java:1229)
        at 
org.apache.ignite.testframework.GridTestUtils$7.call(GridTestUtils.java:1570)
        at 
org.apache.ignite.testframework.GridTestThread.run(GridTestThread.java:88)

{code}

Reproducer:

{code:java}
/** */
    @Test
    public void test() throws Exception {
        Ignite ignite = startGrid(0);

        ignite.createCache(new 
CacheConfiguration<>("test-cache-0").setCacheMode(REPLICATED));
        ignite.createCache(new 
CacheConfiguration<>("test-cache-1").setCacheMode(PARTITIONED));

        try (IgniteClient cli = Ignition.startClient(new 
ClientConfiguration().setAddresses("127.0.0.1:10800"))) {
            ClientCacheAffinityContext affCtx = 
((TcpIgniteClient)cli).reliableChannel().affinityContext();

            IgniteInternalFuture<Object> replCacheOpFut;
            IgniteInternalFuture<Object> partCacheOpFut;

            synchronized (affCtx.cacheKeyMapperFactoryMap) {
                partCacheOpFut = GridTestUtils.runAsync(() -> 
cli.cache("test-cache-0").get(0));
                replCacheOpFut = GridTestUtils.runAsync(() -> 
cli.cache("test-cache-1").get(0));

                GridTestUtils.waitForCondition(
                    () -> 
affCtx.pendingCacheIds.containsAll(F.transform(asList("test-cache-0", 
"test-cache-1"), CU::cacheId)),
                    getTestTimeout()
                );
            }

            partCacheOpFut.get();
            replCacheOpFut.get();
        }
    }
{code}

Explanation: 

Take a look at the ClientCachePartitionAwarenessGroup#write method. During its 
serialization we write to the buffer the variable "dfltAffinity". Then take a 
look at ClientCacheAffinityMapping#readResponse. Here we deserialize the 
ClientCachePartitionAwarenessGroup instances, but in case the PA is not 
"applicable", we do not read the "dfltAffinity" variable from the buffer. As a 
result, if the ClientCacheAffinityMapping#readResponse deals with multiple 
cache group affinity mappings, the second one may not be properly deserialized 
due to the unread dfltAffinity variable .







--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to