增加测试用例

This commit is contained in:
bryan31 2022-02-23 18:24:57 +08:00
parent b9198df609
commit 4a5f436716
60 changed files with 1307 additions and 239 deletions

View File

@ -67,6 +67,12 @@ public class FlowExecutor {
this.liteflowConfig = liteflowConfig;
}
public static FlowExecutor loadInstance(LiteflowConfig liteflowConfig){
FlowExecutor flowExecutor = new FlowExecutor(liteflowConfig);
flowExecutor.init();
return flowExecutor;
}
/**
* FlowExecutor的初始化化方式主要用于parse规则文件
*/

View File

@ -17,6 +17,12 @@
<artifactId>liteflow-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@ -0,0 +1,18 @@
package com.yomahub.liteflow.test;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.spi.holder.SpiFactoryCleaner;
import com.yomahub.liteflow.thread.ExecutorHelper;
import org.junit.AfterClass;
public class BaseTest {
@AfterClass
public static void cleanScanCache(){
FlowBus.cleanCache();
ExecutorHelper.loadInstance().clearExecutorServiceMap();
SpiFactoryCleaner.clean();
LiteflowConfigGetter.clean();
}
}

View File

@ -7,15 +7,13 @@ import com.yomahub.liteflow.property.LiteflowConfig;
import org.junit.Assert;
import org.junit.Test;
public class BaseTest {
public class BaseCommonTest {
@Test
public void testBase(){
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("base/flow.xml");
FlowExecutor executor = new FlowExecutor();
executor.setLiteflowConfig(config);
executor.init();
FlowExecutor executor = FlowExecutor.loadInstance(config);
LiteflowResponse<DefaultSlot> response = executor.execute2Resp("chain1", "test0");
Assert.assertTrue(response.isSuccess());
}

View File

@ -0,0 +1,96 @@
package com.yomahub.liteflow.test.script.groovy;
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.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LiteFlowXmlScriptBuilderGroovyTest.class)
@EnableAutoConfiguration
public class LiteFlowXmlScriptBuilderGroovyTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//测试通过builder方式运行普通script节点以脚本文本的方式运行
@Test
public void testBuilderScript1() {
LiteFlowNodeBuilder.createNode().setId("a")
.setName("组件A")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.groovy.cmp.ACmp")
.build();
LiteFlowNodeBuilder.createNode().setId("b")
.setName("组件B")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.groovy.cmp.BCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("c")
.setName("组件C")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.groovy.cmp.CCmp")
.build();
LiteFlowNodeBuilder.createScriptNode()
.setId("s1")
.setName("普通脚本S1")
.setType(NodeTypeEnum.SCRIPT)
.setScript("Integer a=3;Integer b=2;slot.setData(\"s1\",a*b)")
.build();
LiteFlowChainBuilder.createChain().setChainName("chain1")
.setCondition(LiteFlowConditionBuilder.createThenCondition().setValue("a,b,c,s1").build())
.build();
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1","arg1");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals(Integer.valueOf(6), response.getSlot().getData("s1"));
}
//测试通过builder方式运行普通script节点以file的方式运行
@Test
public void testBuilderScript2() {
LiteFlowNodeBuilder.createNode().setId("d")
.setName("组件D")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.groovy.cmp.DCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("s2")
.setName("条件脚本S2")
.setType(NodeTypeEnum.COND_SCRIPT)
.setFile("builder/s2.groovy")
.build();
LiteFlowNodeBuilder.createNode().setId("a")
.setName("组件A")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.groovy.cmp.ACmp")
.build();
LiteFlowNodeBuilder.createNode().setId("b")
.setName("组件B")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.groovy.cmp.BCmp")
.build();
LiteFlowChainBuilder.createChain().setChainName("chain2")
.setCondition(LiteFlowConditionBuilder.createThenCondition().setValue("d,s2(a|b)").build())
.build();
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain2","arg1");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("d[组件D]==>s2[条件脚本S2]==>a[组件A]", response.getSlot().getExecuteStepStr());
}
}

View File

