From e9dd995453cc614607156f869afa5333de9214ed Mon Sep 17 00:00:00 2001 From: vipinbhatt Date: Mon, 7 Oct 2024 11:10:38 +0530 Subject: [PATCH] Enable TLS Support (DTS - Specific) --- .../io/cdap/plugin/oracle/OracleAction.java | 2 +- .../cdap/plugin/oracle/OracleConnector.java | 2 +- .../plugin/oracle/OracleConnectorConfig.java | 17 +++- .../cdap/plugin/oracle/OracleConstants.java | 86 +++++++++++++++++-- .../cdap/plugin/oracle/OraclePostAction.java | 2 +- .../io/cdap/plugin/oracle/OracleSource.java | 6 +- .../oracle/OracleFailedConnectionTest.java | 3 +- oracle-plugin/widgets/Oracle-batchsink.json | 20 +++++ oracle-plugin/widgets/Oracle-batchsource.json | 20 +++++ oracle-plugin/widgets/Oracle-connector.json | 20 +++++ 10 files changed, 159 insertions(+), 19 deletions(-) diff --git a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleAction.java b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleAction.java index 9b5331d11..d698e17da 100644 --- a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleAction.java +++ b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleAction.java @@ -57,7 +57,7 @@ public static class OracleActionConfig extends DBSpecificQueryConfig { @Override public String getConnectionString() { - return OracleConstants.getConnectionString(this.connectionType, host, port, database); + return OracleConstants.getConnectionString(this.connectionType, host, port, database, null); } @Override diff --git a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnector.java b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnector.java index bc7907b26..3d2f7399a 100644 --- a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnector.java +++ b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnector.java @@ -126,7 +126,7 @@ protected String getConnectionString(@Nullable String database) { return config.getConnectionString(); } return OracleConstants.getConnectionString(config.getConnectionType(), - config.getHost(), config.getPort(), database); + config.getHost(), config.getPort(), database, config.getSSlMode()); } @Override diff --git a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnectorConfig.java b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnectorConfig.java index a60476bd5..10022364a 100644 --- a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnectorConfig.java +++ b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConnectorConfig.java @@ -43,12 +43,12 @@ public OracleConnectorConfig(String host, int port, String user, String password public OracleConnectorConfig(String host, int port, String user, String password, String jdbcPluginName, String connectionArguments, String connectionType, String database) { - this(host, port, user, password, jdbcPluginName, connectionArguments, connectionType, database, null); + this(host, port, user, password, jdbcPluginName, connectionArguments, connectionType, database, null, null); } public OracleConnectorConfig(String host, int port, String user, String password, String jdbcPluginName, String connectionArguments, String connectionType, String database, - String role) { + String role, Boolean useSSL) { this.host = host; this.port = port; @@ -59,11 +59,12 @@ public OracleConnectorConfig(String host, int port, String user, String password this.connectionType = connectionType; this.database = database; this.role = role; + this.useSSL = useSSL; } @Override public String getConnectionString() { - return OracleConstants.getConnectionString(connectionType, host, getPort(), database); + return OracleConstants.getConnectionString(connectionType, host, getPort(), database, useSSL); } @Name(OracleConstants.CONNECTION_TYPE) @@ -86,6 +87,11 @@ public String getConnectionString() { @Nullable private String transactionIsolationLevel; + @Name(OracleConstants.USE_SSL) + @Description("Turns on SSL encryption. Connection will fail if SSL is not available") + @Nullable + public Boolean useSSL; + @Override protected int getDefaultPort() { return 1521; @@ -103,6 +109,11 @@ public String getDatabase() { return database; } + public Boolean getSSlMode() { + // return false if useSSL is null, otherwise return its value + return useSSL != null && useSSL; + } + @Override public Properties getConnectionArgumentsProperties() { Properties prop = super.getConnectionArgumentsProperties(); diff --git a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConstants.java b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConstants.java index ec44d7b94..dc38f80ac 100644 --- a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConstants.java +++ b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleConstants.java @@ -29,6 +29,10 @@ private OracleConstants() { public static final String PLUGIN_NAME = "Oracle"; public static final String ORACLE_CONNECTION_STRING_SID_FORMAT = "jdbc:oracle:thin:@%s:%s:%s"; public static final String ORACLE_CONNECTION_STRING_SERVICE_NAME_FORMAT = "jdbc:oracle:thin:@//%s:%s/%s"; + // Connection formats to accept protocol (e.g., jdbc:oracle:thin:@://:/) + public static final String ORACLE_CONNECTION_STRING_SID_FORMAT_WITH_PROTOCOL = "jdbc:oracle:thin:@%s:%s:%s/%s"; + public static final String ORACLE_CONNECTION_STRING_SERVICE_NAME_FORMAT_WITH_PROTOCOL = + "jdbc:oracle:thin:@%s://%s:%s/%s"; public static final String ORACLE_CONNECTION_STRING_TNS_FORMAT = "jdbc:oracle:thin:@%s"; public static final String DEFAULT_BATCH_VALUE = "defaultBatchValue"; public static final String DEFAULT_ROW_PREFETCH = "defaultRowPrefetch"; @@ -36,28 +40,92 @@ private OracleConstants() { public static final String CONNECTION_TYPE = "connectionType"; public static final String ROLE = "role"; public static final String NAME_DATABASE = "database"; - public static final String TNS_CONNECTION_TYPE = "TNS"; + public static final String TNS_CONNECTION_TYPE = "tns"; public static final String TRANSACTION_ISOLATION_LEVEL = "transactionIsolationLevel"; + public static final String USE_SSL = "useSSL"; /** - * Returns the Connection String for the given ConnectionType. + * Constructs the Oracle connection string based on the provided connection type, host, port, and database. + * If SSL is enabled, the connection protocol will be "tcps" instead of "tcp". * * @param connectionType TNS/Service/SID * @param host Host name of the oracle server * @param port Port of the oracle server * @param database Database to connect to - * @return Connection String based on the given ConnectionType + * @param useSSL Whether SSL/TLS is required(YES/NO) + * @return Connection String based on the given parameters and connection type. */ public static String getConnectionString(String connectionType, @Nullable String host, @Nullable int port, - String database) { - if (OracleConstants.TNS_CONNECTION_TYPE.equalsIgnoreCase(connectionType)) { - return String.format(OracleConstants.ORACLE_CONNECTION_STRING_TNS_FORMAT, database); + String database, + @Nullable Boolean useSSL) { + // Use protocol as "tcps" when SSL is requested or else use "tcp". + String connectionProtocol; + boolean isSSLEnabled = false; + if (useSSL != null && useSSL) { + connectionProtocol = "tcps"; + isSSLEnabled = true; + } else { + connectionProtocol = "tcp"; } - if (OracleConstants.SERVICE_CONNECTION_TYPE.equalsIgnoreCase(connectionType)) { - return String.format(OracleConstants.ORACLE_CONNECTION_STRING_SERVICE_NAME_FORMAT, - host, port, database); + + switch (connectionType.toLowerCase()) { + case OracleConstants.TNS_CONNECTION_TYPE: + // TNS connection doesn't require protocol + return String.format(OracleConstants.ORACLE_CONNECTION_STRING_TNS_FORMAT, database); + case OracleConstants.SERVICE_CONNECTION_TYPE: + // Create connection string for SERVICE type. + return getConnectionStringWithService(host, port, database, connectionProtocol, isSSLEnabled); + default: + // Default to SID format if no matching case is found. + return getConnectionStringWithSID(host, port, database, connectionProtocol, isSSLEnabled); + } + } + + /** + * Constructs the connection string for a SERVICE connection type. + * + * @param host Host name of the Oracle server. + * @param port Port of the Oracle server. + * @param database Database name to connect to. + * @param connectionProtocol Protocol to use for the connection ("tcp" or "tcps"). + * @param isSSLEnabled Indicates if SSL is enabled. + * @return Formatted connection string for a SERVICE connection. + */ + private static String getConnectionStringWithService(@Nullable String host, + @Nullable int port, + String database, + String connectionProtocol, + boolean isSSLEnabled) { + // Choose the appropriate format based on whether SSL is enabled. + if (isSSLEnabled) { + return String.format(OracleConstants.ORACLE_CONNECTION_STRING_SERVICE_NAME_FORMAT_WITH_PROTOCOL, + connectionProtocol, host, port, database); + } + return String.format(OracleConstants.ORACLE_CONNECTION_STRING_SERVICE_NAME_FORMAT, + host, port, database); + } + + /** + * Constructs the connection string for a SID connection type. + * + * @param host Host name of the Oracle server. + * @param port Port of the Oracle server. + * @param database Database name to connect to. + * @param connectionProtocol Protocol to use for the connection ("tcp" or "tcps"). + * @param isSSLEnabled Indicates if SSL is enabled. + * @return Formatted connection string for a SID connection. + */ + private static String getConnectionStringWithSID(@Nullable String host, + @Nullable int port, + String database, + String connectionProtocol, + boolean isSSLEnabled) { + // Choose the appropriate format based on whether SSL is enabled. + if (isSSLEnabled) { + return String.format(OracleConstants.ORACLE_CONNECTION_STRING_SID_FORMAT_WITH_PROTOCOL, + connectionProtocol, host, port, database); } return String.format(OracleConstants.ORACLE_CONNECTION_STRING_SID_FORMAT, host, port, database); diff --git a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OraclePostAction.java b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OraclePostAction.java index 4862aebfa..e11e455c1 100644 --- a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OraclePostAction.java +++ b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OraclePostAction.java @@ -57,7 +57,7 @@ public static class OracleQueryActionConfig extends DBSpecificQueryActionConfig @Override public String getConnectionString() { - return OracleConstants.getConnectionString(this.connectionType, host, port, database); + return OracleConstants.getConnectionString(this.connectionType, host, port, database, null); } @Override diff --git a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleSource.java b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleSource.java index eca7e2532..6df62e63e 100644 --- a/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleSource.java +++ b/oracle-plugin/src/main/java/io/cdap/plugin/oracle/OracleSource.java @@ -117,9 +117,9 @@ public OracleSourceConfig(String host, int port, String user, String password, S String connectionArguments, String connectionType, String database, String role, int defaultBatchValue, int defaultRowPrefetch, String importQuery, Integer numSplits, int fetchSize, - String boundingQuery, String splitBy) { + String boundingQuery, String splitBy, Boolean useSSL) { this.connection = new OracleConnectorConfig(host, port, user, password, jdbcPluginName, connectionArguments, - connectionType, database, role); + connectionType, database, role, useSSL); this.defaultBatchValue = defaultBatchValue; this.defaultRowPrefetch = defaultRowPrefetch; this.fetchSize = fetchSize; @@ -132,7 +132,7 @@ public OracleSourceConfig(String host, int port, String user, String password, S @Override public String getConnectionString() { return OracleConstants.getConnectionString(connection.getConnectionType(), connection.getHost(), - connection.getPort(), connection.getDatabase()); + connection.getPort(), connection.getDatabase(), connection.getSSlMode()); } @Override diff --git a/oracle-plugin/src/test/java/io/cdap/plugin/oracle/OracleFailedConnectionTest.java b/oracle-plugin/src/test/java/io/cdap/plugin/oracle/OracleFailedConnectionTest.java index a2c9bcd5e..7ec6f3844 100644 --- a/oracle-plugin/src/test/java/io/cdap/plugin/oracle/OracleFailedConnectionTest.java +++ b/oracle-plugin/src/test/java/io/cdap/plugin/oracle/OracleFailedConnectionTest.java @@ -28,7 +28,8 @@ public class OracleFailedConnectionTest extends DBSpecificFailedConnectionTest { public void test() throws ClassNotFoundException, IOException { OracleConnector connector = new OracleConnector( - new OracleConnectorConfig("localhost", 1521, "username", "password", "jdbc", "", "database")); + new OracleConnectorConfig("localhost", 1521, "username", "password", "jdbc", "", + "SID", "database")); super.test(JDBC_DRIVER_CLASS_NAME, connector, "Failed to create connection to database via connection string:" + " jdbc:oracle:thin:@localhost:1521:database and arguments: " + diff --git a/oracle-plugin/widgets/Oracle-batchsink.json b/oracle-plugin/widgets/Oracle-batchsink.json index 30d5b345f..8d6168780 100644 --- a/oracle-plugin/widgets/Oracle-batchsink.json +++ b/oracle-plugin/widgets/Oracle-batchsink.json @@ -100,6 +100,26 @@ "default": "TRANSACTION_SERIALIZABLE" } }, + { + "widget-type": "hidden", + "label": "TLS Encryption", + "name": "useSSL", + "description": "Enable TLS encryption (true/false)", + "widget-attributes": { + "layout": "inline", + "default": "false", + "options": [ + { + "id": "true", + "label": "true" + }, + { + "id": "false", + "label": "false" + } + ] + } + }, { "name": "connectionType", "label": "Connection Type", diff --git a/oracle-plugin/widgets/Oracle-batchsource.json b/oracle-plugin/widgets/Oracle-batchsource.json index 0fc0a5285..5eca20cc4 100644 --- a/oracle-plugin/widgets/Oracle-batchsource.json +++ b/oracle-plugin/widgets/Oracle-batchsource.json @@ -100,6 +100,26 @@ "default": "TRANSACTION_SERIALIZABLE" } }, + { + "widget-type": "hidden", + "label": "TLS Encryption", + "name": "useSSL", + "description": "Enable TLS encryption (true/false)", + "widget-attributes": { + "layout": "inline", + "default": "false", + "options": [ + { + "id": "true", + "label": "true" + }, + { + "id": "false", + "label": "false" + } + ] + } + }, { "name": "connectionType", "label": "Connection Type", diff --git a/oracle-plugin/widgets/Oracle-connector.json b/oracle-plugin/widgets/Oracle-connector.json index 46f006c9c..628027caf 100644 --- a/oracle-plugin/widgets/Oracle-connector.json +++ b/oracle-plugin/widgets/Oracle-connector.json @@ -109,6 +109,26 @@ ], "default": "TRANSACTION_SERIALIZABLE" } + }, + { + "widget-type": "hidden", + "label": "TLS Encryption", + "name": "useSSL", + "description": "Enable TLS encryption (true/false)", + "widget-attributes": { + "layout": "inline", + "default": "false", + "options": [ + { + "id": "true", + "label": "true" + }, + { + "id": "false", + "label": "false" + } + ] + } } ] },