!281 [ISSUE #I9H6GN] 支持 Kotlin 脚本语言

Merge pull request !281 from DaleLee/issue/#I9H6GN
This commit is contained in:
铂赛东 2024-05-13 04:17:17 +00:00 committed by Gitee
commit dec552b8db
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
71 changed files with 1909 additions and 1 deletions

View File

@ -8,7 +8,8 @@ public enum ScriptTypeEnum {
PYTHON("python", "python"),
LUA("luaj", "lua"),
AVIATOR("AviatorScript", "aviator"),
JAVA("java", "java");
JAVA("java", "java"),
KOTLIN("kotlin", "kotlin");
private String engineName;

View File

@ -0,0 +1,28 @@
<?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-kotlin</artifactId>
<dependencies>
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-core</artifactId>
<version>${revision}</version>
<optional>true</optional>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-scripting-jsr223</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,15 @@
package com.yomahub.liteflow.script.kotlin;
import com.yomahub.liteflow.enums.ScriptTypeEnum;
import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor;
/**
* Kotlin脚本执行器
* @author DaleLee
*/
public class KotlinScriptExecutor extends JSR223ScriptExecutor {
@Override
public ScriptTypeEnum scriptType() {
return ScriptTypeEnum.KOTLIN;
}
}

View File

@ -0,0 +1,2 @@
# Kotlin的实现
com.yomahub.liteflow.script.kotlin.KotlinScriptExecutor

View File

@ -23,6 +23,7 @@
<module>liteflow-script-lua</module>
<module>liteflow-script-aviator</module>
<module>liteflow-script-java</module>
<module>liteflow-script-kotlin</module>
</modules>
</project>

View File

@ -0,0 +1,32 @@
<?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-kotlin-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-kotlin</artifactId>
<version>${revision}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.script;
import com.yomahub.liteflow.core.FlowInitHook;
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.jupiter.api.AfterAll;
public class BaseTest {
@AfterAll
public static void cleanScanCache() {
ComponentScanner.cleanCache();
FlowBus.cleanCache();
ExecutorHelper.loadInstance().clearExecutorServiceMap();
SpiFactoryCleaner.clean();
LiteflowConfigGetter.clean();
FlowInitHook.cleanHook();
FlowBus.clearStat();
}
}

View File

@ -0,0 +1,36 @@
package com.yomahub.liteflow.test.script.kotlin.cmpdata;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/cmpdata/application.properties")
@SpringBootTest(classes = LiteFlowCmpDataKotlinScriptELTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.test.script.kotlin.cmpdata.cmp" })
public class LiteFlowCmpDataKotlinScriptELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testCmpData1() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
DefaultContext context = response.getFirstContextBean();
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("1995-10-01", context.getData("s1"));
}
}

View File

@ -0,0 +1,22 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.test.script.kotlin.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(this.getCmpData(String.class));
System.out.println("ACmp executed!");
}
}

View File

