This is an automated email from the ASF dual-hosted git repository.

peacewong pushed a commit to branch dev-1.2.0
in repository https://gitbox.apache.org/repos/asf/incubator-linkis.git


The following commit(s) were added to refs/heads/dev-1.2.0 by this push:
     new ae61ee927 [Feature] [1.2.0] Linkis jdbc engine supports multiple data 
source links. (#2260)
ae61ee927 is described below

commit ae61ee9272ef40362542b0d8b3f350db6b521092
Author: weixiao <[email protected]>
AuthorDate: Tue Jun 14 10:47:51 2022 +0800

    [Feature] [1.2.0] Linkis jdbc engine supports multiple data source links. 
(#2260)
    
    * [Feature] [1.2.0] Linkis jdbc engine supports multiple data source links.
    
    * [Feature] [1.2.0] Linkis jdbc engine supports multiple data source links 
and optimize code.
    
    * [Feature] [1.2.0] Linkis jdbc engine supports multiple data source links 
and optimize linkis_dml.sql.
    
    * [Feature] [1.2.0] Linkis jdbc engine supports multiple data source links 
and optimize code format.
    
    * [Feature] [1.2.0] Linkis jdbc engine supports multiple data source links 
and add cn and en data source form label or description.
    
    * [Feature] [1.2.0] Linkis jdbc engine supports multiple data source links 
and add cn and en data source form label or description.
---
 db/linkis_dml.sql                                  |  14 +-
 .../engineconn-plugins/jdbc/pom.xml                |  20 +++
 .../jdbc/JDBCDataSourceConfigurations.java         |  13 +-
 .../engineplugin/jdbc/PropertiesParser.java        |   6 +
 .../jdbc/constant/JDBCEngineConnConstant.java      |  15 ++
 .../jdbc/executer/JDBCEngineConnExecutor.scala     |  26 ++-
 .../jdbc/executer/JDBCMultiDatasourceParser.scala  | 175 +++++++++++++++++++++
 .../executer/JDBCMultiDatasourceParserTest.scala   | 116 ++++++++++++++
 8 files changed, 372 insertions(+), 13 deletions(-)

diff --git a/db/linkis_dml.sql b/db/linkis_dml.sql
index 2b0942913..a268bc5a0 100644
--- a/db/linkis_dml.sql
+++ b/db/linkis_dml.sql
@@ -456,12 +456,14 @@ INSERT INTO `linkis_ps_dm_datasource_type` (`name`, 
`description`, `option`, `cl
 INSERT INTO `linkis_ps_dm_datasource_type` (`name`, `description`, `option`, 
`classifier`, `icon`, `layers`) VALUES ('mongodb', 'default', 'default', 
'DEFAULT', NULL, 3);
 
 
-INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'host', 'Host', NULL, 'TEXT', NULL, 1, 'mysql Host ', 
NULL, NULL, NULL, NULL,  now(), now());
-INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'port', '端口', NULL, 'TEXT', NULL, 1, '端口', NULL, 
NULL, NULL, NULL,  now(), now());
-INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'params', '连接参数', NULL, 'TEXT', NULL, 0, '输入JSON格式: 
{"param":"value"}', NULL, NULL, NULL, NULL,  now(), now());
-INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'username', '用户名', NULL, 'TEXT', NULL, 1, '用户名', 
'^[0-9A-Za-z_-]+$', NULL, NULL, NULL,  now(), now());
-INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'password', '密码', NULL, 'PASSWORD', NULL, 1, '密码', 
'', NULL, NULL, NULL,  now(), now());
-INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (4, 'envId', '集群环境', NULL, 'SELECT', NULL, 1, '集群环境', 
NULL, NULL, NULL, '/data-source-manager/env-list/all/type/4', now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'host', '主机名(Host)', NULL, 'TEXT', NULL, 1, 
'主机名(Host)', NULL, NULL, NULL, NULL,  now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'port', '端口号(Port)', NULL, 'TEXT', NULL, 1, 
'端口号(Port)', NULL, NULL, NULL, NULL,  now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'driverClassName', '驱动类名(Driver class name)', 
'com.mysql.jdbc.Driver', 'TEXT', NULL, 1, '驱动类名(Driver class name)', NULL, 
NULL, NULL, NULL,  now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'params', '连接参数(Connection params)', NULL, 'TEXT', 
NULL, 0, '输入JSON格式(Input JSON format): {"param":"value"}', NULL, NULL, NULL, 
NULL,  now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'username', '用户名(Username)', NULL, 'TEXT', NULL, 1, 
'用户名(Username)', '^[0-9A-Za-z_-]+$', NULL, NULL, NULL,  now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'password', '密码(Password)', NULL, 'PASSWORD', NULL, 
1, '密码(Password)', '', NULL, NULL, NULL,  now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (1, 'databaseName', '数据库名(Database name)', NULL, 'TEXT', 
NULL, 0, '数据库名(Database name)', NULL, NULL, NULL, NULL,  now(), now());
+INSERT INTO `linkis_ps_dm_datasource_type_key` (`data_source_type_id`, `key`, 
`name`, `default_value`, `value_type`, `scope`, `require`, `description`, 
`value_regex`, `ref_id`, `ref_value`, `data_source`, `update_time`, 
`create_time`) VALUES (4, 'envId', '集群环境(Cluster env)', NULL, 'SELECT', NULL, 
1, '集群环境(Cluster env)', NULL, NULL, NULL, 
'/data-source-manager/env-list/all/type/4', now(), now());
 
 
 INSERT INTO `linkis_ps_dm_datasource_env` (`env_name`, `env_desc`, 
`datasource_type_id`, `parameter`, `create_time`, `create_user`, `modify_time`, 
`modify_user`) VALUES ('测试环境SIT', '测试环境SIT', 4, 
'{"uris":"thrift://localhost:9083", 
"hadoopConf":{"hive.metastore.execute.setugi":"true"}}',  now(), NULL,  now(), 
NULL);
diff --git a/linkis-engineconn-plugins/engineconn-plugins/jdbc/pom.xml 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/pom.xml
index 5a28641d0..461a3f56e 100644
--- a/linkis-engineconn-plugins/engineconn-plugins/jdbc/pom.xml
+++ b/linkis-engineconn-plugins/engineconn-plugins/jdbc/pom.xml
@@ -178,6 +178,26 @@
             <version>${druid.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.linkis</groupId>
+            <artifactId>linkis-datasource-client</artifactId>
+            <version>${linkis.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>javax.servlet-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.httpcomponents</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
     </dependencies>
     <build>
         <plugins>
diff --git 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/JDBCDataSourceConfigurations.java
 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/JDBCDataSourceConfigurations.java
index 8b922f2dc..c13939b1f 100644
--- 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/JDBCDataSourceConfigurations.java
+++ 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/JDBCDataSourceConfigurations.java
@@ -17,12 +17,16 @@
 
 package org.apache.linkis.manager.engineplugin.jdbc;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class JDBCDataSourceConfigurations {
+    private static final Logger LOG = 
LoggerFactory.getLogger(JDBCDataSourceConfigurations.class);
     private final Map<String, Statement> taskIdStatementMap;
 
     public JDBCDataSourceConfigurations() {
@@ -36,6 +40,7 @@ public class JDBCDataSourceConfigurations {
             }
         }
         taskIdStatementMap.clear();
+        LOG.info("The jdbc task statement map has be cleared successfully!");
     }
 
     public void saveStatement(String taskId, Statement statement) {
@@ -43,10 +48,16 @@ public class JDBCDataSourceConfigurations {
     }
 
     public void cancelStatement(String taskId) throws SQLException {
-        taskIdStatementMap.get(taskId).cancel();
+        LOG.info("Starting to cancel the statement of task {} ...", taskId);
+        Statement statement = taskIdStatementMap.get(taskId);
+        if (statement != null) {
+            statement.cancel();
+        }
+        LOG.info("Finished cancel the statement of task {}.", taskId);
     }
 
     public void removeStatement(String taskId) {
         taskIdStatementMap.remove(taskId);
+        LOG.info("Finished remove the statement of task {}", taskId);
     }
 }
diff --git 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/PropertiesParser.java
 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/PropertiesParser.java
index 5bc15dcab..2ab943e56 100644
--- 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/PropertiesParser.java
+++ 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/PropertiesParser.java
@@ -23,6 +23,12 @@ import java.util.Map;
 
 public abstract class PropertiesParser {
     interface TypeConversion<T> {
+        /**
+         * String type data is converted to T type
+         *
+         * @param oriV origin type
+         * @return T which is target type
+         */
         T convertTo(String oriV);
     }
 
diff --git 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/constant/JDBCEngineConnConstant.java
 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/constant/JDBCEngineConnConstant.java
index 0ccc4b49e..305643f67 100644
--- 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/constant/JDBCEngineConnConstant.java
+++ 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/constant/JDBCEngineConnConstant.java
@@ -36,6 +36,8 @@ public class JDBCEngineConnConstant {
     public static final String JDBC_PROXY_USER = "wds.linkis.jdbc.proxy.user";
     public static final String JDBC_SCRIPTS_EXEC_USER = "execUser";
     public static final String JDBC_ENGINE_RUN_TIME_DS = 
"wds.linkis.engine.runtime.datasource";
+    public static final String JDBC_ENGINE_RUN_TIME_DS_SYSTEM_QUERY_PARAM =
+            "wds.linkis.engine.runtime.datasource.systemQueryParam";
 
     public static final String JDBC_POOL_TEST_ON_BORROW = 
"wds.linkis.jdbc.pool.testOnBorrow";
     public static final String JDBC_POOL_TEST_ON_RETURN = 
"wds.linkis.jdbc.pool.testOnReturn";
@@ -57,5 +59,18 @@ public class JDBCEngineConnConstant {
     public static final String JDBC_POOL_REMOVE_ABANDONED_TIMEOUT =
             "wds.linkis.jdbc.pool.remove.abandoned.timeout";
 
+    public static final String DS_JDBC_HOST = "host";
+    public static final String DS_JDBC_PORT = "port";
+    public static final String DS_JDBC_DB_NAME = "databaseName";
+    public static final String DS_JDBC_USERNAME = "username";
+    public static final String DS_JDBC_PASSWORD = "password";
+    public static final String DS_JDBC_ENABLE_KERBEROS = "enableKerberos";
+    public static final String DS_JDBC_KERBEROS_PRINCIPAL = 
"kerberosPrincipal";
+    public static final String DS_JDBC_KERBEROS_KEYTAB = "kerberosKeytab";
+    public static final String DS_JDBC_ENABLE_KERBEROS_PROXY_USER = 
"enableKerberosProxyUser";
+    public static final String DS_JDBC_KERBEROS_PROXY_USER_PROPERTY = 
"kerberosProxyUserProperty";
+    public static final String DS_JDBC_PARAMS = "params";
+    public static final String DS_JDBC_DRIVER = "driverClassName";
+
     public static final String JDBC_ENGINE_MEMORY_UNIT = "g";
 }
diff --git 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCEngineConnExecutor.scala
 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCEngineConnExecutor.scala
index 3bb05236a..4a84fb154 100644
--- 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCEngineConnExecutor.scala
+++ 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCEngineConnExecutor.scala
@@ -44,6 +44,7 @@ import org.apache.linkis.governance.common.paser.SQLCodeParser
 import 
org.apache.linkis.manager.engineplugin.jdbc.constant.JDBCEngineConnConstant
 
 import scala.collection.JavaConversions._
+
 import scala.collection.mutable.ArrayBuffer
 
 class JDBCEngineConnExecutor(override val outputPrintLimit: Int, val id: Int) 
extends ConcurrentComputationExecutor(outputPrintLimit) {
@@ -68,13 +69,21 @@ class JDBCEngineConnExecutor(override val outputPrintLimit: 
Int, val id: Int) ex
     val taskId = engineExecutorContext.getJobId.get
     val properties = 
engineExecutorContext.getProperties.asInstanceOf[util.Map[String, String]]
     var dataSourceName = 
properties.getOrDefault(JDBCEngineConnConstant.JDBC_ENGINE_RUN_TIME_DS, "")
+    val dataSourceQuerySystemParam = 
properties.getOrDefault(JDBCEngineConnConstant.JDBC_ENGINE_RUN_TIME_DS_SYSTEM_QUERY_PARAM,
 "")
 
     if (properties.get(JDBCEngineConnConstant.JDBC_URL) == null) {
       info(s"The jdbc url is empty, adding now...")
-      val globalConfig = 
Utils.tryAndWarn(JDBCEngineConfig.getCacheMap(engineExecutorContext.getLabels))
+      val globalConfig: util.Map[String, String] = 
Utils.tryAndWarn(JDBCEngineConfig.getCacheMap(engineExecutorContext.getLabels))
       if (StringUtils.isNotBlank(dataSourceName)) {
         info("Start getting data source connection parameters from the data 
source hub.")
-        // todo get data source info by data source client
+        Utils.tryCatch {
+          val dataSourceInfo = 
JDBCMultiDatasourceParser.queryDatasourceInfoByName(dataSourceName, 
execSqlUser, dataSourceQuerySystemParam)
+          if (dataSourceInfo != null && !dataSourceInfo.isEmpty) {
+            globalConfig.putAll(dataSourceInfo)
+          }
+        } {
+          e: Throwable => return ErrorExecuteResponse(s"Failed to get 
datasource info about [$dataSourceName] from datasource server.", e)
+        }
       }
       properties.put(JDBCEngineConnConstant.JDBC_URL, 
globalConfig.get(JDBCEngineConnConstant.JDBC_URL))
       properties.put(JDBCEngineConnConstant.JDBC_DRIVER, 
globalConfig.get(JDBCEngineConnConstant.JDBC_DRIVER))
@@ -95,16 +104,19 @@ class JDBCEngineConnExecutor(override val 
outputPrintLimit: Int, val id: Int) ex
     var connection: Connection = null
     var statement: Statement = null
     var resultSet: ResultSet = null
-
+    info(s"The data source properties is $properties")
     Utils.tryCatch({
       connection = connectionManager.getConnection(dataSourceName, properties)
+      info("The jdbc connection has created successfully!")
     }) {
-      case e: Exception => return ErrorExecuteResponse("created data source 
connection error.", e)
+      e: Throwable =>
+        error(s"created data source connection error! $e")
+        return ErrorExecuteResponse("created data source connection error!", e)
     }
 
     try {
-      statement.setQueryTimeout(JDBCConfiguration.JDBC_QUERY_TIMEOUT.getValue)
       statement = connection.createStatement()
+      statement.setQueryTimeout(JDBCConfiguration.JDBC_QUERY_TIMEOUT.getValue)
       statement.setFetchSize(outputPrintLimit)
       statement.setMaxRows(outputPrintLimit)
       info(s"create statement is:  $statement")
@@ -131,7 +143,9 @@ class JDBCEngineConnExecutor(override val outputPrintLimit: 
Int, val id: Int) ex
         }
       }
     } catch {
-      case e: Throwable => error(s"Cannot run $code", e)
+      case e: Throwable =>
+        error(s"Cannot run $code", e)
+        return ErrorExecuteResponse(e.getMessage, e)
     } finally {
       if (connection != null) {
         try {
diff --git 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCMultiDatasourceParser.scala
 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCMultiDatasourceParser.scala
new file mode 100644
index 000000000..120f1e470
--- /dev/null
+++ 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/main/scala/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCMultiDatasourceParser.scala
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.linkis.manager.engineplugin.jdbc.executer
+
+import java.util
+import org.apache.commons.lang.StringUtils
+import org.apache.linkis.common.utils.{JsonUtils, Logging, Utils}
+import org.apache.linkis.datasource.client.impl.LinkisDataSourceRemoteClient
+import 
org.apache.linkis.datasource.client.request.GetInfoByDataSourceNameAction
+import org.apache.linkis.datasourcemanager.common.domain.DataSource
+import org.apache.linkis.manager.engineplugin.jdbc.JdbcAuthType
+import 
org.apache.linkis.manager.engineplugin.jdbc.constant.JDBCEngineConnConstant
+import 
org.apache.linkis.manager.engineplugin.jdbc.exception.JDBCParamsIllegalException
+import scala.collection.JavaConversions._
+
+object JDBCMultiDatasourceParser extends Logging {
+
+  def queryDatasourceInfoByName(datasourceName: String, username: String, 
system: String): util.Map[String, String] = {
+    info(s"Starting query [$system, $username, $datasourceName] datasource 
info ......")
+    val dataSourceClient = new LinkisDataSourceRemoteClient()
+    var dataSource: DataSource = null
+    Utils.tryCatch {
+      dataSource = 
dataSourceClient.getInfoByDataSourceName(GetInfoByDataSourceNameAction.builder()
+        .setSystem(system)
+        .setDataSourceName(datasourceName)
+        .setUser(username)
+        .build()).getDataSource
+    } {
+      case e: Exception => warn(s"Get data source info error, $e")
+    }
+    queryDatasourceInfo(datasourceName, dataSource)
+  }
+
+  def queryDatasourceInfo(datasourceName: String, dataSource: DataSource): 
util.Map[String, String] = {
+    val dsConnInfo = new util.HashMap[String, String]()
+
+    if (strObjIsBlank(dataSource)) {
+      throw JDBCParamsIllegalException(s"Data source [$datasourceName] info 
not found!")
+    }
+
+    if (dataSource.getPublishedVersionId == null || 
dataSource.getPublishedVersionId <= 0) {
+      throw JDBCParamsIllegalException(s"Data source [$datasourceName] not yet 
published!")
+    }
+
+    if (dataSource.isExpire) {
+      throw JDBCParamsIllegalException(s"Data source [$datasourceName] is 
expired!")
+    }
+
+    if (dataSource.getDataSourceType == null || 
StringUtils.isBlank(dataSource.getDataSourceType.getName)) {
+      throw JDBCParamsIllegalException("The data source jdbc type cannot be 
null!")
+    }
+
+    val dbType = dataSource.getDataSourceType.getName
+    val dbConnParams = dataSource.getConnectParams
+    if (dbConnParams == null || dbConnParams.isEmpty) {
+      throw JDBCParamsIllegalException("The data source jdbc connection info 
cannot be null!")
+    }
+
+    val driverClassName = 
dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_DRIVER)
+    if (strObjIsBlank(driverClassName)) {
+      throw JDBCParamsIllegalException("The data source jdbc driverClassName 
cannot be null!")
+    }
+
+    val jdbcUrl = createJdbcUrl(dbType, dbConnParams)
+    info(s"The url parsed from the data source connection information is 
$jdbcUrl")
+    dsConnInfo.put(JDBCEngineConnConstant.JDBC_URL, jdbcUrl)
+    dsConnInfo.put(JDBCEngineConnConstant.JDBC_DRIVER, 
driverClassName.toString)
+    appendJdbcAuthType(dbConnParams, dsConnInfo)
+  }
+
+  def createJdbcUrl(dbType: String, dbConnParams: util.Map[String, Object]): 
String = {
+    val host = dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_HOST)
+    if (strObjIsBlank(host)) {
+      throw JDBCParamsIllegalException("The data source jdbc connection host 
cannot be null!")
+    }
+    val port = dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_PORT)
+    if (strObjIsBlank(port)) {
+      throw JDBCParamsIllegalException("The data source jdbc connection port 
cannot be null!")
+    }
+    var jdbcUrl = s"jdbc:$dbType://$host:$port"
+    val dbName = dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_DB_NAME)
+    if (strObjIsNotBlank(dbName)) {
+      jdbcUrl = s"$jdbcUrl/$dbName"
+    }
+
+    val params = dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_PARAMS)
+    val paramsMap = if (strObjIsNotBlank(params)) 
convertJsonStrToMap(params.toString) else new util.HashMap[String, Object]()
+
+    if (!paramsMap.isEmpty) {
+      val headConf = paramsMap.head
+      jdbcUrl = s"$jdbcUrl?${headConf._1}=${headConf._2}"
+      paramsMap.remove(headConf._1)
+    }
+
+    if (!paramsMap.isEmpty) {
+      val paramsJoin = for ((k, v) <- paramsMap) yield 
s"$k=${v.toString}".toList.mkString("&")
+      jdbcUrl = s"$jdbcUrl&$paramsJoin"
+    }
+
+    jdbcUrl
+  }
+
+  def appendJdbcAuthType(dbConnParams: util.Map[String, Object], dsConnInfo: 
util.HashMap[String, String]): util.HashMap[String, String] = {
+    val username = dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_USERNAME)
+    val password = dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_PASSWORD)
+    val enableKerberos = 
dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_ENABLE_KERBEROS)
+    val kerberosPrincipal = 
dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_KERBEROS_PRINCIPAL)
+    val kerberosKeytab = 
dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_KERBEROS_KEYTAB)
+    var authType: JdbcAuthType = JdbcAuthType.SIMPLE
+    if (strObjIsNotBlank(username) && strObjIsNotBlank(password)) {
+      authType = JdbcAuthType.USERNAME
+    } else {
+      if (strObjIsNotBlank(enableKerberos) && 
enableKerberos.toString.toBoolean) {
+        authType = JdbcAuthType.KERBEROS
+        if (strObjIsBlank(kerberosPrincipal)) {
+          throw JDBCParamsIllegalException("In the jdbc authentication mode of 
kerberos, the kerberos principal cannot be empty!")
+        }
+        if (strObjIsBlank(kerberosKeytab)) {
+          throw JDBCParamsIllegalException("In the jdbc authentication mode of 
kerberos, the kerberos keytab cannot be empty!")
+        }
+      } else {
+        authType = JdbcAuthType.SIMPLE
+      }
+    }
+
+    authType match {
+      case JdbcAuthType.SIMPLE =>
+        info("jdbc simple auth type.")
+      case JdbcAuthType.USERNAME =>
+        dsConnInfo.put(JDBCEngineConnConstant.JDBC_USERNAME, username.toString)
+        dsConnInfo.put(JDBCEngineConnConstant.JDBC_PASSWORD, password.toString)
+      case JdbcAuthType.KERBEROS =>
+        
dsConnInfo.put(JDBCEngineConnConstant.JDBC_KERBEROS_AUTH_TYPE_PRINCIPAL, 
kerberosPrincipal.toString)
+        
dsConnInfo.put(JDBCEngineConnConstant.JDBC_KERBEROS_AUTH_TYPE_KEYTAB_LOCATION, 
kerberosKeytab.toString)
+        val enableKerberosProxyUser = 
dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_ENABLE_KERBEROS_PROXY_USER)
+        if (strObjIsNotBlank(enableKerberosProxyUser)) {
+          
dsConnInfo.put(JDBCEngineConnConstant.JDBC_KERBEROS_AUTH_PROXY_ENABLE, 
enableKerberosProxyUser.toString)
+        }
+        val kerberosProxyUserProperty = 
dbConnParams.get(JDBCEngineConnConstant.DS_JDBC_KERBEROS_PROXY_USER_PROPERTY)
+        if (strObjIsNotBlank(kerberosProxyUserProperty)) {
+          dsConnInfo.put(JDBCEngineConnConstant.JDBC_PROXY_USER_PROPERTY, 
kerberosProxyUserProperty.toString)
+        }
+      case _ => throw JDBCParamsIllegalException(s"Unsupported authentication 
type ${authType.getAuthType}")
+    }
+    dsConnInfo.put(JDBCEngineConnConstant.JDBC_AUTH_TYPE, authType.getAuthType)
+    dsConnInfo
+  }
+
+  private def convertJsonStrToMap(jsonStr: String): util.Map[String, Object] = 
{
+    JsonUtils.jackson.readValue(jsonStr, classOf[util.Map[String, Object]])
+  }
+
+  private def strObjIsNotBlank(str: Object): Boolean = {
+    str != null && StringUtils.isNotBlank(str.toString)
+  }
+
+  private def strObjIsBlank(str: Object): Boolean = {
+    ! strObjIsNotBlank(str)
+  }
+}
diff --git 
a/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/test/java/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCMultiDatasourceParserTest.scala
 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/test/java/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCMultiDatasourceParserTest.scala
new file mode 100644
index 000000000..a425ea867
--- /dev/null
+++ 
b/linkis-engineconn-plugins/engineconn-plugins/jdbc/src/test/java/org/apache/linkis/manager/engineplugin/jdbc/executer/JDBCMultiDatasourceParserTest.scala
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.linkis.manager.engineplugin.jdbc.executer
+
+import org.apache.linkis.datasourcemanager.common.domain.{DataSource, 
DataSourceType}
+import org.apache.linkis.manager.engineplugin.jdbc.JdbcAuthType
+
+import java.util
+import org.junit.jupiter.api.{BeforeEach, DisplayName, Test}
+import org.junit.jupiter.api.Assertions.assertTrue
+import 
org.apache.linkis.manager.engineplugin.jdbc.constant.JDBCEngineConnConstant
+
+
+class JDBCMultiDatasourceParserTest {
+
+  val dbType = "mysql"
+  val dbConnParams: util.Map[String, Object] = new util.HashMap[String, 
Object]()
+  val datasource: DataSource = new DataSource()
+
+  @BeforeEach
+  def initDatasourceConnParams(): Unit = {
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_HOST, "localhost")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_PORT, "3306")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_USERNAME, "username")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_PASSWORD, "password")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_DB_NAME, "dbName")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_DRIVER, 
"com.mysql.jdbc.Driver")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_PARAMS, "{\"useSSL\": 
\"false\"}")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_ENABLE_KERBEROS, "false")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_KERBEROS_PRINCIPAL, 
"hadoop@com")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_KERBEROS_KEYTAB, 
"/data/linkis/keytab/hadoop.keytab")
+    
dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_ENABLE_KERBEROS_PROXY_USER, 
"true")
+    
dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_KERBEROS_PROXY_USER_PROPERTY, 
"hive.server2.proxy.user")
+
+    val dataSourceType = new DataSourceType()
+    dataSourceType.setName(dbType)
+    datasource.setDataSourceType(dataSourceType)
+    datasource.setConnectParams(dbConnParams)
+    datasource.setPublishedVersionId(1L)
+    datasource.setExpire(false)
+  }
+
+  @Test
+  @DisplayName("testCreateJdbcUrl")
+  def testCreateJdbcUrl(): Unit = {
+    val url1 = JDBCMultiDatasourceParser.createJdbcUrl(dbType, dbConnParams)
+    assertTrue(url1 != null && 
"jdbc:mysql://localhost:3306/dbName?useSSL=false".equals(url1))
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_DB_NAME, "")
+    val url2 = JDBCMultiDatasourceParser.createJdbcUrl(dbType, dbConnParams)
+    assertTrue(url2 != null && 
"jdbc:mysql://localhost:3306?useSSL=false".equals(url2))
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_HOST, "")
+    try {
+      JDBCMultiDatasourceParser.createJdbcUrl(dbType, dbConnParams)
+    } catch {
+      case e: Throwable => assertTrue(true)
+    }
+  }
+
+  @Test
+  @DisplayName("testAppendJdbcAuthType")
+  def testAppendJdbcAuthType(): Unit = {
+    var dsConnInfo = new util.HashMap[String, String]()
+    dsConnInfo = JDBCMultiDatasourceParser.appendJdbcAuthType(dbConnParams, 
dsConnInfo)
+    
assertTrue(dsConnInfo.get(JDBCEngineConnConstant.JDBC_AUTH_TYPE).equals(JdbcAuthType.USERNAME.getAuthType))
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_USERNAME, "")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_PASSWORD, "")
+    dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_ENABLE_KERBEROS, "true")
+    dsConnInfo = new util.HashMap[String, String]()
+    dsConnInfo = JDBCMultiDatasourceParser.appendJdbcAuthType(dbConnParams, 
dsConnInfo)
+    
assertTrue(dsConnInfo.get(JDBCEngineConnConstant.JDBC_AUTH_TYPE).equals(JdbcAuthType.KERBEROS.getAuthType))
+    
dbConnParams.put(JDBCEngineConnConstant.DS_JDBC_ENABLE_KERBEROS_PROXY_USER, 
"false")
+    dsConnInfo = new util.HashMap[String, String]()
+    dsConnInfo = JDBCMultiDatasourceParser.appendJdbcAuthType(dbConnParams, 
dsConnInfo)
+    
assertTrue(dsConnInfo.get(JDBCEngineConnConstant.JDBC_KERBEROS_AUTH_PROXY_ENABLE).equals("false"))
+  }
+
+  @Test
+  @DisplayName("testQueryDatasourceInfo")
+  def testQueryDatasourceInfo(): Unit = {
+    val dataSourceInfo = 
JDBCMultiDatasourceParser.queryDatasourceInfo("test_mysql", datasource)
+    val jdbcUrl = dataSourceInfo.get(JDBCEngineConnConstant.JDBC_URL)
+    assertTrue(jdbcUrl != null && 
"jdbc:mysql://localhost:3306/dbName?useSSL=false".equals(jdbcUrl))
+    
assertTrue(dataSourceInfo.get(JDBCEngineConnConstant.JDBC_AUTH_TYPE).equals(JdbcAuthType.USERNAME.getAuthType))
+  }
+
+  @Test
+  @DisplayName("testMapPutAll")
+  def testMapPutAll(): Unit = {
+    val globalConfig: util.Map[String, String] = new util.HashMap[String, 
String]()
+    globalConfig.put(JDBCEngineConnConstant.JDBC_URL, 
"jdbc:mysql://localhost:3306/dbName?useSSL=false")
+    globalConfig.put(JDBCEngineConnConstant.JDBC_AUTH_TYPE, 
JdbcAuthType.SIMPLE.getAuthType)
+    val dataSourceInfo: util.Map[String, String] = new util.HashMap[String, 
String]()
+    dataSourceInfo.put(JDBCEngineConnConstant.JDBC_URL, 
"jdbc:mysql://127.0.0.1:3306/dbName?useSSL=false")
+    dataSourceInfo.put(JDBCEngineConnConstant.JDBC_AUTH_TYPE, 
JdbcAuthType.USERNAME.getAuthType)
+    dataSourceInfo.put(JDBCEngineConnConstant.JDBC_USERNAME, "user")
+    dataSourceInfo.put(JDBCEngineConnConstant.JDBC_PASSWORD, "password")
+    globalConfig.putAll(dataSourceInfo)
+    assertTrue(globalConfig.size() == 4)
+    
assertTrue(globalConfig.get(JDBCEngineConnConstant.JDBC_AUTH_TYPE).equals(JdbcAuthType.USERNAME.getAuthType))
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to