@ -0,0 +1,96 @@
package com.yomahub.liteflow.test.script.qlexpress;
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.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LiteFlowXmlScriptBuilderQLExpressTest.class)
@EnableAutoConfiguration
public class LiteFlowXmlScriptBuilderQLExpressTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//测试通过builder方式运行普通script节点以脚本文本的方式运行
@Test
public void testBuilderScript1() {
LiteFlowNodeBuilder.createNode().setId("a")
.setName("组件A")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.qlexpress.cmp.ACmp")
.build();
LiteFlowNodeBuilder.createNode().setId("b")
.setName("组件B")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.qlexpress.cmp.BCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("c")
.setName("组件C")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.qlexpress.cmp.CCmp")
.build();
LiteFlowNodeBuilder.createScriptNode()
.setId("s1")
.setName("普通脚本S1")
.setType(NodeTypeEnum.SCRIPT)
.setScript("a=3;b=2;slot.setData(\"s1\",a*b);")
.build();
LiteFlowChainBuilder.createChain().setChainName("chain1")
.setCondition(LiteFlowConditionBuilder.createThenCondition().setValue("a,b,c,s1").build())
.build();
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1","arg1");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals(Integer.valueOf(6), response.getSlot().getData("s1"));
}
//测试通过builder方式运行普通script节点以file的方式运行
@Test
public void testBuilderScript2() {
LiteFlowNodeBuilder.createNode().setId("d")
.setName("组件D")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.qlexpress.cmp.DCmp")
.build();
LiteFlowNodeBuilder.createNode().setId("s2")
.setName("条件脚本S2")
.setType(NodeTypeEnum.COND_SCRIPT)
.setFile("builder/s2.ql")
.build();
LiteFlowNodeBuilder.createNode().setId("a")
.setName("组件A")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.qlexpress.cmp.ACmp")
.build();
LiteFlowNodeBuilder.createNode().setId("b")
.setName("组件B")
.setType(NodeTypeEnum.COMMON)
.setClazz("com.yomahub.liteflow.test.script.qlexpress.cmp.BCmp")
.build();
LiteFlowChainBuilder.createChain().setChainName("chain2")
.setCondition(LiteFlowConditionBuilder.createThenCondition().setValue("d,s2(a|b)").build())
.build();
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain2","arg1");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("d[组件D]==>s2[条件脚本S2]==>b[组件B]", response.getSlot().getExecuteStepStr());
}
}

View File