@ -0,0 +1,91 @@
package com.yomahub.liteflow.test.script.kotlin.common;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
/**
* Kotlin 脚本测试
*
* @author DaleLee
*/
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/common/application.properties")
@SpringBootTest(classes = LiteFlowKotlinScriptCommonELTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.script.kotlin.common.cmp"})
public class LiteFlowKotlinScriptCommonELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testCommonScript1() {
LiteflowResponse response = flowExecutor.execute2Resp("testCommonScript1", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals(Integer.valueOf(5), context.getData("s1"));
}
@Test
public void testForScript1() {
DefaultContext context = new DefaultContext();
context.setData("k1", 1);
context.setData("k2", 2);
LiteflowResponse response = flowExecutor.execute2Resp("testForScript1", "arg", context);
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("s2==>a==>a==>a", response.getExecuteStepStr());
}
@Test
public void testBooleanScript1() {
LiteflowResponse response = flowExecutor.execute2Resp("testBooleanScript1", "arg");
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("s3==>b", response.getExecuteStepStr());
}
@Test
public void testBooleanScript2() {
LiteflowResponse response = flowExecutor.execute2Resp("testBooleanScript2", "arg");
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("s4", response.getExecuteStepStr());
}
@Test
public void testBooleanScript3() {
DefaultContext context = new DefaultContext();
context.setData("count", 2);
LiteflowResponse response = flowExecutor.execute2Resp("testBooleanScript3", "arg", context);
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("s3==>b==>s6==>s3==>b==>s6==>s3==>b==>s6",response.getExecuteStepStr());
}
@Test
public void testSwitchScript1() {
DefaultContext context = new DefaultContext();
context.setData("id", "c");
LiteflowResponse response = flowExecutor.execute2Resp("testSwitchScript1", "arg", context);
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("s5==>c", response.getExecuteStepStr());
}
@Test
public void testFileScript1() {
LiteflowResponse response = flowExecutor.execute2Resp("testFileScript1", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals(Integer.valueOf(6), context.getData("s7"));
}
}

View File

@ -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.kotlin.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!");
}
}

View File

@ -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.kotlin.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!");
}
}

View File

@ -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.kotlin.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!");
}
}

View File

@ -0,0 +1,57 @@
package com.yomahub.liteflow.test.script.kotlin.contextbean;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.script.BaseTest;
import com.yomahub.liteflow.test.script.kotlin.contextbean.bean.CheckContext;
import com.yomahub.liteflow.test.script.kotlin.contextbean.bean.Order2Context;
import com.yomahub.liteflow.test.script.kotlin.contextbean.bean.OrderContext;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/contextbean/application.properties")
@SpringBootTest(classes = LiteFlowScriptContextbeanKotlinELTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.test.script.kotlin.contextbean.cmp",
"com.yomahub.liteflow.test.script.kotlin.contextbean.bean" })
public class LiteFlowScriptContextbeanKotlinELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testContextBean1() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg", OrderContext.class, CheckContext.class,
Order2Context.class);
Assertions.assertTrue(response.isSuccess());
OrderContext orderContext = response.getContextBean(OrderContext.class);
CheckContext checkContext = response.getContextBean(CheckContext.class);
Order2Context order2Context = response.getContextBean(Order2Context.class);
Assertions.assertEquals("order1", orderContext.getOrderNo());
Assertions.assertEquals("sign1", checkContext.getSign());
Assertions.assertEquals("order2", order2Context.getOrderNo());
}
@Test
public void testContextBean2() throws Exception {
OrderContext orderContext = new OrderContext();
orderContext.setOrderNo("order1");
CheckContext checkContext = new CheckContext();
checkContext.setSign("sign1");
Order2Context orderContext2 = new Order2Context();
orderContext2.setOrderNo("order2");
LiteflowResponse response = flowExecutor.execute2Resp("chain2", null, orderContext, checkContext,
orderContext2);
Assertions.assertTrue(response.isSuccess());
}
}

View File

@ -0,0 +1,28 @@
package com.yomahub.liteflow.test.script.kotlin.contextbean.bean;
import com.yomahub.liteflow.context.ContextBean;
@ContextBean
public class CheckContext {
private String sign;
private int randomId;
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public int getRandomId() {
return randomId;
}
public void setRandomId(int randomId) {
this.randomId = randomId;
}
}

View File

@ -0,0 +1,37 @@
package com.yomahub.liteflow.test.script.kotlin.contextbean.bean;
import java.util.Date;
public class Order2Context {
private String orderNo;
private int orderType;
private Date createTime;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public int getOrderType() {
return orderType;
}
public void setOrderType(int orderType) {
this.orderType = orderType;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,40 @@
package com.yomahub.liteflow.test.script.kotlin.contextbean.bean;
import com.yomahub.liteflow.context.ContextBean;
import java.util.Date;
@ContextBean("order")
public class OrderContext {
private String orderNo;
private int orderType;
private Date createTime;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public int getOrderType() {
return orderType;
}
public void setOrderType(int orderType) {
this.orderType = orderType;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

View File

@ -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.kotlin.contextbean.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!");
}
}

View File

@ -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.kotlin.contextbean.cmp;
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!");
}
}

