Search in sources :

Example 26 with IInvokableInstance

use of org.apache.cassandra.distributed.api.IInvokableInstance in project cassandra by apache.

the class BaseAssassinatedCase method test.

@Test
public void test() throws IOException {
    TokenSupplier even = TokenSupplier.evenlyDistributedTokens(3);
    try (Cluster cluster = Cluster.build(3).withConfig(c -> c.with(Feature.GOSSIP, Feature.NETWORK)).withTokenSupplier(node -> even.token(node == 4 || node == 5 ? NODE_TO_REMOVE_NUM : node)).start()) {
        IInvokableInstance seed = cluster.get(SEED_NUM);
        IInvokableInstance nodeToRemove = cluster.get(NODE_TO_REMOVE_NUM);
        IInvokableInstance peer = cluster.get(PEER_NUM);
        setupCluster(cluster);
        consume(cluster, nodeToRemove);
        assertRingState(seed, nodeToRemove, "Normal");
        // assassinate the node
        peer.nodetoolResult("assassinate", getBroadcastAddressHostWithPortString(nodeToRemove)).asserts().success();
        // wait until the peer sees this assassination
        awaitGossipStatus(seed, nodeToRemove, "LEFT");
        // Any extra checks to run after the node has been as LEFT
        afterNodeStatusIsLeft(cluster, nodeToRemove);
        // allow replacing nodes with the LEFT state, this should fail since the token isn't in the ring
        assertThatThrownBy(() -> replaceHostAndStart(cluster, nodeToRemove, properties -> {
            // since there are downed nodes its possible gossip has the downed node with an old schema, so need
            // this property to allow startup
            properties.set(BOOTSTRAP_SKIP_SCHEMA_CHECK, true);
            // since the bootstrap should fail because the token, don't wait "too long" on schema as it doesn't
            // matter for this test
            properties.set(BOOTSTRAP_SCHEMA_DELAY_MS, 10);
        })).hasMessage(expectedMessage(nodeToRemove));
    }
}
Also used : ClusterUtils.awaitGossipStatus(org.apache.cassandra.distributed.shared.ClusterUtils.awaitGossipStatus) ClusterUtils.getTokens(org.apache.cassandra.distributed.shared.ClusterUtils.getTokens) Feature(org.apache.cassandra.distributed.api.Feature) HostReplacementTest.setupCluster(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.setupCluster) IOException(java.io.IOException) Test(org.junit.Test) BOOTSTRAP_SKIP_SCHEMA_CHECK(org.apache.cassandra.config.CassandraRelevantProperties.BOOTSTRAP_SKIP_SCHEMA_CHECK) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) ClusterUtils.replaceHostAndStart(org.apache.cassandra.distributed.shared.ClusterUtils.replaceHostAndStart) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) ClusterUtils.getBroadcastAddressHostWithPortString(org.apache.cassandra.distributed.shared.ClusterUtils.getBroadcastAddressHostWithPortString) TestBaseImpl(org.apache.cassandra.distributed.test.TestBaseImpl) Cluster(org.apache.cassandra.distributed.Cluster) ClusterUtils.assertRingState(org.apache.cassandra.distributed.shared.ClusterUtils.assertRingState) BOOTSTRAP_SCHEMA_DELAY_MS(org.apache.cassandra.config.CassandraRelevantProperties.BOOTSTRAP_SCHEMA_DELAY_MS) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) HostReplacementTest.setupCluster(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.setupCluster) Cluster(org.apache.cassandra.distributed.Cluster) Test(org.junit.Test)

Example 27 with IInvokableInstance

use of org.apache.cassandra.distributed.api.IInvokableInstance in project cassandra by apache.

the class HostReplacementOfDownedClusterTest method hostReplacementOfDeadNodeAndOtherNodeStartsAfter.

/**
 * Cluster stops completely, then start seed, then host replace node2; after all complete start node3 to make sure
 * it comes up correctly with the new host in the ring.
 */
