浏览代码

Merge branch 'master' of https://gitee.com/dromara/liteFlow into optimized/refactoring-parser-init

 Conflicts:
	liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java
119431682@qq.com 2 年之前
父节点
当前提交
9ee43b0441
共有 100 个文件被更改,包括 2177 次插入123 次删除
  1. 1 1
      README.md
  2. 1 1
      README.zh-CN.md
  3. 1 1
      liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java
  4. 1 1
      liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ToOperator.java
  5. 9 1
      liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java
  6. 22 2
      liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java
  7. 1 1
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java
  8. 3 6
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java
  9. 5 1
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Executable.java
  10. 9 2
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java
  11. 13 0
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/Condition.java
  12. 1 0
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/FinallyCondition.java
  13. 1 0
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/PreCondition.java
  14. 2 0
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java
  15. 1 0
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ThenCondition.java
  16. 3 3
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java
  17. 10 0
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/entity/CmpStep.java
  18. 1 2
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/executor/NodeExecutorHelper.java
  19. 0 59
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/id/IdGeneratorHelper.java
  20. 54 0
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/id/IdGeneratorHolder.java
  21. 5 1
      liteflow-core/src/main/java/com/yomahub/liteflow/flow/parallel/ParallelSupplier.java
  22. 34 1
      liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java
  23. 21 27
      liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java
  24. 1 1
      liteflow-core/src/main/java/com/yomahub/liteflow/spi/local/LocalPathContentParser.java
  25. 1 1
      liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorHelper.java
  26. 1 1
      liteflow-core/src/main/java/com/yomahub/liteflow/util/LOGOPrinter.java
  27. 1 1
      liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowProxyUtil.java
  28. 0 2
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java
  29. 7 5
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ICmp.java
  30. 23 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/cmpStep/CmpStepELDeclSpringbootTest.java
  31. 35 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/LiteflowNodeELSpringbootTest.java
  32. 24 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/cmp/ACmp.java
  33. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/cmp/BCmp.java
  34. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/cmp/CCmp.java
  35. 4 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/package-info.java
  36. 60 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/GetChainNameELDeclSpringbootTest.java
  37. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/ACmp.java
  38. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/BCmp.java
  39. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/CCmp.java
  40. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/DCmp.java
  41. 30 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/ECmp.java
  42. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/FCmp.java
  43. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/GCmp.java
  44. 29 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/HCmp.java
  45. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/JCmp.java
  46. 26 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/KCmp.java
  47. 14 1
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/ImplicitSubFlowELDeclSpringbootTest.java
  48. 35 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/cmp2/PCmp.java
  49. 33 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/cmp2/QCmp.java
  50. 5 1
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/cmpStep/flow.el.xml
  51. 1 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/comments/application.properties
  52. 18 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/comments/flow.el.xml
  53. 1 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/getChainName/application.properties
  54. 38 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/getChainName/flow.el.xml
  55. 8 0
      liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/subflow/flow-implicit.el.xml
  56. 65 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/pom.xml
  57. 20 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/BaseTest.java
  58. 33 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/AbsoluteConfigPathTest.java
  59. 18 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/cmp/ACmp.java
  60. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/cmp/BCmp.java
  61. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/cmp/CCmp.java
  62. 136 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/AsyncNodeTest.java
  63. 22 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ACmp.java
  64. 22 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/BCmp.java
  65. 22 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/CCmp.java
  66. 23 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/DCmp.java
  67. 13 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ECmp.java
  68. 12 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/FCmp.java
  69. 24 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/GCmp.java
  70. 24 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/HCmp.java
  71. 24 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ICmp.java
  72. 13 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/JCmp.java
  73. 4 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/exception/TestException.java
  74. 28 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/BaseCommonTest.java
  75. 18 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/ACmp.java
  76. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/BCmp.java
  77. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/CCmp.java
  78. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/DCmp.java
  79. 18 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/ECmp.java
  80. 210 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/BuilderTest.java
  81. 18 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/ACmp.java
  82. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/BCmp.java
  83. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/CCmp.java
  84. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/DCmp.java
  85. 20 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/ECmp.java
  86. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/FCmp.java
  87. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/GCmp.java
  88. 61 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/LiteflowRetryTest.java
  89. 18 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/ACmp.java
  90. 25 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/BCmp.java
  91. 22 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/CCmp.java
  92. 22 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/DCmp.java
  93. 22 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/ECmp.java
  94. 66 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/CmpStepTest.java
  95. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/ACmp.java
  96. 19 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/BCmp.java
  97. 21 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/CCmp.java
  98. 20 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/DCmp.java
  99. 23 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/ECmp.java
  100. 34 0
      liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/comments/LiteflowNodeTest.java

+ 1 - 1
README.md

@@ -21,7 +21,7 @@ You can find out how to join the community on the official website!
 ## Documents url: [Click here to enter the documentation to learn](https://liteflow.yomahub.com/pages/5816c5/)
 ## Demo projects: [DEMO1](https://github.com/bryan31/message-demo) | [DEMO2](https://gitee.com/bryan31/liteflow-example)
 
-** LiteFlow has more than 650 test cases in the source code, including most scenarios, you can see the test cases in the source code.**
+LiteFlow has more than 860 test cases in the source code, including most scenarios, you can see the test cases in the source code.
 
 ## Feature
 * **Component definition unified:** All logic is a component, for all logic to provide a unified component implementation, small size, large energy.

+ 1 - 1
README.zh-CN.md

@@ -19,7 +19,7 @@ LiteFlow是一个由社区驱动的项目,我们非常重视社区建设,拥
 ## 文档链接:[点这里进入文档进行学习](https://liteflow.yomahub.com/pages/5816c5/)
 ## 示例工程:[DEMO1](https://github.com/bryan31/message-demo) | [DEMO2](https://gitee.com/bryan31/liteflow-example)
 
-**同时LiteFlow的源码中拥有超过650个测试用例,包含了大部分的场景,在源码中可以看到测试用例**
+**同时LiteFlow的源码中拥有超过860个测试用例,包含了大部分的场景,在源码中可以看到测试用例**
 
 ## 特性
 * **组件定义统一:** 所有的逻辑都是组件,为所有的逻辑提供统一化的组件实现方式,小身材,大能量。

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java

@@ -28,7 +28,7 @@ public class LiteFlowNodeBuilder {
         return new LiteFlowNodeBuilder(NodeTypeEnum.COMMON);
     }
 
