diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java index 02140db44..6cc841574 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java @@ -30,6 +30,7 @@ import com.yomahub.liteflow.util.JsonUtil; import java.lang.reflect.Method; import java.util.Date; +import java.util.Stack; /** * 普通组件抽象类 @@ -67,13 +68,7 @@ public abstract class NodeComponent{ /** 当前对象为单例,注册进spring上下文,但是node实例不是单例,这里通过对node实例的引用来获得一些链路属性 **/ - private final TransmittableThreadLocal refNodeTL = new TransmittableThreadLocal<>(); - - /** - ******************* 以下的属性为线程附加属性******************** - * 线程属性是指每一个request的值都是不一样的 - * 这里NodeComponent是单例,所以要用ThreadLocal来修饰 - */ + private final ThreadLocal> refNodeStackTL = new ThreadLocal<>(); public NodeComponent() { // 反射判断是否重写了rollback方法 @@ -225,7 +220,7 @@ public abstract class NodeComponent{ // 是否结束整个流程(不往下继续执行) public boolean isEnd() { - Boolean isEnd = this.refNodeTL.get().getIsEnd(); + Boolean isEnd = this.getRefNode().getIsEnd(); if (ObjectUtil.isNull(isEnd)) { return false; }else { @@ -235,15 +230,15 @@ public abstract class NodeComponent{ // 设置是否结束整个流程 public void setIsEnd(boolean isEnd) { - this.refNodeTL.get().setIsEnd(isEnd); + this.getRefNode().setIsEnd(isEnd); } public void setIsContinueOnError(boolean isContinueOnError) { - this.refNodeTL.get().setIsContinueOnErrorResult(isContinueOnError); + this.getRefNode().setIsContinueOnErrorResult(isContinueOnError); } public Integer getSlotIndex() { - return this.refNodeTL.get().getSlotIndex(); + return this.getRefNode().getSlotIndex(); } public Slot getSlot() { @@ -327,7 +322,7 @@ public abstract class NodeComponent{ } public String getTag() { - return this.refNodeTL.get().getTag(); + return this.getRefNode().getTag(); } public MonitorBus getMonitorBus() { @@ -385,15 +380,28 @@ public abstract class NodeComponent{ } public Node getRefNode() { - return this.refNodeTL.get(); + return this.refNodeStackTL.get().peek(); } public void setRefNode(Node refNode) { - this.refNodeTL.set(refNode); + if (this.refNodeStackTL.get() == null){ + Stack stack = new Stack<>(); + stack.push(refNode); + this.refNodeStackTL.set(stack); + }else{ + Node compareNode = this.refNodeStackTL.get().peek(); + if (!compareNode.equals(refNode)) { + this.refNodeStackTL.get().push(refNode); + } + } } public void removeRefNode() { - this.refNodeTL.remove(); + if (this.refNodeStackTL.get().size() > 1) { + this.refNodeStackTL.get().pop(); + }else{ + this.refNodeStackTL.remove(); + } } public T getCmpData(Class clazz) { @@ -408,11 +416,11 @@ public abstract class NodeComponent{ } public Integer getLoopIndex() { - return this.refNodeTL.get().getLoopIndex(); + return this.getRefNode().getLoopIndex(); } public T getCurrLoopObj() { - return this.refNodeTL.get().getCurrLoopObject(); + return this.getRefNode().getCurrLoopObject(); } @Deprecated diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/NestedImplicitSubFlowTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/NestedImplicitSubFlowTest.java new file mode 100644 index 000000000..588ce3bd9 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/NestedImplicitSubFlowTest.java @@ -0,0 +1,29 @@ +package com.yomahub.liteflow.test.subflow; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +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:/subflow/nestedImplicitSubFlow.properties") +@SpringBootTest(classes = SubflowXMLELSpringBootTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.subflow.cmp1","com.yomahub.liteflow.test.subflow.cmp3" }) +public class NestedImplicitSubFlowTest { + + @Resource + private FlowExecutor flowExecutor; + + @Test + public void testNested(){ + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "it's a request"); + Assertions.assertTrue(response.isSuccess()); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/cmp3/VCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/cmp3/VCmp.java new file mode 100644 index 000000000..063589396 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/cmp3/VCmp.java @@ -0,0 +1,20 @@ +package com.yomahub.liteflow.test.subflow.cmp3; + +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.flow.LiteflowResponse; +import org.springframework.stereotype.Component; + +@Component("v") +public class VCmp extends NodeComponent { + + @Override + public void process() { + String data = this.getTag(); + LiteflowResponse resp = this.invoke2Resp(data, null); + + if (!resp.isSuccess()){ + throw new RuntimeException("implicit sub flow exception"); + } + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/subflow/nestedImplicitSubFlow.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/subflow/nestedImplicitSubFlow.properties new file mode 100644 index 000000000..99a94d876 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/subflow/nestedImplicitSubFlow.properties @@ -0,0 +1 @@ +liteflow.rule-source=subflow/nestedImplicitSubFlow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/subflow/nestedImplicitSubFlow.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/subflow/nestedImplicitSubFlow.xml new file mode 100644 index 000000000..6b3181263 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/subflow/nestedImplicitSubFlow.xml @@ -0,0 +1,14 @@ + + + + THEN(v.tag("subChain1")); + + + + THEN(v.tag("subChain2")); + + + + THEN(a, b); + + \ No newline at end of file