补充测试用例

This commit is contained in:
bryan31
2022-02-24 17:22:10 +08:00
parent 2f41623769
commit 9e01dbfcca
63 changed files with 1157 additions and 139 deletions

View File

@@ -24,7 +24,6 @@ import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BuilderSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.builder.cmp"})
public class BuilderSpringbootTest extends BaseTest {
@Resource

View File

@@ -18,7 +18,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* springboot环境下异步线程超时日志打印测试
* springboot环境下自定义声明节点的测试
* @author Bryan.Zhang
* @since 2.6.4
*/

View File

@@ -1,13 +0,0 @@
package com.yomahub.liteflow.test.customThreadPool;
import com.yomahub.liteflow.thread.ExecutorBuilder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CustomThreadExecutor implements ExecutorBuilder {
@Override
public ExecutorService buildExecutor() {
return Executors.newCachedThreadPool();
}
}

View File

@@ -1,43 +0,0 @@
package com.yomahub.liteflow.test.customThreadPool;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.6.4
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/customThreadPool/application.properties")
@SpringBootTest(classes = CustomThreadPoolSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.customThreadPool.cmp"})
public class CustomThreadPoolSpringbootTest extends BaseTest {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Resource
private FlowExecutor flowExecutor;
@Test
public void testCustomThreadPool() throws Exception{
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertFalse(response.getSlot().getData("threadName").toString().startsWith("lf-when-thead"));
}
}

View File

@@ -1,6 +1,8 @@
package com.yomahub.liteflow.test.enable;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
@@ -27,13 +29,9 @@ import org.springframework.test.context.junit4.SpringRunner;
@ComponentScan({"com.yomahub.liteflow.test.enable.cmp"})
public class LiteflowEnableSpringbootTest extends BaseTest {
@Autowired
private ApplicationContext context;
@Test
public void testEnable() {
LiteflowConfig config = context.getBean(LiteflowConfig.class);
LiteflowConfig config = LiteflowConfigGetter.get();
Boolean enable = config.getEnable();
if (enable) {
System.out.println("成功启动,并且打印");

View File

@@ -3,7 +3,6 @@ package com.yomahub.liteflow.test.exception;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.entity.data.DefaultSlot;
import com.yomahub.liteflow.entity.data.LiteflowResponse;
import com.yomahub.liteflow.entity.data.Slot;
import com.yomahub.liteflow.exception.ChainNotFoundException;
import com.yomahub.liteflow.exception.ConfigErrorException;
import com.yomahub.liteflow.exception.FlowExecutorNotInitException;
@@ -32,10 +31,10 @@ import javax.annotation.Resource;
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/exception/application.properties")
@SpringBootTest(classes = FlowExecutorSpringBootTest.class)
@SpringBootTest(classes = ExceptionSpringBootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.exception.cmp1"})
public class FlowExecutorSpringBootTest extends BaseTest {
@ComponentScan({"com.yomahub.liteflow.test.exception.cmp"})
public class ExceptionSpringBootTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@@ -65,7 +64,7 @@ public class FlowExecutorSpringBootTest extends BaseTest {
public void testComponentCustomException() throws Exception {
flowExecutor.execute("chain1", "exception");
}
@Test(expected = FlowSystemException.class)
public void testNoConditionInChainException() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "test");
@@ -81,11 +80,4 @@ public class FlowExecutorSpringBootTest extends BaseTest {
Assert.assertNotNull(response.getCause());
Assert.assertNotNull(response.getSlot());
}
// @Test(expected = WhenExecuteException.class)
// public void testWhenExecuteTimeoutException() throws Exception {
// LiteflowResponse response = flowExecutor.execute("chain3", "when");
// Assert.assertFalse(response.isSuccess());
// ReflectionUtils.rethrowException(response.getCause());
// }
}

View File

@@ -5,7 +5,7 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp1;
package com.yomahub.liteflow.test.exception.cmp;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.core.NodeComponent;

View File

@@ -5,7 +5,7 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp1;
package com.yomahub.liteflow.test.exception.cmp;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.core.NodeComponent;

View File

@@ -5,7 +5,7 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp1;
package com.yomahub.liteflow.test.exception.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.slf4j.Logger;

View File

@@ -5,7 +5,7 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp1;
package com.yomahub.liteflow.test.exception.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.slf4j.Logger;

View File

@@ -1,2 +0,0 @@
liteflow.rule-source=customThreadPool/flow.xml
liteflow.thread-executor-class=com.yomahub.liteflow.test.customThreadPool.CustomThreadExecutor

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<when value="a,b,c"/>
</chain>
</flow>

View File

@@ -0,0 +1,84 @@
package com.yomahub.liteflow.test.builder;
import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
import com.yomahub.liteflow.builder.LiteFlowConditionBuilder;
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.entity.data.DefaultSlot;
import com.yomahub.liteflow.entity.data.LiteflowResponse;
import com.yomahub.liteflow.enums.NodeTypeEnum;
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;
//基于builder模式的单元测试
//这里只是最基本的builder模式的测试只是为了验证在spring模式下的正常性
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/builder/application.xml")
public class BuilderSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//基于普通组件的builder模式测试
@Test
public void testBuilder() throws Exception {
LiteFlowNodeBuilder.createNode().setId("a")
.setName("组件A")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.builder.cmp.ACmp")
.build();
LiteFlowNodeBuilder.createNode().setId("b")
.setName("组件B")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.builder.cmp.BCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("c")
.setName("组件C")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.builder.cmp.CCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("d")
.setName("组件D")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.builder.cmp.DCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("e")
.setName("组件E")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.builder.cmp.ECmp")
.build();
LiteFlowNodeBuilder.createNode().setId("f")
.setName("组件F")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.builder.cmp.FCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("g")
.setName("组件G")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.builder.cmp.GCmp")
.build();
LiteFlowChainBuilder.createChain().setChainName("chain2").setCondition(
LiteFlowConditionBuilder.createWhenCondition().setValue("c,d").build()
).build();
LiteFlowChainBuilder.createChain().setChainName("chain1").setCondition(
LiteFlowConditionBuilder
.createWhenCondition()
.setValue("a,b").build()
).setCondition(
LiteFlowConditionBuilder.createWhenCondition()
.setValue("e(f|g|chain2)").build()
).build();
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1");
Assert.assertTrue(response.isSuccess());
}
}

View File

@@ -5,12 +5,10 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customThreadPool.cmp;
package com.yomahub.liteflow.test.builder.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("a")
public class ACmp extends NodeComponent {
@Override

View File

@@ -5,17 +5,14 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customThreadPool.cmp;
package com.yomahub.liteflow.test.builder.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("b")
public class BCmp extends NodeComponent {
@Override
public void process() {
this.getSlot().setData("threadName", Thread.currentThread().getName());
System.out.println("BCmp executed!");
}

View File

@@ -5,12 +5,10 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customThreadPool.cmp;
package com.yomahub.liteflow.test.builder.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("c")
public class CCmp extends NodeComponent {
@Override

View File

@@ -0,0 +1,19 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.builder.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class DCmp extends NodeComponent {
@Override
public void process() {
System.out.println("DCmp executed!");
}
}

View File

@@ -0,0 +1,20 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.builder.cmp;
import com.yomahub.liteflow.core.NodeCondComponent;
public class ECmp extends NodeCondComponent {
@Override
public String processCond() throws Exception {
System.out.println("ECmp executed!");
return "chain2";
}
}

View File

@@ -0,0 +1,19 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.builder.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class FCmp extends NodeComponent {
@Override
public void process() {
System.out.println("FCmp executed!");
}
}

View File

@@ -0,0 +1,19 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.builder.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class GCmp extends NodeComponent {
@Override
public void process() {
System.out.println("GCmp executed!");
}
}

View File

@@ -0,0 +1,60 @@
package com.yomahub.liteflow.test.cmpRetry;
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.context.annotation.ComponentScan;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* 测试spring下的节点重试
* @author Bryan.Zhang
* @since 2.5.10
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/cmpRetry/application.xml")
@ComponentScan({"com.yomahub.liteflow.test.cmpRetry.cmp"})
public class LiteflowRetrySpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//全局重试配置测试
@Test
public void testRetry1() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("a==>b==>b==>b", response.getSlot().getExecuteStepStr());
}
//单个组件重试配置测试
@Test
public void testRetry2() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain2", "arg");
Assert.assertFalse(response.isSuccess());
Assert.assertEquals("c==>c==>c==>c==>c==>c", response.getSlot().getExecuteStepStr());
}
//单个组件指定异常,但抛出的并不是指定异常的场景测试
@Test
public void testRetry3() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain3", "arg");
Assert.assertFalse(response.isSuccess());
}
//单个组件指定异常重试,抛出的是指定异常或者
@Test
public void testRetry4() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain4", "arg");
Assert.assertFalse(response.isSuccess());
Assert.assertEquals("e==>e==>e==>e==>e==>e", response.getSlot().getExecuteStepStr());
}
}

View File

@@ -0,0 +1,20 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.cmpRetry.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!");
}
}

View File

@@ -0,0 +1,27 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.cmpRetry.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
@LiteflowComponent("b")
public class BCmp extends NodeComponent {
private int flag = 0;
@Override
public void process() {
System.out.println("BCmp executed!");
if (flag < 2){
flag++;
throw new RuntimeException("demo exception");
}
}
}

View File

@@ -0,0 +1,24 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.cmpRetry.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.annotation.LiteflowRetry;
import com.yomahub.liteflow.core.NodeComponent;
@LiteflowComponent("c")
@LiteflowRetry(5)
public class CCmp extends NodeComponent {
@Override
public void process() {
System.out.println("CCmp executed!");
throw new RuntimeException("demo exception");
}
}

View File

@@ -0,0 +1,24 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.cmpRetry.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.annotation.LiteflowRetry;
import com.yomahub.liteflow.core.NodeComponent;
@LiteflowComponent("d")
@LiteflowRetry(retry = 5, forExceptions = {NullPointerException.class})
public class DCmp extends NodeComponent {
@Override
public void process() {
System.out.println("DCmp executed!");
throw new RuntimeException("demo exception");
}
}

View File

@@ -0,0 +1,24 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.cmpRetry.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.annotation.LiteflowRetry;
import com.yomahub.liteflow.core.NodeComponent;
@LiteflowComponent("e")
@LiteflowRetry(retry = 5, forExceptions = {NullPointerException.class})
public class ECmp extends NodeComponent {
@Override
public void process() {
System.out.println("ECmp executed!");
throw new NullPointerException("demo null exception");
}
}

View File

@@ -0,0 +1,89 @@
package com.yomahub.liteflow.test.component;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ReflectionUtils;
import javax.annotation.Resource;
import java.lang.reflect.UndeclaredThrowableException;
/**
* 组件功能点测试
* 单元测试
*
* @author donguo.tao
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/component/application.xml")
public class ComponentSpringTest extends BaseTest {
private static final Logger LOG = LoggerFactory.getLogger(ComponentSpringTest.class);
@Resource
private FlowExecutor flowExecutor;
//isAccess方法的功能测试
@Test
public void testIsAccess() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", 101);
Assert.assertTrue(response.isSuccess());
Assert.assertNotNull(response.getSlot().getResponseData());
}
//组件抛错的功能点测试
@Test(expected = ArithmeticException.class)
public void testComponentException() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain2", 0);
Assert.assertFalse(response.isSuccess());
Assert.assertEquals("/ by zero", response.getMessage());
ReflectionUtils.rethrowException(response.getCause());
}
//isContinueOnError方法的功能点测试
@Test(expected = UndeclaredThrowableException.class)
public void testIsContinueOnError() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain3", 0);
Assert.assertTrue(response.isSuccess());
ReflectionUtils.rethrowException(response.getCause());
}
//isEnd方法的功能点测试
@Test
public void testIsEnd() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain4", 10);
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("d",response.getSlot().getExecuteStepStr());
}
//setIsEnd方法的功能点测试
@Test
public void testSetIsEnd1() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain5", 10);
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("e",response.getSlot().getExecuteStepStr());
}
//条件组件的功能点测试
@Test
public void testNodeCondComponent() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain6", 0);
Assert.assertTrue(response.isSuccess());
}
//测试setIsEnd如果为truecontinueError也为true那不应该continue了
@Test
public void testSetIsEnd2() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain7", 10);
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("g",response.getSlot().getExecuteStepStr());
}
}

View File

@@ -0,0 +1,26 @@
package com.yomahub.liteflow.test.component.cmp1;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component("a")
public class ACmp extends NodeComponent {
@Override
public void process() {
System.out.println("AComp executed!");
this.getSlot().setResponseData("AComp executed!");
}
@Override
public boolean isAccess() {
Integer requestData = this.getSlot().getRequestData();
if (Objects.nonNull(requestData) && requestData > 100){
return true;
}
System.out.println("AComp isAccess false.");
return false;
}
}

View File

@@ -0,0 +1,29 @@
package com.yomahub.liteflow.test.component.cmp1;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component("b")
public class BCmp extends NodeComponent {
@Override
public void process() {
System.out.println("BComp executed!");
Integer requestData = this.getSlot().getRequestData();
Integer divisor = 130;
Integer result = divisor / requestData;
this.getSlot().setResponseData(result);
}
@Override
public boolean isAccess() {
Integer requestData = this.getSlot().getRequestData();
if (Objects.nonNull(requestData)){
return true;
}
return false;
}
}

View File

@@ -0,0 +1,29 @@
package com.yomahub.liteflow.test.component.cmp1;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component("c")
public class CCmp extends NodeComponent {
@Override
public void process() {
System.out.println("CComp executed!");
Integer requestData = this.getSlot().getRequestData();
Integer divisor = 130;
Integer result = divisor / requestData;
this.getSlot().setResponseData(result);
System.out.println("responseData="+Integer.parseInt(this.getSlot().getResponseData()));
}
@Override
public boolean isContinueOnError() {
Integer requestData = this.getSlot().getRequestData();
if (Objects.nonNull(requestData)){
return true;
}
return false;
}
}

View File

@@ -0,0 +1,26 @@
package com.yomahub.liteflow.test.component.cmp1;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component("d")
public class DCmp extends NodeComponent {
@Override
public void process() throws Exception {
System.out.println("DComp executed!");
}
@Override
public boolean isEnd() {
//组件的process执行完之后才会执行isEnd
Object requestData = this.getSlot().getResponseData();
if (Objects.isNull(requestData)){
System.out.println("DComp flow isEnd, because of responseData is null.");
return true;
}
return false;
}
}

View File

@@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.component.cmp1;
import com.alibaba.fastjson.JSON;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component("e")
public class ECmp extends NodeComponent {
@Override
public void process() throws Exception {
System.out.println("EComp executed!");
Object responseData = this.getSlot().getResponseData();
if (Objects.isNull(responseData)){
System.out.println("EComp responseData flow must be set end .");
//执行到某个条件时,手动结束流程。
this.setIsEnd(true);
}
System.out.println("EComp responseData responseData=" + JSON.toJSONString(responseData));
}
}

View File

@@ -0,0 +1,26 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.component.cmp1;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("g")
public class GCmp extends NodeComponent {
@Override
public void process() {
System.out.println("GCmp executed!");
this.setIsEnd(true);
}
@Override
public boolean isContinueOnError() {
return true;
}
}

View File

@@ -0,0 +1,20 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.component.cmp1;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("h")
public class HCmp extends NodeComponent {
@Override
public void process() {
System.out.println("HCmp executed!");
}
}

View File

@@ -0,0 +1,22 @@
package com.yomahub.liteflow.test.component.cmp2;
import com.yomahub.liteflow.core.NodeCondComponent;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component("f")
public class FCondCmp extends NodeCondComponent {
@Override
public String processCond() {
Integer requestData = this.getSlot().getRequestData();
if (Objects.isNull(requestData)){
return "d";
} else if(requestData == 0){
return "c";
} else {
return "b";
}
}
}

View File

@@ -1,4 +1,4 @@
package com.yomahub.liteflow.test.customThreadPool;
package com.yomahub.liteflow.test.customNodes;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.entity.data.DefaultSlot;
@@ -15,13 +15,13 @@ import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* springboot环境下异步线程超时日志打印测试
* spring环境下自定义声明节点的测试
* @author Bryan.Zhang
* @since 2.6.4
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/customThreadPool/application.xml")
public class CustomThreadPoolSpringTest extends BaseTest {
@ContextConfiguration("classpath:/customNodes/application.xml")
public class CustomNodesSpringTest extends BaseTest {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@@ -29,9 +29,10 @@ public class CustomThreadPoolSpringTest extends BaseTest {
private FlowExecutor flowExecutor;
@Test
public void testCustomThreadPool() throws Exception{
public void testCustomNodes() throws Exception{
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertFalse(response.getSlot().getData("threadName").toString().startsWith("lf-when-thead"));
response = flowExecutor.execute2Resp("chain2", "arg");
Assert.assertTrue(response.isSuccess());
}
}

View File

@@ -5,12 +5,10 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customThreadPool.cmp;
package com.yomahub.liteflow.test.customNodes.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("a")
public class ACmp extends NodeComponent {
@Override

View File

@@ -5,17 +5,21 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customThreadPool.cmp;
package com.yomahub.liteflow.test.customNodes.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
import com.yomahub.liteflow.test.customNodes.domain.DemoDomain;
import javax.annotation.Resource;
@Component("b")
public class BCmp extends NodeComponent {
@Resource
private DemoDomain demoDomain;
@Override
public void process() {
this.getSlot().setData("threadName", Thread.currentThread().getName());
demoDomain.sayHi();
System.out.println("BCmp executed!");
}

View File

@@ -5,12 +5,10 @@
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customThreadPool.cmp;
package com.yomahub.liteflow.test.customNodes.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("c")
public class CCmp extends NodeComponent {
@Override

View File

@@ -0,0 +1,19 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customNodes.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class DCmp extends NodeComponent {
@Override
public void process() {
System.out.println("DCmp executed!");
}
}

View File

@@ -0,0 +1,26 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customNodes.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.test.customNodes.domain.DemoDomain;
import javax.annotation.Resource;
public class ECmp extends NodeComponent {
@Resource
private DemoDomain demoDomain;
@Override
public void process() {
demoDomain.sayHi();
System.out.println("ECmp executed!");
}
}

View File

@@ -0,0 +1,19 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.customNodes.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class FCmp extends NodeComponent {
@Override
public void process() {
System.out.println("FCmp executed!");
}
}

View File

@@ -0,0 +1,11 @@
package com.yomahub.liteflow.test.customNodes.domain;
import org.springframework.stereotype.Component;
@Component
public class DemoDomain {
public void sayHi(){
System.out.println("hi");
}
}

View File

@@ -1,13 +0,0 @@
package com.yomahub.liteflow.test.customThreadPool;
import com.yomahub.liteflow.thread.ExecutorBuilder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CustomThreadExecutor implements ExecutorBuilder {
@Override
public ExecutorService buildExecutor() {
return Executors.newCachedThreadPool();
}
}

View File

@@ -0,0 +1,28 @@
package com.yomahub.liteflow.test.emptyflow;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.test.BaseTest;
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;
/**
* 切面场景单元测试
* @author Bryan.Zhang
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/emptyFlow/application.xml")
public class EmptyFlowTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//测试空flow的情况下liteflow是否能正常启动
@Test
public void testEmptyFlow() {
//不做任何事,为的是能正常启动
}
}

View File

@@ -4,6 +4,7 @@ import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.entity.data.DefaultSlot;
import com.yomahub.liteflow.entity.data.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
@@ -27,12 +28,9 @@ public class LiteflowEnableSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Autowired
private ApplicationContext context;
@Test
public void testEnable() throws Exception {
LiteflowConfig config = context.getBean(LiteflowConfig.class);
LiteflowConfig config = LiteflowConfigGetter.get();
Boolean enable = config.getEnable();
if (enable) {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");

View File

@@ -0,0 +1,77 @@
package com.yomahub.liteflow.test.exception;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.entity.data.DefaultSlot;
import com.yomahub.liteflow.entity.data.LiteflowResponse;
import com.yomahub.liteflow.exception.ChainNotFoundException;
import com.yomahub.liteflow.exception.ConfigErrorException;
import com.yomahub.liteflow.exception.FlowExecutorNotInitException;
import com.yomahub.liteflow.exception.FlowSystemException;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ReflectionUtils;
import javax.annotation.Resource;
/**
* 流程执行异常
* 单元测试
*
* @author zendwang
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/exception/application.xml")
public class ExceptionSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Autowired
private ApplicationContext context;
@Test(expected = ConfigErrorException.class)
public void testConfigErrorException() {
flowExecutor.setLiteflowConfig(null);
flowExecutor.init();
}
@Test(expected = FlowExecutorNotInitException.class)
public void testFlowExecutorNotInitException() {
LiteflowConfig config = context.getBean(LiteflowConfig.class);
config.setRuleSource("error/flow.txt");
flowExecutor.init();
}
@Test(expected = ChainNotFoundException.class)
public void testChainNotFoundException() throws Exception {
flowExecutor.execute("chain0", "it's a request");
}
@Test(expected = RuntimeException.class)
public void testComponentCustomException() throws Exception {
flowExecutor.execute("chain1", "exception");
}
@Test(expected = FlowSystemException.class)
public void testNoConditionInChainException() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "test");
Assert.assertFalse(response.isSuccess());
Assert.assertEquals("no conditionList in this chain[chain2]", response.getMessage());
ReflectionUtils.rethrowException(response.getCause());
}
@Test
public void testGetSlotFromResponseWhenException() throws Exception{
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain4", "test");
Assert.assertFalse(response.isSuccess());
Assert.assertNotNull(response.getCause());
Assert.assertNotNull(response.getSlot());
}
}

View File

@@ -0,0 +1,30 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.core.NodeComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component("a")
public class ACmp extends NodeComponent {
private static final Logger LOG = LoggerFactory.getLogger(ACmp.class);
@Override
public void process() {
String str = this.getSlot().getRequestData();
if(StrUtil.isNotBlank(str) && str.equals("exception")) {
throw new RuntimeException("chain execute execption");
}
LOG.info("Acomp executed!");
}
}

View File

@@ -0,0 +1,35 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.core.NodeComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component("b")
public class BCmp extends NodeComponent {
private static final Logger LOG = LoggerFactory.getLogger(BCmp.class);
@Override
public void process() throws InterruptedException {
String str = this.getSlot().getRequestData();
if(StrUtil.isNotBlank(str) && str.equals("when")) {
try {
LOG.info("Bcomp sleep begin");
Thread.sleep(3000);
LOG.info("Bcomp sleep end");
} catch (InterruptedException e) {
throw e;
}
}
LOG.info("Bcomp executed!");
}
}

View File

@@ -0,0 +1,24 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component("c")
public class CCmp extends NodeComponent {
private static final Logger LOG = LoggerFactory.getLogger(CCmp.class);
@Override
public void process() {
LOG.info("Ccomp executed!");
}
}

View File

@@ -0,0 +1,27 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.exception.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component("d")
public class DCmp extends NodeComponent {
private static final Logger LOG = LoggerFactory.getLogger(DCmp.class);
@Override
public void process() {
if(1==1){
int a = 1/0;
}
LOG.info("Dcomp executed!");
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig"/>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@@ -7,15 +7,16 @@
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.yomahub.liteflow.test.customThreadPool.cmp" />
<context:component-scan base-package="com.yomahub.liteflow.test.cmpRetry.cmp" />
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="customThreadPool/flow.xml"/>
<property name="threadExecutorClass" value="com.yomahub.liteflow.test.customThreadPool.CustomThreadExecutor"/>
<property name="ruleSource" value="cmpRetry/flow.xml"/>
<property name="retryCount" value="3"/>
<property name="slotSize" value="512"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b"/>
</chain>
<chain name="chain2">
<then value="c"/>
</chain>
<chain name="chain3">
<then value="d"/>
</chain>
<chain name="chain4">
<then value="e"/>
</chain>
</flow>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.yomahub.liteflow.test.component.cmp1,com.yomahub.liteflow.test.component.cmp2" />
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="component/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a"/>
</chain>
<chain name="chain2">
<then value="b"/>
</chain>
<chain name="chain3">
<then value="c"/>
</chain>
<chain name="chain4">
<then value="a,d,c"/>
</chain>
<chain name="chain5">
<then value="a,e,c"/>
</chain>
<chain name="chain6">
<then value="f(d | c | b)" />
</chain>
<chain name="chain7">
<then value="g,h"/>
</chain>
</flow>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.yomahub.liteflow.test.customNodes.domain" />
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="customNodes/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="a" class="com.yomahub.liteflow.test.customNodes.cmp.ACmp"/>
<node id="b" class="com.yomahub.liteflow.test.customNodes.cmp.BCmp"/>
<node id="c" class="com.yomahub.liteflow.test.customNodes.cmp.CCmp"/>
<node id="d" class="com.yomahub.liteflow.test.customNodes.cmp.DCmp"/>
<node id="e" class="com.yomahub.liteflow.test.customNodes.cmp.ECmp"/>
<node id="f" class="com.yomahub.liteflow.test.customNodes.cmp.FCmp"/>
</nodes>
<chain name="chain1">
<when value="a,b,c"/>
</chain>
<chain name="chain2">
<when value="d,e,f"/>
</chain>
</flow>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<when value="a,b,c"/>
</chain>
</flow>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="emptyFlow/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.yomahub.liteflow.test.exception.cmp" />
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="exception/flow.xml"/>
<property name="whenMaxWaitSeconds" value="1"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
<chain name="chain2">
</chain>
<chain name="chain3">
<then value="a" />
<when value="b,c" errorResume="false" />
</chain>
<chain name="chain4">
<then value="c,d"/>
</chain>
</flow>