View File

@ -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.kotlin.contextbean.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!");
}
}

View File

@ -0,0 +1,37 @@
package com.yomahub.liteflow.test.script.kotlin.meta;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/meta/application.properties")
@SpringBootTest(classes = LiteflowKotlinScriptMetaELTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.script.kotlin.meta.cmp"})
public class LiteflowKotlinScriptMetaELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testMeta() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
DefaultContext context = response.getFirstContextBean();
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals("chain1", context.getData("currChainId"));
Assertions.assertEquals("arg", context.getData("requestData"));
Assertions.assertEquals("s1", context.getData("nodeId"));
}
}

View File

@ -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.kotlin.meta.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!");
}
}

View File

@ -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.kotlin.meta.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!");
}
}

View File

@ -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.kotlin.meta.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!");
}
}

View File

@ -0,0 +1,48 @@
package com.yomahub.liteflow.test.script.kotlin.refresh;
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.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/refresh/application.properties")
@SpringBootTest(classes = LiteflowKotlinScriptRefreshELTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.test.script.kotlin.refresh.cmp" })
public class LiteflowKotlinScriptRefreshELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
// 测试脚本的热重载
@Test
public void testRefresh1() throws Exception {
// 根据配置加载的应该是flow.xml执行原来的规则
LiteflowResponse responseOld = flowExecutor.execute2Resp("chain1", "arg");
Assertions.assertTrue(responseOld.isSuccess());
Assertions.assertEquals("d==>s1[选择脚本]==>a", responseOld.getExecuteStepStr());
// 更改规则重新加载更改的规则内容从flow_update.xml里读取这里只是为了模拟下获取新的内容不一定是从文件中读取
String newContent = ResourceUtil.readUtf8Str("classpath: /refresh/flow_update.xml");
// 进行刷新
FlowBus.refreshFlowMetaData(FlowParserTypeEnum.TYPE_EL_XML, newContent);
// 重新执行chain2这个链路结果会变
LiteflowResponse responseNew = flowExecutor.execute2Resp("chain1", "arg");
Assertions.assertTrue(responseNew.isSuccess());
Assertions.assertEquals("d==>s1[选择脚本_改]==>b==>s2[普通脚本_新增]", responseNew.getExecuteStepStr());
}
}

View File

@ -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.kotlin.refresh.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!");
}
}

View File

@ -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.kotlin.refresh.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!");
}
}

View File

@ -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.kotlin.refresh.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!");
}
}

View File

@ -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.kotlin.refresh.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!");
}
}

View File

