mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 12:12:08 +08:00
feature #I4HGOW 支持链路的前置和后置节点
This commit is contained in:
@@ -16,6 +16,7 @@ import com.yomahub.liteflow.entity.data.Slot;
|
||||
import com.yomahub.liteflow.entity.flow.parallel.CompletableFutureTimeout;
|
||||
import com.yomahub.liteflow.entity.flow.parallel.ParallelSupplier;
|
||||
import com.yomahub.liteflow.entity.flow.parallel.WhenFutureObj;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.enums.ExecuteTypeEnum;
|
||||
import com.yomahub.liteflow.exception.FlowSystemException;
|
||||
import com.yomahub.liteflow.exception.WhenExecuteException;
|
||||
@@ -72,15 +73,31 @@ public class Chain implements Executable {
|
||||
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
|
||||
//循环chain里包含的condition,每一个condition有可能是then,也有可能是when
|
||||
//when的话为异步,用闭锁进行等待,所有when结束后才能进入下一个condition
|
||||
for (Condition condition : conditionList) {
|
||||
if (condition instanceof ThenCondition) {
|
||||
for (Executable executableItem : condition.getNodeList()) {
|
||||
//先把finally的节点过滤出来
|
||||
List<Condition> finallyConditionList = conditionList.stream().filter(condition ->
|
||||
condition.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())).collect(Collectors.toList());
|
||||
|
||||
//循环chain里包含的condition,每一个condition分四种类型:pre,then,when,finally
|
||||
//这里conditionList其实已经是有序的,pre一定在最前面,finally一定在最后面
|
||||
try{
|
||||
for (Condition condition : conditionList) {
|
||||
if (condition instanceof PreCondition){
|
||||
for (Executable executableItem : condition.getNodeList()) {
|
||||
executableItem.execute(slotIndex);
|
||||
}
|
||||
} else if (condition instanceof ThenCondition) {
|
||||
for (Executable executableItem : condition.getNodeList()) {
|
||||
executableItem.execute(slotIndex);
|
||||
}
|
||||
} else if (condition instanceof WhenCondition) {
|
||||
executeAsyncCondition((WhenCondition) condition, slotIndex, slot.getRequestId());
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
for (Condition finallyCondition : finallyConditionList){
|
||||
for(Executable executableItem : finallyCondition.getNodeList()){
|
||||
executableItem.execute(slotIndex);
|
||||
}
|
||||
} else if (condition instanceof WhenCondition) {
|
||||
executeAsyncCondition((WhenCondition) condition, slotIndex, slot.getRequestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.entity.flow;
|
||||
|
||||
/**
|
||||
* 前置Condition
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.6.4
|
||||
*/
|
||||
public class FinallyCondition extends Condition {
|
||||
|
||||
public FinallyCondition(Condition condition){
|
||||
super(condition.getNodeList());
|
||||
super.setConditionType(condition.getConditionType());
|
||||
}
|
||||
}
|
||||
@@ -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.entity.flow;
|
||||
|
||||
/**
|
||||
* 前置Condition
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.6.4
|
||||
*/
|
||||
public class PreCondition extends Condition {
|
||||
|
||||
public PreCondition(Condition condition){
|
||||
super(condition.getNodeList());
|
||||
super.setConditionType(condition.getConditionType());
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,12 @@
|
||||
*/
|
||||
package com.yomahub.liteflow.entity.flow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 串行器
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public class ThenCondition extends Condition {
|
||||
|
||||
public ThenCondition(List<Executable> nodeList) {
|
||||
super(nodeList);
|
||||
}
|
||||
|
||||
public ThenCondition(Condition condition){
|
||||
super(condition.getNodeList());
|
||||
super.setConditionType(condition.getConditionType());
|
||||
|
||||
@@ -7,25 +7,12 @@
|
||||
*/
|
||||
package com.yomahub.liteflow.entity.flow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 并行器
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public class WhenCondition extends Condition{
|
||||
|
||||
|
||||
public WhenCondition(List<Executable> nodeList) {
|
||||
super(nodeList);
|
||||
super.setErrorResume(true);
|
||||
}
|
||||
|
||||
public WhenCondition(List<Executable> nodeList, boolean errorResume) {
|
||||
super(nodeList);
|
||||
super.setErrorResume(errorResume);
|
||||
}
|
||||
|
||||
public WhenCondition(Condition condition) {
|
||||
super(condition.getNodeList());
|
||||
super.setConditionType(condition.getConditionType());
|
||||
|
||||
@@ -2,7 +2,9 @@ package com.yomahub.liteflow.enums;
|
||||
|
||||
public enum ConditionTypeEnum {
|
||||
TYPE_THEN("then","then"),
|
||||
TYPE_WHEN("when","when")
|
||||
TYPE_WHEN("when","when"),
|
||||
TYPE_PRE("pre","pre"),
|
||||
TYPE_FINALLY("finally","finally")
|
||||
;
|
||||
private String type;
|
||||
private String name;
|
||||
|
||||
@@ -4,9 +4,8 @@ import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.yomahub.liteflow.entity.flow.Condition;
|
||||
import com.yomahub.liteflow.entity.flow.ThenCondition;
|
||||
import com.yomahub.liteflow.entity.flow.WhenCondition;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.yomahub.liteflow.entity.flow.*;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.exception.ConfigErrorException;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -15,12 +14,10 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 虽则Parser的抽象类,所有的parser需要继承这个抽象类
|
||||
* @author guodongqing
|
||||
* @since 2.5.0
|
||||
*/
|
||||
@@ -28,10 +25,15 @@ public abstract class FlowParser {
|
||||
|
||||
public abstract void parseMain(List<String> pathList) throws Exception;
|
||||
|
||||
public abstract void parse(List<String> contentList) throws Exception ;
|
||||
public abstract void parse(List<String> contentList) throws Exception;
|
||||
|
||||
protected void buildBaseFlowConditions(List<Condition> conditionList,Condition condition){
|
||||
if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_THEN.getType())) {
|
||||
protected void buildConditions(List<Condition> conditionList, Condition condition) {
|
||||
//这里进行合并逻辑
|
||||
//对于then来说,相邻的2个then会合并成一个condition
|
||||
//对于when来说,相同组的when会合并成一个condition,不同组的when还是会拆开
|
||||
if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_PRE.getType())) {
|
||||
conditionList.add(new PreCondition(condition));
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_THEN.getType())) {
|
||||
if (conditionList.size() >= 1 &&
|
||||
CollectionUtil.getLast(conditionList) instanceof ThenCondition) {
|
||||
CollectionUtil.getLast(conditionList).getNodeList().addAll(condition.getNodeList());
|
||||
@@ -46,24 +48,37 @@ public abstract class FlowParser {
|
||||
} else {
|
||||
conditionList.add(new WhenCondition(condition));
|
||||
}
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())) {
|
||||
conditionList.add(new FinallyCondition(condition));
|
||||
}
|
||||
|
||||
//每一次build之后,对conditionList进行排序,pre最前面,finally最后
|
||||
//这里为什么要排序,因为在声明的时候,哪怕有人不把pre放最前,finally放最后,但最终也要确保是正确的顺序
|
||||
CollectionUtil.sort(conditionList, (o1, o2) -> {
|
||||
if (o1.getConditionType().equals(ConditionTypeEnum.TYPE_PRE.getType()) || o2.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())){
|
||||
return -1;
|
||||
} else if (o2.getConditionType().equals(ConditionTypeEnum.TYPE_PRE.getType()) || o1.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据配置的ruleSource查找匹配的资源
|
||||
* 根据配置的ruleSource查找匹配的资源
|
||||
*/
|
||||
protected Resource[] matchRuleResources(final List<String> pathList) throws IOException {
|
||||
protected Resource[] matchRuleResources(final List<String> pathList) throws IOException {
|
||||
Assert.notEmpty(pathList, "rule source must not be null");
|
||||
|
||||
List<Resource> allResource = new ArrayList<>();
|
||||
for (String path : pathList){
|
||||
for (String path : pathList) {
|
||||
String locationPattern = path;
|
||||
if (!locationPattern.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) {
|
||||
locationPattern = ResourceUtils.CLASSPATH_URL_PREFIX + locationPattern;
|
||||
}
|
||||
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||
Resource[] resources = resolver.getResources(locationPattern);
|
||||
if(ArrayUtil.isEmpty(resources)) {
|
||||
if (ArrayUtil.isEmpty(resources)) {
|
||||
throw new ConfigErrorException("config error,please check rule source property");
|
||||
}
|
||||
allResource.addAll(ListUtil.toList(resources));
|
||||
@@ -72,7 +87,7 @@ public abstract class FlowParser {
|
||||
//如果有多个资源,检查资源都是同一个类型,如果出现不同类型的配置,则抛出错误提示
|
||||
Set<String> fileTypeSet = new HashSet<>();
|
||||
allResource.forEach(resource -> fileTypeSet.add(FileUtil.extName(resource.getFilename())));
|
||||
if (fileTypeSet.size() != 1){
|
||||
if (fileTypeSet.size() != 1) {
|
||||
throw new ConfigErrorException("config error,please use the same type of configuration");
|
||||
}
|
||||
|
||||
|
||||
@@ -131,14 +131,13 @@ public abstract class JsonFlowParser extends FlowParser {
|
||||
String condArrayStr;
|
||||
String[] condArray;
|
||||
List<Executable> chainNodeList;
|
||||
List<Condition> conditionList;
|
||||
List<Condition> conditionList = new ArrayList<>();
|
||||
String group;
|
||||
String errorResume;
|
||||
Condition condition;
|
||||
String any;
|
||||
String chainName = chainObject.getString("name");
|
||||
JSONArray conditionArray = chainObject.getJSONArray("condition");
|
||||
conditionList = new ArrayList<>();
|
||||
for (Object o : conditionArray) {
|
||||
JSONObject condObject = (JSONObject) o;
|
||||
String condType = condObject.getString("type");
|
||||
@@ -199,7 +198,7 @@ public abstract class JsonFlowParser extends FlowParser {
|
||||
condition.setAny(any.equals(Boolean.TRUE.toString()));
|
||||
condition.setConditionType(condType);
|
||||
condition.setNodeList(chainNodeList);
|
||||
super.buildBaseFlowConditions(conditionList, condition);
|
||||
super.buildConditions(conditionList, condition);
|
||||
}
|
||||
FlowBus.addChain(chainName, new Chain(chainName, conditionList));
|
||||
}
|
||||
|
||||
@@ -135,10 +135,9 @@ public abstract class XmlFlowParser extends FlowParser {
|
||||
Condition condition;
|
||||
Element condE;
|
||||
List<Executable> chainNodeList;
|
||||
List<Condition> conditionList;
|
||||
List<Condition> conditionList = new ArrayList<>();
|
||||
|
||||
String chainName = e.attributeValue("name");
|
||||
conditionList = new ArrayList<>();
|
||||
for (Iterator<Element> it = e.elementIterator(); it.hasNext(); ) {
|
||||
condE = it.next();
|
||||
condArrayStr = condE.attributeValue("value");
|
||||
@@ -198,7 +197,7 @@ public abstract class XmlFlowParser extends FlowParser {
|
||||
condition.setAny(any.equals(Boolean.TRUE.toString()));
|
||||
condition.setConditionType(condE.getName());
|
||||
condition.setNodeList(chainNodeList);
|
||||
super.buildBaseFlowConditions(conditionList, condition);
|
||||
super.buildConditions(conditionList, condition);
|
||||
}
|
||||
FlowBus.addChain(chainName, new Chain(chainName, conditionList));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user