Skip to content

Commit 6e53a57

Browse files
VitaliiMaltsevvmaltsev
and
vmaltsev
authored
🐛 Destination Oracle: maxStringLength should be 128 (#6611)
* revert back to 128 characters in OracleNameTransformer | Create Custom OracleContainer * update to 0.1.9 Co-authored-by: vmaltsev <[email protected]>
1 parent 00b43df commit 6e53a57

File tree

8 files changed

+209
-7
lines changed

8 files changed

+209
-7
lines changed

Diff for: airbyte-config/init/src/main/resources/config/STANDARD_DESTINATION_DEFINITION/3986776d-2319-4de9-8af8-db14c0996e72.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
"destinationDefinitionId": "3986776d-2319-4de9-8af8-db14c0996e72",
33
"name": "Oracle (Alpha)",
44
"dockerRepository": "airbyte/destination-oracle",
5-
"dockerImageTag": "0.1.8",
5+
"dockerImageTag": "0.1.9",
66
"documentationUrl": "https://docs.airbyte.io/integrations/destinations/oracle"
77
}

Diff for: airbyte-config/init/src/main/resources/seed/destination_definitions.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
- destinationDefinitionId: 3986776d-2319-4de9-8af8-db14c0996e72
7474
name: Oracle (Alpha)
7575
dockerRepository: airbyte/destination-oracle
76-
dockerImageTag: 0.1.8
76+
dockerImageTag: 0.1.9
7777
documentationUrl: https://docs.airbyte.io/integrations/destinations/oracle
7878
- destinationDefinitionId: 9f760101-60ae-462f-9ee6-b7a9dafd454d
7979
name: Kafka

Diff for: airbyte-integrations/connectors/destination-oracle/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ COPY build/distributions/${APPLICATION}*.tar ${APPLICATION}.tar
88

99
RUN tar xf ${APPLICATION}.tar --strip-components=1
1010

11-
LABEL io.airbyte.version=0.1.8
11+
LABEL io.airbyte.version=0.1.9
1212
LABEL io.airbyte.name=airbyte/destination-oracle

Diff for: airbyte-integrations/connectors/destination-oracle/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ dependencies {
2222
implementation "com.oracle.database.jdbc:ojdbc8-production:19.7.0.0"
2323

2424
testImplementation 'org.apache.commons:commons-lang3:3.11'
25-
testImplementation 'org.testcontainers:oracle-xe:1.15.2'
25+
testImplementation 'org.testcontainers:oracle-xe:1.16.0'
2626

2727
integrationTestJavaImplementation project(':airbyte-integrations:bases:standard-destination-test')
2828
integrationTestJavaImplementation project(':airbyte-integrations:connectors:destination-oracle')

Diff for: airbyte-integrations/connectors/destination-oracle/src/main/java/io/airbyte/integrations/destination/oracle/OracleNameTransformer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public String convertStreamName(String input) {
4141
}
4242
// prior to Oracle version 12.2, identifiers are not allowed to exceed 30 characters in length.
4343
// However, from version 12.2 they can be up to 128 bytes long. (Note: bytes, not characters).
44-
return maxStringLength(result, 30);
44+
return maxStringLength(result, 128);
4545
}
4646

