!60 chain重名的检测

Merge pull request !60 from 与或非/issues/I5BR5M
This commit is contained in:
铂赛东
2022-06-13 12:57:34 +00:00
committed by Gitee
20 changed files with 176 additions and 55 deletions

View File

@@ -65,13 +65,13 @@ public class FlowExecutor {
DataBus.init();
}
public FlowExecutor(LiteflowConfig liteflowConfig){
public FlowExecutor(LiteflowConfig liteflowConfig) {
this.liteflowConfig = liteflowConfig;
//把liteFlowConfig设到LiteFlowGetter中去
LiteflowConfigGetter.setLiteflowConfig(liteflowConfig);
//设置FlowExecutor的Holder虽然大部分地方都可以通过Spring上下文获取到但放入Holder还是为了某些地方能方便的取到
FlowExecutorHolder.setHolder(this);
if (liteflowConfig.isParseOnStart()){
if (liteflowConfig.isParseOnStart()) {
this.init();
}
//初始化DataBus
@@ -86,7 +86,7 @@ public class FlowExecutor {
throw new ConfigErrorException("config error, please check liteflow config property");
}
if (StrUtil.isBlank(liteflowConfig.getRuleSource())){
if (StrUtil.isBlank(liteflowConfig.getRuleSource())) {
return;
}
@@ -128,7 +128,7 @@ public class FlowExecutor {
throw new ConfigErrorException("parse error, please check liteflow config property");
}
}
} catch (CyclicDependencyException e){
} catch (CyclicDependencyException e) {
LOG.error(e.getMessage());
throw e;
} catch (Exception e) {
@@ -139,22 +139,25 @@ public class FlowExecutor {
}
//单类型的配置文件,需要一起解析
if (!liteflowConfig.isSupportMultipleType()){
if (!liteflowConfig.isSupportMultipleType()) {
//检查Parser是否只有一个因为多个不同的parser会造成子流程的混乱
if (parserNameSet.size() > 1){
if (parserNameSet.size() > 1) {
String errorMsg = "cannot have multiple different parsers";
LOG.error(errorMsg);
throw new MultipleParsersException(errorMsg);
}
//进行多个配置文件的一起解析
try{
try {
if (ObjectUtil.isNotNull(parser)) {
parser.parseMain(rulePathList);
} else {
throw new ConfigErrorException("parse error, please check liteflow config property");
}
} catch (CyclicDependencyException e){
} catch (CyclicDependencyException e) {
LOG.error(e.getMessage());
throw e;
} catch (ChainDuplicateException e) {
LOG.error(e.getMessage());
throw e;
} catch (Exception e) {
@@ -270,7 +273,7 @@ public class FlowExecutor {
this.execute(chainId, param, null, slotIndex, true);
}
public <T> LiteflowResponse<T> invoke2Resp(String chainId, Object param, Integer slotIndex){
public <T> LiteflowResponse<T> invoke2Resp(String chainId, Object param, Integer slotIndex) {
return this.execute2Resp(chainId, param, null, slotIndex, true);
}
@@ -293,7 +296,7 @@ public class FlowExecutor {
}
private <T> T execute(String chainId, Object param, Class<T> contextBeanClazz,
Integer slotIndex, boolean isInnerChain) throws Exception {
Integer slotIndex, boolean isInnerChain) throws Exception {
Slot<T> slot = this.doExecute(chainId, param, contextBeanClazz, slotIndex, isInnerChain);
if (ObjectUtil.isNotNull(slot.getException())) {
throw slot.getException();
@@ -338,14 +341,14 @@ public class FlowExecutor {
}
private <T> Slot<T> doExecute(String chainId, Object param, Class<T> contextBeanClazz, Integer slotIndex,
boolean isInnerChain) {
boolean isInnerChain) {
if (FlowBus.needInit()) {
init();
}
if (!isInnerChain && ObjectUtil.isNull(slotIndex)) {
slotIndex = DataBus.offerSlot(contextBeanClazz);
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())){
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
LOG.info("slot[{}] offered", slotIndex);
}
}
@@ -361,17 +364,17 @@ public class FlowExecutor {
if (StrUtil.isBlank(slot.getRequestId())) {
slot.generateRequestId();
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())){
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
LOG.info("requestId[{}] has generated", slot.getRequestId());
}
}
if (!isInnerChain) {
if (ObjectUtil.isNotNull(param)){
if (ObjectUtil.isNotNull(param)) {
slot.setRequestData(param);
}
} else {
if (ObjectUtil.isNotNull(param)){
if (ObjectUtil.isNotNull(param)) {
slot.setChainReqData(chainId, param);
}
}
@@ -387,12 +390,12 @@ public class FlowExecutor {
// 执行chain
chain.execute(slotIndex);
} catch (ChainEndException e) {
if (ObjectUtil.isNotNull(chain)){
if (ObjectUtil.isNotNull(chain)) {
String warnMsg = StrUtil.format("[{}]:chain[{}] execute end on slot[{}]", slot.getRequestId(), chain.getChainName(), slotIndex);
LOG.warn(warnMsg);
}
} catch (Exception e) {
if (ObjectUtil.isNotNull(chain)){
if (ObjectUtil.isNotNull(chain)) {
String errMsg = StrUtil.format("[{}]:chain[{}] execute error on slot[{}]", slot.getRequestId(), chain.getChainName(), slotIndex);
LOG.error(errMsg, e);
}

View File

@@ -0,0 +1,29 @@
package com.yomahub.liteflow.exception;
/**
* Chain 重复异常
*
* @author tangkc
*/
public class ChainDuplicateException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 异常信息
*/
private String message;
public ChainDuplicateException(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -9,12 +9,15 @@ import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
import com.yomahub.liteflow.builder.prop.ChainPropBean;
import com.yomahub.liteflow.builder.prop.NodePropBean;
import com.yomahub.liteflow.enums.ConditionTypeEnum;
import com.yomahub.liteflow.exception.ChainDuplicateException;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.spi.holder.ContextCmpInitHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import static com.yomahub.liteflow.common.ChainConstant.ANY;
import static com.yomahub.liteflow.common.ChainConstant.CHAIN;
@@ -42,6 +45,8 @@ public abstract class JsonFlowParser extends BaseFlowParser {
private final Logger LOG = LoggerFactory.getLogger(JsonFlowParser.class);
private final Set<String> CHAIN_NAME_SET = new CopyOnWriteArraySet<>();
public void parse(String content) throws Exception {
parse(ListUtil.toList(content));
}
@@ -80,9 +85,18 @@ public abstract class JsonFlowParser extends BaseFlowParser {
//先在元数据里放上chain
chainArray.forEach(o -> {
JSONObject innerJsonObject = (JSONObject) o;
// 校验加载的 chainName 是否有重复的
String chainName = innerJsonObject.getString(NAME);
if (!CHAIN_NAME_SET.add(chainName)) {
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
}
FlowBus.addChain(innerJsonObject.getString(NAME));
});
});
// 清空
CHAIN_NAME_SET.clear();
for (JSONObject flowJsonObject : flowJsonObjectList) {
// 当存在<nodes>节点定义时解析node节点

View File

@@ -7,6 +7,7 @@ import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
import com.yomahub.liteflow.builder.prop.ChainPropBean;
import com.yomahub.liteflow.builder.prop.NodePropBean;
import com.yomahub.liteflow.enums.ConditionTypeEnum;
import com.yomahub.liteflow.exception.ChainDuplicateException;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.spi.holder.ContextCmpInitHolder;
import org.dom4j.Document;
@@ -17,6 +18,8 @@ import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import static com.yomahub.liteflow.common.ChainConstant.ANY;
import static com.yomahub.liteflow.common.ChainConstant.CHAIN;
@@ -43,6 +46,8 @@ public abstract class XmlFlowParser extends BaseFlowParser {
private final Logger LOG = LoggerFactory.getLogger(XmlFlowParser.class);
private final Set<String> CHAIN_NAME_SET = new CopyOnWriteArraySet<>();
public void parse(String content) throws Exception {
parse(ListUtil.toList(content));
}
@@ -76,8 +81,19 @@ public abstract class XmlFlowParser extends BaseFlowParser {
List<Element> chainList = document.getRootElement().elements(CHAIN);
//先在元数据里放上chain
chainList.forEach(e -> FlowBus.addChain(e.attributeValue(NAME)));
chainList.forEach(e -> {
// 校验加载的 chainName 是否有重复的
String chainName = e.attributeValue(NAME);
if (!CHAIN_NAME_SET.add(chainName)) {
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
}
FlowBus.addChain(chainName);
});
});
// 清空
CHAIN_NAME_SET.clear();
for (Document document : documentList) {
Element rootElement = document.getRootElement();

View File

@@ -1,26 +1,17 @@
package com.yomahub.liteflow.test.exception;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.exception.ChainNotFoundException;
import com.yomahub.liteflow.exception.ChainDuplicateException;
import com.yomahub.liteflow.exception.ConfigErrorException;
import com.yomahub.liteflow.exception.FlowExecutorNotInitException;
import com.yomahub.liteflow.exception.FlowSystemException;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ReflectionUtils;
import javax.annotation.Resource;
@@ -34,10 +25,20 @@ import javax.annotation.Resource;
@SpringBootTest(classes = Exception1SpringBootTest.class)
@EnableAutoConfiguration
public class Exception1SpringBootTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
/**
* 验证 chain 节点重复的异常
*/
@Test(expected = ChainDuplicateException.class)
public void testChainDuplicateException() {
LiteflowConfig config = LiteflowConfigGetter.get();
config.setRuleSource("exception/flow-exception.xml");
flowExecutor.init();
}
@Test(expected = ConfigErrorException.class)
public void testConfigErrorException() {
flowExecutor.setLiteflowConfig(null);

View File

@@ -26,7 +26,7 @@ public class SpringELSupportSpringbootTest extends BaseTest {
//测试springEL的解析情况
@Test
public void testSpringELParser() {
LiteflowResponse<DefaultContext> response = flowExecutor.execute2Resp("chain1", "arg");
LiteflowResponse<DefaultContext> response = flowExecutor.execute2Resp("chain11", "arg");
Assert.assertTrue(response.isSuccess());
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
</flow>

View File

@@ -10,13 +10,13 @@
<node id="g" class="com.yomahub.liteflow.test.parser.cmp.GCmp"/>
</nodes>
<chain name="chain1">
<chain name="chain11">
<then value="a,c"/>
<when value="b,d,e(f|g)"/>
<then value="chain2"/>
</chain>
<chain name="chain2">
<chain name="chain12">
<then value="c,g,f"/>
</chain>
</flow>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<chain name="chain21">
<then value="a,c"/>
<when value="b,d,e(f|g)"/>
<then value="chain2"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain2">
<chain name="chain32">
<then value="c,g,f"/>
</chain>
</flow>

View File

@@ -2,16 +2,12 @@ package com.yomahub.liteflow.test.exception;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.FlowExecutorHolder;
import com.yomahub.liteflow.exception.ChainNotFoundException;
import com.yomahub.liteflow.exception.ChainDuplicateException;
import com.yomahub.liteflow.exception.ConfigErrorException;
import com.yomahub.liteflow.exception.FlowExecutorNotInitException;
import com.yomahub.liteflow.exception.FlowSystemException;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -33,6 +29,16 @@ public class Exception1Test extends BaseTest {
flowExecutor = FlowExecutorHolder.loadInstance(config);
}
/**
* 验证 chain 节点重复的异常
*/
@Test(expected = ChainDuplicateException.class)
public void testChainDuplicateException() {
LiteflowConfig config = LiteflowConfigGetter.get();
config.setRuleSource("exception/flow-exception.xml");
flowExecutor.init();
}
@Test(expected = ConfigErrorException.class)
public void testConfigErrorException() {
flowExecutor.setLiteflowConfig(null);

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
</flow>

View File

@@ -1,26 +1,17 @@
package com.yomahub.liteflow.test.exception;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.exception.ChainNotFoundException;
import com.yomahub.liteflow.exception.ChainDuplicateException;
import com.yomahub.liteflow.exception.ConfigErrorException;
import com.yomahub.liteflow.exception.FlowExecutorNotInitException;
import com.yomahub.liteflow.exception.FlowSystemException;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ReflectionUtils;
import javax.annotation.Resource;
@@ -34,10 +25,20 @@ import javax.annotation.Resource;
@SpringBootTest(classes = Exception1SpringBootTest.class)
@EnableAutoConfiguration
public class Exception1SpringBootTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
/**
* 验证 chain 节点重复的异常
*/
@Test(expected = ChainDuplicateException.class)
public void testChainDuplicateException() {
LiteflowConfig config = LiteflowConfigGetter.get();
config.setRuleSource("exception/flow-exception.xml");
flowExecutor.init();
}
@Test(expected = ConfigErrorException.class)
public void testConfigErrorException() {
flowExecutor.setLiteflowConfig(null);

View File

@@ -26,7 +26,7 @@ public class SpringELSupportSpringbootTest extends BaseTest {
//测试springEL的解析情况
@Test
public void testSpringELParser() {
LiteflowResponse<DefaultContext> response = flowExecutor.execute2Resp("chain1", "arg");
LiteflowResponse<DefaultContext> response = flowExecutor.execute2Resp("chain11", "arg");
Assert.assertTrue(response.isSuccess());
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
</flow>

View File

@@ -10,13 +10,13 @@
<node id="g" class="com.yomahub.liteflow.test.parser.cmp.GCmp"/>
</nodes>
<chain name="chain1">
<chain name="chain11">
<then value="a,c"/>
<when value="b,d,e(f|g)"/>
<then value="chain2"/>
</chain>
<chain name="chain2">
<chain name="chain12">
<then value="c,g,f"/>
</chain>
</flow>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<chain name="chain21">
<then value="a,c"/>
<when value="b,d,e(f|g)"/>
<then value="chain2"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain2">
<chain name="chain32">
<then value="c,g,f"/>
</chain>
</flow>

View File

@@ -1,6 +1,7 @@
package com.yomahub.liteflow.test.exception;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.exception.ChainDuplicateException;
import com.yomahub.liteflow.exception.ConfigErrorException;
import com.yomahub.liteflow.exception.FlowExecutorNotInitException;
import com.yomahub.liteflow.property.LiteflowConfig;
@@ -26,6 +27,16 @@ public class Exception1SpringTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
/**
* 验证 chain 节点重复的异常
*/
@Test(expected = ChainDuplicateException.class)
public void testChainDuplicateException() {
LiteflowConfig config = LiteflowConfigGetter.get();
config.setRuleSource("exception/flow-exception.xml");
flowExecutor.init();
}
@Test(expected = ConfigErrorException.class)
public void testConfigErrorException() {
flowExecutor.setLiteflowConfig(null);

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
</flow>