1
0
Эх сурвалжийг харах

feature #I5WNMG 脚本组件支持javascript的语法

everywhere.z 2 жил өмнө
parent
commit
96f55b2ee8
16 өөрчлөгдсөн 345 нэмэгдсэн , 2 устгасан
  1. 0 1
      liteflow-script-plugin/liteflow-script-groovy/src/main/java/com/yomahub/liteflow/script/groovy/GroovyScriptExecutor.java
  2. 23 0
      liteflow-script-plugin/liteflow-script-javascript/pom.xml
  3. 103 0
      liteflow-script-plugin/liteflow-script-javascript/src/main/java/com/yomahub/liteflow/script/javascript/JavaScriptExecutor.java
  4. 2 0
      liteflow-script-plugin/liteflow-script-javascript/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor
  5. 1 0
      liteflow-script-plugin/pom.xml
  6. 33 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/pom.xml
  7. 20 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java
  8. 45 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/LiteflowXmlScriptJsELTest.java
  9. 20 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/ACmp.java
  10. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/BCmp.java
  11. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/CCmp.java
  12. 24 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/DCmp.java
  13. 1 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/common/application.properties
  14. 29 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/common/flow.xml
  15. 1 0
      liteflow-testcase-el/pom.xml
  16. 1 1
      pom.xml

+ 0 - 1
liteflow-script-plugin/liteflow-script-groovy/src/main/java/com/yomahub/liteflow/script/groovy/GroovyScriptExecutor.java

@@ -16,7 +16,6 @@ import org.slf4j.LoggerFactory;
 
 import javax.script.*;
 import java.util.Map;
-import java.util.function.Consumer;
 
 /**
  * Groovy脚本语言的执行器实现

+ 23 - 0
liteflow-script-plugin/liteflow-script-javascript/pom.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>liteflow-script-plugin</artifactId>
+        <groupId>com.yomahub</groupId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>liteflow-script-javascript</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.yomahub</groupId>
+            <artifactId>liteflow-core</artifactId>
+            <version>${revision}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 103 - 0
liteflow-script-plugin/liteflow-script-javascript/src/main/java/com/yomahub/liteflow/script/javascript/JavaScriptExecutor.java

@@ -0,0 +1,103 @@
+package com.yomahub.liteflow.script.javascript;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.script.ScriptBeanManager;
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
+import com.yomahub.liteflow.slot.DataBus;
+import com.yomahub.liteflow.slot.Slot;
+import com.yomahub.liteflow.script.ScriptExecutor;
+import com.yomahub.liteflow.script.exception.ScriptExecuteException;
+import com.yomahub.liteflow.script.exception.ScriptLoadException;
+import com.yomahub.liteflow.util.CopyOnWriteHashMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.script.*;
+import java.util.Map;
+
+/**
+ * JavaScript脚本语言的执行器实现
+ * @author Bryan.Zhang
+ * @since 2.9.1
+ */
+public class JavaScriptExecutor implements ScriptExecutor {
+
+    private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+    private ScriptEngine scriptEngine;
+
+    private final Map<String, CompiledScript> compiledScriptMap = new CopyOnWriteHashMap<>();
+
+    @Override
+    public ScriptExecutor init() {
+        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
+        scriptEngine = scriptEngineManager.getEngineByName("javascript");
+        return this;
+    }
+
+    @Override
+    public void load(String nodeId, String script) {
+        try{
+            CompiledScript compiledScript = ((Compilable) scriptEngine).compile(script);
+            compiledScriptMap.put(nodeId, compiledScript);
+        }catch (Exception e){
+            String errorMsg = StrUtil.format("script loading error for node[{}], error msg:{}", nodeId, e.getMessage());
+            throw new ScriptLoadException(errorMsg);
+        }
+
+    }
+
+    @Override
+    public Object execute(ScriptExecuteWrap wrap) {
+        try{
+            if (!compiledScriptMap.containsKey(wrap.getNodeId())){
+                String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId());
+                throw new ScriptLoadException(errorMsg);
+            }
+
+            CompiledScript compiledScript = compiledScriptMap.get(wrap.getNodeId());
+            Bindings bindings = new SimpleBindings();
+
+            //往脚本语言绑定表里循环增加绑定上下文的key
+            //key的规则为自定义上下文的simpleName
+            //比如你的自定义上下文为AbcContext,那么key就为:abcContext
+            //这里不统一放一个map的原因是考虑到有些用户会调用上下文里的方法,而不是参数,所以脚本语言的绑定表里也是放多个上下文
+            DataBus.getContextBeanList(wrap.getSlotIndex()).forEach(o -> {
+                String key = StrUtil.lowerFirst(o.getClass().getSimpleName());
+                bindings.put(key, o);
+            });
+
+            //把wrap对象转换成元数据map
+            Map<String, Object> metaMap = BeanUtil.beanToMap(wrap);
+
+            //在元数据里放入主Chain的流程参数
+            Slot slot = DataBus.getSlot(wrap.getSlotIndex());
+            metaMap.put("requestData", slot.getRequestData());
+
+            //如果有隐式流程,则放入隐式流程的流程参数
+            Object subRequestData = slot.getChainReqData(wrap.getCurrChainName());
+            if (ObjectUtil.isNotNull(subRequestData)){
+                metaMap.put("subRequestData", subRequestData);
+            }
+
+            //往脚本上下文里放入元数据
+            bindings.put("_meta", metaMap);
+
+            //放入用户自己定义的bean
+            bindings.putAll(ScriptBeanManager.getScriptBeanMap());
+
+            return compiledScript.eval(bindings);
+        }catch (Exception e){
+            log.error(e.getMessage(), e);
+            String errorMsg = StrUtil.format("script execute error for node[{}]", wrap.getNodeId());
+            throw new ScriptExecuteException(errorMsg);
+        }
+    }
+
+    @Override
+    public void cleanCache() {
+        compiledScriptMap.clear();
+    }
+}

