Răsfoiți Sursa

feat #IAUS2R 重构连接查找逻辑

gaibu 7 luni în urmă
părinte
comite
8d2e464d3d

+ 26 - 9
liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/datasource/LiteflowDataSourceConnectFactory.java

@@ -1,16 +1,20 @@
 package com.yomahub.liteflow.parser.sql.datasource;
 
-import cn.hutool.core.collection.CollUtil;
 import com.yomahub.liteflow.parser.sql.datasource.impl.BaoMiDouDynamicDsConn;
+import com.yomahub.liteflow.parser.sql.datasource.impl.DefaultLiteFlowJdbcConn;
+import com.yomahub.liteflow.parser.sql.datasource.impl.LiteFlowAutoLookUpJdbcConn;
 import com.yomahub.liteflow.parser.sql.datasource.impl.ShardingJdbcDsConn;
 import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
 import com.yomahub.liteflow.spi.ContextAware;
 import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * 数据源获取接口工厂
@@ -19,22 +23,35 @@ import java.util.Optional;
  * @since 2.12.5
  */
 public class LiteflowDataSourceConnectFactory {
-    private static List<LiteFlowDataSourceConnect> CONNECT_LIST = CollUtil.newArrayList(
-            new BaoMiDouDynamicDsConn(),
-            new ShardingJdbcDsConn()
-    );
+    private static final List<LiteFlowDataSourceConnect> CONNECT_LIST = new CopyOnWriteArrayList<>();
+    private static final Logger LOG = LoggerFactory.getLogger(LiteflowDataSourceConnectFactory.class);
 
     public static void register() {
         ContextAware contextAware = ContextAwareHolder.loadContextAware();
         Map<String, LiteFlowDataSourceConnect> beanMap = contextAware.getBeansOfType(LiteFlowDataSourceConnect.class);
         Collection<LiteFlowDataSourceConnect> values = beanMap.values();
+
+        // 清空原有的列表
+        CONNECT_LIST.clear();
+        // 将自定义的放在最前面
         CONNECT_LIST.addAll(values);
 
-        // 根据类名去重
-        CONNECT_LIST = CollUtil.distinct(CONNECT_LIST, t -> t.getClass().getName(), true);
+        // 内置的几种处理器
+        CONNECT_LIST.add(new DefaultLiteFlowJdbcConn());
+        CONNECT_LIST.add(new BaoMiDouDynamicDsConn());
+        CONNECT_LIST.add(new ShardingJdbcDsConn());
+
+        // 自动查找放在最后,这个用于兜底处理,这个里面如果找不到,会直接抛出异常
+        CONNECT_LIST.add(new LiteFlowAutoLookUpJdbcConn());
     }
 
-    public static Optional<LiteFlowDataSourceConnect> getConnect(SQLParserVO sqlParserVO) {
-        return CONNECT_LIST.stream().filter(connect -> connect.filter(sqlParserVO)).findFirst();
+    public static Optional<LiteFlowDataSourceConnect> getConnect(SQLParserVO config) {
+        for (LiteFlowDataSourceConnect dataSourceConnect : CONNECT_LIST) {
+            if (dataSourceConnect.filter(config)) {
+                LOG.debug("use lite-flow-data-source-connect: {}", dataSourceConnect.getClass().getName());
+                return Optional.of(dataSourceConnect);
+            }
+        }
+        return Optional.empty();
     }
 }

+ 29 - 0
liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/datasource/impl/DefaultLiteFlowJdbcConn.java

@@ -0,0 +1,29 @@
+package com.yomahub.liteflow.parser.sql.datasource.impl;
+
+import com.yomahub.liteflow.parser.sql.datasource.LiteFlowDataSourceConnect;
+import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+/**
+ * lite flow 默认的数据源连接
+ *
+ * @author tkc
+ * @since 2.12.5
+ */
+public class DefaultLiteFlowJdbcConn implements LiteFlowDataSourceConnect {
+    @Override
+    public boolean filter(SQLParserVO config) {
+        return config.isUseJdbcConn();
+    }
+
+    @Override
+    public Connection getConn(SQLParserVO config) throws Exception {
+        String url = config.getUrl();
+        String username = config.getUsername();
+        String password = config.getPassword();
+
+        return DriverManager.getConnection(url, username, password);
+    }
+}

+ 94 - 0
liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/datasource/impl/LiteFlowAutoLookUpJdbcConn.java

@@ -0,0 +1,94 @@
+package com.yomahub.liteflow.parser.sql.datasource.impl;
+
+import com.yomahub.liteflow.parser.sql.datasource.LiteFlowDataSourceConnect;
+import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
+import com.yomahub.liteflow.parser.sql.util.LiteFlowJdbcUtil;
+import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
+import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * lite flow 自动查找连接
+ *
+ * @author tkc
+ * @since 2.12.5
+ */
+public class LiteFlowAutoLookUpJdbcConn implements LiteFlowDataSourceConnect {
+    private static final Logger LOG = LoggerFactory.getLogger(LiteFlowAutoLookUpJdbcConn.class);
+
+    @Override
+    public boolean filter(SQLParserVO config) {
+        return true;
+    }
+
+    @Override
+    public Connection getConn(SQLParserVO config) throws Exception {
+        return DataSourceBeanNameHolder.autoLookUpConn(config);
+    }
+
+    public static class DataSourceBeanNameHolder {
+        private static String DATA_SOURCE_NAME = null;
+
+        public static synchronized void init(String dataSourceName) {
+            if (DATA_SOURCE_NAME == null) {
+                DATA_SOURCE_NAME = dataSourceName;
+            }
+        }
+
+        public static String getDataSourceName() {
+            return DATA_SOURCE_NAME;
+        }
+
+        public static boolean isNotInit() {
+            return DATA_SOURCE_NAME == null;
+        }
+
+        /**
+         * 自动查找可用数据源
+         */
+        public static Connection autoLookUpConn(SQLParserVO sqlParserVO) throws SQLException {
+            Connection connection;
+            Map<String, DataSource> dataSourceMap = ContextAwareHolder.loadContextAware().getBeansOfType(DataSource.class);
+            if (LiteFlowJdbcUtil.DataSourceBeanNameHolder.isNotInit()) {
+                synchronized (LiteFlowJdbcUtil.DataSourceBeanNameHolder.class) {
+                    if (LiteFlowJdbcUtil.DataSourceBeanNameHolder.isNotInit()) {
+                        String executeSql = LiteFlowJdbcUtil.buildCheckSql(sqlParserVO);
+                        // 遍历数据源,多数据源场景下,判断哪个数据源有 liteflow 配置
+                        for (Map.Entry<String, DataSource> entry : dataSourceMap.entrySet()) {
+                            String dataSourceName = entry.getKey();
+                            DataSource dataSource = entry.getValue();
+
+                            if (LiteFlowJdbcUtil.checkConnectionCanExecuteSql(dataSource.getConnection(), executeSql)) {
+                                // 找到数据源名称后,将其缓存起来,下次使用就不再寻找
+                                LiteFlowJdbcUtil.DataSourceBeanNameHolder.init(dataSourceName);
+
+                                LOG.info("use dataSourceName[{}],has found liteflow config", dataSourceName);
+                                break;
+                            } else {
+                                LOG.info("check dataSourceName[{}],but not has liteflow config", dataSourceName);
+                            }
+                        }
+                    }
+                }
+            }
+            DataSource dataSource = Optional.ofNullable(LiteFlowJdbcUtil.DataSourceBeanNameHolder.getDataSourceName())
+                    .map(dataSourceMap::get)
+                    .orElse(null);
+            if (dataSource == null) {
+                throw new ELSQLException("can not found liteflow config in dataSourceName " + dataSourceMap.keySet());
+            }
+            connection = dataSource.getConnection();
+            if (connection == null) {
+                throw new ELSQLException("can not found liteflow config in dataSourceName " + dataSourceMap.keySet());
+            }
+            return connection;
+        }
+    }
+}

+ 1 - 1
liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/datasource/impl/ShardingJdbcDsConn.java

@@ -31,7 +31,7 @@ public class ShardingJdbcDsConn implements LiteFlowDataSourceConnect {
         }
         boolean classLoadFlag = ClassLoaderUtil.isPresent(Constant.LOAD_CLASS_NAME);
         if (!classLoadFlag) {
-            throw new MissMavenDependencyException(Constant.MAVEN_GROUP_ID, BaoMiDouDynamicDsConn.Constant.MAVEN_ARTIFACT_ID);
+            throw new MissMavenDependencyException(Constant.MAVEN_GROUP_ID, Constant.MAVEN_ARTIFACT_ID);
         }
         return true;
     }

