From 37900a23030b2590af05f7271c3f182e41f39e8e Mon Sep 17 00:00:00 2001 From: zhanghua <964552300@qq.com> Date: Thu, 22 Dec 2022 12:30:35 +0800 Subject: [PATCH 01/36] =?UTF-8?q?1.=20ruleSource=E5=A4=9A=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=97=B6=E5=80=99=E4=B8=AD=E9=97=B4=E6=9C=89=E7=A9=BA?= =?UTF-8?q?=E6=A0=BC=E5=85=BC=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yomahub/liteflow/core/FlowExecutor.java | 13 ++++++++----- ...ubflowInDifferentConfigELDeclSpringbootTest.java | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) 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 4055c0db2..42bfaf8ba 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 @@ -27,6 +27,7 @@ import com.yomahub.liteflow.slot.DefaultContext; import com.yomahub.liteflow.slot.Slot; import com.yomahub.liteflow.spi.holder.ContextCmpInitHolder; import com.yomahub.liteflow.thread.ExecutorHelper; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,7 +83,8 @@ public class FlowExecutor { //进行id生成器的初始化 IdGeneratorHolder.init(); - if (StrUtil.isBlank(liteflowConfig.getRuleSource())) { + String ruleSource = liteflowConfig.getRuleSource(); + if (StrUtil.isBlank(ruleSource)) { //查看有没有Parser的SPI实现 //所有的Parser的SPI实现都是以custom形式放入的,且只支持xml形式 ServiceLoader loader = ServiceLoader.load(ParserClassNameSpi.class); @@ -100,10 +102,11 @@ public class FlowExecutor { //如果有前缀的,则不需要再进行分割了,说明是一个整体 //如果没有前缀,说明是本地文件,可能配置多个,所以需要分割 List sourceRulePathList; - if (ReUtil.contains(PREFIX_FORMAT_CONFIG_REGEX, liteflowConfig.getRuleSource())){ - sourceRulePathList = ListUtil.toList(liteflowConfig.getRuleSource()); - }else{ - sourceRulePathList = ListUtil.toList(liteflowConfig.getRuleSource().split(",|;")); + if (ReUtil.contains(PREFIX_FORMAT_CONFIG_REGEX, ruleSource)) { + sourceRulePathList = ListUtil.toList(ruleSource); + } else { + String afterHandleRuleSource = ruleSource.replace(StrUtil.SPACE, StrUtil.EMPTY); + sourceRulePathList = ListUtil.toList(afterHandleRuleSource.split(",|;")); } FlowParser parser = null; diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowInDifferentConfigELDeclSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowInDifferentConfigELDeclSpringbootTest.java index 83523d4f8..2bc3bf53e 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowInDifferentConfigELDeclSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowInDifferentConfigELDeclSpringbootTest.java @@ -47,7 +47,7 @@ public class SubflowInDifferentConfigELDeclSpringbootTest extends BaseTest { @Test(expected = MultipleParsersException.class) public void testExplicitSubFlow2() { LiteflowConfig config = context.getBean(LiteflowConfig.class); - config.setRuleSource("subflow/flow-main.xml,subflow/flow-sub1.xml,subflow/flow-sub2.yml"); + config.setRuleSource("subflow/flow-main.xml, subflow/flow-sub1.xml,subflow/flow-sub2.yml"); flowExecutor.reloadRule(); } } From e6ed271faebad53674774e756de83f608c421dc7 Mon Sep 17 00:00:00 2001 From: zhanghua <964552300@qq.com> Date: Thu, 22 Dec 2022 12:36:01 +0800 Subject: [PATCH 02/36] =?UTF-8?q?1.=20=E5=8E=BB=E6=8E=89=E6=97=A0=E7=94=A8?= =?UTF-8?q?import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/core/FlowExecutor.java | 1 - 1 file changed, 1 deletion(-) 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 42bfaf8ba..e45663937 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 @@ -27,7 +27,6 @@ import com.yomahub.liteflow.slot.DefaultContext; import com.yomahub.liteflow.slot.Slot; import com.yomahub.liteflow.spi.holder.ContextCmpInitHolder; import com.yomahub.liteflow.thread.ExecutorHelper; -import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; From 513d90db69d3daf0817a21508947b8f5b448d1ee Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Wed, 28 Dec 2022 20:29:02 +0800 Subject: [PATCH 03/36] =?UTF-8?q?hutool=E7=89=88=E6=9C=AC=E5=8D=87?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 99bd35eb5..7661e895d 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ 2.1.3 5.3.0 4.12 - 5.8.8 + 5.8.11 2.12.3 5.1.0 0.10 @@ -64,9 +64,7 @@ 1.11.13 1.8.13 1.2.3 - 1.12.0-M1 - 4.1.84.Final 31.1-jre 4.5.13 From df76a05c4f7c63caaff75bd74d69ec37e91c722f Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Thu, 5 Jan 2023 17:39:32 +0800 Subject: [PATCH 04/36] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E6=B3=9B=E5=9E=8B=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/yomahub/liteflow/core/NodeComponent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java index 5a397769c..a9f075f0e 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java @@ -135,7 +135,7 @@ public abstract class NodeComponent{ } } - public void beforeProcess(String nodeId, Slot slot){ + public void beforeProcess(String nodeId, Slot slot){ //全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类 //非spring环境下,全局切面为空实现 CmpAroundAspectHolder.loadCmpAroundAspect().beforeProcess(nodeId, slot); @@ -151,7 +151,7 @@ public abstract class NodeComponent{ //如果需要在抛错后回调某一段逻辑,请覆盖这个方法 } - public void afterProcess(String nodeId, Slot slot){ + public void afterProcess(String nodeId, Slot slot){ CmpAroundAspectHolder.loadCmpAroundAspect().afterProcess(nodeId, slot); } From db8f38846e96b8616ad7bedcfbe94a3ea30b8a0c Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Thu, 5 Jan 2023 19:51:27 +0800 Subject: [PATCH 05/36] =?UTF-8?q?enhancement=20#I691LD=20=E5=AF=B9beforePr?= =?UTF-8?q?ocess=E5=92=8CafterProcess=E4=B8=A4=E4=B8=AA=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=8F=82=E6=95=B0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/NodeComponent.java | 12 ++++----- .../liteflow/core/proxy/ComponentProxy.java | 27 +++++++------------ .../liteflow/solon/NodeComponentOfMethod.java | 4 +-- .../test/customMethodName/cmp/CmpConfig.java | 4 +-- .../test/customMethodName/cmp/ACmp.java | 4 +-- 5 files changed, 21 insertions(+), 30 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java index a9f075f0e..de2e6a1ca 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java @@ -92,7 +92,7 @@ public abstract class NodeComponent{ try{ //前置处理 - self.beforeProcess(this.getNodeId(), slot); + self.beforeProcess(); //主要的处理逻辑 self.process(); @@ -118,7 +118,7 @@ public abstract class NodeComponent{ throw e; } finally { //后置处理 - self.afterProcess(this.getNodeId(), slot); + self.afterProcess(); stopWatch.stop(); final long timeSpent = stopWatch.getTotalTimeMillis(); @@ -135,10 +135,10 @@ public abstract class NodeComponent{ } } - public void beforeProcess(String nodeId, Slot slot){ + public void beforeProcess(){ //全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类 //非spring环境下,全局切面为空实现 - CmpAroundAspectHolder.loadCmpAroundAspect().beforeProcess(nodeId, slot); + CmpAroundAspectHolder.loadCmpAroundAspect().beforeProcess(nodeId, this.getSlot()); } public abstract void process() throws Exception; @@ -151,8 +151,8 @@ public abstract class NodeComponent{ //如果需要在抛错后回调某一段逻辑,请覆盖这个方法 } - public void afterProcess(String nodeId, Slot slot){ - CmpAroundAspectHolder.loadCmpAroundAspect().afterProcess(nodeId, slot); + public void afterProcess(){ + CmpAroundAspectHolder.loadCmpAroundAspect().afterProcess(nodeId, this.getSlot()); } //是否进入该节点 diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/ComponentProxy.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/ComponentProxy.java index 4af0b8dd8..eb54fb175 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/ComponentProxy.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/ComponentProxy.java @@ -194,26 +194,17 @@ public class ComponentProxy { ).findFirst().orElse(null); //如果被代理的对象里有此标注标的方法,则调用此被代理的对象里的方法,如果没有,则调用父类里的方法 - //beforeProcess和afterProcess这2个方法除外 - if (!ListUtil.toList("beforeProcess","afterProcess").contains(liteFlowMethodBean.getMethodName())) { - //进行检查,检查被代理的bean里是否有且仅有NodeComponent这个类型的参数 - boolean checkFlag = liteFlowMethodBean.getMethod().getParameterTypes().length == 1 - && Arrays.asList(liteFlowMethodBean.getMethod().getParameterTypes()).contains(NodeComponent.class); - if (!checkFlag) { - String errMsg = StrUtil.format("Method[{}.{}] must have NodeComponent parameter(and only one parameter)", bean.getClass().getName(), liteFlowMethodBean.getMethod().getName()); - LOG.error(errMsg); - throw new ComponentMethodDefineErrorException(errMsg); - } - - try{ - return liteFlowMethodBean.getMethod().invoke(bean, proxy); - }catch (Exception e){ - InvocationTargetException targetEx = (InvocationTargetException)e; - throw targetEx.getTargetException(); - } + //进行检查,检查被代理的bean里是否有且仅有NodeComponent这个类型的参数 + boolean checkFlag = liteFlowMethodBean.getMethod().getParameterTypes().length == 1 + && Arrays.asList(liteFlowMethodBean.getMethod().getParameterTypes()).contains(NodeComponent.class); + if (!checkFlag) { + String errMsg = StrUtil.format("Method[{}.{}] must have NodeComponent parameter(and only one parameter)", bean.getClass().getName(), liteFlowMethodBean.getMethod().getName()); + LOG.error(errMsg); + throw new ComponentMethodDefineErrorException(errMsg); } + try{ - return liteFlowMethodBean.getMethod().invoke(bean, args); + return liteFlowMethodBean.getMethod().invoke(bean, proxy); }catch (Exception e){ InvocationTargetException targetEx = (InvocationTargetException)e; throw targetEx.getTargetException(); diff --git a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/NodeComponentOfMethod.java b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/NodeComponentOfMethod.java index fbc58edb3..c2665b9dc 100644 --- a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/NodeComponentOfMethod.java +++ b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/NodeComponentOfMethod.java @@ -53,7 +53,7 @@ public class NodeComponentOfMethod extends NodeComponent { @Override - public void beforeProcess(String nodeId, Slot slot) { + public void beforeProcess() { if(methodEnum != LiteFlowMethodEnum.BEFORE_PROCESS){ return; } @@ -68,7 +68,7 @@ public class NodeComponentOfMethod extends NodeComponent { } @Override - public void afterProcess(String nodeId, Slot slot) { + public void afterProcess() { if (methodEnum != LiteFlowMethodEnum.AFTER_PROCESS) { return; } diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/CmpConfig.java b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/CmpConfig.java index fd6293ca6..54ca00a24 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/CmpConfig.java +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/CmpConfig.java @@ -20,12 +20,12 @@ public class CmpConfig { } @LiteflowMethod(value = LiteFlowMethodEnum.BEFORE_PROCESS,nodeId = "a") - public void beforeAcmp(String nodeId, Slot slot){ + public void beforeAcmp(NodeComponent bindCmp){ System.out.println("before A"); } @LiteflowMethod(value = LiteFlowMethodEnum.AFTER_PROCESS,nodeId = "a") - public void afterAcmp(String nodeId, Slot slot){ + public void afterAcmp(NodeComponent bindCmp){ System.out.println("after A"); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/ACmp.java index 6944cecd8..acfbcbf06 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/ACmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/customMethodName/cmp/ACmp.java @@ -27,12 +27,12 @@ public class ACmp{ } @LiteflowMethod(LiteFlowMethodEnum.BEFORE_PROCESS) - public void beforeAcmp(String nodeId, Slot slot){ + public void beforeAcmp(NodeComponent bindCmp){ System.out.println("before A"); } @LiteflowMethod(LiteFlowMethodEnum.AFTER_PROCESS) - public void afterAcmp(String nodeId, Slot slot){ + public void afterAcmp(NodeComponent bindCmp){ System.out.println("after A"); } From 53adc62b9871a4e030d135196dff07c342d0ab36 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 6 Jan 2023 11:52:01 +0800 Subject: [PATCH 06/36] =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=88=B0v2.9.https://cloud.tencent.com/developer/article/11824?= =?UTF-8?q?407?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7661e895d..6f61a07ab 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ - 2.9.6 + 2.9.7 UTF-8 UTF-8 8 From e9a9a7e72de7dbea17a7bc993b530f969c7cd7f9 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 6 Jan 2023 11:53:17 +0800 Subject: [PATCH 07/36] =?UTF-8?q?Revert=20"=E7=89=88=E6=9C=AC=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=88=B0v2.9.https://cloud.tencent.com/developer/arti?= =?UTF-8?q?cle/11824407"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 53adc62b9871a4e030d135196dff07c342d0ab36. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6f61a07ab..7661e895d 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ - 2.9.7 + 2.9.6 UTF-8 UTF-8 8 From 6395f9e4a468b3c6de3aab293deca895f61d0222 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 6 Jan 2023 11:53:35 +0800 Subject: [PATCH 08/36] =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=88=B0v2.9.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7661e895d..6f61a07ab 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ - 2.9.6 + 2.9.7 UTF-8 UTF-8 8 From 0ef1593c8f7442bbbe18957a954c17467cbaf3e5 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Mon, 9 Jan 2023 13:46:15 +0800 Subject: [PATCH 09/36] =?UTF-8?q?=E4=BF=AE=E6=94=B9dtd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- liteflow-core/src/main/resources/dtd/liteflow.dtd | 1 + 1 file changed, 1 insertion(+) diff --git a/liteflow-core/src/main/resources/dtd/liteflow.dtd b/liteflow-core/src/main/resources/dtd/liteflow.dtd index d3faa5400..cee92d450 100644 --- a/liteflow-core/src/main/resources/dtd/liteflow.dtd +++ b/liteflow-core/src/main/resources/dtd/liteflow.dtd @@ -9,6 +9,7 @@ id CDATA #REQUIRED type (script|if_script|switch_script|while_script|for_script|break_script) #IMPLIED class CDATA #IMPLIED + file CDATA #IMPLIED language (groovy|js|python|lua) #IMPLIED > Date: Mon, 9 Jan 2023 13:46:32 +0800 Subject: [PATCH 10/36] =?UTF-8?q?solon=E7=89=88=E6=9C=AC=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6f61a07ab..7c832b3ec 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 1.11.13 1.8.13 1.2.3 - 1.12.0-M1 + 1.12.0 4.1.84.Final 31.1-jre 4.5.13 From c7c795f5b283538951005d6e176380e4183c0545 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Mon, 9 Jan 2023 19:11:11 +0800 Subject: [PATCH 11/36] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=9C=A8=E4=BD=BF?= =?UTF-8?q?=E7=94=A8Map=E4=BD=9C=E4=B8=BAcontext=E7=9A=84=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LiteFlowScriptScriptbeanGroovyELTest.java | 14 ++++++++++++++ .../src/test/resources/scriptbean/flow.xml | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java index 6eee3a732..64c78b0b7 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java @@ -3,6 +3,7 @@ package com.yomahub.liteflow.test.script.groovy.scriptbean; import com.yomahub.liteflow.core.FlowExecutor; import com.yomahub.liteflow.exception.ScriptBeanMethodInvokeException; import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.script.ScriptBeanManager; import com.yomahub.liteflow.slot.DefaultContext; import com.yomahub.liteflow.test.BaseTest; import org.junit.Assert; @@ -15,6 +16,8 @@ import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; @RunWith(SpringRunner.class) @TestPropertySource(value = "classpath:/scriptbean/application.properties") @@ -75,4 +78,15 @@ public class LiteFlowScriptScriptbeanGroovyELTest extends BaseTest { Assert.assertFalse(response.isSuccess()); Assert.assertEquals(ScriptBeanMethodInvokeException.class, response.getCause().getClass()); } + + //测试在ScriptBeanManager里放入上下文,实现自定义脚本引用名称 + @Test + public void testScriptBean7() throws Exception{ + Map map = new HashMap<>(); + ScriptBeanManager.addScriptBean("abcCx", map); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg", map); + Assert.assertTrue(response.isSuccess()); + Map context = response.getFirstContextBean(); + Assert.assertEquals("hello", context.get("demo")); + } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml index 397cff2c4..ac6c14749 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml @@ -43,6 +43,13 @@ defaultContext.setData("demo", str) ]]> + + + + @@ -68,4 +75,8 @@ THEN(a,b,c,s4); + + + THEN(a,b,c,s5); + \ No newline at end of file From 1299055a7c49ec81772761febbd4b2ebc230cc06 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Tue, 10 Jan 2023 19:06:18 +0800 Subject: [PATCH 12/36] =?UTF-8?q?bug=20#I69UVL=20=E5=A6=82=E6=9E=9Cswitch?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=B8=BA=E7=A9=BA=E6=88=96=E8=80=85null?= =?UTF-8?q?=EF=BC=8C=E6=97=A0=E6=B3=95=E9=80=89=E5=8F=96=E5=88=B0default?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../element/condition/SwitchCondition.java | 38 +++++++++---------- .../switchcase/SwitchELSpringbootTest.java | 8 ++++ .../test/switchcase/cmp/JSwitchCmp.java | 20 ++++++++++ .../src/test/resources/switchcase/flow.el.xml | 2 +- 4 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/cmp/JSwitchCmp.java diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java index 9f7a7c83d..9e26261df 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java @@ -45,9 +45,9 @@ public class SwitchCondition extends Condition{ //这里可能会有spring代理过的bean,所以拿到user原始的class Class originalClass = LiteFlowProxyUtil.getUserClass(this.getSwitchNode().getInstance().getClass()); String targetId = slot.getSwitchResult(originalClass.getName()); - if (StrUtil.isNotBlank(targetId)) { - Executable targetExecutor; + Executable targetExecutor = null; + if (StrUtil.isNotBlank(targetId)) { //这里要判断是否使用tag模式跳转 if (targetId.contains(TAG_FLAG)){ String[] target = targetId.split(TAG_FLAG, 2); @@ -66,26 +66,26 @@ public class SwitchCondition extends Condition{ executable -> executable.getExecuteId().equals(targetId) ).findFirst().orElse(null); } + } - if (ObjectUtil.isNull(targetExecutor)) { - //没有匹配到执行节点,则走默认的执行节点 - targetExecutor = defaultExecutor; - } + if (ObjectUtil.isNull(targetExecutor)) { + //没有匹配到执行节点,则走默认的执行节点 + targetExecutor = defaultExecutor; + } - if (ObjectUtil.isNotNull(targetExecutor)) { - //switch的目标不能是Pre节点或者Finally节点 - if (targetExecutor instanceof PreCondition || targetExecutor instanceof FinallyCondition){ - String errorInfo = StrUtil.format("[{}]:switch component[{}] error, switch target node cannot be pre or finally", - slot.getRequestId(), this.getSwitchNode().getInstance().getDisplayName()); - throw new SwitchTargetCannotBePreOrFinallyException(errorInfo); - } - targetExecutor.setCurrChainId(this.getCurrChainId()); - targetExecutor.execute(slotIndex); - }else{ - String errorInfo = StrUtil.format("[{}]:no target node find for the component[{}],target str is [{}]", - slot.getRequestId(), this.getSwitchNode().getInstance().getDisplayName(), targetId); - throw new NoSwitchTargetNodeException(errorInfo); + if (ObjectUtil.isNotNull(targetExecutor)) { + //switch的目标不能是Pre节点或者Finally节点 + if (targetExecutor instanceof PreCondition || targetExecutor instanceof FinallyCondition){ + String errorInfo = StrUtil.format("[{}]:switch component[{}] error, switch target node cannot be pre or finally", + slot.getRequestId(), this.getSwitchNode().getInstance().getDisplayName()); + throw new SwitchTargetCannotBePreOrFinallyException(errorInfo); } + targetExecutor.setCurrChainId(this.getCurrChainId()); + targetExecutor.execute(slotIndex); + }else{ + String errorInfo = StrUtil.format("[{}]:no target node find for the component[{}],target str is [{}]", + slot.getRequestId(), this.getSwitchNode().getInstance().getDisplayName(), targetId); + throw new NoSwitchTargetNodeException(errorInfo); } }else{ throw new SwitchTypeErrorException("switch instance must be NodeSwitchComponent"); diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java index c94bb45ee..97755dd8d 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java @@ -84,4 +84,12 @@ public class SwitchELSpringbootTest extends BaseTest { Assert.assertEquals("a==>i==>d",response.getExecuteStepStr()); } + //switch返回如果是空,会走default选项 + @Test + public void testSwitch8() throws Exception{ + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assert.assertTrue(response.isSuccess()); + Assert.assertEquals("a==>j==>d",response.getExecuteStepStr()); + } + } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/cmp/JSwitchCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/cmp/JSwitchCmp.java new file mode 100644 index 000000000..0e70272e5 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/cmp/JSwitchCmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Tingliang Wang + * @email bytlwang@126.com + * @Date 2022/12/09 + */ +package com.yomahub.liteflow.test.switchcase.cmp; + +import com.yomahub.liteflow.core.NodeSwitchComponent; +import org.springframework.stereotype.Component; + +@Component("j") +public class JSwitchCmp extends NodeSwitchComponent { + + @Override + public String processSwitch() throws Exception { + return ""; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml index ee853dd0b..794ad4505 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml @@ -46,7 +46,7 @@ THEN( a, - SWITCH(i).to(b, c).DEFAULT(d) + SWITCH(j).to(b, c).DEFAULT(d) ); From f46b6024ae61182bbbfa9d2527c8d13077a9fb32 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Tue, 10 Jan 2023 19:07:50 +0800 Subject: [PATCH 13/36] =?UTF-8?q?bug=20#I69UVL=20=E5=A6=82=E6=9E=9Cswitch?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=B8=BA=E7=A9=BA=E6=88=96=E8=80=85null?= =?UTF-8?q?=EF=BC=8C=E6=97=A0=E6=B3=95=E9=80=89=E5=8F=96=E5=88=B0default?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/test/switchcase/SwitchELSpringbootTest.java | 2 +- .../src/test/resources/switchcase/flow.el.xml | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java index 97755dd8d..d043364b9 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/switchcase/SwitchELSpringbootTest.java @@ -87,7 +87,7 @@ public class SwitchELSpringbootTest extends BaseTest { //switch返回如果是空,会走default选项 @Test public void testSwitch8() throws Exception{ - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg"); Assert.assertTrue(response.isSuccess()); Assert.assertEquals("a==>j==>d",response.getExecuteStepStr()); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml index 794ad4505..227eaf43a 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/switchcase/flow.el.xml @@ -46,8 +46,14 @@ THEN( a, - SWITCH(j).to(b, c).DEFAULT(d) + SWITCH(i).to(b, c).DEFAULT(d) ); + + THEN( + a, + SWITCH(j).to(b, c).DEFAULT(d) + ); + \ No newline at end of file From 3e30e788181d1f7b41fd35dd228a151d1a9742f3 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Tue, 10 Jan 2023 21:14:44 +0800 Subject: [PATCH 14/36] =?UTF-8?q?feat=20#I69VAR=20=E4=BC=98=E5=8C=96=20nod?= =?UTF-8?q?e=20chain=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E5=80=99?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/el/LiteFlowChainELBuilder.java | 81 ++++++++++++++++--- 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 0b0f720a0..e1ce28689 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -1,18 +1,43 @@ package com.yomahub.liteflow.builder.el; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import com.ql.util.express.DefaultContext; import com.ql.util.express.ExpressRunner; +import com.ql.util.express.InstructionSet; import com.ql.util.express.exception.QLException; -import com.yomahub.liteflow.builder.el.operator.*; +import com.ql.util.express.instruction.detail.Instruction; +import com.ql.util.express.instruction.detail.InstructionLoadAttr; +import com.yomahub.liteflow.builder.el.operator.AnyOperator; +import com.yomahub.liteflow.builder.el.operator.BreakOperator; +import com.yomahub.liteflow.builder.el.operator.DataOperator; +import com.yomahub.liteflow.builder.el.operator.DefaultOperator; +import com.yomahub.liteflow.builder.el.operator.DoOperator; +import com.yomahub.liteflow.builder.el.operator.ElifOperator; +import com.yomahub.liteflow.builder.el.operator.ElseOperator; +import com.yomahub.liteflow.builder.el.operator.FinallyOperator; +import com.yomahub.liteflow.builder.el.operator.ForOperator; +import com.yomahub.liteflow.builder.el.operator.IdOperator; +import com.yomahub.liteflow.builder.el.operator.IfOperator; +import com.yomahub.liteflow.builder.el.operator.IgnoreErrorOperator; +import com.yomahub.liteflow.builder.el.operator.NodeOperator; +import com.yomahub.liteflow.builder.el.operator.PreOperator; +import com.yomahub.liteflow.builder.el.operator.SwitchOperator; +import com.yomahub.liteflow.builder.el.operator.TagOperator; +import com.yomahub.liteflow.builder.el.operator.ThenOperator; +import com.yomahub.liteflow.builder.el.operator.ThreadPoolOperator; +import com.yomahub.liteflow.builder.el.operator.ToOperator; +import com.yomahub.liteflow.builder.el.operator.WhenOperator; +import com.yomahub.liteflow.builder.el.operator.WhileOperator; import com.yomahub.liteflow.common.ChainConstant; import com.yomahub.liteflow.exception.DataNofFoundException; import com.yomahub.liteflow.exception.ELParseException; import com.yomahub.liteflow.exception.FlowSystemException; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.element.Chain; -import com.yomahub.liteflow.flow.element.condition.*; +import com.yomahub.liteflow.flow.element.Node; +import com.yomahub.liteflow.flow.element.condition.Condition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -152,7 +177,9 @@ public class LiteFlowChainELBuilder { } catch (QLException e) { // EL 底层会包装异常,这里是曲线处理 if (Objects.equals(e.getCause().getMessage(), DataNofFoundException.MSG)) { - throw new ELParseException(String.format("[node/chain is not exist or node/chain not register]elStr=%s", elStr)); + // 构建错误信息 + String msg = buildDataNofFoundExceptionMsg(elStr); + throw new ELParseException(msg); } throw new ELParseException(e.getCause().getMessage()); } catch (Exception e) { @@ -160,19 +187,53 @@ public class LiteFlowChainELBuilder { } } + /** + * 解析 EL 表达式,查找未定义的 id 并构建错误信息 + * + * @param elStr el 表达式 + */ + private static String buildDataNofFoundExceptionMsg(String elStr) { + String msg = String.format("[node/chain is not exist or node/chain not register]\n elStr=%s", StrUtil.trim(elStr)); + try { + InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr); + if (parseResult == null) { + return msg; + } + + Object o = ReflectUtil.getFieldValue(parseResult, "instructionList"); + if (o == null){ + return msg; + } + Instruction[] instructionList = (Instruction[]) o; + List chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true); + List nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true); + for (Instruction instruction : instructionList) { + String attrName = ((InstructionLoadAttr) instruction).getAttrName(); + if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) { + msg = String.format("[node/chain is not exist or node/chain not register]\n id=%s \n elStr=%s", attrName, StrUtil.trim(elStr)); + break; + } + } + } catch (Exception ex) { + // ignore + } + return msg; + } + /** * EL表达式校验 + * * @param elStr EL表达式 * @return true 校验成功 false 校验失败 */ public static boolean validate(String elStr) { - try { - LiteFlowChainELBuilder.createChain().setEL(elStr); - return Boolean.TRUE; - } catch (ELParseException e) { - LOG.error(e.getMessage()); - } - return Boolean.FALSE; + try { + LiteFlowChainELBuilder.createChain().setEL(elStr); + return Boolean.TRUE; + } catch (ELParseException e) { + LOG.error(e.getMessage()); + } + return Boolean.FALSE; } public void build() { From b7bbaf549331f7ccdc84f8a16526384af55be5d4 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Tue, 10 Jan 2023 21:21:41 +0800 Subject: [PATCH 15/36] =?UTF-8?q?feat=20#I69VAR=20=E4=BC=98=E5=8C=96=20nod?= =?UTF-8?q?e=20chain=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E5=80=99?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/el/LiteFlowChainELBuilder.java | 69 ++++++++++--------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index e1ce28689..d34fcd57b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -187,39 +187,6 @@ public class LiteFlowChainELBuilder { } } - /** - * 解析 EL 表达式,查找未定义的 id 并构建错误信息 - * - * @param elStr el 表达式 - */ - private static String buildDataNofFoundExceptionMsg(String elStr) { - String msg = String.format("[node/chain is not exist or node/chain not register]\n elStr=%s", StrUtil.trim(elStr)); - try { - InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr); - if (parseResult == null) { - return msg; - } - - Object o = ReflectUtil.getFieldValue(parseResult, "instructionList"); - if (o == null){ - return msg; - } - Instruction[] instructionList = (Instruction[]) o; - List chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true); - List nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true); - for (Instruction instruction : instructionList) { - String attrName = ((InstructionLoadAttr) instruction).getAttrName(); - if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) { - msg = String.format("[node/chain is not exist or node/chain not register]\n id=%s \n elStr=%s", attrName, StrUtil.trim(elStr)); - break; - } - } - } catch (Exception ex) { - // ignore - } - return msg; - } - /** * EL表达式校验 * @@ -244,6 +211,8 @@ public class LiteFlowChainELBuilder { FlowBus.addChain(this.chain); } + //#region private method + /** * build 前简单校验 */ @@ -256,4 +225,38 @@ public class LiteFlowChainELBuilder { throw new RuntimeException(CollUtil.join(errorList, ",", "[", "]")); } } + + /** + * 解析 EL 表达式,查找未定义的 id 并构建错误信息 + * + * @param elStr el 表达式 + */ + private String buildDataNofFoundExceptionMsg(String elStr) { + String msg = String.format("[node/chain is not exist or node/chain not register]\n elStr=%s", StrUtil.trim(elStr)); + try { + InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr); + if (parseResult == null) { + return msg; + } + + Object o = ReflectUtil.getFieldValue(parseResult, "instructionList"); + if (o == null) { + return msg; + } + Instruction[] instructionList = (Instruction[]) o; + List chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true); + List nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true); + for (Instruction instruction : instructionList) { + String attrName = ((InstructionLoadAttr) instruction).getAttrName(); + if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) { + msg = String.format("[node/chain is not exist or node/chain not register]\n id=%s \n elStr=%s", attrName, StrUtil.trim(elStr)); + break; + } + } + } catch (Exception ex) { + // ignore + } + return msg; + } + //#endregion } From 0f46146e119eafc99f2165fe016dae4f73ddd3cd Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Tue, 10 Jan 2023 21:27:28 +0800 Subject: [PATCH 16/36] =?UTF-8?q?feat=20#I69VAR=20=E4=BC=98=E5=8C=96=20nod?= =?UTF-8?q?e=20chain=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E5=80=99?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/builder/el/LiteFlowChainELBuilder.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index d34fcd57b..e6ddbd2f2 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -247,10 +247,12 @@ public class LiteFlowChainELBuilder { List chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true); List nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true); for (Instruction instruction : instructionList) { - String attrName = ((InstructionLoadAttr) instruction).getAttrName(); - if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) { - msg = String.format("[node/chain is not exist or node/chain not register]\n id=%s \n elStr=%s", attrName, StrUtil.trim(elStr)); - break; + if (instruction instanceof InstructionLoadAttr) { + String attrName = ((InstructionLoadAttr) instruction).getAttrName(); + if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) { + msg = String.format("[node/chain is not exist or node/chain not register]\n id=%s \n elStr=%s", attrName, StrUtil.trim(elStr)); + break; + } } } } catch (Exception ex) { From 429d8ed2d62789190ef3238e0c47e076fd072a4b Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Wed, 11 Jan 2023 17:59:12 +0800 Subject: [PATCH 17/36] =?UTF-8?q?enhancement=20#I6A2FI=20=E5=A2=9E?= =?UTF-8?q?=E5=BC=BASlot=E5=85=83=E6=95=B0=E6=8D=AE=E7=9A=84=E5=AD=98?= =?UTF-8?q?=E5=82=A8=EF=BC=8C=E9=81=BF=E5=85=8D=E5=9C=A8=E5=A4=9A=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E7=9B=B8=E5=90=8C=E7=BB=84=E4=BB=B6=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=B8=8B=E5=8F=AF=E8=83=BD=E9=80=A0=E6=88=90?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yomahub/liteflow/slot/Slot.java | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java b/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java index 0425e161f..065639b05 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java @@ -10,6 +10,7 @@ package com.yomahub.liteflow.slot; import cn.hutool.core.collection.ConcurrentHashSet; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.exception.NoSuchContextBeanException; import com.yomahub.liteflow.exception.NullParamException; import com.yomahub.liteflow.flow.entity.CmpStep; @@ -52,6 +53,8 @@ public class Slot{ private static final String WHILE_PREFIX = "_while_"; + private static final String ITERATOR_PREFIX = "_iterator_"; + private static final String BREAK_PREFIX = "_break_"; private static final String NODE_INPUT_PREFIX = "_input_"; @@ -89,6 +92,16 @@ public class Slot{ return metaDataMap.containsKey(key); } + private void putThreadMetaDataMap(String key, T t){ + String threadKey = StrUtil.format("{}_{}", key, Thread.currentThread().getName()); + putMetaDataMap(threadKey, t); + } + + private T getThreadMetaData(String key){ + String threadKey = StrUtil.format("{}_{}", key, Thread.currentThread().getName()); + return (T)metaDataMap.get(threadKey); + } + private void putMetaDataMap(String key, T t) { if (ObjectUtil.isNull(t)) { //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException @@ -197,43 +210,51 @@ public class Slot{ } public void setSwitchResult(String key, T t){ - putMetaDataMap(SWITCH_NODE_PREFIX + key, t); + putThreadMetaDataMap(SWITCH_NODE_PREFIX + key, t); } public T getSwitchResult(String key){ - return (T) metaDataMap.get(SWITCH_NODE_PREFIX + key); + return getThreadMetaData(SWITCH_NODE_PREFIX + key); } public void setIfResult(String key, boolean result){ - putMetaDataMap(IF_NODE_PREFIX + key, result); + putThreadMetaDataMap(IF_NODE_PREFIX + key, result); } public boolean getIfResult(String key){ - return (boolean) metaDataMap.get(IF_NODE_PREFIX + key); + return getThreadMetaData(IF_NODE_PREFIX + key); } public void setForResult(String key, int forCount){ - putMetaDataMap(FOR_PREFIX + key, forCount); + putThreadMetaDataMap(FOR_PREFIX + key, forCount); } public int getForResult(String key){ - return (int) metaDataMap.get(FOR_PREFIX + key); + return getThreadMetaData(FOR_PREFIX + key); } public void setWhileResult(String key, boolean whileFlag){ - putMetaDataMap(WHILE_PREFIX + key, whileFlag); + putThreadMetaDataMap(WHILE_PREFIX + key, whileFlag); } public boolean getWhileResult(String key){ - return (boolean) metaDataMap.get(WHILE_PREFIX + key); + return getThreadMetaData(WHILE_PREFIX + key); } public void setBreakResult(String key, boolean breakFlag){ - putMetaDataMap(BREAK_PREFIX + key, breakFlag); + putThreadMetaDataMap(BREAK_PREFIX + key, breakFlag); } public boolean getBreakResult(String key){ - return (boolean) metaDataMap.get(BREAK_PREFIX + key); + return getThreadMetaData(BREAK_PREFIX + key); + } + + public void setIteratorResult(String key, Iterator it){ + putThreadMetaDataMap(ITERATOR_PREFIX + key, it); + } + + public Iterator getIteratorResult(String key){ + return getThreadMetaData(ITERATOR_PREFIX + key); } /** From cebfb2867ebd4e3ccafecb8cfe3a0c4c6f743c33 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Wed, 11 Jan 2023 18:01:15 +0800 Subject: [PATCH 18/36] =?UTF-8?q?feature=20#I6A2GL=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=BF=AD=E4=BB=A3=E5=99=A8=E8=A1=A8=E8=BE=BE=E5=BC=8F=E7=89=B9?= =?UTF-8?q?=E6=80=A7=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=BF=AD=E4=BB=A3=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E4=B8=AD=E7=9A=84=E9=9B=86=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/builder/LiteFlowNodeBuilder.java | 4 + .../builder/el/LiteFlowChainELBuilder.java | 1 + .../builder/el/operator/IteratorOperator.java | 26 +++++++ .../liteflow/common/ChainConstant.java | 2 + .../yomahub/liteflow/core/NodeComponent.java | 4 + .../liteflow/core/NodeIteratorComponent.java | 24 ++++++ .../liteflow/enums/ConditionTypeEnum.java | 4 +- .../liteflow/enums/LiteFlowMethodEnum.java | 3 + .../yomahub/liteflow/enums/NodeTypeEnum.java | 2 + .../exception/NoIteratorNodeException.java | 29 +++++++ .../yomahub/liteflow/flow/element/Node.java | 14 ++++ .../flow/element/condition/ForCondition.java | 5 +- .../element/condition/IteratorCondition.java | 78 +++++++++++++++++++ .../flow/element/condition/LoopCondition.java | 14 ++++ .../element/condition/WhileCondition.java | 10 +-- .../IteratorELDeclMultiSpringbootTest.java | 57 ++++++++++++++ .../liteflow/test/iterator/cmp/CmpConfig.java | 42 ++++++++++ .../resources/iterator/application.properties | 1 + .../src/test/resources/iterator/flow.xml | 11 +++ .../IteratorELDeclSpringbootTest.java | 57 ++++++++++++++ .../liteflow/test/iterator/cmp/ACmp.java | 34 ++++++++ .../liteflow/test/iterator/cmp/BCmp.java | 20 +++++ .../liteflow/test/iterator/cmp/ITCmp.java | 22 ++++++ .../resources/iterator/application.properties | 1 + .../src/test/resources/iterator/flow.xml | 11 +++ .../liteflow/test/iterator/IteratorTest.java | 48 ++++++++++++ .../liteflow/test/iterator/cmp/ACmp.java | 27 +++++++ .../liteflow/test/iterator/cmp/BCmp.java | 12 +++ .../liteflow/test/iterator/cmp/ITCmp.java | 14 ++++ .../src/test/resources/iterator/flow.xml | 17 ++++ .../iterator/IteratorELSpringbootTest.java | 55 +++++++++++++ .../liteflow/test/iterator/cmp/ACmp.java | 29 +++++++ .../liteflow/test/iterator/cmp/BCmp.java | 15 ++++ .../liteflow/test/iterator/cmp/ITCmp.java | 16 ++++ .../resources/iterator/application.properties | 1 + .../src/test/resources/iterator/flow.xml | 11 +++ .../test/iterator/IteratorELSpringTest.java | 45 +++++++++++ .../liteflow/test/iterator/cmp/ACmp.java | 29 +++++++ .../liteflow/test/iterator/cmp/BCmp.java | 14 ++++ .../liteflow/test/iterator/cmp/ITCmp.java | 16 ++++ .../test/resources/iterator/application.xml | 23 ++++++ .../src/test/resources/iterator/flow.xml | 11 +++ 42 files changed, 848 insertions(+), 11 deletions(-) create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/exception/NoIteratorNodeException.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclMultiSpringbootTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/CmpConfig.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/flow.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclSpringbootTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/flow.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/IteratorTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/iterator/flow.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/application.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/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 e8faff6a1..29d3095ff 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 @@ -53,6 +53,10 @@ public class LiteFlowNodeBuilder { return new LiteFlowNodeBuilder(NodeTypeEnum.BREAK); } + public static LiteFlowNodeBuilder createIteratorNode() { + return new LiteFlowNodeBuilder(NodeTypeEnum.ITERATOR); + } + public static LiteFlowNodeBuilder createScriptNode() { return new LiteFlowNodeBuilder(NodeTypeEnum.SCRIPT); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 0b0f720a0..b86949f9e 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -69,6 +69,7 @@ public class LiteFlowChainELBuilder { EXPRESS_RUNNER.addFunction(ChainConstant.NODE, new NodeOperator()); EXPRESS_RUNNER.addFunction(ChainConstant.FOR, new ForOperator()); EXPRESS_RUNNER.addFunction(ChainConstant.WHILE, new WhileOperator()); + EXPRESS_RUNNER.addFunction(ChainConstant.ITERATOR, new IteratorOperator()); EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DO, Object.class, new DoOperator()); EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.BREAK, Object.class, new BreakOperator()); EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DATA, Object.class, new DataOperator()); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java new file mode 100644 index 000000000..9a19bdb78 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java @@ -0,0 +1,26 @@ +package com.yomahub.liteflow.builder.el.operator; + +import cn.hutool.core.collection.ListUtil; +import com.ql.util.express.exception.QLException; +import com.yomahub.liteflow.builder.el.operator.base.BaseOperator; +import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper; +import com.yomahub.liteflow.enums.NodeTypeEnum; +import com.yomahub.liteflow.flow.element.Node; +import com.yomahub.liteflow.flow.element.condition.IteratorCondition; + +public class IteratorOperator extends BaseOperator { + @Override + public IteratorCondition build(Object[] objects) throws Exception { + OperatorHelper.checkObjectSizeEq(objects, 1); + + Node node = OperatorHelper.convert(objects[0], Node.class); + if (!ListUtil.toList(NodeTypeEnum.ITERATOR).contains(node.getType())) { + throw new QLException("The parameter must be iterator-node item"); + } + + IteratorCondition iteratorCondition = new IteratorCondition(); + iteratorCondition.setIteratorNode(node); + + return iteratorCondition; + } +} 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 baced9a62..a27f871c0 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 @@ -63,6 +63,8 @@ public interface ChainConstant { String DATA = "data"; + String ITERATOR = "ITERATOR"; + String MONITOR_BUS = "monitorBus"; String CURR_CHAIN_ID = "currChainId"; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java index de2e6a1ca..fc44f66bd 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java @@ -349,6 +349,10 @@ public abstract class NodeComponent{ return this.refNodeTL.get().getLoopIndex(); } + public T getCurrLoopObj(){ + return this.refNodeTL.get().getCurrLoopObject(); + } + @Deprecated public void invoke(String chainId, Object param) throws Exception { FlowExecutorHolder.loadInstance().invoke(chainId, param, this.getSlotIndex()); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java new file mode 100644 index 000000000..03710dfcc --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java @@ -0,0 +1,24 @@ +package com.yomahub.liteflow.core; + +import com.yomahub.liteflow.slot.Slot; +import com.yomahub.liteflow.util.LiteFlowProxyUtil; + +import java.util.Iterator; + +/** + * ITERATOR迭代器循环组件抽象类 + * @author Bryan.Zhang + * @since 2.9.7 + */ +public abstract class NodeIteratorComponent extends NodeComponent{ + + @Override + public void process() throws Exception { + Iterator it = processIterator(); + Slot slot = this.getSlot(); + Class originalClass = LiteFlowProxyUtil.getUserClass(this.getClass()); + slot.setIteratorResult(originalClass.getName(), it); + } + + public abstract Iterator processIterator() throws Exception; +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java index fa9178f26..f6c3faf2f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java @@ -14,7 +14,9 @@ public enum ConditionTypeEnum { TYPE_FOR("for", "for"), - TYPE_WHILE("while", "while") + TYPE_WHILE("while", "while"), + + TYPE_ITERATOR("iterator", "iterator") ; private String type; private String name; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/LiteFlowMethodEnum.java b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/LiteFlowMethodEnum.java index 739d37deb..91ee39bae 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/LiteFlowMethodEnum.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/LiteFlowMethodEnum.java @@ -7,6 +7,9 @@ public enum LiteFlowMethodEnum { PROCESS_FOR("processFor", true), PROCESS_WHILE("processWhile", true), PROCESS_BREAK("processBreak", true), + + PROCESS_ITERATOR("processIterator", true), + IS_ACCESS("isAccess", false), IS_END("isEnd", false), diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/NodeTypeEnum.java b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/NodeTypeEnum.java index afca14b6f..2c0806be2 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/NodeTypeEnum.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/NodeTypeEnum.java @@ -35,6 +35,8 @@ public enum NodeTypeEnum { BREAK("break", "循环跳出", false, NodeBreakComponent.class), + ITERATOR("iterator", "循环迭代", false, NodeIteratorComponent.class), + SCRIPT("script", "脚本", true, ScriptCommonComponent.class), SWITCH_SCRIPT("switch_script", "选择脚本", true, ScriptSwitchComponent.class), diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NoIteratorNodeException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NoIteratorNodeException.java new file mode 100644 index 000000000..2e771aec4 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NoIteratorNodeException.java @@ -0,0 +1,29 @@ +package com.yomahub.liteflow.exception; + +/** + * 没有节点异常 + * @author Yun + */ +public class NoIteratorNodeException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * 异常信息 + */ + private String message; + + public NoIteratorNodeException(String message) { + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} 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 64ed465cf..fc0cf0d01 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 @@ -56,6 +56,8 @@ public class Node implements Executable,Cloneable{ private TransmittableThreadLocal loopIndexTL = new TransmittableThreadLocal<>(); + private TransmittableThreadLocal currLoopObject = new TransmittableThreadLocal<>(); + public Node(){ } @@ -241,4 +243,16 @@ public class Node implements Executable,Cloneable{ public void removeLoopIndex(){ this.loopIndexTL.remove(); } + + public void setCurrLoopObject(Object obj){ + this.currLoopObject.set(obj); + } + + public T getCurrLoopObject(){ + return (T)this.currLoopObject.get(); + } + + public void removeCurrLoopObject(){ + this.currLoopObject.remove(); + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java index 64d8c59c8..f6503478d 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java @@ -49,6 +49,7 @@ public class ForCondition extends LoopCondition{ //如果break组件不为空,则去执行 if (ObjectUtil.isNotNull(breakNode)){ breakNode.setCurrChainId(this.getCurrChainId()); + setLoopIndex(breakNode, i); breakNode.execute(slotIndex); Class originalBreakClass = LiteFlowProxyUtil.getUserClass(this.breakNode.getInstance().getClass()); boolean isBreak = slot.getBreakResult(originalBreakClass.getName()); @@ -64,10 +65,6 @@ public class ForCondition extends LoopCondition{ return ConditionTypeEnum.TYPE_FOR; } - public Executable getDoExecutor() { - return this.getExecutableList().get(0); - } - public Node getForNode() { return forNode; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java new file mode 100644 index 000000000..e40141496 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java @@ -0,0 +1,78 @@ +package com.yomahub.liteflow.flow.element.condition; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.enums.ConditionTypeEnum; +import com.yomahub.liteflow.exception.NoIteratorNodeException; +import com.yomahub.liteflow.flow.element.Executable; +import com.yomahub.liteflow.flow.element.Node; +import com.yomahub.liteflow.slot.DataBus; +import com.yomahub.liteflow.slot.Slot; +import com.yomahub.liteflow.util.LiteFlowProxyUtil; + +import java.util.Iterator; + +public class IteratorCondition extends LoopCondition{ + + private Node iteratorNode; + + @Override + public void execute(Integer slotIndex) throws Exception { + Slot slot = DataBus.getSlot(slotIndex); + if (ObjectUtil.isNull(iteratorNode)){ + String errorInfo = StrUtil.format("[{}]:no iterator-node found", slot.getRequestId()); + throw new NoIteratorNodeException(errorInfo); + } + + //执行Iterator组件 + iteratorNode.setCurrChainId(this.getCurrChainId()); + iteratorNode.execute(slotIndex); + + //这里可能会有spring代理过的bean,所以拿到user原始的class + Class originalForCountClass = LiteFlowProxyUtil.getUserClass(this.iteratorNode.getInstance().getClass()); + //获得迭代器 + Iterator it = slot.getIteratorResult(originalForCountClass.getName()); + + //获得要循环的可执行对象 + Executable executableItem = this.getDoExecutor(); + + int index = 0; + while(it.hasNext()){ + Object itObj = it.next(); + + executableItem.setCurrChainId(this.getCurrChainId()); + //设置循环index + setLoopIndex(executableItem, index); + //设置循环迭代器对象 + setCurrLoopObject(executableItem, itObj); + //执行可执行对象 + executableItem.execute(slotIndex); + //如果break组件不为空,则去执行 + if (ObjectUtil.isNotNull(breakNode)){ + breakNode.setCurrChainId(this.getCurrChainId()); + setLoopIndex(breakNode, index); + setCurrLoopObject(breakNode, itObj); + breakNode.execute(slotIndex); + Class originalBreakClass = LiteFlowProxyUtil.getUserClass(this.breakNode.getInstance().getClass()); + boolean isBreak = slot.getBreakResult(originalBreakClass.getName()); + if (isBreak){ + break; + } + } + index++; + } + } + + @Override + public ConditionTypeEnum getConditionType() { + return ConditionTypeEnum.TYPE_ITERATOR; + } + + public Node getIteratorNode() { + return iteratorNode; + } + + public void setIteratorNode(Node iteratorNode) { + this.iteratorNode = iteratorNode; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java index c559585cd..6e2cc3cc3 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java @@ -32,4 +32,18 @@ public abstract class LoopCondition extends Condition { ((Node)executableItem).setLoopIndex(index); } } + + protected void setCurrLoopObject(Executable executableItem, Object obj){ + if (executableItem instanceof Chain){ + ((Chain)executableItem).getConditionList().forEach(condition -> setCurrLoopObject(condition, obj)); + }else if(executableItem instanceof Condition){ + ((Condition)executableItem).getExecutableList().forEach(executable -> setCurrLoopObject(executable, obj)); + }else if(executableItem instanceof Node){ + ((Node)executableItem).setCurrLoopObject(obj); + } + } + + protected Executable getDoExecutor() { + return this.getExecutableList().get(0); + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java index 813832902..3e6773b55 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java @@ -35,11 +35,12 @@ public class WhileCondition extends LoopCondition{ int index = 0; while(getWhileResult(slotIndex)){ executableItem.setCurrChainId(this.getCurrChainId()); - setLoopIndex(executableItem, index++); + setLoopIndex(executableItem, index); executableItem.execute(slotIndex); //如果break组件不为空,则去执行 if (ObjectUtil.isNotNull(breakNode)){ breakNode.setCurrChainId(this.getCurrChainId()); + setLoopIndex(breakNode, index); breakNode.execute(slotIndex); Class originalBreakClass = LiteFlowProxyUtil.getUserClass(this.breakNode.getInstance().getClass()); boolean isBreak = slot.getBreakResult(originalBreakClass.getName()); @@ -47,22 +48,19 @@ public class WhileCondition extends LoopCondition{ break; } } + index++; } } private boolean getWhileResult(Integer slotIndex) throws Exception{ Slot slot = DataBus.getSlot(slotIndex); //执行while组件 - whileNode.setCurrChainName(this.getCurrChainName()); + whileNode.setCurrChainId(this.getCurrChainId()); whileNode.execute(slotIndex); Class originalWhileClass = LiteFlowProxyUtil.getUserClass(this.whileNode.getInstance().getClass()); return slot.getWhileResult(originalWhileClass.getName()); } - public Executable getDoExecutor() { - return this.getExecutableList().get(0); - } - @Override public ConditionTypeEnum getConditionType() { return ConditionTypeEnum.TYPE_WHILE; diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclMultiSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclMultiSpringbootTest.java new file mode 100644 index 000000000..e8563a67e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclMultiSpringbootTest.java @@ -0,0 +1,57 @@ +package com.yomahub.liteflow.test.iterator; + +import cn.hutool.core.collection.ListUtil; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.BaseTest; +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.List; + +/** + * springboot环境最普通的例子测试 + * @author Bryan.Zhang + * @since 2.6.4 + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/iterator/application.properties") +@SpringBootTest(classes = IteratorELDeclMultiSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.iterator.cmp"}) +public class IteratorELDeclMultiSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //最简单的情况 + @Test + public void testIt1() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("123", str); + } + + //迭代器带break + @Test + public void testIt2() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain2", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("12", str); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/CmpConfig.java b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/CmpConfig.java new file mode 100644 index 000000000..c63119279 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/CmpConfig.java @@ -0,0 +1,42 @@ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.base.cmp.TestDomain; + +import javax.annotation.Resource; +import java.util.Iterator; +import java.util.List; + +@LiteflowComponent +public class CmpConfig { + + @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "a") + public void processA(NodeComponent bindCmp) { + String key = "test"; + DefaultContext context = bindCmp.getFirstContextBean(); + if (!context.hasData(key)){ + context.setData(key, bindCmp.getCurrLoopObj()); + }else{ + String str = context.getData(key); + str += bindCmp.getCurrLoopObj(); + context.setData(key, str); + } + } + + @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_BREAK, nodeId = "b", nodeType = NodeTypeEnum.BREAK) + public boolean processB(NodeComponent bindCmp) { + return bindCmp.getLoopIndex() == 1; + } + @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_ITERATOR, nodeId = "it", nodeType = NodeTypeEnum.ITERATOR) + public Iterator processIT(NodeComponent bindCmp) { + List list = bindCmp.getRequestData(); + return list.iterator(); + } +} + + diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/application.properties b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/application.properties new file mode 100644 index 000000000..eee2ed632 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=iterator/flow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/flow.xml new file mode 100644 index 000000000..7c732861a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/resources/iterator/flow.xml @@ -0,0 +1,11 @@ + + + + + ITERATOR(it).DO(a); + + + + ITERATOR(it).DO(a).BREAK(b); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclSpringbootTest.java new file mode 100644 index 000000000..fdc1d51e9 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELDeclSpringbootTest.java @@ -0,0 +1,57 @@ +package com.yomahub.liteflow.test.iterator; + +import cn.hutool.core.collection.ListUtil; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.BaseTest; +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.List; + +/** + * springboot环境最普通的例子测试 + * @author Bryan.Zhang + * @since 2.6.4 + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/iterator/application.properties") +@SpringBootTest(classes = IteratorELDeclSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.iterator.cmp"}) +public class IteratorELDeclSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //最简单的情况 + @Test + public void testIt1() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("123", str); + } + + //迭代器带break + @Test + public void testIt2() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain2", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("12", str); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java new file mode 100644 index 000000000..fc53c287c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java @@ -0,0 +1,34 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.annotation.LiteflowCmpDefine; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; +import com.yomahub.liteflow.slot.DefaultContext; +import org.springframework.stereotype.Component; + +@Component("a") +@LiteflowCmpDefine(NodeTypeEnum.COMMON) +public class ACmp{ + + @LiteflowMethod(LiteFlowMethodEnum.PROCESS) + public void process(NodeComponent bindCmp) { + String key = "test"; + DefaultContext context = bindCmp.getFirstContextBean(); + if (!context.hasData(key)){ + context.setData(key, bindCmp.getCurrLoopObj()); + }else{ + String str = context.getData(key); + str += bindCmp.getCurrLoopObj(); + context.setData(key, str); + } + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java new file mode 100644 index 000000000..642ba8b35 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java @@ -0,0 +1,20 @@ + +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.annotation.LiteflowCmpDefine; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeBreakComponent; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; +import org.springframework.stereotype.Component; + +@Component("b") +@LiteflowCmpDefine(NodeTypeEnum.BREAK) +public class BCmp{ + + @LiteflowMethod(LiteFlowMethodEnum.PROCESS_BREAK) + public boolean processBreak(NodeComponent bindCmp) throws Exception { + return bindCmp.getLoopIndex() == 1; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java new file mode 100644 index 000000000..43c60973a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java @@ -0,0 +1,22 @@ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.annotation.LiteflowCmpDefine; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.core.NodeIteratorComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; +import org.springframework.stereotype.Component; + +import java.util.Iterator; +import java.util.List; + +@Component("it") +@LiteflowCmpDefine(NodeTypeEnum.ITERATOR) +public class ITCmp{ + @LiteflowMethod(LiteFlowMethodEnum.PROCESS_ITERATOR) + public Iterator processIterator(NodeComponent bindCmp) throws Exception { + List list = bindCmp.getRequestData(); + return list.iterator(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/application.properties b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/application.properties new file mode 100644 index 000000000..eee2ed632 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=iterator/flow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/flow.xml new file mode 100644 index 000000000..7c732861a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/iterator/flow.xml @@ -0,0 +1,11 @@ + + + + + ITERATOR(it).DO(a); + + + + ITERATOR(it).DO(a).BREAK(b); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/IteratorTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/IteratorTest.java new file mode 100644 index 000000000..5f3e2c0f4 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/IteratorTest.java @@ -0,0 +1,48 @@ +package com.yomahub.liteflow.test.iterator; + +import cn.hutool.core.collection.ListUtil; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.core.FlowExecutorHolder; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +public class IteratorTest extends BaseTest{ + + private static FlowExecutor flowExecutor; + + @BeforeClass + public static void init(){ + LiteflowConfig config = new LiteflowConfig(); + config.setRuleSource("iterator/flow.xml"); + flowExecutor = FlowExecutorHolder.loadInstance(config); + } + + //最简单的情况 + @Test + public void testIt1() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("123", str); + } + + //迭代器带break + @Test + public void testIt2() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain2", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("12", str); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java new file mode 100644 index 000000000..8d366b370 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java @@ -0,0 +1,27 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.slot.DefaultContext; + +public class ACmp extends NodeComponent { + + @Override + public void process() { + String key = "test"; + DefaultContext context = this.getFirstContextBean(); + if (!context.hasData(key)){ + context.setData(key, this.getCurrLoopObj()); + }else{ + String str = context.getData(key); + str += this.getCurrLoopObj(); + context.setData(key, str); + } + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java new file mode 100644 index 000000000..8ccfda17a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java @@ -0,0 +1,12 @@ + +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeBreakComponent; + +public class BCmp extends NodeBreakComponent { + + @Override + public boolean processBreak() throws Exception { + return this.getLoopIndex() == 1; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java new file mode 100644 index 000000000..d3c5a763b --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java @@ -0,0 +1,14 @@ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeIteratorComponent; + +import java.util.Iterator; +import java.util.List; + +public class ITCmp extends NodeIteratorComponent { + @Override + public Iterator processIterator() throws Exception { + List list = this.getRequestData(); + return list.iterator(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/iterator/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/iterator/flow.xml new file mode 100644 index 000000000..f32f9169f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/iterator/flow.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + ITERATOR(it).DO(a); + + + + ITERATOR(it).DO(a).BREAK(b); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java new file mode 100644 index 000000000..dc26c7be0 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java @@ -0,0 +1,55 @@ +package com.yomahub.liteflow.test.iterator; + +import cn.hutool.core.collection.ListUtil; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.BaseTest; +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.List; + +/** + * springboot环境EL常规的例子测试 + * @author Bryan.Zhang + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/iterator/application.properties") +@SpringBootTest(classes = IteratorELSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.iterator.cmp"}) +public class IteratorELSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //最简单的情况 + @Test + public void testIt1() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("123", str); + } + + //迭代器带break + @Test + public void testIt2() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain2", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("12", str); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java new file mode 100644 index 000000000..665236a0f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java @@ -0,0 +1,29 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.slot.DefaultContext; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + String key = "test"; + DefaultContext context = this.getFirstContextBean(); + if (!context.hasData(key)){ + context.setData(key, this.getCurrLoopObj()); + }else{ + String str = context.getData(key); + str += this.getCurrLoopObj(); + context.setData(key, str); + } + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java new file mode 100644 index 000000000..74110c698 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java @@ -0,0 +1,15 @@ + +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeBreakComponent; +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeBreakComponent { + + @Override + public boolean processBreak() throws Exception { + return this.getLoopIndex() == 1; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java new file mode 100644 index 000000000..cc36766d7 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java @@ -0,0 +1,16 @@ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeIteratorComponent; +import org.springframework.stereotype.Component; + +import java.util.Iterator; +import java.util.List; + +@Component("it") +public class ITCmp extends NodeIteratorComponent { + @Override + public Iterator processIterator() throws Exception { + List list = this.getRequestData(); + return list.iterator(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/application.properties new file mode 100644 index 000000000..eee2ed632 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=iterator/flow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml new file mode 100644 index 000000000..7c732861a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml @@ -0,0 +1,11 @@ + + + + + ITERATOR(it).DO(a); + + + + ITERATOR(it).DO(a).BREAK(b); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringTest.java new file mode 100644 index 000000000..207a48986 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringTest.java @@ -0,0 +1,45 @@ +package com.yomahub.liteflow.test.iterator; + +import cn.hutool.core.collection.ListUtil; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; +import java.util.List; + +@RunWith(SpringRunner.class) +@ContextConfiguration("classpath:/iterator/application.xml") +public class IteratorELSpringTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //最简单的情况 + @Test + public void testIt1() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("123", str); + } + + //迭代器带break + @Test + public void testIt2() throws Exception{ + List list = ListUtil.toList("1","2","3"); + LiteflowResponse response = flowExecutor.execute2Resp("chain2", list); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + String str = context.getData("test"); + Assert.assertEquals("12", str); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java new file mode 100644 index 000000000..665236a0f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ACmp.java @@ -0,0 +1,29 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.slot.DefaultContext; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + String key = "test"; + DefaultContext context = this.getFirstContextBean(); + if (!context.hasData(key)){ + context.setData(key, this.getCurrLoopObj()); + }else{ + String str = context.getData(key); + str += this.getCurrLoopObj(); + context.setData(key, str); + } + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java new file mode 100644 index 000000000..cc7d0e748 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/BCmp.java @@ -0,0 +1,14 @@ + +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeBreakComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeBreakComponent { + + @Override + public boolean processBreak() throws Exception { + return this.getLoopIndex() == 1; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java new file mode 100644 index 000000000..cc36766d7 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/iterator/cmp/ITCmp.java @@ -0,0 +1,16 @@ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.core.NodeIteratorComponent; +import org.springframework.stereotype.Component; + +import java.util.Iterator; +import java.util.List; + +@Component("it") +public class ITCmp extends NodeIteratorComponent { + @Override + public Iterator processIterator() throws Exception { + List list = this.getRequestData(); + return list.iterator(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/application.xml b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/application.xml new file mode 100644 index 000000000..d5a2e14c2 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/application.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/flow.xml new file mode 100644 index 000000000..7c732861a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/iterator/flow.xml @@ -0,0 +1,11 @@ + + + + + ITERATOR(it).DO(a); + + + + ITERATOR(it).DO(a).BREAK(b); + + \ No newline at end of file From 56761c44c8390915bd7acf0b52140e45c69e2ebe Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 13 Jan 2023 11:29:11 +0800 Subject: [PATCH 19/36] =?UTF-8?q?fix=20#I69VAR=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=8D=95=E8=AF=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/builder/el/LiteFlowChainELBuilder.java | 8 ++++---- .../liteflow/builder/el/operator/base/OperatorHelper.java | 4 ++-- ...aNofFoundException.java => DataNotFoundException.java} | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) rename liteflow-core/src/main/java/com/yomahub/liteflow/exception/{DataNofFoundException.java => DataNotFoundException.java} (67%) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index e6ddbd2f2..0ef5f6af8 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -31,7 +31,7 @@ import com.yomahub.liteflow.builder.el.operator.ToOperator; import com.yomahub.liteflow.builder.el.operator.WhenOperator; import com.yomahub.liteflow.builder.el.operator.WhileOperator; import com.yomahub.liteflow.common.ChainConstant; -import com.yomahub.liteflow.exception.DataNofFoundException; +import com.yomahub.liteflow.exception.DataNotFoundException; import com.yomahub.liteflow.exception.ELParseException; import com.yomahub.liteflow.exception.FlowSystemException; import com.yomahub.liteflow.flow.FlowBus; @@ -176,9 +176,9 @@ public class LiteFlowChainELBuilder { return this; } catch (QLException e) { // EL 底层会包装异常,这里是曲线处理 - if (Objects.equals(e.getCause().getMessage(), DataNofFoundException.MSG)) { + if (Objects.equals(e.getCause().getMessage(), DataNotFoundException.MSG)) { // 构建错误信息 - String msg = buildDataNofFoundExceptionMsg(elStr); + String msg = buildDataNotFoundExceptionMsg(elStr); throw new ELParseException(msg); } throw new ELParseException(e.getCause().getMessage()); @@ -231,7 +231,7 @@ public class LiteFlowChainELBuilder { * * @param elStr el 表达式 */ - private String buildDataNofFoundExceptionMsg(String elStr) { + private String buildDataNotFoundExceptionMsg(String elStr) { String msg = String.format("[node/chain is not exist or node/chain not register]\n elStr=%s", StrUtil.trim(elStr)); try { InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java index 401254036..88f60764b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java @@ -2,7 +2,7 @@ package com.yomahub.liteflow.builder.el.operator.base; import cn.hutool.core.util.StrUtil; import com.ql.util.express.exception.QLException; -import com.yomahub.liteflow.exception.DataNofFoundException; +import com.yomahub.liteflow.exception.DataNotFoundException; import com.yomahub.liteflow.flow.element.Node; import java.util.Objects; @@ -156,7 +156,7 @@ public class OperatorHelper { public static void checkNodeAndChainExist(Object[] objects) throws QLException { for (Object object : objects) { if (Objects.isNull(object)) { - throw new QLException(DataNofFoundException.MSG); + throw new QLException(DataNotFoundException.MSG); } } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/DataNofFoundException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/DataNotFoundException.java similarity index 67% rename from liteflow-core/src/main/java/com/yomahub/liteflow/exception/DataNofFoundException.java rename to liteflow-core/src/main/java/com/yomahub/liteflow/exception/DataNotFoundException.java index c31111517..cb2f65ad6 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/DataNofFoundException.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/DataNotFoundException.java @@ -4,8 +4,8 @@ package com.yomahub.liteflow.exception; * 未找到数据异常 * @author tangkc */ -public class DataNofFoundException extends RuntimeException { - public static final String MSG = "DataNofFoundException"; +public class DataNotFoundException extends RuntimeException { + public static final String MSG = "DataNotFoundException"; private static final long serialVersionUID = 1L; @@ -14,11 +14,11 @@ public class DataNofFoundException extends RuntimeException { */ private String message; - public DataNofFoundException() { + public DataNotFoundException() { this.message = MSG; } - public DataNofFoundException(String message) { + public DataNotFoundException(String message) { this.message = message; } From 062302af1a4267696c3d1f155568d5c70f75aea5 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 13 Jan 2023 14:01:51 +0800 Subject: [PATCH 20/36] =?UTF-8?q?feat=20#I69VAR=20=E4=BC=98=E5=8C=96=20nod?= =?UTF-8?q?e=20chain=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E5=80=99?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/el/LiteFlowChainELBuilder.java | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 0ef5f6af8..723d36b07 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -1,14 +1,13 @@ package com.yomahub.liteflow.builder.el; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.StrUtil; import com.ql.util.express.DefaultContext; import com.ql.util.express.ExpressRunner; import com.ql.util.express.InstructionSet; import com.ql.util.express.exception.QLException; -import com.ql.util.express.instruction.detail.Instruction; -import com.ql.util.express.instruction.detail.InstructionLoadAttr; import com.yomahub.liteflow.builder.el.operator.AnyOperator; import com.yomahub.liteflow.builder.el.operator.BreakOperator; import com.yomahub.liteflow.builder.el.operator.DataOperator; @@ -232,27 +231,45 @@ public class LiteFlowChainELBuilder { * @param elStr el 表达式 */ private String buildDataNotFoundExceptionMsg(String elStr) { - String msg = String.format("[node/chain is not exist or node/chain not register]\n elStr=%s", StrUtil.trim(elStr)); + String msg = String.format("[node/chain is not exist or node/chain not register]\n EL: %s", StrUtil.trim(elStr)); try { InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr); if (parseResult == null) { return msg; } - Object o = ReflectUtil.getFieldValue(parseResult, "instructionList"); - if (o == null) { + String[] outAttrNames = parseResult.getOutAttrNames(); + if (ArrayUtil.isEmpty(outAttrNames)) { return msg; } - Instruction[] instructionList = (Instruction[]) o; + List chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true); List nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true); - for (Instruction instruction : instructionList) { - if (instruction instanceof InstructionLoadAttr) { - String attrName = ((InstructionLoadAttr) instruction).getAttrName(); - if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) { - msg = String.format("[node/chain is not exist or node/chain not register]\n id=%s \n elStr=%s", attrName, StrUtil.trim(elStr)); - break; + for (String attrName : outAttrNames) { + if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) { + msg = String.format("[%s] is not exist or [%s] is not registered, you need to define a node or chain with id [%s] and register it \n EL: ", attrName, attrName, attrName); + + // 去除 EL 表达式中的空格和换行符 + String sourceEl = StrUtil.removeAll(elStr, CharUtil.SPACE, CharUtil.LF, CharUtil.CR); + // 这里需要注意的是,nodeId 和 chainId 可能是关键字的一部分,如果直接 indexOf(attrName) 会出现误判 + // 所以需要判断 attrName 前后是否有 "," + int commaRightIndex = sourceEl.indexOf(attrName + StrUtil.COMMA); + if (commaRightIndex != -1) { + // 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1 + msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true); } + int commaLeftIndex = sourceEl.indexOf(StrUtil.COMMA + attrName); + if (commaLeftIndex != -1) { + // 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,再加上 "," 的长度 1,indexOf 从 0 开始,所以还需要加 1 + msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true); + } + // 还有一种特殊情况,就是 EL 表达式中的节点使用 node("a") + int nodeIndex = sourceEl.indexOf(String.format("node(\"%s\")", attrName)); + if (nodeIndex != -1) { + // 需要加上 "EL: " 的长度 4,再加上 “node("” 长度 6,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1 + msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true); + } + break; } } } catch (Exception ex) { From 0b7450e504ee1549769a1e782e93e89a549053dd Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 13 Jan 2023 18:32:11 +0800 Subject: [PATCH 21/36] =?UTF-8?q?=E6=9B=B4=E6=94=B9dtd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- liteflow-core/src/main/resources/dtd/liteflow.dtd | 1 + 1 file changed, 1 insertion(+) diff --git a/liteflow-core/src/main/resources/dtd/liteflow.dtd b/liteflow-core/src/main/resources/dtd/liteflow.dtd index cee92d450..115cf2db1 100644 --- a/liteflow-core/src/main/resources/dtd/liteflow.dtd +++ b/liteflow-core/src/main/resources/dtd/liteflow.dtd @@ -7,6 +7,7 @@ Date: Fri, 13 Jan 2023 18:32:30 +0800 Subject: [PATCH 22/36] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/resources/common/flow.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-python-springboot/src/test/resources/common/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-python-springboot/src/test/resources/common/flow.xml index 3990c03e7..311888fe4 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-script-python-springboot/src/test/resources/common/flow.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-script-python-springboot/src/test/resources/common/flow.xml @@ -1,8 +1,16 @@ + - + 5: From ed7f29abbbb78b9e1033e502897d6d06df376e82 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Tue, 17 Jan 2023 10:50:52 +0800 Subject: [PATCH 23/36] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/flow/element/condition/WhenCondition.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java index 4fc1037ee..ecdd6a4fa 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java @@ -164,7 +164,7 @@ public class WhenCondition extends Condition { } } } else if (interrupted[0]) { - // 这里由于配置了errorResume,所以只打印warn日志 + // 这里由于配置了ignoreError,所以只打印warn日志 LOG.warn("requestId [{}] executing when condition timeout , but ignore with errorResume.", slot.getRequestId()); } } From 0ccb363044df0297e4e34b93039b160c915f44dc Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Tue, 17 Jan 2023 11:10:08 +0800 Subject: [PATCH 24/36] =?UTF-8?q?errorResume=E5=8F=98=E9=87=8F=E6=94=B9?= =?UTF-8?q?=E6=88=90ignoreError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/el/operator/IgnoreErrorOperator.java | 2 +- .../flow/element/condition/WhenCondition.java | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java index e6990f6ce..ede076eb7 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java @@ -20,7 +20,7 @@ public class IgnoreErrorOperator extends BaseOperator { WhenCondition condition = OperatorHelper.convert(objects[0], WhenCondition.class); Boolean ignoreError = OperatorHelper.convert(objects[1], Boolean.class); - condition.setErrorResume(ignoreError); + condition.setIgnoreError(ignoreError); return condition; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java index ecdd6a4fa..2bdcdc777 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java @@ -37,7 +37,7 @@ public class WhenCondition extends Condition { private final Logger LOG = LoggerFactory.getLogger(this.getClass()); //只在when类型下有效,以区分当when调用链调用失败时是否继续往下执行 默认false不继续执行 - private boolean errorResume = false; + private boolean ignoreError = false; //只在when类型下有效,用于不同node进行同组合并,相同的组会进行合并,不同的组不会进行合并 //此属性已弃用 @@ -150,8 +150,8 @@ public class WhenCondition extends Condition { timeOutWhenFutureObjList.forEach(whenFutureObj -> LOG.warn("requestId [{}] executing thread has reached max-wait-seconds, thread canceled.Execute-item: [{}]", slot.getRequestId(), whenFutureObj.getExecutorName())); - //当配置了errorResume = false,出现interrupted或者!f.get()的情况,将抛出WhenExecuteException - if (!this.isErrorResume()) { + //当配置了ignoreError = false,出现interrupted或者!f.get()的情况,将抛出WhenExecuteException + if (!this.isIgnoreError()) { if (interrupted[0]) { throw new WhenExecuteException(StrUtil.format("requestId [{}] when execute interrupted. errorResume [false].", slot.getRequestId())); } @@ -169,12 +169,12 @@ public class WhenCondition extends Condition { } } - public boolean isErrorResume() { - return errorResume; + public boolean isIgnoreError() { + return ignoreError; } - public void setErrorResume(boolean errorResume) { - this.errorResume = errorResume; + public void setIgnoreError(boolean ignoreError) { + this.ignoreError = ignoreError; } public String getGroup() { From 0bfdee1ea7a4be493587296e46baa1151ae6c293 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Tue, 17 Jan 2023 11:10:45 +0800 Subject: [PATCH 25/36] =?UTF-8?q?=E4=BC=98=E5=8C=96pr153?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/core/FlowExecutor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 002c9359c..55c4c233f 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 @@ -90,7 +90,8 @@ public class FlowExecutor { Iterator it = loader.iterator(); if (it.hasNext()){ ParserClassNameSpi parserClassNameSpi = it.next(); - liteflowConfig.setRuleSource("el_xml:" + parserClassNameSpi.getSpiClassName()); + ruleSource = "el_xml:" + parserClassNameSpi.getSpiClassName(); + liteflowConfig.setRuleSource(ruleSource); }else{ //ruleSource为空,而且没有spi形式的扩展,那么说明真的没有ruleSource //这种情况有可能是基于代码动态构建的 From 2d57b5392b464ef632b9d0dcd7b7e87f97eb0999 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Tue, 17 Jan 2023 16:42:36 +0800 Subject: [PATCH 26/36] =?UTF-8?q?=E4=BF=AE=E6=94=B9dtd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- liteflow-core/src/main/resources/dtd/liteflow.dtd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/liteflow-core/src/main/resources/dtd/liteflow.dtd b/liteflow-core/src/main/resources/dtd/liteflow.dtd index 115cf2db1..a5486a47d 100644 --- a/liteflow-core/src/main/resources/dtd/liteflow.dtd +++ b/liteflow-core/src/main/resources/dtd/liteflow.dtd @@ -14,4 +14,5 @@ language (groovy|js|python|lua) #IMPLIED > \ No newline at end of file + id CDATA #REQUIRED + > \ No newline at end of file From 64f97ede935e6168fdf99660c675e2eaadfc832c Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 20 Jan 2023 11:25:53 +0800 Subject: [PATCH 27/36] =?UTF-8?q?bug=20#I6ASNG=20=E9=87=87=E7=94=A8sql?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=BA=90=E5=BD=A2=E5=BC=8F=EF=BC=8CFlowExecu?= =?UTF-8?q?tor=E9=A1=B9=E7=9B=AE=E5=88=9D=E5=A7=8B=E5=8C=96=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=A6=82=E6=9E=9C=E6=B2=A1=E6=9C=89=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=B5=81=E7=A8=8BFlowBus.getChainMap()=E4=BC=9A=E5=88=A4?= =?UTF-8?q?=E7=A9=BA=E5=88=99=E6=8A=9B=E5=87=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yomahub/liteflow/core/FlowExecutor.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 55c4c233f..da831e266 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 @@ -9,6 +9,7 @@ package com.yomahub.liteflow.core; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.*; import com.yomahub.liteflow.enums.InnerChainTypeEnum; import com.yomahub.liteflow.exception.*; @@ -166,9 +167,11 @@ public class FlowExecutor { } //如果是ruleSource方式的,最后判断下有没有解析出来,如果没有解析出来则报错 - if (FlowBus.getChainMap().isEmpty()){ - String errMsg = StrUtil.format("no valid rule config found in rule path [{}]", liteflowConfig.getRuleSource()); - throw new ConfigErrorException(errMsg); + if (StrUtil.isBlank(liteflowConfig.getRuleSourceExtData()) && MapUtil.isEmpty(liteflowConfig.getRuleSourceExtDataMap())){ + if (FlowBus.getChainMap().isEmpty()){ + String errMsg = StrUtil.format("no valid rule config found in rule path [{}]", liteflowConfig.getRuleSource()); + throw new ConfigErrorException(errMsg); + } } //执行钩子 From 87e0e269df4ac6dfe4b20936fe552f7cc7f5714d Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 20 Jan 2023 11:27:11 +0800 Subject: [PATCH 28/36] =?UTF-8?q?enhancement=20#I69QOB=20=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E5=88=9B=E5=BB=BA=E7=BB=84=E4=BB=B6=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=BC=82=E5=B8=B8=E4=BF=A1=E6=81=AF=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/flow/FlowBus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e7c42879d..95e2b1aa1 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 @@ -207,7 +207,7 @@ public class FlowBus { } catch (Exception e) { String error = StrUtil.format("component[{}] register error", StrUtil.isEmpty(name) ? nodeId : StrUtil.format("{}({})", nodeId, name)); LOG.error(e.getMessage()); - throw new ComponentCannotRegisterException(error); + throw new ComponentCannotRegisterException(StrUtil.format("{} {}", error, e.getMessage())); } } From e022b26efb5f9fc7e2704ac661d1d2a97f76116f Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 20 Jan 2023 13:48:32 +0800 Subject: [PATCH 29/36] =?UTF-8?q?feat=20#I69VAR=20=E4=BC=98=E5=8C=96=20nod?= =?UTF-8?q?e=20chain=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E5=80=99?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/builder/el/LiteFlowChainELBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 6d1740dfb..83ced38fc 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -20,6 +20,7 @@ import com.yomahub.liteflow.builder.el.operator.ForOperator; import com.yomahub.liteflow.builder.el.operator.IdOperator; import com.yomahub.liteflow.builder.el.operator.IfOperator; import com.yomahub.liteflow.builder.el.operator.IgnoreErrorOperator; +import com.yomahub.liteflow.builder.el.operator.IteratorOperator; import com.yomahub.liteflow.builder.el.operator.NodeOperator; import com.yomahub.liteflow.builder.el.operator.PreOperator; import com.yomahub.liteflow.builder.el.operator.SwitchOperator; @@ -257,18 +258,18 @@ public class LiteFlowChainELBuilder { int commaRightIndex = sourceEl.indexOf(attrName + StrUtil.COMMA); if (commaRightIndex != -1) { // 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1 - msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true); + return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true); } int commaLeftIndex = sourceEl.indexOf(StrUtil.COMMA + attrName); if (commaLeftIndex != -1) { // 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,再加上 "," 的长度 1,indexOf 从 0 开始,所以还需要加 1 - msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true); + return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true); } // 还有一种特殊情况,就是 EL 表达式中的节点使用 node("a") int nodeIndex = sourceEl.indexOf(String.format("node(\"%s\")", attrName)); if (nodeIndex != -1) { // 需要加上 "EL: " 的长度 4,再加上 “node("” 长度 6,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1 - msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true); + return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true); } break; } From cc3c9fc8728c02bd89b3c90d2c54c912e7a0c7f8 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 20 Jan 2023 13:49:51 +0800 Subject: [PATCH 30/36] =?UTF-8?q?feat=20#I69VAR=20=E4=BC=98=E5=8C=96=20nod?= =?UTF-8?q?e=20chain=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E5=80=99?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 83ced38fc..a685ce890 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -271,7 +271,6 @@ public class LiteFlowChainELBuilder { // 需要加上 "EL: " 的长度 4,再加上 “node("” 长度 6,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1 return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true); } - break; } } } catch (Exception ex) { From 7338670327fb94aee22cb5a944f40de851219c9a Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 20 Jan 2023 14:08:48 +0800 Subject: [PATCH 31/36] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/el/LiteFlowChainELBuilder.java | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 6d1740dfb..da11f1a5b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -8,27 +8,7 @@ import com.ql.util.express.DefaultContext; import com.ql.util.express.ExpressRunner; import com.ql.util.express.InstructionSet; import com.ql.util.express.exception.QLException; -import com.yomahub.liteflow.builder.el.operator.AnyOperator; -import com.yomahub.liteflow.builder.el.operator.BreakOperator; -import com.yomahub.liteflow.builder.el.operator.DataOperator; -import com.yomahub.liteflow.builder.el.operator.DefaultOperator; -import com.yomahub.liteflow.builder.el.operator.DoOperator; -import com.yomahub.liteflow.builder.el.operator.ElifOperator; -import com.yomahub.liteflow.builder.el.operator.ElseOperator; -import com.yomahub.liteflow.builder.el.operator.FinallyOperator; -import com.yomahub.liteflow.builder.el.operator.ForOperator; -import com.yomahub.liteflow.builder.el.operator.IdOperator; -import com.yomahub.liteflow.builder.el.operator.IfOperator; -import com.yomahub.liteflow.builder.el.operator.IgnoreErrorOperator; -import com.yomahub.liteflow.builder.el.operator.NodeOperator; -import com.yomahub.liteflow.builder.el.operator.PreOperator; -import com.yomahub.liteflow.builder.el.operator.SwitchOperator; -import com.yomahub.liteflow.builder.el.operator.TagOperator; -import com.yomahub.liteflow.builder.el.operator.ThenOperator; -import com.yomahub.liteflow.builder.el.operator.ThreadPoolOperator; -import com.yomahub.liteflow.builder.el.operator.ToOperator; -import com.yomahub.liteflow.builder.el.operator.WhenOperator; -import com.yomahub.liteflow.builder.el.operator.WhileOperator; +import com.yomahub.liteflow.builder.el.operator.*; import com.yomahub.liteflow.common.ChainConstant; import com.yomahub.liteflow.exception.DataNotFoundException; import com.yomahub.liteflow.exception.ELParseException; From b7bd185851bea4ed4e5ef4559835b109164fcb5d Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 20 Jan 2023 15:26:16 +0800 Subject: [PATCH 32/36] =?UTF-8?q?feat=20#I69VAR=20=E4=BC=98=E5=8C=96=20nod?= =?UTF-8?q?e=20chain=20=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E5=80=99?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/builder/el/LiteFlowChainELBuilder.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index da11f1a5b..6ad8f2ff4 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -237,20 +237,19 @@ public class LiteFlowChainELBuilder { int commaRightIndex = sourceEl.indexOf(attrName + StrUtil.COMMA); if (commaRightIndex != -1) { // 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1 - msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true); + return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true); } int commaLeftIndex = sourceEl.indexOf(StrUtil.COMMA + attrName); if (commaLeftIndex != -1) { // 需要加上 "EL: " 的长度 4,再加上 "^" 的长度 1,再加上 "," 的长度 1,indexOf 从 0 开始,所以还需要加 1 - msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true); + return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true); } // 还有一种特殊情况,就是 EL 表达式中的节点使用 node("a") int nodeIndex = sourceEl.indexOf(String.format("node(\"%s\")", attrName)); if (nodeIndex != -1) { // 需要加上 "EL: " 的长度 4,再加上 “node("” 长度 6,再加上 "^" 的长度 1,indexOf 从 0 开始,所以还需要加 1 - msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true); + return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true); } - break; } } } catch (Exception ex) { From 3321aaa2add1e0f580148f07eef4d7689948d98f Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Sat, 28 Jan 2023 10:51:03 +0800 Subject: [PATCH 33/36] =?UTF-8?q?=E4=BF=AE=E6=94=B9dtd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- liteflow-core/src/main/resources/dtd/liteflow.dtd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/liteflow-core/src/main/resources/dtd/liteflow.dtd b/liteflow-core/src/main/resources/dtd/liteflow.dtd index a5486a47d..ed76a7fa2 100644 --- a/liteflow-core/src/main/resources/dtd/liteflow.dtd +++ b/liteflow-core/src/main/resources/dtd/liteflow.dtd @@ -1,6 +1,6 @@ - + @@ -14,5 +14,6 @@ language (groovy|js|python|lua) #IMPLIED > \ No newline at end of file From 29ca22f1102e3349d0d103c12fbbb4691ce41df1 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Sat, 28 Jan 2023 18:14:02 +0800 Subject: [PATCH 34/36] =?UTF-8?q?feat=20#I6BDN3=20groovy=20=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E6=96=87=E4=BB=B6=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=BB=9D=E5=AF=B9=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/builder/LiteFlowNodeBuilder.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) 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 29d3095ff..542974912 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 @@ -1,23 +1,19 @@ package com.yomahub.liteflow.builder; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.io.resource.ResourceUtil; +import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.enums.NodeTypeEnum; import com.yomahub.liteflow.exception.NodeBuildException; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.element.Node; +import com.yomahub.liteflow.spi.holder.PathContentParserHolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; -import java.util.Set; -import java.util.function.BiConsumer; -import java.util.function.Consumer; public class LiteFlowNodeBuilder { @@ -134,8 +130,15 @@ public class LiteFlowNodeBuilder { if (StrUtil.isBlank(filePath)) { return this; } - String script = ResourceUtil.readUtf8Str(StrUtil.format("classpath: {}", filePath.trim())); - return setScript(script); + try { + List scriptList = PathContentParserHolder.loadContextAware().parseContent(ListUtil.toList(filePath)); + String script = CollUtil.getFirst(scriptList); + setScript(script); + } catch (Exception e) { + String errMsg = StrUtil.format("An exception occurred while building the node[{}],{}", this.node.getId(), e.getMessage()); + throw new NodeBuildException(errMsg); + } + return this; } public void build() { From 58372abd1de40f08ed2f462fcddeabd3aa1705ed Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Sun, 29 Jan 2023 10:49:54 +0800 Subject: [PATCH 35/36] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E7=9A=84import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/spi/spring/SpringPathContentParser.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/liteflow-spring/src/main/java/com/yomahub/liteflow/spi/spring/SpringPathContentParser.java b/liteflow-spring/src/main/java/com/yomahub/liteflow/spi/spring/SpringPathContentParser.java index 791f2789e..822aa411b 100644 --- a/liteflow-spring/src/main/java/com/yomahub/liteflow/spi/spring/SpringPathContentParser.java +++ b/liteflow-spring/src/main/java/com/yomahub/liteflow/spi/spring/SpringPathContentParser.java @@ -1,6 +1,5 @@ package com.yomahub.liteflow.spi.spring; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.io.FileUtil; @@ -9,19 +8,15 @@ import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.exception.ConfigErrorException; -import com.yomahub.liteflow.property.LiteflowConfig; -import com.yomahub.liteflow.property.LiteflowConfigGetter; import com.yomahub.liteflow.spi.PathContentParser; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.util.ResourceUtils; - import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; public class SpringPathContentParser implements PathContentParser { @Override From dcf2b9a96cfb72aa76ca6f74b28edee4f1952562 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Mon, 30 Jan 2023 21:14:29 +0800 Subject: [PATCH 36/36] =?UTF-8?q?feat=20#I6BDN3=20groovy=20=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E6=96=87=E4=BB=B6=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=BB=9D=E5=AF=B9=E8=B7=AF=E5=BE=84=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LiteFlowXmlScriptBuilderGroovyELTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/common/LiteFlowXmlScriptBuilderGroovyELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/common/LiteFlowXmlScriptBuilderGroovyELTest.java index e2c6468c8..5f46ffda1 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/common/LiteFlowXmlScriptBuilderGroovyELTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/common/LiteFlowXmlScriptBuilderGroovyELTest.java @@ -1,5 +1,6 @@ package com.yomahub.liteflow.test.script.groovy.common; +import cn.hutool.core.io.resource.ClassPathResource; import com.yomahub.liteflow.builder.LiteFlowNodeBuilder; import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; import com.yomahub.liteflow.core.FlowExecutor; @@ -25,6 +26,44 @@ public class LiteFlowXmlScriptBuilderGroovyELTest extends BaseTest { @Resource private FlowExecutor flowExecutor; + /** + * 测试通过builder方式运行普通script节点,以file绝对路径的方式运行 + */ + @Test + public void testAbsoluteScriptFilePath(){ + String absolutePath = new ClassPathResource("classpath:builder/s2.groovy").getAbsolutePath(); + LiteFlowNodeBuilder.createNode().setId("d") + .setName("组件D") + .setType(NodeTypeEnum.COMMON) + .setClazz("com.yomahub.liteflow.test.script.groovy.common.cmp.DCmp") + .build(); + LiteFlowNodeBuilder.createNode().setId("s2") + .setName("条件脚本S2") + .setType(NodeTypeEnum.SWITCH_SCRIPT) + .setFile(absolutePath) + .build(); + LiteFlowNodeBuilder.createNode().setId("a") + .setName("组件A") + .setType(NodeTypeEnum.COMMON) + .setClazz("com.yomahub.liteflow.test.script.groovy.common.cmp.ACmp") + .build(); + LiteFlowNodeBuilder.createNode().setId("b") + .setName("组件B") + .setType(NodeTypeEnum.COMMON) + .setClazz("com.yomahub.liteflow.test.script.groovy.common.cmp.BCmp") + .build(); + + LiteFlowChainELBuilder.createChain().setChainName("chain2") + .setEL("THEN(d,SWITCH(s2).to(a,b))") + .build(); + + + LiteflowResponse response = flowExecutor.execute2Resp("chain2","arg1"); + DefaultContext context = response.getFirstContextBean(); + Assert.assertTrue(response.isSuccess()); + Assert.assertEquals("d[组件D]==>s2[条件脚本S2]==>a[组件A]", response.getExecuteStepStr()); + } + //测试通过builder方式运行普通script节点,以脚本文本的方式运行 @Test public void testBuilderScript1() {