static void runWithWaitingForSchemas( RunnableCheckedException<TException> task, CassandraKeyValueServiceConfig config, CassandraClient client, String unsafeSchemaChangeDescription) throws TException { waitForSchemaVersions(config, client, "before " + unsafeSchemaChangeDescription); task.run(); waitForSchemaVersions(config, client, "after " + unsafeSchemaChangeDescription); }
private void assertWaitForSchemaVersionsDoesNotThrow() throws TException { CassandraKeyValueServices.waitForSchemaVersions(config, client, TABLE); } }
/** * This is a request from pbrown / FDEs; basically it's a pain to do DB surgery to get out * of failed patch upgrades, the majority of which requires schema mutations; they would find * it preferable to stop before starting the actual patch upgrade / setting APPLYING state. */ static void warnUserInInitializationIfClusterAlreadyInInconsistentState( CassandraClientPool clientPool, CassandraKeyValueServiceConfig config) { try { clientPool.run(client -> { waitForSchemaVersions(config, client, " during an initialization check"); return null; }); } catch (Exception e) { log.warn("Failed to retrieve current Cassandra cluster schema status.", e); } }
private Set<String> getTableNames(CassandraClient client, String keyspace, Function<CfDef, String> nameGetter) throws TException { try { CassandraKeyValueServices .waitForSchemaVersions(config, client, "before making a call to get all table names."); } catch (IllegalStateException e) { throw new InsufficientConsistencyException("Could not reach a quorum of nodes agreeing on schema versions " + "before making a call to get all table names.", e); } KsDef ks = client.describe_keyspace(keyspace); return ks.getCf_defs().stream() .map(nameGetter) .collect(Collectors.toSet()); } }
private void assertWaitForSchemaVersionsThrowsAndContainsConfigNodesInformation() { assertThatThrownBy(() -> CassandraKeyValueServices.waitForSchemaVersions(config, client, TABLE)) .isInstanceOf(IllegalStateException.class) .hasMessageContaining(FIVE_SERVERS.iterator().next().getHostName()); }
private static boolean keyspaceAlreadyExists(InetSocketAddress host, CassandraKeyValueServiceConfig config) throws TException { try { CassandraClient client = CassandraClientFactory.getClientInternal(host, config); client.describe_keyspace(config.getKeyspaceOrThrow()); CassandraKeyValueServices.waitForSchemaVersions(config, client, "while checking if schemas diverged on startup"); return true; } catch (NotFoundException e) { return false; } }
@Test public void waitWaitsForSchemaVersions() throws TException { CassandraClient waitingClient = mock(CassandraClient.class); when(waitingClient.describe_schema_versions()).thenReturn( ImmutableMap.of(), ImmutableMap.of(VERSION_UNREACHABLE, QUORUM_OF_NODES, VERSION_1, REST_OF_NODES), ImmutableMap.of(VERSION_1, QUORUM_OF_NODES, VERSION_UNREACHABLE, REST_OF_NODES), ImmutableMap.of(VERSION_1, ALL_NODES)); CassandraKeyValueServices.waitForSchemaVersions(waitingConfig, waitingClient, TABLE); verify(waitingClient, times(3)).describe_schema_versions(); }
private static boolean attemptToCreateKeyspaceOnHost(InetSocketAddress host, CassandraKeyValueServiceConfig config) throws TException { try { CassandraClient client = CassandraClientFactory.getClientInternal(host, config); KsDef ksDef = createKsDefForFresh(client, config); client.system_add_keyspace(ksDef); log.info("Created keyspace: {}", SafeArg.of("keyspace", config.getKeyspaceOrThrow())); CassandraKeyValueServices.waitForSchemaVersions(config, client, "after adding the initial empty keyspace"); return true; } catch (InvalidRequestException e) { return keyspaceAlreadyExists(host, config); } }
private void putMetadataAndMaybeAlterTables( boolean possiblyNeedToPerformSettingsChanges, Map<Cell, byte[]> newMetadata, Collection<CfDef> updatedCfs) { try { clientPool.runWithRetry(client -> { if (possiblyNeedToPerformSettingsChanges) { for (CfDef cf : updatedCfs) { client.system_update_column_family(cf); } CassandraKeyValueServices.waitForSchemaVersions(config, client, schemaChangeDescriptionForPutMetadataForTables(updatedCfs)); } // Done with actual schema mutation, push the metadata put(AtlasDbConstants.DEFAULT_METADATA_TABLE, newMetadata, System.currentTimeMillis()); return null; }); } catch (Exception e) { throw Throwables.unwrapAndThrowAtlasDbDependencyException(e); } }
private static void updateExistingKeyspace(CassandraClientPool clientPool, CassandraKeyValueServiceConfig config) throws TException { clientPool.runWithRetry((FunctionCheckedException<CassandraClient, Void, TException>) client -> { KsDef originalKsDef = client.describe_keyspace(config.getKeyspaceOrThrow()); // there was an existing keyspace // check and make sure it's definition is up to date with our config KsDef modifiedKsDef = originalKsDef.deepCopy(); checkAndSetReplicationFactor( client, modifiedKsDef, config); if (!modifiedKsDef.equals(originalKsDef)) { // Can't call system_update_keyspace to update replication factor if CfDefs are set modifiedKsDef.setCf_defs(ImmutableList.of()); client.system_update_keyspace(modifiedKsDef); CassandraKeyValueServices.waitForSchemaVersions(config, client, "after updating the existing keyspace"); } return null; }); }
static void runWithWaitingForSchemas( RunnableCheckedException<TException> task, CassandraKeyValueServiceConfig config, CassandraClient client, String unsafeSchemaChangeDescription) throws TException { waitForSchemaVersions(config, client, "before " + unsafeSchemaChangeDescription); task.run(); waitForSchemaVersions(config, client, "after " + unsafeSchemaChangeDescription); }
/** * This is a request from pbrown / FDEs; basically it's a pain to do DB surgery to get out * of failed patch upgrades, the majority of which requires schema mutations; they would find * it preferable to stop before starting the actual patch upgrade / setting APPLYING state. */ static void warnUserInInitializationIfClusterAlreadyInInconsistentState( CassandraClientPool clientPool, CassandraKeyValueServiceConfig config) { try { clientPool.run(client -> { waitForSchemaVersions(config, client, " during an initialization check"); return null; }); } catch (Exception e) { log.warn("Failed to retrieve current Cassandra cluster schema status.", e); } }
private Set<String> getTableNames(CassandraClient client, String keyspace, Function<CfDef, String> nameGetter) throws TException { try { CassandraKeyValueServices .waitForSchemaVersions(config, client, "before making a call to get all table names."); } catch (IllegalStateException e) { throw new InsufficientConsistencyException("Could not reach a quorum of nodes agreeing on schema versions " + "before making a call to get all table names.", e); } KsDef ks = client.describe_keyspace(keyspace); return ks.getCf_defs().stream() .map(nameGetter) .collect(Collectors.toSet()); } }
private static boolean keyspaceAlreadyExists(InetSocketAddress host, CassandraKeyValueServiceConfig config) throws TException { try { CassandraClient client = CassandraClientFactory.getClientInternal(host, config); client.describe_keyspace(config.getKeyspaceOrThrow()); CassandraKeyValueServices.waitForSchemaVersions(config, client, "while checking if schemas diverged on startup"); return true; } catch (NotFoundException e) { return false; } }
private static boolean attemptToCreateKeyspaceOnHost(InetSocketAddress host, CassandraKeyValueServiceConfig config) throws TException { try { CassandraClient client = CassandraClientFactory.getClientInternal(host, config); KsDef ksDef = createKsDefForFresh(client, config); client.system_add_keyspace(ksDef); log.info("Created keyspace: {}", SafeArg.of("keyspace", config.getKeyspaceOrThrow())); CassandraKeyValueServices.waitForSchemaVersions(config, client, "after adding the initial empty keyspace"); return true; } catch (InvalidRequestException e) { return keyspaceAlreadyExists(host, config); } }
private void putMetadataAndMaybeAlterTables( boolean possiblyNeedToPerformSettingsChanges, Map<Cell, byte[]> newMetadata, Collection<CfDef> updatedCfs) { try { clientPool.runWithRetry(client -> { if (possiblyNeedToPerformSettingsChanges) { for (CfDef cf : updatedCfs) { client.system_update_column_family(cf); } CassandraKeyValueServices.waitForSchemaVersions(config, client, schemaChangeDescriptionForPutMetadataForTables(updatedCfs)); } // Done with actual schema mutation, push the metadata put(AtlasDbConstants.DEFAULT_METADATA_TABLE, newMetadata, System.currentTimeMillis()); return null; }); } catch (Exception e) { throw Throwables.unwrapAndThrowAtlasDbDependencyException(e); } }
private static void updateExistingKeyspace(CassandraClientPool clientPool, CassandraKeyValueServiceConfig config) throws TException { clientPool.runWithRetry((FunctionCheckedException<CassandraClient, Void, TException>) client -> { KsDef originalKsDef = client.describe_keyspace(config.getKeyspaceOrThrow()); // there was an existing keyspace // check and make sure it's definition is up to date with our config KsDef modifiedKsDef = originalKsDef.deepCopy(); checkAndSetReplicationFactor( client, modifiedKsDef, config); if (!modifiedKsDef.equals(originalKsDef)) { // Can't call system_update_keyspace to update replication factor if CfDefs are set modifiedKsDef.setCf_defs(ImmutableList.of()); client.system_update_keyspace(modifiedKsDef); CassandraKeyValueServices.waitForSchemaVersions(config, client, "after updating the existing keyspace"); } return null; }); }