4747
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
* Copyright (c) 2021 Airbyte, Inc., all rights reserved.
3+
*/
4+
5+
package io.airbyte.integrations.destination.oracle;
6+
7+
import static java.time.temporal.ChronoUnit.SECONDS;
8+
import static java.util.Collections.singleton;
9+
10+
import java.time.Duration;
11+
import java.util.Arrays;
12+
import java.util.List;
13+
import java.util.Set;
14+
import java.util.concurrent.Future;
15+
import org.apache.commons.lang3.StringUtils;
16+
import org.testcontainers.containers.JdbcDatabaseContainer;
17+
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
18+
import org.testcontainers.utility.DockerImageName;
19+
20+
public class OracleContainer extends JdbcDatabaseContainer<OracleContainer> {
21+
22+
public static final String NAME = "oracle";
23+
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gvenzl/oracle-xe");
24+
25+
static final String DEFAULT_TAG = "18.4.0-slim";
26+
static final String IMAGE = DEFAULT_IMAGE_NAME.getUnversionedPart();
27+
28+
private static final int ORACLE_PORT = 1521;
29+
private static final int APEX_HTTP_PORT = 8080;
30+
31+
private static final int DEFAULT_STARTUP_TIMEOUT_SECONDS = 240;
32+
private static final int DEFAULT_CONNECT_TIMEOUT_SECONDS = 120;
33+
34+
// Container defaults
35+
static final String DEFAULT_DATABASE_NAME = "xepdb1";
36+
static final String DEFAULT_SID = "xe";
37+
static final String DEFAULT_SYSTEM_USER = "system";
38+
static final String DEFAULT_SYS_USER = "sys";
39+
40+
// Test container defaults
41+
static final String APP_USER = "test";
42+
static final String APP_USER_PASSWORD = "test";
43+
44+
// Restricted user and database names
45+
private static final List<String> ORACLE_SYSTEM_USERS = Arrays.asList(DEFAULT_SYSTEM_USER, DEFAULT_SYS_USER);
46+
47+
private String databaseName = DEFAULT_DATABASE_NAME;
48+
private String username = APP_USER;
49+
private String password = APP_USER_PASSWORD;
50+
private boolean usingSid = false;
51+
52+
public OracleContainer() {
53+
this(DEFAULT_IMAGE_NAME.withTag(DEFAULT_TAG));
54+
}
55+
56+
public OracleContainer(String dockerImageName) {
57+
this(DockerImageName.parse(dockerImageName));
58+
}
59+
60+
public OracleContainer(final DockerImageName dockerImageName) {
61+
super(dockerImageName);
62+
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
63+
preconfigure();
64+
}
65+
66+
public OracleContainer(Future<String> dockerImageName) {
67+
super(dockerImageName);
68+
preconfigure();
69+
}
70+
71+
private void preconfigure() {
72+
this.waitStrategy = new LogMessageWaitStrategy()
73+
.withRegEx(".*DATABASE IS READY TO USE!.*\\s")
74+
.withTimes(1)
75+
.withStartupTimeout(Duration.of(DEFAULT_STARTUP_TIMEOUT_SECONDS, SECONDS));
76+
77+
withConnectTimeoutSeconds(DEFAULT_CONNECT_TIMEOUT_SECONDS);
78+
addExposedPorts(ORACLE_PORT, APEX_HTTP_PORT);
79+
}
80+
81+
@Override
82+
protected void waitUntilContainerStarted() {
83+
getWaitStrategy().waitUntilReady(this);
84+
}
85+
86+
@Override
87+
public Set<Integer> getLivenessCheckPortNumbers() {
88+
return singleton(getMappedPort(ORACLE_PORT));
89+
}
90+
91+
@Override
92+
public String getDriverClassName() {
93+
return "oracle.jdbc.OracleDriver";
94+
}
95+
96+
@Override
97+
public String getJdbcUrl() {
98+
return isUsingSid() ? "jdbc:oracle:thin:" + "@" + getHost() + ":" + getOraclePort() + ":" + getSid()
99+
: "jdbc:oracle:thin:" + "@" + getHost() + ":" + getOraclePort() + "/" + getDatabaseName();
100+
}
101+
102+
@Override
103+
public String getUsername() {
104+
// An application user is tied to the database, and therefore not authenticated to connect to SID.
105+
return isUsingSid() ? DEFAULT_SYSTEM_USER : username;
106+
}
107+
108+
@Override
109+
public String getPassword() {
110+
return password;
111+
}
112+
113+
@Override
114+
public String getDatabaseName() {
115+
return databaseName;
116+
}
117+
118+
protected boolean isUsingSid() {
119+
return usingSid;
120+
}
121+
122+
@Override
123+
public OracleContainer withUsername(String username) {
124+
if (StringUtils.isEmpty(username)) {
125+
throw new IllegalArgumentException("Username cannot be null or empty");
126+
}
127+
if (ORACLE_SYSTEM_USERS.contains(username.toLowerCase())) {
128+
throw new IllegalArgumentException("Username cannot be one of " + ORACLE_SYSTEM_USERS);
129+
}
130+
this.username = username;
131+
return self();
132+
}
133+
134+
@Override
135+
public OracleContainer withPassword(String password) {
136+
if (StringUtils.isEmpty(password)) {
137+
throw new IllegalArgumentException("Password cannot be null or empty");
138+
}
139+
this.password = password;
140+
return self();
141+
}
142+
143+
@Override
144+
public OracleContainer withDatabaseName(String databaseName) {
145+
if (StringUtils.isEmpty(databaseName)) {
146+
throw new IllegalArgumentException("Database name cannot be null or empty");
147+
}
148+
149+
if (DEFAULT_DATABASE_NAME.equals(databaseName.toLowerCase())) {
150+
throw new IllegalArgumentException("Database name cannot be set to " + DEFAULT_DATABASE_NAME);
151+
}
152+
153+
this.databaseName = databaseName;
154+
return self();
155+
}
156+
157+
public OracleContainer usingSid() {
158+
this.usingSid = true;
159+
return self();
160+
}
161+
162+
@Override
163+
public OracleContainer withUrlParam(String paramName, String paramValue) {
164+
throw new UnsupportedOperationException("The Oracle Database driver does not support this");
165+
}
166+
167+
@SuppressWarnings("SameReturnValue")
168+
public String getSid() {
169+
return DEFAULT_SID;
170+
}
171+
172+
public Integer getOraclePort() {
173+
return getMappedPort(ORACLE_PORT);
174+
}
175+
176+
@SuppressWarnings("unused")
177+
public Integer getWebPort() {
178+
return getMappedPort(APEX_HTTP_PORT);
179+
}
180+
181+
@Override
182+
public String getTestQueryString() {
183+
return "SELECT 1 FROM DUAL";
184+
}
185+
186+
@Override
187+
protected void configure() {
188+
withEnv("ORACLE_PASSWORD", password);
189+
190+
// Only set ORACLE_DATABASE if different than the default.
191+
if (databaseName != DEFAULT_DATABASE_NAME) {
192+
withEnv("ORACLE_DATABASE", databaseName);
193+
}
194+
195+
withEnv("APP_USER", username);
196+
withEnv("APP_USER_PASSWORD", password);
197+
}
198+
199+
}