@ -23,11 +23,11 @@ import javax.annotation.Resource;
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/aop/application.properties")
@SpringBootTest(classes = LFCustomAOPTest.class)
@SpringBootTest(classes = CustomAOPSpringbootTest.class)
@EnableAutoConfiguration
@Import(CustomAspect.class)
@ComponentScan({"com.yomahub.liteflow.test.aop.cmp1","com.yomahub.liteflow.test.aop.cmp2"})
public class LFCustomAOPTest extends BaseTest {
public class CustomAOPSpringbootTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;

View File

@ -25,11 +25,11 @@ import javax.annotation.Resource;
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/aop/application.properties")
@SpringBootTest(classes = LFGlobalAOPTest.class)
@SpringBootTest(classes = GlobalAOPSpringbootTest.class)
@EnableAutoConfiguration
@Import(CmpAspect.class)
@ComponentScan({"com.yomahub.liteflow.test.aop.cmp1","com.yomahub.liteflow.test.aop.cmp2"})
public class LFGlobalAOPTest extends BaseTest {
public class GlobalAOPSpringbootTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;

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;
@ -24,20 +25,17 @@ import javax.annotation.Resource;
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/config/application-local.properties")
@SpringBootTest(classes = LiteflowConfigSpringbootTest.class)
@TestPropertySource(value = "classpath:/config/application1.properties")
@SpringBootTest(classes = LiteflowConfigSpringbootTest1.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.config.cmp"})
public class LiteflowConfigSpringbootTest extends BaseTest {
public class LiteflowConfigSpringbootTest1 extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Autowired
private ApplicationContext context;
@Test
public void testConfig() {
LiteflowConfig config = context.getBean(LiteflowConfig.class);
LiteflowConfig config = LiteflowConfigGetter.get();
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("config/flow.yml", config.getRuleSource());

View File

@ -0,0 +1,44 @@
package com.yomahub.liteflow.test.config;
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.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.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
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 zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/config/application2.properties")
@SpringBootTest(classes = LiteflowConfigSpringbootTest2.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.config.cmp"})
public class LiteflowConfigSpringbootTest2 extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//测试通配符
@Test
public void testRuleSourceMatch() {
LiteflowResponse<DefaultSlot> response0 = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertEquals("a==>b==>c", response0.getSlot().getExecuteStepStr());
LiteflowResponse<DefaultSlot> response1 = flowExecutor.execute2Resp("chain2", "arg");
Assert.assertEquals("a==>c==>b==>d", response1.getSlot().getExecuteStepStr());
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1 @@
liteflow.rule-source=config/**/flow*.xml

View File

@ -57,6 +57,12 @@
<artifactId>zkclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,27 @@
package com.yomahub.liteflow.test.absoluteConfigPath;
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.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/absoluteConfigPath/application.xml")
public class AbsoluteConfigPathSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testAbsoluteConfig(){
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
}

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.absoluteConfigPath.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("ACmp executed!");
}
}

View File

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

View File

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

View File

@ -0,0 +1,45 @@
package com.yomahub.liteflow.test.aop;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.entity.data.DefaultSlot;
import com.yomahub.liteflow.entity.data.LiteflowResponse;
import com.yomahub.liteflow.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;
/**
* 切面场景单元测试
* @author Bryan.Zhang
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/aop/application-global.xml")
public class CustomAOPSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//测试自定义AOP串行场景
@Test
public void testCustomAopS() {
LiteflowResponse<DefaultSlot> response= flowExecutor.execute2Resp("chain1", "it's a request");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("before_after", response.getSlot().getData("a"));
Assert.assertEquals("before_after", response.getSlot().getData("b"));
Assert.assertEquals("before_after", response.getSlot().getData("c"));
}
//测试自定义AOP并行场景
@Test
public void testCustomAopP() {
LiteflowResponse<DefaultSlot> response= flowExecutor.execute2Resp("chain2", "it's a request");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("before_after", response.getSlot().getData("a"));
Assert.assertEquals("before_after", response.getSlot().getData("b"));
Assert.assertEquals("before_after", response.getSlot().getData("c"));
}
}

View File

@ -0,0 +1,58 @@
package com.yomahub.liteflow.test.aop;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.entity.data.DefaultSlot;
import com.yomahub.liteflow.entity.data.LiteflowResponse;
import com.yomahub.liteflow.spring.ComponentScanner;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.AfterClass;
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;
/**
* 切面场景单元测试
* @author Bryan.Zhang
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/aop/application-global.xml")
public class GlobalAOPSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//测试全局AOP串行场景
@Test
public void testGlobalAopS() {
LiteflowResponse<DefaultSlot> response= flowExecutor.execute2Resp("chain1", "it's a request");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("before_after", response.getSlot().getData("a"));
Assert.assertEquals("before_after", response.getSlot().getData("b"));
Assert.assertEquals("before_after", response.getSlot().getData("c"));
Assert.assertEquals("before_after", response.getSlot().getData("d"));
Assert.assertEquals("before_after", response.getSlot().getData("e"));
}
//测试全局AOP并行场景
@Test
public void testGlobalAopP() {
LiteflowResponse<DefaultSlot> response= flowExecutor.execute2Resp("chain2", "it's a request");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("before_after", response.getSlot().getData("a"));
Assert.assertEquals("before_after", response.getSlot().getData("b"));
Assert.assertEquals("before_after", response.getSlot().getData("c"));
Assert.assertEquals("before_after", response.getSlot().getData("d"));
Assert.assertEquals("before_after", response.getSlot().getData("e"));
}
@AfterClass
public static void cleanScanCache(){
BaseTest.cleanScanCache();
ComponentScanner.cmpAroundAspect = null;
}
}

View File

@ -0,0 +1,17 @@
package com.yomahub.liteflow.test.aop.aspect;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.aop.ICmpAroundAspect;
import com.yomahub.liteflow.entity.data.Slot;
public class CmpAspect implements ICmpAroundAspect {
@Override
public void beforeProcess(String nodeId, Slot slot) {
slot.setData(nodeId, "before");
}
@Override
public void afterProcess(String nodeId, Slot slot) {
slot.setData(nodeId, StrUtil.format("{}_{}", slot.getData(nodeId), "after"));
}
}

View File

@ -0,0 +1,27 @@
package com.yomahub.liteflow.test.aop.aspect;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class CustomAspect {
@Pointcut("execution(* com.yomahub.liteflow.test.aop.cmp1.*.process())")
public void cut() {
}
@Around("cut()")
public Object around(ProceedingJoinPoint jp) throws Throwable {
NodeComponent cmp = (NodeComponent) jp.getThis();
Slot slot = cmp.getSlot();
slot.setData(cmp.getNodeId(), "before");
Object returnObj = jp.proceed();
slot.setData(cmp.getNodeId(), StrUtil.format("{}_{}", slot.getData(cmp.getNodeId()), "after"));
return returnObj;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,128 @@
package com.yomahub.liteflow.test.asyncNode;
import cn.hutool.core.collection.ListUtil;
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 com.yomahub.liteflow.test.asyncNode.exception.TestException;
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;
/**
* 测试隐式调用子流程
* 单元测试
*
* @author ssss
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/asyncNode/application.xml")
public class AsyncNodeSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
/*****
* 标准chain 嵌套选择 嵌套子chain进行执行
* 验证了when情况下 多个node是并行执行
* 验证了默认参数情况下 when可以加载执行
* **/
@Test
public void testAsyncFlow1() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "it's a base request");
Assert.assertTrue(response.isSuccess());
System.out.println(response.getSlot().getExecuteStepStr());
}
//这个和test1有点类似只不过进一步验证了步骤
@Test
public void testAsyncFlow2() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain2", "it's a base request");
Assert.assertTrue(ListUtil.toList("b==>j==>g==>f==>h","b==>j==>g==>h==>f",
"b==>j==>h==>g==>f","b==>j==>h==>f==>g",
"b==>j==>f==>h==>g","b==>j==>f==>g==>h"
).contains(response.getSlot().getExecuteStepStr()));
}
//测试errorResume,默认的errorResume为false这里测试默认的
@Test
public void testAsyncFlow3_1() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain3-1", "it's a base request");
Assert.assertFalse(response.isSuccess());
Assert.assertEquals(response.getSlot().getException().getClass(), TestException.class);
}
//测试errorResume,默认的errorResume为false这里设置为true
@Test
public void testAsyncFlow3_2() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain3-2", "it's a base request");
Assert.assertTrue(response.isSuccess());
}
//相同group的并行组会合并并且errorResume根据第一个when来这里第一个when配置了不抛错
@Test
public void testAsyncFlow4() {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain4", "it's a base request");
//因为不记录错误所以最终结果是true
Assert.assertTrue(response.isSuccess());
//因为是并行组所以即便抛错了其他组件也会执行i在流程里配置了2遍i抛错但是也执行了2遍这里验证下
Integer count = response.getSlot().getData("count");
Assert.assertEquals(new Integer(2), count);
//因为配置了不抛错所以response里的cause应该为null
Assert.assertNull(response.getCause());
}
//相同group的并行组会合并并且errorResume根据第一个when来这里第一个when配置了会抛错
@Test
public void testAsyncFlow5() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain5", "it's a base request");
//整个并行组是报错的所以最终结果是false
Assert.assertFalse(response.isSuccess());
//因为是并行组所以即便抛错了其他组件也会执行i在流程里配置了2遍i抛错但是也执行了2遍这里验证下
Integer count = response.getSlot().getData("count");
Assert.assertEquals(new Integer(2), count);
//因为第一个when配置了会报错所以response里的cause里应该会有TestException
Assert.assertEquals(TestException.class, response.getCause().getClass());
}
//不同group的并行组不会合并第一个when的errorResume是false会抛错那第二个when就不会执行
@Test
public void testAsyncFlow6() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain6", "it's a base request");
//第一个when会抛错所以最终结果是false
Assert.assertFalse(response.isSuccess());
//因为是不同组并行组第一组的when里的i就抛错了所以i就执行了1遍
Integer count = response.getSlot().getData("count");
Assert.assertEquals(new Integer(1), count);
//第一个when会报错所以最终response的cause里应该会有TestException
Assert.assertEquals(TestException.class, response.getCause().getClass());
}
//不同group的并行组不会合并第一个when的errorResume是true不会报错那第二个when还会继续执行但是第二个when的errorResume是false所以第二个when会报错
@Test
public void testAsyncFlow7() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain7", "it's a base request");
//第二个when会抛错所以最终结果是false
Assert.assertFalse(response.isSuccess());
// 传递了slotIndex则set的size==2
Integer count = response.getSlot().getData("count");
Assert.assertEquals(new Integer(2), count);
//第一个when会报错所以最终response的cause里应该会有TestException
Assert.assertEquals(TestException.class, response.getCause().getClass());
}
//测试任意异步一个执行完即继续的场景
//d g h并行配置了any=true其中d耗时1秒g耗时0.5秒其他都不设耗时
//最终执行效果应该是h先返回然后执行abc,最后gd
//这里要注意的是由于step是先加入所以step的打印顺序并不是这样的但是实际执行是正确的
@Test
public void testAsyncFlow8() throws Exception {
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain8", "it's a base request");
Assert.assertTrue(response.isSuccess());
Assert.assertTrue(response.getSlot().getData("check").toString().startsWith("habc"));
}
}