@Test
public void hostReplacementOfDeadNodeAndOtherNodeStartsAfter() throws IOException {
    // start with 3 nodes, stop both nodes, start the seed, host replace the down node)
    int numStartNodes = 3;
    TokenSupplier even = TokenSupplier.evenlyDistributedTokens(numStartNodes);
    try (Cluster cluster = Cluster.build(numStartNodes).withConfig(c -> c.with(Feature.GOSSIP, Feature.NETWORK)).withTokenSupplier(node -> even.token(node == (numStartNodes + 1) ? 2 : node)).start()) {
        IInvokableInstance seed = cluster.get(1);
        IInvokableInstance nodeToRemove = cluster.get(2);
        IInvokableInstance nodeToStartAfterReplace = cluster.get(3);
        InetSocketAddress addressToReplace = nodeToRemove.broadcastAddress();
        setupCluster(cluster);
        // collect rows/tokens to detect issues later on if the state doesn't match
        SimpleQueryResult expectedState = nodeToRemove.coordinator().executeWithResult("SELECT * FROM " + KEYSPACE + ".tbl", ConsistencyLevel.ALL);
        List<String> beforeCrashTokens = getTokenMetadataTokens(seed);
        // now stop all nodes
        stopAll(cluster);
        // with all nodes down, now start the seed (should be first node)
        seed.startup();
        // at this point node2 should be known in gossip, but with generation/version of 0
        assertGossipInfo(seed, addressToReplace, 0, -1);
        // make sure node1 still has node2's tokens
        List<String> currentTokens = getTokenMetadataTokens(seed);
        Assertions.assertThat(currentTokens).as("Tokens no longer match after restarting").isEqualTo(beforeCrashTokens);
        // now create a new node to replace the other node
        IInvokableInstance replacingNode = replaceHostAndStart(cluster, nodeToRemove);
        // wait till the replacing node is in the ring
        awaitRingJoin(seed, replacingNode);
        awaitRingJoin(replacingNode, seed);
        // we see that the replaced node is properly in the ring, now lets add the other node back
        nodeToStartAfterReplace.startup();
        awaitRingJoin(seed, nodeToStartAfterReplace);
        awaitRingJoin(replacingNode, nodeToStartAfterReplace);
        // make sure all nodes are healthy
        awaitRingHealthy(seed);
        assertRingIs(seed, seed, replacingNode, nodeToStartAfterReplace);
        assertRingIs(replacingNode, seed, replacingNode, nodeToStartAfterReplace);
        logger.info("Current ring is {}", assertRingIs(nodeToStartAfterReplace, seed, replacingNode, nodeToStartAfterReplace));
        validateRows(seed.coordinator(), expectedState);
        validateRows(replacingNode.coordinator(), expectedState);
    }
}
Also used : HostReplacementTest.setupCluster(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.setupCluster) ClusterUtils.getTokenMetadataTokens(org.apache.cassandra.distributed.shared.ClusterUtils.getTokenMetadataTokens) LoggerFactory(org.slf4j.LoggerFactory) ClusterUtils.stopAll(org.apache.cassandra.distributed.shared.ClusterUtils.stopAll) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) ClusterUtils.replaceHostAndStart(org.apache.cassandra.distributed.shared.ClusterUtils.replaceHostAndStart) TestBaseImpl(org.apache.cassandra.distributed.test.TestBaseImpl) SimpleQueryResult(org.apache.cassandra.distributed.api.SimpleQueryResult) Assertions(org.assertj.core.api.Assertions) Feature(org.apache.cassandra.distributed.api.Feature) Logger(org.slf4j.Logger) GOSSIPER_QUARANTINE_DELAY(org.apache.cassandra.config.CassandraRelevantProperties.GOSSIPER_QUARANTINE_DELAY) ClusterUtils.awaitRingJoin(org.apache.cassandra.distributed.shared.ClusterUtils.awaitRingJoin) HostReplacementTest.validateRows(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.validateRows) IOException(java.io.IOException) Test(org.junit.Test) ConsistencyLevel(org.apache.cassandra.distributed.api.ConsistencyLevel) InetSocketAddress(java.net.InetSocketAddress) List(java.util.List) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) ClusterUtils.assertNotInRing(org.apache.cassandra.distributed.shared.ClusterUtils.assertNotInRing) Cluster(org.apache.cassandra.distributed.Cluster) ClusterUtils.assertGossipInfo(org.apache.cassandra.distributed.shared.ClusterUtils.assertGossipInfo) ClusterUtils.assertRingIs(org.apache.cassandra.distributed.shared.ClusterUtils.assertRingIs) ClusterUtils.awaitRingHealthy(org.apache.cassandra.distributed.shared.ClusterUtils.awaitRingHealthy) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) SimpleQueryResult(org.apache.cassandra.distributed.api.SimpleQueryResult) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) InetSocketAddress(java.net.InetSocketAddress) HostReplacementTest.setupCluster(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.setupCluster) Cluster(org.apache.cassandra.distributed.Cluster) Test(org.junit.Test)

