diff --git a/liteflow-core/pom.xml b/liteflow-core/pom.xml index c93d6578d6225604eaaac6f6e5351be82d040fef..635f5925722c44965a344ecfafe12a8398b5d980 100644 --- a/liteflow-core/pom.xml +++ b/liteflow-core/pom.xml @@ -54,5 +54,9 @@ commons-io commons-io + + com.github.ben-manes.caffeine + caffeine + diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 50118790e1b3551fcbadd6e400328c52bf5edb28..58c18df1a6f54782faba56b80c17d2886beadc1e 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -20,13 +20,13 @@ import com.yomahub.liteflow.enums.ParseModeEnum; import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.flow.cache.RuleCachePostProcessFlowExecuteLifeCycle; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Node; import com.yomahub.liteflow.flow.element.Rollbackable; import com.yomahub.liteflow.flow.entity.CmpStep; import com.yomahub.liteflow.flow.id.IdGeneratorHolder; import com.yomahub.liteflow.lifecycle.LifeCycleHolder; -import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; import com.yomahub.liteflow.log.LFLog; import com.yomahub.liteflow.log.LFLoggerManager; import com.yomahub.liteflow.monitor.MonitorFile; @@ -45,10 +45,7 @@ import com.yomahub.liteflow.thread.ExecutorHelper; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; -import java.util.function.Consumer; import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -103,6 +100,11 @@ public class FlowExecutor { IdGeneratorHolder.init(); } + // 规则缓存 + if (isStart && liteflowConfig.isRuleCacheEnabled()) { + LifeCycleHolder.addLifeCycle(new RuleCachePostProcessFlowExecuteLifeCycle()); + } + String ruleSource = liteflowConfig.getRuleSource(); if (StrUtil.isBlank(ruleSource)) { // 查看有没有Parser的SPI实现 diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java index 1294248a0cfc38e43d7931fd81a1201519892b85..340baeea713b4d5a5f5cdc52544682ab226b74e0 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java @@ -10,6 +10,7 @@ package com.yomahub.liteflow.flow; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.annotation.FallbackCmp; import com.yomahub.liteflow.annotation.util.AnnoUtil; @@ -22,6 +23,8 @@ import com.yomahub.liteflow.enums.FlowParserTypeEnum; import com.yomahub.liteflow.enums.NodeTypeEnum; import com.yomahub.liteflow.exception.ComponentCannotRegisterException; import com.yomahub.liteflow.exception.NullNodeTypeException; +import com.yomahub.liteflow.flow.cache.CacheFactory; +import com.yomahub.liteflow.flow.cache.ChainRepository; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Condition; import com.yomahub.liteflow.flow.element.Node; @@ -68,15 +71,22 @@ public class FlowBus { static { LiteflowConfig liteflowConfig = LiteflowConfigGetter.get(); + Map expectedChainMap; if (liteflowConfig.getFastLoad()){ - chainMap = new HashMap<>(); + expectedChainMap = new HashMap<>(); nodeMap = new HashMap<>(); fallbackNodeMap = new HashMap<>(); }else{ - chainMap = new CopyOnWriteHashMap<>(); + expectedChainMap = new CopyOnWriteHashMap<>(); nodeMap = new CopyOnWriteHashMap<>(); fallbackNodeMap = new CopyOnWriteHashMap<>(); } + // 开启了规则缓存 + if (liteflowConfig.isRuleCacheEnabled()) { + Integer capacity = liteflowConfig.getRuleCacheCapacity(); + expectedChainMap = CacheFactory.newCache(capacity); + } + chainMap = expectedChainMap; } public static Chain getChain(String id) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/CacheFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/CacheFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..2cf8e3494eaf526509b4e3c566933fe6ab1f7e69 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/CacheFactory.java @@ -0,0 +1,27 @@ +package com.yomahub.liteflow.flow.cache; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; + +import java.util.Map; + +/** + * 缓存工厂 + * @author DaleLee + * @since + */ +public class CacheFactory { + /** + * 构建一个缓存 + * @param capacity 缓存容量 + * @return Map形式的缓存 + * @param 键 + * @param 值 + */ + public static Map newCache(int capacity) { + Cache cache = Caffeine.newBuilder() + .maximumSize(capacity) + .build(); + return cache.asMap(); + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainFinder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainFinder.java new file mode 100644 index 0000000000000000000000000000000000000000..425feaf8682520e8dd1bc1b3365a9a8747292440 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainFinder.java @@ -0,0 +1,15 @@ +package com.yomahub.liteflow.flow.cache; + +/** + * Chain查找器 + * @author DaleLee + * @since + */ +public interface ChainFinder { + /** + * 根据chainId查找对应的RawChain + * @param chainId chainId + * @return RawChain + */ + RawChain findChainById(String chainId); +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainRepository.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..b5624c58a0031aa9e0c360280d720a9043045646 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainRepository.java @@ -0,0 +1,49 @@ +package com.yomahub.liteflow.flow.cache; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * 外部数据源下Chain的统一访问类 + * @author DaleLee + * @since + */ +public class ChainRepository { + private static final List chainFinders = new ArrayList<>(); + + /** + * 根据chainId获取对应的RawChain + * @param chainId chainId + * @return RawChain + */ + public static RawChain getChain(String chainId) { + if (CollUtil.isEmpty(chainFinders)) { + return null; + } + for (ChainFinder chainFinder : chainFinders) { + RawChain rawChain = chainFinder.findChainById(chainId); + if (ObjectUtil.isNotNull(rawChain)) { + return rawChain; + } + } + return null; + } + + /** + * 添加一个ChainFinder + * @param chainFinder ChainFinder + */ + public static void addFinder(ChainFinder chainFinder) { + chainFinders.add(chainFinder); + } + + /** + * 清空所有的ChainFinder + */ + public static void clearFinders() { + chainFinders.clear(); + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RawChain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RawChain.java new file mode 100644 index 0000000000000000000000000000000000000000..61079e72ba703f7ef671bffbe90c84fe30ca2866 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RawChain.java @@ -0,0 +1,57 @@ +package com.yomahub.liteflow.flow.cache; + +/** + * Chain的原始信息 + * @author DaleLee + * @since + */ +public class RawChain { + /** + * id + */ + private String chainId; + /** + * EL表达式 + */ + private String el; + /** + * 路由 + */ + private String route; + /** + * 命名空间 + */ + private String namespace; + + public String getChainId() { + return chainId; + } + + public void setChainId(String chainId) { + this.chainId = chainId; + } + + public String getEl() { + return el; + } + + public void setEl(String el) { + this.el = el; + } + + public String getRoute() { + return route; + } + + public void setRoute(String route) { + this.route = route; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java new file mode 100644 index 0000000000000000000000000000000000000000..ba1a249f05e0c42865fd9a44e2ab3721b18373b5 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java @@ -0,0 +1,45 @@ +package com.yomahub.liteflow.flow.cache; + +import cn.hutool.core.util.ObjectUtil; +import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; +import com.yomahub.liteflow.slot.Slot; + +/** + * Chain执行前的缓存处理 + * @author DaleLee + * @since + */ +public class RuleCachePostProcessFlowExecuteLifeCycle implements PostProcessFlowExecuteLifeCycle { + @Override + public void postProcessBeforeFlowExecute(String chainId, Slot slot) { + if (!FlowBus.containChain(chainId)) { + // 如果chain不存在,尝试去加载 + tryLoadChain(chainId); + } + } + + @Override + public void postProcessAfterFlowExecute(String chainId, Slot slot) { + + } + + /** + * 尝试加载chain + * @param chainId chainId + */ + private void tryLoadChain(String chainId) { + RawChain rawChain = ChainRepository.getChain(chainId); + if (ObjectUtil.isNull(rawChain)) { + return; + } + LiteFlowChainELBuilder + .createChain() + .setChainId(chainId) + .setEL(rawChain.getEl()) + .setNamespace(rawChain.getNamespace()) + .setRoute(rawChain.getRoute()) + .build(); + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java index d269da250cc645584451d281ba47818cf425522b..4b4db3f97a67dbb81eb5b5491faa9dce7b90c23d 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java @@ -124,6 +124,9 @@ public class LiteflowConfig { //脚本特殊设置选项 private Map scriptSetting; + // 规则缓存容量 + private Integer ruleCacheCapacity; + public Boolean getEnableMonitorFile() { return enableMonitorFile; } @@ -509,4 +512,16 @@ public class LiteflowConfig { public void setScriptSetting(Map scriptSetting) { this.scriptSetting = scriptSetting; } + + public Integer getRuleCacheCapacity() { + return ruleCacheCapacity; + } + + public void setRuleCacheCapacity(Integer ruleCacheCapacity) { + this.ruleCacheCapacity = ruleCacheCapacity; + } + + public boolean isRuleCacheEnabled() { + return ObjectUtil.isNotNull(ruleCacheCapacity) && ruleCacheCapacity > 0; + } } diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java index a758fd6069ed8e1fdb5ec8291e28ef4706ee37e8..4b8c884432ad61c080199dad9089d2f00879a3d7 100644 --- a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java +++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java @@ -6,11 +6,14 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrFormatter; import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.core.FlowInitHook; +import com.yomahub.liteflow.flow.cache.ChainRepository; import com.yomahub.liteflow.parser.constant.ReadType; import com.yomahub.liteflow.parser.el.ClassXmlFlowELParser; import com.yomahub.liteflow.parser.sql.exception.ELSQLException; +import com.yomahub.liteflow.parser.sql.finder.SQLChainFinder; import com.yomahub.liteflow.parser.sql.read.SqlReadFactory; import com.yomahub.liteflow.parser.sql.util.JDBCHelper; +import com.yomahub.liteflow.parser.sql.util.SQLUtil; import com.yomahub.liteflow.parser.sql.vo.SQLParserVO; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.property.LiteflowConfigGetter; @@ -49,6 +52,18 @@ public class SQLXmlELParser extends ClassXmlFlowELParser { throw new ELSQLException(ERROR_COMMON_MSG); } + if (liteflowConfig.isRuleCacheEnabled()) { + // 启用规则缓存则禁用轮询 + sqlParserVO.setPollingEnabled(false); + // 如果用户设置了自定义SQL,则初次查询的chain数据由用户决定 + // 否则限制初次查询返回的chain的数量 + if (StrUtil.isBlank(sqlParserVO.getChainCustomSql())) { + String querySql = SQLUtil.buildLimitChainsQuerySql(sqlParserVO, liteflowConfig.getRuleCacheCapacity()); + sqlParserVO.setChainCustomSql(querySql); + } + ChainRepository.addFinder(new SQLChainFinder()); + } + // 检查配置文件 checkParserVO(sqlParserVO); diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/finder/SQLChainFinder.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/finder/SQLChainFinder.java new file mode 100644 index 0000000000000000000000000000000000000000..d1713661d73b98dc55999ae05cec4fa78b20d4aa --- /dev/null +++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/finder/SQLChainFinder.java @@ -0,0 +1,54 @@ +package com.yomahub.liteflow.parser.sql.finder; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.exception.ChainDuplicateException; +import com.yomahub.liteflow.flow.cache.ChainFinder; +import com.yomahub.liteflow.flow.cache.RawChain; +import com.yomahub.liteflow.parser.constant.ReadType; +import com.yomahub.liteflow.parser.sql.read.SqlRead; +import com.yomahub.liteflow.parser.sql.read.SqlReadFactory; +import com.yomahub.liteflow.parser.sql.read.impl.ChainRead; +import com.yomahub.liteflow.parser.sql.read.vo.ChainVO; +import com.yomahub.liteflow.parser.sql.util.SQLUtil; +import com.yomahub.liteflow.parser.sql.vo.SQLParserVO; + +import java.util.List; + +/** + * SQL数据源的ChainFinder实现 + * @author DaleLee + * @since + */ +public class SQLChainFinder implements ChainFinder { + + @Override + public RawChain findChainById(String chainId) { + SqlRead sqlRead = SqlReadFactory.getSqlRead(ReadType.CHAIN); + ChainRead chainRead = (ChainRead) sqlRead; + SQLParserVO config = chainRead.config; + // 构建chain查询sql + String sql = SQLUtil.buildChainQuerySQL(config, chainId); + List chainVOList = chainRead.read(sql); + if (CollUtil.isEmpty(chainVOList)) { + return null; + } + if (chainVOList.size() > 1) { + throw new ChainDuplicateException("SQL data source chain duplicate, chainName: " + chainId); + } + ChainVO chainVO = chainVOList.get(0); + return covert2RawChain(chainVO); + } + + private RawChain covert2RawChain(ChainVO chainVO) { + if (chainVO == null) { + return null; + } + RawChain rawChain = new RawChain(); + rawChain.setChainId(chainVO.getChainId()); + rawChain.setEl(chainVO.getBody()); + rawChain.setNamespace(chainVO.getNamespace()); + rawChain.setRoute(chainVO.getRoute()); + return rawChain; + } +} diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java index 01cb01148e0182a7a1092221f954827ca6644496..56e5267aaf093323bdfa89a1618dd4f02633e288 100644 --- a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java +++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java @@ -41,6 +41,11 @@ public abstract class AbstractSqlRead implements SqlRead { // 如果允许,就打印 sql 语句 logSqlIfEnable(sqlCmd); + return read(sqlCmd); + } + + @Override + public List read(String sqlCmd) { List result = new ArrayList<>(); Connection conn = null; PreparedStatement stmt = null; diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java index b56b31a30c6edc3a286b794fab418640265f9419..d18e1736492a93b5005d1ff1565c62d8164a8deb 100644 --- a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java +++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java @@ -9,6 +9,7 @@ import java.util.List; * * @author tangkc * @author houxinyu + * @author DaleLee * @since 2.11.1 */ public interface SqlRead { @@ -20,6 +21,14 @@ public interface SqlRead { */ List read(); + /** + * 通过指定SQL读取 + * + * @param sqlCmd SQL命令 + * @return 返回读取到的数据 + */ + List read(String sqlCmd); + /** * 类型 * diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/util/SQLUtil.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/util/SQLUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..b4becdd122aeee033cf280d89b26e3192c65b398 --- /dev/null +++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/util/SQLUtil.java @@ -0,0 +1,42 @@ +package com.yomahub.liteflow.parser.sql.util; + +import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.parser.sql.vo.SQLParserVO; + +/** + * SQL构建工具类 + */ +public class SQLUtil { + + private static final String SQL_PATTERN = "SELECT * FROM {} WHERE {}='{}' AND {}='{}'"; + + private static final String SQL_PATTERN_WITH_LIMIT = "SELECT * FROM {} WHERE {}='{}' LIMIT {}"; + + /** + * 构建查询指定条数chain的SQL + * @param config SQL配置 + * @param limit 上限 + * @return SQL + */ + public static String buildLimitChainsQuerySql(SQLParserVO config, Integer limit) { + String chainTableName = config.getChainTableName(); + String chainApplicationNameField = config.getChainApplicationNameField(); + String applicationName = config.getApplicationName(); + return StrUtil.format(SQL_PATTERN_WITH_LIMIT, chainTableName, chainApplicationNameField, applicationName, limit); + } + + /** + * 构建查询某一个chain的SQL + * @param config SQL配置 + * @param chainId chainId + * @return SQL + */ + public static String buildChainQuerySQL(SQLParserVO config, String chainId) { + String chainTableName = config.getChainTableName(); + String chainApplicationNameField = config.getChainApplicationNameField(); + String applicationName = config.getApplicationName(); + String chainNameField = config.getChainNameField(); + return StrUtil.format(SQL_PATTERN, chainTableName, chainApplicationNameField, applicationName, + chainNameField, chainId); + } +} diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index 930a62d4c919f4751e09790e3473f5a9a932ae50..0e37d6495c662442ed4173702d70a0190a2a9970 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -101,6 +101,9 @@ public class LiteflowProperty { //脚本特殊设置选项 private Map scriptSetting; + // 规则缓存容量 + private Integer ruleCacheCapacity; + public boolean isEnableMonitorFile() { return enableMonitorFile; } @@ -336,4 +339,12 @@ public class LiteflowProperty { public void setScriptSetting(Map scriptSetting) { this.scriptSetting = scriptSetting; } + + public Integer getRuleCacheCapacity() { + return ruleCacheCapacity; + } + + public void setRuleCacheCapacity(Integer ruleCacheCapacity) { + this.ruleCacheCapacity = ruleCacheCapacity; + } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java index 37356fcb3a9c0db16f3061022781b13680d2a8d7..f3fd544866c6144324677f8f88dc4437fa3bbd91 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java @@ -54,6 +54,7 @@ public class LiteflowPropertyAutoConfiguration { liteflowConfig.setDelay(liteflowMonitorProperty.getDelay()); liteflowConfig.setPeriod(liteflowMonitorProperty.getPeriod()); liteflowConfig.setScriptSetting(property.getScriptSetting()); + liteflowConfig.setRuleCacheCapacity(property.getRuleCacheCapacity()); return liteflowConfig; } diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/SQLWithXmlELRuleCacheSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/SQLWithXmlELRuleCacheSpringbootTest.java new file mode 100644 index 0000000000000000000000000000000000000000..37345c445fbbd7de71253aec24ec7dbe8662e548 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/SQLWithXmlELRuleCacheSpringbootTest.java @@ -0,0 +1,56 @@ +package com.yomahub.liteflow.test.ruleCache; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.exception.ChainNotFoundException; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import javax.annotation.Resource; + +/** + * SQL数据源规则缓存测试 + * @author DaleLee + * @since + */ +@ExtendWith(SpringExtension.class) +@TestPropertySource(value = "classpath:/application-rule-cache.properties") +@SpringBootTest(classes = SQLWithXmlELRuleCacheSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.ruleCache.cmp" }) +public class SQLWithXmlELRuleCacheSpringbootTest extends BaseTest { + @Resource + private FlowExecutor flowExecutor; + + @Test + public void testRuleCache() throws Exception{ + // 缓存大小为3 + Assertions.assertEquals(3, FlowBus.getChainMap().size()); + // 缓存命中的情况 + Assertions.assertTrue(FlowBus.containChain("chain1")); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + + // 缓存未命中,但加载成功 + Assertions.assertFalse(FlowBus.containChain("")); + response = flowExecutor.execute2Resp("", "arg"); + Assertions.assertEquals("x0[if 脚本]==>a==>b", response.getExecuteStepStr()); + // 已加载 + Assertions.assertTrue(FlowBus.containChain("")); + + // 缓存未命中,且加载失败 + Assertions.assertFalse(FlowBus.containChain("chain5")); + response = flowExecutor.execute2Resp("chain5", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getSlot().getException().getClass()); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java new file mode 100644 index 0000000000000000000000000000000000000000..20d073b52e0017cb21d8005c168f4c0b71ca8341 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java new file mode 100644 index 0000000000000000000000000000000000000000..c79f55d47dbb1fa1e9bf2af41ee4658e67487173 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java new file mode 100644 index 0000000000000000000000000000000000000000..adcf920f6723379c4eb1c7f2438cb1d710246b50 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/sql/cmp/X0Cmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/sql/cmp/X0Cmp.java new file mode 100644 index 0000000000000000000000000000000000000000..f7133f2bffb22cf6afb63a05465764b3fae493ba --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/sql/cmp/X0Cmp.java @@ -0,0 +1,5 @@ +package com.yomahub.liteflow.test.sql.cmp; + + +public class X0Cmp { +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/resources/application-rule-cache.properties b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/resources/application-rule-cache.properties new file mode 100644 index 0000000000000000000000000000000000000000..a97a0a1aa25baa253d7060de55cb58d3c68b3ec3 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/resources/application-rule-cache.properties @@ -0,0 +1,26 @@ +liteflow.rule-source-ext-data={\ + "url":"jdbc:h2:mem:test_db;MODE=MySQL",\ + "driverClassName":"org.h2.Driver",\ + "username":"root",\ + "password":"123456",\ + "applicationName":"demo",\ + "chainTableName":"EL_TABLE",\ + "chainApplicationNameField":"application_name",\ + "chainNameField":"chain_name",\ + "elDataField":"EL_DATA",\ + "scriptTableName":"script_node_table",\ + "scriptApplicationNameField":"application_name",\ + "scriptIdField":"script_node_id",\ + "scriptNameField":"script_node_name",\ + "scriptDataField":"script_node_data",\ + "scriptLanguageField":"script_language",\ + "scriptTypeField":"script_node_type"\ + } +liteflow.rule-cache-capacity=3 +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:test_db;MODE=MySQL +spring.datasource.username=root +spring.datasource.password=123456 +spring.datasource.schema=classpath:/sql/schema.sql +spring.datasource.data=classpath:/sql/data.sql +spring.datasource.platform=h2 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 00b1a19986dc5e63190b34ddb11f12e93b4de5a2..9970b5991f95f346fd5d50c963227dec6fdafea5 100644 --- a/pom.xml +++ b/pom.xml @@ -78,6 +78,7 @@ 3.1.12 1.9.23 1.3.6 + 2.9.3 @@ -326,6 +327,11 @@ liquor-eval ${liquor.version} + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} +