View File

@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import org.springframework.stereotype.Component;
@Component("a")
public class ACmp extends NodeComponent {
@Override
public void process() {
Slot slot = this.getSlot();
synchronized (NodeComponent.class){
if (slot.hasData("check")){
String str = slot.getData("check");
str += this.getNodeId();
slot.setData("check", str);
}else{
slot.setData("check", this.getNodeId());
}
}
System.out.println("Acomp executed!");
}
}

View File

@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import org.springframework.stereotype.Component;
@Component("b")
public class BCmp extends NodeComponent {
@Override
public void process() {
Slot slot = this.getSlot();
synchronized (NodeComponent.class){
if (slot.hasData("check")){
String str = slot.getData("check");
str += this.getNodeId();
slot.setData("check", str);
}else{
slot.setData("check", this.getNodeId());
}
}
System.out.println("Bcomp executed!");
}
}

View File

@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import org.springframework.stereotype.Component;
@Component("c")
public class CCmp extends NodeComponent {
@Override
public void process() throws Exception {
Slot slot = this.getSlot();
synchronized (NodeComponent.class){
if (slot.hasData("check")){
String str = slot.getData("check");
str += this.getNodeId();
slot.setData("check", str);
}else{
slot.setData("check", this.getNodeId());
}
}
System.out.println("Ccomp executed!");
}
}

