mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 20:22:07 +08:00
bug #I5YEHG 脚本的加载有先后顺序问题
This commit is contained in:
@@ -35,7 +35,8 @@ public abstract class BaseJsonFlowParser implements FlowParser {
|
||||
JsonNode flowJsonNode = JsonUtil.parseObject(content);
|
||||
jsonObjectList.add(flowJsonNode);
|
||||
}
|
||||
ParserHelper.parseJsonNode(jsonObjectList, CHAIN_NAME_SET, this::parseOneChain);
|
||||
ParserHelper.parseNodeJson(jsonObjectList);
|
||||
ParserHelper.parseChainJson(jsonObjectList, CHAIN_NAME_SET, this::parseOneChain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,8 +36,8 @@ public abstract class BaseXmlFlowParser implements FlowParser {
|
||||
documentList.add(document);
|
||||
}
|
||||
|
||||
Consumer<Element> parseOneChainConsumer = this::parseOneChain;
|
||||
ParserHelper.parseDocument(documentList, CHAIN_NAME_SET, parseOneChainConsumer);
|
||||
ParserHelper.parseNodeDocument(documentList);
|
||||
ParserHelper.parseChainDocument(documentList, CHAIN_NAME_SET, this::parseOneChain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,8 @@ public abstract class BaseYmlFlowParser implements FlowParser {
|
||||
}
|
||||
|
||||
Consumer<JsonNode> parseOneChainConsumer = this::parseOneChain;
|
||||
ParserHelper.parseJsonNode(jsonObjectList, CHAIN_NAME_SET,parseOneChainConsumer);
|
||||
ParserHelper.parseNodeJson(jsonObjectList);
|
||||
ParserHelper.parseChainJson(jsonObjectList, CHAIN_NAME_SET, parseOneChainConsumer);
|
||||
}
|
||||
|
||||
protected JsonNode convertToJson(String yamlString) {
|
||||
|
||||
@@ -87,35 +87,9 @@ public class ParserHelper {
|
||||
|
||||
/**
|
||||
* xml 形式的主要解析过程
|
||||
*
|
||||
* @param documentList documentList
|
||||
* @param chainNameSet 用于去重
|
||||
* @param parseOneChainConsumer parseOneChain 函数
|
||||
*/
|
||||
public static void parseDocument(List<Document> documentList, Set<String> chainNameSet, Consumer<Element> parseOneChainConsumer) {
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
documentList.forEach(document -> {
|
||||
// 解析chain节点
|
||||
List<Element> chainList = document.getRootElement().elements(CHAIN);
|
||||
|
||||
//先在元数据里放上chain
|
||||
chainList.forEach(e -> {
|
||||
//校验加载的 chainName 是否有重复的
|
||||
//TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = e.attributeValue(NAME);
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(chainName);
|
||||
});
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
public static void parseNodeDocument(List<Document> documentList) {
|
||||
for (Document document : documentList) {
|
||||
Element rootElement = document.getRootElement();
|
||||
Element nodesElement = rootElement.element(NODES);
|
||||
@@ -143,37 +117,42 @@ public class ParserHelper {
|
||||
ParserHelper.buildNode(nodePropBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//解析每一个chain
|
||||
public static void parseChainDocument(List<Document> documentList, Set<String> chainNameSet, Consumer<Element> parseOneChainConsumer){
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
documentList.forEach(document -> {
|
||||
// 解析chain节点
|
||||
List<Element> chainList = document.getRootElement().elements(CHAIN);
|
||||
|
||||
//先在元数据里放上chain
|
||||
chainList.forEach(e -> {
|
||||
//校验加载的 chainName 是否有重复的
|
||||
//TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = e.attributeValue(NAME);
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(chainName);
|
||||
});
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
//解析每一个chain
|
||||
for (Document document : documentList) {
|
||||
Element rootElement = document.getRootElement();
|
||||
List<Element> chainList = rootElement.elements(CHAIN);
|
||||
chainList.forEach(parseOneChainConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseJsonNode(List<JsonNode> flowJsonObjectList, Set<String> chainNameSet, Consumer<JsonNode> parseOneChainConsumer) {
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
flowJsonObjectList.forEach(jsonObject -> {
|
||||
// 解析chain节点
|
||||
Iterator<JsonNode> iterator = jsonObject.get(FLOW).get(CHAIN).elements();
|
||||
//先在元数据里放上chain
|
||||
while (iterator.hasNext()) {
|
||||
JsonNode innerJsonObject = iterator.next();
|
||||
//校验加载的 chainName 是否有重复的
|
||||
// TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = innerJsonObject.get(NAME).textValue();
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(innerJsonObject.get(NAME).textValue());
|
||||
}
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
public static void parseNodeJson(List<JsonNode> flowJsonObjectList) {
|
||||
for (JsonNode flowJsonNode : flowJsonObjectList) {
|
||||
// 当存在<nodes>节点定义时,解析node节点
|
||||
if (flowJsonNode.get(FLOW).has(NODES)) {
|
||||
@@ -200,7 +179,34 @@ public class ParserHelper {
|
||||
ParserHelper.buildNode(nodePropBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseChainJson(List<JsonNode> flowJsonObjectList, Set<String> chainNameSet, Consumer<JsonNode> parseOneChainConsumer){
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
flowJsonObjectList.forEach(jsonObject -> {
|
||||
// 解析chain节点
|
||||
Iterator<JsonNode> iterator = jsonObject.get(FLOW).get(CHAIN).elements();
|
||||
//先在元数据里放上chain
|
||||
while (iterator.hasNext()) {
|
||||
JsonNode innerJsonObject = iterator.next();
|
||||
//校验加载的 chainName 是否有重复的
|
||||
// TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = innerJsonObject.get(NAME).textValue();
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(innerJsonObject.get(NAME).textValue());
|
||||
}
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
for (JsonNode flowJsonNode : flowJsonObjectList) {
|
||||
//解析每一个chain
|
||||
Iterator<JsonNode> chainIterator = flowJsonNode.get(FLOW).get(CHAIN).elements();
|
||||
while (chainIterator.hasNext()) {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.yomahub.liteflow.test.script.groovy.scriptOrder;
|
||||
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.enums.FlowParserTypeEnum;
|
||||
import com.yomahub.liteflow.flow.FlowBus;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
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.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* 测试springboot下的groovy脚本组件,基于xml配置
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.6.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(value = "classpath:/scriptOrder/application.properties")
|
||||
@SpringBootTest(classes = LiteflowScriptOrderGroovyELTest.class)
|
||||
@EnableAutoConfiguration
|
||||
public class LiteflowScriptOrderGroovyELTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
//测试普通脚本节点
|
||||
@Test
|
||||
public void testScript1() {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
liteflow.rule-source=scriptOrder/flow1.xml,scriptOrder/flow2.xml
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="s1" language="groovy" type="if_script">
|
||||
<![CDATA[
|
||||
System.out.println("Groovy 脚本1 被调用。")
|
||||
return false
|
||||
]]>
|
||||
</node>
|
||||
<node id="s2" language="groovy" type="script">
|
||||
<![CDATA[
|
||||
System.out.println("Groovy 脚本2 被调用。")
|
||||
]]>
|
||||
</node>
|
||||
<node id="s3" language="groovy" type="script">
|
||||
<![CDATA[
|
||||
System.out.println("Groovy 脚本3 被调用。")
|
||||
]]>
|
||||
</node>
|
||||
</nodes>
|
||||
|
||||
<chain name="chain1">
|
||||
// IF(s1, s2, s3);
|
||||
IF(s1, s2, s4);
|
||||
</chain>
|
||||
</flow>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="s4" language="groovy" type="script">
|
||||
<![CDATA[
|
||||
System.out.println("Groovy 脚本4 被调用。")
|
||||
]]>
|
||||
</node>
|
||||
</nodes>
|
||||
</flow>
|
||||
Reference in New Issue
Block a user