add final for params, local variables, and fields (#7084)
This commit is contained in:
@@ -13,13 +13,13 @@ import io.airbyte.integrations.debezium.CdcMetadataInjector;
|
||||
public class MssqlCdcConnectorMetadataInjector implements CdcMetadataInjector {
|
||||
|
||||
@Override
|
||||
public void addMetaData(ObjectNode event, JsonNode source) {
|
||||
String commitLsn = source.get("commit_lsn").asText();
|
||||
public void addMetaData(final ObjectNode event, final JsonNode source) {
|
||||
final String commitLsn = source.get("commit_lsn").asText();
|
||||
event.put(CDC_LSN, commitLsn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String namespace(JsonNode source) {
|
||||
public String namespace(final JsonNode source) {
|
||||
return source.get("schema").asText();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public class MssqlCdcSavedInfoFetcher implements CdcSavedInfoFetcher {
|
||||
private final JsonNode savedOffset;
|
||||
private final JsonNode savedSchemaHistory;
|
||||
|
||||
protected MssqlCdcSavedInfoFetcher(CdcState savedState) {
|
||||
protected MssqlCdcSavedInfoFetcher(final CdcState savedState) {
|
||||
final boolean savedStatePresent = savedState != null && savedState.getState() != null;
|
||||
this.savedOffset = savedStatePresent ? savedState.getState().get(MSSQL_CDC_OFFSET) : null;
|
||||
this.savedSchemaHistory = savedStatePresent ? savedState.getState().get(MSSQL_DB_HISTORY) : null;
|
||||
|
||||
@@ -25,13 +25,13 @@ public class MssqlCdcStateHandler implements CdcStateHandler {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MssqlCdcStateHandler.class);
|
||||
private final StateManager stateManager;
|
||||
|
||||
public MssqlCdcStateHandler(StateManager stateManager) {
|
||||
public MssqlCdcStateHandler(final StateManager stateManager) {
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AirbyteMessage saveState(Map<String, String> offset, String dbHistory) {
|
||||
Map<String, Object> state = new HashMap<>();
|
||||
public AirbyteMessage saveState(final Map<String, String> offset, final String dbHistory) {
|
||||
final Map<String, Object> state = new HashMap<>();
|
||||
state.put(MSSQL_CDC_OFFSET, offset);
|
||||
state.put(MSSQL_DB_HISTORY, dbHistory);
|
||||
|
||||
|
||||
@@ -23,24 +23,24 @@ public class MssqlCdcTargetPosition implements CdcTargetPosition {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MssqlCdcTargetPosition.class);
|
||||
public final Lsn targetLsn;
|
||||
|
||||
public MssqlCdcTargetPosition(Lsn targetLsn) {
|
||||
public MssqlCdcTargetPosition(final Lsn targetLsn) {
|
||||
this.targetLsn = targetLsn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reachedTargetPosition(JsonNode valueAsJson) {
|
||||
Lsn recordLsn = extractLsn(valueAsJson);
|
||||
public boolean reachedTargetPosition(final JsonNode valueAsJson) {
|
||||
final Lsn recordLsn = extractLsn(valueAsJson);
|
||||
|
||||
if (targetLsn.compareTo(recordLsn) > 0) {
|
||||
return false;
|
||||
} else {
|
||||
SnapshotMetadata snapshotMetadata = SnapshotMetadata.valueOf(valueAsJson.get("source").get("snapshot").asText().toUpperCase());
|
||||
final SnapshotMetadata snapshotMetadata = SnapshotMetadata.valueOf(valueAsJson.get("source").get("snapshot").asText().toUpperCase());
|
||||
// if not snapshot or is snapshot but last record in snapshot.
|
||||
return SnapshotMetadata.TRUE != snapshotMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
private Lsn extractLsn(JsonNode valueAsJson) {
|
||||
private Lsn extractLsn(final JsonNode valueAsJson) {
|
||||
return Optional.ofNullable(valueAsJson.get("source"))
|
||||
.flatMap(source -> Optional.ofNullable(source.get("commit_lsn").asText()))
|
||||
.map(Lsn::valueOf)
|
||||
@@ -48,14 +48,14 @@ public class MssqlCdcTargetPosition implements CdcTargetPosition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
MssqlCdcTargetPosition that = (MssqlCdcTargetPosition) o;
|
||||
final MssqlCdcTargetPosition that = (MssqlCdcTargetPosition) o;
|
||||
return targetLsn.equals(that.targetLsn);
|
||||
}
|
||||
|
||||
@@ -64,21 +64,21 @@ public class MssqlCdcTargetPosition implements CdcTargetPosition {
|
||||
return targetLsn.hashCode();
|
||||
}
|
||||
|
||||
public static MssqlCdcTargetPosition getTargetPosition(JdbcDatabase database, String dbName) {
|
||||
public static MssqlCdcTargetPosition getTargetPosition(final JdbcDatabase database, final String dbName) {
|
||||
try {
|
||||
final List<JsonNode> jsonNodes = database
|
||||
.bufferedResultSetQuery(conn -> conn.createStatement().executeQuery(
|
||||
"USE " + dbName + "; SELECT sys.fn_cdc_get_max_lsn() AS max_lsn;"), JdbcUtils.getDefaultSourceOperations()::rowToJson);
|
||||
Preconditions.checkState(jsonNodes.size() == 1);
|
||||
if (jsonNodes.get(0).get("max_lsn") != null) {
|
||||
Lsn maxLsn = Lsn.valueOf(jsonNodes.get(0).get("max_lsn").binaryValue());
|
||||
final Lsn maxLsn = Lsn.valueOf(jsonNodes.get(0).get("max_lsn").binaryValue());
|
||||
LOGGER.info("identified target lsn: " + maxLsn);
|
||||
return new MssqlCdcTargetPosition(maxLsn);
|
||||
} else {
|
||||
throw new RuntimeException("SQL returned max LSN as null, this might be because the SQL Server Agent is not running. " +
|
||||
"Please enable the Agent and try again (https://docs.microsoft.com/en-us/sql/ssms/agent/start-stop-or-pause-the-sql-server-agent-service?view=sql-server-ver15)");
|
||||
}
|
||||
} catch (SQLException | IOException e) {
|
||||
} catch (final SQLException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.sql.SQLException;
|
||||
public class MssqlJdbcStreamingQueryConfiguration implements JdbcStreamingQueryConfiguration {
|
||||
|
||||
@Override
|
||||
public void accept(Connection connection, PreparedStatement preparedStatement) throws SQLException {
|
||||
public void accept(final Connection connection, final PreparedStatement preparedStatement) throws SQLException {
|
||||
connection.setAutoCommit(false);
|
||||
preparedStatement.setFetchSize(1000);
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonNode toDatabaseConfig(JsonNode mssqlConfig) {
|
||||
List<String> additionalParameters = new ArrayList<>();
|
||||
public JsonNode toDatabaseConfig(final JsonNode mssqlConfig) {
|
||||
final List<String> additionalParameters = new ArrayList<>();
|
||||
|
||||
final StringBuilder jdbcUrl = new StringBuilder(String.format("jdbc:sqlserver://%s:%s;databaseName=%s;",
|
||||
mssqlConfig.get("host").asText(),
|
||||
@@ -105,8 +105,8 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AirbyteCatalog discover(JsonNode config) throws Exception {
|
||||
AirbyteCatalog catalog = super.discover(config);
|
||||
public AirbyteCatalog discover(final JsonNode config) throws Exception {
|
||||
final AirbyteCatalog catalog = super.discover(config);
|
||||
|
||||
if (isCdc(config)) {
|
||||
final List<AirbyteStream> streams = catalog.getStreams().stream()
|
||||
@@ -122,7 +122,7 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CheckedConsumer<JdbcDatabase, Exception>> getCheckOperations(JsonNode config) throws Exception {
|
||||
public List<CheckedConsumer<JdbcDatabase, Exception>> getCheckOperations(final JsonNode config) throws Exception {
|
||||
final List<CheckedConsumer<JdbcDatabase, Exception>> checkOperations = new ArrayList<>(super.getCheckOperations(config));
|
||||
|
||||
if (isCdc(config)) {
|
||||
@@ -135,10 +135,10 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
return checkOperations;
|
||||
}
|
||||
|
||||
protected void assertCdcEnabledInDb(JsonNode config, JdbcDatabase database) throws SQLException {
|
||||
List<JsonNode> queryResponse = database.query(connection -> {
|
||||
protected void assertCdcEnabledInDb(final JsonNode config, final JdbcDatabase database) throws SQLException {
|
||||
final List<JsonNode> queryResponse = database.query(connection -> {
|
||||
final String sql = "SELECT name, is_cdc_enabled FROM sys.databases WHERE name = ?";
|
||||
PreparedStatement ps = connection.prepareStatement(sql);
|
||||
final PreparedStatement ps = connection.prepareStatement(sql);
|
||||
ps.setString(1, config.get("database").asText());
|
||||
LOGGER.info(String.format("Checking that cdc is enabled on database '%s' using the query: '%s'",
|
||||
config.get("database").asText(), sql));
|
||||
@@ -156,10 +156,10 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertCdcSchemaQueryable(JsonNode config, JdbcDatabase database) throws SQLException {
|
||||
List<JsonNode> queryResponse = database.query(connection -> {
|
||||
protected void assertCdcSchemaQueryable(final JsonNode config, final JdbcDatabase database) throws SQLException {
|
||||
final List<JsonNode> queryResponse = database.query(connection -> {
|
||||
final String sql = "USE " + config.get("database").asText() + "; SELECT * FROM cdc.change_tables";
|
||||
PreparedStatement ps = connection.prepareStatement(sql);
|
||||
final PreparedStatement ps = connection.prepareStatement(sql);
|
||||
LOGGER.info(String.format("Checking user '%s' can query the cdc schema and that we have at least 1 cdc enabled table using the query: '%s'",
|
||||
config.get("username").asText(), sql));
|
||||
return ps;
|
||||
@@ -171,11 +171,11 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
|
||||
// todo: ensure this works for Azure managed SQL (since it uses different sql server agent)
|
||||
protected void assertSqlServerAgentRunning(JdbcDatabase database) throws SQLException {
|
||||
protected void assertSqlServerAgentRunning(final JdbcDatabase database) throws SQLException {
|
||||
try {
|
||||
List<JsonNode> queryResponse = database.query(connection -> {
|
||||
final List<JsonNode> queryResponse = database.query(connection -> {
|
||||
final String sql = "SELECT status_desc FROM sys.dm_server_services WHERE [servicename] LIKE 'SQL Server Agent%'";
|
||||
PreparedStatement ps = connection.prepareStatement(sql);
|
||||
final PreparedStatement ps = connection.prepareStatement(sql);
|
||||
LOGGER.info(String.format("Checking that the SQL Server Agent is running using the query: '%s'", sql));
|
||||
return ps;
|
||||
}, sourceOperations::rowToJson).collect(toList());
|
||||
@@ -184,7 +184,7 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
"The SQL Server Agent is not running. Current state: '%s'. Please check the documentation on ensuring SQL Server Agent is running.",
|
||||
queryResponse.get(0).get("status_desc").toString()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
if (e.getCause() != null && e.getCause().getClass().equals(com.microsoft.sqlserver.jdbc.SQLServerException.class)) {
|
||||
LOGGER.warn(String.format("Skipping check for whether the SQL Server Agent is running, SQLServerException thrown: '%s'",
|
||||
e.getMessage()));
|
||||
@@ -194,10 +194,10 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertSnapshotIsolationAllowed(JsonNode config, JdbcDatabase database) throws SQLException {
|
||||
List<JsonNode> queryResponse = database.query(connection -> {
|
||||
protected void assertSnapshotIsolationAllowed(final JsonNode config, final JdbcDatabase database) throws SQLException {
|
||||
final List<JsonNode> queryResponse = database.query(connection -> {
|
||||
final String sql = "SELECT name, snapshot_isolation_state FROM sys.databases WHERE name = ?";
|
||||
PreparedStatement ps = connection.prepareStatement(sql);
|
||||
final PreparedStatement ps = connection.prepareStatement(sql);
|
||||
ps.setString(1, config.get("database").asText());
|
||||
LOGGER.info(String.format("Checking that snapshot isolation is enabled on database '%s' using the query: '%s'",
|
||||
config.get("database").asText(), sql));
|
||||
@@ -217,15 +217,15 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AutoCloseableIterator<AirbyteMessage>> getIncrementalIterators(JdbcDatabase database,
|
||||
ConfiguredAirbyteCatalog catalog,
|
||||
Map<String, TableInfo<CommonField<JDBCType>>> tableNameToTable,
|
||||
StateManager stateManager,
|
||||
Instant emittedAt) {
|
||||
JsonNode sourceConfig = database.getSourceConfig();
|
||||
public List<AutoCloseableIterator<AirbyteMessage>> getIncrementalIterators(final JdbcDatabase database,
|
||||
final ConfiguredAirbyteCatalog catalog,
|
||||
final Map<String, TableInfo<CommonField<JDBCType>>> tableNameToTable,
|
||||
final StateManager stateManager,
|
||||
final Instant emittedAt) {
|
||||
final JsonNode sourceConfig = database.getSourceConfig();
|
||||
if (isCdc(sourceConfig) && shouldUseCDC(catalog)) {
|
||||
LOGGER.info("using CDC: {}", true);
|
||||
AirbyteDebeziumHandler handler = new AirbyteDebeziumHandler(sourceConfig,
|
||||
final AirbyteDebeziumHandler handler = new AirbyteDebeziumHandler(sourceConfig,
|
||||
MssqlCdcTargetPosition.getTargetPosition(database, sourceConfig.get("database").asText()),
|
||||
MssqlCdcProperties.getDebeziumProperties(), catalog, true);
|
||||
return handler.getIncrementalIterators(new MssqlCdcSavedInfoFetcher(stateManager.getCdcStateManager().getCdcState()),
|
||||
@@ -236,20 +236,20 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCdc(JsonNode config) {
|
||||
private static boolean isCdc(final JsonNode config) {
|
||||
return config.hasNonNull("replication_method")
|
||||
&& ReplicationMethod.valueOf(config.get("replication_method").asText())
|
||||
.equals(ReplicationMethod.CDC);
|
||||
}
|
||||
|
||||
private static boolean shouldUseCDC(ConfiguredAirbyteCatalog catalog) {
|
||||
Optional<SyncMode> any = catalog.getStreams().stream().map(ConfiguredAirbyteStream::getSyncMode)
|
||||
private static boolean shouldUseCDC(final ConfiguredAirbyteCatalog catalog) {
|
||||
final Optional<SyncMode> any = catalog.getStreams().stream().map(ConfiguredAirbyteStream::getSyncMode)
|
||||
.filter(syncMode -> syncMode == SyncMode.INCREMENTAL).findAny();
|
||||
return any.isPresent();
|
||||
}
|
||||
|
||||
// Note: in place mutation.
|
||||
private static AirbyteStream removeIncrementalWithoutPk(AirbyteStream stream) {
|
||||
private static AirbyteStream removeIncrementalWithoutPk(final AirbyteStream stream) {
|
||||
if (stream.getSourceDefinedPrimaryKey().isEmpty()) {
|
||||
stream.getSupportedSyncModes().remove(SyncMode.INCREMENTAL);
|
||||
}
|
||||
@@ -258,7 +258,7 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
|
||||
// Note: in place mutation.
|
||||
private static AirbyteStream setIncrementalToSourceDefined(AirbyteStream stream) {
|
||||
private static AirbyteStream setIncrementalToSourceDefined(final AirbyteStream stream) {
|
||||
if (stream.getSupportedSyncModes().contains(SyncMode.INCREMENTAL)) {
|
||||
stream.setSourceDefinedCursor(true);
|
||||
}
|
||||
@@ -267,10 +267,10 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
|
||||
// Note: in place mutation.
|
||||
private static AirbyteStream addCdcMetadataColumns(AirbyteStream stream) {
|
||||
private static AirbyteStream addCdcMetadataColumns(final AirbyteStream stream) {
|
||||
|
||||
ObjectNode jsonSchema = (ObjectNode) stream.getJsonSchema();
|
||||
ObjectNode properties = (ObjectNode) jsonSchema.get("properties");
|
||||
final ObjectNode jsonSchema = (ObjectNode) stream.getJsonSchema();
|
||||
final ObjectNode properties = (ObjectNode) jsonSchema.get("properties");
|
||||
|
||||
final JsonNode stringType = Jsons.jsonNode(ImmutableMap.of("type", "string"));
|
||||
properties.set(CDC_LSN, stringType);
|
||||
@@ -280,8 +280,8 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
return stream;
|
||||
}
|
||||
|
||||
private void readSsl(JsonNode sslMethod, List<String> additionalParameters) {
|
||||
JsonNode config = sslMethod.get("ssl_method");
|
||||
private void readSsl(final JsonNode sslMethod, final List<String> additionalParameters) {
|
||||
final JsonNode config = sslMethod.get("ssl_method");
|
||||
switch (config.get("ssl_method").asText()) {
|
||||
case "unencrypted" -> additionalParameters.add("encrypt=false");
|
||||
case "encrypted_trust_server_certificate" -> {
|
||||
@@ -292,15 +292,15 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
additionalParameters.add("encrypt=true");
|
||||
|
||||
// trust store location code found at https://stackoverflow.com/a/56570588
|
||||
String trustStoreLocation = Optional.ofNullable(System.getProperty("javax.net.ssl.trustStore"))
|
||||
final String trustStoreLocation = Optional.ofNullable(System.getProperty("javax.net.ssl.trustStore"))
|
||||
.orElseGet(() -> System.getProperty("java.home") + "/lib/security/cacerts");
|
||||
File trustStoreFile = new File(trustStoreLocation);
|
||||
final File trustStoreFile = new File(trustStoreLocation);
|
||||
if (!trustStoreFile.exists()) {
|
||||
throw new RuntimeException(
|
||||
"Unable to locate the Java TrustStore: the system property javax.net.ssl.trustStore is undefined or "
|
||||
+ trustStoreLocation + " does not exist.");
|
||||
}
|
||||
String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
|
||||
final String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
|
||||
additionalParameters.add("trustStore=" + trustStoreLocation);
|
||||
if (trustStorePassword != null && !trustStorePassword.isEmpty()) {
|
||||
additionalParameters.add("trustStorePassword=" + config.get("trustStorePassword").asText());
|
||||
@@ -312,7 +312,7 @@ public class MssqlSource extends AbstractJdbcSource implements Source {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
public static void main(final String[] args) throws Exception {
|
||||
final Source source = MssqlSource.sshWrappedSource();
|
||||
LOGGER.info("starting source: {}", MssqlSource.class);
|
||||
new IntegrationRunner(source).run(args);
|
||||
|
||||
@@ -50,7 +50,7 @@ public abstract class AbstractSshMssqlSourceAcceptanceTest extends SourceAccepta
|
||||
populateDatabaseTestData();
|
||||
}
|
||||
|
||||
public ImmutableMap.Builder<Object, Object> getMSSQLDbConfigBuilder(JdbcDatabaseContainer<?> db) {
|
||||
public ImmutableMap.Builder<Object, Object> getMSSQLDbConfigBuilder(final JdbcDatabaseContainer<?> db) {
|
||||
dbName = "db_" + RandomStringUtils.randomAlphabetic(10).toLowerCase();
|
||||
return ImmutableMap.builder()
|
||||
.put("host", Objects.requireNonNull(db.getContainerInfo().getNetworkSettings()
|
||||
|
||||
@@ -93,7 +93,7 @@ public class CdcMssqlSourceAcceptanceTest extends SourceAcceptanceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupEnvironment(TestDestinationEnv environment) throws InterruptedException {
|
||||
protected void setupEnvironment(final TestDestinationEnv environment) throws InterruptedException {
|
||||
container = new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-latest").acceptLicense();
|
||||
container.addEnv("MSSQL_AGENT_ENABLED", "True"); // need this running for cdc to work
|
||||
container.start();
|
||||
@@ -151,12 +151,12 @@ public class CdcMssqlSourceAcceptanceTest extends SourceAcceptanceTest {
|
||||
// solving with a simple while retry loop
|
||||
boolean failingToStart = true;
|
||||
int retryNum = 0;
|
||||
int maxRetries = 10;
|
||||
final int maxRetries = 10;
|
||||
while (failingToStart) {
|
||||
try {
|
||||
// enabling CDC on each table
|
||||
String[] tables = {STREAM_NAME, STREAM_NAME2};
|
||||
for (String table : tables) {
|
||||
final String[] tables = {STREAM_NAME, STREAM_NAME2};
|
||||
for (final String table : tables) {
|
||||
executeQuery(String.format(
|
||||
"EXEC sys.sp_cdc_enable_table\n"
|
||||
+ "\t@source_schema = N'%s',\n"
|
||||
@@ -166,7 +166,7 @@ public class CdcMssqlSourceAcceptanceTest extends SourceAcceptanceTest {
|
||||
SCHEMA_NAME, table, CDC_ROLE_NAME));
|
||||
}
|
||||
failingToStart = false;
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
if (retryNum >= maxRetries) {
|
||||
throw e;
|
||||
} else {
|
||||
@@ -183,18 +183,18 @@ public class CdcMssqlSourceAcceptanceTest extends SourceAcceptanceTest {
|
||||
executeQuery(String.format("EXEC sp_addrolemember N'%s', N'%s';", CDC_ROLE_NAME, TEST_USER_NAME));
|
||||
}
|
||||
|
||||
private void executeQuery(String query) {
|
||||
private void executeQuery(final String query) {
|
||||
try {
|
||||
database.query(
|
||||
ctx -> ctx
|
||||
.execute(query));
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown(TestDestinationEnv testEnv) {
|
||||
protected void tearDown(final TestDestinationEnv testEnv) {
|
||||
container.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class CdcMssqlSourceDatatypeTest extends AbstractSourceDatabaseTypeTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown(TestDestinationEnv testEnv) {
|
||||
protected void tearDown(final TestDestinationEnv testEnv) {
|
||||
container.close();
|
||||
}
|
||||
|
||||
@@ -75,8 +75,8 @@ public class CdcMssqlSourceDatatypeTest extends AbstractSourceDatabaseTypeTest {
|
||||
return SCHEMA_NAME;
|
||||
}
|
||||
|
||||
private void executeQuery(String query) {
|
||||
try (Database database = Databases.createDatabase(
|
||||
private void executeQuery(final String query) {
|
||||
try (final Database database = Databases.createDatabase(
|
||||
container.getUsername(),
|
||||
container.getPassword(),
|
||||
String.format("jdbc:sqlserver://%s:%s",
|
||||
@@ -87,13 +87,13 @@ public class CdcMssqlSourceDatatypeTest extends AbstractSourceDatabaseTypeTest {
|
||||
database.query(
|
||||
ctx -> ctx
|
||||
.execute(query));
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupEnvironment(TestDestinationEnv environment) throws Exception {
|
||||
protected void setupEnvironment(final TestDestinationEnv environment) throws Exception {
|
||||
super.setupEnvironment(environment);
|
||||
enableCdcOnAllTables();
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ public class MssqlRdsSourceAcceptanceTest extends MssqlSourceAcceptanceTest {
|
||||
private JsonNode baseConfig;
|
||||
|
||||
@Override
|
||||
protected void setupEnvironment(TestDestinationEnv environment) throws SQLException {
|
||||
protected void setupEnvironment(final TestDestinationEnv environment) throws SQLException {
|
||||
baseConfig = getStaticConfig();
|
||||
String dbName = "db_" + RandomStringUtils.randomAlphabetic(10).toLowerCase();
|
||||
final String dbName = "db_" + RandomStringUtils.randomAlphabetic(10).toLowerCase();
|
||||
|
||||
final Database database = getDatabase();
|
||||
database.query(ctx -> {
|
||||
@@ -45,7 +45,7 @@ public class MssqlRdsSourceAcceptanceTest extends MssqlSourceAcceptanceTest {
|
||||
|
||||
private Database getDatabase() {
|
||||
String additionalParameter = "";
|
||||
JsonNode sslMethod = baseConfig.get("ssl_method");
|
||||
final JsonNode sslMethod = baseConfig.get("ssl_method");
|
||||
switch (sslMethod.get("ssl_method").asText()) {
|
||||
case "unencrypted" -> additionalParameter = "encrypt=false;";
|
||||
case "encrypted_trust_server_certificate" -> additionalParameter = "encrypt=true;trustServerCertificate=true;";
|
||||
@@ -62,8 +62,8 @@ public class MssqlRdsSourceAcceptanceTest extends MssqlSourceAcceptanceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown(TestDestinationEnv testEnv) throws Exception {
|
||||
String database = config.get("database").asText();
|
||||
protected void tearDown(final TestDestinationEnv testEnv) throws Exception {
|
||||
final String database = config.get("database").asText();
|
||||
getDatabase().query(ctx -> {
|
||||
ctx.fetch(String.format("ALTER DATABASE %s SET single_user with rollback immediate;", database));
|
||||
ctx.fetch(String.format("DROP DATABASE %s;", database));
|
||||
|
||||
@@ -33,7 +33,7 @@ public class MssqlSourceAcceptanceTest extends SourceAcceptanceTest {
|
||||
protected JsonNode config;
|
||||
|
||||
@Override
|
||||
protected void setupEnvironment(TestDestinationEnv environment) throws SQLException {
|
||||
protected void setupEnvironment(final TestDestinationEnv environment) throws SQLException {
|
||||
db = new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-latest").acceptLicense();
|
||||
db.start();
|
||||
|
||||
@@ -62,7 +62,7 @@ public class MssqlSourceAcceptanceTest extends SourceAcceptanceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown(TestDestinationEnv testEnv) throws Exception {
|
||||
protected void tearDown(final TestDestinationEnv testEnv) throws Exception {
|
||||
db.stop();
|
||||
db.close();
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class MssqlSourceAcceptanceTest extends SourceAcceptanceTest {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static Database getDatabase(JsonNode config) {
|
||||
private static Database getDatabase(final JsonNode config) {
|
||||
return Databases.createDatabase(
|
||||
config.get("username").asText(),
|
||||
config.get("password").asText(),
|
||||
|
||||
@@ -49,7 +49,7 @@ public class MssqlSourceDatatypeTest extends AbstractSourceDatabaseTypeTest {
|
||||
return database;
|
||||
}
|
||||
|
||||
private static Database getDatabase(JsonNode config) {
|
||||
private static Database getDatabase(final JsonNode config) {
|
||||
return Databases.createDatabase(
|
||||
config.get("username").asText(),
|
||||
config.get("password").asText(),
|
||||
@@ -76,7 +76,7 @@ public class MssqlSourceDatatypeTest extends AbstractSourceDatabaseTypeTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown(TestDestinationEnv testEnv) throws Exception {
|
||||
protected void tearDown(final TestDestinationEnv testEnv) throws Exception {
|
||||
container.stop();
|
||||
container.close();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.testcontainers.utility.DockerImageName;
|
||||
public class SslEnabledMssqlSourceAcceptanceTest extends MssqlSourceAcceptanceTest {
|
||||
|
||||
@Override
|
||||
protected void setupEnvironment(TestDestinationEnv environment) throws SQLException {
|
||||
protected void setupEnvironment(final TestDestinationEnv environment) throws SQLException {
|
||||
db = new MSSQLServerContainer<>(DockerImageName
|
||||
.parse("airbyte/mssql_ssltest:dev")
|
||||
.asCompatibleSubstituteFor("mcr.microsoft.com/mssql/server"))
|
||||
@@ -51,7 +51,7 @@ public class SslEnabledMssqlSourceAcceptanceTest extends MssqlSourceAcceptanceTe
|
||||
((ObjectNode) config).put("database", dbName);
|
||||
}
|
||||
|
||||
private static Database getDatabase(JsonNode baseConfig) {
|
||||
private static Database getDatabase(final JsonNode baseConfig) {
|
||||
return Databases.createDatabase(
|
||||
baseConfig.get("username").asText(),
|
||||
baseConfig.get("password").asText(),
|
||||
|
||||
@@ -103,8 +103,8 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
switchSnapshotIsolation(true, dbName);
|
||||
}
|
||||
|
||||
private void switchSnapshotIsolation(Boolean on, String db) {
|
||||
String onOrOff = on ? "ON" : "OFF";
|
||||
private void switchSnapshotIsolation(final Boolean on, final String db) {
|
||||
final String onOrOff = on ? "ON" : "OFF";
|
||||
executeQuery("ALTER DATABASE " + db + "\n\tSET ALLOW_SNAPSHOT_ISOLATION " + onOrOff);
|
||||
}
|
||||
|
||||
@@ -119,8 +119,8 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
executeQuery("EXEC sp_msforeachtable \"REVOKE ALL ON '?' TO " + TEST_USER_NAME + ";\"");
|
||||
}
|
||||
|
||||
private void alterPermissionsOnSchema(Boolean grant, String schema) {
|
||||
String grantOrRemove = grant ? "GRANT" : "REVOKE";
|
||||
private void alterPermissionsOnSchema(final Boolean grant, final String schema) {
|
||||
final String grantOrRemove = grant ? "GRANT" : "REVOKE";
|
||||
executeQuery(String.format("USE %s;\n" + "%s SELECT ON SCHEMA :: [%s] TO %s", dbName, grantOrRemove, schema, TEST_USER_NAME));
|
||||
}
|
||||
|
||||
@@ -132,17 +132,17 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createSchemaQuery(String schemaName) {
|
||||
public String createSchemaQuery(final String schemaName) {
|
||||
return "CREATE SCHEMA " + schemaName;
|
||||
}
|
||||
|
||||
private void switchCdcOnDatabase(Boolean enable, String db) {
|
||||
String storedProc = enable ? "sys.sp_cdc_enable_db" : "sys.sp_cdc_disable_db";
|
||||
private void switchCdcOnDatabase(final Boolean enable, final String db) {
|
||||
final String storedProc = enable ? "sys.sp_cdc_enable_db" : "sys.sp_cdc_disable_db";
|
||||
executeQuery("USE " + db + "\n" + "EXEC " + storedProc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTable(String schemaName, String tableName, String columnClause) {
|
||||
public void createTable(final String schemaName, final String tableName, final String columnClause) {
|
||||
switchCdcOnDatabase(true, dbName);
|
||||
super.createTable(schemaName, tableName, columnClause);
|
||||
|
||||
@@ -151,7 +151,7 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
// solving with a simple while retry loop
|
||||
boolean failingToStart = true;
|
||||
int retryNum = 0;
|
||||
int maxRetries = 10;
|
||||
final int maxRetries = 10;
|
||||
while (failingToStart) {
|
||||
try {
|
||||
executeQuery(String.format(
|
||||
@@ -162,14 +162,14 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
+ "\t@supports_net_changes = 0",
|
||||
schemaName, tableName, CDC_ROLE_NAME)); // enables cdc on MODELS_SCHEMA.MODELS_STREAM_NAME, giving CDC_ROLE_NAME select access
|
||||
failingToStart = false;
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
if (retryNum >= maxRetries) {
|
||||
throw e;
|
||||
} else {
|
||||
retryNum++;
|
||||
try {
|
||||
Thread.sleep(10000); // 10 seconds
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (final InterruptedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
@@ -178,10 +178,10 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String columnClause(Map<String, String> columnsWithDataType, Optional<String> primaryKey) {
|
||||
StringBuilder columnClause = new StringBuilder();
|
||||
public String columnClause(final Map<String, String> columnsWithDataType, final Optional<String> primaryKey) {
|
||||
final StringBuilder columnClause = new StringBuilder();
|
||||
int i = 0;
|
||||
for (Map.Entry<String, String> column : columnsWithDataType.entrySet()) {
|
||||
for (final Map.Entry<String, String> column : columnsWithDataType.entrySet()) {
|
||||
columnClause.append(column.getKey());
|
||||
columnClause.append(" ");
|
||||
columnClause.append(column.getValue());
|
||||
@@ -202,7 +202,7 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
try {
|
||||
database.close();
|
||||
container.close();
|
||||
} catch (Exception e) {
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@@ -225,8 +225,8 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
assertThrows(com.microsoft.sqlserver.jdbc.SQLServerException.class, () -> source.assertCdcSchemaQueryable(config, testJdbcDatabase));
|
||||
}
|
||||
|
||||
private void switchSqlServerAgentAndWait(Boolean start) throws InterruptedException {
|
||||
String startOrStop = start ? "START" : "STOP";
|
||||
private void switchSqlServerAgentAndWait(final Boolean start) throws InterruptedException {
|
||||
final String startOrStop = start ? "START" : "STOP";
|
||||
executeQuery(String.format("EXEC xp_servicecontrol N'%s',N'SQLServerAGENT';", startOrStop));
|
||||
Thread.sleep(15 * 1000); // 15 seconds to wait for change of agent state
|
||||
}
|
||||
@@ -283,16 +283,16 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
void testGetTargetPosition() throws InterruptedException {
|
||||
Thread.sleep(10 * 1000); // Sleeping because sometimes the db is not yet completely ready and the lsn is not found
|
||||
// check that getTargetPosition returns higher Lsn after inserting new row
|
||||
Lsn firstLsn = MssqlCdcTargetPosition.getTargetPosition(testJdbcDatabase, dbName).targetLsn;
|
||||
final Lsn firstLsn = MssqlCdcTargetPosition.getTargetPosition(testJdbcDatabase, dbName).targetLsn;
|
||||
executeQuery(String.format("USE %s; INSERT INTO %s.%s (%s, %s, %s) VALUES (%s, %s, '%s');",
|
||||
dbName, MODELS_SCHEMA, MODELS_STREAM_NAME, COL_ID, COL_MAKE_ID, COL_MODEL, 910019, 1, "another car"));
|
||||
Thread.sleep(15 * 1000); // 15 seconds to wait for Agent capture job to log cdc change
|
||||
Lsn secondLsn = MssqlCdcTargetPosition.getTargetPosition(testJdbcDatabase, dbName).targetLsn;
|
||||
final Lsn secondLsn = MssqlCdcTargetPosition.getTargetPosition(testJdbcDatabase, dbName).targetLsn;
|
||||
assertTrue(secondLsn.compareTo(firstLsn) > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeCDCColumns(ObjectNode data) {
|
||||
protected void removeCDCColumns(final ObjectNode data) {
|
||||
data.remove(CDC_LSN);
|
||||
data.remove(CDC_UPDATED_AT);
|
||||
data.remove(CDC_DELETED_AT);
|
||||
@@ -303,10 +303,10 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
try {
|
||||
// Sleeping because sometimes the db is not yet completely ready and the lsn is not found
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
} catch (final InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
JdbcDatabase jdbcDatabase = Databases.createStreamingJdbcDatabase(
|
||||
final JdbcDatabase jdbcDatabase = Databases.createStreamingJdbcDatabase(
|
||||
config.get("username").asText(),
|
||||
config.get("password").asText(),
|
||||
String.format("jdbc:sqlserver://%s:%s;databaseName=%s;",
|
||||
@@ -318,19 +318,19 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CdcTargetPosition extractPosition(JsonNode record) {
|
||||
protected CdcTargetPosition extractPosition(final JsonNode record) {
|
||||
return new MssqlCdcTargetPosition(Lsn.valueOf(record.get(CDC_LSN).asText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertNullCdcMetaData(JsonNode data) {
|
||||
protected void assertNullCdcMetaData(final JsonNode data) {
|
||||
assertNull(data.get(CDC_LSN));
|
||||
assertNull(data.get(CDC_UPDATED_AT));
|
||||
assertNull(data.get(CDC_DELETED_AT));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertCdcMetaData(JsonNode data, boolean deletedAtNull) {
|
||||
protected void assertCdcMetaData(final JsonNode data, final boolean deletedAtNull) {
|
||||
assertNotNull(data.get(CDC_LSN));
|
||||
assertNotNull(data.get(CDC_UPDATED_AT));
|
||||
if (deletedAtNull) {
|
||||
@@ -341,9 +341,9 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCdcMetadataColumns(AirbyteStream stream) {
|
||||
ObjectNode jsonSchema = (ObjectNode) stream.getJsonSchema();
|
||||
ObjectNode properties = (ObjectNode) jsonSchema.get("properties");
|
||||
protected void addCdcMetadataColumns(final AirbyteStream stream) {
|
||||
final ObjectNode jsonSchema = (ObjectNode) stream.getJsonSchema();
|
||||
final ObjectNode properties = (ObjectNode) jsonSchema.get("properties");
|
||||
|
||||
final JsonNode stringType = Jsons.jsonNode(ImmutableMap.of("type", "string"));
|
||||
properties.set(CDC_LSN, stringType);
|
||||
@@ -368,7 +368,7 @@ public class CdcMssqlSourceTest extends CdcSourceTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertExpectedStateMessages(List<AirbyteStateMessage> stateMessages) {
|
||||
protected void assertExpectedStateMessages(final List<AirbyteStateMessage> stateMessages) {
|
||||
assertEquals(1, stateMessages.size());
|
||||
assertNotNull(stateMessages.get(0).getData());
|
||||
assertNotNull(stateMessages.get(0).getData().get("cdc_state").get("state").get(MSSQL_CDC_OFFSET));
|
||||
|
||||
@@ -96,7 +96,7 @@ class MssqlSourceTest {
|
||||
assertEquals(CATALOG, actual);
|
||||
}
|
||||
|
||||
private JsonNode getConfig(MSSQLServerContainer<?> db) {
|
||||
private JsonNode getConfig(final MSSQLServerContainer<?> db) {
|
||||
return Jsons.jsonNode(ImmutableMap.builder()
|
||||
.put("host", db.getHost())
|
||||
.put("port", db.getFirstMappedPort())
|
||||
@@ -105,7 +105,7 @@ class MssqlSourceTest {
|
||||
.build());
|
||||
}
|
||||
|
||||
public static Database getDatabase(JsonNode config) {
|
||||
public static Database getDatabase(final JsonNode config) {
|
||||
// todo (cgardens) - rework this abstraction so that we do not have to pass a null into the
|
||||
// constructor. at least explicitly handle it, even if the impl doesn't change.
|
||||
return Databases.createDatabase(
|
||||
|
||||
Reference in New Issue
Block a user