Skip to content

Commit

Permalink
🐛 Destination Oracle: maxStringLength should be 128 (#6611)
Browse files Browse the repository at this point in the history
* revert back to 128 characters in OracleNameTransformer | Create Custom OracleContainer

* update to 0.1.9

Co-authored-by: vmaltsev <[email protected]>
  • Loading branch information
VitaliiMaltsev and vmaltsev authored Oct 6, 2021
1 parent 00b43df commit 6e53a57
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"destinationDefinitionId": "3986776d-2319-4de9-8af8-db14c0996e72",
"name": "Oracle (Alpha)",
"dockerRepository": "airbyte/destination-oracle",
"dockerImageTag": "0.1.8",
"dockerImageTag": "0.1.9",
"documentationUrl": "https://docs.airbyte.io/integrations/destinations/oracle"
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
- destinationDefinitionId: 3986776d-2319-4de9-8af8-db14c0996e72
name: Oracle (Alpha)
dockerRepository: airbyte/destination-oracle
dockerImageTag: 0.1.8
dockerImageTag: 0.1.9
documentationUrl: https://docs.airbyte.io/integrations/destinations/oracle
- destinationDefinitionId: 9f760101-60ae-462f-9ee6-b7a9dafd454d
name: Kafka
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ COPY build/distributions/${APPLICATION}*.tar ${APPLICATION}.tar

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

LABEL io.airbyte.version=0.1.8
LABEL io.airbyte.version=0.1.9
LABEL io.airbyte.name=airbyte/destination-oracle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies {
implementation "com.oracle.database.jdbc:ojdbc8-production:19.7.0.0"

testImplementation 'org.apache.commons:commons-lang3:3.11'
testImplementation 'org.testcontainers:oracle-xe:1.15.2'
testImplementation 'org.testcontainers:oracle-xe:1.16.0'

integrationTestJavaImplementation project(':airbyte-integrations:bases:standard-destination-test')
integrationTestJavaImplementation project(':airbyte-integrations:connectors:destination-oracle')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public String convertStreamName(String input) {
}
// prior to Oracle version 12.2, identifiers are not allowed to exceed 30 characters in length.
// However, from version 12.2 they can be up to 128 bytes long. (Note: bytes, not characters).
return maxStringLength(result, 30);
return maxStringLength(result, 128);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/*
* Copyright (c) 2021 Airbyte, Inc., all rights reserved.
*/

package io.airbyte.integrations.destination.oracle;

import static java.time.temporal.ChronoUnit.SECONDS;
import static java.util.Collections.singleton;

import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Future;
import org.apache.commons.lang3.StringUtils;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
import org.testcontainers.utility.DockerImageName;

public class OracleContainer extends JdbcDatabaseContainer<OracleContainer> {

public static final String NAME = "oracle";
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gvenzl/oracle-xe");

static final String DEFAULT_TAG = "18.4.0-slim";
static final String IMAGE = DEFAULT_IMAGE_NAME.getUnversionedPart();

private static final int ORACLE_PORT = 1521;
private static final int APEX_HTTP_PORT = 8080;

private static final int DEFAULT_STARTUP_TIMEOUT_SECONDS = 240;
private static final int DEFAULT_CONNECT_TIMEOUT_SECONDS = 120;

// Container defaults
static final String DEFAULT_DATABASE_NAME = "xepdb1";
static final String DEFAULT_SID = "xe";
static final String DEFAULT_SYSTEM_USER = "system";
static final String DEFAULT_SYS_USER = "sys";

// Test container defaults
static final String APP_USER = "test";
static final String APP_USER_PASSWORD = "test";

// Restricted user and database names
private static final List<String> ORACLE_SYSTEM_USERS = Arrays.asList(DEFAULT_SYSTEM_USER, DEFAULT_SYS_USER);

private String databaseName = DEFAULT_DATABASE_NAME;
private String username = APP_USER;
private String password = APP_USER_PASSWORD;
private boolean usingSid = false;

public OracleContainer() {
this(DEFAULT_IMAGE_NAME.withTag(DEFAULT_TAG));
}

public OracleContainer(String dockerImageName) {
this(DockerImageName.parse(dockerImageName));
}

public OracleContainer(final DockerImageName dockerImageName) {
super(dockerImageName);
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
preconfigure();
}

public OracleContainer(Future<String> dockerImageName) {
super(dockerImageName);
preconfigure();
}

private void preconfigure() {
this.waitStrategy = new LogMessageWaitStrategy()
.withRegEx(".*DATABASE IS READY TO USE!.*\\s")
.withTimes(1)
.withStartupTimeout(Duration.of(DEFAULT_STARTUP_TIMEOUT_SECONDS, SECONDS));

withConnectTimeoutSeconds(DEFAULT_CONNECT_TIMEOUT_SECONDS);
addExposedPorts(ORACLE_PORT, APEX_HTTP_PORT);
}

@Override
protected void waitUntilContainerStarted() {
getWaitStrategy().waitUntilReady(this);
}

@Override
public Set<Integer> getLivenessCheckPortNumbers() {
return singleton(getMappedPort(ORACLE_PORT));
}

@Override
public String getDriverClassName() {
return "oracle.jdbc.OracleDriver";
}

@Override
public String getJdbcUrl() {
return isUsingSid() ? "jdbc:oracle:thin:" + "@" + getHost() + ":" + getOraclePort() + ":" + getSid()
: "jdbc:oracle:thin:" + "@" + getHost() + ":" + getOraclePort() + "/" + getDatabaseName();
}

@Override
public String getUsername() {
// An application user is tied to the database, and therefore not authenticated to connect to SID.
return isUsingSid() ? DEFAULT_SYSTEM_USER : username;
}

@Override
public String getPassword() {
return password;
}

@Override
public String getDatabaseName() {
return databaseName;
}

protected boolean isUsingSid() {
return usingSid;
}

@Override
public OracleContainer withUsername(String username) {
if (StringUtils.isEmpty(username)) {
throw new IllegalArgumentException("Username cannot be null or empty");
}
if (ORACLE_SYSTEM_USERS.contains(username.toLowerCase())) {
throw new IllegalArgumentException("Username cannot be one of " + ORACLE_SYSTEM_USERS);
}
this.username = username;
return self();
}

@Override
public OracleContainer withPassword(String password) {
if (StringUtils.isEmpty(password)) {
throw new IllegalArgumentException("Password cannot be null or empty");
}
this.password = password;
return self();
}

@Override
public OracleContainer withDatabaseName(String databaseName) {
if (StringUtils.isEmpty(databaseName)) {
throw new IllegalArgumentException("Database name cannot be null or empty");
}

if (DEFAULT_DATABASE_NAME.equals(databaseName.toLowerCase())) {
throw new IllegalArgumentException("Database name cannot be set to " + DEFAULT_DATABASE_NAME);
}

this.databaseName = databaseName;
return self();
}

public OracleContainer usingSid() {
this.usingSid = true;
return self();
}

@Override
public OracleContainer withUrlParam(String paramName, String paramValue) {
throw new UnsupportedOperationException("The Oracle Database driver does not support this");
}

@SuppressWarnings("SameReturnValue")
public String getSid() {
return DEFAULT_SID;
}

public Integer getOraclePort() {
return getMappedPort(ORACLE_PORT);
}

@SuppressWarnings("unused")
public Integer getWebPort() {
return getMappedPort(APEX_HTTP_PORT);
}

@Override
public String getTestQueryString() {
return "SELECT 1 FROM DUAL";
}

@Override
protected void configure() {
withEnv("ORACLE_PASSWORD", password);

// Only set ORACLE_DATABASE if different than the default.
if (databaseName != DEFAULT_DATABASE_NAME) {
withEnv("ORACLE_DATABASE", databaseName);
}

withEnv("APP_USER", username);
withEnv("APP_USER_PASSWORD", password);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.stream.Collectors;
import org.jooq.JSONFormat;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.OracleContainer;

public abstract class SshOracleDestinationAcceptanceTest extends DestinationAcceptanceTest {

Expand Down Expand Up @@ -135,7 +134,10 @@ private void startTestContainers() {
}

private void initAndStartJdbcContainer() {
db = new OracleContainer("epiclabs/docker-oracle-xe-11g")
db = new OracleContainer()
.withUsername("test")
.withPassword("oracle")
.usingSid()
.withNetwork(sshBastionContainer.getNetWork());
db.start();
}
Expand Down
1 change: 1 addition & 0 deletions docs/integrations/destinations/oracle.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Using this feature requires additional configuration, when creating the source.
## Changelog
| Version | Date | Pull Request | Subject |
| :--- | :--- | :--- | :--- |
| 0.1.9 | 2021-10-06 | [#6611](https://github.com/airbytehq/airbyte/pull/6611)| 🐛 Destination Oracle: maxStringLength should be 128|
| 0.1.8 | 2021-09-28 | [#6370](https://github.com/airbytehq/airbyte/pull/6370)| Add SSH Support for Oracle Destination |
| 0.1.7 | 2021-08-30 | [#5746](https://github.com/airbytehq/airbyte/pull/5746) | Use default column name for raw tables |
| 0.1.6 | 2021-08-23 | [#5542](https://github.com/airbytehq/airbyte/pull/5542) | Remove support for Oracle 11g to allow normalization |
Expand Down

0 comments on commit 6e53a57

Please sign in to comment.