@ -0,0 +1,114 @@
package com.yomahub.liteflow.test.script.kotlin.remove;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.enums.ScriptTypeEnum;
import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.script.ScriptExecutor;
import com.yomahub.liteflow.script.ScriptExecutorFactory;
import com.yomahub.liteflow.script.exception.ScriptLoadException;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
import java.util.List;
/**
* 测试脚本的卸载和重载功能
*
* @author DaleLee
*/
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/remove/application.properties")
@SpringBootTest(classes = LiteFlowKotlinScriptRemoveELTest.class)
@EnableAutoConfiguration
public class LiteFlowKotlinScriptRemoveELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
private ScriptExecutor scriptExecutor = ScriptExecutorFactory.loadInstance()
.getScriptExecutor(ScriptTypeEnum.KOTLIN.getDisplayName());
// 仅卸载脚本
@Test
public void testUnload() {
flowExecutor.reloadRule();
// 获取节点id
List<String> nodeIds = scriptExecutor.getNodeIds();
Assertions.assertEquals(2, nodeIds.size());
Assertions.assertTrue(nodeIds.contains("s1"));
Assertions.assertTrue(nodeIds.contains("s2"));
// 保证脚本可以正常运行
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals(Integer.valueOf(6), context.getData("s1"));
// 卸载脚本
scriptExecutor.unLoad("s1");
response = flowExecutor.execute2Resp("chain1", "arg");
Assertions.assertFalse(response.isSuccess());
Assertions.assertEquals(ScriptLoadException.class, response.getCause().getClass());
Assertions.assertEquals("script for node[s1] is not loaded", response.getMessage());
// 脚本已卸载
Assertions.assertFalse(scriptExecutor.getNodeIds().contains("s1"));
}
// 卸载节点和脚本
@Test
public void testRemove() {
flowExecutor.reloadRule();
// 保证脚本可以正常运行
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals(Integer.valueOf(5), context.getData("s2"));
// 卸载节点
FlowBus.unloadScriptNode("s2");
// chain 报脚本加载错误
response = flowExecutor.execute2Resp("chain2", "arg");
Assertions.assertEquals(ScriptLoadException.class, response.getCause().getClass());
// chian 会找不到节点
Assertions.assertThrows(ELParseException.class,
() -> LiteFlowChainELBuilder.createChain()
.setChainId("chain3")
.setEL("THEN(s2)")
.build());
// 节点已卸载
Assertions.assertFalse(FlowBus.containNode("s2"));
// 脚本已卸载
Assertions.assertFalse(scriptExecutor.getNodeIds().contains("s2"));
}
// 重载脚本
@Test
public void testReloadScript() {
flowExecutor.reloadRule();
String script = "(bindings[\"defaultContext\"] as? DefaultContext)?.setData(\"s1\", \"abc\")";
FlowBus.reloadScript("s1", script);
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
DefaultContext context = response.getFirstContextBean();
// 执行结果变更
Assertions.assertEquals("abc", context.getData("s1"));
// 脚本变更
Assertions.assertEquals(FlowBus.getNode("s1").getScript(), script);
}
}

View File

@ -0,0 +1,103 @@
package com.yomahub.liteflow.test.script.kotlin.scriptbean;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.exception.ScriptBeanMethodInvokeException;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.script.ScriptBeanManager;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/scriptbean/application.properties")
@SpringBootTest(classes = LiteFlowScriptScriptbeanKotlinELTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.test.script.kotlin.scriptbean.cmp",
"com.yomahub.liteflow.test.script.kotlin.scriptbean.bean" })
public class LiteFlowScriptScriptbeanKotlinELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testScriptBean1() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals("hello", context.getData("demo"));
}
@Test
public void testScriptBean2() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals("hello,kobe", context.getData("demo"));
}
// 测试scriptBean includeMethodName配置包含情况下
@Test
public void testScriptBean3() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals("hello,kobe", context.getData("demo"));
}
// 测试scriptBean includeMethodName配置不包含情况下
@Test
public void testScriptBean4() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
Assertions.assertFalse(response.isSuccess());
Assertions.assertEquals(ScriptBeanMethodInvokeException.class, response.getCause().getClass());
}
// 测试scriptBean excludeMethodName配置不包含情况下
@Test
public void testScriptBean5() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals("hello,kobe", context.getData("demo"));
}
// 测试scriptBean excludeMethodName配置包含情况下
@Test
public void testScriptBean6() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
Assertions.assertFalse(response.isSuccess());
Assertions.assertEquals(ScriptBeanMethodInvokeException.class, response.getCause().getClass());
}
// 测试在ScriptBeanManager里放入上下文实现自定义脚本引用名称
@Test
public void testScriptBean7() throws Exception {
Map<String, String> map = new HashMap<>();
ScriptBeanManager.addScriptBean("abcCx", map);
LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg", map);
Assertions.assertTrue(response.isSuccess());
Map<String, String> context = response.getFirstContextBean();
Assertions.assertEquals("hello", context.get("demo"));
}
//测试用构造方法的方式注入bean的场景
@Test
public void testScriptBean8() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain8", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals("hello,jordan", context.getData("demo"));
}
}

