|
@@ -13,22 +13,19 @@ import cn.hutool.core.util.BooleanUtil;
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
import cn.hutool.core.util.ReUtil;
|
|
import cn.hutool.core.util.ReUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
-import com.yomahub.liteflow.enums.FlowParserTypeEnum;
|
|
|
|
import com.yomahub.liteflow.exception.*;
|
|
import com.yomahub.liteflow.exception.*;
|
|
import com.yomahub.liteflow.flow.FlowBus;
|
|
import com.yomahub.liteflow.flow.FlowBus;
|
|
import com.yomahub.liteflow.flow.LiteflowResponse;
|
|
import com.yomahub.liteflow.flow.LiteflowResponse;
|
|
import com.yomahub.liteflow.flow.element.Chain;
|
|
import com.yomahub.liteflow.flow.element.Chain;
|
|
import com.yomahub.liteflow.flow.element.Node;
|
|
import com.yomahub.liteflow.flow.element.Node;
|
|
import com.yomahub.liteflow.flow.id.IdGeneratorHolder;
|
|
import com.yomahub.liteflow.flow.id.IdGeneratorHolder;
|
|
-import com.yomahub.liteflow.parser.*;
|
|
|
|
import com.yomahub.liteflow.parser.base.FlowParser;
|
|
import com.yomahub.liteflow.parser.base.FlowParser;
|
|
-import com.yomahub.liteflow.parser.el.*;
|
|
|
|
|
|
+import com.yomahub.liteflow.parser.factory.FlowParserProvider;
|
|
import com.yomahub.liteflow.property.LiteflowConfig;
|
|
import com.yomahub.liteflow.property.LiteflowConfig;
|
|
import com.yomahub.liteflow.property.LiteflowConfigGetter;
|
|
import com.yomahub.liteflow.property.LiteflowConfigGetter;
|
|
import com.yomahub.liteflow.slot.DataBus;
|
|
import com.yomahub.liteflow.slot.DataBus;
|
|
import com.yomahub.liteflow.slot.DefaultContext;
|
|
import com.yomahub.liteflow.slot.DefaultContext;
|
|
import com.yomahub.liteflow.slot.Slot;
|
|
import com.yomahub.liteflow.slot.Slot;
|
|
-import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
|
|
|
|
import com.yomahub.liteflow.spi.holder.ContextCmpInitHolder;
|
|
import com.yomahub.liteflow.spi.holder.ContextCmpInitHolder;
|
|
import com.yomahub.liteflow.thread.ExecutorHelper;
|
|
import com.yomahub.liteflow.thread.ExecutorHelper;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
@@ -49,35 +46,7 @@ public class FlowExecutor {
|
|
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(FlowExecutor.class);
|
|
private static final Logger LOG = LoggerFactory.getLogger(FlowExecutor.class);
|
|
|
|
|
|
- private static final String ZK_CONFIG_REGEX = "[\\w\\d][\\w\\d\\.]+\\:(\\d)+(\\,[\\w\\d][\\w\\d\\.]+\\:(\\d)+)*";
|
|
|
|
-
|
|
|
|
- private static final String LOCAL_XML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.xml$";
|
|
|
|
-
|
|
|
|
- private static final String LOCAL_EL_XML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.el\\.xml$";
|
|
|
|
- private static final String LOCAL_JSON_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.json$";
|
|
|
|
-
|
|
|
|
- private static final String LOCAL_EL_JSON_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.el\\.json$";
|
|
|
|
- private static final String LOCAL_YML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.yml$";
|
|
|
|
-
|
|
|
|
- private static final String LOCAL_EL_YML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.el\\.yml$";
|
|
|
|
-
|
|
|
|
- private static final String FORMATE_XML_CONFIG_REGEX = "xml:.+";
|
|
|
|
-
|
|
|
|
- private static final String FORMATE_EL_XML_CONFIG_REGEX = "el_xml:.+";
|
|
|
|
-
|
|
|
|
- private static final String FORMATE_JSON_CONFIG_REGEX = "json:.+";
|
|
|
|
-
|
|
|
|
- private static final String FORMATE_EL_JSON_CONFIG_REGEX = "el_json:.+";
|
|
|
|
-
|
|
|
|
- private static final String FORMATE_YML_CONFIG_REGEX = "yml:.+";
|
|
|
|
-
|
|
|
|
- private static final String FORMATE_EL_YML_CONFIG_REGEX = "el_yml:.+";
|
|
|
|
-
|
|
|
|
- private static final String PREFIX_FORMAT_CONFIG_REGEX = "xml:|json:|yml:";
|
|
|
|
-
|
|
|
|
- private static final String PREFIX_EL_FORMAT_CONFIG_REGEX = "el_xml:|el_json:|el_yml:";
|
|
|
|
-
|
|
|
|
- private static final String CLASS_CONFIG_REGEX = "^\\w+(\\.\\w+)*$";
|
|
|
|
|
|
+ private static final String PREFIX_FORMAT_CONFIG_REGEX = "xml:|json:|yml:|el_xml:|el_json:|el_yml:";
|
|
|
|
|
|
private LiteflowConfig liteflowConfig;
|
|
private LiteflowConfig liteflowConfig;
|
|
|
|
|
|
@@ -130,30 +99,11 @@ public class FlowExecutor {
|
|
List<String> rulePathList = new ArrayList<>();
|
|
List<String> rulePathList = new ArrayList<>();
|
|
for (String path : sourceRulePathList) {
|
|
for (String path : sourceRulePathList) {
|
|
try {
|
|
try {
|
|
- //根据path获得pattern类型
|
|
|
|
- FlowParserTypeEnum pattern = matchFormatConfig(path);
|
|
|
|
- if (pattern == null){
|
|
|
|
- String errorMsg = StrUtil.format("can't support the path:{}", path);
|
|
|
|
- throw new ErrorSupportPathException(errorMsg);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (pattern.getType().startsWith("el")){
|
|
|
|
- path = ReUtil.replaceAll(path, PREFIX_EL_FORMAT_CONFIG_REGEX, "");
|
|
|
|
- }else{
|
|
|
|
- path = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, "");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //获得parser
|
|
|
|
- parser = matchFormatParser(path, pattern);
|
|
|
|
-
|
|
|
|
- if (parser == null){
|
|
|
|
- String errorMsg = StrUtil.format("can't find the parser for path:{}", path);
|
|
|
|
- throw new ErrorSupportPathException(errorMsg);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ // 查找对应的解析器
|
|
|
|
+ parser = FlowParserProvider.lookup(path);
|
|
parserNameSet.add(parser.getClass().getName());
|
|
parserNameSet.add(parser.getClass().getName());
|
|
-
|
|
|
|
|
|
+ // 替换掉前缀标识(如:xml:/json:),保留剩下的完整地址
|
|
|
|
+ path = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, "");
|
|
rulePathList.add(path);
|
|
rulePathList.add(path);
|
|
|
|
|
|
//支持多类型的配置文件,分别解析
|
|
//支持多类型的配置文件,分别解析
|
|
@@ -201,135 +151,6 @@ public class FlowExecutor {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * 匹配路径配置,生成对应的解析器
|
|
|
|
- */
|
|
|
|
- private FlowParser matchFormatParser(String path, FlowParserTypeEnum pattern) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
|
|
|
|
- boolean isLocalFile = isLocalConfig(path);
|
|
|
|
- if (isLocalFile) {
|
|
|
|
- LOG.info("flow info loaded from local file,path={},format type={}", path, pattern.getType());
|
|
|
|
- switch (pattern) {
|
|
|
|
- case TYPE_XML:
|
|
|
|
- return new LocalXmlFlowParser();
|
|
|
|
- case TYPE_JSON:
|
|
|
|
- return new LocalJsonFlowParser();
|
|
|
|
- case TYPE_YML:
|
|
|
|
- return new LocalYmlFlowParser();
|
|
|
|
- case TYPE_EL_XML:
|
|
|
|
- return new LocalXmlFlowELParser();
|
|
|
|
- case TYPE_EL_JSON:
|
|
|
|
- return new LocalJsonFlowELParser();
|
|
|
|
- case TYPE_EL_YML:
|
|
|
|
- return new LocalYmlFlowELParser();
|
|
|
|
- default:
|
|
|
|
- }
|
|
|
|
- } else if (isClassConfig(path)) {
|
|
|
|
- LOG.info("flow info loaded from class config,class={},format type={}", path, pattern.getType());
|
|
|
|
- Class<?> c = Class.forName(path);
|
|
|
|
- switch (pattern) {
|
|
|
|
- case TYPE_XML:
|
|
|
|
- return (XmlFlowParser) ContextAwareHolder.loadContextAware().registerBean(c);
|
|
|
|
- case TYPE_JSON:
|
|
|
|
- return (JsonFlowParser) ContextAwareHolder.loadContextAware().registerBean(c);
|
|
|
|
- case TYPE_YML:
|
|
|
|
- return (YmlFlowParser) ContextAwareHolder.loadContextAware().registerBean(c);
|
|
|
|
- case TYPE_EL_XML:
|
|
|
|
- return (XmlFlowELParser) ContextAwareHolder.loadContextAware().registerBean(c);
|
|
|
|
- case TYPE_EL_JSON:
|
|
|
|
- return (JsonFlowELParser) ContextAwareHolder.loadContextAware().registerBean(c);
|
|
|
|
- case TYPE_EL_YML:
|
|
|
|
- return (YmlFlowELParser) ContextAwareHolder.loadContextAware().registerBean(c);
|
|
|
|
- default:
|
|
|
|
- }
|
|
|
|
- } else if (isZKConfig(path)) {
|
|
|
|
- LOG.info("flow info loaded from Zookeeper,zkNode={},format type={}", path, pattern.getType());
|
|
|
|
- switch (pattern) {
|
|
|
|
- case TYPE_XML:
|
|
|
|
- return new ZookeeperXmlFlowParser(liteflowConfig.getZkNode());
|
|
|
|
- case TYPE_JSON:
|
|
|
|
- return new ZookeeperJsonFlowParser(liteflowConfig.getZkNode());
|
|
|
|
- case TYPE_YML:
|
|
|
|
- return new ZookeeperYmlFlowParser(liteflowConfig.getZkNode());
|
|
|
|
- case TYPE_EL_XML:
|
|
|
|
- return new ZookeeperXmlFlowELParser(liteflowConfig.getZkNode());
|
|
|
|
- case TYPE_EL_JSON:
|
|
|
|
- return new ZookeeperJsonFlowELParser(liteflowConfig.getZkNode());
|
|
|
|
- case TYPE_EL_YML:
|
|
|
|
- return new ZookeeperYmlFlowELParser(liteflowConfig.getZkNode());
|
|
|
|
- default:
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- LOG.info("load flow info error, path={}, pattern={}", path, pattern.getType());
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 判定是否为本地文件
|
|
|
|
- */
|
|
|
|
- private boolean isLocalConfig(String path) {
|
|
|
|
- return ReUtil.isMatch(LOCAL_XML_CONFIG_REGEX, path)
|
|
|
|
- || ReUtil.isMatch(LOCAL_JSON_CONFIG_REGEX, path)
|
|
|
|
- || ReUtil.isMatch(LOCAL_YML_CONFIG_REGEX, path)
|
|
|
|
- || ReUtil.isMatch(LOCAL_EL_XML_CONFIG_REGEX, path)
|
|
|
|
- || ReUtil.isMatch(LOCAL_EL_JSON_CONFIG_REGEX, path)
|
|
|
|
- || ReUtil.isMatch(LOCAL_EL_YML_CONFIG_REGEX, path);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 判定是否为自定义class配置
|
|
|
|
- */
|
|
|
|
- private boolean isClassConfig(String path) {
|
|
|
|
- return ReUtil.isMatch(CLASS_CONFIG_REGEX, path);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 判定是否为zk配置
|
|
|
|
- */
|
|
|
|
- private boolean isZKConfig(String path) {
|
|
|
|
- return ReUtil.isMatch(ZK_CONFIG_REGEX, path);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 匹配文本格式,支持xml,json和yml
|
|
|
|
- */
|
|
|
|
- private FlowParserTypeEnum matchFormatConfig(String path) {
|
|
|
|
- if (ReUtil.isMatch(LOCAL_XML_CONFIG_REGEX, path) || ReUtil.isMatch(FORMATE_XML_CONFIG_REGEX, path)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_XML;
|
|
|
|
- } else if (ReUtil.isMatch(LOCAL_JSON_CONFIG_REGEX, path) || ReUtil.isMatch(FORMATE_JSON_CONFIG_REGEX, path)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_JSON;
|
|
|
|
- } else if (ReUtil.isMatch(LOCAL_YML_CONFIG_REGEX, path) || ReUtil.isMatch(FORMATE_YML_CONFIG_REGEX, path)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_YML;
|
|
|
|
- } else if (ReUtil.isMatch(LOCAL_EL_XML_CONFIG_REGEX, path) || ReUtil.isMatch(FORMATE_EL_XML_CONFIG_REGEX, path)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_EL_XML;
|
|
|
|
- } else if (ReUtil.isMatch(LOCAL_EL_JSON_CONFIG_REGEX, path) || ReUtil.isMatch(FORMATE_EL_JSON_CONFIG_REGEX, path)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_EL_JSON;
|
|
|
|
- } else if (ReUtil.isMatch(LOCAL_EL_YML_CONFIG_REGEX, path) || ReUtil.isMatch(FORMATE_EL_YML_CONFIG_REGEX, path)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_EL_YML;
|
|
|
|
- } else if (isClassConfig(path)) {
|
|
|
|
- //其实整个这个判断块代码可以不要,因为如果是自定义配置源的话,标准写法也要在前面加xml:/json:/yml:这种
|
|
|
|
- //但是这块可能是考虑到有些人忘加了,所以再来判断下。如果写了标准的话,是不会走到这块来的
|
|
|
|
- try {
|
|
|
|
- Class<?> clazz = Class.forName(path);
|
|
|
|
- if (ClassXmlFlowParser.class.isAssignableFrom(clazz)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_XML;
|
|
|
|
- } else if (ClassJsonFlowParser.class.isAssignableFrom(clazz)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_JSON;
|
|
|
|
- } else if (ClassYmlFlowParser.class.isAssignableFrom(clazz)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_YML;
|
|
|
|
- } else if (ClassXmlFlowELParser.class.isAssignableFrom(clazz)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_EL_XML;
|
|
|
|
- } else if (ClassJsonFlowELParser.class.isAssignableFrom(clazz)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_EL_JSON;
|
|
|
|
- } else if (ClassYmlFlowELParser.class.isAssignableFrom(clazz)) {
|
|
|
|
- return FlowParserTypeEnum.TYPE_EL_YML;
|
|
|
|
- }
|
|
|
|
- } catch (ClassNotFoundException e) {
|
|
|
|
- LOG.error(e.getMessage());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
//此方法就是从原有的配置源主动拉取新的进行刷新
|
|
//此方法就是从原有的配置源主动拉取新的进行刷新
|
|
//和FlowBus.refreshFlowMetaData的区别就是一个为主动拉取,一个为被动监听到新的内容进行刷新
|
|
//和FlowBus.refreshFlowMetaData的区别就是一个为主动拉取,一个为被动监听到新的内容进行刷新
|
|
public void reloadRule() {
|
|
public void reloadRule() {
|