[ https://issues.apache.org/jira/browse/IGNITE-20038?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mikhail Petrov updated IGNITE-20038: ------------------------------------ Fix Version/s: 2.16 > [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 > Affects Versions: 2.14, 2.15 > Environment: > Reporter: Mikhail Petrov > Assignee: Mikhail Petrov > Priority: Major > Fix For: 2.16 > > Time Spent: 40m > Remaining Estimate: 0h > > 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)