Example 28 with IInvokableInstance

use of org.apache.cassandra.distributed.api.IInvokableInstance in project cassandra by apache.

the class HostReplacementOfDownedClusterTest method hostReplacementOfDeadNode.

/**
 * When the full cluster crashes, make sure that we can replace a dead node after recovery.  This can happen
 * with DC outages (assuming single DC setup) where the recovery isn't able to recover a specific node.
 */
@Test
public void hostReplacementOfDeadNode() throws IOException {
    // start with 2 nodes, stop both nodes, start the seed, host replace the down node)
    TokenSupplier even = TokenSupplier.evenlyDistributedTokens(2);
    try (Cluster cluster = Cluster.build(2).withConfig(c -> c.with(Feature.GOSSIP, Feature.NETWORK)).withTokenSupplier(node -> even.token(node == 3 ? 2 : node)).start()) {
        IInvokableInstance seed = cluster.get(1);
        IInvokableInstance nodeToRemove = cluster.get(2);
        InetSocketAddress addressToReplace = nodeToRemove.broadcastAddress();
        setupCluster(cluster);
        // collect rows/tokens to detect issues later on if the state doesn't match
        SimpleQueryResult expectedState = nodeToRemove.coordinator().executeWithResult("SELECT * FROM " + KEYSPACE + ".tbl", ConsistencyLevel.ALL);
        List<String> beforeCrashTokens = getTokenMetadataTokens(seed);
        // now stop all nodes
        stopAll(cluster);
        // with all nodes down, now start the seed (should be first node)
        seed.startup();
        // at this point node2 should be known in gossip, but with generation/version of 0
        assertGossipInfo(seed, addressToReplace, 0, -1);
        // make sure node1 still has node2's tokens
        List<String> currentTokens = getTokenMetadataTokens(seed);
        Assertions.assertThat(currentTokens).as("Tokens no longer match after restarting").isEqualTo(beforeCrashTokens);
        // now create a new node to replace the other node
        IInvokableInstance replacingNode = replaceHostAndStart(cluster, nodeToRemove);
        awaitRingJoin(seed, replacingNode);
        awaitRingJoin(replacingNode, seed);
        assertNotInRing(seed, nodeToRemove);
        logger.info("Current ring is {}", assertNotInRing(replacingNode, nodeToRemove));
        validateRows(seed.coordinator(), expectedState);
        validateRows(replacingNode.coordinator(), expectedState);
    }
}
Also used : HostReplacementTest.setupCluster(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.setupCluster) ClusterUtils.getTokenMetadataTokens(org.apache.cassandra.distributed.shared.ClusterUtils.getTokenMetadataTokens) LoggerFactory(org.slf4j.LoggerFactory) ClusterUtils.stopAll(org.apache.cassandra.distributed.shared.ClusterUtils.stopAll) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) ClusterUtils.replaceHostAndStart(org.apache.cassandra.distributed.shared.ClusterUtils.replaceHostAndStart) TestBaseImpl(org.apache.cassandra.distributed.test.TestBaseImpl) SimpleQueryResult(org.apache.cassandra.distributed.api.SimpleQueryResult) Assertions(org.assertj.core.api.Assertions) Feature(org.apache.cassandra.distributed.api.Feature) Logger(org.slf4j.Logger) GOSSIPER_QUARANTINE_DELAY(org.apache.cassandra.config.CassandraRelevantProperties.GOSSIPER_QUARANTINE_DELAY) ClusterUtils.awaitRingJoin(org.apache.cassandra.distributed.shared.ClusterUtils.awaitRingJoin) HostReplacementTest.validateRows(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.validateRows) IOException(java.io.IOException) Test(org.junit.Test) ConsistencyLevel(org.apache.cassandra.distributed.api.ConsistencyLevel) InetSocketAddress(java.net.InetSocketAddress) List(java.util.List) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) ClusterUtils.assertNotInRing(org.apache.cassandra.distributed.shared.ClusterUtils.assertNotInRing) Cluster(org.apache.cassandra.distributed.Cluster) ClusterUtils.assertGossipInfo(org.apache.cassandra.distributed.shared.ClusterUtils.assertGossipInfo) ClusterUtils.assertRingIs(org.apache.cassandra.distributed.shared.ClusterUtils.assertRingIs) ClusterUtils.awaitRingHealthy(org.apache.cassandra.distributed.shared.ClusterUtils.awaitRingHealthy) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) SimpleQueryResult(org.apache.cassandra.distributed.api.SimpleQueryResult) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) InetSocketAddress(java.net.InetSocketAddress) HostReplacementTest.setupCluster(org.apache.cassandra.distributed.test.hostreplacement.HostReplacementTest.setupCluster) Cluster(org.apache.cassandra.distributed.Cluster) Test(org.junit.Test)

