diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index cbc068e0a..26eae68ff 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -69,6 +69,7 @@ public class LiteFlowChainELBuilder { EXPRESS_RUNNER.addFunction("WHILE", new WhileOperator()); EXPRESS_RUNNER.addFunctionAndClassMethod("DO", Object.class, new DoOperator()); EXPRESS_RUNNER.addFunctionAndClassMethod("BREAK", Object.class, new BreakOperator()); + EXPRESS_RUNNER.addFunctionAndClassMethod("data", Object.class, new DataOperator()); } public static LiteFlowChainELBuilder createChain() { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/DataOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/DataOperator.java new file mode 100644 index 000000000..da22cab75 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/DataOperator.java @@ -0,0 +1,27 @@ +package com.yomahub.liteflow.builder.el.operator; + +import com.yomahub.liteflow.builder.el.operator.base.BaseOperator; +import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper; +import com.yomahub.liteflow.flow.element.Node; + +/** + * EL规则中的data的操作符 + * + * @author Bryan.Zhang + * @since 2.8.0 + */ +public class DataOperator extends BaseOperator { + + @Override + public Node build(Object[] objects) throws Exception { + OperatorHelper.checkObjectSizeEqTwo(objects); + + Node node = OperatorHelper.convert(objects[0], Node.class); + + String cmpData = OperatorHelper.convert(objects[1], String.class); + + node.setCmpData(cmpData); + + return node; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java index e9d36be3a..f9e22322a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java @@ -16,6 +16,7 @@ import com.yomahub.liteflow.flow.executor.NodeExecutor; import com.yomahub.liteflow.flow.executor.DefaultNodeExecutor; import com.yomahub.liteflow.enums.NodeTypeEnum; import com.yomahub.liteflow.spi.holder.CmpAroundAspectHolder; +import com.yomahub.liteflow.util.JsonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.yomahub.liteflow.flow.entity.CmpStep; @@ -71,6 +72,9 @@ public abstract class NodeComponent{ //当前流程名字 private final TransmittableThreadLocal currChainNameTL = new TransmittableThreadLocal<>(); + //组件外部参数 + private final TransmittableThreadLocal cmpDataTL = new TransmittableThreadLocal<>(); + public NodeComponent() { } @@ -325,6 +329,21 @@ public abstract class NodeComponent{ this.currChainNameTL.remove(); } + public void setCmpData(String cmpData){ + this.cmpDataTL.set(cmpData); + } + + public T getCmpData(Class clazz){ + if (StrUtil.isBlank(this.cmpDataTL.get())){ + return null; + } + return JsonUtil.parseObject(this.cmpDataTL.get(), clazz); + } + + public void removeCmpData(){ + this.cmpDataTL.remove(); + } + public void invoke(String chainId, Object param) throws Exception { FlowExecutorHolder.loadInstance().invoke(chainId, param, this.getSlotIndex()); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java index bafdbb9ee..21019395b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java @@ -48,6 +48,8 @@ public class Node implements Executable,Cloneable{ private String tag; + private String cmpData; + public Node(){ } @@ -105,6 +107,7 @@ public class Node implements Executable,Cloneable{ //把线程属性赋值给组件对象 instance.setSlotIndex(slotIndex); instance.setTag(tag); + instance.setCmpData(cmpData); LiteflowConfig liteflowConfig = LiteflowConfigGetter.get(); @@ -147,6 +150,7 @@ public class Node implements Executable,Cloneable{ instance.removeIsEnd(); instance.removeTag(); instance.removeCurrChainName(); + instance.removeCmpData(); } } @@ -207,4 +211,12 @@ public class Node implements Executable,Cloneable{ public void setCurrChainName(String currentChainName) { instance.setCurrChainName(currentChainName); } + + public String getCmpData() { + return cmpData; + } + + public void setCmpData(String cmpData) { + this.cmpData = cmpData; + } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/CmpDataELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/CmpDataELSpringbootTest.java new file mode 100644 index 000000000..ef3e9c965 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/CmpDataELSpringbootTest.java @@ -0,0 +1,45 @@ +package com.yomahub.liteflow.test.cmpData; + +import cn.hutool.core.date.DateUtil; +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 com.yomahub.liteflow.test.cmpData.vo.User; +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环境EL常规的例子测试 + * @author Bryan.Zhang + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/cmpData/application.properties") +@SpringBootTest(classes = CmpDataELSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.cmpData.cmp"}) +public class CmpDataELSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + //最简单的情况 + @Test + public void testCmpData() throws Exception{ + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assert.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + User user = context.getData("user"); + Assert.assertEquals(27, user.getAge()); + Assert.assertEquals("jack", user.getName()); + Assert.assertEquals(0, user.getBirth().compareTo(DateUtil.parseDate("1995-10-01").toJdkDate())); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/ACmp.java new file mode 100644 index 000000000..a084f84d1 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/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.cmpData.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/BCmp.java new file mode 100644 index 000000000..ab6061970 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/BCmp.java @@ -0,0 +1,26 @@ +/** + *

Title: liteflow

+ *

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

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.cmpData.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.cmpData.vo.User; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + User user = this.getCmpData(User.class); + DefaultContext context = this.getFirstContextBean(); + context.setData("user", user); + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/CCmp.java new file mode 100644 index 000000000..72b022fea --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/cmp/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.cmpData.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/vo/User.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/vo/User.java new file mode 100644 index 000000000..483a78dd6 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/cmpData/vo/User.java @@ -0,0 +1,36 @@ +package com.yomahub.liteflow.test.cmpData.vo; + +import java.util.Date; + +public class User { + + private String name; + + private int age; + + private Date birth; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Date getBirth() { + return birth; + } + + public void setBirth(Date birth) { + this.birth = birth; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/cmpData/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/cmpData/application.properties new file mode 100644 index 000000000..2bb38b038 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/cmpData/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=cmpData/flow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/cmpData/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/cmpData/flow.xml new file mode 100644 index 000000000..a1d624342 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/cmpData/flow.xml @@ -0,0 +1,12 @@ + + + + cmpData = '{"name":"jack","age":27,"birth":"1995-10-01"}'; + + THEN( + a, + b.data(cmpData), + c + ); + + \ No newline at end of file