Skip to content

Commit d527f20

Browse files
aiceflowerclaude
andauthored
[fix][EC][jdbc] Add configurable validation query for different database types (#5412)
* #AI COMMIT# fix: Add DB2 validation query support for JDBC engine connection pool - Add DB2-specific validation query "SELECT 1 FROM SYSIBM.SYSDUMMY1" - Same pattern as existing Oracle validation query handling - Fixes DB2 connection pool validation error when using datasource name Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * #AI COMMIT# fix: Exclude conflicting jars from JDBC plugin assembly - Exclude Jetty jars to avoid version conflicts with public-module - Exclude SLF4J bindings to prevent multiple binding errors - Exclude Hadoop jars to use shared public-module versions These exclusions prevent class loading conflicts when JDBC engine starts and uses jars from both plugin lib and public-module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * #AI COMMIT# refactor: Make validation query configurable for different database types - Add configuration parameter 'wds.linkis.jdbc.validation.query.mapping' - Default mapping: oracle:SELECT 1 FROM DUAL,db2:SELECT 1 FROM SYSIBM.SYSDUMMY1 - Remove hardcoded database-specific validation query logic - To add new database type, just update configuration, no code change needed Benefits: - Configuration-driven approach for extensibility - Easy to add support for new databases without modifying source code - Default values work for most common databases Usage example: Add to linkis-engineconn.properties: wds.linkis.jdbc.validation.query.mapping=oracle:SELECT 1 FROM DUAL,db2:SELECT 1 FROM SYSIBM.SYSDUMMY1,postgresql:SELECT 1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 58281e7 commit d527f20

4 files changed

Lines changed: 87 additions & 4 deletions

File tree

linkis-engineconn-plugins/jdbc/src/main/assembly/distribution.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@
4545
<exclude>org.apache.hbase:hbase-shaded-protobuf:jar</exclude>
4646
<exclude>org.apache.hbase:hbase-shaded-miscellaneous:jar</exclude>
4747
<exclude>org.apache.hbase:hbase-protocol-shaded:jar</exclude>
48+
<!-- Exclude conflicting Jetty jars - use from public-module -->
49+
<exclude>org.eclipse.jetty:jetty-*:jar</exclude>
50+
<exclude>org.eclipse.jetty:jetty-runner:jar</exclude>
51+
<!-- Exclude SLF4J binding to avoid conflict -->
52+
<exclude>org.apache.logging.log4j:log4j-slf4j-impl:jar</exclude>
53+
<exclude>org.slf4j:slf4j-reload4j:jar</exclude>
54+
<exclude>org.slf4j:slf4j-log4j12:jar</exclude>
55+
<!-- Exclude Hadoop jars - use from public-module -->
56+
<exclude>org.apache.hadoop:hadoop-*:jar</exclude>
4857
</excludes>
4958
</dependencySet>
5059
</dependencySets>

linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/ConnectionManager.java

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,64 @@ public class ConnectionManager {
5757
private final Map<String, DataSource> dataSourceFactories;
5858
private final JDBCDataSourceConfigurations jdbcDataSourceConfigurations;
5959

60+
// Cache for validation query mapping parsed from configuration
61+
private volatile Map<String, String> validationQueryMapping = null;
62+
6063
private static volatile ConnectionManager connectionManager; // NOSONAR
6164
private ScheduledExecutorService scheduledExecutorService;
6265
private Integer kinitFailCount = 0;
6366

6467
private ConnectionManager() {
6568
jdbcDataSourceConfigurations = new JDBCDataSourceConfigurations();
6669
dataSourceFactories = new HashMap<>();
70+
initValidationQueryMapping();
71+
}
72+
73+
/**
74+
* Parse validation query mapping from configuration. Format: dbType1:query1,dbType2:query2,...
75+
* Example: oracle:SELECT 1 FROM DUAL,db2:SELECT 1 FROM SYSIBM.SYSDUMMY1
76+
*/
77+
private void initValidationQueryMapping() {
78+
String mappingConfig = JDBCConfiguration$.MODULE$.JDBC_VALIDATION_QUERY_MAPPING();
79+
Map<String, String> mapping = new HashMap<>();
80+
if (StringUtils.isNotBlank(mappingConfig)) {
81+
String[] entries = mappingConfig.split(",");
82+
for (String entry : entries) {
83+
String[] parts = entry.split(":");
84+
if (parts.length == 2) {
85+
String dbType = parts[0].trim().toLowerCase();
86+
String query = parts[1].trim();
87+
mapping.put(dbType, query);
88+
LOG.info("Loaded validation query mapping: {} -> {}", dbType, query);
89+
}
90+
}
91+
}
92+
this.validationQueryMapping = mapping;
93+
}
94+
95+
/**
96+
* Get validation query for a specific JDBC URL based on database type. Returns null if no
97+
* specific mapping found (will use default "SELECT 1").
98+
*
99+
* @param jdbcUrl the JDBC connection URL
100+
* @return the validation query for this database type, or null if using default
101+
*/
102+
private String getValidationQueryFromUrl(String jdbcUrl) {
103+
if (jdbcUrl == null || validationQueryMapping == null || validationQueryMapping.isEmpty()) {
104+
return null;
105+
}
106+
String lowerUrl = jdbcUrl.toLowerCase();
107+
for (Map.Entry<String, String> entry : validationQueryMapping.entrySet()) {
108+
if (lowerUrl.contains(entry.getKey())) {
109+
LOG.debug(
110+
"Using validation query '{}' for database type '{}' from URL: {}",
111+
entry.getValue(),
112+
entry.getKey(),
113+
jdbcUrl);
114+
return entry.getValue();
115+
}
116+
}
117+
return null;
67118
}
68119

69120
public static ConnectionManager getInstance() {
@@ -203,9 +254,13 @@ protected DataSource buildDataSource(String dbUrl, Map<String, String> propertie
203254
DruidDataSource datasource = new DruidDataSource();
204255
LOG.info("Database connection address information(数据库连接地址信息)=" + dbUrl);
205256
datasource.setUrl(dbUrl);
206-
if (dbUrl.toLowerCase().contains("oracle")) {
207-
datasource.setValidationQuery("SELECT 1 FROM DUAL");
257+
258+
// Set validation query based on database type from configuration
259+
String dbSpecificValidationQuery = getValidationQueryFromUrl(dbUrl);
260+
if (dbSpecificValidationQuery != null) {
261+
datasource.setValidationQuery(dbSpecificValidationQuery);
208262
}
263+
209264
datasource.setUsername(username);
210265
if (AESUtils.LINKIS_DATASOURCE_AES_SWITCH.getValue()) {
211266
// decrypt
@@ -246,9 +301,13 @@ private Connection getConnectionFromDataSource(
246301
}
247302
}
248303
}
249-
if (url.contains("oracle")) {
250-
((DruidDataSource) dataSource).setValidationQuery("SELECT 1 FROM DUAL");
304+
305+
// Set validation query based on database type from configuration
306+
String dbSpecificValidationQuery = getValidationQueryFromUrl(url);
307+
if (dbSpecificValidationQuery != null) {
308+
((DruidDataSource) dataSource).setValidationQuery(dbSpecificValidationQuery);
251309
}
310+
252311
return dataSource.getConnection();
253312
}
254313

linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/constant/JDBCEngineConnConstant.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ private JDBCEngineConnConstant() {}
5757
public static final String JDBC_POOL_TEST_WHILE_IDLE = "wds.linkis.jdbc.pool.testWhileIdle";
5858
public static final String JDBC_POOL_VALIDATION_QUERY = "wds.linkis.jdbc.pool.validationQuery";
5959
public static final String JDBC_POOL_DEFAULT_VALIDATION_QUERY = "SELECT 1";
60+
61+
// Configuration for database-specific validation queries
62+
// Format: dbType1:query1,dbType2:query2,...
63+
// Example: oracle:SELECT 1 FROM DUAL,db2:SELECT 1 FROM SYSIBM.SYSDUMMY1,mysql:SELECT 1
64+
public static final String JDBC_VALIDATION_QUERY_MAPPING =
65+
"wds.linkis.jdbc.validation.query.mapping";
6066
public static final String JDBC_POOL_TIME_BETWEEN_MIN_EVIC_IDLE_MS =
6167
"wds.linkis.jdbc.pool.minEvictableIdleTimeMillis";
6268
public static final String JDBC_POOL_TIME_BETWEEN_EVIC_RUNS_MS =

linkis-engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/conf/JDBCConfiguration.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,13 @@ object JDBCConfiguration {
4343
val SUPPORT_CONN_PARAM_EXECUTE_ENABLE: Boolean =
4444
CommonVars[Boolean]("linkis.support.conn.param.execute.enable", true).getValue
4545

46+
// Validation query mapping for different database types
47+
// Format: dbType1:query1,dbType2:query2,...
48+
// Default includes common databases that need non-standard validation queries
49+
val JDBC_VALIDATION_QUERY_MAPPING: String =
50+
CommonVars[String](
51+
"wds.linkis.jdbc.validation.query.mapping",
52+
"oracle:SELECT 1 FROM DUAL,db2:SELECT 1 FROM SYSIBM.SYSDUMMY1"
53+
).getValue
54+
4655
}

0 commit comments

Comments
 (0)