diff --git a/airbyte-config/init/src/main/resources/seed/source_definitions.yaml b/airbyte-config/init/src/main/resources/seed/source_definitions.yaml index 92746b09a109..bf3cf9c796bb 100644 --- a/airbyte-config/init/src/main/resources/seed/source_definitions.yaml +++ b/airbyte-config/init/src/main/resources/seed/source_definitions.yaml @@ -651,7 +651,7 @@ - name: Oracle DB sourceDefinitionId: b39a7370-74c3-45a6-ac3a-380d48520a83 dockerRepository: airbyte/source-oracle - dockerImageTag: 0.3.18 + dockerImageTag: 0.3.19 documentationUrl: https://docs.airbyte.io/integrations/sources/oracle icon: oracle.svg sourceType: database diff --git a/airbyte-config/init/src/main/resources/seed/source_specs.yaml b/airbyte-config/init/src/main/resources/seed/source_specs.yaml index 706ea22da4d0..f0379bcf9f4a 100644 --- a/airbyte-config/init/src/main/resources/seed/source_specs.yaml +++ b/airbyte-config/init/src/main/resources/seed/source_specs.yaml @@ -6297,7 +6297,7 @@ supportsNormalization: false supportsDBT: false supported_destination_sync_modes: [] -- dockerImage: "airbyte/source-oracle:0.3.18" +- dockerImage: "airbyte/source-oracle:0.3.19" spec: documentationUrl: "https://docs.airbyte.io/integrations/sources/oracle" connectionSpecification: @@ -6307,7 +6307,6 @@ required: - "host" - "port" - - "sid" - "username" properties: host: @@ -6326,10 +6325,40 @@ maximum: 65536 default: 1521 order: 2 - sid: - title: "SID (Oracle System Identifier)" - type: "string" + connection_data: + title: "Connect by" + type: "object" + description: "Connect data that will be used for DB connection" order: 3 + oneOf: + - title: "Service name" + description: "Use service name" + required: + - "service_name" + properties: + connection_type: + type: "string" + const: "service_name" + default: "service_name" + order: 0 + service_name: + title: "Service name" + type: "string" + order: 1 + - title: "System ID (SID)" + description: "Use SID (Oracle System Identifier)" + required: + - "sid" + properties: + connection_type: + type: "string" + const: "sid" + default: "sid" + order: 0 + sid: + title: "System ID (SID)" + type: "string" + order: 1 username: title: "User" description: "The username which is used to access the database." diff --git a/airbyte-integrations/connectors/source-oracle-strict-encrypt/Dockerfile b/airbyte-integrations/connectors/source-oracle-strict-encrypt/Dockerfile index 030f9909887a..a9259e058681 100644 --- a/airbyte-integrations/connectors/source-oracle-strict-encrypt/Dockerfile +++ b/airbyte-integrations/connectors/source-oracle-strict-encrypt/Dockerfile @@ -17,5 +17,5 @@ ENV TZ UTC COPY --from=build /airbyte /airbyte -LABEL io.airbyte.version=0.3.16 +LABEL io.airbyte.version=0.3.17 LABEL io.airbyte.name=airbyte/source-oracle-strict-encrypt diff --git a/airbyte-integrations/connectors/source-oracle-strict-encrypt/src/test/resources/expected_spec.json b/airbyte-integrations/connectors/source-oracle-strict-encrypt/src/test/resources/expected_spec.json index 4c0c66c1d5af..17e68834058f 100644 --- a/airbyte-integrations/connectors/source-oracle-strict-encrypt/src/test/resources/expected_spec.json +++ b/airbyte-integrations/connectors/source-oracle-strict-encrypt/src/test/resources/expected_spec.json @@ -4,7 +4,7 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Oracle Source Spec", "type": "object", - "required": ["host", "port", "sid", "username", "encryption"], + "required": ["host", "port", "username", "encryption"], "properties": { "host": { "title": "Host", @@ -21,10 +21,53 @@ "default": 1521, "order": 2 }, - "sid": { - "title": "SID (Oracle System Identifier)", - "type": "string", - "order": 3 + "connection_data": { + "title": "Connect by", + "type": "object", + "description": "Connect data that will be used for DB connection", + "order": 3, + "oneOf": [ + { + "title": "Service name", + "description": "Use service name", + "required": [ + "service_name" + ], + "properties": { + "connection_type": { + "type": "string", + "const": "service_name", + "default": "service_name", + "order": 0 + }, + "service_name": { + "title": "Service name", + "type": "string", + "order": 1 + } + } + }, + { + "title": "System ID (SID)", + "description": "Use SID (Oracle System Identifier)", + "required": [ + "sid" + ], + "properties": { + "connection_type": { + "type": "string", + "const": "sid", + "default": "sid", + "order": 0 + }, + "sid": { + "title": "System ID (SID)", + "type": "string", + "order": 1 + } + } + } + ] }, "username": { "title": "User", diff --git a/airbyte-integrations/connectors/source-oracle/Dockerfile b/airbyte-integrations/connectors/source-oracle/Dockerfile index 2e6f9348df76..a10075770570 100644 --- a/airbyte-integrations/connectors/source-oracle/Dockerfile +++ b/airbyte-integrations/connectors/source-oracle/Dockerfile @@ -8,5 +8,5 @@ ENV TZ UTC COPY build/distributions/${APPLICATION}*.tar ${APPLICATION}.tar RUN tar xf ${APPLICATION}.tar --strip-components=1 -LABEL io.airbyte.version=0.3.18 +LABEL io.airbyte.version=0.3.19 LABEL io.airbyte.name=airbyte/source-oracle diff --git a/airbyte-integrations/connectors/source-oracle/src/main/java/io/airbyte/integrations/source/oracle/OracleSource.java b/airbyte-integrations/connectors/source-oracle/src/main/java/io/airbyte/integrations/source/oracle/OracleSource.java index 100f19cb619b..d0b084d45ce1 100644 --- a/airbyte-integrations/connectors/source-oracle/src/main/java/io/airbyte/integrations/source/oracle/OracleSource.java +++ b/airbyte-integrations/connectors/source-oracle/src/main/java/io/airbyte/integrations/source/oracle/OracleSource.java @@ -41,6 +41,11 @@ public class OracleSource extends AbstractJdbcSource implements Source private static final String KEY_STORE_FILE_PATH = "clientkeystore.jks"; private static final String KEY_STORE_PASS = RandomStringUtils.randomAlphanumeric(8); + private static final String SID = "sid"; + private static final String SERVICE_NAME = "service_name"; + private static final String UNRECOGNIZED = "Unrecognized"; + private static final String CONNECTION_DATA = "connection_data"; + enum Protocol { TCP, TCPS @@ -70,12 +75,21 @@ public JsonNode toDatabaseConfig(final JsonNode config) { final Protocol protocol = config.has(JdbcUtils.ENCRYPTION_KEY) ? obtainConnectionProtocol(config.get(JdbcUtils.ENCRYPTION_KEY), additionalParameters) : Protocol.TCP; - final String connectionString = String.format( - "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=%s)(HOST=%s)(PORT=%s))(CONNECT_DATA=(SID=%s)))", - protocol, - config.get(JdbcUtils.HOST_KEY).asText(), - config.get(JdbcUtils.PORT_KEY).asText(), - config.get("sid").asText()); + String connectionString; + if (config.has(CONNECTION_DATA)) { + JsonNode connectionData = config.get(CONNECTION_DATA); + final String connectionType = connectionData.has("connection_type") ? connectionData.get("connection_type").asText() + : UNRECOGNIZED; + connectionString = switch (connectionType) { + case SERVICE_NAME -> buildConnectionString(config, protocol.toString(), SERVICE_NAME.toUpperCase(), config.get(CONNECTION_DATA).get(SERVICE_NAME).asText()); + case SID -> buildConnectionString(config, protocol.toString(), SID.toUpperCase(), config.get(CONNECTION_DATA).get(SID).asText()); + default -> throw new IllegalArgumentException("Unrecognized connection type: " + connectionType); + }; + } else { + // To keep backward compatibility with existing connectors which doesn't have connection_data + // and use only sid. + connectionString = buildConnectionString(config, protocol.toString(), SID.toUpperCase(), config.get(SID).asText()); + } final ImmutableMap.Builder configBuilder = ImmutableMap.builder() .put(JdbcUtils.USERNAME_KEY, config.get(JdbcUtils.USERNAME_KEY).asText()) @@ -189,4 +203,13 @@ public static void main(final String[] args) throws Exception { LOGGER.info("completed source: {}", OracleSource.class); } + private String buildConnectionString(JsonNode config, String protocol, String connectionTypeName, String connectionTypeValue) { + return String.format( + "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=%s)(HOST=%s)(PORT=%s))(CONNECT_DATA=(%s=%s)))", + protocol, + config.get(JdbcUtils.HOST_KEY).asText(), + config.get(JdbcUtils.PORT_KEY).asText(), + connectionTypeName, + connectionTypeValue); + } } diff --git a/airbyte-integrations/connectors/source-oracle/src/main/resources/spec.json b/airbyte-integrations/connectors/source-oracle/src/main/resources/spec.json index d3bfbdc3a3af..a0fbd7624dc9 100644 --- a/airbyte-integrations/connectors/source-oracle/src/main/resources/spec.json +++ b/airbyte-integrations/connectors/source-oracle/src/main/resources/spec.json @@ -4,7 +4,7 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Oracle Source Spec", "type": "object", - "required": ["host", "port", "sid", "username"], + "required": ["host", "port", "username"], "properties": { "host": { "title": "Host", @@ -21,10 +21,53 @@ "default": 1521, "order": 2 }, - "sid": { - "title": "SID (Oracle System Identifier)", - "type": "string", - "order": 3 + "connection_data": { + "title": "Connect by", + "type": "object", + "description": "Connect data that will be used for DB connection", + "order": 3, + "oneOf": [ + { + "title": "Service name", + "description": "Use service name", + "required": [ + "service_name" + ], + "properties": { + "connection_type": { + "type": "string", + "const": "service_name", + "default": "service_name", + "order": 0 + }, + "service_name": { + "title": "Service name", + "type": "string", + "order": 1 + } + } + }, + { + "title": "System ID (SID)", + "description": "Use SID (Oracle System Identifier)", + "required": [ + "sid" + ], + "properties": { + "connection_type": { + "type": "string", + "const": "sid", + "default": "sid", + "order": 0 + }, + "sid": { + "title": "System ID (SID)", + "type": "string", + "order": 1 + } + } + } + ] }, "username": { "title": "User", diff --git a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/AbstractSshOracleSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/AbstractSshOracleSourceAcceptanceTest.java index dc96e6b1f3ef..3c410eee49a5 100644 --- a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/AbstractSshOracleSourceAcceptanceTest.java +++ b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/AbstractSshOracleSourceAcceptanceTest.java @@ -57,7 +57,7 @@ private void populateDatabaseTestData() throws Exception { String.format(DatabaseDriver.ORACLE.getUrlFormatString(), config.get("host").asText(), config.get("port").asInt(), - config.get("sid").asText())); + config.get("connection_data").get("service_name").asText())); try { final JdbcDatabase database = new DefaultJdbcDatabase(dataSource); @@ -117,7 +117,9 @@ public ImmutableMap.Builder getBasicOracleDbConfigBuider(final O .put("username", db.getUsername()) .put("password", db.getPassword()) .put("port", db.getExposedPorts().get(0)) - .put("sid", db.getSid()) + .put("connection_data", ImmutableMap.builder() + .put("service_name", db.getSid()) + .put("connection_type", "service_name").build()) .put("schemas", List.of("JDBC_SPACE")) .put("encryption", Jsons.jsonNode(ImmutableMap.builder() .put("encryption_method", "unencrypted") diff --git a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceAcceptanceTest.java index 28939a2079f6..1de56a02dde5 100644 --- a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceAcceptanceTest.java +++ b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceAcceptanceTest.java @@ -45,7 +45,9 @@ protected void setupEnvironment(final TestDestinationEnv environment) throws Exc config = Jsons.jsonNode(ImmutableMap.builder() .put("host", container.getHost()) .put("port", container.getFirstMappedPort()) - .put("sid", container.getSid()) + .put("connection_data", ImmutableMap.builder() + .put("service_name", container.getSid()) + .put("connection_type", "service_name").build()) .put("username", container.getUsername()) .put("password", container.getPassword()) .put("schemas", List.of("JDBC_SPACE")) @@ -61,7 +63,7 @@ protected void setupEnvironment(final TestDestinationEnv environment) throws Exc String.format(DatabaseDriver.ORACLE.getUrlFormatString(), config.get("host").asText(), config.get("port").asInt(), - config.get("sid").asText())); + config.get("connection_data").get("service_name").asText())); try { final JdbcDatabase database = new DefaultJdbcDatabase(dataSource); diff --git a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceDatatypeTest.java b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceDatatypeTest.java index 96d65d89512e..64e69c208569 100644 --- a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceDatatypeTest.java +++ b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceDatatypeTest.java @@ -44,7 +44,9 @@ protected Database setupDatabase() throws Exception { config = Jsons.jsonNode(ImmutableMap.builder() .put("host", container.getHost()) .put("port", container.getFirstMappedPort()) - .put("sid", container.getSid()) + .put("connection_data", ImmutableMap.builder() + .put("service_name", container.getSid()) + .put("connection_type", "service_name").build()) .put("username", container.getUsername()) .put("password", container.getPassword()) .put("schemas", List.of("TEST")) @@ -57,7 +59,7 @@ protected Database setupDatabase() throws Exception { String.format(DatabaseDriver.ORACLE.getUrlFormatString(), config.get("host").asText(), config.get("port").asInt(), - config.get("sid").asText()), + config.get("connection_data").get("service_name").asText()), null); final Database database = new Database(dslContext); LOGGER.warn("config: " + config); diff --git a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceNneAcceptanceTest.java b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceNneAcceptanceTest.java index 46474c784459..5a4a31cc0259 100644 --- a/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceNneAcceptanceTest.java +++ b/airbyte-integrations/connectors/source-oracle/src/test-integration/java/io/airbyte/integrations/source/oracle/OracleSourceNneAcceptanceTest.java @@ -41,7 +41,7 @@ public void testEncrytion() throws SQLException { String.format("jdbc:oracle:thin:@//%s:%d/%s", clone.get(JdbcUtils.HOST_KEY).asText(), clone.get(JdbcUtils.PORT_KEY).asInt(), - clone.get("sid").asText()), + clone.get("connection_data").get("service_name").asText()), JdbcUtils.parseJdbcParameters("oracle.net.encryption_client=REQUIRED&" + "oracle.net.encryption_types_client=( " + algorithm + " )"))); @@ -64,7 +64,7 @@ public void testNoneEncrytion() throws SQLException { String.format(DatabaseDriver.ORACLE.getUrlFormatString(), config.get(JdbcUtils.HOST_KEY).asText(), config.get(JdbcUtils.PORT_KEY).asInt(), - config.get("sid").asText()))); + config.get("connection_data").get("service_name").asText()))); final String networkServiceBanner = "select network_service_banner from v$session_connect_info where sid in (select distinct sid from v$mystat)"; @@ -92,7 +92,7 @@ public void testCheckProtocol() throws SQLException { String.format(DatabaseDriver.ORACLE.getUrlFormatString(), config.get(JdbcUtils.HOST_KEY).asText(), config.get(JdbcUtils.PORT_KEY).asInt(), - config.get("sid").asText()), + config.get("connection_data").get("service_name").asText()), JdbcUtils.parseJdbcParameters("oracle.net.encryption_client=REQUIRED&" + "oracle.net.encryption_types_client=( " + algorithm + " )"))); diff --git a/airbyte-integrations/connectors/source-oracle/src/test/java/io/airbyte/integrations/source/oracle/OracleSpecTest.java b/airbyte-integrations/connectors/source-oracle/src/test/java/io/airbyte/integrations/source/oracle/OracleSpecTest.java index 90facba583d0..33888094c0bb 100644 --- a/airbyte-integrations/connectors/source-oracle/src/test/java/io/airbyte/integrations/source/oracle/OracleSpecTest.java +++ b/airbyte-integrations/connectors/source-oracle/src/test/java/io/airbyte/integrations/source/oracle/OracleSpecTest.java @@ -32,12 +32,14 @@ public class OracleSpecTest { { "host": "localhost", "port": 1521, - "sid": "ora_db", "username": "ora", "password": "pwd", "schemas": [ "public" ], + "connection_data": { + "sid": "ora_db" + }, "jdbc_url_params": "property1=pValue1&property2=pValue2" } """; @@ -70,7 +72,7 @@ void testPortMissing() { @Test void testSsidMissing() { final JsonNode config = Jsons.deserialize(CONFIGURATION); - ((ObjectNode) config).remove("sid"); + ((ObjectNode) (config.get("connection_data"))).remove("sid"); assertFalse(validator.test(schema, config)); } diff --git a/docs/integrations/sources/oracle.md b/docs/integrations/sources/oracle.md index 184a0723788b..8e981f82f9a3 100644 --- a/docs/integrations/sources/oracle.md +++ b/docs/integrations/sources/oracle.md @@ -130,8 +130,9 @@ Airbite has the ability to connect to the Oracle source with 3 network connectiv ## Changelog -| Version | Date | Pull Request | Subject | -|:--------| :--- | :--- |:------------------------------------------------| +| Version | Date | Pull Request | Subject | +|:--------|:-----------| :--- |:------------------------------------------------| +| 0.3.19 | 2022-08-03 | [14953](https://github.com/airbytehq/airbyte/pull/14953) | Use Service Name to connect to database | | 0.3.18 | 2022-07-14 | [14574](https://github.com/airbytehq/airbyte/pull/14574) | Removed additionalProperties:false from JDBC source connectors | | 0.3.17 | 2022-06-24 | [14092](https://github.com/airbytehq/airbyte/pull/14092) | Introduced a custom jdbc param field | | 0.3.16 | 2022-06-22 | [13997](https://github.com/airbytehq/airbyte/pull/13997) | Fixed tests |