use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class BootstrapTest method readWriteDuringBootstrapTest.
@Test
public void readWriteDuringBootstrapTest() throws Throwable {
int originalNodeCount = 2;
int expandedNodeCount = originalNodeCount + 1;
try (Cluster cluster = builder().withNodes(originalNodeCount).withTokenSupplier(TokenSupplier.evenlyDistributedTokens(expandedNodeCount)).withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(expandedNodeCount, "dc0", "rack0")).withConfig(config -> config.with(NETWORK, GOSSIP)).start()) {
IInstanceConfig config = cluster.newInstanceConfig();
IInvokableInstance newInstance = cluster.bootstrap(config);
withProperty("cassandra.join_ring", false, () -> newInstance.startup(cluster));
cluster.forEach(statusToBootstrap(newInstance));
populate(cluster, 0, 100);
Assert.assertEquals(100, newInstance.executeInternal("SELECT *FROM " + KEYSPACE + ".tbl").length);
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class BootstrapTest method bootstrapTest.
@Test
public void bootstrapTest() throws Throwable {
int originalNodeCount = 2;
int expandedNodeCount = originalNodeCount + 1;
try (Cluster cluster = builder().withNodes(originalNodeCount).withTokenSupplier(TokenSupplier.evenlyDistributedTokens(expandedNodeCount)).withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(expandedNodeCount, "dc0", "rack0")).withConfig(config -> config.with(NETWORK, GOSSIP)).start()) {
populate(cluster, 0, 100);
IInstanceConfig config = cluster.newInstanceConfig();
IInvokableInstance newInstance = cluster.bootstrap(config);
withProperty("cassandra.join_ring", false, () -> newInstance.startup(cluster));
cluster.forEach(statusToBootstrap(newInstance));
cluster.run(asList(pullSchemaFrom(cluster.get(1)), bootstrap()), newInstance.config().num());
for (Map.Entry<Integer, Long> e : count(cluster).entrySet()) Assert.assertEquals("Node " + e.getKey() + " has incorrect row state", 100L, e.getValue().longValue());
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class ReadsDuringBootstrapTest method readsDuringBootstrapTest.
@Test
public void readsDuringBootstrapTest() throws IOException, ExecutionException, InterruptedException, TimeoutException {
int originalNodeCount = 3;
int expandedNodeCount = originalNodeCount + 1;
ExecutorService es = Executors.newSingleThreadExecutor();
try (Cluster cluster = builder().withNodes(originalNodeCount).withTokenSupplier(TokenSupplier.evenlyDistributedTokens(expandedNodeCount)).withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(expandedNodeCount, "dc0", "rack0")).withConfig(config -> config.with(NETWORK, GOSSIP).set("read_request_timeout", String.format("%dms", Integer.MAX_VALUE)).set("request_timeout", String.format("%dms", Integer.MAX_VALUE))).withInstanceInitializer(BB::install).start()) {
String query = withKeyspace("SELECT * FROM %s.tbl WHERE id = ?");
cluster.schemaChange(withKeyspace("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 2};"));
cluster.schemaChange(withKeyspace("CREATE TABLE %s.tbl (id int PRIMARY KEY)"));
cluster.get(1).runOnInstance(() -> BB.block.set(true));
Future<?> read = es.submit(() -> cluster.coordinator(1).execute(query, ConsistencyLevel.QUORUM, 3));
long mark = cluster.get(1).logs().mark();
bootstrapAndJoinNode(cluster);
cluster.get(1).logs().watchFor(mark, "New node /127.0.0.4");
cluster.get(1).runOnInstance(() -> BB.block.set(false));
// populate cache
for (int i = 0; i < 10; i++) cluster.coordinator(1).execute(query, ConsistencyLevel.QUORUM, i);
cluster.get(1).runOnInstance(() -> BB.latch.countDown());
read.get();
} finally {
es.shutdown();
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class HostReplacementAbruptDownedInstanceTest method hostReplaceAbruptShutdown.
/**
* Can we maybe also test with an abrupt shutdown, that is when the shutdown state is not broadcast and the node to be replaced is on NORMAL state?
*/
@Test
public void hostReplaceAbruptShutdown() throws IOException {
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 peer = cluster.get(3);
List<IInvokableInstance> peers = Arrays.asList(seed, peer);
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);
stopAbrupt(cluster, nodeToRemove);
// at this point node 2 should still be NORMAL on all other nodes
peers.forEach(p -> assertRingState(p, nodeToRemove, "Normal"));
// node is down, but queries should still work
// TODO failing, but shouldn't!
// peers.forEach(p -> validateRows(p.coordinator(), expectedState));
// now create a new node to replace the other node
long startNanos = nanoTime();
IInvokableInstance replacingNode = replaceHostAndStart(cluster, nodeToRemove, properties -> {
// since node2 was killed abruptly its possible that node2's gossip state has an old schema version
// if this happens then bootstrap will fail waiting for a schema version it will never see; to avoid
// this, setting this property to log the warning rather than fail bootstrap
properties.set(BOOTSTRAP_SKIP_SCHEMA_CHECK, true);
});
logger.info("Host replacement of {} with {} took {}", nodeToRemove, replacingNode, Duration.ofNanos(nanoTime() - startNanos));
peers.forEach(p -> awaitRingJoin(p, replacingNode));
// make sure all nodes are healthy
awaitRingHealthy(seed);
List<IInvokableInstance> expectedRing = Arrays.asList(seed, peer, replacingNode);
expectedRing.forEach(p -> assertRingIs(p, expectedRing));
expectedRing.forEach(p -> validateRows(p.coordinator(), expectedState));
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class UnableToParseClientMessageFromBlockedSubnetTest method badMessageCausesProtocolExceptionFromExcludeList.
@Test
public void badMessageCausesProtocolExceptionFromExcludeList() throws IOException, TimeoutException {
Cluster cluster = getCluster();
// write gibberish to the native protocol
IInvokableInstance node = cluster.get(1);
// make sure everything is fine at the start
Assertions.assertThat(node.metrics().getCounter("org.apache.cassandra.metrics.Client.ProtocolException")).isEqualTo(0);
Assertions.assertThat(node.metrics().getCounter("org.apache.cassandra.metrics.Client.UnknownException")).isEqualTo(0);
LogAction logs = node.logs();
long mark = logs.mark();
try (SimpleClient client = SimpleClient.builder("127.0.0.1", 9042).protocolVersion(version).useBeta().build()) {
client.connect(false, true);
// this should return a failed response
// disable waiting on procol errors as that logic was reverted until we can figure out its 100% safe
// right now ProtocolException is thrown for fatal and non-fatal issues, so closing the channel
// on non-fatal issues could cause other issues for the cluster
byte expectedVersion = (byte) (80 + version.asInt());
Message.Response response = client.execute(new UnableToParseClientMessageTest.CustomHeaderMessage(new byte[] { expectedVersion, 1, 2, 3, 4, 5, 6, 7, 8, 9 }), false);
Assertions.assertThat(response).isInstanceOf(ErrorMessage.class);
logs.watchFor(mark, "address contained in client_error_reporting_exclusions");
Assertions.assertThat(node.metrics().getCounter("org.apache.cassandra.metrics.Client.ProtocolException")).isEqualTo(0);
Assertions.assertThat(node.metrics().getCounter("org.apache.cassandra.metrics.Client.UnknownException")).isEqualTo(0);
Assertions.assertThat(logs.grep(mark, "Excluding client exception fo").getResult()).hasSize(1);
Assertions.assertThat(logs.grep(mark, "Unexpected exception during request").getResult()).isEmpty();
}
}
Aggregations