View File

@ -0,0 +1,25 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import org.springframework.stereotype.Component;
@Component("d")
public class DCmp extends NodeComponent {
@Override
public void process() throws Exception {
Thread.sleep(1000);
Slot slot = this.getSlot();
synchronized (NodeComponent.class){
if (slot.hasData("check")){
String str = slot.getData("check");
str += this.getNodeId();
slot.setData("check", str);
}else{
slot.setData("check", this.getNodeId());
}
}
System.out.println("Dcomp executed!");
}
}

View File

@ -0,0 +1,15 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeCondComponent;
import org.springframework.stereotype.Component;
@Component("e")
public class ECmp extends NodeCondComponent {
@Override
public String processCond() throws Exception {
System.out.println("Ecomp executed!");
return "g";
}
}

View File

@ -0,0 +1,14 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("f")
public class FCmp extends NodeComponent {
@Override
public void process() throws Exception {
System.out.println("Fcomp executed!");
}
}

View File

@ -0,0 +1,26 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import org.springframework.stereotype.Component;
@Component("g")
public class GCmp extends NodeComponent {
@Override
public void process() throws Exception {
Thread.sleep(500);
Slot slot = this.getSlot();
synchronized (NodeComponent.class){
if (slot.hasData("check")){
String str = slot.getData("check");
str += this.getNodeId();
slot.setData("check", str);
}else{
slot.setData("check", this.getNodeId());
}
}
System.out.println("Gcomp executed!");
}
}

View File

@ -0,0 +1,26 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import org.springframework.stereotype.Component;
@Component("h")
public class HCmp extends NodeComponent {
@Override
public void process() throws Exception {
Slot slot = this.getSlot();
synchronized (NodeComponent.class){
if (slot.hasData("check")){
String str = slot.getData("check");
str += this.getNodeId();
slot.setData("check", str);
}else{
slot.setData("check", this.getNodeId());
}
}
System.out.println("Hcomp executed!");
}
}

View File

@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.entity.data.Slot;
import com.yomahub.liteflow.test.asyncNode.exception.TestException;
import org.springframework.stereotype.Component;
@Component("i")
public class ICmp extends NodeComponent {
@Override
public void process() throws Exception {
Slot slot = this.getSlot();
if (slot.hasData("count")){
Integer count = slot.getData("count");
slot.setData("count", ++count);
} else{
slot.setData("count", 1);
}
System.out.println("Icomp executed! throw Exception!");
throw new TestException();
}
}

View File

@ -0,0 +1,15 @@
package com.yomahub.liteflow.test.asyncNode.cmp;
import com.yomahub.liteflow.core.NodeCondComponent;
import org.springframework.stereotype.Component;
@Component("j")
public class JCmp extends NodeCondComponent {
@Override
public String processCond() throws Exception {
System.out.println("Jcomp executed!");
return "chain3";
}
}

