cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmcken...@apache.org
Subject cassandra git commit: Throw UnsupportedOperationException for bad removeNode calls
Date Wed, 13 Jan 2016 19:35:08 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk 8036f04c0 -> 3f053121f


Throw UnsupportedOperationException for bad removeNode calls

Patch by jknighton; reviewed by jmckenzie for CASSANDRA-10926.


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/3f053121
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/3f053121
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/3f053121

Branch: refs/heads/trunk
Commit: 3f053121f12aa7cf059d14414769bc96d0ee6b37
Parents: 8036f04
Author: Joel Knighton <joel.knighton@datastax.com>
Authored: Sun Dec 27 12:58:38 2015 -0600
Committer: Joshua McKenzie <jmckenzie@apache.org>
Committed: Wed Jan 13 14:34:51 2016 -0500

----------------------------------------------------------------------
 .../cassandra/service/StorageService.java       | 13 ++++++-----
 .../apache/cassandra/service/RemoveTest.java    | 23 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/3f053121/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java
index 92a8136..22ea0c1 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -3885,7 +3885,7 @@ public class StorageService extends NotificationBroadcasterSupport implements
IE
 
     /**
      * Force a remove operation to complete. This may be necessary if a remove operation
-     * blocks forever due to node/stream failure. removeToken() must be called
+     * blocks forever due to node/stream failure. removeNode() must be called
      * first, this is a last resort measure.  No further attempt will be made to restore
replicas.
      */
     public void forceRemoveCompletion()
@@ -3904,18 +3904,18 @@ public class StorageService extends NotificationBroadcasterSupport
implements IE
         }
         else
         {
-            logger.warn("No tokens to force removal on, call 'removenode' first");
+            logger.warn("No nodes to force removal on, call 'removenode' first");
         }
     }
 
     /**
      * Remove a node that has died, attempting to restore the replica count.
      * If the node is alive, decommission should be attempted.  If decommission
-     * fails, then removeToken should be called.  If we fail while trying to
+     * fails, then removeNode should be called.  If we fail while trying to
      * restore the replica count, finally forceRemoveCompleteion should be
      * called to forcibly remove the node without regard to replica count.
      *
-     * @param hostIdString token for the node
+     * @param hostIdString Host ID for the node
      */
     public void removeNode(String hostIdString)
     {
@@ -3927,7 +3927,8 @@ public class StorageService extends NotificationBroadcasterSupport implements
IE
         if (endpoint == null)
             throw new UnsupportedOperationException("Host ID not found.");
 
-        Collection<Token> tokens = tokenMetadata.getTokens(endpoint);
+        if (!tokenMetadata.isMember(endpoint))
+            throw new UnsupportedOperationException("Node to be removed is not a member of
the token ring");
 
         if (endpoint.equals(myAddress))
              throw new UnsupportedOperationException("Cannot remove self");
@@ -3942,6 +3943,8 @@ public class StorageService extends NotificationBroadcasterSupport implements
IE
         if (!replicatingNodes.isEmpty())
             throw new UnsupportedOperationException("This node is already processing a removal.
Wait for it to complete, or use 'removenode force' if this has failed.");
 
+        Collection<Token> tokens = tokenMetadata.getTokens(endpoint);
+
         // Find the endpoints that are going to become responsible for data
         for (String keyspaceName : Schema.instance.getNonSystemKeyspaces())
         {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/3f053121/test/unit/org/apache/cassandra/service/RemoveTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/service/RemoveTest.java b/test/unit/org/apache/cassandra/service/RemoveTest.java
index 9f1d6a8..4c26fc5 100644
--- a/test/unit/org/apache/cassandra/service/RemoveTest.java
+++ b/test/unit/org/apache/cassandra/service/RemoveTest.java
@@ -22,6 +22,7 @@ package org.apache.cassandra.service;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
@@ -31,11 +32,14 @@ import org.junit.*;
 
 import org.apache.cassandra.SchemaLoader;
 import org.apache.cassandra.Util;
+import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.dht.RandomPartitioner;
 import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.exceptions.ConfigurationException;
+import org.apache.cassandra.gms.ApplicationState;
 import org.apache.cassandra.gms.Gossiper;
+import org.apache.cassandra.gms.VersionedValue.VersionedValueFactory;
 import org.apache.cassandra.locator.TokenMetadata;
 import org.apache.cassandra.net.MessageOut;
 import org.apache.cassandra.net.MessagingService;
@@ -108,6 +112,25 @@ public class RemoveTest
         ss.removeNode(hostIds.get(0).toString());
     }
 
+    @Test(expected = UnsupportedOperationException.class)
+    public void testNonmemberId()
+    {
+        VersionedValueFactory valueFactory = new VersionedValueFactory(DatabaseDescriptor.getPartitioner());
+        Collection<Token> tokens = Collections.singleton(DatabaseDescriptor.getPartitioner().getRandomToken());
+
+        InetAddress joininghost = hosts.get(4);
+        UUID joiningId = hostIds.get(4);
+
+        hosts.remove(joininghost);
+        hostIds.remove(joiningId);
+
+        // Change a node to a bootstrapping node that is not yet a member of the ring
+        Gossiper.instance.injectApplicationState(joininghost, ApplicationState.TOKENS, valueFactory.tokens(tokens));
+        ss.onChange(joininghost, ApplicationState.STATUS, valueFactory.bootstrapping(tokens));
+
+        ss.removeNode(joiningId.toString());
+    }
+
     @Test
     public void testRemoveHostId() throws InterruptedException
     {


Mime
View raw message