Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎉 Source Oracle: Use Service Name to connect to database #14953

Merged
merged 7 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 34 additions & 5 deletions airbyte-config/init/src/main/resources/seed/source_specs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -6307,7 +6307,6 @@
required:
- "host"
- "port"
- "sid"
- "username"
properties:
host:
Expand All @@ -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."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion airbyte-integrations/connectors/source-oracle/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public class OracleSource extends AbstractJdbcSource<JDBCType> 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
Expand Down Expand Up @@ -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<Object, Object> configBuilder = ImmutableMap.builder()
.put(JdbcUtils.USERNAME_KEY, config.get(JdbcUtils.USERNAME_KEY).asText())
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -21,10 +21,53 @@
"default": 1521,
"order": 2
},
"sid": {
"title": "SID (Oracle System Identifier)",
"type": "string",
"order": 3
"connection_data": {
"title": "Connect by",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot from 2022-07-25 14-25-40

"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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -117,7 +117,9 @@ public ImmutableMap.Builder<Object, Object> 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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 + " )")));
Expand All @@ -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)";
Expand Down Expand Up @@ -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 + " )")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
""";
Expand Down Expand Up @@ -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));
}

Expand Down
5 changes: 3 additions & 2 deletions docs/integrations/sources/oracle.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down