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]

Reply via email to