View File

@ -0,0 +1,23 @@
package com.yomahub.liteflow.test.script.kotlin.scriptbean.bean;
import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
@ScriptBean("demo")
public class DemoBean1 {
@Resource
private DemoBean2 demoBean2;
public String getDemoStr1() {
return "hello";
}
public String getDemoStr2(String name) {
return demoBean2.getDemoStr2(name);
}
}

View File

@ -0,0 +1,12 @@
package com.yomahub.liteflow.test.script.kotlin.scriptbean.bean;
import org.springframework.stereotype.Component;
@Component
public class DemoBean2 {
public String getDemoStr2(String name) {
return "hello," + name;
}
}

View File

@ -0,0 +1,22 @@
package com.yomahub.liteflow.test.script.kotlin.scriptbean.bean;
import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
@Component
@ScriptBean(name = "demo3", includeMethodName = { "test1", "test2" })
public class DemoBean3 {
public String test1(String name) {
return "hello," + name;
}
public String test2(String name) {
return "hello," + name;
}
public String test3(String name) {
return "hello," + name;
}
}

View File

@ -0,0 +1,22 @@
package com.yomahub.liteflow.test.script.kotlin.scriptbean.bean;
import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
@Component
@ScriptBean(name = "demo4", excludeMethodName = { "test2", "test3" })
public class DemoBean4 {
public String test1(String name) {
return "hello," + name;
}
public String test2(String name) {
return "hello," + name;
}
public String test3(String name) {
return "hello," + name;
}
}

View File

@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.script.kotlin.scriptbean.bean;
import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
@Component
@ScriptBean("demo5")
public class DemoBean5 {
private final DemoBean2 demoBean2;
public DemoBean5(DemoBean2 demoBean2) {
this.demoBean2 = demoBean2;
}
public String getDemoStr1() {
return "hello";
}
public String getDemoStr2(String name) {
return demoBean2.getDemoStr2(name);
}
}

View File

@ -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.kotlin.scriptbean.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!");
}
}

View File

@ -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.kotlin.scriptbean.cmp;
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!");
}
}

View File

@ -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.kotlin.scriptbean.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!");
}
}

View File

@ -0,0 +1,45 @@
package com.yomahub.liteflow.test.script.kotlin.scriptmethod;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/scriptmethod/application.properties")
@SpringBootTest(classes = LiteFlowScriptScriptMethodKotlinELTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.test.script.kotlin.scriptmethod.cmp",
"com.yomahub.liteflow.test.script.kotlin.scriptmethod.bean" })
public class LiteFlowScriptScriptMethodKotlinELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void testScriptBean1() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals("hello", context.getData("demo"));
}
@Test
public void testScriptBean2() throws Exception {
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
Assertions.assertTrue(response.isSuccess());
DefaultContext context = response.getFirstContextBean();
Assertions.assertEquals("hello,kobe", context.getData("demo"));
}
}

View File

@ -0,0 +1,24 @@
package com.yomahub.liteflow.test.script.kotlin.scriptmethod.bean;
import com.yomahub.liteflow.script.annotation.ScriptMethod;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class DemoBean1 {
@Resource
private DemoBean2 demoBean2;
@ScriptMethod("demo")
public String getDemoStr1() {
return "hello";
}
@ScriptMethod("demo2")
public String getDemoStr2(String name) {
return demoBean2.getDemoStr2(name);
}
}

View File

@ -0,0 +1,12 @@
package com.yomahub.liteflow.test.script.kotlin.scriptmethod.bean;
import org.springframework.stereotype.Component;
@Component
public class DemoBean2 {
public String getDemoStr2(String name) {
return "hello," + name;
}
}

View File

@ -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.kotlin.scriptmethod.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!");
}
}

View File

