use of org.apache.cassandra.distributed.api.IInvokableInstance 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.api.IInvokableInstance 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.api.IInvokableInstance in project cassandra by apache.
the class AssassinatedEmptyNodeTest method consume.
@Override
void consume(Cluster cluster, IInvokableInstance nodeToRemove) {
IInvokableInstance seed = cluster.get(SEED_NUM);
IInvokableInstance peer = cluster.get(PEER_NUM);
InetSocketAddress addressToReplace = nodeToRemove.broadcastAddress();
// now stop all nodes
stopAll(cluster);
// with all nodes down, now start the seed (should be first node)
seed.startup();
peer.startup();
// at this point node2 should be known in gossip, but with generation/version of 0
assertGossipInfo(seed, addressToReplace, 0, -1);
assertGossipInfo(peer, addressToReplace, 0, -1);
}
use of org.apache.cassandra.distributed.api.IInvokableInstance 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.api.IInvokableInstance 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