This commit is contained in:
luoyi
2024-01-15 10:26:02 +08:00
42 changed files with 217 additions and 98 deletions

View File

@@ -22,7 +22,7 @@ public class AndOperator extends BaseOperator<AndOrCondition> {
andOrCondition.setBooleanConditionType(BooleanConditionTypeEnum.AND);
for (Object object : objects){
OperatorHelper.checkObjectMustBeBooleanItem(object);
OperatorHelper.checkObjMustBeBooleanTypeItem(object);
Executable item = OperatorHelper.convert(object, Executable.class);
andOrCondition.addItem(item);

View File

@@ -1,12 +1,8 @@
package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.element.condition.LoopCondition;
/**
@@ -26,8 +22,8 @@ public class BreakOperator extends BaseOperator<LoopCondition> {
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
// 获得需要执行的可执行表达式
OperatorHelper.checkObjMustBeBooleanTypeItem(objects[1]);
Executable breakItem = OperatorHelper.convert(objects[1], Executable.class);
OperatorHelper.checkObjectMustBeBooleanItem(breakItem);
condition.setBreakItem(breakItem);
return condition;
}

View File

@@ -19,6 +19,8 @@ public class CatchOperator extends BaseOperator<CatchCondition> {
public CatchCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEq(objects, 1);
OperatorHelper.checkObjMustBeCommonTypeItem(objects[0]);
Executable catchItem = OperatorHelper.convert(objects[0], Executable.class);
CatchCondition catchCondition = new CatchCondition();

View File

@@ -17,9 +17,13 @@ public class DefaultOperator extends BaseOperator<SwitchCondition> {
public SwitchCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqTwo(objects);
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class);
String errorMsg = "The caller must be SwitchCondition item";
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class, errorMsg);
OperatorHelper.checkObjMustBeCommonTypeItem(objects[1]);
Executable target = OperatorHelper.convert(objects[1], Executable.class);
switchCondition.setDefaultExecutor(target);
return switchCondition;

View File

@@ -24,6 +24,7 @@ public class DoOperator extends BaseOperator<Condition> {
String errorMsg = "The caller must be CatchCondition item";
CatchCondition condition = OperatorHelper.convert(objects[0], CatchCondition.class, errorMsg);
// 获得需要执行的可执行表达式
OperatorHelper.checkObjMustBeCommonTypeItem(objects[1]);
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
condition.setDoItem(doExecutableItem);
return condition;
@@ -33,6 +34,7 @@ public class DoOperator extends BaseOperator<Condition> {
// DO关键字有可能用在FOR后面也有可能用于WHILE后面所以这里要进行判断是不是这两种类型的超类LoopCondition
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
// 获得需要执行的可执行表达式
OperatorHelper.checkObjMustBeCommonTypeItem(objects[1]);
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
condition.setDoExecutor(doExecutableItem);
return condition;

View File

@@ -1,12 +1,8 @@
package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.element.condition.IfCondition;
/**
@@ -22,13 +18,15 @@ public class ElifOperator extends BaseOperator<IfCondition> {
OperatorHelper.checkObjectSizeEqThree(objects);
// 解析caller
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class);
String errorMsg = "The caller must be IfCondition item";
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class, errorMsg);
// 解析第一个参数
OperatorHelper.checkObjMustBeBooleanTypeItem(objects[1]);
Executable ifItem = OperatorHelper.convert(objects[1], Executable.class);
OperatorHelper.checkObjectMustBeBooleanItem(ifItem);
// 解析第二个参数
OperatorHelper.checkObjMustBeCommonTypeItem(objects[2]);
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
// 构建一个内部的IfCondition

View File

@@ -18,8 +18,10 @@ public class ElseOperator extends BaseOperator<IfCondition> {
// 参数只能是1个但这里为什么是2个呢第一个是caller第二个才是参数
OperatorHelper.checkObjectSizeEqTwo(objects);
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class);
String errorMsg = "The caller must be IfCondition item";
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class, errorMsg);
OperatorHelper.checkObjMustBeCommonTypeItem(objects[1]);
Executable elseExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
// 因为当中可能会有多个ELIF所以并不知道这个ELSE前面有没有ELIF

View File

@@ -20,7 +20,9 @@ public class FinallyOperator extends BaseOperator<FinallyCondition> {
FinallyCondition finallyCondition = new FinallyCondition();
for (Object obj : objects) {
finallyCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
OperatorHelper.checkObjMustBeCommonTypeItem(obj);
Executable item = OperatorHelper.convert(obj, Executable.class);
finallyCondition.addExecutable(item);
}
return finallyCondition;
}

View File

@@ -26,10 +26,8 @@ public class ForOperator extends BaseOperator<ForCondition> {
Node node;
if (objects[0] instanceof Node) {
OperatorHelper.checkObjMustBeForTypeItem(objects[0]);
node = OperatorHelper.convert(objects[0], Node.class);
if (!ListUtil.toList(NodeTypeEnum.FOR, NodeTypeEnum.FOR_SCRIPT, NodeTypeEnum.FALLBACK).contains(node.getType())) {
throw new QLException("The parameter must be for-node item");
}
}
else if (objects[0] instanceof Integer) {
Integer forCount = OperatorHelper.convert(objects[0], Integer.class);

View File

@@ -16,7 +16,8 @@ public class IdOperator extends BaseOperator<Condition> {
public Condition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqTwo(objects);
Condition condition = OperatorHelper.convert(objects[0], Condition.class);
String errorMsg = "The caller must be Condition item";
Condition condition = OperatorHelper.convert(objects[0], Condition.class, errorMsg);
String id = OperatorHelper.convert(objects[1], String.class);

View File

@@ -1,15 +1,9 @@
package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
import com.yomahub.liteflow.flow.element.condition.IfCondition;
import com.yomahub.liteflow.flow.element.condition.NotCondition;
/**
* EL规则中的IF的操作符
@@ -24,15 +18,18 @@ public class IfOperator extends BaseOperator<IfCondition> {
OperatorHelper.checkObjectSizeEq(objects, 2, 3);
// 解析第一个参数
OperatorHelper.checkObjMustBeBooleanTypeItem(objects[0]);
Executable ifItem = OperatorHelper.convert(objects[0], Executable.class);
OperatorHelper.checkObjectMustBeBooleanItem(ifItem);
// 解析第二个参数
OperatorHelper.checkObjMustBeCommonTypeItem(objects[1]);
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
// 解析第三个参数,如果有的话
Executable falseCaseExecutableItem = null;
if (objects.length == 3) {
OperatorHelper.checkObjMustBeCommonTypeItem(objects[2]);
falseCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
}

View File

@@ -17,7 +17,8 @@ public class IgnoreErrorOperator extends BaseOperator<WhenCondition> {
public WhenCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqTwo(objects);
WhenCondition condition = OperatorHelper.convert(objects[0], WhenCondition.class);
String errorMsg = "The caller must be WhenCondition item";
WhenCondition condition = OperatorHelper.convert(objects[0], WhenCondition.class, errorMsg);
Boolean ignoreError = OperatorHelper.convert(objects[1], Boolean.class);
condition.setIgnoreError(ignoreError);

View File

@@ -14,10 +14,9 @@ public class IteratorOperator extends BaseOperator<IteratorCondition> {
public IteratorCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEq(objects, 1);
OperatorHelper.checkObjMustBeIteratorTypeItem(objects[0]);
Node node = OperatorHelper.convert(objects[0], Node.class);
if (!ListUtil.toList(NodeTypeEnum.ITERATOR, NodeTypeEnum.FALLBACK).contains(node.getType())) {
throw new QLException("The parameter must be iterator-node item");
}
IteratorCondition iteratorCondition = new IteratorCondition();
iteratorCondition.setIteratorNode(node);

View File

@@ -21,7 +21,8 @@ public class MustOperator extends BaseOperator<WhenCondition> {
public WhenCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeGtTwo(objects);
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
String errorMsg = "The caller must be WhenCondition item";
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class, errorMsg);
// 解析指定完成的任务 ID 集合
Set<String> specifyIdSet = new HashSet<>();

View File

@@ -3,7 +3,7 @@ package com.yomahub.liteflow.builder.el.operator;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.element.FallbackNodeProxy;
import com.yomahub.liteflow.flow.element.FallbackNode;
import com.yomahub.liteflow.flow.element.Node;
/**
@@ -25,7 +25,7 @@ public class NodeOperator extends BaseOperator<Node> {
return FlowBus.getNode(nodeId);
} else {
// 生成代理节点
return new FallbackNodeProxy(nodeId);
return new FallbackNode(nodeId);
}
}

View File

@@ -3,8 +3,6 @@ package com.yomahub.liteflow.builder.el.operator;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
import com.yomahub.liteflow.flow.element.condition.BooleanConditionTypeEnum;
import com.yomahub.liteflow.flow.element.condition.NotCondition;
/**
@@ -20,7 +18,7 @@ public class NotOperator extends BaseOperator<NotCondition> {
OperatorHelper.checkObjectSizeEqOne(objects);
Object object = objects[0];
OperatorHelper.checkObjectMustBeBooleanItem(object);
OperatorHelper.checkObjMustBeBooleanTypeItem(object);
Executable item = OperatorHelper.convert(object, Executable.class);
NotCondition notCondition = new NotCondition();

View File

@@ -22,7 +22,7 @@ public class OrOperator extends BaseOperator<AndOrCondition> {
andOrCondition.setBooleanConditionType(BooleanConditionTypeEnum.OR);
for (Object object : objects){
OperatorHelper.checkObjectMustBeBooleanItem(object);
OperatorHelper.checkObjMustBeBooleanTypeItem(object);
Executable item = OperatorHelper.convert(object, Executable.class);
andOrCondition.addItem(item);

View File

@@ -16,7 +16,8 @@ public class ParallelOperator extends BaseOperator<LoopCondition> {
public LoopCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqTwo(objects);
LoopCondition loopCondition = OperatorHelper.convert(objects[0], LoopCondition.class);
String errorMsg = "The caller must be LoopCondition item";
LoopCondition loopCondition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
Boolean parallel = OperatorHelper.convert(objects[1], Boolean.class);
loopCondition.setParallel(parallel);

View File

@@ -19,6 +19,7 @@ public class PreOperator extends BaseOperator<PreCondition> {
PreCondition preCondition = new PreCondition();
for (Object obj : objects) {
OperatorHelper.checkObjMustBeCommonTypeItem(obj);
preCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
}
return preCondition;

View File

@@ -20,10 +20,8 @@ public class SwitchOperator extends BaseOperator<SwitchCondition> {
public SwitchCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqOne(objects);
OperatorHelper.checkObjMustBeSwitchTypeItem(objects[0]);
Node switchNode = OperatorHelper.convert(objects[0], Node.class);
if (!ListUtil.toList(NodeTypeEnum.SWITCH, NodeTypeEnum.SWITCH_SCRIPT, NodeTypeEnum.FALLBACK).contains(switchNode.getType())) {
throw new QLException("The caller must be Switch item");
}
SwitchCondition switchCondition = new SwitchCondition();
switchCondition.setSwitchNode(switchNode);

View File

@@ -19,6 +19,7 @@ public class ThenOperator extends BaseOperator<ThenCondition> {
ThenCondition thenCondition = new ThenCondition();
for (Object obj : objects) {
OperatorHelper.checkObjMustBeCommonTypeItem(obj);
thenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
}
return thenCondition;

View File

@@ -16,7 +16,8 @@ public class ThreadPoolOperator extends BaseOperator<WhenCondition> {
public WhenCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqTwo(objects);
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
String errorMsg = "The caller must be WhenCondition item";
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class, errorMsg);
whenCondition.setThreadExecutorClass(OperatorHelper.convert(objects[1], String.class));

View File

@@ -17,9 +17,11 @@ public class ToOperator extends BaseOperator<SwitchCondition> {
public SwitchCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeGtTwo(objects);
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class);
String errorMsg = "The caller must be SwitchCondition item";
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class, errorMsg);
for (int i = 1; i < objects.length; i++) {
OperatorHelper.checkObjMustBeCommonTypeItem(objects[i]);
Executable target = OperatorHelper.convert(objects[i], Executable.class);
switchCondition.addTargetItem(target);
}

View File

@@ -4,6 +4,8 @@ import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.condition.WhenCondition;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
/**
* EL规则中的WHEN的操作符
@@ -18,8 +20,12 @@ public class WhenOperator extends BaseOperator<WhenCondition> {
OperatorHelper.checkObjectSizeGtZero(objects);
WhenCondition whenCondition = new WhenCondition();
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
for (Object obj : objects) {
OperatorHelper.checkObjMustBeCommonTypeItem(obj);
whenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
whenCondition.setThreadExecutorClass(liteflowConfig.getThreadExecutorClass());
}
return whenCondition;
}

View File

@@ -1,12 +1,8 @@
package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.element.condition.WhileCondition;
/**
@@ -21,8 +17,8 @@ public class WhileOperator extends BaseOperator<WhileCondition> {
public WhileCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqOne(objects);
OperatorHelper.checkObjMustBeBooleanTypeItem(objects[0]);
Executable whileItem = OperatorHelper.convert(objects[0], Executable.class);
OperatorHelper.checkObjectMustBeBooleanItem(whileItem);
WhileCondition whileCondition = new WhileCondition();
whileCondition.setWhileItem(whileItem);

View File

@@ -3,8 +3,12 @@ package com.yomahub.liteflow.builder.el.operator.base;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.enums.ConditionTypeEnum;
import com.yomahub.liteflow.enums.ExecuteTypeEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.exception.DataNotFoundException;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
import com.yomahub.liteflow.flow.element.condition.NotCondition;
@@ -137,18 +141,100 @@ public class OperatorHelper {
}
}
/**
* 检查对象是否为一个正常可执行的对象。
* 大部分的Node,Condition,Chain都是正常可执行的对象这个检查是为了避免THEN(sw,if)类的情况(sw是选择组件if是条件组件)这种就不能放在THEN里
*/
public static void checkObjMustBeCommonTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
throw new QLException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteTypeEnum.NODE)){
Node node = (Node) item;
if (!ListUtil.toList(NodeTypeEnum.COMMON, NodeTypeEnum.SCRIPT, NodeTypeEnum.FALLBACK).contains(node.getType())){
throw new QLException(StrUtil.format("The node[{}] must be a common type component", node.getId()));
}
}
}
/**
* 所谓Boolean item指的是那些最终的结果值为布尔类型的Item
* 布尔类型的items有ifwhilebreak类型的Node以及AndOrCondition以及NotCondition
*/
public static void checkObjectMustBeBooleanItem(Object object) throws Exception{
if (!(object instanceof Node && ListUtil.toList(
NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT,
NodeTypeEnum.WHILE, NodeTypeEnum.WHILE_SCRIPT,
NodeTypeEnum.BREAK, NodeTypeEnum.BREAK_SCRIPT, NodeTypeEnum.FALLBACK)
.contains(((Node) object).getType())
|| object instanceof AndOrCondition || object instanceof NotCondition)) {
throw new QLException("The first parameter must be boolean type Node or boolean type condition");
public static void checkObjMustBeBooleanTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
throw new QLException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteTypeEnum.NODE)){
Node node = (Node) item;
if (!ListUtil.toList(NodeTypeEnum.IF,
NodeTypeEnum.IF_SCRIPT,
NodeTypeEnum.WHILE,
NodeTypeEnum.WHILE_SCRIPT,
NodeTypeEnum.BREAK,
NodeTypeEnum.BREAK_SCRIPT,
NodeTypeEnum.FALLBACK).contains(node.getType())){
throw new QLException(StrUtil.format("The node[{}] must be boolean type Node.", node.getId()));
}
}else if(item.getExecuteType().equals(ExecuteTypeEnum.CONDITION)){
Condition condition = (Condition) item;
if (!ListUtil.toList(ConditionTypeEnum.TYPE_AND_OR_OPT, ConditionTypeEnum.TYPE_NOT_OPT).contains(condition.getConditionType())){
throw new QLException(StrUtil.format("The condition[{}] must be boolean type Condition.", condition.getId()));
}
}else{
throw new QLException("The parameter error.");
}
}
public static void checkObjMustBeForTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
throw new QLException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteTypeEnum.NODE)){
Node node = (Node) item;
if (!ListUtil.toList(NodeTypeEnum.FOR,
NodeTypeEnum.FOR_SCRIPT,
NodeTypeEnum.FALLBACK).contains(node.getType())){
throw new QLException(StrUtil.format("The node[{}] must be For type Node.", node.getId()));
}
}else{
throw new QLException("The parameter error.");
}
}
public static void checkObjMustBeIteratorTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
throw new QLException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteTypeEnum.NODE)){
Node node = (Node) item;
if (!ListUtil.toList(NodeTypeEnum.ITERATOR,
NodeTypeEnum.FALLBACK).contains(node.getType())){
throw new QLException(StrUtil.format("The node[{}] must be Iterator type Node.", node.getId()));
}
}else{
throw new QLException("The parameter error.");
}
}
public static void checkObjMustBeSwitchTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
throw new QLException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteTypeEnum.NODE)){
Node node = (Node) item;
if (!ListUtil.toList(NodeTypeEnum.SWITCH,
NodeTypeEnum.SWITCH_SCRIPT,
NodeTypeEnum.FALLBACK).contains(node.getType())){
throw new QLException(StrUtil.format("The node[{}] must be Switch type Node.", node.getId()));
}
}else{
throw new QLException("The parameter error.");
}
}
}