@ -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.kotlin.scriptmethod.cmp;
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!");
}
}

View File

@ -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.kotlin.scriptmethod.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!");
}
}

View File

@ -0,0 +1,15 @@
package com.yomahub.liteflow.test.script.kotlin.throwException;
import com.yomahub.liteflow.exception.LiteFlowException;
public class TestException extends LiteFlowException {
public TestException(String message) {
super(message);
}
public TestException(String code, String message) {
super(code, message);
}
}

View File

@ -0,0 +1,37 @@
package com.yomahub.liteflow.test.script.kotlin.throwException;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.script.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
/**
* 测试 springboot下的 Kotlin 脚本抛错
*/
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:/throwException/application.properties")
@SpringBootTest(classes = ThrowExceptionScriptKotlinELTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.test.script.kotlin.throwException.cmp" })
public class ThrowExceptionScriptKotlinELTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void test1() {
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assertions.assertFalse(response.isSuccess());
Assertions.assertEquals("T01", response.getCode());
}
}

View File

@ -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.kotlin.throwException.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!");
}
}

View File

@ -0,0 +1,33 @@
package com.yomahub.liteflow.test.script.kotlin.validate;
import com.yomahub.liteflow.enums.ScriptTypeEnum;
import com.yomahub.liteflow.script.ScriptExecutor;
import com.yomahub.liteflow.script.ScriptExecutorFactory;
import com.yomahub.liteflow.script.validator.ScriptValidator;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import javax.script.Compilable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
@SpringBootTest(classes = ValidateKotlinScriptComponentTest.class)
@EnableAutoConfiguration
public class ValidateKotlinScriptComponentTest {
@Test
public void testScriptComponentValidateFunction() throws Exception {
// 编译错误字符串不能直接赋值给Int
String wrongScript = "val number: Int = \"123\"";
// 使用转换函数
String correctScript = "val number: Int = \"123\".toInt()";
Assertions.assertTrue(ScriptValidator.validate(correctScript));
Assertions.assertFalse(ScriptValidator.validate(wrongScript));
Assertions.assertTrue(ScriptValidator.validate(correctScript, ScriptTypeEnum.KOTLIN));
Assertions.assertFalse(ScriptValidator.validate(correctScript, ScriptTypeEnum.JS));
}
}

View File

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

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
<flow>
<nodes>
<node id="s1" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
var _meta = bindings["_meta"] as Map<String, *>
var cmpData = _meta["cmpData"] as Map<String, *>
var context = bindings["defaultContext"] as DefaultContext
context.setData("s1", cmpData["birth"])
]]>
</node>
</nodes>
<chain name="chain1">
cmpData = '{"name":"jack","age":27,"birth":"1995-10-01"}';
THEN(
s1.data(cmpData),
a
);
</chain>
</flow>

