mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 20:22:07 +08:00
!229 初始化时增加 Chain 引用判断,避免死循环而导致堆栈溢出
Merge pull request !229 from luoyi/issues/I821F1
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="a" class="com.yomahub.liteflow.test.endlessLoop.cmp.ACmp"/>
|
||||
<node id="b" class="com.yomahub.liteflow.test.endlessLoop.cmp.BCmp"/>
|
||||
<node id="c" class="com.yomahub.liteflow.test.endlessLoop.cmp.CCmp"/>
|
||||
<node id="d" class="com.yomahub.liteflow.test.endlessLoop.cmp.DCmp"/>
|
||||
<node id="e" class="com.yomahub.liteflow.test.endlessLoop.cmp.ECmp"/>
|
||||
</nodes>
|
||||
<chain name="chain1">
|
||||
THEN(a, b, chain2);
|
||||
</chain>
|
||||
</flow>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain2">
|
||||
THEN(b, a, chain1);
|
||||
</chain>
|
||||
</flow>
|
||||
@@ -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);"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="a" class="com.yomahub.liteflow.test.endlessLoop.cmp.ACmp"/>
|
||||
<node id="b" class="com.yomahub.liteflow.test.endlessLoop.cmp.BCmp"/>
|
||||
<node id="c" class="com.yomahub.liteflow.test.endlessLoop.cmp.CCmp"/>
|
||||
<node id="d" class="com.yomahub.liteflow.test.endlessLoop.cmp.DCmp"/>
|
||||
<node id="e" class="com.yomahub.liteflow.test.endlessLoop.cmp.ECmp"/>
|
||||
</nodes>
|
||||
<chain name="chain1">
|
||||
THEN(a, chain2);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN(b, chain3);
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN(c, chain1);
|
||||
</chain>
|
||||
</flow>
|
||||
@@ -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);"
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN(a, b);
|
||||
</chain>
|
||||
</flow>
|
||||
@@ -0,0 +1,6 @@
|
||||
flow:
|
||||
chain:
|
||||
- name: chain2
|
||||
value: "THEN(c, d, chain3);"
|
||||
- name: chain3
|
||||
value: "THEN(a, chain2);"
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"flow": {
|
||||
"chain": [
|
||||
{
|
||||
"name": "chain7",
|
||||
"value": "THEN(a, chain8);"
|
||||
},
|
||||
{
|
||||
"name": "chain8",
|
||||
"value": "THEN(b, chain9);"
|
||||
},
|
||||
{
|
||||
"name": "chain9",
|
||||
"value": "WHEN(c, chain7);"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
|
||||
<chain name="chain1">
|
||||
THEN(a, chain2);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN(b, chain3);
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN(c, chain1);
|
||||
</chain>
|
||||
|
||||
</flow>
|
||||
@@ -0,0 +1,8 @@
|
||||
flow:
|
||||
chain:
|
||||
- name: chain4
|
||||
value: "THEN(a, chain5);"
|
||||
- name: chain5
|
||||
value: "THEN(b, chain6);"
|
||||
- name: chain6
|
||||
value: "THEN(c, chain5);"
|
||||
Reference in New Issue
Block a user