Diff for: airbyte-integrations/connectors/destination-oracle/src/test-integration/java/io/airbyte/integrations/destination/oracle/SshOracleDestinationAcceptanceTest.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.util.stream.Collectors;
2424
import org.jooq.JSONFormat;
2525
import org.testcontainers.containers.Network;
26-
import org.testcontainers.containers.OracleContainer;
2726

2827
public abstract class SshOracleDestinationAcceptanceTest extends DestinationAcceptanceTest {
2928

@@ -135,7 +134,10 @@ private void startTestContainers() {
135134
}
136135

137136
private void initAndStartJdbcContainer() {
138-
db = new OracleContainer("epiclabs/docker-oracle-xe-11g")
137+
db = new OracleContainer()
138+
.withUsername("test")
139+
.withPassword("oracle")
140+
.usingSid()
139141
.withNetwork(sshBastionContainer.getNetWork());
140142
db.start();
141143
}

Diff for: docs/integrations/destinations/oracle.md

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ Using this feature requires additional configuration, when creating the source.
8181
## Changelog
8282
| Version | Date | Pull Request | Subject |
8383
| :--- | :--- | :--- | :--- |
84+
| 0.1.9 | 2021-10-06 | [#6611](https://github.com/airbytehq/airbyte/pull/6611)| 🐛 Destination Oracle: maxStringLength should be 128|
8485
| 0.1.8 | 2021-09-28 | [#6370](https://github.com/airbytehq/airbyte/pull/6370)| Add SSH Support for Oracle Destination |
8586
| 0.1.7 | 2021-08-30 | [#5746](https://github.com/airbytehq/airbyte/pull/5746) | Use default column name for raw tables |
8687
| 0.1.6 | 2021-08-23 | [#5542](https://github.com/airbytehq/airbyte/pull/5542) | Remove support for Oracle 11g to allow normalization |

0 commit comments

Comments
 (0)