/** * 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.cassandra.service; import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.*; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.Util; 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.Gossiper; import org.apache.cassandra.locator.TokenMetadata; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.sink.SinkManager; import org.apache.cassandra.utils.FBUtilities; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class RemoveTest { static final IPartitioner partitioner = new RandomPartitioner(); StorageService ss = StorageService.instance; TokenMetadata tmd = ss.getTokenMetadata(); static IPartitioner oldPartitioner; ArrayList<Token> endpointTokens = new ArrayList<Token>(); ArrayList<Token> keyTokens = new ArrayList<Token>(); List<InetAddress> hosts = new ArrayList<InetAddress>(); List<UUID> hostIds = new ArrayList<UUID>(); InetAddress removalhost; UUID removalId; @BeforeClass public static void setupClass() throws IOException, ConfigurationException { oldPartitioner = StorageService.instance.setPartitionerUnsafe(partitioner); SchemaLoader.loadSchema(); } @AfterClass public static void tearDownClass() { StorageService.instance.setPartitionerUnsafe(oldPartitioner); SchemaLoader.stopGossiper(); } @Before public void setup() throws IOException, ConfigurationException { tmd.clearUnsafe(); // create a ring of 5 nodes Util.createInitialRing(ss, partitioner, endpointTokens, keyTokens, hosts, hostIds, 6); MessagingService.instance().listen(FBUtilities.getBroadcastAddress()); Gossiper.instance.start(1); removalhost = hosts.get(5); hosts.remove(removalhost); removalId = hostIds.get(5); hostIds.remove(removalId); } @After public void tearDown() { SinkManager.clear(); MessagingService.instance().clearCallbacksUnsafe(); MessagingService.instance().shutdown(); } @Test(expected = UnsupportedOperationException.class) public void testBadHostId() { ss.removeNode("ffffffff-aaaa-aaaa-aaaa-ffffffffffff"); } @Test(expected = UnsupportedOperationException.class) public void testLocalHostId() { //first ID should be localhost ss.removeNode(hostIds.get(0).toString()); } @Test public void testRemoveHostId() throws InterruptedException { // start removal in background and send replication confirmations final AtomicBoolean success = new AtomicBoolean(false); Thread remover = new Thread() { public void run() { try { ss.removeNode(removalId.toString()); } catch (Exception e) { System.err.println(e); e.printStackTrace(); return; } success.set(true); } }; remover.start(); Thread.sleep(1000); // make sure removal is waiting for confirmation assertTrue(tmd.isLeaving(removalhost)); assertEquals(1, tmd.getLeavingEndpoints().size()); for (InetAddress host : hosts) { MessageOut msg = new MessageOut(host, MessagingService.Verb.REPLICATION_FINISHED, null, null, Collections.<String, byte[]>emptyMap()); MessagingService.instance().sendRR(msg, FBUtilities.getBroadcastAddress()); } remover.join(); assertTrue(success.get()); assertTrue(tmd.getLeavingEndpoints().isEmpty()); } }