diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 0e5505217386f9bfcf8bdb4e32e1f4e3b4ba24de..cb0382d7c1868a6d94bf79e49f1f8509f31e02bb 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -1,7 +1,10 @@ package com.yomahub.liteflow.builder.el; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.*; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.CharUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.ql.util.express.DefaultContext; @@ -30,7 +33,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.function.Consumer; /** * Chain基于代码形式的组装器 EL表达式规则专属组装器 diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java index 02140db44b75063407c0ceefa9f94809d062d4ee..998bd8e416edc4165f96740483215c9154d28aca 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java @@ -8,6 +8,7 @@ package com.yomahub.liteflow.core; import cn.hutool.core.date.StopWatch; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.ttl.TransmittableThreadLocal; @@ -30,6 +31,7 @@ import com.yomahub.liteflow.util.JsonUtil; import java.lang.reflect.Method; import java.util.Date; +import java.util.Optional; /** * 普通组件抽象类 @@ -415,6 +417,44 @@ public abstract class NodeComponent{ return this.refNodeTL.get().getCurrLoopObject(); } + private Optional getParentLoopObj(Node iteratorObject, int currentLayer, int targetLayer) { + if (ObjUtil.isNull(iteratorObject)) { + return Optional.empty(); + } + Node parentIteratorObject = iteratorObject.getParentIteratorObj(); + if (currentLayer >= targetLayer || ObjUtil.isNull(parentIteratorObject) || ObjUtil.isNull(parentIteratorObject.getCurrLoopObject())) { + return Optional.ofNullable(iteratorObject.getCurrLoopObject()); + } + return getParentLoopObj(parentIteratorObject, currentLayer + 1, targetLayer); + } + + private Optional getParentLoopIndex(Node iteratorObject, int currentLayer, int targetLayer) { + if (ObjUtil.isNull(iteratorObject)) { + return Optional.empty(); + } + Node parentIteratorObject = iteratorObject.getParentIteratorObj(); + if (currentLayer >= targetLayer || ObjUtil.isNull(parentIteratorObject) || ObjUtil.isNull(parentIteratorObject.getLoopIndex())) { + return Optional.ofNullable(iteratorObject.getLoopIndex()); + } + return getParentLoopIndex(parentIteratorObject, currentLayer + 1, targetLayer); + } + + public Optional getParentLoopObj(int loopLayer) { + return getParentLoopObj(this.refNodeTL.get().getParentIteratorObj(), 0, loopLayer); + } + + public Optional getParentLoopObj() { + return getParentLoopObj(1); + } + + public Optional getParentLoopIndex(int loopLayer) { + return getParentLoopIndex(this.refNodeTL.get().getParentIteratorObj(), 0, loopLayer); + } + + public Optional getParentLoopIndex() { + return getParentLoopIndex(1); + } + @Deprecated public void invoke(String chainId, Object param) throws Exception { FlowExecutorHolder.loadInstance().invoke(chainId, param, this.getSlotIndex()); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java index 95a65a32e166bec0359769192ad62e0736fa663b..20360690be140a714174c0bcb73a11c701c50871 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java @@ -1,8 +1,6 @@ package com.yomahub.liteflow.core.proxy; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.exceptions.InvocationTargetRuntimeException; -import cn.hutool.core.lang.Tuple; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; @@ -14,9 +12,7 @@ import com.yomahub.liteflow.annotation.LiteflowRetry; import com.yomahub.liteflow.core.NodeComponent; import com.yomahub.liteflow.exception.ComponentMethodDefineErrorException; import com.yomahub.liteflow.exception.LiteFlowException; -import com.yomahub.liteflow.exception.ParameterFactException; import com.yomahub.liteflow.exception.ProxyException; -import com.yomahub.liteflow.flow.element.Node; import com.yomahub.liteflow.log.LFLog; import com.yomahub.liteflow.log.LFLoggerManager; import com.yomahub.liteflow.slot.DataBus; @@ -25,16 +21,14 @@ import net.bytebuddy.ByteBuddy; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.implementation.InvocationHandlerAdapter; import net.bytebuddy.matcher.ElementMatchers; + import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java index 32bed79122eaf048217a990722061d1d6d191cc7..46b45a5f9a73f1ae7f849dc706a0fd02030504fd 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java @@ -17,6 +17,7 @@ import com.yomahub.liteflow.core.ComponentInitializer; import com.yomahub.liteflow.core.NodeComponent; import com.yomahub.liteflow.core.ScriptComponent; import com.yomahub.liteflow.core.proxy.DeclWarpBean; +import com.yomahub.liteflow.core.proxy.LiteFlowProxyUtil; import com.yomahub.liteflow.enums.FlowParserTypeEnum; import com.yomahub.liteflow.enums.NodeTypeEnum; import com.yomahub.liteflow.exception.ComponentCannotRegisterException; @@ -38,7 +39,6 @@ import com.yomahub.liteflow.spi.ContextAware; import com.yomahub.liteflow.spi.holder.ContextAwareHolder; import com.yomahub.liteflow.spi.holder.DeclComponentParserHolder; import com.yomahub.liteflow.util.CopyOnWriteHashMap; -import com.yomahub.liteflow.core.proxy.LiteFlowProxyUtil; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java index 3659586e842f05e84faa900db26118177bad9040..f3c7055c69fe196f0ac92d2b37d93b75d6e15ca6 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java @@ -74,6 +74,9 @@ public class Node implements Executable, Cloneable, Rollbackable{ // isContinueOnError 结果 private TransmittableThreadLocal isContinueOnErrorResult = new TransmittableThreadLocal<>(); + // 主要用于 ITERATOR 关键字获取父循环的对象 + private TransmittableThreadLocal parentIteratorNodeTL = new TransmittableThreadLocal<>(); + public Node() { } @@ -186,7 +189,8 @@ public class Node implements Executable, Cloneable, Rollbackable{ this.getInstance().removeRefNode(); removeSlotIndex(); removeIsEnd(); - removeLoopIndex(); + // 注释掉该方法,避免在 loopCondition 无法正常获取 index,同时其他 condition 无 loop 相关对象设置,只有循环相关 condition 会进行赋值,并且 LoopCondition 执行结束也会执行该方法 +// removeLoopIndex(); removeAccessResult(); removeIsContinueOnErrorResult(); } @@ -290,6 +294,18 @@ public class Node implements Executable, Cloneable, Rollbackable{ this.isContinueOnErrorResult.remove(); } + public Node getParentIteratorObj() { + return parentIteratorNodeTL.get(); + } + + public void setParentIteratorObj(Node iteratorObj) { + this.parentIteratorNodeTL.set(iteratorObj); + } + + public void removeParentIteratorObj() { + this.parentIteratorNodeTL.remove(); + } + public void setLoopIndex(int index) { this.loopIndexTL.set(index); } @@ -360,6 +376,7 @@ public class Node implements Executable, Cloneable, Rollbackable{ node.slotIndexTL = new TransmittableThreadLocal<>(); node.isEndTL = new TransmittableThreadLocal<>(); node.isContinueOnErrorResult = new TransmittableThreadLocal<>(); + node.parentIteratorNodeTL = new TransmittableThreadLocal<>(); return node; } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java index 50f0a56e36e4e89b01eed987e9309d32d8d0dc4e..868da630e73da82beb7e2f3f7851f364576407e4 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java @@ -60,11 +60,17 @@ public class ForCondition extends LoopCondition { executableItem.setCurrChainId(this.getCurrChainId()); // 设置循环index setLoopIndex(executableItem, i); + // 为当前迭代器设置 index + setLoopIndex(forNode, i); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(executableItem, forNode); executableItem.execute(slotIndex); // 如果break组件不为空,则去执行 if (ObjectUtil.isNotNull(breakItem)) { breakItem.setCurrChainId(this.getCurrChainId()); setLoopIndex(breakItem, i); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(breakItem, forNode); breakItem.execute(slotIndex); boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); if (isBreak) { @@ -81,11 +87,13 @@ public class ForCondition extends LoopCondition { for (int i = 0; i < forCount; i++){ //提交异步任务 CompletableFuture future = - CompletableFuture.supplyAsync(new LoopParallelSupplier(executableItem, this.getCurrChainId(), slotIndex, i), parallelExecutor); + CompletableFuture.supplyAsync(new LoopParallelSupplier(executableItem, this.getCurrChainId(), slotIndex, i, null, forNode), parallelExecutor); futureList.add(future); if (ObjectUtil.isNotNull(breakItem)) { breakItem.setCurrChainId(this.getCurrChainId()); setLoopIndex(breakItem, i); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(breakItem, forNode); breakItem.execute(slotIndex); boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); if (isBreak) { @@ -98,6 +106,7 @@ public class ForCondition extends LoopCondition { } } finally { removeLoopIndex(executableItem); + removeParentLoopObject(executableItem); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java index 2a2a640b0bf301f45617ead58e0f902349cf4ca5..5f2ca62ecdff4e967c3e4fe36806902196eb3b83 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java @@ -60,6 +60,12 @@ public class IteratorCondition extends LoopCondition { setLoopIndex(executableItem, index); // 设置循环迭代器对象 setCurrLoopObject(executableItem, itObj); + // 为当前迭代器设置 index + setLoopIndex(iteratorNode, index); + // 为当前迭代器设置对象 + setCurrLoopObject(iteratorNode, itObj); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(executableItem, iteratorNode); // 执行可执行对象 executableItem.execute(slotIndex); // 如果break组件不为空,则去执行 @@ -67,6 +73,8 @@ public class IteratorCondition extends LoopCondition { breakItem.setCurrChainId(this.getCurrChainId()); setLoopIndex(breakItem, index); setCurrLoopObject(breakItem, itObj); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(breakItem, iteratorNode); breakItem.execute(slotIndex); boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); if (isBreak) { @@ -85,13 +93,15 @@ public class IteratorCondition extends LoopCondition { Object itObj = it.next(); //提交异步任务 CompletableFuture future = - CompletableFuture.supplyAsync(new LoopParallelSupplier(executableItem, this.getCurrChainId(), slotIndex, index, itObj), parallelExecutor); + CompletableFuture.supplyAsync(new LoopParallelSupplier(executableItem, this.getCurrChainId(), slotIndex, index, itObj, iteratorNode), parallelExecutor); futureList.add(future); //break判断 if (ObjectUtil.isNotNull(breakItem)) { breakItem.setCurrChainId(this.getCurrChainId()); setLoopIndex(breakItem, index); setCurrLoopObject(breakItem, itObj); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(breakItem, iteratorNode); breakItem.execute(slotIndex); boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); if (isBreak) { @@ -106,6 +116,7 @@ public class IteratorCondition extends LoopCondition { } finally { removeLoopIndex(executableItem); removeCurrLoopObject(executableItem); + removeParentLoopObject(executableItem); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java index 0355ffd3afb43b27be44152b0ee628bf0ac8eb9f..88d2b5e2ce37318cdcfdf5fbd2795b12df1e125e 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java @@ -14,6 +14,7 @@ import java.util.function.Supplier; * 循环Condition的抽象类 主要继承对象有ForCondition和WhileCondition * * @author Bryan.Zhang + * @author luo yi * @since 2.9.0 */ public abstract class LoopCondition extends Condition { @@ -58,6 +59,17 @@ public abstract class LoopCondition extends Condition { } } + protected void setParentLoopObject(Executable executableItem, Node iteratorObj) { + if (executableItem instanceof Chain) { + ((Chain) executableItem).getConditionList().forEach(condition -> setParentLoopObject(condition, iteratorObj)); + } else if (executableItem instanceof Condition) { + ((Condition) executableItem).getExecutableGroup() + .forEach((key, value) -> value.forEach(executable -> setParentLoopObject(executable, iteratorObj))); + } else if (executableItem instanceof Node) { + ((Node) executableItem).setParentIteratorObj(iteratorObj); + } + } + protected void removeLoopIndex(Executable executableItem) { if (executableItem instanceof Chain) { ((Chain) executableItem).getConditionList().forEach(this::removeLoopIndex); @@ -80,6 +92,17 @@ public abstract class LoopCondition extends Condition { } } + protected void removeParentLoopObject(Executable executableItem) { + if (executableItem instanceof Chain) { + ((Chain) executableItem).getConditionList().forEach(this::removeParentLoopObject); + } else if (executableItem instanceof Condition) { + ((Condition) executableItem).getExecutableGroup() + .forEach((key, value) -> value.forEach(this::removeParentLoopObject)); + } else if (executableItem instanceof Node) { + ((Node) executableItem).removeParentIteratorObj(); + } + } + public boolean isParallel() { return parallel; } @@ -108,6 +131,7 @@ public abstract class LoopCondition extends Condition { private final Integer slotIndex; private final Integer loopIndex; private final Object itObj; + private final Node loopNode; public LoopParallelSupplier(Executable executableItem, String currChainId, Integer slotIndex, Integer loopIndex) { this.executableItem = executableItem; @@ -115,14 +139,16 @@ public abstract class LoopCondition extends Condition { this.slotIndex = slotIndex; this.loopIndex = loopIndex; this.itObj = null; + this.loopNode = null; } - public LoopParallelSupplier(Executable executableItem, String currChainId, Integer slotIndex, Integer loopIndex, Object itObj) { + public LoopParallelSupplier(Executable executableItem, String currChainId, Integer slotIndex, Integer loopIndex, Object itObj, Node loopNode) { this.executableItem = executableItem; this.currChainId = currChainId; this.slotIndex = slotIndex; this.loopIndex = loopIndex; this.itObj = itObj; + this.loopNode = loopNode; } @@ -132,10 +158,18 @@ public abstract class LoopCondition extends Condition { executableItem.setCurrChainId(this.currChainId); // 设置循环index setLoopIndex(executableItem, loopIndex); + // 为当前迭代器设置 index + setLoopIndex(loopNode, loopIndex); //IteratorCondition的情况下,需要设置当前循环对象 if(itObj != null){ + // 为当前迭代器设置 object + setCurrLoopObject(loopNode, itObj); setCurrLoopObject(executableItem, itObj); } + // 设置 DO 执行对象中当前所属的 Iterator 对象 + if (loopNode != null) { + setParentLoopObject(executableItem, loopNode); + } executableItem.execute(slotIndex); return LoopFutureObj.success(executableItem.getId()); } catch (Exception e) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java index 0e00e761f53e77f0a973300a5687331578d563e5..dd8a11837cfbfeb95342ab29b74386102393dc9d 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java @@ -3,6 +3,7 @@ package com.yomahub.liteflow.flow.element.condition; import cn.hutool.core.util.ObjectUtil; import com.yomahub.liteflow.enums.ConditionTypeEnum; import com.yomahub.liteflow.flow.element.Executable; +import com.yomahub.liteflow.flow.element.Node; import com.yomahub.liteflow.flow.parallel.LoopFutureObj; import com.yomahub.liteflow.thread.ExecutorHelper; @@ -15,6 +16,7 @@ import java.util.concurrent.ExecutorService; * 循环条件Condition * * @author Bryan.Zhang + * @author luo yi * @since 2.9.0 */ public class WhileCondition extends LoopCondition { @@ -37,49 +39,60 @@ public class WhileCondition extends LoopCondition { // 获取Break节点 Executable breakItem = this.getBreakItem(); - // 循环执行 - int index = 0; - if(!this.isParallel()){ - //串行循环 - while (getWhileResult(slotIndex, index)) { - executableItem.setCurrChainId(this.getCurrChainId()); - setLoopIndex(executableItem, index); - executableItem.execute(slotIndex); - // 如果break组件不为空,则去执行 - if (ObjectUtil.isNotNull(breakItem)) { - breakItem.setCurrChainId(this.getCurrChainId()); - setLoopIndex(breakItem, index); - breakItem.execute(slotIndex); - boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); - if (isBreak) { - break; + try { + // 循环执行 + int index = 0; + if (!this.isParallel()) { + //串行循环 + while (getWhileResult(slotIndex, index)) { + executableItem.setCurrChainId(this.getCurrChainId()); + setLoopIndex(executableItem, index); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(executableItem, (Node) whileItem); + executableItem.execute(slotIndex); + // 如果break组件不为空,则去执行 + if (ObjectUtil.isNotNull(breakItem)) { + breakItem.setCurrChainId(this.getCurrChainId()); + setLoopIndex(breakItem, index); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(breakItem, (Node) whileItem); + breakItem.execute(slotIndex); + boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); + if (isBreak) { + break; + } } + index++; } - index++; - } - }else{ - //并行循环逻辑 - List> futureList = new ArrayList<>(); - //获取并行循环的线程池 - ExecutorService parallelExecutor = ExecutorHelper.loadInstance().buildLoopParallelExecutor(); - while (getWhileResult(slotIndex, index)){ - CompletableFuture future = - CompletableFuture.supplyAsync(new LoopParallelSupplier(executableItem, this.getCurrChainId(), slotIndex, index), parallelExecutor); - futureList.add(future); - //break判断 - if (ObjectUtil.isNotNull(breakItem)) { - breakItem.setCurrChainId(this.getCurrChainId()); - setLoopIndex(breakItem, index); - breakItem.execute(slotIndex); - boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); - if (isBreak) { - break; + } else { + //并行循环逻辑 + List> futureList = new ArrayList<>(); + //获取并行循环的线程池 + ExecutorService parallelExecutor = ExecutorHelper.loadInstance().buildLoopParallelExecutor(); + while (getWhileResult(slotIndex, index)) { + CompletableFuture future = + CompletableFuture.supplyAsync(new LoopParallelSupplier(executableItem, this.getCurrChainId(), slotIndex, index, null, (Node) whileItem), parallelExecutor); + futureList.add(future); + //break判断 + if (ObjectUtil.isNotNull(breakItem)) { + breakItem.setCurrChainId(this.getCurrChainId()); + setLoopIndex(breakItem, index); + // 设置 DO 执行对象中当前所属的 Iterator 对象 + setParentLoopObject(breakItem, (Node) whileItem); + breakItem.execute(slotIndex); + boolean isBreak = breakItem.getItemResultMetaValue(slotIndex); + if (isBreak) { + break; + } } + index++; } - index++; + //等待所有的异步执行完毕 + handleFutureList(futureList); } - //等待所有的异步执行完毕 - handleFutureList(futureList); + } finally { + removeLoopIndex(executableItem); + removeParentLoopObject(executableItem); } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclMultiSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclMultiSpringbootTest.java index 5bbb232058732ec9c7cc8f4e9258967a32bf3839..33ccc6ce2b87d0f9c391f59aba1d8e0ea91db521 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclMultiSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclMultiSpringbootTest.java @@ -6,12 +6,11 @@ import com.yomahub.liteflow.test.BaseTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.context.junit.jupiter.SpringExtension; 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 org.springframework.test.context.junit.jupiter.SpringExtension; import javax.annotation.Resource; diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclSpringbootTest.java index b3b89e891f987eff6c7f2058ec29226a4c13b2b2..16a513b816ebff1b229a64b1adac5880d9d271be 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/base/BaseELDeclSpringbootTest.java @@ -6,12 +6,11 @@ import com.yomahub.liteflow.test.BaseTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.context.junit.jupiter.SpringExtension; 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 org.springframework.test.context.junit.jupiter.SpringExtension; import javax.annotation.Resource; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorCase_IADIXE.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorCase_IADIXE.java index 12b1686f22350bb8eebb369a388c17f2f976b0e7..1986b710dd2b0bb7060974354a83cfe8828ed237 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorCase_IADIXE.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorCase_IADIXE.java @@ -3,7 +3,6 @@ package com.yomahub.liteflow.test.iterator; import cn.hutool.core.collection.ListUtil; 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.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java index cdeb448d01bea09c02ba29d8a6f380e89b872c1c..915d2ecb7b98bcdc34ac082a46e41cffb1d4ba3c 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/IteratorELSpringbootTest.java @@ -11,6 +11,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.TestPropertySource; + import javax.annotation.Resource; import java.util.List; @@ -56,4 +57,19 @@ public class IteratorELSpringbootTest extends BaseTest { LiteflowResponse response = flowExecutor.execute2Resp("chain3"); Assertions.assertTrue(response.isSuccess()); } + + // 多层迭代测试,获取顶层循环对象 + @Test + public void testIt4() throws Exception { + LiteflowResponse response = flowExecutor.execute2Resp("chain4"); + Assertions.assertTrue(response.isSuccess()); + } + + // 多层迭代并行测试,获取顶层循环对象 + @Test + public void testIt5() throws Exception { + LiteflowResponse response = flowExecutor.execute2Resp("chain5"); + Assertions.assertTrue(response.isSuccess()); + } + } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/Br1Cmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/Br1Cmp.java new file mode 100644 index 0000000000000000000000000000000000000000..e220fd6006277fc346244e6a79e026653c33c1cd --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/Br1Cmp.java @@ -0,0 +1,20 @@ +package com.yomahub.liteflow.test.iterator.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeBooleanComponent; + +@LiteflowComponent("br1") +public class Br1Cmp extends NodeBooleanComponent { + + @Override + public boolean processBoolean() throws Exception { + System.out.println("breakCmp get current iterator object : " + this.getCurrLoopObj().toString()); + System.out.println("breakCmp get first layer parent iterator object : " + this.getParentLoopObj().toString()); + System.out.println("breakCmp get second layer parent iterator object : " + this.getParentLoopObj(2).toString()); + System.out.println("breakCmp get current iterator index : " + this.getLoopIndex().toString()); + System.out.println("breakCmp get first layer parent iterator index : " + this.getParentLoopIndex().toString()); + System.out.println("breakCmp get second layer parent iterator index : " + this.getParentLoopIndex(2).toString()); + return false; + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/DCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/DCmp.java index e675f550172c4dba10eb3cddd94e8b731964d79d..ad20914fa3f1408dc4896e7b7595f5775e4a66c1 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/DCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/DCmp.java @@ -9,6 +9,11 @@ public class DCmp extends NodeComponent { @Override public void process() throws Exception { - System.out.println(this.getCurrLoopObj().toString()); + System.out.println("get current iterator object : " + this.getCurrLoopObj().toString()); + System.out.println("get first layer parent iterator object : " + this.getParentLoopObj().toString()); + System.out.println("get second layer parent iterator object : " + this.getParentLoopObj(2).toString()); + System.out.println("get current iterator index : " + this.getLoopIndex().toString()); + System.out.println("get first layer parent iterator index : " + this.getParentLoopIndex().toString()); + System.out.println("get second layer parent iterator index : " + this.getParentLoopIndex(2).toString()); } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/X3Cmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/X3Cmp.java new file mode 100644 index 0000000000000000000000000000000000000000..61208ddf33ebfbdcff20b11f8b2a954695454b45 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/iterator/cmp/X3Cmp.java @@ -0,0 +1,17 @@ +package com.yomahub.liteflow.test.iterator.cmp; + +import cn.hutool.core.collection.ListUtil; +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeIteratorComponent; + +import java.util.Iterator; +import java.util.List; + +@LiteflowComponent("x3") +public class X3Cmp extends NodeIteratorComponent { + @Override + public Iterator processIterator() throws Exception { + List list = ListUtil.toList("-"); + return list.iterator(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/LoopELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/LoopELSpringbootTest.java index ac5916b091ba0357d3a68c74cec38c4da3c42b10..b33b013c38df9b3d766bb4716249f090c4d9710e 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/LoopELSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/LoopELSpringbootTest.java @@ -11,6 +11,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.TestPropertySource; + import javax.annotation.Resource; import java.util.List; @@ -108,4 +109,12 @@ public class LoopELSpringbootTest extends BaseTest { LiteflowResponse response = flowExecutor.execute2Resp("chain9", "arg"); Assertions.assertTrue(response.isSuccess()); } + + // 嵌套循环测试,获取顶层循环下标 + @Test + public void testLoop10() throws Exception { + LiteflowResponse response = flowExecutor.execute2Resp("chain10", "arg"); + Assertions.assertTrue(response.isSuccess()); + } + } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/cmp/Br1Cmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/cmp/Br1Cmp.java new file mode 100644 index 0000000000000000000000000000000000000000..eb48dde0bcdc809626b1cd48299134fd9c412ffc --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/cmp/Br1Cmp.java @@ -0,0 +1,17 @@ +package com.yomahub.liteflow.test.loop.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeBooleanComponent; + +@LiteflowComponent("br1") +public class Br1Cmp extends NodeBooleanComponent { + + @Override + public boolean processBoolean() throws Exception { + System.out.println("breakCmp get current loop index : " + this.getLoopIndex().toString()); + System.out.println("breakCmp get first layer parent loop index : " + this.getParentLoopIndex().toString()); + System.out.println("breakCmp get second layer parent loop index : " + this.getParentLoopIndex(2).toString()); + return false; + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/cmp/GCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/cmp/GCmp.java new file mode 100644 index 0000000000000000000000000000000000000000..b24e3c36509095076796527594a1db7681106ef1 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/loop/cmp/GCmp.java @@ -0,0 +1,16 @@ + +package com.yomahub.liteflow.test.loop.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("g") +public class GCmp extends NodeComponent { + + @Override + public void process() throws Exception { + System.out.println("get current loop index : " + this.getLoopIndex().toString()); + System.out.println("get first layer parent loop index : " + this.getParentLoopIndex().toString()); + System.out.println("get second layer parent loop index : " + this.getParentLoopIndex(2).toString()); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml index a6015d40f0c8e03fd53a0a49d544eca24a4ce383..67fab6cb7b6a5e16f7ee13d8dd82aec67979be41 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/iterator/flow.xml @@ -18,4 +18,32 @@ ); + + + ITERATOR(x1).DO( + THEN( + c, + ITERATOR(x2).DO( + THEN( + c, + ITERATOR(x3).DO(d).BREAK(br1) + ) + ) + ) + ); + + + + ITERATOR(x1).DO( + THEN( + c, + ITERATOR(x2).parallel(true).DO( + THEN( + c, + ITERATOR(x3).DO(d).BREAK(br1) + ) + ) + ) + ); + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/loop/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/loop/flow.xml index 6dcdb59e4818bc2f8ddee14ad8593769acac2808..2afcc3f936a6ee84bd3a457021e7f9c7330f9477 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/loop/flow.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/loop/flow.xml @@ -52,4 +52,13 @@ FOR(2).DO(THEN(c, c, c)); + + + FOR(2).DO( + WHILE(z).DO( + FOR(x).DO(THEN(c, g)).BREAK(br1) + ) + ); + + \ No newline at end of file