Example 29 with IInvokableInstance

use of org.apache.cassandra.distributed.api.IInvokableInstance in project cassandra by apache.

the class NodeCannotJoinAsHibernatingNodeWithoutReplaceAddressTest method test.

@Test
public void test() throws IOException, InterruptedException {
    TokenSupplier even = TokenSupplier.evenlyDistributedTokens(2);
    try (Cluster cluster = init(Cluster.build(2).withConfig(c -> c.with(Feature.values()).set(Constants.KEY_DTEST_API_STARTUP_FAILURE_AS_SHUTDOWN, false)).withInstanceInitializer(BBHelper::install).withTokenSupplier(node -> even.token((node == 3 || node == 4) ? 2 : node)).start())) {
        final IInvokableInstance toReplace = cluster.get(2);
        final String toReplaceAddress = toReplace.broadcastAddress().getAddress().getHostAddress();
        SharedState.cluster = cluster;
        // ignore host replacement errors
        cluster.setUncaughtExceptionsFilter((nodeId, cause) -> nodeId > 2);
        fixDistributedSchemas(cluster);
        ClusterUtils.stopUnchecked(toReplace);
        try {
            ClusterUtils.replaceHostAndStart(cluster, toReplace, (inst, ignore) -> ClusterUtils.updateAddress(inst, toReplaceAddress));
            Assert.fail("Host replacement should exit with an error");
        } catch (Exception e) {
            // the instance is expected to fail, but it may not have finished shutdown yet, so wait for it to shutdown
            SharedState.shutdownComplete.await(1, TimeUnit.MINUTES);
        }
        IInvokableInstance inst = ClusterUtils.addInstance(cluster, toReplace.config(), c -> c.set("auto_bootstrap", true));
        ClusterUtils.updateAddress(inst, toReplaceAddress);
        Assertions.assertThatThrownBy(() -> inst.startup()).hasMessageContaining("A node with address").hasMessageContaining("already exists, cancelling join");
    }
}
Also used : IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) TokenSupplier(org.apache.cassandra.distributed.api.TokenSupplier) ICluster(org.apache.cassandra.distributed.api.ICluster) Cluster(org.apache.cassandra.distributed.Cluster) IOException(java.io.IOException) Test(org.junit.Test)

