From 36526c1903645851f065e2a2218046ec2b7de150 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Wed, 15 Mar 2023 19:11:26 +0800 Subject: [PATCH] =?UTF-8?q?feature=20#I6NGM3=20LiteFlow=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=A4=9A=E7=A7=8D=E4=B8=8D=E5=90=8C=E8=AF=AD=E8=A8=80=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E6=B7=B7=E5=90=88=E8=B0=83=E7=94=A8=E7=9A=84=E7=89=B9?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/builder/LiteFlowNodeBuilder.java | 7 ++- .../liteflow/builder/prop/NodePropBean.java | 14 +++++ .../liteflow/common/ChainConstant.java | 2 + .../liteflow/core/ScriptBreakComponent.java | 6 +-- .../liteflow/core/ScriptCommonComponent.java | 6 +-- .../liteflow/core/ScriptComponent.java | 2 +- .../liteflow/core/ScriptForComponent.java | 6 +-- .../liteflow/core/ScriptIfComponent.java | 6 +-- .../liteflow/core/ScriptSwitchComponent.java | 6 +-- .../liteflow/core/ScriptWhileComponent.java | 6 +-- .../liteflow/enums/ScriptTypeEnum.java | 44 ++++++++++++++++ .../com/yomahub/liteflow/flow/FlowBus.java | 18 +++---- .../yomahub/liteflow/flow/element/Node.java | 10 ++++ .../yomahub/liteflow/monitor/MonitorFile.java | 1 - .../liteflow/parser/helper/ParserHelper.java | 8 ++- .../liteflow/script/ScriptExecutor.java | 4 ++ .../script/ScriptExecutorFactory.java | 52 +++++++++++++++---- .../script/jsr223/JSR223ScriptExecutor.java | 4 +- .../graaljs/GraalJavaScriptExecutor.java | 6 +++ .../script/groovy/GroovyScriptExecutor.java | 5 +- .../script/javascript/JavaScriptExecutor.java | 11 ++-- .../script/lua/LuaScriptExecutor.java | 5 +- .../script/python/PythonScriptExecutor.java | 5 +- .../qlexpress/QLExpressScriptExecutor.java | 6 +++ .../monitorFile/LiteflowMonitorFileTest.java | 1 - .../pom.xml | 44 ++++++++++++++++ .../com/yomahub/liteflow/test/BaseTest.java | 22 ++++++++ .../multi/language/MultiLanguageELTest.java | 51 ++++++++++++++++++ .../test/script/multi/language/cmp/ACmp.java | 20 +++++++ .../test/script/multi/language/cmp/BCmp.java | 21 ++++++++ .../test/script/multi/language/cmp/CCmp.java | 21 ++++++++ .../multiLanguage/application.properties | 1 + .../src/test/resources/multiLanguage/flow.xml | 42 +++++++++++++++ .../test/catchcase/CatchELSpringbootTest.java | 4 +- .../monitorFile/application.properties | 3 +- liteflow-testcase-el/pom.xml | 1 + 36 files changed, 411 insertions(+), 60 deletions(-) create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/pom.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/MultiLanguageELTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/CCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/flow.xml diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java index 9321da703..3849e3a0e 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java @@ -146,12 +146,17 @@ public class LiteFlowNodeBuilder { return this; } + public LiteFlowNodeBuilder setLanguage(String language) { + this.node.setLanguage(language); + return this; + } + public void build() { checkBuild(); try { // 用于处理脚本 node if (this.node.getType().isScript()){ - FlowBus.addScriptNode(this.node.getId(), this.node.getName(), this.node.getType(), this.node.getScript()); + FlowBus.addScriptNode(this.node.getId(), this.node.getName(), this.node.getType(), this.node.getScript(), this.node.getLanguage()); } // 用于处理普通 node else{ diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/prop/NodePropBean.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/prop/NodePropBean.java index ac674c2c5..1a0741cfa 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/prop/NodePropBean.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/prop/NodePropBean.java @@ -35,6 +35,11 @@ public class NodePropBean { */ String file; + /** + * 脚本语言 + */ + String language; + public String getId() { return id; } @@ -88,4 +93,13 @@ public class NodePropBean { this.file = file; return this; } + + public String getLanguage() { + return language; + } + + public NodePropBean setLanguage(String language) { + this.language = language; + return this; + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java b/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java index 745765b40..5d1315471 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java @@ -23,6 +23,8 @@ public interface ChainConstant { String NAME = "name"; + String LANGUAGE = "language"; + String VALUE = "value"; String ANY = "any"; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptBreakComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptBreakComponent.java index e34b0f704..83f8d347c 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptBreakComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptBreakComponent.java @@ -19,11 +19,11 @@ public class ScriptBreakComponent extends NodeBreakComponent implements ScriptCo wrap.setSlotIndex(this.getSlotIndex()); wrap.setTag(this.getTag()); wrap.setCmpData(this.getCmpData(Map.class)); - return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap); + return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap); } @Override - public void loadScript(String script) { - ScriptExecutorFactory.loadInstance().getScriptExecutor().load(getNodeId(), script); + public void loadScript(String script, String language) { + ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptCommonComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptCommonComponent.java index 6956c673f..8187849f9 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptCommonComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptCommonComponent.java @@ -24,12 +24,12 @@ public class ScriptCommonComponent extends NodeComponent implements ScriptCompon wrap.setSlotIndex(this.getSlotIndex()); wrap.setTag(this.getTag()); wrap.setCmpData(this.getCmpData(Map.class)); - ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap); + ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap); } @Override - public void loadScript(String script) { + public void loadScript(String script, String language) { log.info("load script for component[{}]", getDisplayName()); - ScriptExecutorFactory.loadInstance().getScriptExecutor().load(getNodeId(), script); + ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java index 8a95c8840..efb8009f5 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java @@ -28,5 +28,5 @@ public interface ScriptComponent { * 加载脚本 * @param script */ - void loadScript(String script); + void loadScript(String script, String language); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptForComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptForComponent.java index 4196f6019..bb2cf78c3 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptForComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptForComponent.java @@ -19,11 +19,11 @@ public class ScriptForComponent extends NodeForComponent implements ScriptCompon wrap.setSlotIndex(this.getSlotIndex()); wrap.setTag(this.getTag()); wrap.setCmpData(this.getCmpData(Map.class)); - return (int) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap); + return (int) ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap); } @Override - public void loadScript(String script) { - ScriptExecutorFactory.loadInstance().getScriptExecutor().load(getNodeId(), script); + public void loadScript(String script, String language) { + ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptIfComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptIfComponent.java index 167782e1a..4e74abf92 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptIfComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptIfComponent.java @@ -19,11 +19,11 @@ public class ScriptIfComponent extends NodeIfComponent implements ScriptComponen wrap.setSlotIndex(this.getSlotIndex()); wrap.setTag(this.getTag()); wrap.setCmpData(this.getCmpData(Map.class)); - return (boolean)ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap); + return (boolean)ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap); } @Override - public void loadScript(String script) { - ScriptExecutorFactory.loadInstance().getScriptExecutor().load(getNodeId(), script); + public void loadScript(String script, String language) { + ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptSwitchComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptSwitchComponent.java index b77faca46..808a3c6d0 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptSwitchComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptSwitchComponent.java @@ -20,11 +20,11 @@ public class ScriptSwitchComponent extends NodeSwitchComponent implements Script wrap.setSlotIndex(this.getSlotIndex()); wrap.setTag(this.getTag()); wrap.setCmpData(this.getCmpData(Map.class)); - return (String)ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap); + return (String)ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap); } @Override - public void loadScript(String script) { - ScriptExecutorFactory.loadInstance().getScriptExecutor().load(getNodeId(), script); + public void loadScript(String script, String language) { + ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptWhileComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptWhileComponent.java index 9f1339fe6..6ed651207 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptWhileComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptWhileComponent.java @@ -20,11 +20,11 @@ public class ScriptWhileComponent extends NodeWhileComponent implements ScriptCo wrap.setSlotIndex(this.getSlotIndex()); wrap.setTag(this.getTag()); wrap.setCmpData(this.getCmpData(Map.class)); - return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap); + return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor(this.getRefNode().getLanguage()).execute(wrap); } @Override - public void loadScript(String script) { - ScriptExecutorFactory.loadInstance().getScriptExecutor().load(getNodeId(), script); + public void loadScript(String script, String language) { + ScriptExecutorFactory.loadInstance().getScriptExecutor(language).load(getNodeId(), script); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java new file mode 100644 index 000000000..512b05cbc --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java @@ -0,0 +1,44 @@ +package com.yomahub.liteflow.enums; + +public enum ScriptTypeEnum { + + GROOVY("groovy", "groovy"), + QLEXPRESS("qlexpress", "qlexpress"), + JS("javascript", "js"), + PYTHON("python", "python"), + LUA("luaj", "lua") + ; + private String engineName; + + private String displayName; + + ScriptTypeEnum(String engineName, String displayName) { + this.engineName = engineName; + this.displayName = displayName; + } + + public String getEngineName() { + return engineName; + } + + public void setEngineName(String engineName) { + this.engineName = engineName; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public static ScriptTypeEnum getEnumByDisplayName(String displayName) { + for (ScriptTypeEnum e : ScriptTypeEnum.values()) { + if (e.getDisplayName().equals(displayName)) { + return e; + } + } + return null; + } +} 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 95e2b1aa1..67b0c55b8 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 @@ -106,7 +106,7 @@ public class FlowBus { * @param cmpClazz 节点组件类 */ public static void addNode(String nodeId, String name, NodeTypeEnum type, Class cmpClazz) { - addNode(nodeId, name, type, cmpClazz, null); + addNode(nodeId, name, type, cmpClazz, null, null); } /** @@ -124,7 +124,7 @@ public class FlowBus { } catch (Exception e) { throw new ComponentCannotRegisterException(e.getMessage()); } - addNode(nodeId, name, nodeType, cmpClazz, null); + addNode(nodeId, name, nodeType, cmpClazz, null, null); } /** @@ -135,11 +135,11 @@ public class FlowBus { * @param nodeType 节点类型 * @param script 脚本 */ - public static void addScriptNode(String nodeId, String name, NodeTypeEnum nodeType, String script) { - addNode(nodeId, name, nodeType, ScriptComponent.ScriptComponentClassMap.get(nodeType), script); + public static void addScriptNode(String nodeId, String name, NodeTypeEnum nodeType, String script, String language) { + addNode(nodeId, name, nodeType, ScriptComponent.ScriptComponentClassMap.get(nodeType), script, language); } - private static void addNode(String nodeId, String name, NodeTypeEnum type, Class cmpClazz, String script) { + private static void addNode(String nodeId, String name, NodeTypeEnum type, Class cmpClazz, String script, String language) { try { //判断此类是否是声明式的组件,如果是声明式的组件,就用动态代理生成实例 //如果不是声明式的,就用传统的方式进行判断 @@ -193,7 +193,8 @@ public class FlowBus { if (type.isScript()) { if (StrUtil.isNotBlank(script)) { node.setScript(script); - ((ScriptComponent) cmpInstance).loadScript(script); + node.setLanguage(language); + ((ScriptComponent) cmpInstance).loadScript(script, language); } else { String errorMsg = StrUtil.format("script for node[{}] is empty", nodeId); throw new ScriptLoadException(errorMsg); @@ -244,10 +245,7 @@ public class FlowBus { public static void cleanScriptCache() { //如果引入了脚本组件SPI,则还需要清理脚本的缓存 try { - ScriptExecutor scriptExecutor = ScriptExecutorFactory.loadInstance().getScriptExecutor(); - if (ObjectUtil.isNotNull(scriptExecutor)) { - scriptExecutor.cleanCache(); - } + ScriptExecutorFactory.loadInstance().cleanScriptCache(); } catch (ScriptSpiException ignored) { } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java index fc0cf0d01..63937f9f8 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java @@ -46,6 +46,8 @@ public class Node implements Executable,Cloneable{ private String script; + private String language; + private NodeComponent instance; private String tag; @@ -255,4 +257,12 @@ public class Node implements Executable,Cloneable{ public void removeCurrLoopObject(){ this.currLoopObject.remove(); } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java b/liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java index c5be34129..cfbb5e206 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java @@ -51,7 +51,6 @@ public class MonitorFile { */ public void create() { for (String filePath : CollUtil.distinct(PATH_LIST)) { - // 这里只监听两种类型,文件修改和文件覆盖 WatchMonitor.createAll(filePath, new SimpleWatcher(){ @Override public void onModify(WatchEvent event, Path currentPath) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java index 1ef8f4c48..627b9a220 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java @@ -44,6 +44,7 @@ public class ParserHelper { String script = nodePropBean.getScript(); String type = nodePropBean.getType(); String file = nodePropBean.getFile(); + String language = nodePropBean.getLanguage(); //clazz有值的,基本都不是脚本节点 //脚本节点,都必须配置type @@ -80,6 +81,7 @@ public class ParserHelper { .setType(nodeTypeEnum) .setScript(script) .setFile(file) + .setLanguage(language) .build(); } @@ -98,7 +100,7 @@ public class ParserHelper { // 当存在节点定义时,解析node节点 if (ObjectUtil.isNotNull(nodesElement)) { List nodeList = nodesElement.elements(NODE); - String id, name, clazz, type, script, file; + String id, name, clazz, type, script, file, language; for (Element e : nodeList) { id = e.attributeValue(ID); name = e.attributeValue(NAME); @@ -106,6 +108,7 @@ public class ParserHelper { type = e.attributeValue(TYPE); script = e.getText(); file = e.attributeValue(FILE); + language = e.attributeValue(LANGUAGE); // 构建 node NodePropBean nodePropBean = new NodePropBean() @@ -114,7 +117,8 @@ public class ParserHelper { .setClazz(clazz) .setScript(script) .setType(type) - .setFile(file); + .setFile(file) + .setLanguage(language); ParserHelper.buildNode(nodePropBean); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutor.java index 9b96f129c..49c9910ab 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutor.java @@ -1,5 +1,7 @@ package com.yomahub.liteflow.script; +import com.yomahub.liteflow.enums.ScriptTypeEnum; + /** * 脚本执行器接口 * @author Bryan.Zhang @@ -14,4 +16,6 @@ public interface ScriptExecutor { Object execute(ScriptExecuteWrap wrap) throws Exception; void cleanCache(); + + ScriptTypeEnum scriptType(); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutorFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutorFactory.java index 076ab298f..5f0729c37 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutorFactory.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutorFactory.java @@ -1,9 +1,15 @@ package com.yomahub.liteflow.script; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.exception.ScriptSpiException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import java.util.ServiceLoader; +import java.util.function.Consumer; /** * 脚本执行器工厂类 @@ -14,7 +20,9 @@ public class ScriptExecutorFactory { private static ScriptExecutorFactory scriptExecutorFactory; - private ScriptExecutor scriptExecutor; + private final Map scriptExecutorMap = new HashMap<>(); + + private final String NONE_LANGUAGE = "none"; public static ScriptExecutorFactory loadInstance(){ if (ObjectUtil.isNull(scriptExecutorFactory)){ @@ -23,17 +31,43 @@ public class ScriptExecutorFactory { return scriptExecutorFactory; } - public ScriptExecutor getScriptExecutor(){ - if (ObjectUtil.isNull(scriptExecutor)){ + public ScriptExecutor getScriptExecutor(String language){ + if (StrUtil.isBlank(language)){ + language = NONE_LANGUAGE; + } + + + if (!scriptExecutorMap.containsKey(language)){ ServiceLoader loader = ServiceLoader.load(ScriptExecutor.class); - if (loader.iterator().hasNext()){ - scriptExecutor = loader.iterator().next().init(); - return scriptExecutor; - }else{ - throw new ScriptSpiException("script spi component failed to load"); + ScriptExecutor scriptExecutor; + Iterator it = loader.iterator(); + while(it.hasNext()){ + scriptExecutor = it.next().init(); + if (language.equals(NONE_LANGUAGE)){ + scriptExecutorMap.put(language, scriptExecutor); + break; + }else{ + ScriptTypeEnum scriptType = ScriptTypeEnum.getEnumByDisplayName(language); + if (ObjectUtil.isNull(scriptType)){ + throw new ScriptSpiException("script language config error"); + } + if (scriptType.equals(scriptExecutor.scriptType())){ + scriptExecutorMap.put(language, scriptExecutor); + break; + } + } } } - return scriptExecutor; + + if (scriptExecutorMap.containsKey(language)){ + return scriptExecutorMap.get(language); + }else{ + throw new ScriptSpiException("script spi component failed to load"); + } + } + + public void cleanScriptCache(){ + this.scriptExecutorMap.forEach((key, value) -> value.cleanCache()); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java index c96d71c16..72b8b95a3 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java @@ -36,12 +36,10 @@ public abstract class JSR223ScriptExecutor implements ScriptExecutor { @Override public ScriptExecutor init() { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); - scriptEngine = scriptEngineManager.getEngineByName(scriptEngineName()); + scriptEngine = scriptEngineManager.getEngineByName(this.scriptType().getEngineName()); return this; } - protected abstract String scriptEngineName(); - protected String convertScript(String script){ return script; } diff --git a/liteflow-script-plugin/liteflow-script-graaljs/src/main/java/com/yomahub/liteflow/script/graaljs/GraalJavaScriptExecutor.java b/liteflow-script-plugin/liteflow-script-graaljs/src/main/java/com/yomahub/liteflow/script/graaljs/GraalJavaScriptExecutor.java index 88be9ae4f..c6350fa55 100644 --- a/liteflow-script-plugin/liteflow-script-graaljs/src/main/java/com/yomahub/liteflow/script/graaljs/GraalJavaScriptExecutor.java +++ b/liteflow-script-plugin/liteflow-script-graaljs/src/main/java/com/yomahub/liteflow/script/graaljs/GraalJavaScriptExecutor.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.annotation.util.AnnoUtil; import com.yomahub.liteflow.context.ContextBean; +import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.ScriptBeanManager; import com.yomahub.liteflow.script.ScriptExecuteWrap; import com.yomahub.liteflow.script.ScriptExecutor; @@ -111,4 +112,9 @@ public class GraalJavaScriptExecutor implements ScriptExecutor { public void cleanCache() { scriptMap.clear(); } + + @Override + public ScriptTypeEnum scriptType() { + return ScriptTypeEnum.JS; + } } diff --git a/liteflow-script-plugin/liteflow-script-groovy/src/main/java/com/yomahub/liteflow/script/groovy/GroovyScriptExecutor.java b/liteflow-script-plugin/liteflow-script-groovy/src/main/java/com/yomahub/liteflow/script/groovy/GroovyScriptExecutor.java index c4654629b..645495395 100644 --- a/liteflow-script-plugin/liteflow-script-groovy/src/main/java/com/yomahub/liteflow/script/groovy/GroovyScriptExecutor.java +++ b/liteflow-script-plugin/liteflow-script-groovy/src/main/java/com/yomahub/liteflow/script/groovy/GroovyScriptExecutor.java @@ -1,5 +1,6 @@ package com.yomahub.liteflow.script.groovy; +import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor; /** @@ -10,7 +11,7 @@ import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor; public class GroovyScriptExecutor extends JSR223ScriptExecutor { @Override - protected String scriptEngineName() { - return "groovy"; + public ScriptTypeEnum scriptType() { + return ScriptTypeEnum.GROOVY; } } diff --git a/liteflow-script-plugin/liteflow-script-javascript/src/main/java/com/yomahub/liteflow/script/javascript/JavaScriptExecutor.java b/liteflow-script-plugin/liteflow-script-javascript/src/main/java/com/yomahub/liteflow/script/javascript/JavaScriptExecutor.java index 9af7a2fd5..13c387b24 100644 --- a/liteflow-script-plugin/liteflow-script-javascript/src/main/java/com/yomahub/liteflow/script/javascript/JavaScriptExecutor.java +++ b/liteflow-script-plugin/liteflow-script-javascript/src/main/java/com/yomahub/liteflow/script/javascript/JavaScriptExecutor.java @@ -1,6 +1,7 @@ package com.yomahub.liteflow.script.javascript; import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor; /** * JavaScript脚本语言的执行器实现 @@ -9,13 +10,13 @@ import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor; */ public class JavaScriptExecutor extends JSR223ScriptExecutor { - @Override - protected String scriptEngineName() { - return "javascript"; - } - @Override protected String convertScript(String script) { return StrUtil.format("function process(){{}} process();",script); } + + @Override + public ScriptTypeEnum scriptType() { + return ScriptTypeEnum.JS; + } } diff --git a/liteflow-script-plugin/liteflow-script-lua/src/main/java/com/yomahub/liteflow/script/lua/LuaScriptExecutor.java b/liteflow-script-plugin/liteflow-script-lua/src/main/java/com/yomahub/liteflow/script/lua/LuaScriptExecutor.java index 0f7a3cad7..1aff1228c 100644 --- a/liteflow-script-plugin/liteflow-script-lua/src/main/java/com/yomahub/liteflow/script/lua/LuaScriptExecutor.java +++ b/liteflow-script-plugin/liteflow-script-lua/src/main/java/com/yomahub/liteflow/script/lua/LuaScriptExecutor.java @@ -2,6 +2,7 @@ package com.yomahub.liteflow.script.lua; import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor; import java.util.Arrays; @@ -15,8 +16,8 @@ import java.util.stream.Collectors; */ public class LuaScriptExecutor extends JSR223ScriptExecutor { @Override - protected String scriptEngineName() { - return "luaj"; + public ScriptTypeEnum scriptType() { + return ScriptTypeEnum.LUA; } @Override diff --git a/liteflow-script-plugin/liteflow-script-python/src/main/java/com/yomahub/liteflow/script/python/PythonScriptExecutor.java b/liteflow-script-plugin/liteflow-script-python/src/main/java/com/yomahub/liteflow/script/python/PythonScriptExecutor.java index 151f54a5d..6968040b5 100644 --- a/liteflow-script-plugin/liteflow-script-python/src/main/java/com/yomahub/liteflow/script/python/PythonScriptExecutor.java +++ b/liteflow-script-plugin/liteflow-script-python/src/main/java/com/yomahub/liteflow/script/python/PythonScriptExecutor.java @@ -2,6 +2,7 @@ package com.yomahub.liteflow.script.python; import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor; import java.util.Arrays; import java.util.List; @@ -15,8 +16,8 @@ import java.util.stream.Collectors; public class PythonScriptExecutor extends JSR223ScriptExecutor { @Override - protected String scriptEngineName() { - return "python"; + public ScriptTypeEnum scriptType() { + return ScriptTypeEnum.PYTHON; } @Override diff --git a/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java b/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java index 4b55f80aa..db77dae4c 100644 --- a/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java +++ b/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java @@ -10,6 +10,7 @@ import com.ql.util.express.ExpressRunner; import com.ql.util.express.InstructionSet; import com.yomahub.liteflow.annotation.util.AnnoUtil; import com.yomahub.liteflow.context.ContextBean; +import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.ScriptBeanManager; import com.yomahub.liteflow.script.ScriptExecuteWrap; import com.yomahub.liteflow.slot.DataBus; @@ -116,4 +117,9 @@ public class QLExpressScriptExecutor implements ScriptExecutor { expressRunner.clearExpressCache(); ReflectUtil.setFieldValue(expressRunner,"loader",new ExpressLoader(expressRunner)); } + + @Override + public ScriptTypeEnum scriptType() { + return ScriptTypeEnum.QLEXPRESS; + } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java index 83c823a4a..2b4a509d7 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java @@ -32,7 +32,6 @@ public class LiteflowMonitorFileTest extends BaseTest { String content = FileUtil.readUtf8String(absolutePath); String newContent = content.replace("THEN(a, b, c);", "THEN(a, c, b);"); FileUtil.writeString(newContent, new File(absolutePath), CharsetUtil.CHARSET_UTF_8); - Thread.sleep(1000L); LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); Assert.assertEquals("a==>c==>b", response.getExecuteStepStr()); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/pom.xml b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/pom.xml new file mode 100644 index 000000000..9a730b95b --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + + com.yomahub + liteflow-testcase-el + ${revision} + + + liteflow-testcase-el-script-multi-language-springboot + + + + com.yomahub + liteflow-spring-boot-starter + ${revision} + + + com.yomahub + liteflow-script-groovy + ${revision} + test + + + com.yomahub + liteflow-script-javascript + ${revision} + test + + + com.yomahub + liteflow-script-python + ${revision} + test + + + org.springframework.boot + spring-boot-starter-test + + + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java new file mode 100644 index 000000000..02e76f923 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java @@ -0,0 +1,22 @@ +package com.yomahub.liteflow.test; + +import com.yomahub.liteflow.core.FlowInitHook; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.spi.holder.SpiFactoryCleaner; +import com.yomahub.liteflow.spring.ComponentScanner; +import com.yomahub.liteflow.thread.ExecutorHelper; +import org.junit.AfterClass; + +public class BaseTest { + + @AfterClass + public static void cleanScanCache(){ + ComponentScanner.cleanCache(); + FlowBus.cleanCache(); + ExecutorHelper.loadInstance().clearExecutorServiceMap(); + SpiFactoryCleaner.clean(); + LiteflowConfigGetter.clean(); + FlowInitHook.cleanHook(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/MultiLanguageELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/MultiLanguageELTest.java new file mode 100644 index 000000000..78f6e1936 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/MultiLanguageELTest.java @@ -0,0 +1,51 @@ +package com.yomahub.liteflow.test.script.multi.language; + +import cn.hutool.core.io.resource.ResourceUtil; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.enums.FlowParserTypeEnum; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.BaseTest; +import com.yomahub.liteflow.util.JsonUtil; +import groovy.lang.MetaClass; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +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.junit4.SpringRunner; + +import javax.annotation.Resource; +import java.util.Map; + + +/** + * 测试springboot下的groovy脚本组件,基于xml配置 + * @author Bryan.Zhang + * @since 2.6.0 + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/multiLanguage/application.properties") +@SpringBootTest(classes = MultiLanguageELTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.script.multi.language.cmp"}) +public class MultiLanguageELTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //测试普通脚本节点 + @Test + public void testMultiLanguage1() { + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + DefaultContext context = response.getFirstContextBean(); + Object student = context.getData("student"); + Map studentMap = JsonUtil.parseObject(JsonUtil.toJsonString(student), Map.class); + Assert.assertTrue(response.isSuccess()); + Assert.assertEquals(Integer.valueOf(18), context.getData("s1")); + Assert.assertEquals(10032, studentMap.get("studentID")); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/ACmp.java new file mode 100644 index 000000000..a9c0fd847 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.script.multi.language.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/BCmp.java new file mode 100644 index 000000000..b145ebb57 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/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.script.multi.language.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/cmp/CCmp.java new file mode 100644 index 000000000..c24a69bcf --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/java/com/yomahub/liteflow/test/script/multi/language/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.script.multi.language.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/application.properties b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/application.properties new file mode 100644 index 000000000..20bcec214 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=multiLanguage/flow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/flow.xml new file mode 100644 index 000000000..90d4b2f81 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-multi-language-springboot/src/test/resources/multiLanguage/flow.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + THEN(a, s1, b, s2, c, s3); + + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/catchcase/CatchELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/catchcase/CatchELSpringbootTest.java index 4841446e3..efec5a32b 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/catchcase/CatchELSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/catchcase/CatchELSpringbootTest.java @@ -46,14 +46,14 @@ public class CatchELSpringbootTest extends BaseTest { @Test public void testCatch3() throws Exception{ LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg"); - Assert.assertFalse(response.isSuccess()); + Assert.assertTrue(response.isSuccess()); Assert.assertEquals("a", response.getExecuteStepStrWithoutTime()); } @Test public void testCatch4() throws Exception{ LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg"); - Assert.assertFalse(response.isSuccess()); + Assert.assertTrue(response.isSuccess()); Assert.assertEquals("LOOP_3==>a==>b==>a==>b==>a==>b", response.getExecuteStepStrWithoutTime()); } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties index 361f7e90e..453d42ecd 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties @@ -1,2 +1,3 @@ -liteflow.rule-source=monitorFile/flow.el.xml +#???monitorFile??????rule.xml??????????????????????? +liteflow.rule-source=monitorFile/rule.xml liteflow.enable-monitor-file=true \ No newline at end of file diff --git a/liteflow-testcase-el/pom.xml b/liteflow-testcase-el/pom.xml index 0bd044434..f1011252d 100644 --- a/liteflow-testcase-el/pom.xml +++ b/liteflow-testcase-el/pom.xml @@ -32,6 +32,7 @@ liteflow-testcase-el-apollo-springboot liteflow-testcase-el-script-python-springboot liteflow-testcase-el-script-lua-springboot + liteflow-testcase-el-script-multi-language-springboot