mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 20:22:07 +08:00
enhancement #I6RFOE 在流程(表达式)添加类似tag字段的属性
This commit is contained in:
@@ -4,6 +4,8 @@ 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.flow.FlowBus;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
|
||||
/**
|
||||
@@ -12,19 +14,19 @@ import com.yomahub.liteflow.flow.element.Node;
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public class TagOperator extends BaseOperator<Node> {
|
||||
public class TagOperator extends BaseOperator<Executable> {
|
||||
|
||||
@Override
|
||||
public Node build(Object[] objects) throws Exception {
|
||||
public Executable build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeEqTwo(objects);
|
||||
|
||||
Node node = OperatorHelper.convert(objects[0], Node.class);
|
||||
Executable refObj = OperatorHelper.convert(objects[0], Executable.class);
|
||||
|
||||
String tag = OperatorHelper.convert(objects[1], String.class);
|
||||
|
||||
node.setTag(tag);
|
||||
refObj.setTag(tag);
|
||||
|
||||
return node;
|
||||
return refObj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public class OperatorHelper {
|
||||
public static <T> T convert(Object object, Class<T> clazz, String errorMsg) throws QLException {
|
||||
try {
|
||||
if (clazz.isAssignableFrom(object.getClass())) {
|
||||
if (clazz.equals(Node.class)) {
|
||||
if (object instanceof Node) {
|
||||
Node node = (Node) object;
|
||||
return (T) node.copy();
|
||||
}
|
||||
|
||||
@@ -220,19 +220,6 @@ public class FlowBus {
|
||||
return nodeMap.get(nodeId);
|
||||
}
|
||||
|
||||
// 虽然实现了cloneable,但是还是浅copy,因为condNodeMap这个对象还是共用的。
|
||||
// 那condNodeMap共用有关系么,原则上没有关系。但是从设计理念上,以后应该要分开
|
||||
// tag和condNodeMap这2个属性不属于全局概念,属于每个chain范围的属性
|
||||
public static Node copyNode(String nodeId) {
|
||||
try {
|
||||
Node node = nodeMap.get(nodeId);
|
||||
return node.copy();
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Node> getNodeMap() {
|
||||
return nodeMap;
|
||||
}
|
||||
|
||||
@@ -24,12 +24,14 @@ import java.util.List;
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public class Chain implements Executable {
|
||||
public class Chain implements Executable{
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Chain.class);
|
||||
|
||||
private String chainId;
|
||||
|
||||
private String tag;
|
||||
|
||||
private List<Condition> conditionList = new ArrayList<>();
|
||||
|
||||
public Chain(String chainName) {
|
||||
@@ -115,8 +117,21 @@ public class Chain implements Executable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecuteId() {
|
||||
public void setId(String id) {
|
||||
this.chainId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return chainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,12 @@ import java.util.Map;
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public abstract class Condition implements Executable {
|
||||
public abstract class Condition implements Executable{
|
||||
|
||||
private String id;
|
||||
|
||||
private String tag;
|
||||
|
||||
/**
|
||||
* 可执行元素的集合
|
||||
*/
|
||||
@@ -73,11 +75,6 @@ public abstract class Condition implements Executable {
|
||||
return ExecuteTypeEnum.CONDITION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecuteId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public List<Executable> getExecutableList() {
|
||||
return getExecutableList(ConditionKey.DEFAULT_KEY);
|
||||
}
|
||||
@@ -131,6 +128,15 @@ public abstract class Condition implements Executable {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请使用 {@link #setCurrChainId(String)}
|
||||
*/
|
||||
@@ -151,5 +157,4 @@ public abstract class Condition implements Executable {
|
||||
public Map<String, List<Executable>> getExecutableGroup() {
|
||||
return executableGroup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.yomahub.liteflow.enums.ExecuteTypeEnum;
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public interface Executable {
|
||||
public interface Executable{
|
||||
|
||||
void execute(Integer slotIndex) throws Exception;
|
||||
|
||||
@@ -19,11 +19,11 @@ public interface Executable {
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @deprecated 请使用 {@link #getExecuteId()}
|
||||
* @deprecated 请使用 {@link #getId()}
|
||||
*/
|
||||
@Deprecated
|
||||
default String getExecuteName() {
|
||||
return getExecuteId();
|
||||
return getId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,13 @@ public interface Executable {
|
||||
setCurrChainId(currentChainName);
|
||||
}
|
||||
|
||||
String getExecuteId();
|
||||
void setId(String id);
|
||||
|
||||
String getId();
|
||||
|
||||
void setTag(String tag);
|
||||
|
||||
String getTag();
|
||||
|
||||
default void setCurrChainId(String currentChainId) {
|
||||
|
||||
@@ -43,5 +49,4 @@ public interface Executable {
|
||||
default <T> T getItemResultMetaValue(Integer slotIndex){
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public class Node implements Executable, Cloneable {
|
||||
public class Node implements Executable, Cloneable{
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Node.class);
|
||||
|
||||
@@ -56,9 +56,9 @@ public class Node implements Executable, Cloneable {
|
||||
|
||||
private String currChainId;
|
||||
|
||||
private TransmittableThreadLocal<Integer> loopIndexTL = new TransmittableThreadLocal<>();
|
||||
private final TransmittableThreadLocal<Integer> loopIndexTL = new TransmittableThreadLocal<>();
|
||||
|
||||
private TransmittableThreadLocal<Object> currLoopObject = new TransmittableThreadLocal<>();
|
||||
private final TransmittableThreadLocal<Object> currLoopObject = new TransmittableThreadLocal<>();
|
||||
|
||||
public Node() {
|
||||
|
||||
@@ -72,6 +72,7 @@ public class Node implements Executable, Cloneable {
|
||||
this.clazz = instance.getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -80,6 +81,14 @@ public class Node implements Executable, Cloneable {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -183,33 +192,11 @@ public class Node implements Executable, Cloneable {
|
||||
return instance.isAccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
public Node copy() throws Exception {
|
||||
return (Node) this.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecuteTypeEnum getExecuteType() {
|
||||
return ExecuteTypeEnum.NODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecuteId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getScript() {
|
||||
return script;
|
||||
}
|
||||
@@ -279,4 +266,13 @@ public class Node implements Executable, Cloneable {
|
||||
public <T> T getItemResultMetaValue(Integer slotIndex) {
|
||||
return instance.getItemResultMetaValue(slotIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
public Node copy() throws Exception {
|
||||
return (Node)this.clone();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.*;
|
||||
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.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
/**
|
||||
* 条件Condition
|
||||
@@ -46,7 +42,7 @@ public class IfCondition extends Condition {
|
||||
// trueCaseExecutableItem这个不能为空,否则执行什么呢
|
||||
if (ObjectUtil.isNull(trueCaseExecutableItem)) {
|
||||
String errorInfo = StrUtil.format("[{}]:no if-true node found for the component[{}]",
|
||||
slot.getRequestId(), ifItem.getExecuteId());
|
||||
slot.getRequestId(), ifItem.getId());
|
||||
throw new NoIfTrueNodeException(errorInfo);
|
||||
}
|
||||
|
||||
@@ -55,7 +51,7 @@ public class IfCondition extends Condition {
|
||||
|| trueCaseExecutableItem instanceof FinallyCondition) {
|
||||
String errorInfo = StrUtil.format(
|
||||
"[{}]:if component[{}] error, if true node cannot be pre or finally", slot.getRequestId(),
|
||||
ifItem.getExecuteId());
|
||||
ifItem.getId());
|
||||
throw new IfTargetCannotBePreOrFinallyException(errorInfo);
|
||||
}
|
||||
|
||||
@@ -71,7 +67,7 @@ public class IfCondition extends Condition {
|
||||
|| falseCaseExecutableItem instanceof FinallyCondition) {
|
||||
String errorInfo = StrUtil.format(
|
||||
"[{}]:if component[{}] error, if true node cannot be pre or finally",
|
||||
slot.getRequestId(), ifItem.getExecuteId());
|
||||
slot.getRequestId(), ifItem.getId());
|
||||
throw new IfTargetCannotBePreOrFinallyException(errorInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -59,20 +58,14 @@ public class SwitchCondition extends Condition {
|
||||
String _targetId = target[0];
|
||||
String _targetTag = target[1];
|
||||
targetExecutor = targetList.stream().filter(executable -> {
|
||||
if (executable instanceof Node) {
|
||||
Node node = (Node) executable;
|
||||
return (StrUtil.startWith(_targetId, TAG_PREFIX) && _targetTag.equals(node.getTag()))
|
||||
|| ((StrUtil.isEmpty(_targetId) || _targetId.equals(node.getId()))
|
||||
&& (StrUtil.isEmpty(_targetTag) || _targetTag.equals(node.getTag())));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return (StrUtil.startWith(_targetId, TAG_PREFIX) && _targetTag.equals(executable.getTag()))
|
||||
|| ((StrUtil.isEmpty(_targetId) || _targetId.equals(executable.getId()))
|
||||
&& (StrUtil.isEmpty(_targetTag) || _targetTag.equals(executable.getTag())));
|
||||
}).findFirst().orElse(null);
|
||||
}
|
||||
else {
|
||||
targetExecutor = targetList.stream()
|
||||
.filter(executable -> executable.getExecuteId().equals(targetId))
|
||||
.filter(executable -> executable.getId().equals(targetId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class WhenCondition extends Condition {
|
||||
}
|
||||
})
|
||||
.map(executable -> CompletableFutureTimeout.completeOnTimeout(
|
||||
WhenFutureObj.timeOut(executable.getExecuteId()),
|
||||
WhenFutureObj.timeOut(executable.getId()),
|
||||
CompletableFuture.supplyAsync(new ParallelSupplier(executable, currChainName, slotIndex),
|
||||
parallelExecutor),
|
||||
liteflowConfig.getWhenMaxWaitSeconds(), TimeUnit.SECONDS))
|
||||
|
||||
@@ -32,10 +32,10 @@ public class ParallelSupplier implements Supplier<WhenFutureObj> {
|
||||
try {
|
||||
executableItem.setCurrChainId(currChainId);
|
||||
executableItem.execute(slotIndex);
|
||||
return WhenFutureObj.success(executableItem.getExecuteId());
|
||||
return WhenFutureObj.success(executableItem.getId());
|
||||
}
|
||||
catch (Exception e) {
|
||||
return WhenFutureObj.fail(executableItem.getExecuteId(), e);
|
||||
return WhenFutureObj.fail(executableItem.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,4 +108,11 @@ public class SwitchELSpringbootTest extends BaseTest {
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
}
|
||||
|
||||
// 表达式上设置tag
|
||||
@Test
|
||||
public void testSwitch11() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain12", "arg");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,4 +71,8 @@
|
||||
SWITCH(l.tag("node_3")).TO(a.tag("node_3"), a.tag("node_4"))
|
||||
);
|
||||
</chain>
|
||||
|
||||
<chain name="chain12">
|
||||
SWITCH(l.tag("xx1")).TO(THEN(a,b).tag("xx1"), THEN(a,b,c).tag("xx2"));
|
||||
</chain>
|
||||
</flow>
|
||||
Reference in New Issue
Block a user