View File

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

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
fun sum(a: Int, b: Int) = a + b
var a = 2
var b = 3
// 从 bindings 中获取上下文
val defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("s1", sum(a, b))
println("Hello Kotlin!")
]]>
</node>
<node id="s2" type="for_script" language="kotlin">
<![CDATA[
fun getCount(): Int {
val ctx = bindings["defaultContext"] as DefaultContext
var n1 = ctx.getData("k1") as Int;
var n2 = ctx.getData("k2") as Int;
return n1 + n2;
}
// 函数名可以自定义,但必须返回 Int
// 以最后调用的函数返回结果作为脚本的返回值
// 最后调用的函数结果不能赋值给其他变量
getCount()
]]>
</node>
<node id="s3" type="boolean_script" language="kotlin">
<![CDATA[
fun getBoolean1() = 2 > 1
// 函数名可以自定义,但必须返回 Boolean
getBoolean1()
]]>
</node>
<node id="s4" type="boolean_script" language="kotlin">
<![CDATA[
fun getBoolean2() = 2 < 1
getBoolean2()
]]>
</node>
<node id="s5" type="switch_script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
fun getId(ctx: DefaultContext) : String {
return ctx.getData("id") as String
}
// 函数名可以自定义,但必须返回 String
getId(bindings["defaultContext"] as DefaultContext)
]]>
</node>
<node id="s6" type="boolean_script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
fun isBreak() : Boolean {
val ctx = bindings["defaultContext"] as DefaultContext
var count = ctx.getData("count") as Int;
ctx.setData("count", --count)
println("count: $count")
return count < 0;
}
isBreak()
]]>
</node>
<node id="s7" type="script" language="kotlin" file="script-file/s7.kts"/>
</nodes>
<chain name="testCommonScript1">
THEN(a, b, c, s1);
</chain>
<chain name="testForScript1">
FOR(s2).DO(a);
</chain>
<chain name="testBooleanScript1">
IF(s3, b);
</chain>
<chain name="testBooleanScript2">
IF(s4, b);
</chain>
<chain name="testBooleanScript3">
WHILE(s3).DO(b).BREAK(s6);
</chain>
<chain name="testSwitchScript1">
SWITCH(s5).TO(a, b, c);
</chain>
<chain name="testFileScript1">
THEN(s7);
</chain>
</flow>

View File

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

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="d" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.test.script.kotlin.contextbean.bean.*
var order = bindings["order"] as OrderContext
var checkContext = bindings["checkContext"] as CheckContext
var order2Context = bindings["order2Context"] as Order2Context
order.setOrderNo("order1")
checkContext.setSign("sign1")
order2Context.setOrderNo("order2")
]]>
</node>
<node id="e" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.test.script.kotlin.contextbean.bean.*
var order = bindings["order"] as OrderContext
var checkContext = bindings["checkContext"] as CheckContext
var order2Context = bindings["order2Context"] as Order2Context
var orderNo = order.getOrderNo()
println(orderNo)
var sign = checkContext.getSign()
println(sign)
var orderNo2 = order2Context.getOrderNo()
println(orderNo2)
]]>
</node>
</nodes>
<chain name="chain1">
THEN(a,b,c,d);
</chain>
<chain name="chain2">
THEN(a,b,c,e);
</chain>
</flow>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" name="普通脚本1" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
var _meta = bindings["_meta"] as Map<String, *>
var nodeId = _meta["nodeId"]
var currChainId = _meta["currChainId"]
var requestData = _meta["requestData"]
var context = bindings["defaultContext"] as DefaultContext
context.setData("nodeId",nodeId)
context.setData("currChainId",currChainId)
context.setData("requestData",requestData)
]]>
</node>
</nodes>
<chain id="chain1">
THEN(a, b, c, s1);
</chain>
</flow>

View File

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

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" name="选择脚本" type="switch_script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
fun getId(): String {
val context = bindings["defaultContext"] as DefaultContext
var count = context.getData("count") as Int;
if(count > 100) {
return "a";
} else {
return "b";
}
}
getId()
]]>
</node>
</nodes>
<chain name="chain1">
THEN(d, SWITCH(s1).to(a,b));
</chain>
</flow>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" name="选择脚本_改" type="switch_script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
fun getId(): String {
val context = bindings["defaultContext"] as DefaultContext
var count = context.getData("count") as Int;
if(count > 100) {
return "b";
} else {
return "a";
}
}
getId()
]]>
</node>
<node id="s2" name="普通脚本_新增" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
var a = 3
var b = 2
var c = 10
(bindings["defaultContext"] as? DefaultContext)?.setData("s2", a*b+c)
]]>
</node>
</nodes>
<chain name="chain1">
THEN(d, SWITCH(s1).to(a,b), s2);
</chain>
</flow>

