enhancement #I5QMDZ 把Zk存储的支持拆出来作为插件解耦合

This commit is contained in:
everywhere.z 2022-09-11 15:03:07 +08:00
parent 50bcd7039a
commit f3b8993457
130 changed files with 377 additions and 3215 deletions

View File

@ -40,28 +40,6 @@
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>

View File

@ -19,6 +19,7 @@ import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.id.IdGeneratorHolder;
import com.yomahub.liteflow.parser.base.FlowParser;
import com.yomahub.liteflow.parser.factory.FlowParserProvider;
import com.yomahub.liteflow.parser.spi.ParserClassNameSpi;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.slot.DataBus;
@ -29,10 +30,7 @@ import com.yomahub.liteflow.thread.ExecutorHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.concurrent.Future;
/**
@ -84,10 +82,19 @@ public class FlowExecutor {
//进行id生成器的初始化
IdGeneratorHolder.init();
//如果没有配置规则文件路径就停止初始化
//规则文件路径不是一定要有因为liteflow分基于规则和基于代码两种有可能是动态代码构建的
if (StrUtil.isBlank(liteflowConfig.getRuleSource())) {
return;
//查看有没有Parser的SPI实现
//所有的Parser的SPI实现都是以custom形式放入的且只支持xml形式
ServiceLoader<ParserClassNameSpi> loader = ServiceLoader.load(ParserClassNameSpi.class);
Iterator<ParserClassNameSpi> it = loader.iterator();
if (it.hasNext()){
ParserClassNameSpi parserClassNameSpi = it.next();
liteflowConfig.setRuleSource("el_xml:" + parserClassNameSpi.getSpiClassName());
}else{
//ruleSource为空而且没有spi形式的扩展那么说明真的没有ruleSource
//这种情况有可能是基于代码动态构建的
return;
}
}
//如果有前缀的则不需要再进行分割了说明是一个整体

View File

@ -1,23 +0,0 @@
package com.yomahub.liteflow.parser;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.base.BaseZookeeperJsonFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
/**
* 基于zk方式的json形式的解析器
* @author guodongqing
* @since 2.5.0
*/
public class ZookeeperJsonFlowParser extends BaseZookeeperJsonFlowParser {
public ZookeeperJsonFlowParser(String node) {
super(node);
}
@Override
public void parseOneChain(JsonNode chainObject) {
ParserHelper.parseOneChain(chainObject);
}
}

View File

@ -1,21 +0,0 @@
package com.yomahub.liteflow.parser;
import com.yomahub.liteflow.parser.base.BaseZookeeperXmlFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
import org.dom4j.Element;
/**
* 基于zk方式的xml形式的解析器
* @author Bryan.Zhang
*/
public class ZookeeperXmlFlowParser extends BaseZookeeperXmlFlowParser {
public ZookeeperXmlFlowParser(String node) {
super(node);
}
@Override
public void parseOneChain(Element chain) {
ParserHelper.parseOneChain(chain);
}
}

View File

@ -1,22 +0,0 @@
package com.yomahub.liteflow.parser;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.base.BaseZookeeperYmlFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
/**
* 基于zk方式的yml形式的解析器
*
* @author guodongqing
* @since 2.5.0
*/
public class ZookeeperYmlFlowParser extends BaseZookeeperYmlFlowParser {
public ZookeeperYmlFlowParser(String node) {
super(node);
}
@Override
public void parseOneChain(JsonNode chain) {
ParserHelper.parseOneChain(chain);
}
}

View File

