From 566b5222a668432f718014886afbeab2f536f8da Mon Sep 17 00:00:00 2001 From: Mikhail Petrov <32207922+petrov-mg@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:58:14 +0300 Subject: [PATCH] IGNITE-21001 Java Thin Client: Fixed stale client cluster group data after cluster restart. (#11173) --- .../client/thin/ClientClusterGroupImpl.java | 7 +- .../thin/ClusterGroupClusterRestartTest.java | 78 +++++++++++++++++++ .../apache/ignite/client/ClientTestSuite.java | 2 + 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterGroupClusterRestartTest.java 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 b33a7caa1d75f..5b1154db8a9e9 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 @@ -62,6 +62,9 @@ class ClientClusterGroupImpl implements ClientClusterGroup { /** Projection filters. */ private final ProjectionFilters projectionFilters; + /** Client channel from which the cluster group nodes data was previously received. */ + private ClientChannel topDataSrc; + /** Cached topology version. */ private long cachedTopVer; @@ -304,7 +307,7 @@ private synchronized Collection requestNodeIds() { throw new ClientFeatureNotSupportedByServerException(ProtocolBitmaskFeature.CLUSTER_GROUPS); try (BinaryRawWriterEx writer = utils.createBinaryWriter(req.out())) { - writer.writeLong(cachedTopVer); + writer.writeLong(topDataSrc == null || topDataSrc.closed() ? 0 : cachedTopVer); projectionFilters.write(writer); } @@ -328,6 +331,8 @@ private synchronized Collection requestNodeIds() { cachedNodeIds = nodeIds; + topDataSrc = res.clientChannel(); + return new ArrayList<>(nodeIds); }); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterGroupClusterRestartTest.java b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterGroupClusterRestartTest.java new file mode 100644 index 0000000000000..15588bc882868 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/client/thin/ClusterGroupClusterRestartTest.java @@ -0,0 +1,78 @@ +/* + * 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.ignite.internal.client.thin; + +import java.util.Arrays; +import java.util.Collections; +import java.util.stream.Collectors; +import org.apache.ignite.client.ClientClusterGroup; +import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.junit.Test; + +import static org.apache.ignite.internal.processors.cache.distributed.GridCacheModuloAffinityFunction.IDX_ATTR; + +/** */ +public class ClusterGroupClusterRestartTest extends AbstractThinClientTest { + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName) + .setUserAttributes(Collections.singletonMap(IDX_ATTR, getTestIgniteInstanceIndex(igniteInstanceName))); + } + + /** */ + @Test + public void testGroupNodesAfterClusterRestart() throws Exception { + prepareCluster(); + + try (IgniteClient client = startClient(0, 1)) { + ClientClusterGroup dfltGrp = client.cluster(); + ClientClusterGroup srvGrp = client.cluster().forServers(); + ClientClusterGroup cliGrp = client.cluster().forClients(); + ClientClusterGroup attrGrp = client.cluster().forAttribute(IDX_ATTR, 0); + + assertContainsNodes(dfltGrp, 0, 1, 2); + assertContainsNodes(srvGrp, 0, 1); + assertContainsNodes(cliGrp, 2); + assertContainsNodes(attrGrp, 0); + + stopAllGrids(); + + prepareCluster(); + + assertContainsNodes(dfltGrp, 0, 1, 2); + assertContainsNodes(srvGrp, 0, 1); + assertContainsNodes(cliGrp, 2); + assertContainsNodes(attrGrp, 0); + } + } + + /** */ + private void assertContainsNodes(ClientClusterGroup grp, int... nodeIdxs) { + assertTrue(grp.nodes().containsAll(Arrays.stream(nodeIdxs).mapToObj(idx -> grid(idx).localNode()).collect(Collectors.toList()))); + + for (int idx : nodeIdxs) + assertNotNull(grp.node(grid(idx).localNode().id())); + } + + /** */ + private void prepareCluster() throws Exception { + startGrids(2); + startClientGrid(2); + } +} diff --git a/modules/indexing/src/test/java/org/apache/ignite/client/ClientTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/client/ClientTestSuite.java index 588715be8572d..45e55939fedbd 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/client/ClientTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/client/ClientTestSuite.java @@ -22,6 +22,7 @@ import org.apache.ignite.internal.client.thin.CacheAsyncTest; import org.apache.ignite.internal.client.thin.CacheEntryListenersTest; import org.apache.ignite.internal.client.thin.ClusterApiTest; +import org.apache.ignite.internal.client.thin.ClusterGroupClusterRestartTest; import org.apache.ignite.internal.client.thin.ClusterGroupTest; import org.apache.ignite.internal.client.thin.ComputeTaskTest; import org.apache.ignite.internal.client.thin.DataReplicationOperationsTest; @@ -90,6 +91,7 @@ ThinClientEnpointsDiscoveryTest.class, InactiveClusterCacheRequestTest.class, AffinityMetricsTest.class, + ClusterGroupClusterRestartTest.class }) public class ClientTestSuite { // No-op.