View File

@@ -35,8 +35,6 @@ public enum NodeTypeEnum {
ITERATOR("iterator", "循环迭代", false, NodeIteratorComponent.class),
FALLBACK("fallback", "降级", false, null),
SCRIPT("script", "脚本", true, ScriptCommonComponent.class),
SWITCH_SCRIPT("switch_script", "选择脚本", true, ScriptSwitchComponent.class),
@@ -47,7 +45,9 @@ public enum NodeTypeEnum {
WHILE_SCRIPT("while_script", "循环条件脚本", true, ScriptWhileComponent.class),
BREAK_SCRIPT("break_script", "循环跳出脚本", true, ScriptBreakComponent.class);
BREAK_SCRIPT("break_script", "循环跳出脚本", true, ScriptBreakComponent.class),
FALLBACK("fallback", "降级", false, null);
private static final LFLog LOG = LFLoggerManager.getLogger(NodeTypeEnum.class);
@@ -120,7 +120,7 @@ public enum NodeTypeEnum {
}
for (NodeTypeEnum e : NodeTypeEnum.values()) {
if (e.getMappingClazz().equals(superClazz)) {
if (e.getMappingClazz() != null && e.getMappingClazz().equals(superClazz)) {
return e;
}
}

View File

@@ -23,7 +23,7 @@ import com.yomahub.liteflow.slot.Slot;
* @author DaleLee
* @since 2.11.1
*/
public class FallbackNodeProxy extends Node {
public class FallbackNode extends Node {
// 原节点 id
private String expectedNodeId;
@@ -31,11 +31,11 @@ public class FallbackNodeProxy extends Node {
// 降级节点
private Node fallbackNode;
public FallbackNodeProxy() {
public FallbackNode() {
this.setType(NodeTypeEnum.FALLBACK);
}
public FallbackNodeProxy(String expectedNodeId) {
public FallbackNode(String expectedNodeId) {
this();
this.expectedNodeId = expectedNodeId;
}

View File

@@ -39,7 +39,7 @@ public class WhileCondition extends LoopCondition {
int index = 0;
if(!this.isParallel()){
//串行循环
while (getWhileResult(slotIndex)) {
while (getWhileResult(slotIndex, index)) {
executableItem.setCurrChainId(this.getCurrChainId());
setLoopIndex(executableItem, index);
executableItem.execute(slotIndex);
@@ -60,7 +60,7 @@ public class WhileCondition extends LoopCondition {
List<CompletableFuture<LoopFutureObj>> futureList = new ArrayList<>();
//获取并行循环的线程池
ExecutorService parallelExecutor = ExecutorHelper.loadInstance().buildLoopParallelExecutor();
while (getWhileResult(slotIndex)){
while (getWhileResult(slotIndex, index)){
CompletableFuture<LoopFutureObj> future =
CompletableFuture.supplyAsync(new LoopParallelSupplier(executableItem, this.getCurrChainId(), slotIndex, index), parallelExecutor);
futureList.add(future);
@@ -81,10 +81,11 @@ public class WhileCondition extends LoopCondition {
}
}
private boolean getWhileResult(Integer slotIndex) throws Exception {
private boolean getWhileResult(Integer slotIndex, int loopIndex) throws Exception {
Executable whileItem = this.getWhileItem();
// 执行while组件
whileItem.setCurrChainId(this.getCurrChainId());
setLoopIndex(whileItem, loopIndex);
whileItem.execute(slotIndex);
return whileItem.getItemResultMetaValue(slotIndex);

View File

@@ -214,13 +214,6 @@
"description": "Custom thread pool implement for parallel-loop executor.",
"sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty",
"defaultValue": "com.yomahub.liteflow.thread.LiteFlowDefaultParallelLoopExecutorBuilder"
},
{
"name": "liteflow.fallback-cmp-enable",
"type": "java.lang.Boolean",
"description": "Enable fallback component.",
"sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty",
"defaultValue": false
}
]
}

View File

@@ -26,7 +26,7 @@ import javax.annotation.Resource;
@TestPropertySource(value = "classpath:/common/application.properties")
@SpringBootTest(classes = ScriptPythonCommonELTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.test.script.python.common.cmp" })
@ComponentScan({ "com.yomahub.liteflow.test.script.python.common.cmp","com.yomahub.liteflow.test.script.python.common.domain" })
public class ScriptPythonCommonELTest extends BaseTest {
@Resource
@@ -40,6 +40,7 @@ public class ScriptPythonCommonELTest extends BaseTest {
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals(Integer.valueOf(30), context.getData("s1"));
Assertions.assertEquals("杰克", context.getData("name"));
Assertions.assertEquals("hi,jack", context.getData("td"));
}
}

View File

@@ -0,0 +1,13 @@
package com.yomahub.liteflow.test.script.python.common.domain;
import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
@Component
@ScriptBean("td")
public class TestDomain {
public String sayHi(String name){
return "hi," + name;
}
}

View File

@@ -16,10 +16,11 @@
b=10
if a>5:
b=5
print 'hello'
print '你好'.decode('UTF-8')
else:
print 'hi'
defaultContext.setData("s1",a*b)
defaultContext.setData("td", td.sayHi("jack"))
]]>
</node>

View File

@@ -19,6 +19,12 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-el-builder</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -1,5 +1,8 @@
package com.yomahub.liteflow.test.fallback;
import com.yomahub.liteflow.builder.el.ELBus;
import com.yomahub.liteflow.builder.el.ELWrapper;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
@@ -222,4 +225,13 @@ public class FallbackELSpringbootTest extends BaseTest {
String stepStr2 = response2.getExecuteStepStrWithoutTime();
Assertions.assertTrue("c==>ifn2".equals(stepStr2) || "ifn2==>c".equals(stepStr2));
}
@Test
public void testWithElBuild(){
ELWrapper el = ELBus.then("a", "b", "az");
LiteFlowChainELBuilder.createChain().setChainId("elBuilder").setEL(el.toEL()).build();
LiteflowResponse response = flowExecutor.execute2Resp("elBuilder");
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("a==>b==>c", response.getExecuteStepStrWithoutTime());
}
}

View File

@@ -15,7 +15,6 @@ public class CCmp extends NodeComponent {
@Override
public void process() {
System.out.println(this.getLoopIndex());
System.out.println("CCmp executed!");
}

View File

@@ -16,15 +16,7 @@ public class DCmp extends NodeComponent {
@Override
public void process() {
DefaultContext context = this.getFirstContextBean();
String key = "test";
if (context.hasData(key)) {
int count = context.getData(key);
context.setData(key, ++count);
}
else {
context.setData(key, 1);
}
System.out.println("DCmp executed!");
}
}

View File

@@ -10,9 +10,7 @@ public class YCmp extends NodeBreakComponent {
@Override
public boolean processBreak() throws Exception {
DefaultContext context = this.getFirstContextBean();
int count = context.getData("test");
return count > 3;
return this.getLoopIndex() > 2;
}
}

View File

@@ -10,15 +10,7 @@ public class ZCmp extends NodeWhileComponent {
@Override
public boolean processWhile() throws Exception {
DefaultContext context = this.getFirstContextBean();
String key = "test";
if (context.hasData(key)) {
int count = context.getData("test");
return count < 5;
}
else {
return true;
}
return this.getLoopIndex()<5;
}
}

View File

@@ -1,8 +1,13 @@
package com.yomahub.liteflow.test.sql;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.ds.ItemDataSource;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariPoolMXBean;
import com.zaxxer.hikari.pool.HikariPool;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -13,6 +18,11 @@ import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author tangkc
@@ -27,6 +37,7 @@ public class SQLWithXmlELSpringbootTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testSQLWithXml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");

View File

@@ -4,6 +4,9 @@ liteflow.rule-source-ext-data={\
"chainApplicationNameField":"application_name",\
"chainNameField":"chain_name",\
"elDataField":"EL_DATA",\
"pollingEnabled": true,\
"pollingIntervalSeconds": 10,\
"pollingStartSeconds": 5,\
"scriptTableName":"script_node_table",\
"scriptApplicationNameField":"application_name",\
"scriptIdField":"script_node_id",\
@@ -21,11 +24,15 @@ spring.datasource.dynamic.datasource.h2-first.username=root1
spring.datasource.dynamic.datasource.h2-first.password=123456
spring.datasource.dynamic.datasource.h2-first.init.schema=classpath:/sql/schema.sql
spring.datasource.dynamic.datasource.h2-first.init.data=classpath:/sql/data.sql
spring.datasource.dynamic.datasource.h2-first.hikari.min-idle=1
spring.datasource.dynamic.datasource.h2-first.hikari.max-pool-size=5
spring.datasource.dynamic.datasource.h2-second.url=jdbc:h2:mem:test_db2
spring.datasource.dynamic.datasource.h2-second.username=root2
spring.datasource.dynamic.datasource.h2-second.password=123456
spring.datasource.dynamic.datasource.h2-second.init.schema=classpath:/sql/second/schema.sql
spring.datasource.dynamic.datasource.h2-second.init.data=classpath:/sql/second/data.sql
spring.datasource.dynamic.datasource.h2-second.hikari.min-idle=1
spring.datasource.dynamic.datasource.h2-second.hikari.max-pool-size=5

View File

@@ -39,7 +39,7 @@
</scm>
<properties>
<revision>2.11.4-BETA3</revision>
<revision>2.11.4</revision>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>8</maven.compiler.source>