@ -1,58 +0,0 @@
package com.yomahub.liteflow.parser.base;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.ZookeeperJsonFlowParser;
import com.yomahub.liteflow.parser.helper.ZkParserHelper;
import org.apache.curator.framework.CuratorFramework;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.function.Consumer;
/**
* 基类用于存放 ZookeeperJsonFlowParser 通用方法
*
* @author tangkc
*/
public abstract class BaseZookeeperJsonFlowParser extends BaseJsonFlowParser {
private static final Logger LOG = LoggerFactory.getLogger(ZookeeperJsonFlowParser.class);
private final String nodePath;
private final ZkParserHelper zkParserHelper;
public BaseZookeeperJsonFlowParser(String node) {
nodePath = node;
Consumer<String> parseConsumer = t -> {
try {
parse(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
zkParserHelper = new ZkParserHelper(nodePath, parseConsumer);
}
@Override
public void parseMain(List<String> pathList) throws Exception {
CuratorFramework client = zkParserHelper.getZkCuratorFramework(pathList);
String content = new String(client.getData().forPath(nodePath));
zkParserHelper.checkContent(content);
parse(content);
zkParserHelper.listenZkNode(client);
}
/**
* 解析一个chain的过程
*
* @param chainObject chain 节点
*/
@Override
public abstract void parseOneChain(JsonNode chainObject);
}

View File

@ -1,58 +0,0 @@
package com.yomahub.liteflow.parser.base;
import com.yomahub.liteflow.parser.ZookeeperXmlFlowParser;
import com.yomahub.liteflow.parser.helper.ZkParserHelper;
import org.apache.curator.framework.CuratorFramework;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.function.Consumer;
/**
* 基类用于存放 ZookeeperXmlFlowELParser 通用方法
*
* @author tangkc
*/
public abstract class BaseZookeeperXmlFlowParser extends BaseXmlFlowParser {
private static final Logger LOG = LoggerFactory.getLogger(ZookeeperXmlFlowParser.class);
private final String nodePath;
private final ZkParserHelper zkParserHelper;
public BaseZookeeperXmlFlowParser(String node) {
nodePath = node;
Consumer<String> parseConsumer = t -> {
try {
parse(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
zkParserHelper = new ZkParserHelper(nodePath, parseConsumer);
}
@Override
public void parseMain(List<String> pathList) throws Exception {
CuratorFramework client = zkParserHelper.getZkCuratorFramework(pathList);
String content = new String(client.getData().forPath(nodePath));
zkParserHelper.checkContent(content);
parse(content);
zkParserHelper.listenZkNode(client);
}
/**
* 解析一个chain的过程
*
* @param chain 节点
*/
@Override
public abstract void parseOneChain(Element chain);
}

View File

@ -1,60 +0,0 @@
package com.yomahub.liteflow.parser.base;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.helper.ZkParserHelper;
import org.apache.curator.framework.CuratorFramework;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.function.Consumer;
/**
* 基类用于存放 ZookeeperYmlFlowELParser 通用方法
*
* @author tangkc
*/
public abstract class BaseZookeeperYmlFlowParser extends BaseYmlFlowParser{
private static final Logger LOG = LoggerFactory.getLogger(BaseZookeeperYmlFlowParser.class);
private final String nodePath;
private final ZkParserHelper zkParserHelper;
public BaseZookeeperYmlFlowParser(String node) {
nodePath = node;
Consumer<String> parseConsumer = t -> {
try {
parse(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
zkParserHelper = new ZkParserHelper(nodePath, parseConsumer);
}
@Override
public void parseMain(List<String> pathList) throws Exception {
CuratorFramework client = zkParserHelper.getZkCuratorFramework(pathList);
String content = new String(client.getData().forPath(nodePath));
zkParserHelper.checkContent(content);
JsonNode ruleObject = convertToJson(content);
parse(ruleObject.toString());
zkParserHelper.listenZkNode(client);
}
/**
* 解析一个 chain 的过程
*
* @param chain chain
*/
@Override
public abstract void parseOneChain(JsonNode chain);
}

View File

@ -1,23 +0,0 @@
package com.yomahub.liteflow.parser.el;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.base.BaseZookeeperJsonFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
/**
* 基于zk方式的json形式的解析器
* @author guodongqing
* @since 2.5.0
*/
public class ZookeeperJsonFlowELParser extends BaseZookeeperJsonFlowParser {
public ZookeeperJsonFlowELParser(String node) {
super(node);
}
@Override
public void parseOneChain(JsonNode chainObject) {
ParserHelper.parseOneChainEl(chainObject);
}
}

View File

@ -1,22 +0,0 @@
package com.yomahub.liteflow.parser.el;
import com.yomahub.liteflow.parser.base.BaseZookeeperXmlFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
import org.dom4j.Element;
/**
* 基于zk方式的xml形式EL表达式解析器
* @author Bryan.Zhang
* @since 2.8.0
*/
public class ZookeeperXmlFlowELParser extends BaseZookeeperXmlFlowParser {
public ZookeeperXmlFlowELParser(String node) {
super(node);
}
@Override
public void parseOneChain(Element chain) {
ParserHelper.parseOneChainEl(chain);
}
}

View File

@ -1,22 +0,0 @@
package com.yomahub.liteflow.parser.el;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.base.BaseZookeeperYmlFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
/**
* 基于zk方式的yml形式EL表达式解析器
*
* @author Bryan.Zhang
* @since 2.8.0
*/
public class ZookeeperYmlFlowELParser extends BaseZookeeperYmlFlowParser {
public ZookeeperYmlFlowELParser(String node) {
super(node);
}
@Override
public void parseOneChain(JsonNode chain) {
ParserHelper.parseOneChainEl(chain);
}
}

View File

@ -36,24 +36,10 @@ public class FlowParserProvider {
private static final String LOCAL_EL_YML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.el\\.yml$";
private static final String FORMAT_EL_XML_CONFIG_REGEX = "el_xml:.+";
private static final String FORMAT_EL_JSON_CONFIG_REGEX = "el_json:.+";
private static final String FORMAT_EL_YML_CONFIG_REGEX = "el_yml:.+";
private static final String FORMAT_XML_CONFIG_REGEX = "xml:.+";
private static final String FORMAT_JSON_CONFIG_REGEX = "json:.+";
private static final String FORMAT_YML_CONFIG_REGEX = "yml:.+";
private static final String PREFIX_FORMAT_CONFIG_REGEX = "xml:|json:|yml:|el_xml:|el_json:|el_yml:";
private static final String CLASS_CONFIG_REGEX = "^(xml:|json:|yml:|el_xml:|el_json:|el_yml:)?\\w+(\\.\\w+)*$";
private static final String ZK_CONFIG_REGEX = "(xml:|json:|yml:|el_xml:|el_json:|el_yml:)?[\\w\\d][\\w\\d\\.]+\\:(\\d)+(\\,[\\w\\d][\\w\\d\\.]+\\:(\\d)+)*";
/**
* 根据配置的地址找到对应的解析器
*/
@ -118,34 +104,6 @@ public class FlowParserProvider {
String errorMsg = StrUtil.format("can't support the format {}", path);
throw new ErrorSupportPathException(errorMsg);
}
else if (isZKConfig(path)) {
FlowParserFactory factory = new ZookeeperParserFactory();
if (ReUtil.isMatch(FORMAT_XML_CONFIG_REGEX, path)) {
LOG.info("flow info loaded from Zookeeper,zkNode={},format type={}", path, TYPE_XML.getType());
return factory.createXmlParser(path);
}
else if (ReUtil.isMatch(FORMAT_JSON_CONFIG_REGEX, path)) {
LOG.info("flow info loaded from Zookeeper,zkNode={},format type={}", path, TYPE_JSON.getType());
return factory.createJsonParser(path);
}
else if (ReUtil.isMatch(FORMAT_YML_CONFIG_REGEX, path)) {
LOG.info("flow info loaded from Zookeeper,zkNode={},format type={}", path, TYPE_YML.getType());
return factory.createYmlParser(path);
}
else if (ReUtil.isMatch(FORMAT_EL_XML_CONFIG_REGEX, path)) {
LOG.info("flow info loaded from Zookeeper with el,zkNode={},format type={}", path, TYPE_EL_XML.getType());
return factory.createXmlELParser(path);
}
else if (ReUtil.isMatch(FORMAT_EL_YML_CONFIG_REGEX, path)) {
LOG.info("flow info loaded from Zookeeper with el,zkNode={},format type={}", path, TYPE_EL_YML.getType());
return factory.createYmlELParser(path);
}
else if (ReUtil.isMatch(FORMAT_EL_JSON_CONFIG_REGEX, path)) {
LOG.info("flow info loaded from Zookeeper with el,zkNode={},format type={}", path, TYPE_EL_JSON.getType());
return factory.createJsonELParser(path);
}
}
// not found
String errorMsg = StrUtil.format("can't find the parser for path:{}", path);
@ -170,11 +128,4 @@ public class FlowParserProvider {
private static boolean isClassConfig(String path) {
return ReUtil.isMatch(CLASS_CONFIG_REGEX, path);
}
/**
* 判定是否为zk配置
*/
private static boolean isZKConfig(String path) {
return ReUtil.isMatch(ZK_CONFIG_REGEX, path);
}
}

View File

@ -1,47 +0,0 @@
package com.yomahub.liteflow.parser.factory;
import com.yomahub.liteflow.parser.*;
import com.yomahub.liteflow.parser.base.BaseJsonFlowParser;
import com.yomahub.liteflow.parser.base.BaseXmlFlowParser;
import com.yomahub.liteflow.parser.base.BaseYmlFlowParser;
import com.yomahub.liteflow.parser.el.*;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
/**
* Class文件
* <p>
*
* @author junjun
*/
public class ZookeeperParserFactory implements FlowParserFactory {
@Override
public BaseJsonFlowParser createJsonParser(String path) {
return new ZookeeperJsonFlowParser(LiteflowConfigGetter.get().getZkNode());
}
@Override
public BaseXmlFlowParser createXmlParser(String path) {
return new ZookeeperXmlFlowParser(LiteflowConfigGetter.get().getZkNode());
}
@Override
public BaseYmlFlowParser createYmlParser(String path) {
return new ZookeeperYmlFlowParser(LiteflowConfigGetter.get().getZkNode());
}
@Override
public BaseJsonFlowParser createJsonELParser(String path) {
return new ZookeeperJsonFlowELParser(LiteflowConfigGetter.get().getZkNode());
}
@Override
public BaseXmlFlowParser createXmlELParser(String path) {
return new ZookeeperXmlFlowELParser(LiteflowConfigGetter.get().getZkNode());
}
@Override
public BaseYmlFlowParser createYmlELParser(String path) {
return new ZookeeperYmlFlowELParser(LiteflowConfigGetter.get().getZkNode());
}
}

View File

@ -0,0 +1,11 @@
package com.yomahub.liteflow.parser.spi;
/**
* 解析器SPI插件接口
* @author Bryan.Zhang
* @since 2.8.6
*/
public interface ParserClassNameSpi {
String getSpiClassName();
}

View File

@ -29,8 +29,8 @@ public class LiteflowConfig {
//流程定义资源地址
private String ruleSource;
//zk配置的node定义
private String zkNode;
//流程资源扩展数据
private String ruleSourceExtData;
//slot的数量
private Integer slotSize;
@ -242,18 +242,6 @@ public class LiteflowConfig {
this.retryCount = retryCount;
}
public String getZkNode() {
if (StrUtil.isBlank(zkNode)) {
return "/lite-flow/flow";
} else {
return zkNode;
}
}
public void setZkNode(String zkNode) {
this.zkNode = zkNode;
}
public Boolean getPrintBanner() {
if (ObjectUtil.isNull(printBanner)) {
return Boolean.TRUE;
@ -344,4 +332,12 @@ public class LiteflowConfig {
public void setSubstituteCmpClass(String substituteCmpClass) {
this.substituteCmpClass = substituteCmpClass;
}
public String getRuleSourceExtData() {
return ruleSourceExtData;
}
public void setRuleSourceExtData(String ruleSourceExtData) {
this.ruleSourceExtData = ruleSourceExtData;
}
}

View File

@ -16,7 +16,7 @@ public class LiteflowConfigGetter {
//这里liteflowConfig不可能为null
//如果在springboot环境由于自动装配所以不可能为null
//在spring环境如果xml没配置在FlowExecutor的init时候就已经报错了
//只有在非spring环境下是为null
//非spring环境下FlowExecutorHolder.loadInstance(config)的时候会把config放入这个类的静态属性中
if (ObjectUtil.isNull(liteflowConfig)){
liteflowConfig = new LiteflowConfig();
}

View File

@ -54,4 +54,17 @@ public class JsonUtil {
throw new JsonProcessException(errMsg);
}
}
public static <T> T parseObject(String json, Class<T> clazz){
if (StrUtil.isEmpty(json)) {
return null;
}
try {
return objectMapper.readValue(json, clazz);
} catch (IOException e) {
String errMsg = StrUtil.format("Error while parsing text [{}],reason: {}", json, e.getMessage());
LOG.error(e.getMessage(), e);
throw new JsonProcessException(errMsg);
}
}
}

View File

@ -13,7 +13,7 @@ public class LOGOPrinter {
/**
* LiteFlow 当前版本号
*/
private static final String VERSION_NO = "v2.8.6-BETA";
private static final String VERSION_NO = "v2.9.0";
public static void print() {
StringBuilder str = new StringBuilder("\n");

46
liteflow-rule-zk/pom.xml Normal file
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.yomahub</groupId>
<artifactId>liteflow</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>liteflow-rule-zk</artifactId>
<dependencies>
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-core</artifactId>
<version>${revision}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package com.yomahub.liteflow.parser.spi.zk;
import com.yomahub.liteflow.parser.spi.ParserClassNameSpi;
import com.yomahub.liteflow.parser.zk.ZkXmlELParser;
/**
* ZK解析器SPI实现
* @author Bryan.Zhang
* @since 2.8.6
*/
public class ZkParserClassNameSpi implements ParserClassNameSpi {
@Override
public String getSpiClassName() {
return ZkXmlELParser.class.getName();
}
}

View File

@ -0,0 +1,69 @@
package com.yomahub.liteflow.parser.zk;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.parser.el.ClassXmlFlowELParser;
import com.yomahub.liteflow.parser.zk.exception.ZkException;
import com.yomahub.liteflow.parser.zk.util.ZkParserHelper;
import com.yomahub.liteflow.parser.zk.vo.ZkParserVO;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.util.JsonUtil;
import org.apache.curator.framework.CuratorFramework;
import java.util.function.Consumer;
/**
* ZK解析器实现只支持EL形式的XML不支持其他的形式
* @author Bryan.Zhang
* @since 2.8.6
*/
public class ZkXmlELParser extends ClassXmlFlowELParser {
private final ZkParserHelper zkParserHelper;
public ZkXmlELParser() {
Consumer<String> parseConsumer = t -> {
try {
parse(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
if (StrUtil.isBlank(liteflowConfig.getRuleSourceExtData())){
throw new ZkException("rule-source-ext-data is empty");
}
try{
ZkParserVO zkParserVO = JsonUtil.parseObject(liteflowConfig.getRuleSourceExtData(), ZkParserVO.class);
assert zkParserVO != null;
if (StrUtil.isBlank(zkParserVO.getNodePath())){
zkParserVO.setNodePath("/lite-flow/flow");
}
if (StrUtil.isBlank(zkParserVO.getConnectStr())){
throw new ZkException("zk connect string is empty");
}
zkParserHelper = new ZkParserHelper(zkParserVO, parseConsumer);
}catch (Exception e){
throw new ZkException(e.getMessage());
}
}
@Override
public String parseCustom() {
try{
String content = zkParserHelper.getContent();
zkParserHelper.checkContent(content);
zkParserHelper.listenZkNode();
return content;
}catch (Exception e){
throw new ZkException(e.getMessage());
}
}
}

View File

@ -0,0 +1,23 @@
package com.yomahub.liteflow.parser.zk.exception;
public class ZkException extends RuntimeException {
private static final long serialVersionUID = 1L;
/** 异常信息 */
private String message;
public ZkException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -1,7 +1,9 @@
package com.yomahub.liteflow.parser.helper;
package com.yomahub.liteflow.parser.zk.util;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.exception.ParseException;
import com.yomahub.liteflow.parser.zk.exception.ZkException;
import com.yomahub.liteflow.parser.zk.vo.ZkParserVO;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
@ -10,63 +12,61 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
import java.util.List;
import java.util.function.Consumer;
public class ZkParserHelper {
private static final Logger LOG = LoggerFactory.getLogger(ZkParserHelper.class);
private final String nodePath;
private final ZkParserVO zkParserVO;
private final Consumer<String> parseConsumer;
public ZkParserHelper(String node, Consumer<String> parseConsumer) {
this.nodePath = node;
private final CuratorFramework client;
public ZkParserHelper(ZkParserVO zkParserVO, Consumer<String> parseConsumer) {
this.zkParserVO = zkParserVO;
this.parseConsumer = parseConsumer;
try{
CuratorFramework client = CuratorFrameworkFactory.newClient(
zkParserVO.getConnectStr(),
new RetryNTimes(10, 5000)
);
client.start();
if (client.checkExists().forPath(zkParserVO.getNodePath()) == null) {
client.create().creatingParentsIfNeeded().forPath(zkParserVO.getNodePath(), "".getBytes());
}
this.client = client;
}catch (Exception e){
throw new ZkException(e.getMessage());
}
}
/**
* 获取zk客户端
*
* @param pathList zk路径
* @return
* @throws Exception
*/
public CuratorFramework getZkCuratorFramework(List<String> pathList) throws Exception {
//zk不允许有多个path
String path = pathList.get(0);
CuratorFramework client = CuratorFrameworkFactory.newClient(
path,
new RetryNTimes(10, 5000)
);
client.start();
if (client.checkExists().forPath(nodePath) == null) {
client.create().creatingParentsIfNeeded().forPath(nodePath, "".getBytes());
public String getContent(){
try{
return new String(client.getData().forPath(zkParserVO.getNodePath()));
}catch (Exception e){
throw new ZkException(e.getMessage());
}
return client;
}
/**
* 检查 content 是否合法
*
* @param content 内容
*/
public void checkContent(String content) {
if (StrUtil.isBlank(content)) {
String error = MessageFormat.format("the node[{0}] value is empty", nodePath);
String error = MessageFormat.format("the node[{0}] value is empty", zkParserVO.getNodePath());
throw new ParseException(error);
}
}
/**
* 监听 zk 节点
*
* @param client zk 客户端
* @throws Exception
*/
public void listenZkNode(CuratorFramework client) throws Exception {
final NodeCache cache = new NodeCache(client, nodePath);
public void listenZkNode() throws Exception {
final NodeCache cache = new NodeCache(client, zkParserVO.getNodePath());
cache.start();
cache.getListenable().addListener(() -> {

View File

@ -0,0 +1,29 @@
package com.yomahub.liteflow.parser.zk.vo;
/**
* 用于解析RuleSourceExtData的vo类用于zk模式中
* @author Bryan.Zhang
* @since 2.8.6
*/
public class ZkParserVO {
private String connectStr;
private String nodePath;
public String getConnectStr() {
return connectStr;
}
public void setConnectStr(String connectStr) {
this.connectStr = connectStr;
}
public String getNodePath() {
return nodePath;
}
public void setNodePath(String nodePath) {
this.nodePath = nodePath;
}
}

View File

@ -0,0 +1 @@
com.yomahub.liteflow.parser.spi.zk.ZkParserClassNameSpi

View File

@ -15,8 +15,8 @@ public class LiteflowProperty {
//流程定义资源地址
private String ruleSource;
//zk配置的node节点地址
private String zkNode;
//流程资源扩展数据
private String ruleSourceExtData;
//slot的数量
private int slotSize;
@ -137,14 +137,6 @@ public class LiteflowProperty {
this.retryCount = retryCount;
}
public String getZkNode() {
return zkNode;
}
public void setZkNode(String zkNode) {
this.zkNode = zkNode;
}
public boolean isPrintBanner() {
return printBanner;
}
@ -208,4 +200,12 @@ public class LiteflowProperty {
public void setSubstituteCmpClass(String substituteCmpClass) {
this.substituteCmpClass = substituteCmpClass;
}
public String getRuleSourceExtData() {
return ruleSourceExtData;
}
public void setRuleSourceExtData(String ruleSourceExtData) {
this.ruleSourceExtData = ruleSourceExtData;
}
}

View File

@ -25,6 +25,7 @@ public class LiteflowPropertyAutoConfiguration {
public LiteflowConfig liteflowConfig(LiteflowProperty property, LiteflowMonitorProperty liteflowMonitorProperty){
LiteflowConfig liteflowConfig = new LiteflowConfig();
liteflowConfig.setRuleSource(property.getRuleSource());
liteflowConfig.setRuleSourceExtData(property.getRuleSourceExtData());
liteflowConfig.setSlotSize(property.getSlotSize());
liteflowConfig.setThreadExecutorClass(property.getThreadExecutorClass());
liteflowConfig.setWhenMaxWaitSeconds(property.getWhenMaxWaitSeconds());
@ -38,7 +39,6 @@ public class LiteflowPropertyAutoConfiguration {
liteflowConfig.setEnable(property.isEnable());
liteflowConfig.setSupportMultipleType(property.isSupportMultipleType());
liteflowConfig.setRetryCount(property.getRetryCount());
liteflowConfig.setZkNode(property.getZkNode());
liteflowConfig.setPrintBanner(property.isPrintBanner());
liteflowConfig.setNodeExecutorClass(property.getNodeExecutorClass());
liteflowConfig.setRequestIdGeneratorClass(property.getRequestIdGeneratorClass());

View File

@ -1,5 +1,11 @@
{
"properties": [
{
"name": "liteflow.rule-source-ext-data",
"type": "java.lang.String",
"description": "rule source extended data.",
"sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty"
},
{
"name": "liteflow.request-id-generator-class",
"type": "java.lang.String",
@ -28,13 +34,6 @@
"sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty",
"defaultValue": true
},
{
"name": "liteflow.zk-node",
"type": "java.lang.String",
"description": "Node definition for ZK configuration.",
"sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty",
"defaultValue": "/lite-flow/flow"
},
{
"name": "liteflow.slot-size",
"type": "java.lang.Integer",

View File

@ -1,6 +1,5 @@
liteflow.enable=true
liteflow.print-banner=true
liteflow.zk-node=/lite-flow/flow
liteflow.slot-size=1024
liteflow.main-executor-works=64
liteflow.main-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultMainExecutorBuilder

View File

@ -1,82 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为json文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-json.properties")
@SpringBootTest(classes = ZkNodeWithJsonELDeclSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithJsonELDeclSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.json");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithJson() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,82 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为xml文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-xml.properties")
@SpringBootTest(classes = ZkNodeWithXmlELDeclSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithXmlELDeclSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.xml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithXml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,82 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为yml文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-yml.properties")
@SpringBootTest(classes = ZkNodeWithYmlELDeclSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithYmlELDeclSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.yml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithYml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,24 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import org.springframework.stereotype.Component;
@Component("a")
@LiteflowCmpDefine
public class ACmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
public void process(NodeComponent bindCmp) {
System.out.println("ACmp executed!");
}
}

View File

@ -1,25 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import org.springframework.stereotype.Component;
@Component("b")
@LiteflowCmpDefine
public class BCmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
public void process(NodeComponent bindCmp) {
System.out.println("BCmp executed!");
}
}

View File

@ -1,25 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import org.springframework.stereotype.Component;
@Component("c")
@LiteflowCmpDefine
public class CCmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
public void process(NodeComponent bindCmp) {
System.out.println("CCmp executed!");
}
}

View File

@ -1,10 +0,0 @@
{
"flow": {
"chain": [
{
"name": "chain1",
"value": "THEN(a, b, c);"
}
]
}
}

View File

@ -1,4 +0,0 @@
flow:
chain:
- name: chain1
value: "THEN(a, b, c);"

View File

@ -1,75 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.FlowExecutorHolder;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* 非spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为json文件
* @author zendwang
* @since 2.5.0
*/
public class ZkNodeWithJsonTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
private static FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.json");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("el_json:127.0.0.1:21810");
flowExecutor = FlowExecutorHolder.loadInstance(config);
}
@Test
public void testZkNodeWithJson() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,75 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.FlowExecutorHolder;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* 非spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为xml文件
* @author zendwang
* @since 2.5.0
*/
public class ZkNodeWithXmlTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
private static FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.xml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("el_xml:127.0.0.1:21810");
flowExecutor = FlowExecutorHolder.loadInstance(config);
}
@Test
public void testZkNodeWithXml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,75 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.FlowExecutorHolder;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* 非spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为yml文件
* @author zendwang
* @since 2.5.0
*/
public class ZkNodeWithYmlTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
private static FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.yml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("el_yml:127.0.0.1:21810");
flowExecutor = FlowExecutorHolder.loadInstance(config);
}
@Test
public void testZkNodeWithYml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,18 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class ACmp extends NodeComponent {
@Override
public void process() {
System.out.println("ACmp executed!");
}
}

View File

@ -1,19 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class BCmp extends NodeComponent {
@Override
public void process() {
System.out.println("BCmp executed!");
}
}

View File

@ -1,19 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class CCmp extends NodeComponent {
@Override
public void process() {
System.out.println("CCmp executed!");
}
}

View File

@ -1,82 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为json文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-json.properties")
@SpringBootTest(classes = ZkNodeWithJsonELSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithJsonELSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.json");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithJson() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,82 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为yml文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-yml.properties")
@SpringBootTest(classes = ZkNodeWithYmlELSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithYmlELSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.yml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithYml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1 +0,0 @@
liteflow.rule-source=el_json:127.0.0.1:21810

View File

@ -1 +0,0 @@
liteflow.rule-source=el_xml:127.0.0.1:21810,127.0.0.1:21811,127.0.0.1:21812

View File

@ -1 +0,0 @@
liteflow.rule-source=el_xml:127.0.0.1:21810

View File

@ -1 +0,0 @@
liteflow.rule-source=el_yml:127.0.0.1:21810

View File

@ -1,10 +0,0 @@
{
"flow": {
"chain": [
{
"name": "chain1",
"value": "THEN(a, b, c);"
}
]
}
}

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
THEN(a, b, c);
</chain>
</flow>

View File

@ -1,4 +0,0 @@
flow:
chain:
- name: chain1
value: "THEN(a, b, c);"

View File

@ -1,77 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为json文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/zookeeper/application-json.xml")
public class ZkNodeWithJsonELSpringTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.el.json");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void test() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("a==>b==>c", response.getExecuteStepStr());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,77 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为xml文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/zookeeper/application-xml.xml")
public class ZkNodeWithXmlELSpringTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.el.xml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void test() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("a==>b==>c", response.getExecuteStepStr());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,77 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为yml文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:/zookeeper/application-yml.xml")
public class ZkNodeWithYmlELSpringTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.el.yml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void test() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
Assert.assertEquals("a==>b==>c", response.getExecuteStepStr());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,20 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("a")
public class ACmp extends NodeComponent {
@Override
public void process() {
System.out.println("ACmp executed!");
}
}

View File

@ -1,21 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("b")
public class BCmp extends NodeComponent {
@Override
public void process() {
System.out.println("BCmp executed!");
}
}

View File

@ -1,21 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("c")
public class CCmp extends NodeComponent {
@Override
public void process() {
System.out.println("CCmp executed!");
}
}

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.yomahub.liteflow.test.zookeeper.cmp" />
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="el_json:127.0.0.1:21810"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<constructor-arg name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.yomahub.liteflow.test.zookeeper.cmp" />
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="el_xml:127.0.0.1:21810"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<constructor-arg name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.yomahub.liteflow.test.zookeeper.cmp" />
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
<property name="ruleSource" value="el_yml:127.0.0.1:21810"/>
</bean>
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
<constructor-arg name="liteflowConfig" ref="liteflowConfig"/>
</bean>
</beans>

View File

@ -1,10 +0,0 @@
{
"flow": {
"chain": [
{
"name": "chain1",
"value": "THEN(a,b,c)"
}
]
}
}

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
THEN(a,b,c)
</chain>
</flow>

View File

@ -1,5 +0,0 @@
flow:
chain:
- name: chain1
value: "THEN(a,b,c)"

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>liteflow-testcase-el</artifactId>
<groupId>com.yomahub</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>liteflow-testcase-el-zk-springboot</artifactId>
<dependencies>
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-rule-zk</artifactId>
<version>${revision}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,20 @@
package com.yomahub.liteflow.test;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.spi.holder.SpiFactoryCleaner;
import com.yomahub.liteflow.spring.ComponentScanner;
import com.yomahub.liteflow.thread.ExecutorHelper;
import org.junit.AfterClass;
public class BaseTest {
@AfterClass
public static void cleanScanCache(){
ComponentScanner.cleanCache();
FlowBus.cleanCache();
ExecutorHelper.loadInstance().clearExecutorServiceMap();
SpiFactoryCleaner.clean();
LiteflowConfigGetter.clean();
}
}

View File

@ -9,7 +9,6 @@ import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.InstanceSpec;
import org.apache.curator.test.TestingCluster;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@ -23,7 +22,6 @@ import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk cluster的测试
@ -73,7 +71,7 @@ public class ZkClusterWithXmlELSpringbootTest extends BaseTest {
Assert.assertTrue(response.isSuccess());
}
// @AfterClass
@AfterClass
public static void tearDown() throws Exception {
zkCluster.stop();
}

View File

@ -0,0 +1 @@
liteflow.rule-source-ext-data={"connectStr":"127.0.0.1:21810,127.0.0.1:21811,127.0.0.1:21812"}

View File

@ -0,0 +1 @@
liteflow.rule-source-ext-data={"connectStr":"127.0.0.1:21810"}

View File

@ -21,5 +21,6 @@
<module>liteflow-testcase-el-declare-springboot</module>
<module>liteflow-testcase-el-script-groovy-springboot</module>
<module>liteflow-testcase-el-script-qlexpress-springboot</module>
<module>liteflow-testcase-el-zk-springboot</module>
</modules>
</project>

View File

@ -29,24 +29,6 @@
<artifactId>aspectjweaver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -1,83 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为json文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-json.properties")
@SpringBootTest(classes = ZkNodeWithJsonSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithJsonSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.json");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithJson() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,83 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为xml文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-xml.properties")
@SpringBootTest(classes = ZkNodeWithXmlSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithXmlSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.xml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithXml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,83 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
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;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* springboot环境下的zk配置源功能测试
* ZK节点存储数据的格式为yml文件
* @author zendwang
* @since 2.5.0
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/zookeeper/application-yml.properties")
@SpringBootTest(classes = ZkNodeWithYmlSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.zookeeper.cmp"})
public class ZkNodeWithYmlSpringbootTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
@Resource
private FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.yml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
}
@Test
public void testZkNodeWithYml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,24 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import org.springframework.stereotype.Component;
@Component("a")
@LiteflowCmpDefine
public class ACmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
public void process(NodeComponent bindCmp) {
System.out.println("ACmp executed!");
}
}

View File

@ -1,25 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import org.springframework.stereotype.Component;
@Component("b")
@LiteflowCmpDefine
public class BCmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
public void process(NodeComponent bindCmp) {
System.out.println("BCmp executed!");
}
}

View File

@ -1,25 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import org.springframework.stereotype.Component;
@Component("c")
@LiteflowCmpDefine
public class CCmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
public void process(NodeComponent bindCmp) {
System.out.println("CCmp executed!");
}
}

View File

@ -1,12 +0,0 @@
{
"flow": {
"chain": [
{
"name": "chain1",
"condition": [
{"type": "then", "value": "a,b,c"}
]
}
]
}
}

View File

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

View File

@ -1,6 +0,0 @@
flow:
chain:
- name: chain1
condition:
- type: then
value: 'a,b,c'

View File

@ -28,24 +28,6 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -1,75 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.FlowExecutorHolder;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* 非spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为json文件
* @author zendwang
* @since 2.5.0
*/
public class ZkNodeWithJsonTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
private static FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.json");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("json:127.0.0.1:21810");
flowExecutor = FlowExecutorHolder.loadInstance(config);
}
@Test
public void testZkNodeWithJson() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,75 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.FlowExecutorHolder;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* 非spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为xml文件
* @author zendwang
* @since 2.5.0
*/
public class ZkNodeWithXmlTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
private static FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.xml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("xml:127.0.0.1:21810");
flowExecutor = FlowExecutorHolder.loadInstance(config);
}
@Test
public void testZkNodeWithXml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,75 +0,0 @@
package com.yomahub.liteflow.test.zookeeper;
import cn.hutool.core.io.resource.ResourceUtil;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.FlowExecutorHolder;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
/**
* 非spring环境下的zk配置源功能测试
* ZK节点存储数据的格式为yml文件
* @author zendwang
* @since 2.5.0
*/
public class ZkNodeWithYmlTest extends BaseTest {
private static final String ZK_NODE_PATH = "/lite-flow/flow";
private static TestingServer zkServer;
private static FlowExecutor flowExecutor;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
zkServer = new TestingServer(21810);
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
String data = ResourceUtil.readUtf8Str("zookeeper/flow.yml");
ZkClient zkClient = new ZkClient("127.0.0.1:21810");
zkClient.setZkSerializer(new ZkSerializer() {
@Override
public byte[] serialize(final Object o) throws ZkMarshallingError {
return o.toString().getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(final byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
});
zkClient.createPersistent(ZK_NODE_PATH, true);
zkClient.writeData(ZK_NODE_PATH, data);
zkClient.close();
latch.countDown();
}).start();
latch.await();
LiteflowConfig config = new LiteflowConfig();
config.setRuleSource("yml:127.0.0.1:21810");
flowExecutor = FlowExecutorHolder.loadInstance(config);
}
@Test
public void testZkNodeWithYml() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
@AfterClass
public static void tearDown() throws Exception {
zkServer.stop();
}
}

View File

@ -1,18 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class ACmp extends NodeComponent {
@Override
public void process() {
System.out.println("ACmp executed!");
}
}

View File

@ -1,19 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class BCmp extends NodeComponent {
@Override
public void process() {
System.out.println("BCmp executed!");
}
}

View File

@ -1,19 +0,0 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.zookeeper.cmp;
import com.yomahub.liteflow.core.NodeComponent;
public class CCmp extends NodeComponent {
@Override
public void process() {
System.out.println("CCmp executed!");
}
}

View File

@ -1,28 +0,0 @@
{
"flow": {
"nodes": {
"node": [
{
"id": "a",
"class": "com.yomahub.liteflow.test.zookeeper.cmp.ACmp"
},
{
"id": "b",
"class": "com.yomahub.liteflow.test.zookeeper.cmp.BCmp"
},
{
"id": "c",
"class": "com.yomahub.liteflow.test.zookeeper.cmp.CCmp"
}
]
},
"chain": [
{
"name": "chain1",
"condition": [
{"type": "then", "value": "a,b,c"}
]
}
]
}
}

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="a" class="com.yomahub.liteflow.test.zookeeper.cmp.ACmp"/>
<node id="b" class="com.yomahub.liteflow.test.zookeeper.cmp.BCmp"/>
<node id="c" class="com.yomahub.liteflow.test.zookeeper.cmp.CCmp"/>
</nodes>
<chain name="chain1">
<then value="a,b,c"/>
</chain>
</flow>

Some files were not shown because too many files have changed in this diff Show More