use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class GossipTest method nodeDownDuringMove.
@Test
public void nodeDownDuringMove() throws Throwable {
int liveCount = 1;
try (Cluster cluster = Cluster.build(2 + liveCount).withConfig(config -> config.with(NETWORK).with(GOSSIP)).createWithoutStarting()) {
int fail = liveCount + 1;
int late = fail + 1;
for (int i = 1; i <= liveCount; ++i) cluster.get(i).startup();
cluster.get(fail).startup();
Collection<String> expectTokens = cluster.get(fail).callsOnInstance(() -> StorageService.instance.getTokenMetadata().getTokens(FBUtilities.getBroadcastAddressAndPort()).stream().map(Object::toString).collect(Collectors.toList())).call();
InetSocketAddress failAddress = cluster.get(fail).broadcastAddress();
// wait for NORMAL state
for (int i = 1; i <= liveCount; ++i) {
cluster.get(i).acceptsOnInstance((InetSocketAddress address) -> {
EndpointState ep;
InetAddressAndPort endpoint = toCassandraInetAddressAndPort(address);
while (null == (ep = Gossiper.instance.getEndpointStateForEndpoint(endpoint)) || ep.getApplicationState(ApplicationState.STATUS_WITH_PORT) == null || !ep.getApplicationState(ApplicationState.STATUS_WITH_PORT).value.startsWith("NORMAL")) LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10L));
}).accept(failAddress);
}
// set ourselves to MOVING, and wait for it to propagate
cluster.get(fail).runOnInstance(() -> {
Token token = Iterables.getFirst(StorageService.instance.getTokenMetadata().getTokens(FBUtilities.getBroadcastAddressAndPort()), null);
Gossiper.instance.addLocalApplicationState(ApplicationState.STATUS_WITH_PORT, StorageService.instance.valueFactory.moving(token));
});
for (int i = 1; i <= liveCount; ++i) {
cluster.get(i).acceptsOnInstance((InetSocketAddress address) -> {
EndpointState ep;
InetAddressAndPort endpoint = toCassandraInetAddressAndPort(address);
while (null == (ep = Gossiper.instance.getEndpointStateForEndpoint(endpoint)) || (ep.getApplicationState(ApplicationState.STATUS_WITH_PORT) == null || !ep.getApplicationState(ApplicationState.STATUS_WITH_PORT).value.startsWith("MOVING"))) LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(100L));
}).accept(failAddress);
}
cluster.get(fail).shutdown(false).get();
cluster.get(late).startup();
cluster.get(late).acceptsOnInstance((InetSocketAddress address) -> {
EndpointState ep;
InetAddressAndPort endpoint = toCassandraInetAddressAndPort(address);
while (null == (ep = Gossiper.instance.getEndpointStateForEndpoint(endpoint)) || !ep.getApplicationState(ApplicationState.STATUS_WITH_PORT).value.startsWith("MOVING")) LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(100L));
}).accept(failAddress);
Collection<String> tokens = cluster.get(late).appliesOnInstance((InetSocketAddress address) -> StorageService.instance.getTokenMetadata().getTokens(toCassandraInetAddressAndPort(address)).stream().map(Object::toString).collect(Collectors.toList())).apply(failAddress);
Assert.assertEquals(expectTokens, tokens);
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class HintedHandoffAddRemoveNodesTest method shouldBootstrapWithHintsOutstanding.
@Ignore
@Test
public void shouldBootstrapWithHintsOutstanding() throws Exception {
try (Cluster cluster = builder().withNodes(3).withTokenSupplier(TokenSupplier.evenlyDistributedTokens(4)).withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(4, "dc0", "rack0")).withConfig(config -> config.with(NETWORK, GOSSIP, NATIVE_PROTOCOL)).start()) {
cluster.schemaChange(withKeyspace("CREATE KEYSPACE %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 2}"));
cluster.schemaChange(withKeyspace("CREATE TABLE %s.boot_hint_test (key int PRIMARY KEY, value int)"));
cluster.get(3).shutdown().get();
// Write data using the second node as the coordinator...
populate(cluster, "boot_hint_test", 2, 0, 128, ConsistencyLevel.ONE);
Long totalHints = countTotalHints(cluster);
// ...and verify that we've accumulated hints intended for node 3, which is down.
assertThat(totalHints).isGreaterThan(0);
// Bootstrap a new/4th node into the cluster...
bootstrapAndJoinNode(cluster);
// ...and verify that all data is available.
verify(cluster, "boot_hint_test", 4, 0, 128, ConsistencyLevel.ONE);
// Finally, bring node 3 back up and verify that all hints were delivered.
cluster.get(3).startup();
await().atMost(30, SECONDS).pollDelay(3, SECONDS).until(() -> count(cluster, "boot_hint_test", 3).equals(totalHints));
verify(cluster, "boot_hint_test", 3, 0, 128, ConsistencyLevel.ONE);
verify(cluster, "boot_hint_test", 3, 0, 128, ConsistencyLevel.TWO);
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class HintedHandoffAddRemoveNodesTest method shouldStreamHintsDuringDecommission.
/**
* Replaces Python dtest {@code hintedhandoff_test.py:TestHintedHandoff.test_hintedhandoff_decom()}.
* Ignored for now as there is some in-jvm bug which needs to be fixed, otherwise the test is flaky
* For more information see CASSANDRA-16679
*/
@Ignore
@Test
public void shouldStreamHintsDuringDecommission() throws Exception {
try (Cluster cluster = builder().withNodes(4).withConfig(config -> config.with(NETWORK, GOSSIP, NATIVE_PROTOCOL)).start()) {
cluster.schemaChange(withKeyspace("CREATE KEYSPACE %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 2}"));
cluster.schemaChange(withKeyspace("CREATE TABLE %s.decom_hint_test (key int PRIMARY KEY, value int)"));
cluster.get(4).shutdown().get();
// Write data using the second node as the coordinator...
populate(cluster, "decom_hint_test", 2, 0, 128, ConsistencyLevel.ONE);
Long totalHints = countTotalHints(cluster);
// ...and verify that we've accumulated hints intended for node 4, which is down.
assertThat(totalHints).isGreaterThan(0);
// Decomision node 1...
assertEquals(4, endpointsKnownTo(cluster, 2));
cluster.run(decommission(), 1);
await().pollDelay(1, SECONDS).until(() -> endpointsKnownTo(cluster, 2) == 3);
// ...and verify that all data still exists on either node 2 or 3.
verify(cluster, "decom_hint_test", 2, 0, 128, ConsistencyLevel.ONE);
// Start node 4 back up and verify that all hints were delivered.
cluster.get(4).startup();
await().atMost(30, SECONDS).pollDelay(3, SECONDS).until(() -> count(cluster, "decom_hint_test", 4).equals(totalHints));
// Now decommission both nodes 2 and 3...
cluster.run(GossipHelper.decommission(true), 2);
cluster.run(GossipHelper.decommission(true), 3);
await().pollDelay(1, SECONDS).until(() -> endpointsKnownTo(cluster, 4) == 1);
// ...and verify that even if we drop below the replication factor of 2, all data has been preserved.
verify(cluster, "decom_hint_test", 4, 0, 128, ConsistencyLevel.ONE);
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class IPMembershipTest method startupNewIP.
/**
* Tests the behavior if a node restarts with a different IP.
*/
@Test
public void startupNewIP() throws IOException, InterruptedException {
try (Cluster cluster = Cluster.build(3).withConfig(c -> c.with(Feature.GOSSIP, Feature.NATIVE_PROTOCOL).set("endpoint_snitch", "org.apache.cassandra.locator.SimpleSnitch")).start()) {
IInvokableInstance nodeToReplace = cluster.get(3);
ToolRunner.invokeCassandraStress("write", "n=10000", "-schema", "replication(factor=3)", "-port", "native=9042").assertOnExitCode();
stopUnchecked(nodeToReplace);
// change the IP of the node
updateAddress(nodeToReplace, "127.0.0.4");
nodeToReplace.startup();
// gossip takes some time, wait for the other nodes to see this one updated
ClusterUtils.awaitRingJoin(cluster.get(1), "127.0.0.4");
ClusterUtils.awaitRingJoin(cluster.get(2), "127.0.0.4");
Set<String> expected = ImmutableSet.of("127.0.0.1", "127.0.0.2", "127.0.0.4");
cluster.forEach(i -> assertRingIs(i, expected));
ToolRunner.invokeCassandraStress("read", "n=10000", "no-warmup", "-port", "native=9042").assertOnExitCode();
}
}
use of org.apache.cassandra.distributed.Cluster in project cassandra by apache.
the class AbstractNetstatsBootstrapStreaming method executeTest.
protected void executeTest(final boolean streamEntireSSTables, final boolean compressionEnabled, final int throughput) throws Exception {
final Cluster.Builder builder = builder().withNodes(1).withTokenSupplier(TokenSupplier.evenlyDistributedTokens(2)).withNodeIdTopology(NetworkTopology.singleDcNetworkTopology(2, "dc0", "rack0")).withConfig(config -> config.with(NETWORK, GOSSIP, NATIVE_PROTOCOL).set(streamEntireSSTables ? "entire_sstable_stream_throughput_outbound" : "stream_throughput_outbound", throughput + "MiB/s").set("compaction_throughput", "1MiB/s").set("stream_entire_sstables", streamEntireSSTables));
try (final Cluster cluster = builder.withNodes(1).start()) {
// populate data only against 1 node first
createTable(cluster, 1, compressionEnabled);
cluster.get(1).nodetoolResult("disableautocompaction", "netstats_test").asserts().success();
populateData(compressionEnabled);
cluster.get(1).flush("netstats_test");
// then bootstrap the second one, upon joining,
// we should see that netstats shows how SSTables are being streamed on the first node
final IInstanceConfig config = cluster.newInstanceConfig();
config.set("auto_bootstrap", true);
IInvokableInstance secondNode = cluster.bootstrap(config);
final Future<?> startupRunnable = executorService.submit((Runnable) secondNode::startup);
final Future<AbstractNetstatsStreaming.NetstatResults> netstatsFuture = executorService.submit(new NetstatsCallable(cluster.get(1)));
startupRunnable.get(3, MINUTES);
// 1m is a bit much, but should be fine on slower environments. Node2 can't come up without streaming
// completing, so if node2 is up 1m is enough time for the nodetool watcher to yield
final AbstractNetstatsStreaming.NetstatResults results = netstatsFuture.get(1, MINUTES);
results.assertSuccessful();
AbstractNetstatsStreaming.NetstatsOutputParser.validate(AbstractNetstatsStreaming.NetstatsOutputParser.parse(results));
}
}
Aggregations