+ 5 - 13
liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/util/LiteFlowJdbcUtil.java

@@ -30,25 +30,17 @@ public class LiteFlowJdbcUtil {
      */
     public static Connection getConn(SQLParserVO sqlParserVO) {
         Connection connection = null;
-        String url = sqlParserVO.getUrl();
-        String username = sqlParserVO.getUsername();
-        String password = sqlParserVO.getPassword();
 
         try {
             // 如果指定连接查找器,就使用连接查找器获取连接
             Optional<LiteFlowDataSourceConnect> connectOpt = LiteflowDataSourceConnectFactory.getConnect(sqlParserVO);
             if (connectOpt.isPresent()) {
                 connection = connectOpt.get().getConn(sqlParserVO);
+            } else {
+                // 理论上这里不会走,因为最后一个连接查找器 LiteFlowAutoLookUpJdbcConn 没找到会抛出异常的
+                // 这里是一个兜底,理论上不会走
+                throw new ELSQLException("can not found connect by liteflow config");
             }
-            // 如果不配置 jdbc 连接相关配置,代表使用项目数据源
-            else if (sqlParserVO.isAutoFoundDataSource()) {
-                connection = DataSourceBeanNameHolder.autoLookUpConn(sqlParserVO);
-            }
-            // 如果配置 jdbc 连接相关配置,代表使用指定链接信息
-            else {
-                connection = DriverManager.getConnection(url, username, password);
-            }
-
         } catch (Exception e) {
             throw new ELSQLException(e);
         }
@@ -118,7 +110,7 @@ public class LiteFlowJdbcUtil {
      * @param sqlParserVO sql解析器参数
      * @return 返回组合完成的检查sql
      */
-    private static String buildCheckSql(SQLParserVO sqlParserVO) {
+    public static String buildCheckSql(SQLParserVO sqlParserVO) {
         String chainTableName = sqlParserVO.getChainTableName();
         String elDataField = sqlParserVO.getElDataField();
         String chainNameField = sqlParserVO.getChainNameField();

+ 10 - 0
liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/vo/SQLParserVO.java

@@ -290,6 +290,16 @@ public class SQLParserVO {
                 StrUtil.isBlank(driverClassName);
     }
 
+    /**
+     * 判断是否使用jdbc连接
+     */
+    public boolean isUseJdbcConn(){
+        return StrUtil.isNotBlank(url) &&
+                StrUtil.isNotBlank(username) &&
+                StrUtil.isNotBlank(password) &&
+                StrUtil.isNotBlank(driverClassName);
+    }
+
     public Boolean getPollingEnabled() {
         return pollingEnabled;
     }