+ 2 - 0
liteflow-script-plugin/liteflow-script-javascript/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor

@@ -0,0 +1,2 @@
+# JavaScript的实现
+com.yomahub.liteflow.script.javascript.JavaScriptExecutor

+ 1 - 0
liteflow-script-plugin/pom.xml

@@ -17,6 +17,7 @@
     <modules>
         <module>liteflow-script-qlexpress</module>
         <module>liteflow-script-groovy</module>
+        <module>liteflow-script-javascript</module>
     </modules>
 
 </project>

+ 33 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>liteflow-testcase-el</artifactId>
+        <groupId>com.yomahub</groupId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>liteflow-testcase-el-script-javascript-springboot</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.yomahub</groupId>
+            <artifactId>liteflow-spring-boot-starter</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.yomahub</groupId>
+            <artifactId>liteflow-script-javascript</artifactId>
+            <version>${revision}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java

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

+ 45 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/LiteflowXmlScriptJsELTest.java

@@ -0,0 +1,45 @@
+package com.yomahub.liteflow.test.script.javascript.common;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.enums.FlowParserTypeEnum;
+import com.yomahub.liteflow.flow.FlowBus;
+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下的groovy脚本组件,基于xml配置
+ * @author Bryan.Zhang
+ * @since 2.6.0
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(value = "classpath:/common/application.properties")
+@SpringBootTest(classes = LiteflowXmlScriptJsELTest.class)
+@EnableAutoConfiguration
+@ComponentScan({"com.yomahub.liteflow.test.script.javascript.common.cmp"})
+public class LiteflowXmlScriptJsELTest extends BaseTest {
+
+    @Resource
+    private FlowExecutor flowExecutor;
+
+    //测试普通脚本节点
+    @Test
+    public void testCommon1() {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertEquals(Double.valueOf(11), context.getData("s1"));
+    }
+}

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/ACmp.java

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

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/BCmp.java

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

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/CCmp.java

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

+ 24 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/common/cmp/DCmp.java

@@ -0,0 +1,24 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.javascript.common.cmp;
+
+import com.yomahub.liteflow.annotation.LiteflowComponent;
+import com.yomahub.liteflow.core.NodeComponent;
+import com.yomahub.liteflow.slot.DefaultContext;
+
+@LiteflowComponent("d")
+public class DCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		DefaultContext context = this.getFirstContextBean();
+		context.setData("count",198);
+		System.out.println("DCmp executed!");
+	}
+
+}

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/common/application.properties

@@ -0,0 +1 @@
+liteflow.rule-source=common/flow.xml

+ 29 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/common/flow.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+    <nodes>
+        <node id="s1" name="普通脚本1" type="script">
+            <![CDATA[
+                var a=3;
+                var b=2;
+                var c=1;
+                var d=5;
+
+                function addByArray(values) {
+                    var sum = 0;
+                    for (var i = 0; i < values.length; i++) {
+                        sum += values[i];
+                    }
+                    return sum;
+                }
+
+                var result = addByArray([a,b,c,d]);
+
+                defaultContext.setData("s1",parseInt(result));
+            ]]>
+        </node>
+    </nodes>
+
+    <chain name="chain1">
+        THEN(a, b, c, s1);
+    </chain>
+</flow>

+ 1 - 0
liteflow-testcase-el/pom.xml

@@ -22,6 +22,7 @@
         <module>liteflow-testcase-el-declare-multi-springboot</module>
         <module>liteflow-testcase-el-script-groovy-springboot</module>
         <module>liteflow-testcase-el-script-qlexpress-springboot</module>
+        <module>liteflow-testcase-el-script-javascript-springboot</module>
         <module>liteflow-testcase-el-zk-springboot</module>
         <module>liteflow-testcase-el-sql-springboot</module>
         <module>liteflow-testcase-el-nacos-springboot</module>

+ 1 - 1
pom.xml

@@ -340,7 +340,7 @@
 		<module>liteflow-spring-boot-starter</module>
 		<module>liteflow-spring</module>
 		<module>liteflow-testcase-el</module>
-    </modules>
+	</modules>
 
 	<distributionManagement>
 		<snapshotRepository>