View File

@ -0,0 +1,28 @@
package com.yomahub.liteflow.test.base;
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.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/base/application.xml")
public class BaseCommonSpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testBaseCommon(){
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("a==>b==>c==>d", 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.base.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("ACmp executed!");
}
}

View File

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

View File

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

View File

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

View File

@ -1,101 +0,0 @@
package com.yomahub.liteflow.test.config;
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.ConfigErrorException;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
/**
* 无spring环境下参数单元测试
* @author zendwang
* @since 2.5.0
*/
public class LiteflowConfigNoSpringTest extends BaseTest {
@Test(expected = ConfigErrorException.class)
public void testNoConfig() {
FlowExecutor executor = new FlowExecutor();
executor.init();
}
@Test
public void testConfig() {
FlowExecutor executor = new FlowExecutor();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("config/flow.json");
executor.setLiteflowConfig(config);
executor.init();
LiteflowResponse<DefaultSlot> response = executor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals(15, config.getWhenMaxWaitSeconds().intValue());
Assert.assertEquals(200, config.getQueueLimit().intValue());
Assert.assertEquals(300000L, config.getDelay().longValue());
Assert.assertEquals(300000L, config.getPeriod().longValue());
Assert.assertFalse(config.getEnableLog());
Assert.assertEquals(Runtime.getRuntime().availableProcessors() * 2, config.getWhenMaxWorkers().longValue());
Assert.assertEquals(100, config.getWhenQueueLimit().longValue());
}
/**
* rule source支持的通配符
* 匹配的文件
* config/nospringgroup0/flow0.xml
* config/nospringgroup1/flow.xml
*/
@Test
public void testLocalXmlRuleSourcePatternMatch() {
FlowExecutor executor = new FlowExecutor();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("config/nospring*/flow*.xml");
executor.setLiteflowConfig(config);
executor.init();
LiteflowResponse<DefaultSlot> response0 = executor.execute2Resp("chain1", "arg");
Assert.assertEquals("a==>b==>c", response0.getSlot().getExecuteStepStr());
LiteflowResponse<DefaultSlot> response1 = executor.execute2Resp("chain3", "arg");
Assert.assertEquals("a==>c==>f==>g", response1.getSlot().getExecuteStepStr());
}
/**
* rule source支持的通配符
* 匹配的文件
* config/nospringgroup0/flow0.json
* config/nospringgroup1/flow0.json
*/
@Test
public void testLocalJsonRuleSourcePatternMatch() {
FlowExecutor executor = new FlowExecutor();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("config/nospring*/flow*.json");
executor.setLiteflowConfig(config);
executor.init();
LiteflowResponse<DefaultSlot> response0 = executor.execute2Resp("chain1", "arg");
Assert.assertEquals("a==>b==>c", response0.getSlot().getExecuteStepStr());
LiteflowResponse<DefaultSlot> response1 = executor.execute2Resp("chain3", "arg");
Assert.assertEquals("a==>c==>f==>g", response1.getSlot().getExecuteStepStr());
}
/**
* rule source支持的通配符
* 匹配的文件
* config/nospringgroup0/flow0.yml
* config/nospringgroup1/flow.yml
*/
@Test
public void testLocalYmlRuleSourcePatternMatch() {
FlowExecutor executor = new FlowExecutor();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("config/nospring*/flow*.yml");
executor.setLiteflowConfig(config);
executor.init();
LiteflowResponse<DefaultSlot> response0 = executor.execute2Resp("chain1", "arg");
Assert.assertEquals("a==>b==>c", response0.getSlot().getExecuteStepStr());
LiteflowResponse<DefaultSlot> response = executor.execute2Resp("chain3", "arg");
Assert.assertEquals("a==>c==>f==>g", response.getSlot().getExecuteStepStr());
}
}

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.absoluteConfigPath.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="/usr/local/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@ -0,0 +1,25 @@
<?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.aop.cmp1,com.yomahub.liteflow.test.aop.cmp2" />
<bean class="com.yomahub.liteflow.test.aop.aspect.CustomAspect"/>
<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="aop/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@ -0,0 +1,25 @@
<?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.aop.cmp1,com.yomahub.liteflow.test.aop.cmp2" />
<bean class="com.yomahub.liteflow.test.aop.aspect.CmpAspect"/>
<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="aop/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b,c,d,e"/>
</chain>
<chain name="chain2">
<then value="a,b,c"/>
<when value="d,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.asyncNode.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="asyncNode/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<!-- base test -->
<chain name="chain1">
<then value="a,b,c"/> <!-- a b c 串联执行-->
<when value="d,e(f|g)"/> <!-- e d 并联执行-->
<then value="chain2"/>
</chain>
<chain name="chain2">
<then value="b,j(a|chain3)"/>
</chain>
<chain name="chain3">
<when value="g,f,h"/>
</chain>
<chain name="chain3-1">
<when value="f,g,i" group="1"/>
<when value="h" group="2"/>
</chain>
<chain name="chain3-2">
<when value="f,g,i" errorResume="true" group="1"/>
<when value="h" group="2"/>
</chain>
<chain name="chain4">
<then value="a,b,c"/> <!-- a b c 串联执行-->
<when value="d,i" errorResume="true"/> <!-- d i 并联执行-->
<when value="g,i,h" errorResume="false"/><!-- 此时 g i h 与 d i并联执行 并且默认异常不抛出-->
</chain>
<chain name="chain5">
<then value="a,b,c"/> <!-- a b c 串联执行-->
<when value="d,i" errorResume="false"/> <!-- d i 并联执行-->
<when value="g,i,h" errorResume="true"/><!-- 此时 g i h 与 d i并联执行 并且默认异常抛出-->
</chain>
<chain name="chain6">
<then value="a,b,c"/> <!-- a b c 串联执行-->
<when value="d,i" errorResume="false" group="1"/> <!-- d i 并联执行-->
<when value="g,i,h" errorResume="true" group="2"/><!-- 此时 g i h 与 d i并联执行 并且默认异常抛出-->
</chain>
<chain name="chain7">
<then value="a,b,c"/> <!-- a b c 串联执行-->
<when value="d,i" errorResume="true" group="1"/> <!-- d i 并联执行-->
<when value="g,i,h" errorResume="false" group="2"/><!-- 此时 g i h 与 d i并联执行 并且默认异常抛出-->
</chain>
<chain name="chain8">
<when value="d,g,h" any="true"/> <!-- a b c 串联执行-->
<then value="a,b,c"/> <!-- d 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.base.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="base/flow.xml"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<property name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

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

