From 25438c17fecc5377f2aabbbd3ef8e1bbe79cca0b Mon Sep 17 00:00:00 2001 From: bryan31 Date: Tue, 20 Apr 2021 19:04:22 +0800 Subject: [PATCH] =?UTF-8?q?feature=20#I3N2E2=20=E6=94=AF=E6=8C=81=E7=BC=96?= =?UTF-8?q?=E7=A8=8B=E6=97=B6=E5=BC=8F=E7=9A=84=E6=B3=A8=E5=86=8C=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComponentCannotRegisterException.java | 27 +++++++++++++ .../com/yomahub/liteflow/flow/FlowBus.java | 40 ++++++++++++++++++- .../liteflow/parser/XmlFlowParser.java | 20 +--------- .../liteflow/property/LiteflowConfig.java | 16 ++++++++ .../springboot/LiteflowExecutorInit.java | 1 + .../LiteflowMainAutoConfiguration.java | 2 + .../liteflow/springboot/LiteflowProperty.java | 12 ++++++ .../LiteflowPropertyAutoConfiguration.java | 1 + ...itional-spring-configuration-metadata.json | 7 ++++ .../META-INF/liteflow-default.properties | 1 + .../config/LiteflowConfigSpringbootTest.java | 1 + .../test/flowmeta/FlowMetaSpringbootTest.java | 38 ++++++++++++++++++ .../liteflow/test/flowmeta/cmp1/ACmp.java | 20 ++++++++++ .../liteflow/test/flowmeta/cmp1/BCmp.java | 21 ++++++++++ .../liteflow/test/flowmeta/cmp1/CCmp.java | 21 ++++++++++ .../liteflow/test/flowmeta/cmp2/DCmp.java | 21 ++++++++++ .../resources/flowmeta/application.properties | 2 + .../src/test/resources/flowmeta/flow.xml | 6 +++ .../src/main/resources/application.properties | 3 +- 19 files changed, 237 insertions(+), 23 deletions(-) create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/exception/ComponentCannotRegisterException.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/FlowMetaSpringbootTest.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/ACmp.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/BCmp.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/CCmp.java create mode 100644 liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp2/DCmp.java create mode 100644 liteflow-spring-boot-starter/src/test/resources/flowmeta/application.properties create mode 100644 liteflow-spring-boot-starter/src/test/resources/flowmeta/flow.xml diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ComponentCannotRegisterException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ComponentCannotRegisterException.java new file mode 100644 index 000000000..7f955ca5d --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ComponentCannotRegisterException.java @@ -0,0 +1,27 @@ + +package com.yomahub.liteflow.exception; + +/** + * 流程规则主要执行器类 + * @author Bryan.Zhang + * @since 2.5.3 + */ +public class ComponentCannotRegisterException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** 异常信息 */ + private String message; + + public ComponentCannotRegisterException(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java index 442a7289a..bbe88e339 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java @@ -12,9 +12,15 @@ import java.util.Map; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.yomahub.liteflow.core.NodeComponent; import com.yomahub.liteflow.entity.flow.Chain; import com.yomahub.liteflow.entity.flow.Node; +import com.yomahub.liteflow.exception.ComponentCannotRegisterException; import com.yomahub.liteflow.util.SpringAware; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * 流程元数据类 @@ -22,9 +28,11 @@ import com.yomahub.liteflow.util.SpringAware; */ public class FlowBus { - private static Map chainMap = new HashMap<>(); + private static final Logger LOG = LoggerFactory.getLogger(FlowBus.class); - private static Map nodeMap = new HashMap<>(); + private static final Map chainMap = new HashMap<>(); + + private static final Map nodeMap = new HashMap<>(); private FlowBus() { } @@ -56,6 +64,34 @@ public class FlowBus { nodeMap.put(nodeId, node); } + public static void addNode(String nodeId, String cmpClazzStr) throws Exception{ + Class cmpClazz = (Class)Class.forName(cmpClazzStr); + addNode(nodeId, cmpClazz); + } + + public static void addNode(String nodeId, Class cmpClazz){ + try{ + Node node = new Node(); + node.setId(nodeId); + node.setClazz(cmpClazz.getName()); + //以node方式配置,本质上是为了适配无spring的环境,如果有spring环境,其实不用这么配置 + //这里的逻辑是判断是否能从spring上下文中取到,如果没有spring,则就是new instance了 + NodeComponent cmpInstance = SpringAware.registerOrGet(cmpClazz); + if (ObjectUtil.isNull(cmpInstance)) { + LOG.warn("couldn't find component class [{}] from spring context", cmpClazz.getName()); + cmpInstance = cmpClazz.newInstance(); + } + cmpInstance.setNodeId(nodeId); + cmpInstance.setSelf(cmpInstance); + node.setInstance(cmpInstance); + nodeMap.put(nodeId,node); + }catch (Exception e){ + String error = StrUtil.format("component[{}] register error", cmpClazz.getName()); + LOG.error(error, e); + throw new ComponentCannotRegisterException(error); + } + } + public static Node getNode(String nodeId) { return nodeMap.get(nodeId); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java index 50bff014f..64f83a92e 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/XmlFlowParser.java @@ -47,28 +47,10 @@ public abstract class XmlFlowParser extends FlowParser{ List nodeList = rootElement.element("nodes").elements("node"); String id; String clazz; - Node node; - NodeComponent component; - Class nodeComponentClass; for (Element e : nodeList) { - node = new Node(); id = e.attributeValue("id"); clazz = e.attributeValue("class"); - node.setId(id); - node.setClazz(clazz); - nodeComponentClass = (Class)Class.forName(clazz); - - //以node方式配置,本质上是为了适配无spring的环境,如果有spring环境,其实不用这么配置 - //这里的逻辑是判断是否能从spring上下文中取到,如果没有spring,则就是new instance了 - component = SpringAware.registerOrGet(nodeComponentClass); - if (ObjectUtil.isNull(component)) { - LOG.error("couldn't find component class [{}] from spring context", clazz); - component = nodeComponentClass.newInstance(); - } - component.setNodeId(id); - component.setSelf(component); - node.setInstance(component); - FlowBus.addNode(id, node); + FlowBus.addNode(id, clazz); } } else { for (Entry componentEntry : ComponentScanner.nodeComponentMap.entrySet()) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java index d18231e27..ffa13e479 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java @@ -45,6 +45,10 @@ public class LiteflowConfig { //异步线程池最大队列数量 private Integer whenQueueLimit; + //是否在启动时解析规则文件 + //这个参数主要给编码式注册元数据的场景用的,结合FlowBus.addNode一起用 + private Boolean parseOnStart; + public String getRuleSource() { return ruleSource; } @@ -148,4 +152,16 @@ public class LiteflowConfig { public void setWhenQueueLimit(Integer whenQueueLimit) { this.whenQueueLimit = whenQueueLimit; } + + public Boolean isParseOnStart() { + if (ObjectUtil.isNull(parseOnStart)){ + return true; + }else{ + return parseOnStart; + } + } + + public void setParseOnStart(Boolean parseOnStart) { + this.parseOnStart = parseOnStart; + } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowExecutorInit.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowExecutorInit.java index de3a6bd79..146d944d7 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowExecutorInit.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowExecutorInit.java @@ -2,6 +2,7 @@ package com.yomahub.liteflow.springboot; import com.yomahub.liteflow.core.FlowExecutor; import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; /** * 执行器初始化类 diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowMainAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowMainAutoConfiguration.java index 0877f73d3..dc03c0156 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowMainAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowMainAutoConfiguration.java @@ -7,6 +7,7 @@ import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.util.SpringAware; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -35,6 +36,7 @@ public class LiteflowMainAutoConfiguration { } @Bean + @ConditionalOnProperty(prefix = "liteflow",name = "parse-on-start",havingValue = "true") public LiteflowExecutorInit liteflowExecutorInit(FlowExecutor flowExecutor) { return new LiteflowExecutorInit(flowExecutor); } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index 8f538eb48..1eebe7480 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -24,6 +24,10 @@ public class LiteflowProperty { //异步线程池最大队列数量 private int whenQueueLimit; + //是否在启动时解析规则文件 + //这个参数主要给编码式注册元数据的场景用的,结合FlowBus.addNode一起用 + private boolean parseOnStart; + public String getRuleSource() { return ruleSource; } @@ -63,4 +67,12 @@ public class LiteflowProperty { public void setWhenQueueLimit(int whenQueueLimit) { this.whenQueueLimit = whenQueueLimit; } + + public boolean isParseOnStart() { + return parseOnStart; + } + + public void setParseOnStart(boolean parseOnStart) { + this.parseOnStart = parseOnStart; + } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowPropertyAutoConfiguration.java index 6d773f3e3..9cb48d441 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowPropertyAutoConfiguration.java @@ -33,6 +33,7 @@ public class LiteflowPropertyAutoConfiguration { liteflowConfig.setPeriod(liteflowMonitorProperty.getPeriod()); liteflowConfig.setWhenMaxWorkers(property.getWhenMaxWorkers()); liteflowConfig.setWhenQueueLimit(property.getWhenQueueLimit()); + liteflowConfig.setParseOnStart(property.isParseOnStart()); return liteflowConfig; } } diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 8df0e24cf..cb078d704 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -33,6 +33,13 @@ "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty", "defaultValue": 512 }, + { + "name": "liteflow.parse-on-start", + "type": "java.lang.Boolean", + "description": "Set whether the rule file needs to be parsed at startup.", + "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty", + "defaultValue": true + }, { "name": "liteflow.monitor.enable-log", "type": "java.lang.Boolean", diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties index 832357d8e..3ab95331f 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties @@ -3,6 +3,7 @@ liteflow.slot-size=1024 liteflow.when-max-wait-seconds=15 liteflow.when-max-workers=4 liteflow.when-queue-limit=512 +liteflow.parse-on-start=true liteflow.monitor.enable-log=false liteflow.monitor.queue-limit=200 liteflow.monitor.delay=300000 diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/config/LiteflowConfigSpringbootTest.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/config/LiteflowConfigSpringbootTest.java index 8ad6a23f9..bd80d2f7c 100644 --- a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/config/LiteflowConfigSpringbootTest.java +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/config/LiteflowConfigSpringbootTest.java @@ -48,5 +48,6 @@ public class LiteflowConfigSpringbootTest extends BaseTest { Assert.assertFalse(config.getEnableLog()); Assert.assertEquals(4, config.getWhenMaxWorkers().longValue()); Assert.assertEquals(512, config.getWhenQueueLimit().longValue()); + Assert.assertEquals(true, config.isParseOnStart()); } } diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/FlowMetaSpringbootTest.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/FlowMetaSpringbootTest.java new file mode 100644 index 000000000..f3d7b00f1 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/FlowMetaSpringbootTest.java @@ -0,0 +1,38 @@ +package com.yomahub.liteflow.test.flowmeta; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.entity.data.DefaultSlot; +import com.yomahub.liteflow.entity.data.LiteflowResponse; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.test.BaseTest; +import com.yomahub.liteflow.test.flowmeta.cmp2.DCmp; +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; + +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/flowmeta/application.properties") +@SpringBootTest(classes = FlowMetaSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.flowmeta.cmp1"}) +public class FlowMetaSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //测试自定义AOP,串行场景 + @Test + public void testFlowMeta() { + FlowBus.addNode("d", DCmp.class); + LiteflowResponse response= flowExecutor.execute2Resp("chain1", "it's a request"); + Assert.assertTrue(response.isSuccess()); + Assert.assertEquals("a==>b==>c==>d", response.getSlot().printStep()); + } +} diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/ACmp.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/ACmp.java new file mode 100644 index 000000000..4df6c78fa --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.flowmeta.cmp1; + +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!"); + } +} diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/BCmp.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/BCmp.java new file mode 100644 index 000000000..f6ef80cb6 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.flowmeta.cmp1; + +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!"); + } + +} diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/CCmp.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/CCmp.java new file mode 100644 index 000000000..ed599b642 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp1/CCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.flowmeta.cmp1; + +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!"); + } + +} diff --git a/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp2/DCmp.java b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp2/DCmp.java new file mode 100644 index 000000000..9bb5283b9 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/java/com/yomahub/liteflow/test/flowmeta/cmp2/DCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.flowmeta.cmp2; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("d") +public class DCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("Dcomp executed!"); + } + +} diff --git a/liteflow-spring-boot-starter/src/test/resources/flowmeta/application.properties b/liteflow-spring-boot-starter/src/test/resources/flowmeta/application.properties new file mode 100644 index 000000000..83834c85b --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/resources/flowmeta/application.properties @@ -0,0 +1,2 @@ +liteflow.rule-source=flowmeta/flow.xml +liteflow.parse-on-start=false \ No newline at end of file diff --git a/liteflow-spring-boot-starter/src/test/resources/flowmeta/flow.xml b/liteflow-spring-boot-starter/src/test/resources/flowmeta/flow.xml new file mode 100644 index 000000000..7153add87 --- /dev/null +++ b/liteflow-spring-boot-starter/src/test/resources/flowmeta/flow.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/liteflow-test-springboot/src/main/resources/application.properties b/liteflow-test-springboot/src/main/resources/application.properties index c20ae8aa2..18986c1a7 100644 --- a/liteflow-test-springboot/src/main/resources/application.properties +++ b/liteflow-test-springboot/src/main/resources/application.properties @@ -5,5 +5,4 @@ liteflow.rule-source=config/flow.json;com.yomahub.flowtest.custom.CustomXmlClass liteflow.when-max-wait-seconds=20 liteflow.monitor.enable-log=true liteflow.monitor.queue-limit=300 -liteflow.monitor.delay=10000 -#liteflow.monitor.period=10000 \ No newline at end of file +liteflow.monitor.delay=10000 \ No newline at end of file