Example 30 with IInvokableInstance

use of org.apache.cassandra.distributed.api.IInvokableInstance in project cassandra by apache.

the class ReprepareNewBehaviourTest method testUseWithMultipleKeyspaces.

@Test
public void testUseWithMultipleKeyspaces() throws Throwable {
    try (ICluster<IInvokableInstance> c = init(builder().withNodes(1).withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL)).start())) {
        try (com.datastax.driver.core.Cluster cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").build();
            Session session = cluster.connect()) {
            c.schemaChange(withKeyspace("CREATE KEYSPACE ks1 WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};"));
            c.schemaChange(withKeyspace("CREATE TABLE ks1.tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck));"));
            c.schemaChange(withKeyspace("CREATE KEYSPACE ks2 WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};"));
            c.schemaChange(withKeyspace("CREATE TABLE ks2.tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck));"));
            String query = "SELECT * FROM tbl";
            session.execute("USE ks1");
            PreparedStatement selectKs1 = session.prepare(query);
            // Insert explicitly into the ks2 version of table...
            session.execute("INSERT INTO ks2.tbl (pk, ck, v) VALUES (1, 1, 1)");
            // There should be nothing in the ks1 version...
            ResultSet resultsKs1 = session.execute(selectKs1.bind());
            Assert.assertEquals(0, resultsKs1.all().size());
            session.execute("USE ks2");
            // ... but after switching to use ks2, a new query prepared against tbl should return a result.
            PreparedStatement selectKs2 = session.prepare(query);
            Assert.assertEquals("ks2", selectKs2.getQueryKeyspace());
            ResultSet resultsKs2 = session.execute(selectKs2.bind());
            Assert.assertEquals(1, resultsKs2.all().size());
            resultsKs1 = session.execute(selectKs1.bind());
            Assert.assertEquals(0, resultsKs1.all().size());
        }
    }
}
Also used : IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) ResultSet(com.datastax.driver.core.ResultSet) PreparedStatement(com.datastax.driver.core.PreparedStatement) Session(com.datastax.driver.core.Session) Test(org.junit.Test)

Aggregations

IInvokableInstance (org.apache.cassandra.distributed.api.IInvokableInstance)55 Test (org.junit.Test)36 Cluster (org.apache.cassandra.distributed.Cluster)31 List (java.util.List)16 IOException (java.io.IOException)15 ConsistencyLevel (org.apache.cassandra.distributed.api.ConsistencyLevel)14 Feature (org.apache.cassandra.distributed.api.Feature)13 GOSSIP (org.apache.cassandra.distributed.api.Feature.GOSSIP)13 NETWORK (org.apache.cassandra.distributed.api.Feature.NETWORK)13 ICluster (org.apache.cassandra.distributed.api.ICluster)13 TestBaseImpl (org.apache.cassandra.distributed.test.TestBaseImpl)13 TokenSupplier (org.apache.cassandra.distributed.api.TokenSupplier)12 Session (com.datastax.driver.core.Session)11 Arrays (java.util.Arrays)11 Assertions (org.assertj.core.api.Assertions)10 Set (java.util.Set)9 NATIVE_PROTOCOL (org.apache.cassandra.distributed.api.Feature.NATIVE_PROTOCOL)9 Assert (org.junit.Assert)9 PreparedStatement (com.datastax.driver.core.PreparedStatement)8 Map (java.util.Map)8