commit
9ae5751305
|
@ -17,6 +17,8 @@ import com.yomahub.liteflow.flow.FlowBus;
|
|||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.flow.element.Chain;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.element.Rollbackable;
|
||||
import com.yomahub.liteflow.flow.entity.CmpStep;
|
||||
import com.yomahub.liteflow.flow.id.IdGeneratorHolder;
|
||||
import com.yomahub.liteflow.log.LFLog;
|
||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||
|
@ -433,6 +435,22 @@ public class FlowExecutor {
|
|||
else {
|
||||
slot.setSubException(chainId, e);
|
||||
}
|
||||
Deque<CmpStep> executeSteps = slot.getExecuteSteps();
|
||||
try {
|
||||
Iterator<CmpStep> cmpStepIterator = executeSteps.descendingIterator();
|
||||
while(cmpStepIterator.hasNext()) {
|
||||
CmpStep cmpStep = cmpStepIterator.next();
|
||||
if(cmpStep.getInstance().isRollback()) {
|
||||
Rollbackable rollbackItem = new Node(cmpStep.getInstance());
|
||||
rollbackItem.rollback(slotIndex);
|
||||
}
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
LOG.error(exception.getMessage());
|
||||
}
|
||||
finally {
|
||||
slot.printRollbackStep();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (innerChainType.equals(InnerChainTypeEnum.NONE)) {
|
||||
|
|
|
@ -31,6 +31,7 @@ import com.yomahub.liteflow.flow.element.Executable;
|
|||
import com.yomahub.liteflow.monitor.CompStatistics;
|
||||
import com.yomahub.liteflow.monitor.MonitorBus;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -57,6 +58,9 @@ public abstract class NodeComponent {
|
|||
// 重试次数
|
||||
private int retryCount = 0;
|
||||
|
||||
// 是否重写了rollback方法
|
||||
private boolean isRollback = false;
|
||||
|
||||
// 在目标异常抛出时才重试
|
||||
private Class<? extends Exception>[] retryForExceptions = new Class[] { Exception.class };
|
||||
|
||||
|
@ -79,6 +83,14 @@ public abstract class NodeComponent {
|
|||
private final TransmittableThreadLocal<Boolean> isEndTL = new TransmittableThreadLocal<>();
|
||||
|
||||
public NodeComponent() {
|
||||
// 反射判断是否重写了rollback方法
|
||||
Class<?> clazz = this.getClass();
|
||||
try {
|
||||
Method method = clazz.getDeclaredMethod("rollback");
|
||||
if(ObjectUtil.isNotNull(method))
|
||||
this.setRollback(true);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void execute() throws Exception {
|
||||
|
@ -87,6 +99,7 @@ public abstract class NodeComponent {
|
|||
// 在元数据里加入step信息
|
||||
CmpStep cmpStep = new CmpStep(nodeId, name, CmpStepTypeEnum.SINGLE);
|
||||
cmpStep.setTag(this.getTag());
|
||||
cmpStep.setInstance(this);
|
||||
slot.addStep(cmpStep);
|
||||
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
|
@ -140,6 +153,37 @@ public abstract class NodeComponent {
|
|||
}
|
||||
}
|
||||
|
||||
public void doRollback() throws Exception {
|
||||
Slot slot = this.getSlot();
|
||||
|
||||
CmpStep cmpStep = new CmpStep(nodeId, name, CmpStepTypeEnum.SINGLE);
|
||||
cmpStep.setTag(this.getTag());
|
||||
slot.addRollbackStep(cmpStep);
|
||||
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
|
||||
try {
|
||||
self.rollback();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
stopWatch.stop();
|
||||
final long timeSpent = stopWatch.getTotalTimeMillis();
|
||||
LOG.info("component[{}] rollback in {} milliseconds", this.getDisplayName(), timeSpent);
|
||||
|
||||
// 往CmpStep中放入时间消耗信息
|
||||
cmpStep.setRollbackTimeSpent(timeSpent);
|
||||
// 性能统计
|
||||
if (ObjectUtil.isNotNull(monitorBus)) {
|
||||
CompStatistics statistics = new CompStatistics(this.getClass().getSimpleName(), timeSpent);
|
||||
monitorBus.addStatistics(statistics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void beforeProcess() {
|
||||
// 全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类
|
||||
// 非spring环境下,全局切面为空实现
|
||||
|
@ -148,6 +192,10 @@ public abstract class NodeComponent {
|
|||
|
||||
public abstract void process() throws Exception;
|
||||
|
||||
public void rollback() throws Exception{
|
||||
// 如果需要失败后回滚某个方法,请覆盖这个方法
|
||||
};
|
||||
|
||||
public void onSuccess() throws Exception {
|
||||
// 如果需要在成功后回调某一个方法,请覆盖这个方法
|
||||
// 全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类
|
||||
|
@ -309,6 +357,14 @@ public abstract class NodeComponent {
|
|||
return getSlot().getChainReqDataFromQueue(this.getCurrChainId());
|
||||
}
|
||||
|
||||
public boolean isRollback() {
|
||||
return isRollback;
|
||||
}
|
||||
|
||||
public void setRollback(boolean rollback) {
|
||||
isRollback = rollback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 请使用 {@link #getChainId()}
|
||||
* @return String
|
||||
|
|
|
@ -26,7 +26,9 @@ public enum LiteFlowMethodEnum {
|
|||
|
||||
AFTER_PROCESS("afterProcess", false),
|
||||
|
||||
GET_DISPLAY_NAME("getDisplayName", false)
|
||||
GET_DISPLAY_NAME("getDisplayName", false),
|
||||
|
||||
ROLLBACK("rollback", false)
|
||||
;
|
||||
|
||||
private String methodName;
|
||||
|
|
|
@ -113,6 +113,34 @@ public class LiteflowResponse {
|
|||
return map;
|
||||
}
|
||||
|
||||
public Queue<CmpStep> getRollbackStepQueue() {
|
||||
return this.getSlot().getRollbackSteps();
|
||||
}
|
||||
|
||||
public String getRollbackStepStr() {
|
||||
return getRollbackStepStrWithoutTime();
|
||||
}
|
||||
|
||||
public String getRollbackStepStrWithTime() {
|
||||
return this.getSlot().getRollbackStepStr(true);
|
||||
}
|
||||
|
||||
public String getRollbackStepStrWithoutTime() {
|
||||
return this.getSlot().getRollbackStepStr(false);
|
||||
}
|
||||
|
||||
public Map<String, List<CmpStep>> getRollbackSteps() {
|
||||
Map<String, List<CmpStep>> map = new LinkedHashMap<>();
|
||||
this.getSlot().getRollbackSteps().forEach(cmpStep -> {
|
||||
if (map.containsKey(cmpStep.getNodeId())){
|
||||
map.get(cmpStep.getNodeId()).add(cmpStep);
|
||||
}else{
|
||||
map.put(cmpStep.getNodeId(), ListUtil.toList(cmpStep));
|
||||
}
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
public Queue<CmpStep> getExecuteStepQueue() {
|
||||
return this.getSlot().getExecuteSteps();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import com.yomahub.liteflow.exception.FlowSystemException;
|
|||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public class Node implements Executable, Cloneable{
|
||||
public class Node implements Executable, Cloneable, Rollbackable{
|
||||
|
||||
private static final LFLog LOG = LFLoggerManager.getLogger(Node.class);
|
||||
|
||||
|
@ -174,6 +174,28 @@ public class Node implements Executable, Cloneable{
|
|||
}
|
||||
}
|
||||
|
||||
// 回滚的主要逻辑
|
||||
@Override
|
||||
public void rollback(Integer slotIndex) throws Exception {
|
||||
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
try {
|
||||
// 把线程属性赋值给组件对象
|
||||
instance.setSlotIndex(slotIndex);
|
||||
instance.setRefNode(this);
|
||||
instance.doRollback();
|
||||
}
|
||||
catch (Exception e) {
|
||||
String errorMsg = StrUtil.format("component[{}] rollback error,error:{}", id, e.getMessage());
|
||||
LOG.error(errorMsg);
|
||||
}
|
||||
finally {
|
||||
// 移除threadLocal里的信息
|
||||
instance.removeSlotIndex();
|
||||
instance.removeRefNode();
|
||||
}
|
||||
}
|
||||
|
||||
// 在同步场景并不会单独执行这方法,同步场景会在execute里面去判断isAccess。
|
||||
// 但是在异步场景的any=true情况下,如果isAccess返回了false,那么异步的any有可能会认为这个组件先执行完。就会导致不正常
|
||||
// 增加这个方法是为了在异步的时候,先去过滤掉isAccess为false的异步组件。然后再异步执行。
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.yomahub.liteflow.flow.element;
|
||||
|
||||
|
||||
/**
|
||||
* 回滚接口 目前实现这个接口的只有Node
|
||||
*
|
||||
* @author RainZs
|
||||
*/
|
||||
public interface Rollbackable {
|
||||
|
||||
void rollback(Integer slotIndex) throws Exception;
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ package com.yomahub.liteflow.flow.entity;
|
|||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.enums.CmpStepTypeEnum;
|
||||
|
||||
/**
|
||||
|
@ -37,6 +38,11 @@ public class CmpStep {
|
|||
// 但是success为false,不一定有exception,因为有可能没执行到,或者没执行结束(any)
|
||||
private Exception exception;
|
||||
|
||||
private NodeComponent instance;
|
||||
|
||||
// 回滚消耗的时间
|
||||
private Long rollbackTimeSpent;
|
||||
|
||||
public CmpStep(String nodeId, String nodeName, CmpStepTypeEnum stepType) {
|
||||
this.nodeId = nodeId;
|
||||
this.nodeName = nodeName;
|
||||
|
@ -91,6 +97,22 @@ public class CmpStep {
|
|||
this.exception = exception;
|
||||
}
|
||||
|
||||
public NodeComponent getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setInstance(NodeComponent instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public Long getRollbackTimeSpent() {
|
||||
return rollbackTimeSpent;
|
||||
}
|
||||
|
||||
public void setRollbackTimeSpent(Long rollbackTimeSpent) {
|
||||
this.rollbackTimeSpent = rollbackTimeSpent;
|
||||
}
|
||||
|
||||
public String buildString() {
|
||||
if (stepType.equals(CmpStepTypeEnum.SINGLE)) {
|
||||
if (StrUtil.isBlank(nodeName)) {
|
||||
|
@ -131,6 +153,31 @@ public class CmpStep {
|
|||
}
|
||||
}
|
||||
|
||||
public String buildRollbackStringWithTime() {
|
||||
if (stepType.equals(CmpStepTypeEnum.SINGLE)) {
|
||||
if (StrUtil.isBlank(nodeName)) {
|
||||
if (rollbackTimeSpent != null) {
|
||||
return StrUtil.format("{}<{}>", nodeId, rollbackTimeSpent);
|
||||
}
|
||||
else {
|
||||
return StrUtil.format("{}", nodeId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rollbackTimeSpent != null) {
|
||||
return StrUtil.format("{}[{}]<{}>", nodeId, nodeName, rollbackTimeSpent);
|
||||
}
|
||||
else {
|
||||
return StrUtil.format("{}[{}]", nodeId, nodeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 目前没有其他的类型
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (ObjectUtil.isNull(obj)) {
|
||||
|
|
|
@ -81,6 +81,10 @@ public class Slot {
|
|||
|
||||
private String executeStepsStr;
|
||||
|
||||
private final Deque<CmpStep> rollbackSteps = new ConcurrentLinkedDeque<>();
|
||||
|
||||
private String rollbackStepsStr;
|
||||
|
||||
protected ConcurrentHashMap<String, Object> metaDataMap = new ConcurrentHashMap<>();
|
||||
|
||||
private List<Object> contextBeanList;
|
||||
|
@ -346,6 +350,43 @@ public class Slot {
|
|||
}
|
||||
}
|
||||
|
||||
public void addRollbackStep(CmpStep step) {
|
||||
this.rollbackSteps.add(step);
|
||||
}
|
||||
|
||||
public String getRollbackStepStr(boolean withRollbackTimeSpent) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
CmpStep cmpStep;
|
||||
for (Iterator<CmpStep> it = rollbackSteps.iterator(); it.hasNext();) {
|
||||
cmpStep = it.next();
|
||||
if (withRollbackTimeSpent) {
|
||||
str.append(cmpStep.buildRollbackStringWithTime());
|
||||
}
|
||||
else {
|
||||
str.append(cmpStep.buildString());
|
||||
}
|
||||
if (it.hasNext()) {
|
||||
str.append("==>");
|
||||
}
|
||||
}
|
||||
this.rollbackStepsStr = str.toString();
|
||||
return this.rollbackStepsStr;
|
||||
}
|
||||
|
||||
public String getRollbackStepStr() {
|
||||
return getRollbackStepStr(false);
|
||||
}
|
||||
|
||||
public void printRollbackStep() {
|
||||
if (ObjectUtil.isNull(this.rollbackStepsStr)) {
|
||||
this.rollbackStepsStr = getRollbackStepStr(true);
|
||||
}
|
||||
if (LiteflowConfigGetter.get().getPrintExecutionLog()) {
|
||||
LOG.info("ROLLBACK_CHAIN_NAME[{}]\n{}", this.getChainName(), this.rollbackStepsStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void generateRequestId() {
|
||||
metaDataMap.put(REQUEST_ID, IdGeneratorHolder.getInstance().generate());
|
||||
}
|
||||
|
@ -362,6 +403,10 @@ public class Slot {
|
|||
return executeSteps;
|
||||
}
|
||||
|
||||
public Deque<CmpStep> getRollbackSteps() {
|
||||
return rollbackSteps;
|
||||
}
|
||||
|
||||
public Exception getException() {
|
||||
return (Exception) this.metaDataMap.get(EXCEPTION);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package com.yomahub.liteflow.test.rollback;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
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.junit.jupiter.SpringExtension;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestPropertySource(value = "classpath:/rollback/application.properties")
|
||||
@SpringBootTest(classes = RollbackELDeclMultiSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({ "com.yomahub.liteflow.test.rollback.cmp" })
|
||||
public class RollbackELDeclMultiSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 在流程正常执行结束情况下的测试
|
||||
@Test
|
||||
public void testRollback() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对串行编排与并行编排语法的测试
|
||||
@Test
|
||||
public void testWhenAndThen() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对条件编排语法的测试
|
||||
@Test
|
||||
public void testIf() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>x", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对选择编排语法的测试
|
||||
@Test
|
||||
public void testSwitch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>f", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对FOR循环编排语法的测试
|
||||
@Test
|
||||
public void testFor() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("h==>b==>g", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对WHILE循环编排语法的测试
|
||||
@Test
|
||||
public void testWhile() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>w", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对ITERATOR迭代循环编排语法的测试
|
||||
@Test
|
||||
public void testIterator() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>i", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
@Test
|
||||
// 对捕获异常表达式的测试
|
||||
public void testCatch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@LiteflowComponent
|
||||
public class CmpConfig {
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "a")
|
||||
public void processA(NodeComponent bindCmp) {
|
||||
System.out.println("ACmp executed!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "a")
|
||||
public void rollbackA(NodeComponent bindCmp) throws Exception {
|
||||
System.out.println("ACmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "b")
|
||||
public void processB(NodeComponent bindCmp) {
|
||||
System.out.println("BCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.IS_CONTINUE_ON_ERROR, nodeId = "b")
|
||||
public boolean isContinueOnErrorB(NodeComponent bindCmp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "b")
|
||||
public void rollbackB(NodeComponent bindCmp) throws Exception {
|
||||
System.out.println("BCmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "c")
|
||||
public void processC(NodeComponent bindCmp) {
|
||||
System.out.println("CCmp executed!");
|
||||
}
|
||||
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "d")
|
||||
public void processD(NodeComponent bindCmp) {
|
||||
System.out.println("DCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "d")
|
||||
public void rollbackD(NodeComponent bindCmp) throws Exception {
|
||||
System.out.println("DCmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "e")
|
||||
public void processE(NodeComponent bindCmp) {
|
||||
System.out.println("ECmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "e")
|
||||
public void rollbackE() throws Exception {
|
||||
System.out.println("ECmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_SWITCH, nodeId = "f", nodeType = NodeTypeEnum.SWITCH)
|
||||
public String processF(NodeComponent bindCmp) {
|
||||
System.out.println("FCmp executed!");
|
||||
return "abc";
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "f", nodeType = NodeTypeEnum.SWITCH)
|
||||
public void rollbackF() throws Exception {
|
||||
System.out.println("FCmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_FOR, nodeId = "g", nodeType = NodeTypeEnum.FOR)
|
||||
public int processG(NodeComponent bindCmp) {
|
||||
System.out.println("GCmp executed!");
|
||||
return 3;
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "g", nodeType = NodeTypeEnum.FOR)
|
||||
public void rollbackG() throws Exception {
|
||||
System.out.println("GCmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_BREAK, nodeId = "h", nodeType = NodeTypeEnum.BREAK)
|
||||
public int processH(NodeComponent bindCmp) {
|
||||
System.out.println("HCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "h", nodeType = NodeTypeEnum.BREAK)
|
||||
public void rollbackH() throws Exception {
|
||||
System.out.println("HCmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_ITERATOR, nodeId = "i", nodeType = NodeTypeEnum.ITERATOR)
|
||||
public Iterator<?> processI(NodeComponent bindCmp) {
|
||||
List<String> list = ListUtil.toList("jack", "mary", "tom");
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "i", nodeType = NodeTypeEnum.ITERATOR)
|
||||
public void rollbackI() throws Exception {
|
||||
System.out.println("ICmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_WHILE, nodeId = "w", nodeType = NodeTypeEnum.WHILE)
|
||||
public boolean processW(NodeComponent bindCmp) {
|
||||
System.out.println("WCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "w", nodeType = NodeTypeEnum.WHILE)
|
||||
public void rollbackW() throws Exception {
|
||||
System.out.println("WCmp rollback!");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_IF, nodeId = "x", nodeType = NodeTypeEnum.IF)
|
||||
public boolean processX(NodeComponent bindCmp) {
|
||||
System.out.println("XCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.ROLLBACK, nodeId = "x", nodeType = NodeTypeEnum.IF)
|
||||
public void rollbackX() throws Exception {
|
||||
System.out.println("XCmp rollback!");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=rollback/flow.el.xml
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN( a, b, WHEN(c, d).ignoreError(true), CATCH(e) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN( a, b, WHEN(c, d) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN( IF(x, d, a), CATCH(IF(x, d, a)) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
SWITCH(f).TO(a, b).DEFAULT(d);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
FOR(g).DO(THEN(b, c)).BREAK(h);
|
||||
</chain>
|
||||
|
||||
<chain name="chain6">
|
||||
WHILE(w).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain7">
|
||||
ITERATOR(i).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain8">
|
||||
CATCH( THEN(b, c, d) ).DO(a);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,95 @@
|
|||
package com.yomahub.liteflow.test.rollback;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import com.yomahub.liteflow.test.whenTimeOut.WhenTimeOutELDeclSpringbootTest1;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
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.junit.jupiter.SpringExtension;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestPropertySource(value = "classpath:/rollback/application.properties")
|
||||
@SpringBootTest(classes = RollbackELDeclSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({ "com.yomahub.liteflow.test.rollback.cmp" })
|
||||
public class RollbackELDeclSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 在流程正常执行结束情况下的测试
|
||||
@Test
|
||||
public void testRollback() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对串行编排与并行编排语法的测试
|
||||
@Test
|
||||
public void testWhenAndThen() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对条件编排语法的测试
|
||||
@Test
|
||||
public void testIf() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>x", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对选择编排语法的测试
|
||||
@Test
|
||||
public void testSwitch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>f", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对FOR循环编排语法的测试
|
||||
@Test
|
||||
public void testFor() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("h==>b==>g", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对WHILE循环编排语法的测试
|
||||
@Test
|
||||
public void testWhile() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>w", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对ITERATOR迭代循环编排语法的测试
|
||||
@Test
|
||||
public void testIterator() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>i", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
@Test
|
||||
// 对捕获异常表达式的测试
|
||||
public void testCatch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.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!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ACmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.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!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("BCmp rollback!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinueOnError() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -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.rollback.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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.rollback.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!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("DCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
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("ECmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ECmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("f")
|
||||
public class FCmp extends NodeSwitchComponent {
|
||||
|
||||
@Override
|
||||
public String processSwitch() {
|
||||
System.out.println("FCmp executed!");
|
||||
return "abc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("FCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeForComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("g")
|
||||
public class GCmp extends NodeForComponent {
|
||||
|
||||
@Override
|
||||
public int processFor() throws Exception {
|
||||
System.out.println("GCmp executed!");
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("GCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("h")
|
||||
public class HCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
System.out.println("HCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("HCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component("i")
|
||||
public class ICmp extends NodeIteratorComponent {
|
||||
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = ListUtil.toList("jack", "mary", "tom");
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ICmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeWhileComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("w")
|
||||
public class WCmp extends NodeWhileComponent {
|
||||
|
||||
@Override
|
||||
public boolean processWhile() throws Exception {
|
||||
System.out.println("WCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("WCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("x")
|
||||
public class XCmp extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
System.out.println("XCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("XCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=rollback/flow.el.xml
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN( a, b, WHEN(c, d).ignoreError(true), CATCH(e) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN( a, b, WHEN(c, d) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN( IF(x, d, a), CATCH(IF(x, d, a)) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
SWITCH(f).TO(a, b).DEFAULT(d);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
FOR(g).DO(THEN(b, c)).BREAK(h);;
|
||||
</chain>
|
||||
|
||||
<chain name="chain6">
|
||||
WHILE(w).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain7">
|
||||
ITERATOR(i).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain8">
|
||||
CATCH( THEN(b, c, d) ).DO(a);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,92 @@
|
|||
package com.yomahub.liteflow.test.rollback;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.core.FlowExecutorHolder;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.property.LiteflowConfig;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
|
||||
public class RollbackTest extends BaseTest {
|
||||
|
||||
private static FlowExecutor flowExecutor;
|
||||
|
||||
@BeforeAll
|
||||
public static void init() {
|
||||
LiteflowConfig config = new LiteflowConfig();
|
||||
config.setRuleSource("rollback/flow.el.xml");
|
||||
flowExecutor = FlowExecutorHolder.loadInstance(config);
|
||||
}
|
||||
|
||||
// 在流程正常执行结束情况下的测试
|
||||
@Test
|
||||
public void testRollback() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对串行编排与并行编排语法的测试
|
||||
@Test
|
||||
public void testWhenAndThen() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对条件编排语法的测试
|
||||
@Test
|
||||
public void testIf() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>x", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对选择编排语法的测试
|
||||
@Test
|
||||
public void testSwitch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>f", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对FOR循环编排语法的测试
|
||||
@Test
|
||||
public void testFor() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("h==>b==>g", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对WHILE循环编排语法的测试
|
||||
@Test
|
||||
public void testWhile() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>w", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对ITERATOR迭代循环编排语法的测试
|
||||
@Test
|
||||
public void testIterator() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>i", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
@Test
|
||||
// 对捕获异常表达式的测试
|
||||
public void testCatch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
public class ACmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("ACmp executed!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ACmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
public class BCmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("BCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("BCmp rollback!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinueOnError() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
public class CCmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("CCmp executed!");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
public class DCmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("DCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("DCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
|
||||
public class ECmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("ECmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ECmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
|
||||
public class FCmp extends NodeSwitchComponent {
|
||||
|
||||
@Override
|
||||
public String processSwitch() {
|
||||
System.out.println("FCmp executed!");
|
||||
return "abc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("FCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeForComponent;
|
||||
|
||||
public class GCmp extends NodeForComponent {
|
||||
|
||||
@Override
|
||||
public int processFor() throws Exception {
|
||||
System.out.println("GCmp executed!");
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("GCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
|
||||
public class HCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
System.out.println("HCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("HCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class ICmp extends NodeIteratorComponent {
|
||||
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = ListUtil.toList("jack", "mary", "tom");
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ICmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeWhileComponent;
|
||||
|
||||
public class WCmp extends NodeWhileComponent {
|
||||
|
||||
@Override
|
||||
public boolean processWhile() throws Exception {
|
||||
System.out.println("WCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("WCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
|
||||
public class XCmp extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
System.out.println("XCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("XCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="a" class="com.yomahub.liteflow.test.rollback.cmp.ACmp"/>
|
||||
<node id="b" class="com.yomahub.liteflow.test.rollback.cmp.BCmp"/>
|
||||
<node id="c" class="com.yomahub.liteflow.test.rollback.cmp.CCmp"/>
|
||||
<node id="d" class="com.yomahub.liteflow.test.rollback.cmp.DCmp"/>
|
||||
<node id="e" class="com.yomahub.liteflow.test.rollback.cmp.ECmp"/>
|
||||
<node id="f" class="com.yomahub.liteflow.test.rollback.cmp.FCmp"/>
|
||||
<node id="g" class="com.yomahub.liteflow.test.rollback.cmp.GCmp"/>
|
||||
<node id="h" class="com.yomahub.liteflow.test.rollback.cmp.HCmp"/>
|
||||
<node id="i" class="com.yomahub.liteflow.test.rollback.cmp.ICmp"/>
|
||||
<node id="w" class="com.yomahub.liteflow.test.rollback.cmp.WCmp"/>
|
||||
<node id="x" class="com.yomahub.liteflow.test.rollback.cmp.XCmp"/>
|
||||
</nodes>
|
||||
<chain name="chain1">
|
||||
THEN( a, b, WHEN(c, d).ignoreError(true), CATCH(e) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN( a, b, WHEN(c, d) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN( IF(x, d, a), CATCH(IF(x, d, a)) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
SWITCH(f).TO(a, b).DEFAULT(d);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
FOR(g).DO(THEN(b, c)).BREAK(h);;
|
||||
</chain>
|
||||
|
||||
<chain name="chain6">
|
||||
WHILE(w).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain7">
|
||||
ITERATOR(i).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain8">
|
||||
CATCH( THEN(b, c, d) ).DO(a);
|
||||
</chain>
|
||||
</flow>
|
|
@ -13,7 +13,7 @@ import org.noear.solon.annotation.Inject;
|
|||
import org.noear.solon.test.SolonJUnit5Extension;
|
||||
import org.noear.solon.test.annotation.TestPropertySource;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
//import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package com.yomahub.liteflow.test.rollback;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.test.SolonJUnit5Extension;
|
||||
import org.noear.solon.test.annotation.TestPropertySource;
|
||||
|
||||
|
||||
@ExtendWith(SolonJUnit5Extension.class)
|
||||
@TestPropertySource("classpath:/rollback/application.properties")
|
||||
public class RollbackSpringbootTest extends BaseTest {
|
||||
|
||||
@Inject
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 在流程正常执行结束情况下的测试
|
||||
@Test
|
||||
public void testRollback() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对串行编排与并行编排语法的测试
|
||||
@Test
|
||||
public void testWhenAndThen() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对条件编排语法的测试
|
||||
@Test
|
||||
public void testIf() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>x", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对选择编排语法的测试
|
||||
@Test
|
||||
public void testSwitch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>f", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对FOR循环编排语法的测试
|
||||
@Test
|
||||
public void testFor() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("h==>b==>g", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对WHILE循环编排语法的测试
|
||||
@Test
|
||||
public void testWhile() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>w", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对ITERATOR迭代循环编排语法的测试
|
||||
@Test
|
||||
public void testIterator() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>i", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
@Test
|
||||
// 对捕获异常表达式的测试
|
||||
public void testCatch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
|
||||
@Component("a")
|
||||
public class ACmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("ACmp executed!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ACmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
|
||||
@Component("b")
|
||||
public class BCmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("BCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("BCmp rollback!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinueOnError() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
|
||||
@Component("c")
|
||||
public class CCmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("CCmp executed!");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
|
||||
@Component("d")
|
||||
public class DCmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("DCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("DCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
|
||||
@Component("e")
|
||||
public class ECmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("ECmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ECmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
@Component("f")
|
||||
public class FCmp extends NodeSwitchComponent {
|
||||
|
||||
@Override
|
||||
public String processSwitch() {
|
||||
System.out.println("FCmp executed!");
|
||||
return "abc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("FCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeForComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
@Component("g")
|
||||
public class GCmp extends NodeForComponent {
|
||||
|
||||
@Override
|
||||
public int processFor() throws Exception {
|
||||
System.out.println("GCmp executed!");
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("GCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
@Component("h")
|
||||
public class HCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
System.out.println("HCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("HCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component("i")
|
||||
public class ICmp extends NodeIteratorComponent {
|
||||
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = ListUtil.toList("jack", "mary", "tom");
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ICmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeWhileComponent;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
@Component("w")
|
||||
public class WCmp extends NodeWhileComponent {
|
||||
|
||||
@Override
|
||||
public boolean processWhile() throws Exception {
|
||||
System.out.println("WCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("WCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.noear.solon.annotation.Component;;
|
||||
|
||||
@Component("x")
|
||||
public class XCmp extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
System.out.println("XCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("XCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=rollback/flow.el.xml
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN( a, b, WHEN(c, d).ignoreError(true), CATCH(e) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN( a, b, WHEN(c, d) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN( IF(x, d, a), CATCH(IF(x, d, a)) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
SWITCH(f).TO(a, b).DEFAULT(d);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
FOR(g).DO(THEN(b, c)).BREAK(h);;
|
||||
</chain>
|
||||
|
||||
<chain name="chain6">
|
||||
WHILE(w).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain7">
|
||||
ITERATOR(i).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain8">
|
||||
CATCH( THEN(b, c, d) ).DO(a);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,90 @@
|
|||
package com.yomahub.liteflow.test.rollback;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
@TestPropertySource(value = "classpath:/rollback/application.properties")
|
||||
@SpringBootTest(classes = RollbackSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({ "com.yomahub.liteflow.test.rollback.cmp" })
|
||||
public class RollbackSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 在流程正常执行结束情况下的测试
|
||||
@Test
|
||||
public void testRollback() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对串行编排与并行编排语法的测试
|
||||
@Test
|
||||
public void testWhenAndThen() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对条件编排语法的测试
|
||||
@Test
|
||||
public void testIf() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>x", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对选择编排语法的测试
|
||||
@Test
|
||||
public void testSwitch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>f", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对FOR循环编排语法的测试
|
||||
@Test
|
||||
public void testFor() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("h==>b==>g", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对WHILE循环编排语法的测试
|
||||
@Test
|
||||
public void testWhile() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>w", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对ITERATOR迭代循环编排语法的测试
|
||||
@Test
|
||||
public void testIterator() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>i", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
@Test
|
||||
// 对捕获异常表达式的测试
|
||||
public void testCatch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.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!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ACmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.flow.element.Rollbackable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("b")
|
||||
public class BCmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
System.out.println("BCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("BCmp rollback!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinueOnError() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -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.rollback.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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.rollback.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!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("DCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
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("ECmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ECmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("f")
|
||||
public class FCmp extends NodeSwitchComponent {
|
||||
|
||||
@Override
|
||||
public String processSwitch() {
|
||||
System.out.println("FCmp executed!");
|
||||
return "abc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("FCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeForComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("g")
|
||||
public class GCmp extends NodeForComponent {
|
||||
|
||||
@Override
|
||||
public int processFor() throws Exception {
|
||||
System.out.println("GCmp executed!");
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("GCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("h")
|
||||
public class HCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
System.out.println("HCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("HCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component("i")
|
||||
public class ICmp extends NodeIteratorComponent {
|
||||
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = ListUtil.toList("jack", "mary", "tom");
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ICmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeWhileComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("w")
|
||||
public class WCmp extends NodeWhileComponent {
|
||||
|
||||
@Override
|
||||
public boolean processWhile() throws Exception {
|
||||
System.out.println("WCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("WCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("x")
|
||||
public class XCmp extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
System.out.println("XCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("XCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=rollback/flow.el.xml
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN( a, b, WHEN(c, d).ignoreError(true), CATCH(e) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN( a, b, WHEN(c, d) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN( IF(x, d, a), CATCH(IF(x, d, a)) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
SWITCH(f).TO(a, b).DEFAULT(d);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
FOR(g).DO(THEN(b, c)).BREAK(h);;
|
||||
</chain>
|
||||
|
||||
<chain name="chain6">
|
||||
WHILE(w).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain7">
|
||||
ITERATOR(i).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain8">
|
||||
CATCH( THEN(b, c, d) ).DO(a);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,89 @@
|
|||
package com.yomahub.liteflow.test.rollback;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration("classpath:/rollback/application.xml")
|
||||
public class RollbackSpringTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 在流程正常执行结束情况下的测试
|
||||
@Test
|
||||
public void testRollback() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对串行编排与并行编排语法的测试
|
||||
@Test
|
||||
public void testWhenAndThen() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对条件编排语法的测试
|
||||
@Test
|
||||
public void testIf() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>x", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对选择编排语法的测试
|
||||
@Test
|
||||
public void testSwitch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>f", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对FOR循环编排语法的测试
|
||||
@Test
|
||||
public void testFor() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("h==>b==>g", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对WHILE循环编排语法的测试
|
||||
@Test
|
||||
public void testWhile() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>w", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
// 对ITERATOR迭代循环编排语法的测试
|
||||
@Test
|
||||
public void testIterator() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg");
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals("d==>b==>a==>i", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
@Test
|
||||
// 对捕获异常表达式的测试
|
||||
public void testCatch() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Assertions.assertNull(response.getCause());
|
||||
Assertions.assertEquals("", response.getRollbackStepStr());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.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!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ACmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.rollback.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!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("BCmp rollback!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinueOnError() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -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.rollback.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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.rollback.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!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("DCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -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.rollback.cmp;
|
||||
|
||||
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("ECmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ECmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("f")
|
||||
public class FCmp extends NodeSwitchComponent {
|
||||
|
||||
@Override
|
||||
public String processSwitch() {
|
||||
System.out.println("FCmp executed!");
|
||||
return "abc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("FCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeForComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("g")
|
||||
public class GCmp extends NodeForComponent {
|
||||
|
||||
@Override
|
||||
public int processFor() throws Exception {
|
||||
System.out.println("GCmp executed!");
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("GCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("h")
|
||||
public class HCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
System.out.println("HCmp executed!");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("HCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component("i")
|
||||
public class ICmp extends NodeIteratorComponent {
|
||||
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = ListUtil.toList("jack", "mary", "tom");
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("ICmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeWhileComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("w")
|
||||
public class WCmp extends NodeWhileComponent {
|
||||
|
||||
@Override
|
||||
public boolean processWhile() throws Exception {
|
||||
System.out.println("WCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("WCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.yomahub.liteflow.test.rollback.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("x")
|
||||
public class XCmp extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
System.out.println("XCmp executed!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws Exception {
|
||||
System.out.println("XCmp rollback!");
|
||||
}
|
||||
}
|
|
@ -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.rollback.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="rollback/flow.el.xml"/>
|
||||
</bean>
|
||||
|
||||
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
|
||||
<constructor-arg name="liteflowConfig" ref="liteflowConfig"/>
|
||||
</bean>
|
||||
</beans>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN( a, b, WHEN(c, d).ignoreError(true), CATCH(e) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN( a, b, WHEN(c, d) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN( IF(x, d, a), CATCH(IF(x, d, a)) );
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
SWITCH(f).TO(a, b).DEFAULT(d);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
FOR(g).DO(THEN(b, c)).BREAK(h);;
|
||||
</chain>
|
||||
|
||||
<chain name="chain6">
|
||||
WHILE(w).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain7">
|
||||
ITERATOR(i).DO(THEN(a, b, d));
|
||||
</chain>
|
||||
|
||||
<chain name="chain8">
|
||||
CATCH( THEN(b, c, d) ).DO(a);
|
||||
</chain>
|
||||
</flow>
|
Loading…
Reference in New Issue