-    public static LiteFlowNodeBuilder createCommonCondNode() {
+    public static LiteFlowNodeBuilder createSwitchNode() {
         return new LiteFlowNodeBuilder(NodeTypeEnum.SWITCH);
     }
 

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ToOperator.java

@@ -24,7 +24,7 @@ public class ToOperator extends Operator {
                 throw new Exception();
             }
 
-            if (objects.length <= 2){
+            if (objects.length <= 1){
                 LOG.error("parameter error");
                 throw new Exception();
             }

+ 9 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java

@@ -18,6 +18,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.id.IdGeneratorHolder;
+import com.yomahub.liteflow.parser.*;
 import com.yomahub.liteflow.parser.base.FlowParser;
 import com.yomahub.liteflow.parser.factory.FlowParserProvider;
 import com.yomahub.liteflow.property.LiteflowConfig;
@@ -82,6 +84,9 @@ public class FlowExecutor {
         //在非spring体系下是一个空实现,等于不做此步骤
         ContextCmpInitHolder.loadContextCmpInit().initCmp();
 
+        //进行id生成器的初始化
+        IdGeneratorHolder.init();
+
         //如果没有配置规则文件路径,就停止初始化。
         //规则文件路径不是一定要有,因为liteflow分基于规则和基于代码两种,有可能是动态代码构建的
         if (StrUtil.isBlank(liteflowConfig.getRuleSource())) {
@@ -133,10 +138,11 @@ public class FlowExecutor {
                     throw new ConfigErrorException("parse error, please check liteflow config property");
                 }
             } catch (CyclicDependencyException e) {
+                LOG.error(e.getMessage(), e);
                 LOG.error(e.getMessage());
                 throw e;
             } catch (ChainDuplicateException e) {
-                LOG.error(e.getMessage());
+                LOG.error(e.getMessage(), e);
                 throw e;
             } catch (Exception e) {
                 String errorMsg = StrUtil.format("init flow executor cause error for path {},reason: {}", rulePathList, e.getMessage());
@@ -276,6 +282,8 @@ public class FlowExecutor {
             if (ObjectUtil.isNotNull(chain)) {
                 String errMsg = StrUtil.format("[{}]:chain[{}] execute error on slot[{}]", slot.getRequestId(), chain.getChainName(), slotIndex);
                 LOG.error(errMsg, e);
+            }else{
+                LOG.error(e.getMessage(), e);
             }
             slot.setException(e);
         } finally {

+ 22 - 2
liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java

@@ -68,6 +68,9 @@ public abstract class NodeComponent{
 	//tag标签
 	private final TransmittableThreadLocal<String> tagTL = new TransmittableThreadLocal<>();
 
+	//当前流程名字
+	private final TransmittableThreadLocal<String> currChainNameTL = new TransmittableThreadLocal<>();
+
 	public NodeComponent() {
 	}
 
@@ -76,6 +79,7 @@ public abstract class NodeComponent{
 
 		//在元数据里加入step信息
 		CmpStep cmpStep = new CmpStep(nodeId, name, CmpStepTypeEnum.SINGLE);
+		cmpStep.setTag(tagTL.get());
 		slot.addStep(cmpStep);
 
 		StopWatch stopWatch = new StopWatch();
@@ -105,7 +109,7 @@ public abstract class NodeComponent{
 				self.onError();
 			}catch (Exception ex){
 				String errMsg = StrUtil.format("[{}]:component[{}] onError method happens exception",slot.getRequestId(),this.getDisplayName());
-				LOG.error(errMsg, ex);
+				LOG.error(errMsg);
 			}
 			throw e;
 		} finally {
@@ -273,6 +277,10 @@ public abstract class NodeComponent{
 		return this.tagTL.get();
 	}
 
+	public void removeTag(){
+		this.tagTL.remove();
+	}
+
 	public MonitorBus getMonitorBus() {
 		return monitorBus;
 	}
@@ -286,7 +294,7 @@ public abstract class NodeComponent{
 	}
 
 	public <T> T getSubChainReqData(){
-		return getSlot().getChainReqData(this.getChainName());
+		return getSlot().getChainReqData(this.getCurrChainName());
 	}
 
 	public String getChainName(){
@@ -301,6 +309,18 @@ public abstract class NodeComponent{
 		}
 	}
 
+	public void setCurrChainName(String currChainName){
+		this.currChainNameTL.set(currChainName);
+	}
+
+	public String getCurrChainName(){
+		return this.currChainNameTL.get();
+	}
+
+	public void removeCurrChainName(){
+		this.currChainNameTL.remove();
+	}
+
 	public void invoke(String chainId, Object param) throws Exception {
 		FlowExecutorHolder.loadInstance().invoke(chainId, param, this.getSlotIndex());
 	}

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java

@@ -183,7 +183,7 @@ public class FlowBus {
             nodeMap.put(nodeId, node);
         } catch (Exception e) {
             String error = StrUtil.format("component[{}] register error", StrUtil.isEmpty(name)?nodeId:StrUtil.format("{}({})",nodeId,name));
-            LOG.error(error, e);
+            LOG.error(error);
             throw new ComponentCannotRegisterException(error);
         }
     }

+ 3 - 6
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java

@@ -74,13 +74,13 @@ public class Chain implements Executable {
         }
         Slot slot = DataBus.getSlot(slotIndex);
         try {
-            //在子流程或者隐式流程里,slot需要取到的chainName是当前流程,所以这不再是set,而是push
-            //其底层结构是一个stack
-            slot.pushChainName(chainName);
+            //设置主ChainName
+            slot.setChainName(chainName);
             //执行前置
             this.executePre(slotIndex);
             //执行主体Condition
             for (Condition condition : conditionList) {
+                condition.setCurrChainName(chainName);
                 condition.execute(slotIndex);
             }
         }catch (ChainEndException e){
@@ -94,9 +94,6 @@ public class Chain implements Executable {
         }finally {
             //执行后置
             this.executeFinally(slotIndex);
-            //流程结束后,需要把当前的chainName从stack结构中移出
-            //里面的逻辑判断了当只剩根chainName的时候,不移除
-            slot.popChainName();
         }
     }
 

+ 5 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Executable.java

@@ -4,7 +4,7 @@ import com.yomahub.liteflow.enums.ExecuteTypeEnum;
 
 /**
  * 可执行器接口
- * 目前实现这个接口的有2个,node和chain
+ * 目前实现这个接口的有3个,Chain,Condition,Node
  *
  * @author Bryan.Zhang
  */
@@ -19,4 +19,8 @@ public interface Executable{
     ExecuteTypeEnum getExecuteType();
 
     String getExecuteName();
+
+    default void setCurrChainName(String currentChainName){
+
+    }
 }

+ 9 - 2
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java

@@ -135,16 +135,18 @@ public class Node implements Executable,Cloneable{
 			//如果组件覆盖了isContinueOnError方法,返回为true,那即便出了异常,也会继续流程
 			if (instance.isContinueOnError()) {
 				String errorMsg = MessageFormat.format("[{0}]:component[{1}] cause error,but flow is still go on", slot.getRequestId(),id);
-				LOG.error(errorMsg,e);
+				LOG.error(errorMsg);
 			} else {
 				String errorMsg = MessageFormat.format("[{0}]:component[{1}] cause error,error:{2}",slot.getRequestId(),id,e.getMessage());
-				LOG.error(errorMsg,e);
+				LOG.error(errorMsg);
 				throw e;
 			}
 		} finally {
 			//移除threadLocal里的信息
 			instance.removeSlotIndex();
 			instance.removeIsEnd();
+			instance.removeTag();
+			instance.removeCurrChainName();
 		}
 	}
 
@@ -200,4 +202,9 @@ public class Node implements Executable,Cloneable{
 	public void setClazz(String clazz) {
 		this.clazz = clazz;
 	}
+
+	@Override
+	public void setCurrChainName(String currentChainName) {
+		instance.setCurrChainName(currentChainName);
+	}
 }

+ 13 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/Condition.java

@@ -38,6 +38,10 @@ public abstract class Condition implements Executable{
 	// when单独的线程池名称
 	private String threadExecutorClass;
 
+	//当前所在的ChainName
+	//如果对于子流程来说,那这个就是子流程所在的Chain
+	private String currChainName;
+
 	@Override
 	public ExecuteTypeEnum getExecuteType() {
 		return ExecuteTypeEnum.CONDITION;
@@ -101,4 +105,13 @@ public abstract class Condition implements Executable{
 	public void setId(String id) {
 		this.id = id;
 	}
+
+	public String getCurrChainName() {
+		return currChainName;
+	}
+
+	@Override
+	public void setCurrChainName(String currChainName) {
+		this.currChainName = currChainName;
+	}
 }

+ 1 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/FinallyCondition.java

@@ -20,6 +20,7 @@ public class FinallyCondition extends Condition {
 	@Override
 	public void execute(Integer slotIndex) throws Exception {
 		for(Executable executableItem : this.getExecutableList()){
+			executableItem.setCurrChainName(this.getCurrChainName());
 			executableItem.execute(slotIndex);
 		}
 	}

+ 1 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/PreCondition.java

@@ -20,6 +20,7 @@ public class PreCondition extends Condition {
 	@Override
 	public void execute(Integer slotIndex) throws Exception {
 		for(Executable executableItem : this.getExecutableList()){
+			executableItem.setCurrChainName(this.getCurrChainName());
 			executableItem.execute(slotIndex);
 		}
 	}

+ 2 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java

@@ -29,6 +29,7 @@ public class SwitchCondition extends Condition{
     public void execute(Integer slotIndex) throws Exception {
         if (ListUtil.toList(NodeTypeEnum.SWITCH, NodeTypeEnum.SWITCH_SCRIPT).contains(this.getSwitchNode().getType())){
             //先执行switch节点
+            this.getSwitchNode().setCurrChainName(this.getCurrChainName());
             this.getSwitchNode().execute(slotIndex);
 
             //根据switch节点执行出来的结果选择
@@ -42,6 +43,7 @@ public class SwitchCondition extends Condition{
                         String errorInfo = StrUtil.format("[{}]:switch component[{}] error, switch target node cannot be pre or finally", slot.getRequestId(), this.getSwitchNode().getInstance().getDisplayName());
                         throw new SwitchTargetCannotBePreOrFinallyException(errorInfo);
                     }
+                    targetExecutor.setCurrChainName(this.getCurrChainName());
                     targetExecutor.execute(slotIndex);
                 }else{
                     String errorInfo = StrUtil.format("[{}]:no target node find for the component[{}]", slot.getRequestId(), this.getSwitchNode().getInstance().getDisplayName());

+ 1 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ThenCondition.java

@@ -27,6 +27,7 @@ public class ThenCondition extends Condition {
 			if (executableItem instanceof PreCondition || executableItem instanceof FinallyCondition){
 				continue;
 			}
+			executableItem.setCurrChainName(this.getCurrChainName());
 			executableItem.execute(slotIndex);
 		}
 	}

+ 3 - 3
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java

@@ -10,7 +10,6 @@ package com.yomahub.liteflow.flow.element.condition;
 import cn.hutool.core.util.StrUtil;
 import com.yomahub.liteflow.enums.ConditionTypeEnum;
 import com.yomahub.liteflow.exception.WhenExecuteException;
-import com.yomahub.liteflow.flow.element.Executable;
 import com.yomahub.liteflow.flow.parallel.CompletableFutureTimeout;
 import com.yomahub.liteflow.flow.parallel.ParallelSupplier;
 import com.yomahub.liteflow.flow.parallel.WhenFutureObj;
@@ -26,7 +25,6 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 /**
@@ -53,6 +51,8 @@ public class WhenCondition extends Condition {
 	private void executeAsyncCondition(Integer slotIndex) throws Exception{
 		Slot slot = DataBus.getSlot(slotIndex);
 
+		String currChainName = this.getCurrChainName();
+
 		//此方法其实只会初始化一次Executor,不会每次都会初始化。Executor是唯一的
 		ExecutorService parallelExecutor = ExecutorHelper.loadInstance().buildWhenExecutor(this.getThreadExecutorClass());
 
@@ -80,7 +80,7 @@ public class WhenCondition extends Condition {
 			}
 		}).map(executable -> CompletableFutureTimeout.completeOnTimeout(
 				WhenFutureObj.timeOut(executable.getExecuteName()),
-				CompletableFuture.supplyAsync(new ParallelSupplier(executable, slotIndex), parallelExecutor),
+				CompletableFuture.supplyAsync(new ParallelSupplier(executable, currChainName, slotIndex), parallelExecutor),
 				liteflowConfig.getWhenMaxWaitSeconds(),
 				TimeUnit.SECONDS
 		)).collect(Collectors.toList());

+ 10 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/entity/CmpStep.java

@@ -22,6 +22,8 @@ public class CmpStep {
 
     private String nodeName;
 
+    private String tag;
+
     private CmpStepTypeEnum stepType;
 
     //消耗的时间,毫秒为单位
@@ -138,4 +140,12 @@ public class CmpStep {
             }
         }
     }
+
+    public String getTag() {
+        return tag;
+    }
+
+    public void setTag(String tag) {
+        this.tag = tag;
+    }
 }

+ 1 - 2
liteflow-core/src/main/java/com/yomahub/liteflow/flow/executor/NodeExecutorHelper.java

@@ -32,8 +32,7 @@ public class NodeExecutorHelper {
     }
 
     public NodeExecutor buildNodeExecutor(Class<? extends NodeExecutor> nodeExecutorClass) {
-        // 高频操作-采取apache判空操作-效率高于hutool的isBlank将近3倍
-        if (ObjectUtil.isNull(nodeExecutorClass)) {
+        if (nodeExecutorClass == null) {
             // 此处使用默认的节点执行器进行执行
             nodeExecutorClass = DefaultNodeExecutor.class;
         }

+ 0 - 59
liteflow-core/src/main/java/com/yomahub/liteflow/flow/id/IdGeneratorHelper.java

@@ -1,59 +0,0 @@
-package com.yomahub.liteflow.flow.id;
-
-import cn.hutool.core.util.StrUtil;
-import com.yomahub.liteflow.exception.RequestIdGeneratorException;
-import com.yomahub.liteflow.property.LiteflowConfig;
-import com.yomahub.liteflow.property.LiteflowConfigGetter;
-import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
-
-import java.util.Objects;
-
-/**
- * Id 生成器帮助器
- *
- * @author tangkc
- */
-public class IdGeneratorHelper {
-
-    private static RequestIdGenerator requestIdGenerator;
-
-    private volatile static IdGeneratorHelper INSTANCE;
-
-    private IdGeneratorHelper() {
-
-    }
-
-    public static IdGeneratorHelper getInstance() {
-        if (Objects.isNull(INSTANCE)) {
-            //这里加同步锁是为了避免启动后第一次多并发获取requestId而造成重复初始化的场景
-            //并非每次都会执行这个同步锁,所以不存在性能问题
-            synchronized (IdGeneratorHelper.class) {
-                if (Objects.isNull(INSTANCE)) {
-                    INSTANCE = new IdGeneratorHelper();
-                    LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
-                    String requestIdGeneratorClass = liteflowConfig.getRequestIdGeneratorClass();
-                    if (StrUtil.isBlank(requestIdGeneratorClass)) {
-                        requestIdGenerator = new DefaultRequestIdGenerator();
-                    }
-                    try {
-                        Class<RequestIdGenerator> idGenerateClass = (Class<RequestIdGenerator>) Class.forName(requestIdGeneratorClass);
-                        requestIdGenerator = ContextAwareHolder.loadContextAware().registerBean(idGenerateClass);
-                    } catch (Exception e) {
-                        throw new RequestIdGeneratorException(e.getMessage());
-                    }
-                }
-            }
-        }
-
-        return INSTANCE;
-    }
-
-    public String generate() {
-        return requestIdGenerator.generate();
-    }
-
-    public void clear(){
-        INSTANCE = null;
-    }
-
-}

+ 54 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/id/IdGeneratorHolder.java

@@ -0,0 +1,54 @@
+package com.yomahub.liteflow.flow.id;
+
+import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.exception.RequestIdGeneratorException;
+import com.yomahub.liteflow.property.LiteflowConfig;
+import com.yomahub.liteflow.property.LiteflowConfigGetter;
+import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
+
+/**
+ * Id 生成器帮助器
+ *
+ * @author tangkc
+ */
+public class IdGeneratorHolder {
+
+    private RequestIdGenerator requestIdGenerator;
+
+    private static IdGeneratorHolder INSTANCE;
+
+    public static void init(){
+        try{
+            INSTANCE = new IdGeneratorHolder();
+            LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+            String requestIdGeneratorClass = liteflowConfig.getRequestIdGeneratorClass();
+
+            RequestIdGenerator requestIdGenerator;
+            if (StrUtil.isBlank(requestIdGeneratorClass)) {
+                requestIdGenerator = new DefaultRequestIdGenerator();
+            } else {
+                Class<RequestIdGenerator> idGenerateClass = (Class<RequestIdGenerator>) Class.forName(requestIdGeneratorClass);
+                requestIdGenerator = ContextAwareHolder.loadContextAware().registerBean(idGenerateClass);
+            }
+            INSTANCE.setRequestIdGenerator(requestIdGenerator);
+        }catch (Exception e) {
+            throw new RequestIdGeneratorException(e.getMessage());
+        }
+    }
+
+    public static IdGeneratorHolder getInstance() {
+        return INSTANCE;
+    }
+
+    public String generate() {
+        return requestIdGenerator.generate();
+    }
+
+    public RequestIdGenerator getRequestIdGenerator() {
+        return requestIdGenerator;
+    }
+
+    public void setRequestIdGenerator(RequestIdGenerator requestIdGenerator) {
+        this.requestIdGenerator = requestIdGenerator;
+    }
+}

+ 5 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/flow/parallel/ParallelSupplier.java

@@ -16,16 +16,20 @@ public class ParallelSupplier implements Supplier<WhenFutureObj> {
 
     private final Executable executableItem;
 
+    private final String currChainName;
+    
     private final Integer slotIndex;
 
-    public ParallelSupplier(Executable executableItem, Integer slotIndex) {
+    public ParallelSupplier(Executable executableItem, String currChainName, Integer slotIndex) {
         this.executableItem = executableItem;
+        this.currChainName = currChainName;
         this.slotIndex = slotIndex;
     }
 
     @Override
     public WhenFutureObj get() {
         try {
+            executableItem.setCurrChainName(currChainName);
             executableItem.execute(slotIndex);
             return WhenFutureObj.success(executableItem.getExecuteName());
         } catch (Exception e){

+ 34 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java

@@ -1,6 +1,7 @@
 package com.yomahub.liteflow.parser.helper;
 
 import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ReflectUtil;
 import cn.hutool.core.util.StrUtil;
@@ -27,6 +28,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.function.Consumer;
+import java.util.regex.Pattern;
 
 import static com.yomahub.liteflow.common.ChainConstant.*;
 
@@ -383,8 +385,39 @@ public class ParserHelper {
 	public static void parseOneChainEl(Element e) {
 		//构建chainBuilder
 		String chainName = e.attributeValue(NAME);
-		String el = e.getTextTrim();
+		String text = e.getText();
+		String el = RegexUtil.removeComments(text);
 		LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainName(chainName);
 		chainELBuilder.setEL(el).build();
 	}
+
+	private static class RegexUtil{
+		// java 注释的正则表达式
+		private static final String REGEX_COMMENT = "/\\*((?!\\*/).|[\\r\\n])*?\\*/|[ \\t]*//.*";
+
+		/**
+		 * 移除 el 表达式中的注释,支持 java 的注释,包括单行注释、多行注释,
+		 * 会压缩字符串,移除空格和换行符
+		 *
+		 * @param elStr el 表达式
+		 * @return 移除注释后的 el 表达式
+		 */
+		private static String removeComments(String elStr) {
+			if (StrUtil.isBlank(elStr)) {
+				return elStr;
+			}
+
+			String text = Pattern.compile(REGEX_COMMENT)
+					.matcher(elStr)
+					// 移除注释
+					.replaceAll(CharSequenceUtil.EMPTY)
+					// 移除字符串中的空格
+					.replaceAll(CharSequenceUtil.SPACE, CharSequenceUtil.EMPTY);
+
+			// 移除所有换行符
+			return StrUtil.removeAllLineBreaks(text);
+		}
+	}
+
+
 }

+ 21 - 27
liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java

@@ -7,11 +7,12 @@
  */
 package com.yomahub.liteflow.slot;
 
+import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.yomahub.liteflow.exception.NoSuchContextBeanException;
 import com.yomahub.liteflow.exception.NullParamException;
 import com.yomahub.liteflow.flow.entity.CmpStep;
-import com.yomahub.liteflow.flow.id.IdGeneratorHelper;
+import com.yomahub.liteflow.flow.id.IdGeneratorHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -112,11 +113,23 @@ public class Slot{
 	}
 
 	public <T> T getChainReqData(String chainId) {
-		return (T) metaDataMap.get(CHAIN_REQ_PREFIX + chainId);
+		String key = CHAIN_REQ_PREFIX + chainId;
+		if (hasMetaData(key)){
+			Queue<Object> queue = (Queue<Object>) metaDataMap.get(key);
+			return (T)queue.poll();
+		}else{
+			return null;
+		}
 	}
 
 	public <T> void setChainReqData(String chainId, T t) {
-		putMetaDataMap(CHAIN_REQ_PREFIX + chainId, t);
+		String key = CHAIN_REQ_PREFIX + chainId;
+		if (hasMetaData(key)){
+			Queue<Object> queue = (Queue<Object>) metaDataMap.get(key);
+			queue.offer(t);
+		}else{
+			putMetaDataMap(key, new ConcurrentLinkedQueue<>(ListUtil.toList(t)));
+		}
 	}
 
 	public <T> void setPrivateDeliveryData(String nodeId, T t){
@@ -160,33 +173,14 @@ public class Slot{
 		return (T) metaDataMap.get(SWITCH_NODE_PREFIX + key);
 	}
 
-	public void pushChainName(String chainName) {
-		if (this.hasMetaData(CHAIN_NAME)){
-			Stack<String> stack = (Stack<String>)metaDataMap.get(CHAIN_NAME);
-			stack.push(chainName);
-		}else{
-			Stack<String> stack = new Stack<>();
-			stack.push(chainName);
-			this.putMetaDataMap(CHAIN_NAME, stack);
-		}
-	}
-
-	public void popChainName(){
-		if (this.hasMetaData(CHAIN_NAME)){
-			Stack<String> stack = (Stack<String>)metaDataMap.get(CHAIN_NAME);
-			if (stack.size() > 1){
-				stack.pop();
-			}
+	public void setChainName(String chainName) {
+		if (!hasMetaData(CHAIN_NAME)){
+			this.putMetaDataMap(CHAIN_NAME, chainName);
 		}
 	}
 
 	public String getChainName() {
-		try{
-			Stack<String> stack = (Stack<String>)metaDataMap.get(CHAIN_NAME);
-			return stack.peek();
-		}catch (Exception e){
-			return null;
-		}
+		return (String) metaDataMap.get(CHAIN_NAME);
 	}
 
 	public void addStep(CmpStep step){
@@ -223,7 +217,7 @@ public class Slot{
 	}
 
 	public void generateRequestId() {
-		metaDataMap.put(REQUEST_ID, IdGeneratorHelper.getInstance().generate());
+		metaDataMap.put(REQUEST_ID, IdGeneratorHolder.getInstance().generate());
 	}
 
 	public String getRequestId() {

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/spi/local/LocalPathContentParser.java

@@ -34,7 +34,7 @@ public class LocalPathContentParser implements PathContentParser {
             }
             String content = ResourceUtil.readUtf8Str(path);
             if (StrUtil.isNotBlank(content)){
-                contentList.add(ResourceUtil.readUtf8Str(path));
+                contentList.add(content);
             }
         }
 

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/thread/ExecutorHelper.java

@@ -130,7 +130,7 @@ public class ExecutorHelper {
                 return executorService;
             }
         }catch (Exception e){
-            LOG.error(e.getMessage(), e);
+            LOG.error(e.getMessage());
             throw new ThreadExecutorServiceCreateException(e.getMessage());
         }
     }

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/util/LOGOPrinter.java

@@ -13,7 +13,7 @@ public class LOGOPrinter {
 	/**
 	 * LiteFlow 当前版本号
 	 */
-	private static final String VERSION_NO = "v2.8.1";
+	private static final String VERSION_NO = "v2.8.2";
 
 	public static void print() {
 		StringBuilder str = new StringBuilder("\n");

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowProxyUtil.java

@@ -77,7 +77,7 @@ public class LiteFlowProxyUtil {
             throw new RuntimeException();
         }catch (Exception e){
             String errMsg = StrUtil.format("Error while proxying bean[{}]",bean.getClass().getName());
-            LOG.error(errMsg, e);
+            LOG.error(errMsg);
             throw new ComponentProxyErrorException(errMsg);
         }
     }

+ 0 - 2
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java

@@ -1,7 +1,6 @@
 package com.yomahub.liteflow.test;
 
 import com.yomahub.liteflow.flow.FlowBus;
-import com.yomahub.liteflow.flow.id.IdGeneratorHelper;
 import com.yomahub.liteflow.property.LiteflowConfigGetter;
 import com.yomahub.liteflow.spi.holder.SpiFactoryCleaner;
 import com.yomahub.liteflow.spring.ComponentScanner;
@@ -17,7 +16,6 @@ public class BaseTest {
         ExecutorHelper.loadInstance().clearExecutorServiceMap();
         SpiFactoryCleaner.clean();
         LiteflowConfigGetter.clean();
-        IdGeneratorHelper.getInstance().clear();
     }
 
 }

+ 7 - 5
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ICmp.java

@@ -17,11 +17,13 @@ public class ICmp {
     @LiteflowMethod(LiteFlowMethodEnum.PROCESS)
     public void process(NodeComponent bindCmp) throws Exception {
         DefaultContext context = bindCmp.getFirstContextBean();
-        if (context.hasData("count")){
-            Integer count = context.getData("count");
-            context.setData("count", ++count);
-        } else{
-            context.setData("count", 1);
+        synchronized (ICmp.class){
+            if (context.hasData("count")){
+                Integer count = context.getData("count");
+                context.setData("count", ++count);
+            } else{
+                context.setData("count", 1);
+            }
         }
         System.out.println("Icomp executed! throw Exception!");
         throw new TestException();

+ 23 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/cmpStep/CmpStepELDeclSpringbootTest.java

@@ -2,6 +2,7 @@ package com.yomahub.liteflow.test.cmpStep;
 
 import com.yomahub.liteflow.core.FlowExecutor;
 import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.flow.entity.CmpStep;
 import com.yomahub.liteflow.test.BaseTest;
 import org.junit.Assert;
 import org.junit.Test;
@@ -13,6 +14,10 @@ import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
 
 /**
  * springboot环境最普通的例子测试
@@ -48,4 +53,22 @@ public class CmpStepELDeclSpringbootTest extends BaseTest {
         Assert.assertTrue(response.isSuccess());
         Assert.assertEquals("a==>b", response.getExecuteStepStrWithoutTime());
     }
+
+    @Test
+    public void testStep3() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
+        Assert.assertTrue(response.isSuccess());
+        Map<String, CmpStep> stepMap = response.getExecuteSteps();
+        Assert.assertEquals(2, stepMap.size());
+        Queue<CmpStep> queue = response.getExecuteStepQueue();
+        Assert.assertEquals(5, queue.size());
+
+        Set<String> tagSet = new HashSet<>();
+        response.getExecuteStepQueue().stream().filter(
+                cmpStep -> cmpStep.getNodeId().equals("a")
+        ).forEach(cmpStep -> tagSet.add(cmpStep.getTag()));
+
+        Assert.assertEquals(3, tagSet.size());
+
+    }
 }

+ 35 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/LiteflowNodeELSpringbootTest.java

@@ -0,0 +1,35 @@
+package com.yomahub.liteflow.test.comments;
+
+import cn.hutool.core.collection.ListUtil;
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+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.context.annotation.ComponentScan;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@TestPropertySource(value = "classpath:/comments/application.properties")
+@SpringBootTest(classes = LiteflowNodeELSpringbootTest.class)
+@EnableAutoConfiguration
+@ComponentScan({"com.yomahub.liteflow.test.comments.cmp"})
+public class LiteflowNodeELSpringbootTest extends BaseTest {
+
+	@Resource
+	private FlowExecutor flowExecutor;
+
+	// 测试注释
+	@Test
+	public void testAsyncFlow1() {
+		LiteflowResponse response = flowExecutor.execute2Resp("chain1", "it's a base request");
+		Assert.assertTrue(response.isSuccess());
+		Assert.assertTrue(ListUtil.toList("a==>b==>c==>b","a==>b==>b==>c").contains(response.getExecuteStepStr()));
+	}
+}

+ 24 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/cmp/ACmp.java

@@ -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.comments.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import org.springframework.stereotype.Component;
+
+@Component("a")
+@LiteflowCmpDefine
+public class ACmp{
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		System.out.println("ACmp executed!");
+	}
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/cmp/BCmp.java

@@ -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.comments.cmp;
+
+import cn.hutool.core.thread.ThreadUtil;
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import org.springframework.stereotype.Component;
+
+@Component("b")
+@LiteflowCmpDefine
+public class BCmp{
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/cmp/CCmp.java

@@ -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.comments.cmp;
+
+import cn.hutool.core.thread.ThreadUtil;
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import org.springframework.stereotype.Component;
+
+@Component("c")
+@LiteflowCmpDefine
+public class CCmp{
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 4 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/comments/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * 测试注释
+ */
+package com.yomahub.liteflow.test.comments;

+ 60 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/GetChainNameELDeclSpringbootTest.java

@@ -0,0 +1,60 @@
+package com.yomahub.liteflow.test.getChainName;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.slot.DefaultContext;
+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.context.annotation.ComponentScan;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+/**
+ * springboot环境获取ChainName的测试
+ * @author Bryan.Zhang
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(value = "classpath:/getChainName/application.properties")
+@SpringBootTest(classes = GetChainNameELDeclSpringbootTest.class)
+@EnableAutoConfiguration
+@ComponentScan({"com.yomahub.liteflow.test.getChainName.cmp"})
+public class GetChainNameELDeclSpringbootTest extends BaseTest {
+
+    @Resource
+    private FlowExecutor flowExecutor;
+
+    @Test
+    public void testGetChainName1() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals("sub1", context.getData("a"));
+        Assert.assertEquals("sub2", context.getData("b"));
+        Assert.assertEquals("sub3", context.getData("c"));
+        Assert.assertEquals("sub4", context.getData("d"));
+    }
+
+    @Test
+    public void testGetChainName2() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals("chain2", context.getData("g"));
+        Assert.assertEquals("sub1", context.getData("a"));
+        Assert.assertEquals("sub2", context.getData("b"));
+        Assert.assertEquals("sub3", context.getData("c"));
+        Assert.assertEquals("sub4", context.getData("d"));
+        Assert.assertEquals("sub5", context.getData("f"));
+        Assert.assertEquals("sub5_chain2", context.getData("e"));
+        Assert.assertEquals("sub6", context.getData("h"));
+        Assert.assertEquals("sub6", context.getData("j"));
+        Assert.assertNull(context.getData("k"));
+    }
+
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/ACmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("a")
+@LiteflowCmpDefine
+public class ACmp{
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/BCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("b")
+@LiteflowCmpDefine
+public class BCmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/CCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("c")
+@LiteflowCmpDefine
+public class CCmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/DCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("d")
+@LiteflowCmpDefine
+public class DCmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 30 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/ECmp.java

@@ -0,0 +1,30 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("e")
+@LiteflowCmpDefine
+public class ECmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		if (context.hasData(bindCmp.getNodeId())){
+			context.setData(bindCmp.getNodeId(), context.getData(bindCmp.getNodeId()) + "_" + bindCmp.getCurrChainName());
+		}else{
+			context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+		}
+	}
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/FCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("f")
+@LiteflowCmpDefine
+public class FCmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/GCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("g")
+@LiteflowCmpDefine
+public class GCmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 29 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/HCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.annotation.LiteflowSwitchCmpDefine;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.core.NodeSwitchComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("h")
+@LiteflowSwitchCmpDefine
+public class HCmp{
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS_SWITCH)
+	public String processSwitch(NodeComponent bindCmp) throws Exception {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+		return "j";
+	}
+
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/JCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("j")
+@LiteflowCmpDefine
+public class JCmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 26 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/getChainName/cmp/KCmp.java

@@ -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.getChainName.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+@Component("k")
+@LiteflowCmpDefine
+public class KCmp {
+
+	@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+	public void process(NodeComponent bindCmp) {
+		DefaultContext context = bindCmp.getFirstContextBean();
+		context.setData(bindCmp.getNodeId(), bindCmp.getCurrChainName());
+	}
+}

+ 14 - 1
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/ImplicitSubFlowELDeclSpringbootTest.java

@@ -36,7 +36,7 @@ public class ImplicitSubFlowELDeclSpringbootTest extends BaseTest {
 
     //这里GCmp中隐式的调用chain4,从而执行了h,m
     @Test
-    public void testImplicitSubFlow() {
+    public void testImplicitSubFlow1() {
         LiteflowResponse response = flowExecutor.execute2Resp("chain3", "it's a request");
         DefaultContext context = response.getFirstContextBean();
         Assert.assertTrue(response.isSuccess());
@@ -49,4 +49,17 @@ public class ImplicitSubFlowELDeclSpringbootTest extends BaseTest {
         //requestData的取值正确
         Assert.assertEquals("it's implicit subflow.", context.getData("innerRequest"));
     }
+
+    //在p里多线程调用q 10次,每个q取到的参数都是不同的。
+    @Test
+    public void testImplicitSubFlow2() {
+        LiteflowResponse response = flowExecutor.execute2Resp("c1", "it's a request");
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertTrue(response.isSuccess());
+
+        Set<String> set = context.getData("test");
+
+        //requestData的取值正确
+        Assert.assertEquals(10, set.size());
+    }
 }

+ 35 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/cmp2/PCmp.java

@@ -0,0 +1,35 @@
+package com.yomahub.liteflow.test.subflow.cmp2;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.flow.element.Node;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+@Component("p")
+@LiteflowCmpDefine
+public class PCmp{
+
+    @Autowired
+    private FlowExecutor flowExecutor;
+
+    @LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+    public void process(NodeComponent bindCmp) throws Exception {
+        int slotIndex = bindCmp.getSlotIndex();
+        for (int i = 0; i < 10; i++) {
+            int finalI = i;
+            new Thread(() -> {
+                try {
+                    flowExecutor.invoke("c2", "it's implicit subflow " + finalI, slotIndex);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }).start();
+        }
+        Thread.sleep(1000);
+    }
+}

+ 33 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/subflow/cmp2/QCmp.java

@@ -0,0 +1,33 @@
+package com.yomahub.liteflow.test.subflow.cmp2;
+
+import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
+import com.yomahub.liteflow.annotation.LiteflowMethod;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
+import com.yomahub.liteflow.slot.DefaultContext;
+import org.springframework.stereotype.Component;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+@Component("q")
+@LiteflowCmpDefine
+public class QCmp{
+    @LiteflowMethod(LiteFlowMethodEnum.PROCESS)
+    public void process(NodeComponent bindCmp) throws Exception {
+        String requestData = bindCmp.getSubChainReqData();
+        DefaultContext context = bindCmp.getFirstContextBean();
+
+        synchronized (QCmp.class){
+            if (context.hasData("test")){
+                Set<String> set = context.getData("test");
+                set.add(requestData);
+            }else{
+                Set<String> set = new HashSet<>();
+                set.add(requestData);
+                context.setData("test", set);
+            }
+        }
+    }
+}

+ 5 - 1
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/cmpStep/flow.el.xml

@@ -1,10 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <flow>
     <chain name="chain1">
-        THEN(a, b, WHEN(c, d));
+        THEN(a.tag("A"), b.tag("B"), WHEN(c.tag("C"), d.tag("D")));
     </chain>
 
     <chain name="chain2">
         THEN(WHEN(e, a).any(true), b);
     </chain>
+
+    <chain name="chain3">
+        THEN(a.tag("a1"), b, a.tag("a2"), a.tag("a3"), b);
+    </chain>
 </flow>

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/comments/application.properties

@@ -0,0 +1 @@
+liteflow.rule-source=comments/flow.el.xml

+ 18 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/comments/flow.el.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+    <chain name="chain1">
+        // 单行注释
+        THEN(
+            // 单行注释
+            a,
+            b,
+            WHEN(
+                /**
+                * 多行注释
+                */
+                c,
+                b
+            )
+        );
+    </chain>
+</flow>

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/getChainName/application.properties

@@ -0,0 +1 @@
+liteflow.rule-source=getChainName/flow.el.xml

+ 38 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/getChainName/flow.el.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+    <chain name="chain1">
+        WHEN(sub1, sub2, sub3, sub4);
+    </chain>
+
+    <chain name="sub1">
+        THEN(a);
+    </chain>
+
+    <chain name="sub2">
+        THEN(b);
+    </chain>
+
+    <chain name="sub3">
+        THEN(c);
+    </chain>
+
+    <chain name="sub4">
+        THEN(d);
+    </chain>
+
+    <chain name="sub5">
+        THEN(e, f);
+    </chain>
+
+    <chain name="sub6">
+        SWITCH(h).to(j, k);
+    </chain>
+
+    <chain name="chain2">
+        THEN(
+            g,
+            WHEN(sub1, WHEN(sub2, sub3)),
+            sub4, sub5, e, sub6
+        );
+    </chain>
+</flow>

+ 8 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/subflow/flow-implicit.el.xml

@@ -7,4 +7,12 @@
     <chain name="chain4">
         THEN(h, m);
     </chain>
+
+    <chain name="c1">
+        THEN(p);
+    </chain>
+
+    <chain name="c2">
+        THEN(q);
+    </chain>
 </flow>

+ 65 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/pom.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>liteflow-testcase-el</artifactId>
+        <groupId>com.yomahub</groupId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>liteflow-testcase-el-nospring</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.yomahub</groupId>
+            <artifactId>liteflow-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.101tec</groupId>
+            <artifactId>zkclient</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-framework</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-recipes</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <version>2.8.2</version>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/BaseTest.java

@@ -0,0 +1,20 @@
+package com.yomahub.liteflow.test;
+
+import com.yomahub.liteflow.core.FlowExecutorHolder;
+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();
+        FlowExecutorHolder.clean();
+    }
+}

+ 33 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/AbsoluteConfigPathTest.java

@@ -0,0 +1,33 @@
+package com.yomahub.liteflow.test.absoluteConfigPath;
+
+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.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * 非spring环境下异步线程超时日志打印测试
+ * @author Bryan.Zhang
+ * @since 2.6.11
+ */
+public class AbsoluteConfigPathTest extends BaseTest {
+
+    private static FlowExecutor flowExecutor;
+
+    @BeforeClass
+    public static void init(){
+        LiteflowConfig config = new LiteflowConfig();
+        config.setRuleSource("/usr/local/flow2.xml");
+        flowExecutor = FlowExecutorHolder.loadInstance(config);
+    }
+
+    @Test
+    public void testAbsoluteConfig() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+    }
+}

+ 18 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/cmp/ACmp.java

@@ -0,0 +1,18 @@
+/**
+ * <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;
+
+public class ACmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ACmp executed!");
+	}
+}

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/cmp/BCmp.java

@@ -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.absoluteConfigPath.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class BCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/absoluteConfigPath/cmp/CCmp.java

@@ -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.absoluteConfigPath.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 136 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/AsyncNodeTest.java

@@ -0,0 +1,136 @@
+package com.yomahub.liteflow.test.asyncNode;
+
+import cn.hutool.core.collection.ListUtil;
+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.slot.DefaultContext;
+import com.yomahub.liteflow.test.BaseTest;
+import com.yomahub.liteflow.test.asyncNode.exception.TestException;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * 测试隐式调用子流程
+ * 单元测试
+ *
+ * @author ssss
+ */
+public class AsyncNodeTest extends BaseTest {
+
+    private static FlowExecutor flowExecutor;
+
+    @BeforeClass
+    public static void init(){
+        LiteflowConfig config = new LiteflowConfig();
+        config.setRuleSource("asyncNode/flow.el.xml");
+        flowExecutor = FlowExecutorHolder.loadInstance(config);
+    }
+
+    /*****
+     * 标准chain 嵌套选择 嵌套子chain进行执行
+     * 验证了when情况下 多个node是并行执行
+     * 验证了默认参数情况下 when可以加载执行
+     * **/
+    @Test
+    public void testAsyncFlow1() {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "it's a base request");
+        Assert.assertTrue(response.isSuccess());
+        System.out.println(response.getExecuteStepStr());
+    }
+
+    //这个和test1有点类似,只不过进一步验证了步骤
+    @Test
+    public void testAsyncFlow2() {
+        LiteflowResponse 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.getExecuteStepStr()));
+    }
+
+    //测试errorResume,默认的errorResume为false,这里测试默认的
+    @Test
+    public void testAsyncFlow3_1() {
+        LiteflowResponse 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 response = flowExecutor.execute2Resp("chain3-2", "it's a base request");
+        Assert.assertTrue(response.isSuccess());
+    }
+
+    //相同group的并行组,会合并,并且errorResume根据第一个when来,这里第一个when配置了不抛错
+    @Test
+    public void testAsyncFlow4() {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain4", "it's a base request");
+        DefaultContext context = response.getFirstContextBean();
+        //因为不记录错误,所以最终结果是true
+        Assert.assertTrue(response.isSuccess());
+        //因为是并行组,所以即便抛错了,其他组件也会执行,i在流程里配置了2遍,i抛错,但是也执行了2遍,这里验证下
+        Integer count = context.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 response = flowExecutor.execute2Resp("chain5", "it's a base request");
+        DefaultContext context = response.getFirstContextBean();
+        //整个并行组是报错的,所以最终结果是false
+        Assert.assertFalse(response.isSuccess());
+        //因为是并行组,所以即便抛错了,其他组件也会执行,i在流程里配置了2遍,i抛错,但是也执行了2遍,这里验证下
+        Integer count = context.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 response = flowExecutor.execute2Resp("chain6", "it's a base request");
+        DefaultContext context = response.getFirstContextBean();
+        //第一个when会抛错,所以最终结果是false
+        Assert.assertFalse(response.isSuccess());
+        //因为是不同组并行组,第一组的when里的i就抛错了,所以i就执行了1遍
+        Integer count = context.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 response = flowExecutor.execute2Resp("chain7", "it's a base request");
+        DefaultContext context = response.getFirstContextBean();
+        //第二个when会抛错,所以最终结果是false
+        Assert.assertFalse(response.isSuccess());
+        //  传递了slotIndex,则set的size==2
+        Integer count = context.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 response = flowExecutor.execute2Resp("chain8", "it's a base request");
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertTrue(context.getData("check").toString().startsWith("habc"));
+    }
+}

+ 22 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ACmp.java

@@ -0,0 +1,22 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+
+public class ACmp extends NodeComponent {
+    @Override
+    public void process() {
+        DefaultContext context = this.getFirstContextBean();
+        synchronized (NodeComponent.class){
+            if (context.hasData("check")){
+                String str = context.getData("check");
+                str += this.getNodeId();
+                context.setData("check", str);
+            }else{
+                context.setData("check", this.getNodeId());
+            }
+        }
+        System.out.println("Acomp executed!");
+    }
+}

+ 22 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/BCmp.java

@@ -0,0 +1,22 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+
+public class BCmp extends NodeComponent {
+    @Override
+    public void process() {
+        DefaultContext context = this.getFirstContextBean();
+        synchronized (NodeComponent.class){
+            if (context.hasData("check")){
+                String str = context.getData("check");
+                str += this.getNodeId();
+                context.setData("check", str);
+            }else{
+                context.setData("check", this.getNodeId());
+            }
+        }
+        System.out.println("Bcomp executed!");
+    }
+}

+ 22 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/CCmp.java

@@ -0,0 +1,22 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+
+public class CCmp extends NodeComponent {
+    @Override
+    public void process() throws Exception {
+        DefaultContext context = this.getFirstContextBean();
+        synchronized (NodeComponent.class){
+            if (context.hasData("check")){
+                String str = context.getData("check");
+                str += this.getNodeId();
+                context.setData("check", str);
+            }else{
+                context.setData("check", this.getNodeId());
+            }
+        }
+        System.out.println("Ccomp executed!");
+    }
+}

+ 23 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/DCmp.java

@@ -0,0 +1,23 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+
+public class DCmp extends NodeComponent {
+    @Override
+    public void process() throws Exception {
+        Thread.sleep(1000);
+        DefaultContext context = this.getFirstContextBean();
+        synchronized (NodeComponent.class){
+            if (context.hasData("check")){
+                String str = context.getData("check");
+                str += this.getNodeId();
+                context.setData("check", str);
+            }else{
+                context.setData("check", this.getNodeId());
+            }
+        }
+        System.out.println("Dcomp executed!");
+    }
+}

+ 13 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ECmp.java

@@ -0,0 +1,13 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeSwitchComponent;
+
+
+public class ECmp extends NodeSwitchComponent {
+
+    @Override
+    public String processSwitch() throws Exception {
+        System.out.println("Ecomp executed!");
+        return "g";
+    }
+}

+ 12 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/FCmp.java

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

+ 24 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/GCmp.java

@@ -0,0 +1,24 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+
+public class GCmp extends NodeComponent {
+
+    @Override
+    public void process() throws Exception {
+        Thread.sleep(500);
+        DefaultContext context = this.getFirstContextBean();
+        synchronized (NodeComponent.class){
+            if (context.hasData("check")){
+                String str = context.getData("check");
+                str += this.getNodeId();
+                context.setData("check", str);
+            }else{
+                context.setData("check", this.getNodeId());
+            }
+        }
+        System.out.println("Gcomp executed!");
+    }
+}

+ 24 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/HCmp.java

@@ -0,0 +1,24 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+
+public class HCmp extends NodeComponent {
+
+    @Override
+    public void process() throws Exception {
+        DefaultContext context = this.getFirstContextBean();
+        synchronized (NodeComponent.class){
+            if (context.hasData("check")){
+                String str = context.getData("check");
+                str += this.getNodeId();
+                context.setData("check", str);
+            }else{
+                context.setData("check", this.getNodeId());
+            }
+        }
+
+        System.out.println("Hcomp executed!");
+    }
+}

+ 24 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/ICmp.java

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

+ 13 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/cmp/JCmp.java

@@ -0,0 +1,13 @@
+package com.yomahub.liteflow.test.asyncNode.cmp;
+
+import com.yomahub.liteflow.core.NodeSwitchComponent;
+
+
+public class JCmp extends NodeSwitchComponent {
+
+    @Override
+    public String processSwitch() throws Exception {
+        System.out.println("Jcomp executed!");
+        return "chain3";
+    }
+}

+ 4 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/asyncNode/exception/TestException.java

@@ -0,0 +1,4 @@
+package com.yomahub.liteflow.test.asyncNode.exception;
+
+public class TestException extends Exception{
+}

+ 28 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/BaseCommonTest.java

@@ -0,0 +1,28 @@
+package com.yomahub.liteflow.test.base;
+
+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.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BaseCommonTest extends BaseTest{
+
+    private static FlowExecutor flowExecutor;
+
+    @BeforeClass
+    public static void init(){
+        LiteflowConfig config = new LiteflowConfig();
+        config.setRuleSource("base/flow.el.xml");
+        flowExecutor = FlowExecutorHolder.loadInstance(config);
+    }
+
+    @Test
+    public void testBase(){
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "test0");
+        Assert.assertTrue(response.isSuccess());
+    }
+}

+ 18 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/ACmp.java

@@ -0,0 +1,18 @@
+/**
+ * <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;
+
+public class ACmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ACmp executed!");
+	}
+}

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/BCmp.java

@@ -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.base.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class BCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/CCmp.java

@@ -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.base.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/DCmp.java

@@ -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.base.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class DCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("DCmp executed!");
+	}
+
+}

+ 18 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/base/cmp/ECmp.java

@@ -0,0 +1,18 @@
+/**
+ * <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.NodeSwitchComponent;
+
+public class ECmp extends NodeSwitchComponent {
+
+	@Override
+	public String processSwitch() throws Exception {
+		return "g";
+	}
+}

+ 210 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/BuilderTest.java

@@ -0,0 +1,210 @@
+package com.yomahub.liteflow.test.builder;
+
+import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
+import com.yomahub.liteflow.builder.LiteFlowConditionBuilder;
+import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
+import com.yomahub.liteflow.builder.entity.ExecutableEntity;
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.core.FlowExecutorHolder;
+import com.yomahub.liteflow.enums.NodeTypeEnum;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.property.LiteflowConfig;
+import com.yomahub.liteflow.test.BaseTest;
+import com.yomahub.liteflow.test.builder.cmp.*;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BuilderTest extends BaseTest {
+
+    private static FlowExecutor flowExecutor;
+
+    @BeforeClass
+    public static void init(){
+        LiteflowConfig config = new LiteflowConfig();
+        flowExecutor = FlowExecutorHolder.loadInstance(config);
+    }
+
+    //基于普通组件的builder模式测试
+    @Test
+    public void testBuilder() throws Exception {
+        LiteFlowNodeBuilder.createNode().setId("a")
+                .setName("组件A")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz("com.yomahub.liteflow.test.builder.cmp.ACmp")
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("b")
+                .setName("组件B")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz("com.yomahub.liteflow.test.builder.cmp.BCmp")
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("c")
+                .setName("组件C")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz("com.yomahub.liteflow.test.builder.cmp.CCmp")
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("d")
+                .setName("组件D")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz("com.yomahub.liteflow.test.builder.cmp.DCmp")
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("e")
+                .setName("组件E")
+                .setType(NodeTypeEnum.SWITCH)
+                .setClazz("com.yomahub.liteflow.test.builder.cmp.ECmp")
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("f")
+                .setName("组件F")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz("com.yomahub.liteflow.test.builder.cmp.FCmp")
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("g")
+                .setName("组件G")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz("com.yomahub.liteflow.test.builder.cmp.GCmp")
+                .build();
+
+
+        LiteFlowChainBuilder.createChain().setChainName("chain2").setCondition(
+                LiteFlowConditionBuilder.createThenCondition().setValue("c,d").build()
+        ).build();
+
+        LiteFlowChainBuilder.createChain().setChainName("chain1").setCondition(
+                LiteFlowConditionBuilder
+                        .createThenCondition()
+                        .setValue("a,b").build()
+        ).setCondition(
+                LiteFlowConditionBuilder.createWhenCondition()
+                        .setValue("e(f|g|chain2)").build()
+        ).build();
+
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1");
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals("a[组件A]==>b[组件B]==>e[组件E]==>c[组件C]==>d[组件D]", response.getExecuteStepStr());
+    }
+
+    //基于普通组件的builder模式测试
+    @Test
+    public void testBuilderForClassAndCode() throws Exception {
+        LiteFlowNodeBuilder.createNode().setId("a")
+                .setName("组件A")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(ACmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("b")
+                .setName("组件B")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(BCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("c")
+                .setName("组件C")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(CCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("d")
+                .setName("组件D")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(DCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("e")
+                .setName("组件E")
+                .setType(NodeTypeEnum.SWITCH)
+                .setClazz(ECmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("f")
+                .setName("组件F")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(FCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("g")
+                .setName("组件G")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(GCmp.class)
+                .build();
+
+        LiteFlowChainBuilder.createChain().setChainName("chain2").setCondition(
+                LiteFlowConditionBuilder.createThenCondition().setValue("c,d").build()
+        ).build();
+
+        LiteFlowChainBuilder.createChain().setChainName("chain1").setCondition(
+                LiteFlowConditionBuilder
+                        .createThenCondition()
+                        .setValue("a,b").build()
+        ).setCondition(
+                LiteFlowConditionBuilder.createWhenCondition()
+                        .setValue("e(f|g|chain2)").build()
+        ).build();
+
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1");
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals("a[组件A]==>b[组件B]==>e[组件E]==>c[组件C]==>d[组件D]", response.getExecuteStepStr());
+    }
+
+    //基于普通组件的builder模式测试
+    @Test
+    public void testBuilderForConditionNode() throws Exception {
+        LiteFlowNodeBuilder.createNode().setId("a")
+                .setName("组件A")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(ACmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("b")
+                .setName("组件B")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(BCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("c")
+                .setName("组件C")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(CCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("d")
+                .setName("组件D")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(DCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("e")
+                .setName("组件E")
+                .setType(NodeTypeEnum.SWITCH)
+                .setClazz(ECmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("f")
+                .setName("组件F")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(FCmp.class)
+                .build();
+        LiteFlowNodeBuilder.createNode().setId("g")
+                .setName("组件G")
+                .setType(NodeTypeEnum.COMMON)
+                .setClazz(GCmp.class)
+                .build();
+
+
+        LiteFlowChainBuilder.createChain().setChainName("chain2").setCondition(
+                LiteFlowConditionBuilder.createThenCondition()
+                        .setExecutable(new ExecutableEntity().setId("c"))
+                        .setExecutable(new ExecutableEntity().setId("d"))
+                        .build()
+        ).build();
+
+        LiteFlowChainBuilder.createChain().setChainName("chain1").setCondition(
+                LiteFlowConditionBuilder
+                        .createThenCondition()
+                        .setExecutable(new ExecutableEntity().setId("a").setTag("hello"))
+                        .setExecutable(new ExecutableEntity().setId("b"))
+                        .build()
+        ).setCondition(
+                LiteFlowConditionBuilder.createWhenCondition()
+                        .setExecutable(
+                                new ExecutableEntity().setId("e")
+                                        .addNodeCondComponent(new ExecutableEntity().setId("f").setTag("FHello"))
+                                        .addNodeCondComponent(new ExecutableEntity().setId("g"))
+                                        .addNodeCondComponent(new ExecutableEntity().setId("chain2")
+                                        )).build()
+        ).build();
+
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1");
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals("a[组件A]==>b[组件B]==>e[组件E]==>c[组件C]==>d[组件D]", response.getExecuteStepStr());
+    }
+}

+ 18 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/ACmp.java

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

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/BCmp.java

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

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/CCmp.java

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

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/DCmp.java

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

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/ECmp.java

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

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/FCmp.java

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

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/builder/cmp/GCmp.java

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

+ 61 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/LiteflowRetryTest.java

@@ -0,0 +1,61 @@
+package com.yomahub.liteflow.test.cmpRetry;
+
+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.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+/**
+ * 测试非spring下的节点执行器
+ * @author Bryan.Zhang
+ * @since 2.5.10
+ */
+public class LiteflowRetryTest extends BaseTest {
+
+    private static FlowExecutor flowExecutor;
+
+    @BeforeClass
+    public static void init(){
+        LiteflowConfig config = new LiteflowConfig();
+        config.setRuleSource("cmpRetry/flow.el.xml");
+        config.setRetryCount(3);
+        config.setSlotSize(512);
+        flowExecutor = FlowExecutorHolder.loadInstance(config);
+    }
+
+    //全局重试配置测试
+    @Test
+    public void testRetry1() {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals("a==>b==>b==>b", response.getExecuteStepStr());
+    }
+
+    //单个组件重试配置测试
+    @Test
+    public void testRetry2() {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+        Assert.assertFalse(response.isSuccess());
+        Assert.assertEquals("c==>c==>c==>c==>c==>c", response.getExecuteStepStr());
+    }
+
+    //单个组件指定异常,但抛出的并不是指定异常的场景测试
+    @Test
+    public void testRetry3() {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
+        Assert.assertFalse(response.isSuccess());
+    }
+
+    //单个组件指定异常重试,抛出的是指定异常或者
+    @Test
+    public void testRetry4() {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
+        Assert.assertFalse(response.isSuccess());
+        Assert.assertEquals("e==>e==>e==>e==>e==>e", response.getExecuteStepStr());
+    }
+}

+ 18 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/ACmp.java

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

+ 25 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/BCmp.java

@@ -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.cmpRetry.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class BCmp extends NodeComponent {
+
+	private int flag = 0;
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+		if (flag < 2){
+			flag++;
+			throw new RuntimeException("demo exception");
+		}
+	}
+
+}

+ 22 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/CCmp.java

@@ -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.cmpRetry.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowRetry;
+import com.yomahub.liteflow.core.NodeComponent;
+
+@LiteflowRetry(5)
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+		throw new RuntimeException("demo exception");
+	}
+
+}

+ 22 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/DCmp.java

@@ -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.cmpRetry.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowRetry;
+import com.yomahub.liteflow.core.NodeComponent;
+
+@LiteflowRetry(retry = 5, forExceptions = {NullPointerException.class})
+public class DCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("DCmp executed!");
+		throw new RuntimeException("demo exception");
+	}
+
+}

+ 22 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpRetry/cmp/ECmp.java

@@ -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.cmpRetry.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowRetry;
+import com.yomahub.liteflow.core.NodeComponent;
+
+@LiteflowRetry(retry = 5, forExceptions = {NullPointerException.class})
+public class ECmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ECmp executed!");
+		throw new NullPointerException("demo null exception");
+	}
+
+}

+ 66 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/CmpStepTest.java

@@ -0,0 +1,66 @@
+package com.yomahub.liteflow.test.cmpStep;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.core.FlowExecutorHolder;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.flow.entity.CmpStep;
+import com.yomahub.liteflow.property.LiteflowConfig;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+public class CmpStepTest extends BaseTest{
+
+    private static FlowExecutor flowExecutor;
+
+    @BeforeClass
+    public static void init(){
+        LiteflowConfig config = new LiteflowConfig();
+        config.setRuleSource("cmpStep/flow.el.xml");
+        flowExecutor = FlowExecutorHolder.loadInstance(config);
+    }
+
+    @Test
+    public void testStep1(){
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertFalse(response.isSuccess());
+        Assert.assertTrue(response.getExecuteSteps().get("a").isSuccess());
+        Assert.assertTrue(response.getExecuteSteps().get("b").isSuccess());
+        Assert.assertFalse(response.getExecuteSteps().get("c").isSuccess());
+        Assert.assertFalse(response.getExecuteSteps().get("d").isSuccess());
+        Assert.assertTrue(response.getExecuteSteps().get("c").getTimeSpent() >= 2000);
+        Assert.assertEquals(RuntimeException.class, response.getExecuteSteps().get("c").getException().getClass());
+        Assert.assertEquals(RuntimeException.class, response.getExecuteSteps().get("d").getException().getClass());
+    }
+
+    @Test
+    public void testStep2() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals("a==>b", response.getExecuteStepStrWithoutTime());
+    }
+
+    @Test
+    public void testStep3() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
+        Assert.assertTrue(response.isSuccess());
+        Map<String, CmpStep> stepMap = response.getExecuteSteps();
+        Assert.assertEquals(2, stepMap.size());
+        Queue<CmpStep> queue = response.getExecuteStepQueue();
+        Assert.assertEquals(5, queue.size());
+
+        Set<String> tagSet = new HashSet<>();
+        response.getExecuteStepQueue().stream().filter(
+                cmpStep -> cmpStep.getNodeId().equals("a")
+        ).forEach(cmpStep -> tagSet.add(cmpStep.getTag()));
+
+        Assert.assertEquals(3, tagSet.size());
+
+    }
+}

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/ACmp.java

@@ -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.cmpStep.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class ACmp extends NodeComponent {
+
+	@Override
+	public void process() throws Exception{
+		Thread.sleep(5000L);
+		System.out.println("ACmp executed!");
+	}
+}

+ 19 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/BCmp.java

@@ -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.cmpStep.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class BCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/CCmp.java

@@ -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.cmpStep.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() throws Exception{
+		System.out.println("CCmp executed!");
+		Thread.sleep(2000);
+		throw new RuntimeException("test error c");
+	}
+
+}

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/DCmp.java

@@ -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.cmpStep.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class DCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+		throw new RuntimeException("test error d");
+	}
+
+}

+ 23 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/cmpStep/cmp/ECmp.java

@@ -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.cmpStep.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+
+public class ECmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ECmp executed!");
+	}
+
+	@Override
+	public boolean isAccess() {
+		return false;
+	}
+}

+ 34 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/comments/LiteflowNodeTest.java

@@ -0,0 +1,34 @@
+package com.yomahub.liteflow.test.comments;
+
+import cn.hutool.core.collection.ListUtil;
+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.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * 测试注释
+ */
+public class LiteflowNodeTest extends BaseTest {
+
+	private static FlowExecutor flowExecutor;
+
+	@BeforeClass
+	public static void init(){
+		LiteflowConfig config = new LiteflowConfig();
+		config.setRuleSource("comments/flow.el.xml");
+		flowExecutor = FlowExecutorHolder.loadInstance(config);
+	}
+
+	// 测试注释
+	@Test
+	public void testAsyncFlow1() {
+		LiteflowResponse response = flowExecutor.execute2Resp("chain1", "it's a base request");
+		Assert.assertTrue(response.isSuccess());
+		Assert.assertTrue(ListUtil.toList("a==>b==>c==>b","a==>b==>b==>c").contains(response.getExecuteStepStr()));
+	}
+}

部分文件因为文件数量过多而无法显示