private boolean isQuorumAvailable(int countUnreachableNodes) { int replicationFactor = config.replicationFactor(); return countUnreachableNodes < (replicationFactor + 1) / 2; }
private static void checkRfsMatchConfig(KsDef ks, CassandraKeyValueServiceConfig config, Set<String> dcs, Map<String, String> strategyOptions) { for (String datacenter : dcs) { if (Integer.parseInt(strategyOptions.get(datacenter)) != config.replicationFactor()) { throw new UnsupportedOperationException("Your current Cassandra keyspace (" + ks.getName() + ") has a replication factor not matching your Atlas Cassandra configuration." + " Change them to match, but be mindful of what steps you'll need to" + " take to correctly repair or cleanup existing data in your cluster."); } } } }
private static void checkMoreRacksThanRfOrFewerHostsThanRf(CassandraKeyValueServiceConfig config, Set<String> hosts, Multimap<String, String> dcRack) { if (dcRack.values().size() < config.replicationFactor() && hosts.size() > config.replicationFactor()) { logErrorOrThrow("The cassandra cluster only has one DC, " + "and is set up with less racks than the desired number of replicas, " + "and there are more hosts than the replication factor. " + "It is very likely that your rack configuration is incorrect and replicas " + "would not be placed correctly for the failure tolerance you want. " + "If you fully understand how NetworkTopology replica placement strategy will be placing " + "your replicas, feel free to set the 'ignoreNodeTopologyChecks' KVS config option.", config.ignoreNodeTopologyChecks()); } }
static KsDef createKsDefForFresh(CassandraClient client, CassandraKeyValueServiceConfig config) throws TException { KsDef ksDef = new KsDef(config.getKeyspaceOrThrow(), CassandraConstants.NETWORK_STRATEGY, ImmutableList.of()); Set<String> dcs = sanityCheckDatacenters(client, config); ksDef.setStrategy_options(Maps.asMap(dcs, ignore -> String.valueOf(config.replicationFactor()))); ksDef.setDurable_writes(true); return ksDef; }
@Test public void preservesOtherPropertiesOnResolvedConfigWithNamespace() { CassandraKeyValueServiceConfig newConfig = CassandraAtlasDbFactory.preprocessKvsConfig(CONFIG_WITHOUT_KEYSPACE, Optional::empty, Optional.of(KEYSPACE)); assertThat(newConfig.servers()).isEqualTo(SERVERS); assertThat(newConfig.replicationFactor()).isEqualTo(1); }
@Test public void differentRfThanConfigThrows() { KsDef ksDef = new KsDef("test", CassandraConstants.SIMPLE_STRATEGY, ImmutableList.of()); ksDef.setStrategy_options(ImmutableMap.of(DC_1, "1", DC_2, "2")); when(config.replicationFactor()).thenReturn(1); assertThatThrownBy(() -> CassandraVerifier.sanityCheckReplicationFactor(ksDef, config, ImmutableSortedSet.of(DC_1, DC_2))) .isInstanceOf(UnsupportedOperationException.class); }
@Test public void simpleStrategyOneDcOneRfSucceedsAndUpdatesKsDef() throws TException { setTopology(createDetails(DC_1, RACK_1, HOST_1)); when(config.replicationFactor()).thenReturn(1); KsDef ksDef = new KsDef("test", CassandraConstants.SIMPLE_STRATEGY, ImmutableList.of()); ImmutableMap<String, String> strategyOptions = ImmutableMap .of(CassandraConstants.REPLICATION_FACTOR_OPTION, "1"); ksDef.setStrategy_options(strategyOptions); ksDef = CassandraVerifier.checkAndSetReplicationFactor(client, ksDef, config); assertThat(ksDef.strategy_class).isEqualTo(CassandraConstants.NETWORK_STRATEGY); assertThat(ksDef.strategy_options).isEqualTo(ImmutableMap.of(DC_1, "1")); }
@Test public void otherPropertiesConservedWhenAddingKeyspace() { CassandraKeyValueServiceConfig newConfig = CassandraKeyValueServiceConfigs.copyWithKeyspace( CONFIG_WITHOUT_KEYSPACE, KEYSPACE); assertThat(newConfig.replicationFactor()).isEqualTo(1); assertThat(newConfig.servers()).isEqualTo(SERVERS); }
@Test public void unsetTopologyAndHighRfThrows() throws TException { setTopology(defaultTopology(HOST_1), defaultTopology(HOST_2)); when(config.replicationFactor()).thenReturn(3); assertThatThrownBy(() -> CassandraVerifier.sanityCheckDatacenters(client, config)) .isInstanceOf(IllegalStateException.class); }
@Test public void returnSameKsDefIfNodeTopologyChecksIgnored() throws TException { setTopology(createDetails(DC_1, RACK_1, HOST_1)); when(config.replicationFactor()).thenReturn(7); when(config.ignoreNodeTopologyChecks()).thenReturn(true); KsDef ksDef = new KsDef("test", CassandraConstants.SIMPLE_STRATEGY, ImmutableList.of()); ImmutableMap<String, String> strategyOptions = ImmutableMap .of(CassandraConstants.REPLICATION_FACTOR_OPTION, "1", DC_1, "7"); ksDef.setStrategy_options(strategyOptions); ksDef = CassandraVerifier.checkAndSetReplicationFactor(client, ksDef, config); assertThat(ksDef.strategy_class).isEqualTo(CassandraConstants.SIMPLE_STRATEGY); assertThat(ksDef.strategy_options).isEqualTo(strategyOptions); }
@Test public void nonDefaultDcAndHighRfSucceeds() throws TException { setTopology(createDetails(DC_1, RACK_1, HOST_1)); when(config.replicationFactor()).thenReturn(3); assertThat(CassandraVerifier.sanityCheckDatacenters(client, config)) .containsExactly(DC_1); }
@Test public void unsetTopologyAndRfOneSucceeds() throws TException { setTopology(defaultTopology(HOST_1), defaultTopology(HOST_2)); when(config.replicationFactor()).thenReturn(1); assertThat(CassandraVerifier.sanityCheckDatacenters(client, config)) .containsExactly(CassandraConstants.DEFAULT_DC); }
@Test public void oneDcOneRackAndMoreHostsThanRfThrows() throws TException { setTopology(createDetails(DC_1, RACK_1, HOST_1), createDetails(DC_1, RACK_1, HOST_2), createDetails(DC_1, RACK_1, HOST_3), createDetails(DC_1, RACK_1, HOST_4)); when(config.replicationFactor()).thenReturn(3); assertThatThrownBy(() -> CassandraVerifier.sanityCheckDatacenters(client, config)) .isInstanceOf(IllegalStateException.class); }
@Test public void oneDcFewerRacksThanRfAndMoreHostsThanRfThrows() throws TException { setTopology(defaultDcDetails(RACK_1, HOST_1), defaultDcDetails(RACK_2, HOST_2), defaultDcDetails(RACK_1, HOST_3), defaultDcDetails(RACK_2, HOST_4)); when(config.replicationFactor()).thenReturn(3); assertThatThrownBy(() -> CassandraVerifier.sanityCheckDatacenters(client, config)) .isInstanceOf(IllegalStateException.class); }
@Test public void simpleStrategyMultipleDcsThrows() throws TException { setTopology(createDetails(DC_1, RACK_1, HOST_1), createDetails(DC_1, RACK_1, HOST_2), createDetails(DC_1, RACK_1, HOST_3), createDetails(DC_2, RACK_1, HOST_4)); when(config.replicationFactor()).thenReturn(1); KsDef ksDef = new KsDef("test", CassandraConstants.SIMPLE_STRATEGY, ImmutableList.of()); ksDef.setStrategy_options(ImmutableMap.of(CassandraConstants.REPLICATION_FACTOR_OPTION, "1")); assertThatThrownBy(() -> CassandraVerifier.checkAndSetReplicationFactor(client, ksDef, config)) .isInstanceOf(IllegalStateException.class); }
@Test public void freshInstanceSetsStrategyOptions() throws TException { setTopology(createDetails(DC_1, RACK_1, HOST_1), createDetails(DC_1, RACK_1, HOST_2), createDetails(DC_1, RACK_1, HOST_3), createDetails(DC_2, RACK_1, HOST_4)); when(config.replicationFactor()).thenReturn(3); KsDef ksDef = CassandraVerifier.createKsDefForFresh(client, config); assertThat(ksDef.strategy_options).isEqualTo(ImmutableMap.of(DC_1, "3", DC_2, "3")); }
@Test public void oneDcMoreRacksThanRfAndMoreHostsThanRfSucceeds() throws TException { setTopology(defaultDcDetails(RACK_1, HOST_1), defaultDcDetails(RACK_2, HOST_2), defaultDcDetails(RACK_1, HOST_3), defaultDcDetails(RACK_3, HOST_4)); when(config.replicationFactor()).thenReturn(2); assertThat(CassandraVerifier.sanityCheckDatacenters(client, config)) .containsExactly(CassandraConstants.DEFAULT_DC); }
@Test public void multipleDcSuceeds() throws TException { setTopology(createDetails(DC_1, RACK_1, HOST_1), createDetails(DC_1, RACK_1, HOST_2), createDetails(DC_1, RACK_1, HOST_3), createDetails(DC_2, RACK_1, HOST_4)); when(config.replicationFactor()).thenReturn(3); assertThat(CassandraVerifier.sanityCheckDatacenters(client, config)) .containsExactlyInAnyOrder(DC_1, DC_2); }
@Test public void oneDcFewerRacksThanRfAndFewerHostsThanRfSucceeds() throws TException { setTopology(defaultDcDetails(RACK_1, HOST_1), defaultDcDetails(RACK_2, HOST_2), defaultDcDetails(RACK_1, HOST_2), defaultDcDetails(RACK_2, HOST_1)); when(config.replicationFactor()).thenReturn(3); assertThat(CassandraVerifier.sanityCheckDatacenters(client, config)) .containsExactly(CassandraConstants.DEFAULT_DC); }
@Test public void testSanitiseReplicationFactorFailsAfterManipulatingReplicationFactorOnCassandra() throws TException { changeReplicationFactor(MODIFIED_REPLICATION_FACTOR); clientPool.run(client -> { try { CassandraVerifier.currentRfOnKeyspaceMatchesDesiredRf(client, CASSANDRA.getConfig()); fail("currentRf On Keyspace Matches DesiredRf after manipulating the cassandra keyspace"); } catch (Exception e) { assertReplicationFactorMismatchError(e); } return false; }); changeReplicationFactor(CASSANDRA.getConfig().replicationFactor()); }