View File

@ -1,28 +0,0 @@
{
"flow": {
"nodes": {
"node": [
{
"id": "a",
"class": "com.yomahub.liteflow.test.config.cmp.ACmp"
},
{
"id": "b",
"class": "com.yomahub.liteflow.test.config.cmp.BCmp"
},
{
"id": "c",
"class": "com.yomahub.liteflow.test.config.cmp.CCmp"
}
]
},
"chain": [
{
"name": "chain1",
"condition": [
{"type": "then", "value": "a,b,c"}
]
}
]
}
}

View File

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

View File

@ -1,14 +0,0 @@
flow:
nodes:
node:
- id: a
class: com.yomahub.liteflow.test.config.cmp.ACmp
- id: b
class: com.yomahub.liteflow.test.config.cmp.BCmp
- id: c
class: com.yomahub.liteflow.test.config.cmp.CCmp
chain:
- name: chain1
condition:
- type: then
value: 'a,b,c'

View File

@ -1,32 +0,0 @@
{
"flow": {
"nodes": {
"node": [
{
"id": "d",
"class": "com.yomahub.liteflow.test.config.cmp.DCmp"
},
{
"id": "e",
"class": "com.yomahub.liteflow.test.config.cmp.ECmp"
},
{
"id": "f",
"class": "com.yomahub.liteflow.test.config.cmp.FCmp"
},
{
"id": "g",
"class": "com.yomahub.liteflow.test.config.cmp.GCmp"
}
]
},
"chain": [
{
"name": "chain3",
"condition": [
{"type": "then", "value": "a,c,f,g"}
]
}
]
}
}

View File

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

View File

@ -1,16 +0,0 @@
flow:
nodes:
node:
- id: d
class: com.yomahub.liteflow.test.config.cmp.DCmp
- id: e
class: com.yomahub.liteflow.test.config.cmp.ECmp
- id: f
class: com.yomahub.liteflow.test.config.cmp.FCmp
- id: g
class: com.yomahub.liteflow.test.config.cmp.GCmp
chain:
- name: chain3
condition:
- type: then
value: 'a,c,f,g'