Merge branch 'v2.5.0-SNAPSHOT' of https://gitee.com/dromara/liteFlow into v2.5.0-SNAPSHOT

This commit is contained in:
tonnyguo
2021-03-31 14:06:01 +08:00
8 changed files with 118 additions and 18 deletions

View File

@@ -0,0 +1,5 @@
package com.yomahub.liteflow.common;
public class LocalDefaultFlowConstant {
public static final String DEFAULT="default";
}

View File

@@ -7,6 +7,8 @@
*/
package com.yomahub.liteflow.entity.flow;
import com.yomahub.liteflow.common.LocalDefaultFlowConstant;
import java.util.List;
/**
@@ -14,6 +16,10 @@ import java.util.List;
* @author Bryan.Zhang
*/
public class Condition {
// 增加errorResume属性以区分当when调用链调用失败时是否继续往下执行 默认true继续执行
private boolean errorResume = true;
// 增加groupId属性用于不同node进行同组合并
private String groupId = LocalDefaultFlowConstant.DEFAULT;
private List<Executable> nodeList;
@@ -28,4 +34,20 @@ public class Condition {
public void setNodeList(List<Executable> nodeList) {
this.nodeList = nodeList;
}
public boolean isErrorResume() {
return errorResume;
}
public void setErrorResume(boolean errorResume) {
this.errorResume = errorResume;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
}

View File

@@ -14,20 +14,16 @@ import java.util.List;
* @author Bryan.Zhang
*/
public class WhenCondition extends Condition{
// 增加errorResume属性以区分当when调用链调用失败时是否继续往下执行
private boolean errorResume;
public WhenCondition(List<Executable> nodeList) {
super(nodeList);
errorResume = true;
super.setErrorResume(true);
}
public WhenCondition(List<Executable> nodeList, boolean errorResume) {
super(nodeList);
this.errorResume = errorResume;
super.setErrorResume(errorResume);
}
public boolean isErrorResume() {
return errorResume;
}
}

View File

@@ -7,12 +7,13 @@ import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.common.LocalDefaultFlowConstant;
import com.yomahub.liteflow.entity.flow.*;
import com.yomahub.liteflow.exception.ExecutableItemNotFoundException;
import com.yomahub.liteflow.exception.ParseException;
import com.yomahub.liteflow.util.SpringAware;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
@@ -90,6 +91,8 @@ public abstract class XmlFlowParser extends FlowParser{
private void parseOneChain(Element e) throws Exception{
String condArrayStr;
String[] condArray;
String group;
String errorResume;
List<Executable> chainNodeList;
List<Condition> conditionList;
@@ -98,9 +101,17 @@ public abstract class XmlFlowParser extends FlowParser{
for (Iterator<Element> it = e.elementIterator(); it.hasNext();) {
Element condE = it.next();
condArrayStr = condE.attributeValue("value");
errorResume = e.attributeValue("errorResume");
group = e.attributeValue("group");
if (StrUtil.isBlank(condArrayStr)) {
continue;
}
if (StrUtil.isBlank(group)) {
group = LocalDefaultFlowConstant.DEFAULT;
}
if (StrUtil.isBlank(errorResume)) {
errorResume = Boolean.TRUE.toString();
}
chainNodeList = new ArrayList<>();
condArray = condArrayStr.split(",");
RegexEntity regexEntity;
@@ -134,14 +145,22 @@ public abstract class XmlFlowParser extends FlowParser{
throw new ExecutableItemNotFoundException(errorMsg);
}
}
if (condE.getName().equals("then")) {
conditionList.add(new ThenCondition(chainNodeList));
if(conditionList.size() > 1 &&
CollectionUtil.getLast(conditionList) instanceof ThenCondition ){
CollectionUtil.getLast(conditionList).getNodeList().addAll(chainNodeList);
}else{
conditionList.add(new ThenCondition(chainNodeList));
}
} else if (condE.getName().equals("when")) {
Attribute errorResume = condE.attribute("errorResume");
if (errorResume != null) {
conditionList.add(new WhenCondition(chainNodeList, errorResume.getValue().equals(Boolean.TRUE.toString())));
} else {
conditionList.add(new WhenCondition(chainNodeList));
if(conditionList.size() > 1 &&
CollectionUtil.getLast(conditionList) instanceof WhenCondition &&
CollectionUtil.getLast(conditionList).getGroupId().equals(group)){
CollectionUtil.getLast(conditionList).getNodeList().addAll(chainNodeList);
}else{
conditionList.add(new WhenCondition(chainNodeList, errorResume.equals(Boolean.TRUE.toString())));
}
}
}

View File

@@ -7,6 +7,9 @@
*/
package com.yomahub.liteflow.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
@@ -16,7 +19,9 @@ import java.util.concurrent.atomic.AtomicLong;
* @author Bryan.Zhang
*/
public class ExecutorHelper {
private static final Logger LOG = LoggerFactory.getLogger(ExecutorHelper.class);
private ExecutorHelper() {
}
@@ -44,7 +49,7 @@ public class ExecutorHelper {
if (!pool.awaitTermination(timeout, TimeUnit.SECONDS)) {
pool.shutdownNow();
if (!pool.awaitTermination(timeout, TimeUnit.SECONDS)) {
System.err.println("Pool did not terminate.");
LOG.error("Pool did not terminate.");
}
}
} catch (InterruptedException ie) {

View File

@@ -3,14 +3,12 @@ package com.yomahub.liteflow.springboot;
import com.yomahub.liteflow.spring.ComponentScaner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* 组件扫描器自动装配类
* @author Bryan.Zhang
*/
@Configuration
@EnableAspectJAutoProxy(exposeProxy = true)
public class LiteflowComponentScannerAutoConfiguration {
@Bean

View File

@@ -0,0 +1,49 @@
package com.yomahub.flowtest.concurrent;
import com.yomahub.liteflow.core.FlowExecutor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static com.yomahub.flowtest.concurrent.ConcurrentCase.caseAssertRandom;
import static com.yomahub.flowtest.concurrent.ConcurrentCase.caseInit;
/**
* 测试流程的顺序执行、并发执行等
* @author justin.xu
*/
@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestGroupIdFlow {
@Resource
private FlowExecutor flowExecutor;
private String init(List<String> steps) {
String requestId = UUID.randomUUID().toString();
caseInit(requestId, steps.stream().map(ConcurrentCase.Routers::new).collect(Collectors.toList()));
return requestId;
}
@Test
public void whenConditionGroupTest() throws Exception {
//由于errorResume即使p5执行失败抛出异常, p7 p8也将会执行
String requestId = init(Arrays.asList("s1", "s2", "s3", "s4", "s5", "s6", "p3", "p4", "p6", "p7", "p8"));
flowExecutor.execute("test-groupId", requestId);
caseAssertRandom(requestId);
}
}

View File

@@ -24,4 +24,10 @@
<chain name="async-concurrent2">
<when value="c6, c7, c8, c9, c10"/> <!-- async = true 表示并行 -->
</chain>
<chain name="test-groupId">
<then value="s1, s2"/> <!-- then表示串行 -->
<when errorResume = "true" value="s3, s4, s5, s6" groupId="g1"/> <!-- 相同groupId errorResume = true -->
<when errorResume = "false" value="p3, p4, p5, p6" groupId="g1"/> <!-- 相同groupId 合并compentent -->
</chain>
</flow>