From 57cb85a955df177b2c8a3e3cd630ab25b14cc6de Mon Sep 17 00:00:00 2001 From: bryan31 Date: Mon, 9 Aug 2021 17:59:38 +0800 Subject: [PATCH] =?UTF-8?q?feature=20#I44FT8=20=E6=94=AF=E6=8C=81=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E8=AF=AD=E8=A8=80=E7=9A=84=E7=BB=84=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E6=94=AF=E6=8C=81=E5=8A=A8=E6=80=81=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E8=84=9A=E6=9C=AC(=E7=89=88=E6=9C=AC=E7=89=B9=E6=80=A7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/parser/JsonFlowParser.java | 29 +++++++++----- .../liteflow/parser/XmlFlowParser.java | 1 + .../liteflow/script/ScriptFactory.java | 6 ++- .../script/exception/ScriptSpiException.java | 27 +++++++++++++ liteflow-script-qlexpress/pom.xml | 1 + ...com.yomahub.liteflow.script.ScriptExecutor | 2 + ...com.yomahub.liteflow.script.ScriptExecutor | 0 liteflow-spring-boot-starter/pom.xml | 6 +++ .../main/resources/META-INF/spring.factories | 4 +- .../liteflow/test/aop/LFGlobalAOPTest.java | 9 +++++ .../LiteflowScriptSpringbootTest.java | 40 +++++++++++++++++++ .../liteflow/test/scriptnode/cmp/ACmp.java | 20 ++++++++++ .../liteflow/test/scriptnode/cmp/BCmp.java | 21 ++++++++++ .../liteflow/test/scriptnode/cmp/CCmp.java | 21 ++++++++++ .../scriptnode/application.properties | 1 + .../src/test/resources/scriptnode/flow.xml | 16 ++++++++ 16 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 liteflow-script-common/src/main/java/com/yomahub/liteflow/script/exception/ScriptSpiException.java create mode 100644 liteflow-script-qlexpress/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor delete mode 100644 liteflow-script-qlexpress/src/main/resources/com.yomahub.liteflow.script.ScriptExecutor create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/LiteflowScriptSpringbootTest.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/ACmp.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/BCmp.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/CCmp.java create mode 100644 liteflow-spring-boot-starter/src/test/resources/scriptnode/application.properties create mode 100644 liteflow-spring-boot-starter/src/test/resources/scriptnode/flow.xml diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/JsonFlowParser.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/JsonFlowParser.java index 839c3da87..a51972c4a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/JsonFlowParser.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/JsonFlowParser.java @@ -50,22 +50,33 @@ public abstract class JsonFlowParser extends FlowParser { //json格式,解析过程 public void parseJsonObject(List flowJsonObjectList) throws Exception { try { + for (Map.Entry componentEntry : ComponentScanner.nodeComponentMap.entrySet()) { + if (!FlowBus.containNode(componentEntry.getKey())) { + FlowBus.addNode(componentEntry.getKey(), new Node(componentEntry.getValue())); + } + } + for (JSONObject flowJsonObject : flowJsonObjectList) { - //判断是以spring方式注册节点,还是以json方式注册 - if (ComponentScanner.nodeComponentMap.isEmpty()) { + // 当存在节点定义时,解析node节点 + if (flowJsonObject.getJSONObject("flow").containsKey("nodes")){ JSONArray nodeArrayList = flowJsonObject.getJSONObject("flow").getJSONObject("nodes").getJSONArray("node"); - String id, name, clazz; + String id, name, clazz, script; for (int i = 0; i < nodeArrayList.size(); i++) { JSONObject nodeObject = nodeArrayList.getJSONObject(i); id = nodeObject.getString("id"); name = nodeObject.getString("name"); clazz = nodeObject.getString("class"); - FlowBus.addNode(id, name, clazz); - } - } else { - for (Map.Entry componentEntry : ComponentScanner.nodeComponentMap.entrySet()) { - if (!FlowBus.containNode(componentEntry.getKey())) { - FlowBus.addNode(componentEntry.getKey(), new Node(componentEntry.getValue())); + + //如果有class的定义,则表明是java组件,无class的定义,则表明是脚本组件 + if (StrUtil.isNotBlank(clazz)){ + if (!FlowBus.containNode(id)){ + FlowBus.addNode(id, name, clazz); + } + }else{ + if (!FlowBus.containNode(id)){ + script = nodeObject.getString("script"); + FlowBus.addScriptNode(id, name, script); + } } } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java index a9ad0bcb9..471d2b92a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java @@ -72,6 +72,7 @@ public abstract class XmlFlowParser extends FlowParser { name = e.attributeValue("name"); clazz = e.attributeValue("class"); + //如果有class的定义,则表明是java组件,无class的定义,则表明是脚本组件 if (StrUtil.isNotBlank(clazz)){ if (!FlowBus.containNode(id)){ FlowBus.addNode(id, name, clazz); diff --git a/liteflow-script-common/src/main/java/com/yomahub/liteflow/script/ScriptFactory.java b/liteflow-script-common/src/main/java/com/yomahub/liteflow/script/ScriptFactory.java index 38e398b79..5d0a0494f 100644 --- a/liteflow-script-common/src/main/java/com/yomahub/liteflow/script/ScriptFactory.java +++ b/liteflow-script-common/src/main/java/com/yomahub/liteflow/script/ScriptFactory.java @@ -1,6 +1,7 @@ package com.yomahub.liteflow.script; import cn.hutool.core.util.ObjectUtil; +import com.yomahub.liteflow.script.exception.ScriptSpiException; import java.util.ServiceLoader; @@ -8,7 +9,7 @@ public class ScriptFactory { private static ScriptFactory scriptFactory; - private static ScriptExecutor scriptExecutor; + private ScriptExecutor scriptExecutor; public static ScriptFactory loadInstance(){ if (ObjectUtil.isNull(scriptFactory)){ @@ -20,9 +21,12 @@ public class ScriptFactory { public ScriptExecutor getScriptExecutor(){ if (ObjectUtil.isNull(scriptExecutor)){ ServiceLoader loader = ServiceLoader.load(ScriptExecutor.class); + if (loader.iterator().hasNext()){ scriptExecutor = loader.iterator().next().init(); return scriptExecutor; + }else{ + throw new ScriptSpiException("script spi component failed to load"); } } return scriptExecutor; diff --git a/liteflow-script-common/src/main/java/com/yomahub/liteflow/script/exception/ScriptSpiException.java b/liteflow-script-common/src/main/java/com/yomahub/liteflow/script/exception/ScriptSpiException.java new file mode 100644 index 000000000..b6820ba05 --- /dev/null +++ b/liteflow-script-common/src/main/java/com/yomahub/liteflow/script/exception/ScriptSpiException.java @@ -0,0 +1,27 @@ + +package com.yomahub.liteflow.script.exception; + +/** + * 脚本SPI插件加载异常 + * @author Bryan.Zhang + * @since 2.5.11 + */ +public class ScriptSpiException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public ScriptSpiException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/liteflow-script-qlexpress/pom.xml b/liteflow-script-qlexpress/pom.xml index 78bc08320..a2e1905b4 100644 --- a/liteflow-script-qlexpress/pom.xml +++ b/liteflow-script-qlexpress/pom.xml @@ -16,6 +16,7 @@ com.yomahub liteflow-script-common ${project.version} + true com.yomahub diff --git a/liteflow-script-qlexpress/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor b/liteflow-script-qlexpress/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor new file mode 100644 index 000000000..79eb605c2 --- /dev/null +++ b/liteflow-script-qlexpress/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor @@ -0,0 +1,2 @@ +# QLExpress的实现 +com.yomahub.liteflow.script.qlexpress.QLExpressScriptExecutor \ No newline at end of file diff --git a/liteflow-script-qlexpress/src/main/resources/com.yomahub.liteflow.script.ScriptExecutor b/liteflow-script-qlexpress/src/main/resources/com.yomahub.liteflow.script.ScriptExecutor deleted file mode 100644 index e69de29bb..000000000 diff --git a/liteflow-spring-boot-starter/pom.xml b/liteflow-spring-boot-starter/pom.xml index e10a790b0..cecbd9be8 100644 --- a/liteflow-spring-boot-starter/pom.xml +++ b/liteflow-spring-boot-starter/pom.xml @@ -52,6 +52,12 @@ zkclient test + + com.yomahub + liteflow-script-qlexpress + ${project.version} + test + diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/spring.factories b/liteflow-spring-boot-starter/src/main/resources/META-INF/spring.factories index 14e35e941..cba719aab 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,6 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.yomahub.liteflow.springboot.config.LiteflowPropertyAutoConfiguration,\ com.yomahub.liteflow.springboot.config.LiteflowExecutorAutoConfiguration,\ - com.yomahub.liteflow.springboot.config.LiteflowMainAutoConfiguration - - + com.yomahub.liteflow.springboot.config.LiteflowMainAutoConfiguration \ No newline at end of file diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/aop/LFGlobalAOPTest.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/aop/LFGlobalAOPTest.java index ef9903bbb..eea72321b 100644 --- a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/aop/LFGlobalAOPTest.java +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/aop/LFGlobalAOPTest.java @@ -3,8 +3,11 @@ package com.yomahub.liteflow.test.aop; import com.yomahub.liteflow.core.FlowExecutor; import com.yomahub.liteflow.entity.data.DefaultSlot; import com.yomahub.liteflow.entity.data.LiteflowResponse; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.spring.ComponentScanner; import com.yomahub.liteflow.test.BaseTest; import com.yomahub.liteflow.test.aop.aspect.CmpAspect; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,4 +58,10 @@ public class LFGlobalAOPTest extends BaseTest { Assert.assertEquals("before_after", response.getSlot().getData("d")); Assert.assertEquals("before_after", response.getSlot().getData("e")); } + + @AfterClass + public static void cleanScanCache(){ + BaseTest.cleanScanCache(); + ComponentScanner.cmpAroundAspect = null; + } } diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/LiteflowScriptSpringbootTest.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/LiteflowScriptSpringbootTest.java new file mode 100644 index 000000000..6092b5d21 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/LiteflowScriptSpringbootTest.java @@ -0,0 +1,40 @@ +package com.yomahub.liteflow.test.scriptnode; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.entity.data.DefaultSlot; +import com.yomahub.liteflow.entity.data.LiteflowResponse; +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; + + +/** + * 测试springboot下的脚本组件 + * @author Bryan.Zhang + * @since 2.5.11 + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/scriptnode/application.properties") +@SpringBootTest(classes = LiteflowScriptSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.scriptnode.cmp"}) +public class LiteflowScriptSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + @Test + public void testScript1() { + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assert.assertTrue(response.isSuccess()); + Assert.assertEquals(Integer.valueOf(6), response.getSlot().getData("s1")); + } +} diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/ACmp.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/ACmp.java new file mode 100644 index 000000000..d925648de --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.scriptnode.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/BCmp.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/BCmp.java new file mode 100644 index 000000000..8dad00650 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.scriptnode.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/CCmp.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/CCmp.java new file mode 100644 index 000000000..d4512137a --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/scriptnode/cmp/CCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.scriptnode.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } + +} diff --git a/liteflow-spring-boot-starter/src/test/resources/scriptnode/application.properties b/liteflow-spring-boot-starter/src/test/resources/scriptnode/application.properties new file mode 100644 index 000000000..0fcb47da5 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/resources/scriptnode/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=scriptnode/flow.xml \ No newline at end of file diff --git a/liteflow-spring-boot-starter/src/test/resources/scriptnode/flow.xml b/liteflow-spring-boot-starter/src/test/resources/scriptnode/flow.xml new file mode 100644 index 000000000..b26ffdf0e --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/resources/scriptnode/flow.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file