This is an automated email from the ASF dual-hosted git repository. samt pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit 51ef21b6bc43d1d2fa24ff362d0411e4e248b079 Author: Marcus Eriksson <[email protected]> AuthorDate: Wed May 8 12:20:32 2024 +0200 Fix gossip status after replacement Patch by Marcus Eriksson; reviewed by Sam Tunnicliffe for CASSANDRA-19712 --- CHANGES.txt | 1 + .../tcm/listeners/LegacyStateListener.java | 1 + .../test/hostreplacement/HostReplacementTest.java | 26 ++++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index e19c99c913..515d837fec 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 5.1 + * Fix gossip status after replacement (CASSANDRA-19712) * Ignore repair requests for system_cluster_metadata (CASSANDRA-19711) * Avoid ClassCastException when verifying tables with reversed partitioner (CASSANDRA-19710) * Always repair the full range when repairing system_cluster_metadata (CASSANDRA-19709) diff --git a/src/java/org/apache/cassandra/tcm/listeners/LegacyStateListener.java b/src/java/org/apache/cassandra/tcm/listeners/LegacyStateListener.java index 0a1a759e08..3a8701f8f2 100644 --- a/src/java/org/apache/cassandra/tcm/listeners/LegacyStateListener.java +++ b/src/java/org/apache/cassandra/tcm/listeners/LegacyStateListener.java @@ -157,6 +157,7 @@ public class LegacyStateListener implements ChangeListener.Async for (Token token : tokens) logger.warn("Token {} changing ownership from {} to {}", token, replaced, replacement); } + Gossiper.instance.mergeNodeToGossip(change, next, tokens); } } else diff --git a/test/distributed/org/apache/cassandra/distributed/test/hostreplacement/HostReplacementTest.java b/test/distributed/org/apache/cassandra/distributed/test/hostreplacement/HostReplacementTest.java index 363b1bf4d9..85105dc8a3 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/hostreplacement/HostReplacementTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/hostreplacement/HostReplacementTest.java @@ -21,6 +21,7 @@ package org.apache.cassandra.distributed.test.hostreplacement; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.Test; import org.slf4j.Logger; @@ -34,7 +35,11 @@ import org.apache.cassandra.distributed.api.ICoordinator; import org.apache.cassandra.distributed.api.IInvokableInstance; import org.apache.cassandra.distributed.api.SimpleQueryResult; import org.apache.cassandra.distributed.api.TokenSupplier; +import org.apache.cassandra.distributed.shared.Uninterruptibles; import org.apache.cassandra.distributed.test.TestBaseImpl; +import org.apache.cassandra.gms.ApplicationState; +import org.apache.cassandra.gms.Gossiper; +import org.apache.cassandra.locator.InetAddressAndPort; import org.apache.cassandra.schema.SchemaConstants; import org.assertj.core.api.Assertions; @@ -48,6 +53,7 @@ import static org.apache.cassandra.distributed.shared.ClusterUtils.awaitRingJoin import static org.apache.cassandra.distributed.shared.ClusterUtils.getTokenMetadataTokens; import static org.apache.cassandra.distributed.shared.ClusterUtils.replaceHostAndStart; import static org.apache.cassandra.distributed.shared.ClusterUtils.stopUnchecked; +import static org.junit.Assert.fail; public class HostReplacementTest extends TestBaseImpl { @@ -106,6 +112,9 @@ public class HostReplacementTest extends TestBaseImpl expectedState.toObjectArrays()); validateRows(seed.coordinator(), expectedState); validateRows(replacingNode.coordinator(), expectedState); + String replacingNodeAddress = replacingNode.config().broadcastAddress().getHostString(); + validateGossipStatusNormal(seed, replacingNodeAddress); + validateGossipStatusNormal(replacingNode, replacingNodeAddress); } } @@ -240,4 +249,21 @@ public class HostReplacementTest extends TestBaseImpl SimpleQueryResult rows = coordinator.executeWithResult("SELECT * FROM " + KEYSPACE + ".tbl", ConsistencyLevel.ALL); assertRows(rows, expected); } + + static void validateGossipStatusNormal(IInvokableInstance i, String address) + { + i.runOnInstance(() -> { + long start = System.nanoTime(); + while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(20)) + { + InetAddressAndPort host = InetAddressAndPort.getByNameUnchecked(address); + String appstate = Gossiper.instance.getApplicationState(host, ApplicationState.STATUS_WITH_PORT); + if (appstate.startsWith("NORMAL")) + return; + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); + } + fail("Gossip STATUS_WITH_PORT did not become NORMAL"); + }); + } + } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