View File

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

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" name="普通脚本1" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
var a = 1
var b = 2
var c = 3
(bindings["defaultContext"] as? DefaultContext)?.setData("s1", a+b+c)
]]>
</node>
<node id="s2" name="普通脚本2" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
var a = 1
var b = 2
var c = 3
(bindings["defaultContext"] as? DefaultContext)?.setData("s2", a*b+c)
]]>
</node>
</nodes>
<chain name="chain1">
THEN(s1);
</chain>
<chain name="chain2">
THEN(s2);
</chain>
</flow>

View File

@ -0,0 +1,6 @@
import com.yomahub.liteflow.slot.DefaultContext
var a = 2
var b = 3
val defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("s7", a * b)

View File

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

View File

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="d" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
var demo = bindings["demo"] as DemoBean1
var str = demo.getDemoStr1()
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
<node id="e" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
var demo = bindings["demo"] as DemoBean1
var str = demo.getDemoStr2("kobe")
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
<node id="s1" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
var demo3 = bindings["demo3"] as DemoBean3
var str = demo3.test1("kobe")
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
<node id="s2" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
var demo3 = bindings["demo3"] as DemoBean3
var str = demo3.test3("kobe")
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
<node id="s3" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
var demo4 = bindings["demo4"] as DemoBean4
var str = demo4.test1("kobe")
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
<node id="s4" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
var demo4 = bindings["demo4"] as DemoBean4
var str = demo4.test3("kobe")
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
<node id="s5" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
import java.util.HashMap
var demo = bindings["demo"] as DemoBean1
var str = demo.getDemoStr1()
var abcCx = bindings["abcCx"] as HashMap<String, String>
abcCx.put("demo", str)
]]>
</node>
<node id="f" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptbean.bean.*
var demo5 = bindings["demo5"] as DemoBean5
var str = demo5.getDemoStr2("jordan")
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
</nodes>
<chain name="chain1">
THEN(a,b,c,d);
</chain>
<chain name="chain2">
THEN(a,b,c,e);
</chain>
<chain name="chain3">
THEN(a,b,c,s1);
</chain>
<chain name="chain4">
THEN(a,b,c,s2);
</chain>
<chain name="chain5">
THEN(a,b,c,s3);
</chain>
<chain name="chain6">
THEN(a,b,c,s4);
</chain>
<chain name="chain7">
THEN(a,b,c,s5);
</chain>
<chain name="chain8">
THEN(a,b,c,f);
</chain>
</flow>

View File

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

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="d" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptmethod.bean.*
var demo = bindings["demo"] as DemoBean1
var str = demo.getDemoStr1()
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
<node id="e" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.slot.DefaultContext
import com.yomahub.liteflow.test.script.kotlin.scriptmethod.bean.*
var demo2 = bindings["demo2"] as DemoBean1
var str = demo2.getDemoStr2("kobe")
var defaultContext = bindings["defaultContext"] as DefaultContext
defaultContext.setData("demo", str)
]]>
</node>
</nodes>
<chain name="chain1">
THEN(a,b,c,d);
</chain>
<chain name="chain2">
THEN(a,b,c,e);
</chain>
</flow>

View File

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

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" name="普通脚本1" type="script" language="kotlin">
<![CDATA[
import com.yomahub.liteflow.test.script.kotlin.throwException.TestException
throw TestException("T01", "测试错误")
]]>
</node>
</nodes>
<chain name="chain1">
THEN(a, s1);
</chain>
</flow>

View File

@ -39,6 +39,7 @@
<module>liteflow-testcase-el-script-java-springboot</module>
<module>liteflow-testcase-el-builder</module>
<module>liteflow-testcase-el-routechain</module>
<module>liteflow-testcase-el-script-kotlin-springboot</module>
</modules>
<build>

View File

@ -76,6 +76,7 @@
<jakarta.version>1.3.5</jakarta.version>
<redisson.version>3.21.0</redisson.version>
<janino.version>3.1.11</janino.version>
<kotlin.version>1.9.23</kotlin.version>
</properties>
<dependencyManagement>
@ -314,6 +315,11 @@
<artifactId>redisson</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-scripting-jsr223</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</dependencyManagement>