From cea575c4d34cb297bc1f4d9c389282b11237b72f Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Sun, 19 Jun 2022 17:06:54 +0800 Subject: [PATCH 1/8] =?UTF-8?q?optimized:=20=E7=AE=80=E5=8C=96=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F=EF=BC=8C=E8=AE=A9=E5=AE=83?= =?UTF-8?q?=E7=9C=8B=E8=B5=B7=E6=9D=A5=E6=9B=B4=E5=8A=A0=E7=9A=84=E7=9B=B4?= =?UTF-8?q?=E8=A7=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/core/FlowExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 21a474560..09bb822c5 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -90,7 +90,7 @@ public class FlowExecutor { return; } - List sourceRulePathList = Lists.newArrayList(liteflowConfig.getRuleSource().split(",|;")); + List sourceRulePathList = Lists.newArrayList(liteflowConfig.getRuleSource().split("[,;]")); FlowParser parser = null; Set parserNameSet = new HashSet<>(); From cad8fe37ae4d94823d313c32ca96bad5d9dfb31c Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Mon, 20 Jun 2022 23:07:55 +0800 Subject: [PATCH 2/8] =?UTF-8?q?test:=20=E4=BF=AE=E5=A4=8D=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=B1=BB=E8=BE=93=E5=87=BA=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/test/java/com/yomahub/liteflow/test/base/cmp/DCmp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/base/cmp/DCmp.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/base/cmp/DCmp.java index ab0317f69..bdf5ca9b3 100644 --- a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/base/cmp/DCmp.java +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/base/cmp/DCmp.java @@ -15,7 +15,7 @@ public class DCmp extends NodeComponent { @Override public void process() { - System.out.println("CCmp executed!"); + System.out.println("DCmp executed!"); } } From aefc00afa8ae119f5fb5157894c695daa60ca741 Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Sun, 26 Jun 2022 09:52:46 +0800 Subject: [PATCH 3/8] test: custom class parsing yml file --- .../CustomParserYmlSpringbootTest.java | 41 +++++++++++++++++++ .../parser/CustomYmlFlowParser.java | 23 +++++++++++ .../application-custom-yml.properties | 1 + 3 files changed, 65 insertions(+) create mode 100644 liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java create mode 100644 liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java create mode 100644 liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java new file mode 100644 index 000000000..84ba705e6 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java @@ -0,0 +1,41 @@ +package com.yomahub.liteflow.test.parsecustom; + +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.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +/** + * springboot环境的自定义yml parser单元测试 + * 主要测试自定义配置源类是否能引入springboot中的其他依赖 + *

+ * + * @author junjun + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/parsecustom/application-custom-yml.properties") +@SpringBootTest(classes = CustomParserYmlSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.parsecustom.cmp"}) +public class CustomParserYmlSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //测试springboot场景的自定义json parser + @Test + public void testYmlCustomParser() { + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "args"); + Assert.assertTrue(response.isSuccess()); + } +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java new file mode 100644 index 000000000..2aa770ece --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java @@ -0,0 +1,23 @@ +package com.yomahub.liteflow.test.parsecustom.parser; + +import com.yomahub.liteflow.parser.ClassYmlFlowParser; + +/** + * springboot环境的自定义yml parser单元测试 + * 主要测试自定义配置源类是否能引入springboot中的其他依赖 + *

+ * + * @author junjun + */ +public class CustomYmlFlowParser extends ClassYmlFlowParser { + + @Override + public String parseCustom() { + return "flow:\n" + + " chain:\n" + + " - name: chain1\n" + + " condition:\n" + + " - type: then\n" + + " value: 'a,b,c'"; + } +} diff --git a/liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties b/liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties new file mode 100644 index 000000000..263e0666c --- /dev/null +++ b/liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties @@ -0,0 +1 @@ +liteflow.rule-source=com.yomahub.liteflow.test.parsecustom.parser.CustomYmlFlowParser \ No newline at end of file From 3a7ddaac23689c3011aa1af9aa09aedd5548c28a Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Sun, 26 Jun 2022 09:56:07 +0800 Subject: [PATCH 4/8] =?UTF-8?q?refactoring:=20=E4=BD=BF=E7=94=A8=E6=8A=BD?= =?UTF-8?q?=E8=B1=A1=E5=B7=A5=E5=8E=82=E6=A8=A1=E5=BC=8F=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=E8=A7=A3=E6=9E=90=E5=99=A8=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 162 +++--------------- .../parser/factory/ClassParserFactory.java | 33 ++++ .../parser/factory/FlowParserFactory.java | 21 +++ .../parser/factory/FlowParserProvider.java | 122 +++++++++++++ .../parser/factory/LocalParserFactory.java | 27 +++ .../factory/ZookeeperParserFactory.java | 28 +++ 6 files changed, 251 insertions(+), 142 deletions(-) create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 09bb822c5..e13a7c6d4 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -14,25 +14,27 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; -import com.yomahub.liteflow.slot.DataBus; -import com.yomahub.liteflow.flow.LiteflowResponse; -import com.yomahub.liteflow.slot.DefaultContext; -import com.yomahub.liteflow.slot.Slot; -import com.yomahub.liteflow.flow.element.Chain; -import com.yomahub.liteflow.flow.element.Node; -import com.yomahub.liteflow.enums.FlowParserTypeEnum; import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; -import com.yomahub.liteflow.parser.*; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.flow.element.Chain; +import com.yomahub.liteflow.flow.element.Node; +import com.yomahub.liteflow.parser.FlowParser; +import com.yomahub.liteflow.parser.factory.FlowParserProvider; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.property.LiteflowConfigGetter; -import com.yomahub.liteflow.spi.holder.ContextAwareHolder; +import com.yomahub.liteflow.slot.DataBus; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.slot.Slot; import com.yomahub.liteflow.thread.ExecutorHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Future; /** * 流程规则主要执行器类 @@ -43,19 +45,8 @@ public class FlowExecutor { 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_JSON_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.json$"; - private static final String LOCAL_YML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.yml$"; - - private static final String FORMATE_XML_CONFIG_REGEX = "xml:.+"; - private static final String FORMATE_JSON_CONFIG_REGEX = "json:.+"; - private static final String FORMATE_YML_CONFIG_REGEX = "yml:.+"; private static final String PREFIX_FORMATE_CONFIG_REGEX = "xml:|json:|yml:"; - private static final String CLASS_CONFIG_REGEX = "^\\w+(\\.\\w+)*$"; - private LiteflowConfig liteflowConfig; public FlowExecutor() { @@ -90,6 +81,7 @@ public class FlowExecutor { return; } + // 获取配置文件地址,','或者';'分割 List sourceRulePathList = Lists.newArrayList(liteflowConfig.getRuleSource().split("[,;]")); FlowParser parser = null; @@ -97,36 +89,16 @@ public class FlowExecutor { List rulePathList = new ArrayList<>(); for (String path : sourceRulePathList) { try { - FlowParserTypeEnum pattern = matchFormatConfig(path); - if (ObjectUtil.isNotNull(pattern)) { - path = ReUtil.replaceAll(path, PREFIX_FORMATE_CONFIG_REGEX, ""); - switch (pattern) { - case TYPE_XML: - parser = matchFormatParser(path, FlowParserTypeEnum.TYPE_XML); - parserNameSet.add(parser.getClass().getName()); - break; - case TYPE_JSON: - parser = matchFormatParser(path, FlowParserTypeEnum.TYPE_JSON); - parserNameSet.add(parser.getClass().getName()); - break; - case TYPE_YML: - parser = matchFormatParser(path, FlowParserTypeEnum.TYPE_YML); - parserNameSet.add(parser.getClass().getName()); - break; - default: - String errorMsg = StrUtil.format("can't support the format {}", path); - throw new ErrorSupportPathException(errorMsg); - } - } + // 查找对应的解析器 + parser = FlowParserProvider.lookup(path); + parserNameSet.add(parser.getClass().getName()); + // 替换掉zk配置的前缀 + path = ReUtil.replaceAll(path, PREFIX_FORMATE_CONFIG_REGEX, ""); rulePathList.add(path); //支持多类型的配置文件,分别解析 if (liteflowConfig.isSupportMultipleType()) { - if (ObjectUtil.isNotNull(parser)) { - parser.parseMain(ListUtil.toList(path)); - } else { - throw new ConfigErrorException("parse error, please check liteflow config property"); - } + parser.parseMain(ListUtil.toList(path)); } } catch (CyclicDependencyException e){ LOG.error(e.getMessage()); @@ -165,100 +137,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(); - 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); - 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()); - 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); - } - - /** - * 判定是否为自定义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 (isClassConfig(path)) { - 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; - } - } catch (ClassNotFoundException e) { - LOG.error(e.getMessage()); - } - } - return null; - } - //此方法就是从原有的配置源主动拉取新的进行刷新 //和FlowBus.refreshFlowMetaData的区别就是一个为主动拉取,一个为被动监听到新的内容进行刷新 public void reloadRule() { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java new file mode 100644 index 000000000..926737100 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java @@ -0,0 +1,33 @@ +package com.yomahub.liteflow.parser.factory; + +import com.yomahub.liteflow.parser.JsonFlowParser; +import com.yomahub.liteflow.parser.XmlFlowParser; +import com.yomahub.liteflow.parser.YmlFlowParser; +import com.yomahub.liteflow.spi.holder.ContextAwareHolder; + +/** + * Class文件 + *

+ * + * @author junjun + */ +public class ClassParserFactory implements FlowParserFactory { + + @Override + public JsonFlowParser createJsonParser(String path) throws Exception { + Class c = Class.forName(path); + return (JsonFlowParser) ContextAwareHolder.loadContextAware().registerBean(c); + } + + @Override + public XmlFlowParser createXmlParser(String path) throws Exception { + Class c = Class.forName(path); + return (XmlFlowParser) ContextAwareHolder.loadContextAware().registerBean(c); + } + + @Override + public YmlFlowParser createYmlParser(String path) throws Exception { + Class c = Class.forName(path); + return (YmlFlowParser) ContextAwareHolder.loadContextAware().registerBean(c); + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java new file mode 100644 index 000000000..e84b755cf --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java @@ -0,0 +1,21 @@ +package com.yomahub.liteflow.parser.factory; + +import com.yomahub.liteflow.parser.JsonFlowParser; +import com.yomahub.liteflow.parser.XmlFlowParser; +import com.yomahub.liteflow.parser.YmlFlowParser; + +/** + * Flow Parser 工厂接口 + *

+ * + * @author junjun + */ +public interface FlowParserFactory { + + JsonFlowParser createJsonParser(String path) throws Exception; + + XmlFlowParser createXmlParser(String path) throws Exception; + + YmlFlowParser createYmlParser(String path) throws Exception; + +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java new file mode 100644 index 000000000..e29f0bdd1 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java @@ -0,0 +1,122 @@ +package com.yomahub.liteflow.parser.factory; + +import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.exception.ConfigErrorException; +import com.yomahub.liteflow.exception.ErrorSupportPathException; +import com.yomahub.liteflow.parser.ClassJsonFlowParser; +import com.yomahub.liteflow.parser.ClassXmlFlowParser; +import com.yomahub.liteflow.parser.ClassYmlFlowParser; +import com.yomahub.liteflow.parser.FlowParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.yomahub.liteflow.enums.FlowParserTypeEnum.*; + +/** + * 解析器提供者 + *

+ * + * @author junjun + */ +public class FlowParserProvider { + + private static final Logger LOG = LoggerFactory.getLogger(FlowExecutor.class); + + private static final String LOCAL_XML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.xml$"; + private static final String LOCAL_JSON_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.json$"; + private static final String LOCAL_YML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.yml$"; + + private static final String FORMATE_XML_CONFIG_REGEX = "xml:.+"; + private static final String FORMATE_JSON_CONFIG_REGEX = "json:.+"; + private static final String FORMATE_YML_CONFIG_REGEX = "yml:.+"; + + private static final String CLASS_CONFIG_REGEX = "^\\w+(\\.\\w+)*$"; + + /** + * 根据配置的地址找到对应的解析器 + * + * @param path + * @return + */ + public static FlowParser lookup(String path) throws Exception { + if (isLocalConfig(path)) { + FlowParserFactory factory = new LocalParserFactory(); + if (ReUtil.isMatch(LOCAL_XML_CONFIG_REGEX, path)) { + LOG.info("flow info loaded from local file,path={},format type={}", path, TYPE_XML.getType()); + return factory.createXmlParser(path); + } + else if (ReUtil.isMatch(LOCAL_JSON_CONFIG_REGEX, path)) { + LOG.info("flow info loaded from local file,path={},format type={}", path, TYPE_JSON.getType()); + return factory.createJsonParser(path); + } + else if (ReUtil.isMatch(LOCAL_YML_CONFIG_REGEX, path)) { + LOG.info("flow info loaded from local file,path={},format type={}", path, TYPE_YML.getType()); + return factory.createYmlParser(path); + } + } + else if (isClassConfig(path)) { + FlowParserFactory factory = new ClassParserFactory(); + Class clazz = Class.forName(path); + if (ClassXmlFlowParser.class.isAssignableFrom(clazz)) { + LOG.info("flow info loaded from class config,class={},format type={}", path, TYPE_XML.getType()); + return factory.createXmlParser(path); + } + else if (ClassJsonFlowParser.class.isAssignableFrom(clazz)) { + LOG.info("flow info loaded from class config,class={},format type={}", path, TYPE_JSON.getType()); + return factory.createJsonParser(path); + } + else if (ClassYmlFlowParser.class.isAssignableFrom(clazz)) { + LOG.info("flow info loaded from class config,class={},format type={}", path, TYPE_YML.getType()); + return factory.createYmlParser(path); + } + // 自定义类必须实现以上实现类,否则报错 + 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(FORMATE_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(FORMATE_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(FORMATE_YML_CONFIG_REGEX, path)) { + LOG.info("flow info loaded from Zookeeper,zkNode={},format type={}", path, TYPE_YML.getType()); + return factory.createYmlParser(path); + } + } + + // not found + throw new ConfigErrorException("parse error, please check liteflow config property"); + } + + /** + * 判定是否为本地文件 + */ + private static 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); + } + + /** + * 判定是否为自定义class配置 + */ + private static boolean isClassConfig(String path) { + return ReUtil.isMatch(CLASS_CONFIG_REGEX, path); + } + + /** + * 判定是否为zk配置 + */ + private static boolean isZKConfig(String path) { + return ReUtil.isMatch(FORMATE_XML_CONFIG_REGEX, path) + || ReUtil.isMatch(FORMATE_JSON_CONFIG_REGEX, path) + || ReUtil.isMatch(FORMATE_YML_CONFIG_REGEX, path); + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java new file mode 100644 index 000000000..c7b2962c3 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java @@ -0,0 +1,27 @@ +package com.yomahub.liteflow.parser.factory; + +import com.yomahub.liteflow.parser.*; + +/** + * 本地文件 + *

+ * + * @author junjun + */ +public class LocalParserFactory implements FlowParserFactory { + + @Override + public JsonFlowParser createJsonParser(String path) { + return new LocalJsonFlowParser(); + } + + @Override + public XmlFlowParser createXmlParser(String path) { + return new LocalXmlFlowParser(); + } + + @Override + public YmlFlowParser createYmlParser(String path) { + return new LocalYmlFlowParser(); + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java new file mode 100644 index 000000000..1a2369c6e --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java @@ -0,0 +1,28 @@ +package com.yomahub.liteflow.parser.factory; + +import com.yomahub.liteflow.parser.*; +import com.yomahub.liteflow.property.LiteflowConfigGetter; + +/** + * Class文件 + *

+ * + * @author junjun + */ +public class ZookeeperParserFactory implements FlowParserFactory { + + @Override + public JsonFlowParser createJsonParser(String path) { + return new ZookeeperJsonFlowParser(LiteflowConfigGetter.get().getZkNode()); + } + + @Override + public XmlFlowParser createXmlParser(String path) { + return new ZookeeperXmlFlowParser(LiteflowConfigGetter.get().getZkNode()); + } + + @Override + public YmlFlowParser createYmlParser(String path) { + return new ZookeeperYmlFlowParser(LiteflowConfigGetter.get().getZkNode()); + } +} From 1e1c9160d3d67cfac078fff4d65c3e7626a2cc41 Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Mon, 18 Jul 2022 23:05:02 +0800 Subject: [PATCH 5/8] test: custom class parsing yml file --- .../CustomParserYmlSpringbootTest.java | 40 +++++++++++++++++++ .../parser/CustomYmlFlowParser.java | 23 +++++++++++ .../application-custom-yml.properties | 1 + 3 files changed, 64 insertions(+) diff --git a/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java b/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java index e69de29bb..6094261bf 100644 --- a/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java +++ b/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlSpringbootTest.java @@ -0,0 +1,40 @@ +package com.yomahub.liteflow.test.parsecustom; + +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.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +/** + * springboot环境的自定义xml parser单元测试 + * 主要测试自定义配置源类是否能引入springboot中的其他依赖 + * @author bryan.zhang + * @since 2.5.7 + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/parsecustom/application-custom-yml.properties") +@SpringBootTest(classes = CustomParserXmlSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.parsecustom.cmp","com.yomahub.liteflow.test.parsecustom.bean"}) +public class CustomParserYmlSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //测试springboot场景的自定义json parser + @Test + public void testYmlCustomParser() { + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "args"); + Assert.assertTrue(response.isSuccess()); + } +} diff --git a/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java b/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java index e69de29bb..f2a56e314 100644 --- a/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java +++ b/liteflow-testcase-old/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java @@ -0,0 +1,23 @@ +package com.yomahub.liteflow.test.parsecustom.parser; + +import com.yomahub.liteflow.parser.ClassYmlFlowParser; + +/** + * springboot环境的自定义yml parser单元测试 + * 主要测试自定义配置源类是否能引入springboot中的其他依赖 + *

+ * + * @author junjun + */ +public class CustomYmlFlowParser extends ClassYmlFlowParser { + + @Override + public String parseCustom() { + return "flow:\n" + + " chain:\n" + + " - name: chain1\n" + + " condition:\n" + + " - type: then\n" + + " value: 'a,b,c'"; + } +} \ No newline at end of file diff --git a/liteflow-testcase-old/liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties b/liteflow-testcase-old/liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties index e69de29bb..263e0666c 100644 --- a/liteflow-testcase-old/liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties +++ b/liteflow-testcase-old/liteflow-testcase-springboot/src/test/resources/parsecustom/application-custom-yml.properties @@ -0,0 +1 @@ +liteflow.rule-source=com.yomahub.liteflow.test.parsecustom.parser.CustomYmlFlowParser \ No newline at end of file From 622669176de5d9245364b144473f1907f586bb98 Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Tue, 19 Jul 2022 22:32:30 +0800 Subject: [PATCH 6/8] test: custom el class parsing yml file --- .../CustomParserYmlELSpringbootTest.java | 39 +++++++++++++++++++ .../parser/CustomYmlFlowParser.java | 19 +++++++++ .../application-custom-yml.properties | 1 + 3 files changed, 59 insertions(+) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlELSpringbootTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/parsecustom/application-custom-yml.properties diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlELSpringbootTest.java new file mode 100644 index 000000000..0ca24257a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/CustomParserYmlELSpringbootTest.java @@ -0,0 +1,39 @@ +package com.yomahub.liteflow.test.parsecustom; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +/** + * springboot环境的自定义yml parser单元测试 + * 主要测试自定义配置源类是否能引入springboot中的其他依赖 + * + * @author junjun + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/parsecustom/application-custom-yml.properties") +@SpringBootTest(classes = CustomParserYmlELSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.parsecustom.cmp","com.yomahub.liteflow.test.parsecustom.bean"}) +public class CustomParserYmlELSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //测试springboot场景的自定义json parser + @Test + public void testYmlCustomParser() { + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "args"); + Assert.assertTrue(response.isSuccess()); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java new file mode 100644 index 000000000..3431a3d54 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/parsecustom/parser/CustomYmlFlowParser.java @@ -0,0 +1,19 @@ +package com.yomahub.liteflow.test.parsecustom.parser; + +import com.yomahub.liteflow.parser.el.ClassYmlFlowELParser; + +/** + * 模拟用户自定义源解析 + * + * @author junjun + */ +public class CustomYmlFlowParser extends ClassYmlFlowELParser { + @Override + public String parseCustom() { + //模拟自定义解析结果 + return "flow:\n" + + " chain:\n" + + " - name: chain1\n" + + " value: \"THEN(a, b, c);\""; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/parsecustom/application-custom-yml.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/parsecustom/application-custom-yml.properties new file mode 100644 index 000000000..c8e50b4f1 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/parsecustom/application-custom-yml.properties @@ -0,0 +1 @@ +liteflow.rule-source=el_yml:com.yomahub.liteflow.test.parsecustom.parser.CustomYmlFlowParser \ No newline at end of file From bbc41ecb8d1480a8ee7ea31cac3c2525831aa7e2 Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Tue, 19 Jul 2022 22:33:53 +0800 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E9=85=8D=E7=BD=AEpath=E6=9F=A5=E6=89=BE=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E7=9A=84=E8=A7=A3=E6=9E=90=E5=99=A8=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 196 +----------------- .../parser/factory/ClassParserFactory.java | 24 +++ .../parser/factory/FlowParserFactory.java | 19 +- .../parser/factory/FlowParserProvider.java | 103 +++++++-- .../parser/factory/LocalParserFactory.java | 16 ++ .../factory/ZookeeperParserFactory.java | 25 ++- 6 files changed, 165 insertions(+), 218 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 82d3e7563..9ec7a29f6 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -13,30 +13,19 @@ import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; -import com.google.common.collect.Lists; -import com.yomahub.liteflow.exception.*; -import com.yomahub.liteflow.flow.FlowBus; -import com.yomahub.liteflow.enums.FlowParserTypeEnum; import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.LiteflowResponse; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Node; -import com.yomahub.liteflow.parser.*; import com.yomahub.liteflow.parser.base.FlowParser; -import com.yomahub.liteflow.parser.el.*; -import com.yomahub.liteflow.parser.FlowParser; import com.yomahub.liteflow.parser.factory.FlowParserProvider; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.property.LiteflowConfigGetter; import com.yomahub.liteflow.slot.DataBus; import com.yomahub.liteflow.slot.DefaultContext; import com.yomahub.liteflow.slot.Slot; -import com.yomahub.liteflow.spi.holder.ContextAwareHolder; import com.yomahub.liteflow.spi.holder.ContextCmpInitHolder; -import com.yomahub.liteflow.slot.DataBus; -import com.yomahub.liteflow.slot.DefaultContext; -import com.yomahub.liteflow.slot.Slot; import com.yomahub.liteflow.thread.ExecutorHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,34 +45,7 @@ public class FlowExecutor { 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 PREFIX_FORMATE_CONFIG_REGEX = "xml:|json:|yml:"; + private static final String PREFIX_FORMAT_CONFIG_REGEX = "xml:|json:|yml:|el_xml:|el_json:|el_yml:"; private LiteflowConfig liteflowConfig; @@ -133,30 +95,11 @@ public class FlowExecutor { List rulePathList = new ArrayList<>(); for (String path : sourceRulePathList) { 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()); - + // 替换掉前缀标识(如:xml:/json:),保留剩下的完整地址 + path = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, ""); rulePathList.add(path); //支持多类型的配置文件,分别解析 @@ -203,135 +146,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的区别就是一个为主动拉取,一个为被动监听到新的内容进行刷新 public void reloadRule() { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java index 926737100..319b2aec9 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ClassParserFactory.java @@ -3,6 +3,12 @@ package com.yomahub.liteflow.parser.factory; import com.yomahub.liteflow.parser.JsonFlowParser; import com.yomahub.liteflow.parser.XmlFlowParser; import com.yomahub.liteflow.parser.YmlFlowParser; +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.JsonFlowELParser; +import com.yomahub.liteflow.parser.el.XmlFlowELParser; +import com.yomahub.liteflow.parser.el.YmlFlowELParser; import com.yomahub.liteflow.spi.holder.ContextAwareHolder; /** @@ -30,4 +36,22 @@ public class ClassParserFactory implements FlowParserFactory { Class c = Class.forName(path); return (YmlFlowParser) ContextAwareHolder.loadContextAware().registerBean(c); } + + @Override + public BaseJsonFlowParser createJsonELParser(String path) throws Exception { + Class c = Class.forName(path); + return (JsonFlowELParser) ContextAwareHolder.loadContextAware().registerBean(c); + } + + @Override + public BaseXmlFlowParser createXmlELParser(String path) throws Exception { + Class c = Class.forName(path); + return (XmlFlowELParser) ContextAwareHolder.loadContextAware().registerBean(c); + } + + @Override + public BaseYmlFlowParser createYmlELParser(String path) throws Exception { + Class c = Class.forName(path); + return (YmlFlowELParser) ContextAwareHolder.loadContextAware().registerBean(c); + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java index e84b755cf..f3d4c7e07 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserFactory.java @@ -3,6 +3,12 @@ package com.yomahub.liteflow.parser.factory; import com.yomahub.liteflow.parser.JsonFlowParser; import com.yomahub.liteflow.parser.XmlFlowParser; import com.yomahub.liteflow.parser.YmlFlowParser; +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.JsonFlowELParser; +import com.yomahub.liteflow.parser.el.XmlFlowELParser; +import com.yomahub.liteflow.parser.el.YmlFlowELParser; /** * Flow Parser 工厂接口 @@ -12,10 +18,17 @@ import com.yomahub.liteflow.parser.YmlFlowParser; */ public interface FlowParserFactory { - JsonFlowParser createJsonParser(String path) throws Exception; + BaseJsonFlowParser createJsonParser(String path) throws Exception; - XmlFlowParser createXmlParser(String path) throws Exception; + BaseXmlFlowParser createXmlParser(String path) throws Exception; + + BaseYmlFlowParser createYmlParser(String path) throws Exception; + + BaseJsonFlowParser createJsonELParser(String path) throws Exception; + + BaseXmlFlowParser createXmlELParser(String path) throws Exception; + + BaseYmlFlowParser createYmlELParser(String path) throws Exception; - YmlFlowParser createYmlParser(String path) throws Exception; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java index e29f0bdd1..814e152f7 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/FlowParserProvider.java @@ -3,12 +3,14 @@ package com.yomahub.liteflow.parser.factory; import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.core.FlowExecutor; -import com.yomahub.liteflow.exception.ConfigErrorException; import com.yomahub.liteflow.exception.ErrorSupportPathException; import com.yomahub.liteflow.parser.ClassJsonFlowParser; import com.yomahub.liteflow.parser.ClassXmlFlowParser; import com.yomahub.liteflow.parser.ClassYmlFlowParser; -import com.yomahub.liteflow.parser.FlowParser; +import com.yomahub.liteflow.parser.base.FlowParser; +import com.yomahub.liteflow.parser.el.ClassJsonFlowELParser; +import com.yomahub.liteflow.parser.el.ClassXmlFlowELParser; +import com.yomahub.liteflow.parser.el.ClassYmlFlowELParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,11 +30,29 @@ public class FlowParserProvider { private static final String LOCAL_JSON_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.json$"; private static final String LOCAL_YML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.yml$"; - private static final String FORMATE_XML_CONFIG_REGEX = "xml:.+"; - private static final String FORMATE_JSON_CONFIG_REGEX = "json:.+"; - private static final String FORMATE_YML_CONFIG_REGEX = "yml:.+"; + private static final String LOCAL_EL_XML_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.el\\.xml$"; - private static final String CLASS_CONFIG_REGEX = "^\\w+(\\.\\w+)*$"; + private static final String LOCAL_EL_JSON_CONFIG_REGEX = "^[\\w\\:\\-\\@\\/\\\\\\*]+\\.el\\.json$"; + + 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)+)*"; /** * 根据配置的地址找到对应的解析器 @@ -55,21 +75,47 @@ public class FlowParserProvider { LOG.info("flow info loaded from local file,path={},format type={}", path, TYPE_YML.getType()); return factory.createYmlParser(path); } + else if (ReUtil.isMatch(LOCAL_EL_XML_CONFIG_REGEX, path)) { + LOG.info("flow info loaded from local EL file,path={},format type={}", path, TYPE_EL_XML.getType()); + return factory.createXmlELParser(path); + } + else if (ReUtil.isMatch(LOCAL_EL_JSON_CONFIG_REGEX, path)) { + LOG.info("flow info loaded from local EL file,path={},format type={}", path, TYPE_EL_JSON.getType()); + return factory.createJsonELParser(path); + } + else if (ReUtil.isMatch(LOCAL_EL_YML_CONFIG_REGEX, path)) { + LOG.info("flow info loaded from local EL file,path={},format type={}", path, TYPE_EL_YML.getType()); + return factory.createYmlELParser(path); + } } else if (isClassConfig(path)) { + // 获取最终的className,因为有些可能className前面带了文件类型的标识,比如json:x.x.x.x + String className = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, ""); FlowParserFactory factory = new ClassParserFactory(); - Class clazz = Class.forName(path); + Class clazz = Class.forName(className); if (ClassXmlFlowParser.class.isAssignableFrom(clazz)) { - LOG.info("flow info loaded from class config,class={},format type={}", path, TYPE_XML.getType()); - return factory.createXmlParser(path); + LOG.info("flow info loaded from class config,class={},format type={}", className, TYPE_XML.getType()); + return factory.createXmlParser(className); } else if (ClassJsonFlowParser.class.isAssignableFrom(clazz)) { - LOG.info("flow info loaded from class config,class={},format type={}", path, TYPE_JSON.getType()); - return factory.createJsonParser(path); + LOG.info("flow info loaded from class config,class={},format type={}", className, TYPE_JSON.getType()); + return factory.createJsonParser(className); } else if (ClassYmlFlowParser.class.isAssignableFrom(clazz)) { - LOG.info("flow info loaded from class config,class={},format type={}", path, TYPE_YML.getType()); - return factory.createYmlParser(path); + LOG.info("flow info loaded from class config,class={},format type={}", className, TYPE_YML.getType()); + return factory.createYmlParser(className); + } + else if (ClassXmlFlowELParser.class.isAssignableFrom(clazz)) { + LOG.info("flow info loaded from class config with el,class={},format type={}", className, TYPE_EL_XML.getType()); + return factory.createXmlELParser(className); + } + else if (ClassJsonFlowELParser.class.isAssignableFrom(clazz)) { + LOG.info("flow info loaded from class config with el,class={},format type={}", className, TYPE_EL_JSON.getType()); + return factory.createJsonELParser(className); + } + else if (ClassYmlFlowELParser.class.isAssignableFrom(clazz)) { + LOG.info("flow info loaded from class config with el,class={},format type={}", className, TYPE_EL_YML.getType()); + return factory.createYmlELParser(className); } // 自定义类必须实现以上实现类,否则报错 String errorMsg = StrUtil.format("can't support the format {}", path); @@ -77,22 +123,36 @@ public class FlowParserProvider { } else if (isZKConfig(path)) { FlowParserFactory factory = new ZookeeperParserFactory(); - if (ReUtil.isMatch(FORMATE_XML_CONFIG_REGEX, path)) { + 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(FORMATE_JSON_CONFIG_REGEX, 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(FORMATE_YML_CONFIG_REGEX, 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 - throw new ConfigErrorException("parse error, please check liteflow config property"); + String errorMsg = StrUtil.format("can't find the parser for path:{}", path); + throw new ErrorSupportPathException(errorMsg); } /** @@ -101,7 +161,10 @@ public class FlowParserProvider { private static 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_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); } /** @@ -115,8 +178,6 @@ public class FlowParserProvider { * 判定是否为zk配置 */ private static boolean isZKConfig(String path) { - return ReUtil.isMatch(FORMATE_XML_CONFIG_REGEX, path) - || ReUtil.isMatch(FORMATE_JSON_CONFIG_REGEX, path) - || ReUtil.isMatch(FORMATE_YML_CONFIG_REGEX, path); + return ReUtil.isMatch(ZK_CONFIG_REGEX, path); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java index c7b2962c3..89a6b88a1 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/LocalParserFactory.java @@ -1,6 +1,7 @@ package com.yomahub.liteflow.parser.factory; import com.yomahub.liteflow.parser.*; +import com.yomahub.liteflow.parser.el.*; /** * 本地文件 @@ -24,4 +25,19 @@ public class LocalParserFactory implements FlowParserFactory { public YmlFlowParser createYmlParser(String path) { return new LocalYmlFlowParser(); } + + @Override + public JsonFlowELParser createJsonELParser(String path) { + return new LocalJsonFlowELParser(); + } + + @Override + public XmlFlowELParser createXmlELParser(String path) { + return new LocalXmlFlowELParser(); + } + + @Override + public YmlFlowELParser createYmlELParser(String path) { + return new LocalYmlFlowELParser(); + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java index 1a2369c6e..deec5f84d 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/factory/ZookeeperParserFactory.java @@ -1,6 +1,10 @@ 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; /** @@ -12,17 +16,32 @@ import com.yomahub.liteflow.property.LiteflowConfigGetter; public class ZookeeperParserFactory implements FlowParserFactory { @Override - public JsonFlowParser createJsonParser(String path) { + public BaseJsonFlowParser createJsonParser(String path) { return new ZookeeperJsonFlowParser(LiteflowConfigGetter.get().getZkNode()); } @Override - public XmlFlowParser createXmlParser(String path) { + public BaseXmlFlowParser createXmlParser(String path) { return new ZookeeperXmlFlowParser(LiteflowConfigGetter.get().getZkNode()); } @Override - public YmlFlowParser createYmlParser(String path) { + 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()); + } } From c076f87d15dba47765da3c5e8ce40abf0cf0349e Mon Sep 17 00:00:00 2001 From: "119431682@qq.com" <119431682@qq.com> Date: Tue, 19 Jul 2022 22:44:52 +0800 Subject: [PATCH 8/8] chore: un import --- .../src/main/java/com/yomahub/liteflow/core/FlowExecutor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index ef7076e5b..e9177885f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -19,7 +19,6 @@ import com.yomahub.liteflow.flow.LiteflowResponse; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Node; import com.yomahub.liteflow.flow.id.IdGeneratorHolder; -import com.yomahub.liteflow.parser.*; import com.yomahub.liteflow.parser.base.FlowParser; import com.yomahub.liteflow.parser.factory.FlowParserProvider; import com.yomahub.liteflow.property.LiteflowConfig;