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 a5e26cab9..cb6fd7748 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 @@ -4,15 +4,15 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; 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.yomahub.liteflow.common.ChainConstant; -import com.yomahub.liteflow.exception.DataNotFoundException; -import com.yomahub.liteflow.exception.ELParseException; -import com.yomahub.liteflow.exception.FlowSystemException; +import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Condition; @@ -34,6 +34,8 @@ public class LiteFlowChainELBuilder { private static final LFLog LOG = LFLoggerManager.getLogger(LiteFlowChainELBuilder.class); + private static ObjectMapper objectMapper =new ObjectMapper(); + private Chain chain; /** @@ -196,6 +198,16 @@ public class LiteFlowChainELBuilder { if (CollUtil.isNotEmpty(errorList)) { throw new RuntimeException(CollUtil.join(errorList, ",", "[", "]")); } + // 对每一个 chain 进行循环引用检测 + try { + objectMapper.writeValueAsString(this.chain); + } catch (Exception e) { + if (e instanceof JsonMappingException) { + throw new CyclicDependencyException(StrUtil.format("There is a circular dependency in the chain[{}], please check carefully.", chain.getChainId(), e)); + } else { + throw new ParseException(e.getMessage()); + } + } } /** 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 5d90e3c16..269a4dd62 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 @@ -8,23 +8,23 @@ package com.yomahub.liteflow.flow.element; -import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.ttl.TransmittableThreadLocal; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.ExecuteTypeEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; +import com.yomahub.liteflow.exception.ChainEndException; +import com.yomahub.liteflow.exception.FlowSystemException; +import com.yomahub.liteflow.flow.executor.NodeExecutor; +import com.yomahub.liteflow.flow.executor.NodeExecutorHelper; import com.yomahub.liteflow.log.LFLog; import com.yomahub.liteflow.log.LFLoggerManager; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.property.LiteflowConfigGetter; import com.yomahub.liteflow.slot.DataBus; import com.yomahub.liteflow.slot.Slot; -import com.yomahub.liteflow.flow.executor.NodeExecutor; -import com.yomahub.liteflow.flow.executor.NodeExecutorHelper; -import com.yomahub.liteflow.enums.ExecuteTypeEnum; -import com.yomahub.liteflow.enums.NodeTypeEnum; -import com.yomahub.liteflow.exception.ChainEndException; -import com.yomahub.liteflow.exception.FlowSystemException; /** * Node节点,实现可执行器 Node节点并不是单例的,每构建一次都会copy出一个新的实例 @@ -47,6 +47,8 @@ public class Node implements Executable, Cloneable, Rollbackable{ private String language; + // 增加该注解,避免在使用 Jackson 序列化检测循环引用时出现不必要异常 + @JsonIgnore private NodeComponent instance; private String tag; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java index eb239f76f..89eb4177b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java @@ -13,7 +13,10 @@ import com.yomahub.liteflow.flow.FlowBus; import org.dom4j.Document; import org.dom4j.Element; -import java.util.*; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; import java.util.regex.Pattern; @@ -237,8 +240,10 @@ public class ParserHelper { // 构建chainBuilder String chainId = Optional.ofNullable(chainNode.get(ID)).orElse(chainNode.get(NAME)).textValue(); String el = chainNode.get(VALUE).textValue(); - LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainId(chainId); - chainELBuilder.setEL(el).build(); + LiteFlowChainELBuilder.createChain() + .setChainId(chainId) + .setEL(el) + .build(); } /** @@ -250,8 +255,10 @@ public class ParserHelper { String chainId = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME)); String text = e.getText(); String el = RegexUtil.removeComments(text); - LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainId(chainId); - chainELBuilder.setEL(el).build(); + LiteFlowChainELBuilder.createChain() + .setChainId(chainId) + .setEL(el) + .build(); } /** diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowInDifferentConfigTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowInDifferentConfigTest.java new file mode 100644 index 000000000..3017205c4 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowInDifferentConfigTest.java @@ -0,0 +1,31 @@ + +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutorHolder; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + + +/** + * 测试多文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +public class FlowInDifferentConfigTest extends BaseTest { + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow-main.el.xml,endlessLoop/flow-sub1.el.xml"); + FlowExecutorHolder.loadInstance(config); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowJsonTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowJsonTest.java new file mode 100644 index 000000000..5f36f22aa --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowJsonTest.java @@ -0,0 +1,29 @@ +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutorHolder; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * 测试 json 文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +public class FlowJsonTest extends BaseTest { + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow.el.json"); + FlowExecutorHolder.loadInstance(config); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowXMLTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowXMLTest.java new file mode 100644 index 000000000..3091e60a9 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowXMLTest.java @@ -0,0 +1,29 @@ +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutorHolder; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * 测试 xml 文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +public class FlowXMLTest extends BaseTest { + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow.el.xml"); + FlowExecutorHolder.loadInstance(config); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowYMLTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowYMLTest.java new file mode 100644 index 000000000..654cf63db --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowYMLTest.java @@ -0,0 +1,29 @@ +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutorHolder; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * 测试 yml 文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +public class FlowYMLTest extends BaseTest { + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow.el.yml"); + FlowExecutorHolder.loadInstance(config); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ACmp.java new file mode 100644 index 000000000..a98b541c2 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ACmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("Acomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/BCmp.java new file mode 100644 index 000000000..f3699371e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/BCmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("Bcomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/CCmp.java new file mode 100644 index 000000000..d9abde6be --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/CCmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class CCmp extends NodeComponent { + + @Override + public void process() throws Exception { + System.out.println("Ccomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/DCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/DCmp.java new file mode 100644 index 000000000..b5ffafe78 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/DCmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class DCmp extends NodeComponent { + + @Override + public void process() throws Exception { + System.out.println("Dcomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ECmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ECmp.java new file mode 100644 index 000000000..fce4af378 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ECmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class ECmp extends NodeComponent { + + @Override + public void process() throws Exception { + System.out.println("Ecomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow-main.el.xml b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow-main.el.xml new file mode 100644 index 000000000..2100fc65f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow-main.el.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + THEN(a, b, chain2); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow-sub1.el.xml b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow-sub1.el.xml new file mode 100644 index 000000000..39b89324e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow-sub1.el.xml @@ -0,0 +1,6 @@ + + + + THEN(b, a, chain1); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.json b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.json new file mode 100644 index 000000000..b63faed4d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.json @@ -0,0 +1,42 @@ +{ + "flow": { + "nodes": { + "node": [ + { + "id": "a", + "class": "com.yomahub.liteflow.test.endlessLoop.cmp.ACmp" + }, + { + "id": "b", + "class": "com.yomahub.liteflow.test.endlessLoop.cmp.BCmp" + }, + { + "id": "c", + "class": "com.yomahub.liteflow.test.endlessLoop.cmp.CCmp" + }, + { + "id": "d", + "class": "com.yomahub.liteflow.test.endlessLoop.cmp.DCmp" + }, + { + "id": "e", + "class": "com.yomahub.liteflow.test.endlessLoop.cmp.ECmp" + } + ] + }, + "chain": [ + { + "name": "chain7", + "value": "THEN(a, chain8);" + }, + { + "name": "chain8", + "value": "THEN(b, chain9);" + }, + { + "name": "chain9", + "value": "WHEN(c, chain7);" + } + ] + } +} \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.xml new file mode 100644 index 000000000..fdd72433d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + THEN(a, chain2); + + + + THEN(b, chain3); + + + + THEN(c, chain1); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.yml b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.yml new file mode 100644 index 000000000..c82163e7c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/endlessLoop/flow.el.yml @@ -0,0 +1,20 @@ +flow: + nodes: + node: + - id: a + class: com.yomahub.liteflow.test.endlessLoop.cmp.ACmp + - id: b + class: com.yomahub.liteflow.test.endlessLoop.cmp.BCmp + - id: c + class: com.yomahub.liteflow.test.endlessLoop.cmp.CCmp + - id: d + class: com.yomahub.liteflow.test.endlessLoop.cmp.DCmp + - id: e + class: com.yomahub.liteflow.test.endlessLoop.cmp.ECmp + chain: + - name: chain4 + value: "THEN(a, chain5);" + - name: chain5 + value: "THEN(b, chain6);" + - name: chain6 + value: "THEN(c, chain5);" \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowInDifferentConfigELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowInDifferentConfigELSpringbootTest.java new file mode 100644 index 000000000..90efa473c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowInDifferentConfigELSpringbootTest.java @@ -0,0 +1,41 @@ +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; + +import javax.annotation.Resource; + +/** + * 测试多文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +@SpringBootTest(classes = FlowInDifferentConfigELSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.endlessLoop.cmp"}) +public class FlowInDifferentConfigELSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow-sub1.el.xml,endlessLoop/flow-sub2.el.yml"); + config.setSupportMultipleType(true); + flowExecutor.reloadRule(); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowJsonELSpringBootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowJsonELSpringBootTest.java new file mode 100644 index 000000000..8bcb71cbf --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowJsonELSpringBootTest.java @@ -0,0 +1,40 @@ +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; + +import javax.annotation.Resource; + +/** + * 测试 json 文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +@SpringBootTest(classes = FlowJsonELSpringBootTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.endlessLoop.cmp" }) +public class FlowJsonELSpringBootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow.el.json"); + flowExecutor.reloadRule(); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowXMLELSpringBootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowXMLELSpringBootTest.java new file mode 100644 index 000000000..585cb02eb --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowXMLELSpringBootTest.java @@ -0,0 +1,40 @@ +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; + +import javax.annotation.Resource; + +/** + * 测试 xml 文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +@SpringBootTest(classes = FlowXMLELSpringBootTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.endlessLoop.cmp" }) +public class FlowXMLELSpringBootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow.el.xml"); + flowExecutor.reloadRule(); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowYmlELSpringBootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowYmlELSpringBootTest.java new file mode 100644 index 000000000..4df3d56db --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/FlowYmlELSpringBootTest.java @@ -0,0 +1,40 @@ +package com.yomahub.liteflow.test.endlessLoop; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.exception.CyclicDependencyException; +import com.yomahub.liteflow.property.LiteflowConfig; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; + +import javax.annotation.Resource; + +/** + * 测试 yml 文件情况下 chain 死循环逻辑 + * + * @author luo yi + * @since 2.11.1 + */ +@SpringBootTest(classes = FlowYmlELSpringBootTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.endlessLoop.cmp" }) +public class FlowYmlELSpringBootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + // 测试 chain 死循环 + @Test + public void testChainEndlessLoop() { + Assertions.assertThrows(CyclicDependencyException.class, () -> { + LiteflowConfig config = LiteflowConfigGetter.get(); + config.setRuleSource("endlessLoop/flow.el.yml"); + flowExecutor.reloadRule(); + }); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ACmp.java new file mode 100644 index 000000000..17c75c038 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ACmp.java @@ -0,0 +1,14 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("Acomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/BCmp.java new file mode 100644 index 000000000..cdaa88716 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/BCmp.java @@ -0,0 +1,14 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("Bcomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/CCmp.java new file mode 100644 index 000000000..7d9ec1ab6 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/CCmp.java @@ -0,0 +1,14 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() throws Exception { + System.out.println("Ccomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/DCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/DCmp.java new file mode 100644 index 000000000..bf2f50f39 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/DCmp.java @@ -0,0 +1,14 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("d") +public class DCmp extends NodeComponent { + + @Override + public void process() throws Exception { + System.out.println("Dcomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ECmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ECmp.java new file mode 100644 index 000000000..5a010ea22 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/endlessLoop/cmp/ECmp.java @@ -0,0 +1,14 @@ +package com.yomahub.liteflow.test.endlessLoop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("e") +public class ECmp extends NodeComponent { + + @Override + public void process() throws Exception { + System.out.println("Ecomp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow-sub1.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow-sub1.el.xml new file mode 100644 index 000000000..3f1a585ab --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow-sub1.el.xml @@ -0,0 +1,6 @@ + + + + THEN(a, b); + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow-sub2.el.yml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow-sub2.el.yml new file mode 100644 index 000000000..6861be3cc --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow-sub2.el.yml @@ -0,0 +1,6 @@ +flow: + chain: + - name: chain2 + value: "THEN(c, d, chain3);" + - name: chain3 + value: "THEN(a, chain2);" \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.json b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.json new file mode 100644 index 000000000..1a54d6c6c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.json @@ -0,0 +1,18 @@ +{ + "flow": { + "chain": [ + { + "name": "chain7", + "value": "THEN(a, chain8);" + }, + { + "name": "chain8", + "value": "THEN(b, chain9);" + }, + { + "name": "chain9", + "value": "WHEN(c, chain7);" + } + ] + } +} \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.xml new file mode 100644 index 000000000..d615bf81d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.xml @@ -0,0 +1,16 @@ + + + + + THEN(a, chain2); + + + + THEN(b, chain3); + + + + THEN(c, chain1); + + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.yml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.yml new file mode 100644 index 000000000..1699d501b --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/endlessLoop/flow.el.yml @@ -0,0 +1,8 @@ +flow: + chain: + - name: chain4 + value: "THEN(a, chain5);" + - name: chain5 + value: "THEN(b, chain6);" + - name: chain6 + value: "THEN(c, chain5);" \ No newline at end of file