diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java
index afb817c92..932cd6b62 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/LiteFlowNodeBuilder.java
@@ -151,7 +151,9 @@ public class LiteFlowNodeBuilder {
}
public LiteFlowNodeBuilder setLanguage(String language) {
- this.node.setLanguage(language);
+ if (StrUtil.isNotBlank(language)){
+ this.node.setLanguage(language);
+ }
return this;
}
diff --git a/liteflow-rule-plugin/liteflow-rule-apollo/src/main/java/com/yomahub/liteflow/parser/apollo/util/ApolloParseHelper.java b/liteflow-rule-plugin/liteflow-rule-apollo/src/main/java/com/yomahub/liteflow/parser/apollo/util/ApolloParseHelper.java
index 197a0dc1a..af965e6da 100644
--- a/liteflow-rule-plugin/liteflow-rule-apollo/src/main/java/com/yomahub/liteflow/parser/apollo/util/ApolloParseHelper.java
+++ b/liteflow-rule-plugin/liteflow-rule-apollo/src/main/java/com/yomahub/liteflow/parser/apollo/util/ApolloParseHelper.java
@@ -166,6 +166,7 @@ public class ApolloParseHelper {
.setType(NodeTypeEnum.getEnumByCode(nodeSimpleVO.getType()))
.setName(nodeSimpleVO.getName())
.setScript(nodeSimpleVO.getScript())
+ .setLanguage(nodeSimpleVO.getLanguage())
.build();
}
// 禁用就删除
diff --git a/liteflow-rule-plugin/liteflow-rule-etcd/src/main/java/com/yomahub/liteflow/parser/etcd/util/EtcdParserHelper.java b/liteflow-rule-plugin/liteflow-rule-etcd/src/main/java/com/yomahub/liteflow/parser/etcd/util/EtcdParserHelper.java
index f58036d5f..9749f9a59 100644
--- a/liteflow-rule-plugin/liteflow-rule-etcd/src/main/java/com/yomahub/liteflow/parser/etcd/util/EtcdParserHelper.java
+++ b/liteflow-rule-plugin/liteflow-rule-etcd/src/main/java/com/yomahub/liteflow/parser/etcd/util/EtcdParserHelper.java
@@ -174,6 +174,7 @@ public class EtcdParserHelper {
.setType(NodeTypeEnum.getEnumByCode(nodeSimpleVO.getType()))
.setName(nodeSimpleVO.getName())
.setScript(nodeSimpleVO.getScript())
+ .setLanguage(nodeSimpleVO.getLanguage())
.build();
}
// 禁用就删除
diff --git a/liteflow-rule-plugin/liteflow-rule-zk/src/main/java/com/yomahub/liteflow/parser/zk/util/ZkParserHelper.java b/liteflow-rule-plugin/liteflow-rule-zk/src/main/java/com/yomahub/liteflow/parser/zk/util/ZkParserHelper.java
index a9811533c..53b6348f2 100644
--- a/liteflow-rule-plugin/liteflow-rule-zk/src/main/java/com/yomahub/liteflow/parser/zk/util/ZkParserHelper.java
+++ b/liteflow-rule-plugin/liteflow-rule-zk/src/main/java/com/yomahub/liteflow/parser/zk/util/ZkParserHelper.java
@@ -1,9 +1,9 @@
package com.yomahub.liteflow.parser.zk.util;
import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.file.FileNameUtil;
+import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
@@ -12,6 +12,7 @@ import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.parser.helper.NodeConvertHelper;
import com.yomahub.liteflow.parser.zk.exception.ZkException;
import com.yomahub.liteflow.parser.zk.vo.ZkParserVO;
+import com.yomahub.liteflow.util.RuleParsePluginUtil;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.CuratorCache;
@@ -26,186 +27,178 @@ import java.util.Objects;
public class ZkParserHelper {
- private static final Logger LOG = LoggerFactory.getLogger(ZkParserHelper.class);
+ private static final Logger LOG = LoggerFactory.getLogger(ZkParserHelper.class);
- private final ZkParserVO zkParserVO;
+ private final ZkParserVO zkParserVO;
- private final CuratorFramework client;
+ private final CuratorFramework client;
- private final String CHAIN_XML_PATTERN = "{}";
+ private final String CHAIN_XML_PATTERN = "{}";
- private final String NODE_XML_PATTERN = "{}";
+ private final String NODE_XML_PATTERN = "{}";
- private final String NODE_ITEM_XML_PATTERN = "";
+ private final String NODE_ITEM_XML_PATTERN = "";
- private final String NODE_ITEM_XML_WITH_LANGUAGE_PATTERN = "";
+ private final String NODE_ITEM_XML_WITH_LANGUAGE_PATTERN = "";
- private final String XML_PATTERN = "{}{}";
+ private final String XML_PATTERN = "{}{}";
- public ZkParserHelper(ZkParserVO zkParserVO) {
- this.zkParserVO = zkParserVO;
+ public ZkParserHelper(ZkParserVO zkParserVO) {
+ this.zkParserVO = zkParserVO;
- try {
- CuratorFramework client = CuratorFrameworkFactory.newClient(zkParserVO.getConnectStr(),
- new RetryNTimes(10, 5000));
- client.start();
+ try {
+ CuratorFramework client = CuratorFrameworkFactory.newClient(zkParserVO.getConnectStr(),
+ new RetryNTimes(10, 5000));
+ client.start();
- this.client = client;
- }
- catch (Exception e) {
- throw new ZkException(e.getMessage());
- }
- }
+ this.client = client;
+ } catch (Exception e) {
+ throw new ZkException(e.getMessage());
+ }
+ }
- public String getContent() {
- try {
- // 检查zk上有没有chainPath节点
- if (client.checkExists().forPath(zkParserVO.getChainPath()) == null) {
- throw new ZkException(StrUtil.format("zk node[{}] is not exist", zkParserVO.getChainPath()));
- }
+ public String getContent() {
+ try {
+ // 检查zk上有没有chainPath节点
+ if (client.checkExists().forPath(zkParserVO.getChainPath()) == null) {
+ throw new ZkException(StrUtil.format("zk node[{}] is not exist", zkParserVO.getChainPath()));
+ }
- // 检查chainPath路径下有没有子节点
- List chainNameList = client.getChildren().forPath(zkParserVO.getChainPath());
- // 获取chainPath路径下的所有子节点内容List
- List chainItemContentList = new ArrayList<>();
- for (String chainName : chainNameList) {
- String chainData = new String(
- client.getData().forPath(StrUtil.format("{}/{}", zkParserVO.getChainPath(), chainName)));
- if (StrUtil.isBlank(chainData)){
- continue;
- }
- chainItemContentList.add(StrUtil.format(CHAIN_XML_PATTERN, chainName, chainData));
- }
- // 合并成所有chain的xml内容
- String chainAllContent = CollUtil.join(chainItemContentList, StrUtil.EMPTY);
+ // 检查chainPath路径下有没有子节点
+ List chainNameList = client.getChildren().forPath(zkParserVO.getChainPath());
+ // 获取chainPath路径下的所有子节点内容List
+ List chainItemContentList = new ArrayList<>();
+ for (String chainName : chainNameList) {
+ RuleParsePluginUtil.ChainDto chainDto = RuleParsePluginUtil.parseChainKey(chainName);
+ String chainData = new String(
+ client.getData().forPath(StrUtil.format("{}/{}", zkParserVO.getChainPath(), chainName)));
+ if (StrUtil.isNotBlank(chainData) && chainDto.isEnable()) {
+ chainItemContentList.add(chainDto.toElXml(chainData));
+ }
+ }
+ // 合并成所有chain的xml内容
+ String chainAllContent = CollUtil.join(chainItemContentList, StrUtil.EMPTY);
- // 检查是否有脚本内容,如果有,进行脚本内容的获取
- String scriptAllContent = StrUtil.EMPTY;
- if (hasScript()) {
- List scriptNodeValueList = client.getChildren().forPath(zkParserVO.getScriptPath());
+ // 检查是否有脚本内容,如果有,进行脚本内容的获取
+ String scriptAllContent = StrUtil.EMPTY;
+ if (hasScript()) {
+ List scriptNodeValueList = client.getChildren().forPath(zkParserVO.getScriptPath());
- List scriptItemContentList = new ArrayList<>();
- for (String scriptNodeValue : scriptNodeValueList) {
- NodeConvertHelper.NodeSimpleVO nodeSimpleVO = NodeConvertHelper.convert(scriptNodeValue);
- if (Objects.isNull(nodeSimpleVO)) {
- throw new ZkException(StrUtil.format("The name of the zk node is invalid:{}", scriptNodeValue));
- }
- String scriptData = new String(client.getData()
- .forPath(StrUtil.format("{}/{}", zkParserVO.getScriptPath(), scriptNodeValue)));
+ List scriptItemContentList = new ArrayList<>();
+ for (String scriptNodeValue : scriptNodeValueList) {
+ NodeConvertHelper.NodeSimpleVO nodeSimpleVO = NodeConvertHelper.convert(scriptNodeValue);
+ if (Objects.isNull(nodeSimpleVO)) {
+ throw new ZkException(StrUtil.format("The name of the zk node is invalid:{}", scriptNodeValue));
+ }
+ String scriptData = new String(client.getData()
+ .forPath(StrUtil.format("{}/{}", zkParserVO.getScriptPath(), scriptNodeValue)));
- // 有语言类型
- if (StrUtil.isNotBlank(nodeSimpleVO.getLanguage())) {
- scriptItemContentList.add(StrUtil.format(NODE_ITEM_XML_WITH_LANGUAGE_PATTERN,
- nodeSimpleVO.getNodeId(), nodeSimpleVO.getName(), nodeSimpleVO.getType(),
- nodeSimpleVO.getLanguage(), scriptData));
- }
- // 没有语言类型
- else {
- scriptItemContentList.add(StrUtil.format(NODE_ITEM_XML_PATTERN, nodeSimpleVO.getNodeId(),
- nodeSimpleVO.getName(), nodeSimpleVO.getType(), scriptData));
- }
- }
+ nodeSimpleVO.setScript(scriptData);
+ scriptItemContentList.add(RuleParsePluginUtil.toScriptXml(nodeSimpleVO));
+ }
- scriptAllContent = StrUtil.format(NODE_XML_PATTERN,
- CollUtil.join(scriptItemContentList, StrUtil.EMPTY));
- }
+ scriptAllContent = StrUtil.format(NODE_XML_PATTERN,
+ CollUtil.join(scriptItemContentList, StrUtil.EMPTY));
+ }
- return StrUtil.format(XML_PATTERN, scriptAllContent, chainAllContent);
- }
- catch (Exception e) {
- throw new ZkException(e.getMessage());
- }
- }
+ return StrUtil.format(XML_PATTERN, scriptAllContent, chainAllContent);
+ } catch (Exception e) {
+ throw new ZkException(e.getMessage());
+ }
+ }
- public boolean hasScript() {
- // 没有配置scriptPath
- if (StrUtil.isBlank(zkParserVO.getScriptPath())) {
- return false;
- }
+ public boolean hasScript() {
+ // 没有配置scriptPath
+ if (StrUtil.isBlank(zkParserVO.getScriptPath())) {
+ return false;
+ }
- try {
- // 配置了,但是不存在这个节点
- if (client.checkExists().forPath(zkParserVO.getScriptPath()) == null) {
- return false;
- }
+ try {
+ // 配置了,但是不存在这个节点
+ if (client.checkExists().forPath(zkParserVO.getScriptPath()) == null) {
+ return false;
+ }
- // 存在这个节点,但是子节点不存在
- List chainNameList = client.getChildren().forPath(zkParserVO.getScriptPath());
- return !CollUtil.isEmpty(chainNameList);
- }
- catch (Exception e) {
- return false;
- }
- }
+ // 存在这个节点,但是子节点不存在
+ List chainNameList = client.getChildren().forPath(zkParserVO.getScriptPath());
+ return !CollUtil.isEmpty(chainNameList);
+ } catch (Exception e) {
+ return false;
+ }
+ }
- /**
- * 监听 zk 节点
- */
- public void listenZkNode() {
- // 监听chain
- CuratorCache cache1 = CuratorCache.build(client, zkParserVO.getChainPath());
- cache1.start();
- cache1.listenable().addListener((type, oldData, data) -> {
- String path = data.getPath();
- String value = new String(data.getData());
- if (StrUtil.isBlank(value)) {
- return;
- }
- if (ListUtil.toList(CuratorCacheListener.Type.NODE_CREATED, CuratorCacheListener.Type.NODE_CHANGED)
- .contains(type)) {
- LOG.info("starting reload flow config... {} path={} value={},", type.name(), path, value);
- String chainName = FileNameUtil.getName(path);
- LiteFlowChainELBuilder.createChain().setChainId(chainName).setEL(value).build();
- }
- else if (CuratorCacheListener.Type.NODE_DELETED.equals(type)) {
- LOG.info("starting reload flow config... delete path={}", path);
- String chainName = FileNameUtil.getName(path);
- FlowBus.removeChain(chainName);
- }
- });
+ /**
+ * 监听 zk 节点
+ */
+ public void listenZkNode() {
+ // 监听chain
+ CuratorCache cache1 = CuratorCache.build(client, zkParserVO.getChainPath());
+ cache1.start();
+ cache1.listenable().addListener((type, oldData, data) -> {
+ String path = data.getPath();
+ String value = new String(data.getData());
+ if (StrUtil.isBlank(value)) {
+ return;
+ }
+ if (ListUtil.toList(CuratorCacheListener.Type.NODE_CREATED, CuratorCacheListener.Type.NODE_CHANGED)
+ .contains(type)) {
+ LOG.info("starting reload flow config... {} path={} value={},", type.name(), path, value);
+ String chainName = FileNameUtil.getName(path);
+ Pair pair = RuleParsePluginUtil.parseIdKey(chainName);
+ String id = pair.getValue();
+ // 如果是启用,就正常更新
+ if (pair.getKey()) {
+ LiteFlowChainELBuilder.createChain().setChainId(id).setEL(value).build();
+ }
+ // 如果是禁用,就删除
+ else {
+ FlowBus.removeChain(id);
+ }
+ } else if (CuratorCacheListener.Type.NODE_DELETED.equals(type)) {
+ LOG.info("starting reload flow config... delete path={}", path);
+ String chainName = FileNameUtil.getName(path);
+ Pair pair = RuleParsePluginUtil.parseIdKey(chainName);
+ FlowBus.removeChain(pair.getValue());
+ }
+ });
- if (StrUtil.isNotBlank(zkParserVO.getScriptPath())) {
- // 监听script
- CuratorCache cache2 = CuratorCache.build(client, zkParserVO.getScriptPath());
- cache2.start();
- cache2.listenable().addListener((type, oldData, data) -> {
- String path = data.getPath();
- String value = new String(data.getData());
- if (StrUtil.isBlank(value)) {
- return;
- }
- if (ListUtil.toList(CuratorCacheListener.Type.NODE_CREATED, CuratorCacheListener.Type.NODE_CHANGED)
- .contains(type)) {
- LOG.info("starting reload flow config... {} path={} value={},", type.name(), path, value);
- String scriptNodeValue = FileNameUtil.getName(path);
- NodeConvertHelper.NodeSimpleVO nodeSimpleVO = NodeConvertHelper.convert(scriptNodeValue);
- // 有语言类型
- if (StrUtil.isNotBlank(nodeSimpleVO.getLanguage())) {
- LiteFlowNodeBuilder.createScriptNode()
- .setId(nodeSimpleVO.getNodeId())
- .setType(NodeTypeEnum.getEnumByCode(nodeSimpleVO.getType()))
- .setName(nodeSimpleVO.getName())
- .setScript(value)
- .setLanguage(nodeSimpleVO.getLanguage())
- .build();
- }
- // 没有语言类型
- else {
- LiteFlowNodeBuilder.createScriptNode()
- .setId(nodeSimpleVO.getNodeId())
- .setType(NodeTypeEnum.getEnumByCode(nodeSimpleVO.getType()))
- .setName(nodeSimpleVO.getName())
- .setScript(value)
- .build();
- }
- }
- else if (CuratorCacheListener.Type.NODE_DELETED.equals(type)) {
- LOG.info("starting reload flow config... delete path={}", path);
- String scriptNodeValue = FileNameUtil.getName(path);
- NodeConvertHelper.NodeSimpleVO nodeSimpleVO = NodeConvertHelper.convert(scriptNodeValue);
- FlowBus.getNodeMap().remove(nodeSimpleVO.getNodeId());
- }
- });
- }
- }
+ if (StrUtil.isNotBlank(zkParserVO.getScriptPath())) {
+ // 监听script
+ CuratorCache cache2 = CuratorCache.build(client, zkParserVO.getScriptPath());
+ cache2.start();
+ cache2.listenable().addListener((type, oldData, data) -> {
+ String path = data.getPath();
+ String value = new String(data.getData());
+ if (StrUtil.isBlank(value)) {
+ return;
+ }
+ if (ListUtil.toList(CuratorCacheListener.Type.NODE_CREATED, CuratorCacheListener.Type.NODE_CHANGED)
+ .contains(type)) {
+ LOG.info("starting reload flow config... {} path={} value={},", type.name(), path, value);
+ String scriptNodeValue = FileNameUtil.getName(path);
+ NodeConvertHelper.NodeSimpleVO nodeSimpleVO = NodeConvertHelper.convert(scriptNodeValue);
+
+ // 启用就正常更新
+ if (nodeSimpleVO.getEnable()) {
+ LiteFlowNodeBuilder.createScriptNode()
+ .setId(nodeSimpleVO.getNodeId())
+ .setType(NodeTypeEnum.getEnumByCode(nodeSimpleVO.getType()))
+ .setName(nodeSimpleVO.getName())
+ .setScript(nodeSimpleVO.getScript())
+ .setLanguage(nodeSimpleVO.getLanguage())
+ .build();
+ }
+ // 禁用就删除
+ else {
+ FlowBus.getNodeMap().remove(nodeSimpleVO.getNodeId());
+ }
+ } else if (CuratorCacheListener.Type.NODE_DELETED.equals(type)) {
+ LOG.info("starting reload flow config... delete path={}", path);
+ String scriptNodeValue = FileNameUtil.getName(path);
+ NodeConvertHelper.NodeSimpleVO nodeSimpleVO = NodeConvertHelper.convert(scriptNodeValue);
+ FlowBus.getNodeMap().remove(nodeSimpleVO.getNodeId());
+ }
+ });
+ }
+ }
}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-zk-springboot/src/test/java/com/yomahub/liteflow/test/zookeeper/ZkNodeWithXmlELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-zk-springboot/src/test/java/com/yomahub/liteflow/test/zookeeper/ZkNodeWithXmlELSpringbootTest.java
index c04891253..0ade361f7 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-zk-springboot/src/test/java/com/yomahub/liteflow/test/zookeeper/ZkNodeWithXmlELSpringbootTest.java
+++ b/liteflow-testcase-el/liteflow-testcase-el-zk-springboot/src/test/java/com/yomahub/liteflow/test/zookeeper/ZkNodeWithXmlELSpringbootTest.java
@@ -1,6 +1,8 @@
package com.yomahub.liteflow.test.zookeeper;
import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.exception.ChainNotFoundException;
+import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
@@ -66,6 +68,10 @@ public class ZkNodeWithXmlELSpringbootTest extends BaseTest {
zkClient.createPersistent(chain2Path, true);
zkClient.writeData(chain2Path, "THEN(a, b, c, s3);");
+ String chain3Path = ZK_CHAIN_PATH + "/chain3:false";
+ zkClient.createPersistent(chain3Path, true);
+ zkClient.writeData(chain3Path, "THEN(a, b, c, s3);");
+
String script1Path = ZK_SCRIPT_PATH + "/s1:script:脚本s1:groovy";
zkClient.createPersistent(script1Path, true);
zkClient.writeData(script1Path, "defaultContext.setData(\"test\",\"hello\");");
@@ -77,6 +83,10 @@ public class ZkNodeWithXmlELSpringbootTest extends BaseTest {
String script3Path = ZK_SCRIPT_PATH + "/s3:script:脚本s3";
zkClient.createPersistent(script3Path, true);
zkClient.writeData(script3Path, "defaultContext.setData(\"test\",\"hello\");");
+
+ String script4Path = ZK_SCRIPT_PATH + "/s4:script:脚本s3:groovy:false";
+ zkClient.createPersistent(script4Path, true);
+ zkClient.writeData(script4Path, "defaultContext.setData(\"test\",\"hello\");");
}
@Test
@@ -94,6 +104,14 @@ public class ZkNodeWithXmlELSpringbootTest extends BaseTest {
DefaultContext context = response.getFirstContextBean();
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("hello", context.getData("test"));
+
+ // 测试 chain 停用
+ Assertions.assertThrows(ChainNotFoundException.class, () -> {
+ throw flowExecutor.execute2Resp("chain3", "arg").getCause();
+ });
+
+ // 测试 script 停用
+ Assertions.assertTrue(!FlowBus.getNodeMap().containsKey("s4"));
}
@AfterAll