diff --git a/crates/dbx-core/src/agent_connection.rs b/crates/dbx-core/src/agent_connection.rs index 5aa9672f5..9b5475ea4 100644 --- a/crates/dbx-core/src/agent_connection.rs +++ b/crates/dbx-core/src/agent_connection.rs @@ -59,6 +59,7 @@ pub fn agent_connect_params(config: &ConnectionConfig, host: &str, port: u16, da "ca_cert_path": config.ca_cert_path, "client_cert_path": config.client_cert_path, "client_key_path": config.client_key_path, + "connect_timeout_secs": config.effective_connect_timeout_secs(), "etcd_endpoints": etcd_endpoints, "zookeeper_connect_string": zookeeper_connect_string, "gbase_server": config.gbase_server, @@ -734,6 +735,16 @@ mod tests { assert_eq!(params["connection_timeout_ms"], 20_000); } + #[test] + fn agent_params_include_effective_connect_timeout_seconds() { + let mut cfg = config(DatabaseType::Mysql, Some("app")); + cfg.connect_timeout_secs = 45; + + let params = agent_connect_params(&cfg, "mysql.example.com", 3306, "app"); + + assert_eq!(params["connect_timeout_secs"], 45); + } + #[test] fn zookeeper_agent_params_fall_back_to_host_port_connect_string() { let cfg = config(DatabaseType::ZooKeeper, None); diff --git a/plugins/jdbc/manifest.json b/plugins/jdbc/manifest.json index d19a48d6d..5f45506a0 100644 --- a/plugins/jdbc/manifest.json +++ b/plugins/jdbc/manifest.json @@ -1,7 +1,7 @@ { "id": "jdbc", "name": "DBX JDBC Plugin", - "version": "0.1.24", + "version": "0.1.25", "protocol_version": 1, "description": "Adds optional JDBC driver support to DBX.", "executable": "bin/dbx-jdbc-plugin", diff --git a/plugins/jdbc/pom.xml b/plugins/jdbc/pom.xml index 88ad74a77..92607fdfb 100644 --- a/plugins/jdbc/pom.xml +++ b/plugins/jdbc/pom.xml @@ -4,7 +4,7 @@ 4.0.0 app.dbx dbx-jdbc-plugin - 0.1.24 + 0.1.25 17 diff --git a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java b/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java index a099e95c6..43381f200 100644 --- a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java +++ b/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java @@ -554,7 +554,36 @@ public final class DbxJdbcPlugin { } String value = Integer.toString(connectTimeoutSecs); properties.putIfAbsent("loginTimeout", value); - properties.putIfAbsent("connectTimeout", value); + if (!jdbcUrlHasParameter(jdbcUrl(connection), "connectTimeout")) { + properties.putIfAbsent("connectTimeout", connectTimeoutPropertyValue(connection, connectTimeoutSecs)); + } + } + + private static String connectTimeoutPropertyValue(JsonNode connection, int connectTimeoutSecs) { + if (usesMillisecondConnectTimeout(connection)) { + return Integer.toString(connectTimeoutSecs * 1000); + } + return Integer.toString(connectTimeoutSecs); + } + + private static boolean usesMillisecondConnectTimeout(JsonNode connection) { + String url = jdbcUrl(connection); + if ( + urlMatchesPrefix(url, "jdbc:mysql:") || + urlMatchesPrefix(url, "jdbc:mariadb:") || + urlMatchesPrefix(url, "jdbc:starrocks:") || + urlMatchesPrefix(url, "jdbc:doris:") + ) { + return true; + } + String driverClass = optionalText(connection, "jdbc_driver_class"); + if (driverClass == null) { + return false; + } + String normalized = driverClass.toLowerCase(Locale.ROOT); + return normalized.equals("com.mysql.cj.jdbc.driver") || + normalized.equals("com.mysql.jdbc.driver") || + normalized.equals("org.mariadb.jdbc.driver"); } private static boolean isPrestoOrTrinoConnection(JsonNode connection) { @@ -2396,6 +2425,13 @@ public final class DbxJdbcPlugin { } private static boolean urlHasQueryParam(String url, String key) { + return jdbcUrlHasParameter(url, key); + } + + private static boolean jdbcUrlHasParameter(String url, String key) { + if (url == null) { + return false; + } int queryStart = url.indexOf('?'); if (queryStart < 0) { return false; diff --git a/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java b/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java index 494d1178d..ab9bb5b72 100644 --- a/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java +++ b/plugins/jdbc/src/test/java/app/dbx/jdbc/DbxJdbcPluginTest.java @@ -485,6 +485,43 @@ final class DbxJdbcPluginTest { assertEquals("45", properties.getProperty("connectTimeout")); } + @Test + void mysqlConnectTimeoutSecondsAreMappedToMilliseconds() throws Exception { + Method method = DbxJdbcPlugin.class.getDeclaredMethod("applyConnectTimeout", JsonNode.class, Properties.class); + method.setAccessible(true); + Properties properties = new Properties(); + JsonNode connection = MAPPER.readTree(""" + { + "connection_string": "jdbc:mysql://ddb.example.test:6000/app", + "jdbc_driver_class": "com.mysql.cj.jdbc.Driver", + "connect_timeout_secs": 45 + } + """); + + method.invoke(null, connection, properties); + + assertEquals("45", properties.getProperty("loginTimeout")); + assertEquals("45000", properties.getProperty("connectTimeout")); + } + + @Test + void explicitJdbcUrlConnectTimeoutIsNotOverridden() throws Exception { + Method method = DbxJdbcPlugin.class.getDeclaredMethod("applyConnectTimeout", JsonNode.class, Properties.class); + method.setAccessible(true); + Properties properties = new Properties(); + JsonNode connection = MAPPER.readTree(""" + { + "connection_string": "jdbc:mysql://ddb.example.test:6000/app?connectTimeout=5000", + "connect_timeout_secs": 45 + } + """); + + method.invoke(null, connection, properties); + + assertEquals("45", properties.getProperty("loginTimeout")); + assertFalse(properties.containsKey("connectTimeout")); + } + @Test void jdbcxHighPrivilegeExtensionsAreDisabledByDefault() throws Exception { Method method = DbxJdbcPlugin.class.getDeclaredMethod(