Merge branch 'refs/heads/dev'
This commit is contained in:
commit
d4e464eb1a
|
@ -0,0 +1,12 @@
|
||||||
|
package com.yomahub.liteflow.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.PARAMETER})
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface LiteflowFact {
|
||||||
|
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -136,8 +136,7 @@ public class LiteFlowChainELBuilder {
|
||||||
|
|
||||||
public LiteFlowChainELBuilder setRoute(String routeEl){
|
public LiteFlowChainELBuilder setRoute(String routeEl){
|
||||||
if (StrUtil.isBlank(routeEl)) {
|
if (StrUtil.isBlank(routeEl)) {
|
||||||
String errMsg = StrUtil.format("You have defined the label <route> but there is no el in the chain route[{}].", chain.getChainId());
|
return this;
|
||||||
throw new FlowSystemException(errMsg);
|
|
||||||
}
|
}
|
||||||
List<String> errorList = new ArrayList<>();
|
List<String> errorList = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
|
@ -233,6 +232,14 @@ public class LiteFlowChainELBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiteFlowChainELBuilder setNamespace(String nameSpace){
|
||||||
|
if (StrUtil.isBlank(nameSpace)) {
|
||||||
|
nameSpace = ChainConstant.DEFAULT_NAMESPACE;
|
||||||
|
}
|
||||||
|
this.chain.setNamespace(nameSpace);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL表达式校验
|
* EL表达式校验
|
||||||
* @param elStr EL表达式
|
* @param elStr EL表达式
|
||||||
|
|
|
@ -32,6 +32,10 @@ public interface ChainConstant {
|
||||||
|
|
||||||
String LANGUAGE = "language";
|
String LANGUAGE = "language";
|
||||||
|
|
||||||
|
String NAMESPACE = "namespace";
|
||||||
|
|
||||||
|
String DEFAULT_NAMESPACE = "default";
|
||||||
|
|
||||||
String VALUE = "value";
|
String VALUE = "value";
|
||||||
|
|
||||||
String ANY = "any";
|
String ANY = "any";
|
||||||
|
|
|
@ -13,6 +13,7 @@ import cn.hutool.core.collection.ListUtil;
|
||||||
import cn.hutool.core.lang.Tuple;
|
import cn.hutool.core.lang.Tuple;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.*;
|
import cn.hutool.core.util.*;
|
||||||
|
import com.yomahub.liteflow.common.ChainConstant;
|
||||||
import com.yomahub.liteflow.enums.ChainExecuteModeEnum;
|
import com.yomahub.liteflow.enums.ChainExecuteModeEnum;
|
||||||
import com.yomahub.liteflow.enums.InnerChainTypeEnum;
|
import com.yomahub.liteflow.enums.InnerChainTypeEnum;
|
||||||
import com.yomahub.liteflow.enums.ParseModeEnum;
|
import com.yomahub.liteflow.enums.ParseModeEnum;
|
||||||
|
@ -136,8 +137,8 @@ public class FlowExecutor {
|
||||||
// 查找对应的解析器
|
// 查找对应的解析器
|
||||||
parser = FlowParserProvider.lookup(path);
|
parser = FlowParserProvider.lookup(path);
|
||||||
parserNameSet.add(parser.getClass().getName());
|
parserNameSet.add(parser.getClass().getName());
|
||||||
// 替换掉前缀标识(如:xml:/json:),保留剩下的完整地址
|
// 替换掉前缀标识(如:xml:/json:),保留剩下的完整地址,并统一路径格式
|
||||||
path = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, "");
|
path = ReUtil.replaceAll(path, PREFIX_FORMAT_CONFIG_REGEX, "").replace("\\", "/");
|
||||||
rulePathList.add(path);
|
rulePathList.add(path);
|
||||||
|
|
||||||
// 支持多类型的配置文件,分别解析
|
// 支持多类型的配置文件,分别解析
|
||||||
|
@ -283,7 +284,11 @@ public class FlowExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LiteflowResponse> executeRouteChain(Object param, Class<?>... contextBeanClazzArray){
|
public List<LiteflowResponse> executeRouteChain(Object param, Class<?>... contextBeanClazzArray){
|
||||||
return this.executeWithRoute(param, null, contextBeanClazzArray, null);
|
return this.executeWithRoute(null, param, null, contextBeanClazzArray, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LiteflowResponse> executeRouteChain(String namespace, Object param, Class<?>... contextBeanClazzArray){
|
||||||
|
return this.executeWithRoute(namespace, param, null, contextBeanClazzArray, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteflowResponse execute2Resp(String chainId, Object param, Object... contextBeanArray) {
|
public LiteflowResponse execute2Resp(String chainId, Object param, Object... contextBeanArray) {
|
||||||
|
@ -291,23 +296,35 @@ public class FlowExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LiteflowResponse> executeRouteChain(Object param, Object... contextBeanArray){
|
public List<LiteflowResponse> executeRouteChain(Object param, Object... contextBeanArray){
|
||||||
return this.executeWithRoute(param, null, null, contextBeanArray);
|
return this.executeWithRoute(null, param, null, null, contextBeanArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LiteflowResponse> executeRouteChain(String namespace, Object param, Object... contextBeanArray){
|
||||||
|
return this.executeWithRoute(namespace, param, null, null, contextBeanArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteflowResponse execute2RespWithRid(String chainId, Object param, String requestId, Class<?>... contextBeanClazzArray) {
|
public LiteflowResponse execute2RespWithRid(String chainId, Object param, String requestId, Class<?>... contextBeanClazzArray) {
|
||||||
return this.execute2Resp(chainId, param, requestId, contextBeanClazzArray, null);
|
return this.execute2Resp(chainId, param, requestId, contextBeanClazzArray, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LiteflowResponse> executeRouteChainWithRid(String chainId, Object param, String requestId, Class<?>... contextBeanClazzArray) {
|
public List<LiteflowResponse> executeRouteChainWithRid(Object param, String requestId, Class<?>... contextBeanClazzArray) {
|
||||||
return this.executeWithRoute(param, requestId, contextBeanClazzArray, null);
|
return this.executeWithRoute(null, param, requestId, contextBeanClazzArray, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LiteflowResponse> executeRouteChainWithRid(String namespace, Object param, String requestId, Class<?>... contextBeanClazzArray) {
|
||||||
|
return this.executeWithRoute(namespace, param, requestId, contextBeanClazzArray, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiteflowResponse execute2RespWithRid(String chainId, Object param, String requestId, Object... contextBeanArray) {
|
public LiteflowResponse execute2RespWithRid(String chainId, Object param, String requestId, Object... contextBeanArray) {
|
||||||
return this.execute2Resp(chainId, param, requestId, null, contextBeanArray);
|
return this.execute2Resp(chainId, param, requestId, null, contextBeanArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LiteflowResponse> executeRouteChainWithRid(String chainId, Object param, String requestId, Object... contextBeanArray) {
|
public List<LiteflowResponse> executeRouteChainWithRid(Object param, String requestId, Object... contextBeanArray) {
|
||||||
return this.executeWithRoute(param, requestId, null, contextBeanArray);
|
return this.executeWithRoute(null, param, requestId, null, contextBeanArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LiteflowResponse> executeRouteChainWithRid(String namespace, Object param, String requestId, Object... contextBeanArray) {
|
||||||
|
return this.executeWithRoute(namespace, param, requestId, null, contextBeanArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用一个流程并返回Future<LiteflowResponse>,允许多上下文的传入
|
// 调用一个流程并返回Future<LiteflowResponse>,允许多上下文的传入
|
||||||
|
@ -353,8 +370,8 @@ public class FlowExecutor {
|
||||||
return LiteflowResponse.newMainResponse(slot);
|
return LiteflowResponse.newMainResponse(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<LiteflowResponse> executeWithRoute(Object param, String requestId, Class<?>[] contextBeanClazzArray, Object[] contextBeanArray){
|
private List<LiteflowResponse> executeWithRoute(String namespace, Object param, String requestId, Class<?>[] contextBeanClazzArray, Object[] contextBeanArray){
|
||||||
List<Slot> slotList = doExecuteWithRoute(param, requestId, contextBeanClazzArray, contextBeanArray);
|
List<Slot> slotList = doExecuteWithRoute(namespace, param, requestId, contextBeanClazzArray, contextBeanArray);
|
||||||
return slotList.stream().map(LiteflowResponse::newMainResponse).collect(Collectors.toList());
|
return slotList.stream().map(LiteflowResponse::newMainResponse).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,15 +539,23 @@ public class FlowExecutor {
|
||||||
MonitorFile.getInstance().addMonitorFilePaths(fileAbsolutePath);
|
MonitorFile.getInstance().addMonitorFilePaths(fileAbsolutePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Slot> doExecuteWithRoute(Object param, String requestId, Class<?>[] contextBeanClazzArray, Object[] contextBeanArray){
|
private List<Slot> doExecuteWithRoute(String namespace, Object param, String requestId, Class<?>[] contextBeanClazzArray, Object[] contextBeanArray){
|
||||||
if (FlowBus.needInit()) {
|
if (FlowBus.needInit()) {
|
||||||
init(true);
|
init(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Chain> routeChainList = FlowBus.getChainMap().values().stream().filter(chain -> chain.getRouteItem() != null).collect(Collectors.toList());
|
if (StrUtil.isBlank(namespace)){
|
||||||
|
namespace = ChainConstant.DEFAULT_NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
String finalNamespace = namespace;
|
||||||
|
List<Chain> routeChainList = FlowBus.getChainMap().values().stream()
|
||||||
|
.filter(chain -> chain.getNamespace().equals(finalNamespace))
|
||||||
|
.filter(chain -> chain.getRouteItem() != null).collect(Collectors.toList());
|
||||||
|
|
||||||
if (CollUtil.isEmpty(routeChainList)){
|
if (CollUtil.isEmpty(routeChainList)){
|
||||||
throw new RouteChainNotFoundException("cannot find any route chain");
|
String errorMsg = StrUtil.format("no route found for namespace[{}]", finalNamespace);
|
||||||
|
throw new RouteChainNotFoundException(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
String finalRequestId;
|
String finalRequestId;
|
||||||
|
@ -601,7 +626,7 @@ public class FlowExecutor {
|
||||||
}
|
}
|
||||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
|
||||||
LOG.info("There are {} chains that matched the route.", resultSlotList.size());
|
LOG.info("chain namespace:[{}], total size:[{}], matched size:[{}]", namespace, routeChainList.size(), resultSlotList.size());
|
||||||
|
|
||||||
return resultSlotList;
|
return resultSlotList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
package com.yomahub.liteflow.core.proxy;
|
package com.yomahub.liteflow.core.proxy;
|
||||||
|
|
||||||
import cn.hutool.core.exceptions.InvocationTargetRuntimeException;
|
import cn.hutool.core.exceptions.InvocationTargetRuntimeException;
|
||||||
|
import cn.hutool.core.lang.Tuple;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.ql.util.express.DefaultContext;
|
||||||
|
import com.ql.util.express.ExpressRunner;
|
||||||
|
import com.ql.util.express.InstructionSet;
|
||||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||||
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
||||||
import com.yomahub.liteflow.core.NodeComponent;
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
import com.yomahub.liteflow.exception.ComponentMethodDefineErrorException;
|
import com.yomahub.liteflow.exception.ComponentMethodDefineErrorException;
|
||||||
import com.yomahub.liteflow.exception.LiteFlowException;
|
import com.yomahub.liteflow.exception.LiteFlowException;
|
||||||
|
import com.yomahub.liteflow.exception.ParameterFactException;
|
||||||
import com.yomahub.liteflow.exception.ProxyException;
|
import com.yomahub.liteflow.exception.ProxyException;
|
||||||
|
import com.yomahub.liteflow.flow.element.Node;
|
||||||
import com.yomahub.liteflow.log.LFLog;
|
import com.yomahub.liteflow.log.LFLog;
|
||||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||||
|
import com.yomahub.liteflow.slot.DataBus;
|
||||||
import com.yomahub.liteflow.util.SerialsUtil;
|
import com.yomahub.liteflow.util.SerialsUtil;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
|
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
|
||||||
|
@ -21,7 +28,12 @@ import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -112,6 +124,10 @@ public class DeclComponentProxy {
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
|
if (currentMethodWrapBean == null){
|
||||||
|
throw new ProxyException("currentMethodWrapBean is null");
|
||||||
|
}
|
||||||
|
|
||||||
// 如果被代理的对象里有此标注标的方法,则调用此被代理的对象里的方法,如果没有,则调用父类里的方法
|
// 如果被代理的对象里有此标注标的方法,则调用此被代理的对象里的方法,如果没有,则调用父类里的方法
|
||||||
// 进行检查,检查被代理的bean里是否第一个参数为NodeComponent这个类型的
|
// 进行检查,检查被代理的bean里是否第一个参数为NodeComponent这个类型的
|
||||||
boolean checkFlag = currentMethodWrapBean.getMethod().getParameterTypes().length > 0
|
boolean checkFlag = currentMethodWrapBean.getMethod().getParameterTypes().length > 0
|
||||||
|
@ -124,13 +140,13 @@ public class DeclComponentProxy {
|
||||||
throw new ComponentMethodDefineErrorException(errMsg);
|
throw new ComponentMethodDefineErrorException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 这里是针对于参数的处理
|
||||||
|
// 首先需要保证第一个参数是NodeComponent
|
||||||
|
// 其次需要针对于@LiteflowFact做处理
|
||||||
try {
|
try {
|
||||||
if (args != null && args.length > 0){
|
Object[] realArgs = loadMethodParameter(proxy, currentMethodWrapBean);
|
||||||
Object[] wrapArgs = ArrayUtil.insert(args, 0, proxy);
|
return ReflectUtil.invoke(declWarpBean.getRawBean(), currentMethodWrapBean.getMethod(), realArgs);
|
||||||
return ReflectUtil.invoke(declWarpBean.getRawBean(), currentMethodWrapBean.getMethod(), wrapArgs);
|
|
||||||
}else{
|
|
||||||
return ReflectUtil.invoke(declWarpBean.getRawBean(), currentMethodWrapBean.getMethod(), proxy);
|
|
||||||
}
|
|
||||||
}catch (InvocationTargetRuntimeException e) {
|
}catch (InvocationTargetRuntimeException e) {
|
||||||
InvocationTargetException targetEx = (InvocationTargetException) e.getCause();
|
InvocationTargetException targetEx = (InvocationTargetException) e.getCause();
|
||||||
throw targetEx.getTargetException();
|
throw targetEx.getTargetException();
|
||||||
|
@ -138,4 +154,55 @@ public class DeclComponentProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ExpressRunner expressRunner = new ExpressRunner();
|
||||||
|
|
||||||
|
private Object[] loadMethodParameter(Object proxy, MethodWrapBean methodWrapBean){
|
||||||
|
NodeComponent thisNodeComponent = (NodeComponent) proxy;
|
||||||
|
|
||||||
|
return methodWrapBean.getParameterWrapBeanList().stream().map(parameterWrapBean -> {
|
||||||
|
// 如果参数是NodeComponent,那就返回proxy本身
|
||||||
|
if (parameterWrapBean.getParameterType().isAssignableFrom(NodeComponent.class)) {
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有@LiteflowFact标注,那么不处理,直接赋值null
|
||||||
|
if (parameterWrapBean.getFact() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把上下文数据转换成map形式的,key为别名,value为上下文
|
||||||
|
Map<String, Object> contextMap = DataBus.getSlot(thisNodeComponent.getSlotIndex()).getContextBeanList().stream().collect(
|
||||||
|
Collectors.toMap(tuple -> tuple.get(0), tuple -> tuple.get(1))
|
||||||
|
);
|
||||||
|
|
||||||
|
List<String> errorList = new ArrayList<>();
|
||||||
|
|
||||||
|
Object result = null;
|
||||||
|
// 根据表达式去上下文里搜索相匹配的数据
|
||||||
|
for(Map.Entry<String, Object> entry : contextMap.entrySet()){
|
||||||
|
try{
|
||||||
|
InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache(entry.getKey() + "." + parameterWrapBean.getFact().value());
|
||||||
|
DefaultContext<String, Object> context = new DefaultContext<>();
|
||||||
|
context.put(entry.getKey(), entry.getValue());
|
||||||
|
result = expressRunner.execute(instructionSet, context, errorList, false, false);
|
||||||
|
if (result != null){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}catch (Exception ignore){}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null){
|
||||||
|
try{
|
||||||
|
// 如果没有搜到,那么尝试推断表达式是指定的上下文,按照指定上下文的方式去再获取
|
||||||
|
InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache("contextMap." + parameterWrapBean.getFact().value());
|
||||||
|
DefaultContext<String, Object> context = new DefaultContext<>();
|
||||||
|
context.put("contextMap", contextMap);
|
||||||
|
result = expressRunner.execute(instructionSet, context, errorList, false, false);
|
||||||
|
}catch (Exception ignore){}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}).toArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||||
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LiteflowMethod的包装类
|
* LiteflowMethod的包装类
|
||||||
|
@ -18,10 +19,13 @@ public class MethodWrapBean {
|
||||||
|
|
||||||
private LiteflowRetry liteflowRetry;
|
private LiteflowRetry liteflowRetry;
|
||||||
|
|
||||||
public MethodWrapBean(Method method, LiteflowMethod liteflowMethod, LiteflowRetry liteflowRetry) {
|
private List<ParameterWrapBean> parameterWrapBeanList;
|
||||||
|
|
||||||
|
public MethodWrapBean(Method method, LiteflowMethod liteflowMethod, LiteflowRetry liteflowRetry, List<ParameterWrapBean> parameterWrapBeanList) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.liteflowMethod = liteflowMethod;
|
this.liteflowMethod = liteflowMethod;
|
||||||
this.liteflowRetry = liteflowRetry;
|
this.liteflowRetry = liteflowRetry;
|
||||||
|
this.parameterWrapBeanList = parameterWrapBeanList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method getMethod() {
|
public Method getMethod() {
|
||||||
|
@ -47,4 +51,12 @@ public class MethodWrapBean {
|
||||||
public void setLiteflowRetry(LiteflowRetry liteflowRetry) {
|
public void setLiteflowRetry(LiteflowRetry liteflowRetry) {
|
||||||
this.liteflowRetry = liteflowRetry;
|
this.liteflowRetry = liteflowRetry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ParameterWrapBean> getParameterWrapBeanList() {
|
||||||
|
return parameterWrapBeanList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameterWrapBeanList(List<ParameterWrapBean> parameterWrapBeanList) {
|
||||||
|
this.parameterWrapBeanList = parameterWrapBeanList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.yomahub.liteflow.core.proxy;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 声明式的包装类
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
* @since 2.12.1
|
||||||
|
*/
|
||||||
|
public class ParameterWrapBean {
|
||||||
|
|
||||||
|
private Class<?> parameterType;
|
||||||
|
|
||||||
|
private LiteflowFact fact;
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public ParameterWrapBean(Class<?> parameterType, LiteflowFact fact, int index) {
|
||||||
|
this.parameterType = parameterType;
|
||||||
|
this.fact = fact;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> getParameterType() {
|
||||||
|
return parameterType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameterType(Class<?> parameterType) {
|
||||||
|
this.parameterType = parameterType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiteflowFact getFact() {
|
||||||
|
return fact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFact(LiteflowFact fact) {
|
||||||
|
this.fact = fact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,13 +2,15 @@ package com.yomahub.liteflow.enums;
|
||||||
|
|
||||||
public enum ScriptTypeEnum {
|
public enum ScriptTypeEnum {
|
||||||
|
|
||||||
|
CUSTOM("custom", "custom"),
|
||||||
GROOVY("groovy", "groovy"),
|
GROOVY("groovy", "groovy"),
|
||||||
QLEXPRESS("qlexpress", "qlexpress"),
|
QLEXPRESS("qlexpress", "qlexpress"),
|
||||||
JS("javascript", "js"),
|
JS("javascript", "js"),
|
||||||
PYTHON("python", "python"),
|
PYTHON("python", "python"),
|
||||||
LUA("luaj", "lua"),
|
LUA("luaj", "lua"),
|
||||||
AVIATOR("AviatorScript", "aviator"),
|
AVIATOR("AviatorScript", "aviator"),
|
||||||
JAVA("java", "java");
|
JAVA("java", "java"),
|
||||||
|
KOTLIN("kotlin", "kotlin");
|
||||||
|
|
||||||
private String engineName;
|
private String engineName;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.yomahub.liteflow.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
*/
|
||||||
|
public class ParameterFactException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 异常信息 */
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public ParameterFactException(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -40,6 +40,8 @@ public class Chain implements Executable{
|
||||||
|
|
||||||
private boolean isCompiled = true;
|
private boolean isCompiled = true;
|
||||||
|
|
||||||
|
private String namespace;
|
||||||
|
|
||||||
public Chain(String chainName) {
|
public Chain(String chainName) {
|
||||||
this.chainId = chainName;
|
this.chainId = chainName;
|
||||||
}
|
}
|
||||||
|
@ -195,4 +197,12 @@ public class Chain implements Executable{
|
||||||
public void setCompiled(boolean compiled) {
|
public void setCompiled(boolean compiled) {
|
||||||
isCompiled = compiled;
|
isCompiled = compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNamespace(String namespace) {
|
||||||
|
this.namespace = namespace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,29 +15,6 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class NodeConvertHelper {
|
public class NodeConvertHelper {
|
||||||
|
|
||||||
/*script节点的修改/添加*/
|
|
||||||
public static void changeScriptNode(NodeSimpleVO nodeSimpleVO, String newValue) {
|
|
||||||
// 有语言类型
|
|
||||||
if (StrUtil.isNotBlank(nodeSimpleVO.getLanguage())) {
|
|
||||||
LiteFlowNodeBuilder.createScriptNode()
|
|
||||||
.setId(nodeSimpleVO.getNodeId())
|
|
||||||
.setType(NodeTypeEnum.getEnumByCode(nodeSimpleVO.getType()))
|
|
||||||
.setName(nodeSimpleVO.getName())
|
|
||||||
.setScript(newValue)
|
|
||||||
.setLanguage(nodeSimpleVO.getLanguage())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
// 没有语言类型
|
|
||||||
else {
|
|
||||||
LiteFlowNodeBuilder.createScriptNode()
|
|
||||||
.setId(nodeSimpleVO.getNodeId())
|
|
||||||
.setType(NodeTypeEnum.getEnumByCode(nodeSimpleVO.getType()))
|
|
||||||
.setName(nodeSimpleVO.getName())
|
|
||||||
.setScript(newValue)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NodeSimpleVO convert(String scriptKey){
|
public static NodeSimpleVO convert(String scriptKey){
|
||||||
// 不需要去理解这串正则,就是一个匹配冒号的
|
// 不需要去理解这串正则,就是一个匹配冒号的
|
||||||
// 一定得是a:b,或是a:b:c...这种完整类型的字符串的
|
// 一定得是a:b,或是a:b:c...这种完整类型的字符串的
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.yomahub.liteflow.parser.helper;
|
package com.yomahub.liteflow.parser.helper;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
@ -24,6 +25,7 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import static com.yomahub.liteflow.common.ChainConstant.*;
|
import static com.yomahub.liteflow.common.ChainConstant.*;
|
||||||
|
|
||||||
|
@ -205,7 +207,7 @@ public class ParserHelper {
|
||||||
// 当存在<nodes>节点定义时,解析node节点
|
// 当存在<nodes>节点定义时,解析node节点
|
||||||
if (flowJsonNode.get(FLOW).has(NODES)) {
|
if (flowJsonNode.get(FLOW).has(NODES)) {
|
||||||
Iterator<JsonNode> nodeIterator = flowJsonNode.get(FLOW).get(NODES).get(NODE).elements();
|
Iterator<JsonNode> nodeIterator = flowJsonNode.get(FLOW).get(NODES).get(NODE).elements();
|
||||||
String id, name, clazz, script, type, file;
|
String id, name, clazz, script, type, file, language;
|
||||||
while ((nodeIterator.hasNext())) {
|
while ((nodeIterator.hasNext())) {
|
||||||
JsonNode nodeObject = nodeIterator.next();
|
JsonNode nodeObject = nodeIterator.next();
|
||||||
id = nodeObject.get(ID).textValue();
|
id = nodeObject.get(ID).textValue();
|
||||||
|
@ -214,6 +216,7 @@ public class ParserHelper {
|
||||||
type = nodeObject.hasNonNull(TYPE) ? nodeObject.get(TYPE).textValue() : null;
|
type = nodeObject.hasNonNull(TYPE) ? nodeObject.get(TYPE).textValue() : null;
|
||||||
script = nodeObject.hasNonNull(VALUE) ? nodeObject.get(VALUE).textValue() : "";
|
script = nodeObject.hasNonNull(VALUE) ? nodeObject.get(VALUE).textValue() : "";
|
||||||
file = nodeObject.hasNonNull(FILE) ? nodeObject.get(FILE).textValue() : "";
|
file = nodeObject.hasNonNull(FILE) ? nodeObject.get(FILE).textValue() : "";
|
||||||
|
language = nodeObject.hasNonNull(LANGUAGE) ? nodeObject.get(LANGUAGE).textValue() : "";
|
||||||
|
|
||||||
// 如果是禁用的,就不编译了
|
// 如果是禁用的,就不编译了
|
||||||
if (!getEnableByJsonNode(nodeObject)) {
|
if (!getEnableByJsonNode(nodeObject)) {
|
||||||
|
@ -226,7 +229,8 @@ public class ParserHelper {
|
||||||
.setClazz(clazz)
|
.setClazz(clazz)
|
||||||
.setScript(script)
|
.setScript(script)
|
||||||
.setType(type)
|
.setType(type)
|
||||||
.setFile(file);
|
.setFile(file)
|
||||||
|
.setLanguage(language);
|
||||||
|
|
||||||
ParserHelper.buildNode(nodePropBean);
|
ParserHelper.buildNode(nodePropBean);
|
||||||
}
|
}
|
||||||
|
@ -308,9 +312,11 @@ public class ParserHelper {
|
||||||
// 构建chainBuilder
|
// 构建chainBuilder
|
||||||
String chainId = Optional.ofNullable(chainNode.get(ID)).orElse(chainNode.get(NAME)).textValue();
|
String chainId = Optional.ofNullable(chainNode.get(ID)).orElse(chainNode.get(NAME)).textValue();
|
||||||
|
|
||||||
|
String namespace = chainNode.get(NAMESPACE) == null? DEFAULT_NAMESPACE : chainNode.get(NAMESPACE).textValue();
|
||||||
|
|
||||||
JsonNode routeJsonNode = chainNode.get(ROUTE);
|
JsonNode routeJsonNode = chainNode.get(ROUTE);
|
||||||
|
|
||||||
LiteFlowChainELBuilder builder = LiteFlowChainELBuilder.createChain().setChainId(chainId);
|
LiteFlowChainELBuilder builder = LiteFlowChainELBuilder.createChain().setChainId(chainId).setNamespace(namespace);
|
||||||
|
|
||||||
// 如果有route这个标签,说明是决策表chain
|
// 如果有route这个标签,说明是决策表chain
|
||||||
// 决策表链路必须有route和body这两个标签
|
// 决策表链路必须有route和body这两个标签
|
||||||
|
@ -337,9 +343,11 @@ public class ParserHelper {
|
||||||
// 构建chainBuilder
|
// 构建chainBuilder
|
||||||
String chainId = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME));
|
String chainId = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME));
|
||||||
|
|
||||||
|
String namespace = StrUtil.blankToDefault(e.attributeValue(NAMESPACE), DEFAULT_NAMESPACE);
|
||||||
|
|
||||||
Element routeElement = e.element(ROUTE);
|
Element routeElement = e.element(ROUTE);
|
||||||
|
|
||||||
LiteFlowChainELBuilder builder = LiteFlowChainELBuilder.createChain().setChainId(chainId);
|
LiteFlowChainELBuilder builder = LiteFlowChainELBuilder.createChain().setChainId(chainId).setNamespace(namespace);
|
||||||
|
|
||||||
// 如果有route这个标签,说明是决策表chain
|
// 如果有route这个标签,说明是决策表chain
|
||||||
// 决策表链路必须有route和body这两个标签
|
// 决策表链路必须有route和body这两个标签
|
||||||
|
@ -362,6 +370,7 @@ public class ParserHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
builder.build();
|
builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.yomahub.liteflow.util;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.yomahub.liteflow.exception.JsonProcessException;
|
import com.yomahub.liteflow.exception.JsonProcessException;
|
||||||
|
@ -27,6 +28,7 @@ public class JsonUtil {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
objectMapper.setTimeZone(TimeZone.getDefault());
|
objectMapper.setTimeZone(TimeZone.getDefault());
|
||||||
|
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toJsonString(Object object) {
|
public static String toJsonString(Object object) {
|
||||||
|
@ -71,5 +73,4 @@ public class JsonUtil {
|
||||||
throw new JsonProcessException(errMsg);
|
throw new JsonProcessException(errMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,13 @@
|
||||||
type (script|boolean_script|switch_script|for_script) #IMPLIED
|
type (script|boolean_script|switch_script|for_script) #IMPLIED
|
||||||
class CDATA #IMPLIED
|
class CDATA #IMPLIED
|
||||||
file CDATA #IMPLIED
|
file CDATA #IMPLIED
|
||||||
language (qlexpress|groovy|js|python|lua|aviator|java) #IMPLIED
|
language (qlexpress|groovy|js|python|lua|aviator|java|kotlin) #IMPLIED
|
||||||
|
enable (true|false) #IMPLIED
|
||||||
>
|
>
|
||||||
<!ATTLIST chain
|
<!ATTLIST chain
|
||||||
id CDATA #IMPLIED
|
id CDATA #IMPLIED
|
||||||
name CDATA #IMPLIED
|
name CDATA #IMPLIED
|
||||||
extends CDATA #IMPLIED
|
extends CDATA #IMPLIED
|
||||||
|
enable (true|false) #IMPLIED
|
||||||
|
namespace CDATA #IMPLIED
|
||||||
>
|
>
|
|
@ -16,7 +16,7 @@ public class SqlReadConstant {
|
||||||
|
|
||||||
public static final String SCRIPT_SQL_PATTERN = "SELECT * FROM {} WHERE {}=?";
|
public static final String SCRIPT_SQL_PATTERN = "SELECT * FROM {} WHERE {}=?";
|
||||||
|
|
||||||
public static final String CHAIN_XML_PATTERN = "<chain name=\"{}\"><![CDATA[{}]]></chain>";
|
public static final String CHAIN_XML_PATTERN = "<chain id=\"{}\" namespace=\"{}\"><route><![CDATA[{}]]></route><body><![CDATA[{}]]></body></chain>";
|
||||||
|
|
||||||
public static final String NODE_XML_PATTERN = "<nodes>{}</nodes>";
|
public static final String NODE_XML_PATTERN = "<nodes>{}</nodes>";
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sql 轮询任务抽象类,维护公共方法
|
* sql 轮询任务抽象类,维护公共方法
|
||||||
|
@ -19,11 +21,11 @@ import java.util.Set;
|
||||||
* @author houxinyu
|
* @author houxinyu
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSqlReadPollTask implements SqlReadPollTask {
|
public abstract class AbstractSqlReadPollTask<T> implements SqlReadPollTask<T> {
|
||||||
private final Map<String/*唯一键*/, String/*data-xml的sha1值*/> DATA_SHA_MAP = new HashMap<>();
|
private final Map<String/*唯一键*/, String/*data-xml的sha1值*/> DATA_SHA_MAP = new HashMap<>();
|
||||||
private final SqlRead read;
|
private final SqlRead<T> read;
|
||||||
|
|
||||||
public AbstractSqlReadPollTask(SqlRead read) {
|
public AbstractSqlReadPollTask(SqlRead<T> read) {
|
||||||
this.read = read;
|
this.read = read;
|
||||||
|
|
||||||
if (!read.type().equals(type())) {
|
if (!read.type().equals(type())) {
|
||||||
|
@ -33,35 +35,34 @@ public abstract class AbstractSqlReadPollTask implements SqlReadPollTask {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
Map<String/*唯一键*/, String/*data-xml*/> newData = read.read();
|
List<T> dataList = read.read();
|
||||||
// 新增或者更新的元素
|
// 新增或者更新的元素
|
||||||
Map<String, String> saveElementMap = new HashMap<>();
|
List<T> saveElementList = new ArrayList<>();
|
||||||
// 删除的元素
|
// 删除的元素
|
||||||
List<String> deleteElementIds = new ArrayList<>();
|
List<String> deleteElementIds;
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : newData.entrySet()) {
|
for (T data : dataList) {
|
||||||
String id = entry.getKey();
|
String id = getKey(data);
|
||||||
String element = entry.getValue();
|
String newSHA = getNeedSha1Value(data);
|
||||||
String newSHA = DigestUtil.sha1Hex(element);
|
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
// 如果封装的SHAMap中不存在该chain, 表示该元素为新增
|
// 如果封装的SHAMap中不存在该chain, 表示该元素为新增
|
||||||
if (!DATA_SHA_MAP.containsKey(id)) {
|
if (!DATA_SHA_MAP.containsKey(id)) {
|
||||||
saveElementMap.put(id, element);
|
saveElementList.add(data);
|
||||||
|
|
||||||
DATA_SHA_MAP.put(id, newSHA);
|
DATA_SHA_MAP.put(id, newSHA);
|
||||||
}
|
}
|
||||||
// 修改
|
// 修改
|
||||||
// SHA值发生变化,表示该元素的值已被修改,重新拉取变化的chain
|
// SHA值发生变化,表示该元素的值已被修改,重新拉取变化的chain
|
||||||
else if (!StrUtil.equals(newSHA, DATA_SHA_MAP.get(id))) {
|
else if (!StrUtil.equals(newSHA, DATA_SHA_MAP.get(id))) {
|
||||||
saveElementMap.put(id, element);
|
saveElementList.add(data);
|
||||||
|
|
||||||
DATA_SHA_MAP.put(id, newSHA);
|
DATA_SHA_MAP.put(id, newSHA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> oldIdList = DATA_SHA_MAP.keySet(); // 旧的 id 列表
|
Set<String> oldIdList = DATA_SHA_MAP.keySet(); // 旧的 id 列表
|
||||||
Set<String> newIdList = newData.keySet(); // 新的 id 列表
|
Set<String> newIdList = dataList.stream().map(this::getKey).collect(Collectors.toSet()); // 新的 id 列表
|
||||||
// 计算单差集
|
// 计算单差集
|
||||||
// 计算集合的单差集,即只返回【oldIdList】中有,但是【newIdList】中没有的元素,例如:
|
// 计算集合的单差集,即只返回【oldIdList】中有,但是【newIdList】中没有的元素,例如:
|
||||||
// subtractToList([1,2,3,4],[2,3,4,5]) -》 [1]
|
// subtractToList([1,2,3,4],[2,3,4,5]) -》 [1]
|
||||||
|
@ -71,8 +72,8 @@ public abstract class AbstractSqlReadPollTask implements SqlReadPollTask {
|
||||||
DATA_SHA_MAP.remove(id);
|
DATA_SHA_MAP.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CollUtil.isNotEmpty(saveElementMap)) {
|
if (CollUtil.isNotEmpty(saveElementList)) {
|
||||||
doSave(saveElementMap);
|
doSave(saveElementList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CollUtil.isNotEmpty(deleteElementIds)) {
|
if (CollUtil.isNotEmpty(deleteElementIds)) {
|
||||||
|
@ -81,20 +82,34 @@ public abstract class AbstractSqlReadPollTask implements SqlReadPollTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initData(Map<String/*唯一键*/, String/*data-xml的数据*/> dataMap) {
|
public void initData(List<T> dataList) {
|
||||||
DATA_SHA_MAP.putAll(shaMapValue(dataMap));
|
DATA_SHA_MAP.putAll(shaValue(dataList));
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void doSave(Map<String, String> saveElementMap);
|
public abstract void doSave(List<T> saveElementList);
|
||||||
|
|
||||||
public abstract void doDelete(List<String> deleteElementId);
|
public abstract void doDelete(List<String> deleteElementId);
|
||||||
|
|
||||||
private Map<String/*唯一键*/, String/*data-xml的sha1值*/> shaMapValue(Map<String, String> dataMap) {
|
private Map<String/*唯一键*/, String/*data-xml的sha1值*/> shaValue(List<T> dataList) {
|
||||||
Map<String, String> result = new HashMap<>();
|
Map<String, String> result = new HashMap<>();
|
||||||
dataMap.forEach((k, v) -> {
|
dataList.forEach(t -> result.put(getKey(t), DigestUtil.sha1Hex(getNeedSha1Value(t))));
|
||||||
result.put(k, DigestUtil.sha1Hex(v));
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getNeedSha1Value(T data) {
|
||||||
|
if (StrUtil.isBlank(getExtValue(data))) {
|
||||||
|
return DigestUtil.sha1Hex(getValue(data));
|
||||||
|
}else{
|
||||||
|
return DigestUtil.sha1Hex(getValue(data) + "|||" + getExtValue(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是chain,那就是返回chain的id,如果是script,那就返回script的id
|
||||||
|
protected abstract String getKey(T t);
|
||||||
|
|
||||||
|
// 如果是chain,那就返回EL,如果是script,那就返回脚本数据
|
||||||
|
protected abstract String getValue(T t);
|
||||||
|
|
||||||
|
// 如果是chain,那就返回route el,如果是script,这个不返回,因为script没有扩展value
|
||||||
|
protected abstract String getExtValue(T t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.parser.sql.polling;
|
||||||
|
|
||||||
import com.yomahub.liteflow.parser.constant.ReadType;
|
import com.yomahub.liteflow.parser.constant.ReadType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,7 +12,7 @@ import java.util.Map;
|
||||||
* @author houxinyu
|
* @author houxinyu
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public interface SqlReadPollTask {
|
public interface SqlReadPollTask<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行
|
* 执行
|
||||||
|
@ -21,9 +22,8 @@ public interface SqlReadPollTask {
|
||||||
/**
|
/**
|
||||||
* 初始化数据
|
* 初始化数据
|
||||||
*
|
*
|
||||||
* @param dataMap 数据
|
|
||||||
*/
|
*/
|
||||||
void initData(Map<String/*唯一键*/, String/*data-xml的数据*/> dataMap);
|
void initData(List<T> dataList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package com.yomahub.liteflow.parser.sql.polling.impl;
|
package com.yomahub.liteflow.parser.sql.polling.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
|
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
|
||||||
import com.yomahub.liteflow.flow.FlowBus;
|
import com.yomahub.liteflow.flow.FlowBus;
|
||||||
import com.yomahub.liteflow.parser.constant.ReadType;
|
import com.yomahub.liteflow.parser.constant.ReadType;
|
||||||
import com.yomahub.liteflow.parser.sql.polling.AbstractSqlReadPollTask;
|
import com.yomahub.liteflow.parser.sql.polling.AbstractSqlReadPollTask;
|
||||||
import com.yomahub.liteflow.parser.sql.read.SqlRead;
|
import com.yomahub.liteflow.parser.sql.read.SqlRead;
|
||||||
|
import com.yomahub.liteflow.parser.sql.read.vo.ChainVO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* chain 读取任务
|
* chain 读取任务
|
||||||
|
@ -16,20 +19,20 @@ import java.util.Map;
|
||||||
* @author houxinyu
|
* @author houxinyu
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public class ChainReadPollTask extends AbstractSqlReadPollTask {
|
public class ChainReadPollTask extends AbstractSqlReadPollTask<ChainVO> {
|
||||||
|
|
||||||
public ChainReadPollTask(SqlRead read) {
|
public ChainReadPollTask(SqlRead<ChainVO> read) {
|
||||||
super(read);
|
super(read);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doSave(Map<String, String> saveElementMap) {
|
public void doSave(List<ChainVO> saveElementList) {
|
||||||
for (Map.Entry<String, String> entry : saveElementMap.entrySet()) {
|
saveElementList.forEach(chainVO ->
|
||||||
String chainName = entry.getKey();
|
LiteFlowChainELBuilder.createChain().setChainId(chainVO.getChainId())
|
||||||
String newData = entry.getValue();
|
.setRoute(chainVO.getRoute())
|
||||||
|
.setNamespace(chainVO.getNamespace())
|
||||||
LiteFlowChainELBuilder.createChain().setChainId(chainName).setEL(newData).build();
|
.setEL(chainVO.getBody())
|
||||||
}
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,6 +42,21 @@ public class ChainReadPollTask extends AbstractSqlReadPollTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getKey(ChainVO chainVO) {
|
||||||
|
return chainVO.getChainId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getValue(ChainVO chainVO) {
|
||||||
|
return chainVO.getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getExtValue(ChainVO chainVO) {
|
||||||
|
return chainVO.getRoute();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReadType type() {
|
public ReadType type() {
|
||||||
return ReadType.CHAIN;
|
return ReadType.CHAIN;
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
package com.yomahub.liteflow.parser.sql.polling.impl;
|
package com.yomahub.liteflow.parser.sql.polling.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
|
||||||
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
import com.yomahub.liteflow.flow.FlowBus;
|
import com.yomahub.liteflow.flow.FlowBus;
|
||||||
import com.yomahub.liteflow.parser.constant.ReadType;
|
import com.yomahub.liteflow.parser.constant.ReadType;
|
||||||
import com.yomahub.liteflow.parser.helper.NodeConvertHelper;
|
import com.yomahub.liteflow.parser.helper.NodeConvertHelper;
|
||||||
import com.yomahub.liteflow.parser.sql.polling.AbstractSqlReadPollTask;
|
import com.yomahub.liteflow.parser.sql.polling.AbstractSqlReadPollTask;
|
||||||
import com.yomahub.liteflow.parser.sql.read.SqlRead;
|
import com.yomahub.liteflow.parser.sql.read.SqlRead;
|
||||||
|
import com.yomahub.liteflow.parser.sql.read.vo.ScriptVO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本轮询任务
|
* 脚本轮询任务
|
||||||
|
@ -16,32 +21,45 @@ import java.util.Map;
|
||||||
* @author houxinyu
|
* @author houxinyu
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public class ScriptReadPollTask extends AbstractSqlReadPollTask {
|
public class ScriptReadPollTask extends AbstractSqlReadPollTask<ScriptVO> {
|
||||||
public ScriptReadPollTask(SqlRead read) {
|
public ScriptReadPollTask(SqlRead<ScriptVO> read) {
|
||||||
super(read);
|
super(read);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doSave(Map<String, String> saveElementMap) {
|
public void doSave(List<ScriptVO> saveElementList) {
|
||||||
for (Map.Entry<String, String> entry : saveElementMap.entrySet()) {
|
saveElementList.forEach(scriptVO -> LiteFlowNodeBuilder.createScriptNode()
|
||||||
String scriptKey = entry.getKey();
|
.setId(scriptVO.getNodeId())
|
||||||
String newData = entry.getValue();
|
.setType(NodeTypeEnum.getEnumByCode(scriptVO.getType()))
|
||||||
|
.setName(scriptVO.getName())
|
||||||
NodeConvertHelper.NodeSimpleVO scriptVO = NodeConvertHelper.convert(scriptKey);
|
.setScript(scriptVO.getScript())
|
||||||
NodeConvertHelper.changeScriptNode(scriptVO, newData);
|
.setLanguage(scriptVO.getLanguage())
|
||||||
}
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doDelete(List<String> deleteElementId) {
|
public void doDelete(List<String> deleteElementId) {
|
||||||
for (String id : deleteElementId) {
|
for (String id : deleteElementId) {
|
||||||
NodeConvertHelper.NodeSimpleVO scriptVO = NodeConvertHelper.convert(id);
|
|
||||||
|
|
||||||
// 删除script
|
// 删除script
|
||||||
FlowBus.unloadScriptNode(scriptVO.getNodeId());
|
FlowBus.unloadScriptNode(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getKey(ScriptVO scriptVO) {
|
||||||
|
return scriptVO.getNodeId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getValue(ScriptVO scriptVO) {
|
||||||
|
return scriptVO.getScript();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getExtValue(ScriptVO scriptVO) {
|
||||||
|
return StrUtil.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReadType type() {
|
public ReadType type() {
|
||||||
return ReadType.SCRIPT;
|
return ReadType.SCRIPT;
|
||||||
|
|
|
@ -9,7 +9,9 @@ import com.yomahub.liteflow.parser.sql.util.LiteFlowJdbcUtil;
|
||||||
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,7 +22,7 @@ import java.util.Map;
|
||||||
* @author Bryan.Zhang
|
* @author Bryan.Zhang
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSqlRead implements SqlRead {
|
public abstract class AbstractSqlRead<T> implements SqlRead<T> {
|
||||||
public final SQLParserVO config;
|
public final SQLParserVO config;
|
||||||
private static LFLog LOG = LFLoggerManager.getLogger(AbstractSqlRead.class);
|
private static LFLog LOG = LFLoggerManager.getLogger(AbstractSqlRead.class);
|
||||||
|
|
||||||
|
@ -29,10 +31,10 @@ public abstract class AbstractSqlRead implements SqlRead {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String/*规则唯一键*/, String/*规则内容*/> read() {
|
public List<T> read() {
|
||||||
// 如果不需要读取直接返回
|
// 如果不需要读取直接返回
|
||||||
if (!needRead()) {
|
if (!needRead()) {
|
||||||
return new HashMap<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkConfig();
|
checkConfig();
|
||||||
|
@ -40,7 +42,7 @@ public abstract class AbstractSqlRead implements SqlRead {
|
||||||
// 如果允许,就打印 sql 语句
|
// 如果允许,就打印 sql 语句
|
||||||
logSqlIfEnable(sqlCmd);
|
logSqlIfEnable(sqlCmd);
|
||||||
|
|
||||||
Map<String/*规则唯一键*/, String/*规则*/> result = new HashMap<>();
|
List<T> result = new ArrayList<>();
|
||||||
Connection conn = null;
|
Connection conn = null;
|
||||||
PreparedStatement stmt = null;
|
PreparedStatement stmt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
|
@ -54,9 +56,6 @@ public abstract class AbstractSqlRead implements SqlRead {
|
||||||
rs = stmt.executeQuery();
|
rs = stmt.executeQuery();
|
||||||
|
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
String xml = buildXmlElement(rs);
|
|
||||||
String uniqueKey = buildXmlElementUniqueKey(rs);
|
|
||||||
|
|
||||||
if (hasEnableFiled()){
|
if (hasEnableFiled()){
|
||||||
boolean enable = getEnableFiledValue(rs);
|
boolean enable = getEnableFiledValue(rs);
|
||||||
// 如果停用,直接跳过
|
// 如果停用,直接跳过
|
||||||
|
@ -64,7 +63,7 @@ public abstract class AbstractSqlRead implements SqlRead {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.put(uniqueKey, xml);
|
result.add(parse(rs));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ELSQLException(e.getMessage());
|
throw new ELSQLException(e.getMessage());
|
||||||
|
@ -76,6 +75,8 @@ public abstract class AbstractSqlRead implements SqlRead {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract T parse(ResultSet rs) throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否包含启停字段
|
* 是否包含启停字段
|
||||||
*/
|
*/
|
||||||
|
@ -88,10 +89,6 @@ public abstract class AbstractSqlRead implements SqlRead {
|
||||||
|
|
||||||
public abstract String buildQuerySql();
|
public abstract String buildQuerySql();
|
||||||
|
|
||||||
public abstract String buildXmlElement(ResultSet rs) throws SQLException;
|
|
||||||
|
|
||||||
public abstract String buildXmlElementUniqueKey(ResultSet rs) throws SQLException;
|
|
||||||
|
|
||||||
public abstract void checkConfig();
|
public abstract void checkConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.yomahub.liteflow.parser.sql.read;
|
||||||
|
|
||||||
import com.yomahub.liteflow.parser.constant.ReadType;
|
import com.yomahub.liteflow.parser.constant.ReadType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,14 +12,14 @@ import java.util.Map;
|
||||||
* @author houxinyu
|
* @author houxinyu
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public interface SqlRead {
|
public interface SqlRead<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取
|
* 读取
|
||||||
*
|
*
|
||||||
* @return 返回读取到的数据
|
* @return 返回读取到的数据
|
||||||
*/
|
*/
|
||||||
Map<String/*规则唯一键*/, String/*规则内容*/> read();
|
List<T> read();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
|
|
|
@ -19,8 +19,8 @@ import java.util.Map;
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public class SqlReadFactory {
|
public class SqlReadFactory {
|
||||||
private static final Map<ReadType, SqlRead> READ_MAP = new HashMap<>();
|
private static final Map<ReadType, SqlRead<?>> READ_MAP = new HashMap<>();
|
||||||
private static final Map<ReadType, SqlReadPollTask> POLL_TASK_MAP = new HashMap<>();
|
private static final Map<ReadType, SqlReadPollTask<?>> POLL_TASK_MAP = new HashMap<>();
|
||||||
|
|
||||||
public static void registerRead(SQLParserVO config) {
|
public static void registerRead(SQLParserVO config) {
|
||||||
READ_MAP.put(ReadType.CHAIN, new ChainRead(config));
|
READ_MAP.put(ReadType.CHAIN, new ChainRead(config));
|
||||||
|
@ -28,19 +28,21 @@ public class SqlReadFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerSqlReadPollTask(ReadType readType) {
|
public static void registerSqlReadPollTask(ReadType readType) {
|
||||||
SqlRead sqlRead = getSqlRead(readType);
|
SqlRead<?> sqlRead = getSqlRead(readType);
|
||||||
if (ReadType.CHAIN.equals(readType)) {
|
if (ReadType.CHAIN.equals(readType)) {
|
||||||
POLL_TASK_MAP.put(ReadType.CHAIN, new ChainReadPollTask(sqlRead));
|
POLL_TASK_MAP.put(ReadType.CHAIN, new ChainReadPollTask((ChainRead)sqlRead));
|
||||||
} else if (ReadType.SCRIPT.equals(readType)) {
|
} else if (ReadType.SCRIPT.equals(readType)) {
|
||||||
POLL_TASK_MAP.put(ReadType.SCRIPT, new ScriptReadPollTask(sqlRead));
|
POLL_TASK_MAP.put(ReadType.SCRIPT, new ScriptReadPollTask((ScriptRead)sqlRead));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SqlRead getSqlRead(ReadType readType) {
|
@SuppressWarnings("unchecked")
|
||||||
return READ_MAP.get(readType);
|
public static <T> SqlRead<T> getSqlRead(ReadType readType) {
|
||||||
|
return (SqlRead<T>)READ_MAP.get(readType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SqlReadPollTask getSqlReadPollTask(ReadType readType) {
|
@SuppressWarnings("unchecked")
|
||||||
return POLL_TASK_MAP.get(readType);
|
public static <T> SqlReadPollTask<T> getSqlReadPollTask(ReadType readType) {
|
||||||
|
return (SqlReadPollTask<T>)POLL_TASK_MAP.get(readType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.yomahub.liteflow.parser.constant.ReadType;
|
||||||
import com.yomahub.liteflow.parser.constant.SqlReadConstant;
|
import com.yomahub.liteflow.parser.constant.SqlReadConstant;
|
||||||
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
|
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
|
||||||
import com.yomahub.liteflow.parser.sql.read.AbstractSqlRead;
|
import com.yomahub.liteflow.parser.sql.read.AbstractSqlRead;
|
||||||
|
import com.yomahub.liteflow.parser.sql.read.vo.ChainVO;
|
||||||
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
@ -17,12 +18,26 @@ import java.sql.SQLException;
|
||||||
* @author houxinyu
|
* @author houxinyu
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public class ChainRead extends AbstractSqlRead {
|
public class ChainRead extends AbstractSqlRead<ChainVO> {
|
||||||
|
|
||||||
public ChainRead(SQLParserVO config) {
|
public ChainRead(SQLParserVO config) {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChainVO parse(ResultSet rs) throws SQLException {
|
||||||
|
ChainVO chainVO = new ChainVO();
|
||||||
|
chainVO.setChainId(getStringFromRsWithCheck(rs, super.config.getChainNameField()));
|
||||||
|
chainVO.setBody(getStringFromRsWithCheck(rs, super.config.getElDataField()));
|
||||||
|
if (StrUtil.isNotBlank(super.config.getNamespaceField())){
|
||||||
|
chainVO.setNamespace(getStringFromRs(rs, super.config.getNamespaceField()));
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(super.config.getRouteField())){
|
||||||
|
chainVO.setRoute(getStringFromRs(rs, super.config.getRouteField()));
|
||||||
|
}
|
||||||
|
return chainVO;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasEnableFiled() {
|
public boolean hasEnableFiled() {
|
||||||
String chainEnableField = super.config.getChainEnableField();
|
String chainEnableField = super.config.getChainEnableField();
|
||||||
|
@ -70,20 +85,6 @@ public class ChainRead extends AbstractSqlRead {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String buildXmlElement(ResultSet rs) throws SQLException {
|
|
||||||
String elDataField = super.config.getElDataField();
|
|
||||||
|
|
||||||
return getStringFromRs(rs, elDataField);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String buildXmlElementUniqueKey(ResultSet rs) throws SQLException {
|
|
||||||
String chainNameField = super.config.getChainNameField();
|
|
||||||
|
|
||||||
return getStringFromRsWithCheck(rs, chainNameField);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReadType type() {
|
public ReadType type() {
|
||||||
return ReadType.CHAIN;
|
return ReadType.CHAIN;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.yomahub.liteflow.parser.constant.ReadType;
|
||||||
import com.yomahub.liteflow.parser.constant.SqlReadConstant;
|
import com.yomahub.liteflow.parser.constant.SqlReadConstant;
|
||||||
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
|
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
|
||||||
import com.yomahub.liteflow.parser.sql.read.AbstractSqlRead;
|
import com.yomahub.liteflow.parser.sql.read.AbstractSqlRead;
|
||||||
|
import com.yomahub.liteflow.parser.sql.read.vo.ScriptVO;
|
||||||
import com.yomahub.liteflow.parser.sql.util.LiteFlowJdbcUtil;
|
import com.yomahub.liteflow.parser.sql.util.LiteFlowJdbcUtil;
|
||||||
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
||||||
|
|
||||||
|
@ -24,12 +25,23 @@ import java.util.Objects;
|
||||||
* @author houxinyu
|
* @author houxinyu
|
||||||
* @since 2.11.1
|
* @since 2.11.1
|
||||||
*/
|
*/
|
||||||
public class ScriptRead extends AbstractSqlRead {
|
public class ScriptRead extends AbstractSqlRead<ScriptVO> {
|
||||||
|
|
||||||
public ScriptRead(SQLParserVO config) {
|
public ScriptRead(SQLParserVO config) {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ScriptVO parse(ResultSet rs) throws SQLException {
|
||||||
|
ScriptVO scriptVO = new ScriptVO();
|
||||||
|
scriptVO.setNodeId(getStringFromRsWithCheck(rs, super.config.getScriptIdField()));
|
||||||
|
scriptVO.setName(getStringFromRs(rs, super.config.getScriptNameField()));
|
||||||
|
scriptVO.setType(getStringFromRsWithCheck(rs, super.config.getScriptTypeField()));
|
||||||
|
scriptVO.setLanguage(getStringFromRs(rs, super.config.getScriptLanguageField()));
|
||||||
|
scriptVO.setScript(getStringFromRsWithCheck(rs, super.config.getScriptDataField()));
|
||||||
|
return scriptVO;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasEnableFiled() {
|
public boolean hasEnableFiled() {
|
||||||
String scriptEnableField = super.config.getScriptEnableField();
|
String scriptEnableField = super.config.getScriptEnableField();
|
||||||
|
@ -80,46 +92,6 @@ public class ScriptRead extends AbstractSqlRead {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String buildXmlElement(ResultSet rs) throws SQLException {
|
|
||||||
String scriptDataField = super.config.getScriptDataField();
|
|
||||||
|
|
||||||
return getStringFromRs(rs, scriptDataField);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String buildXmlElementUniqueKey(ResultSet rs) throws SQLException {
|
|
||||||
String scriptIdField = super.config.getScriptIdField();
|
|
||||||
String scriptNameField = super.config.getScriptNameField();
|
|
||||||
String scriptTypeField = super.config.getScriptTypeField();
|
|
||||||
String scriptLanguageField = super.config.getScriptLanguageField();
|
|
||||||
|
|
||||||
String id = getStringFromRsWithCheck(rs, scriptIdField);
|
|
||||||
String name = getStringFromRsWithCheck(rs, scriptNameField);
|
|
||||||
String type = getStringFromRsWithCheck(rs, scriptTypeField);
|
|
||||||
String language = withLanguage() ? getStringFromRs(rs, scriptLanguageField) : null;
|
|
||||||
|
|
||||||
NodeTypeEnum nodeTypeEnum = NodeTypeEnum.getEnumByCode(type);
|
|
||||||
if (Objects.isNull(nodeTypeEnum)) {
|
|
||||||
throw new ELSQLException(StrUtil.format("Invalid type value[{}]", type));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nodeTypeEnum.isScript()) {
|
|
||||||
throw new ELSQLException(StrUtil.format("The type value[{}] is not a script type", type));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (withLanguage() && !ScriptTypeEnum.checkScriptType(language)) {
|
|
||||||
throw new ELSQLException(StrUtil.format("The language value[{}] is invalid", language));
|
|
||||||
}
|
|
||||||
List<String> keys = CollUtil.newArrayList(id, type, name);
|
|
||||||
if (StrUtil.isNotBlank(language)) {
|
|
||||||
keys.add(language);
|
|
||||||
}
|
|
||||||
|
|
||||||
return StrUtil.join(StrUtil.COLON, keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean needRead() {
|
public boolean needRead() {
|
||||||
if (StrUtil.isBlank(super.config.getScriptTableName())) {
|
if (StrUtil.isBlank(super.config.getScriptTableName())) {
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.yomahub.liteflow.parser.sql.read.vo;
|
||||||
|
|
||||||
|
public class ChainVO {
|
||||||
|
|
||||||
|
private String chainId;
|
||||||
|
|
||||||
|
private String route;
|
||||||
|
|
||||||
|
private String namespace;
|
||||||
|
|
||||||
|
private String body;
|
||||||
|
|
||||||
|
public String getChainId() {
|
||||||
|
return chainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChainId(String chainId) {
|
||||||
|
this.chainId = chainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRoute() {
|
||||||
|
return route;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoute(String route) {
|
||||||
|
this.route = route;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNamespace(String namespace) {
|
||||||
|
this.namespace = namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(String body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.yomahub.liteflow.parser.sql.read.vo;
|
||||||
|
|
||||||
|
public class ScriptVO {
|
||||||
|
|
||||||
|
private String nodeId;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String language;
|
||||||
|
|
||||||
|
private Boolean enable;
|
||||||
|
|
||||||
|
private String script;
|
||||||
|
|
||||||
|
public String getNodeId() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeId(String nodeId) {
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(String language) {
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEnable() {
|
||||||
|
return enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnable(Boolean enable) {
|
||||||
|
this.enable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getScript() {
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScript(String script) {
|
||||||
|
this.script = script;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,9 +11,12 @@ import com.yomahub.liteflow.parser.constant.ReadType;
|
||||||
|
|
||||||
import com.yomahub.liteflow.parser.helper.NodeConvertHelper;
|
import com.yomahub.liteflow.parser.helper.NodeConvertHelper;
|
||||||
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
|
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
|
||||||
|
import com.yomahub.liteflow.parser.sql.polling.SqlReadPollTask;
|
||||||
import com.yomahub.liteflow.parser.sql.read.AbstractSqlRead;
|
import com.yomahub.liteflow.parser.sql.read.AbstractSqlRead;
|
||||||
import com.yomahub.liteflow.parser.sql.read.SqlRead;
|
import com.yomahub.liteflow.parser.sql.read.SqlRead;
|
||||||
import com.yomahub.liteflow.parser.sql.read.SqlReadFactory;
|
import com.yomahub.liteflow.parser.sql.read.SqlReadFactory;
|
||||||
|
import com.yomahub.liteflow.parser.sql.read.vo.ChainVO;
|
||||||
|
import com.yomahub.liteflow.parser.sql.read.vo.ScriptVO;
|
||||||
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
@ -87,30 +90,30 @@ public class JDBCHelper {
|
||||||
* @return 数据内容
|
* @return 数据内容
|
||||||
*/
|
*/
|
||||||
public String getContent() {
|
public String getContent() {
|
||||||
SqlRead chainRead = SqlReadFactory.getSqlRead(ReadType.CHAIN);
|
SqlRead<ChainVO> chainRead = SqlReadFactory.getSqlRead(ReadType.CHAIN);
|
||||||
SqlRead scriptRead = SqlReadFactory.getSqlRead(ReadType.SCRIPT);
|
SqlRead<ScriptVO> scriptRead = SqlReadFactory.getSqlRead(ReadType.SCRIPT);
|
||||||
|
|
||||||
// 获取 chain 数据
|
// 获取 chain 数据
|
||||||
Map<String, String> chainMap = chainRead.read();
|
List<ChainVO> chainVOList = chainRead.read();
|
||||||
List<String> chainList = new ArrayList<>();
|
List<String> chainList = new ArrayList<>();
|
||||||
|
|
||||||
chainMap.entrySet().stream()
|
chainVOList.forEach(
|
||||||
.filter(entry -> StrUtil.isNotBlank(entry.getValue()))
|
chainVO -> chainList.add(StrUtil.format(CHAIN_XML_PATTERN, XmlUtil.escape(chainVO.getChainId()), StrUtil.emptyIfNull(chainVO.getNamespace()), StrUtil.emptyIfNull(chainVO.getRoute()), chainVO.getBody()))
|
||||||
.forEach(
|
);
|
||||||
entry -> chainList.add(StrUtil.format(CHAIN_XML_PATTERN, XmlUtil.escape(entry.getKey()), entry.getValue()))
|
|
||||||
);
|
|
||||||
|
|
||||||
String chainsContent = CollUtil.join(chainList, StrUtil.EMPTY);
|
String chainsContent = CollUtil.join(chainList, StrUtil.EMPTY);
|
||||||
|
|
||||||
// 获取脚本数据
|
// 获取脚本数据
|
||||||
Map<String, String> scriptMap = scriptRead.read();
|
List<ScriptVO> scriptVOList = scriptRead.read();
|
||||||
List<String> scriptList = new ArrayList<>();
|
List<String> scriptList = new ArrayList<>();
|
||||||
scriptMap.forEach((scriptKey, elData) -> {
|
|
||||||
NodeConvertHelper.NodeSimpleVO scriptVO = NodeConvertHelper.convert(scriptKey);
|
scriptVOList.forEach(scriptVO -> {
|
||||||
String id = scriptVO.getNodeId();
|
String id = scriptVO.getNodeId();
|
||||||
String name = scriptVO.getName();
|
String name = scriptVO.getName();
|
||||||
String type = scriptVO.getType();
|
String type = scriptVO.getType();
|
||||||
String language = scriptVO.getLanguage();
|
String language = scriptVO.getLanguage();
|
||||||
|
String elData = scriptVO.getScript();
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(scriptVO.getLanguage())) {
|
if (StringUtils.isNotBlank(scriptVO.getLanguage())) {
|
||||||
scriptList.add(StrUtil.format(NODE_ITEM_WITH_LANGUAGE_XML_PATTERN, XmlUtil.escape(id), XmlUtil.escape(name), type, language, elData));
|
scriptList.add(StrUtil.format(NODE_ITEM_WITH_LANGUAGE_XML_PATTERN, XmlUtil.escape(id), XmlUtil.escape(name), type, language, elData));
|
||||||
|
@ -118,11 +121,14 @@ public class JDBCHelper {
|
||||||
scriptList.add(StrUtil.format(NODE_ITEM_XML_PATTERN, XmlUtil.escape(id), XmlUtil.escape(name), type, elData));
|
scriptList.add(StrUtil.format(NODE_ITEM_XML_PATTERN, XmlUtil.escape(id), XmlUtil.escape(name), type, elData));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
String nodesContent = StrUtil.format(NODE_XML_PATTERN, CollUtil.join(scriptList, StrUtil.EMPTY));
|
String nodesContent = StrUtil.format(NODE_XML_PATTERN, CollUtil.join(scriptList, StrUtil.EMPTY));
|
||||||
|
|
||||||
// 初始化轮询任务
|
// 初始化轮询任务
|
||||||
SqlReadFactory.getSqlReadPollTask(ReadType.CHAIN).initData(chainMap);
|
SqlReadPollTask<ChainVO> sqlReadPollTask4Chain = SqlReadFactory.getSqlReadPollTask(ReadType.CHAIN);
|
||||||
SqlReadFactory.getSqlReadPollTask(ReadType.SCRIPT).initData(scriptMap);
|
sqlReadPollTask4Chain.initData(chainVOList);
|
||||||
|
SqlReadPollTask<ScriptVO> sqlReadPollTask4Script = SqlReadFactory.getSqlReadPollTask(ReadType.SCRIPT);
|
||||||
|
sqlReadPollTask4Script.initData(scriptVOList);
|
||||||
return StrUtil.format(XML_PATTERN, nodesContent, chainsContent);
|
return StrUtil.format(XML_PATTERN, nodesContent, chainsContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,16 @@ public class SQLParserVO {
|
||||||
*/
|
*/
|
||||||
private String elDataField = "el_data";
|
private String elDataField = "el_data";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 决策路由字段
|
||||||
|
*/
|
||||||
|
private String routeField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命名空间字段
|
||||||
|
*/
|
||||||
|
private String namespaceField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否启动某一条chain
|
* 是否启动某一条chain
|
||||||
*/
|
*/
|
||||||
|
@ -310,4 +320,20 @@ public class SQLParserVO {
|
||||||
public boolean hasEnableField() {
|
public boolean hasEnableField() {
|
||||||
return StrUtil.isNotBlank(chainEnableField) || StrUtil.isNotBlank(scriptEnableField);
|
return StrUtil.isNotBlank(chainEnableField) || StrUtil.isNotBlank(scriptEnableField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRouteField() {
|
||||||
|
return routeField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouteField(String routeField) {
|
||||||
|
this.routeField = routeField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespaceField() {
|
||||||
|
return namespaceField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNamespaceField(String namespaceField) {
|
||||||
|
this.namespaceField = namespaceField;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Kotlin的实现
|
||||||
|
com.yomahub.liteflow.script.kotlin.KotlinScriptExecutor
|
|
@ -23,6 +23,7 @@
|
||||||
<module>liteflow-script-lua</module>
|
<module>liteflow-script-lua</module>
|
||||||
<module>liteflow-script-aviator</module>
|
<module>liteflow-script-aviator</module>
|
||||||
<module>liteflow-script-java</module>
|
<module>liteflow-script-java</module>
|
||||||
|
<module>liteflow-script-kotlin</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -8,6 +8,7 @@ import cn.hutool.core.util.CharsetUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.yomahub.liteflow.exception.ConfigErrorException;
|
import com.yomahub.liteflow.exception.ConfigErrorException;
|
||||||
import com.yomahub.liteflow.spi.PathContentParser;
|
import com.yomahub.liteflow.spi.PathContentParser;
|
||||||
|
import com.yomahub.liteflow.util.PathMatchUtil;
|
||||||
import org.noear.solon.Utils;
|
import org.noear.solon.Utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -47,9 +48,10 @@ public class SolonPathContentParser implements PathContentParser {
|
||||||
if (CollectionUtil.isEmpty(pathList)) {
|
if (CollectionUtil.isEmpty(pathList)) {
|
||||||
throw new ConfigErrorException("rule source must not be null");
|
throw new ConfigErrorException("rule source must not be null");
|
||||||
}
|
}
|
||||||
|
List<String> absolutePathList = PathMatchUtil.searchAbsolutePath(pathList);
|
||||||
List<URL> allResource = new ArrayList<>();
|
List<URL> allResource = new ArrayList<>();
|
||||||
for (String path : pathList) {
|
|
||||||
|
for (String path : absolutePathList) {
|
||||||
// 如果 path 是绝对路径且这个文件存在时,我们认为这是一个本地文件路径,而并非classpath路径
|
// 如果 path 是绝对路径且这个文件存在时,我们认为这是一个本地文件路径,而并非classpath路径
|
||||||
if (FileUtil.isAbsolutePath(path) && FileUtil.isFile(path)) {
|
if (FileUtil.isAbsolutePath(path) && FileUtil.isFile(path)) {
|
||||||
allResource.add(new File(path).toURI().toURL());
|
allResource.add(new File(path).toURI().toURL());
|
||||||
|
|
|
@ -1,24 +1,27 @@
|
||||||
package com.yomahub.liteflow.spi.spring;
|
package com.yomahub.liteflow.spi.spring;
|
||||||
|
|
||||||
import cn.hutool.core.annotation.AnnotationUtil;
|
import cn.hutool.core.annotation.AnnotationUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
|
import com.yomahub.liteflow.annotation.*;
|
||||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
|
||||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
|
||||||
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
|
||||||
import com.yomahub.liteflow.annotation.util.AnnoUtil;
|
import com.yomahub.liteflow.annotation.util.AnnoUtil;
|
||||||
import com.yomahub.liteflow.core.proxy.DeclWarpBean;
|
import com.yomahub.liteflow.core.proxy.DeclWarpBean;
|
||||||
import com.yomahub.liteflow.core.proxy.MethodWrapBean;
|
import com.yomahub.liteflow.core.proxy.MethodWrapBean;
|
||||||
|
import com.yomahub.liteflow.core.proxy.ParameterWrapBean;
|
||||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
import com.yomahub.liteflow.exception.CmpDefinitionException;
|
import com.yomahub.liteflow.exception.CmpDefinitionException;
|
||||||
import com.yomahub.liteflow.spi.DeclComponentParser;
|
import com.yomahub.liteflow.spi.DeclComponentParser;
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring环境声明式组件解析器实现
|
* Spring环境声明式组件解析器实现
|
||||||
|
@ -73,7 +76,16 @@ public class SpringDeclComponentParser implements DeclComponentParser {
|
||||||
nodeType = liteflowMethod.nodeType();
|
nodeType = liteflowMethod.nodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DeclInfo(currNodeId, currNodeName, nodeType, method.getDeclaringClass(), new MethodWrapBean(method, liteflowMethod, liteflowRetry));
|
|
||||||
|
Parameter[] parameters = method.getParameters();
|
||||||
|
List<ParameterWrapBean> parameterList = IntStream.range(0, parameters.length).boxed().map(index -> {
|
||||||
|
Parameter parameter = parameters[index];
|
||||||
|
return new ParameterWrapBean(parameter.getType(), AnnotationUtil.getAnnotation(parameter, LiteflowFact.class), index);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return new DeclInfo(currNodeId, currNodeName, nodeType, method.getDeclaringClass(), new MethodWrapBean(method, liteflowMethod, liteflowRetry, parameterList));
|
||||||
}).filter(declInfo -> StrUtil.isNotBlank(declInfo.getNodeId())).collect(Collectors.groupingBy(DeclInfo::getNodeId));
|
}).filter(declInfo -> StrUtil.isNotBlank(declInfo.getNodeId())).collect(Collectors.groupingBy(DeclInfo::getNodeId));
|
||||||
|
|
||||||
return definitionMap.entrySet().stream().map(entry -> {
|
return definitionMap.entrySet().stream().map(entry -> {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.EnabledIf;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -63,6 +64,29 @@ public class AbsoluteConfigPathELDeclMultiSpringbootTest extends BaseTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@EnabledIf("isWindows")
|
||||||
|
public void testAbsPath() throws Exception{
|
||||||
|
Assertions.assertTrue(() -> {
|
||||||
|
LiteflowConfig config = LiteflowConfigGetter.get();
|
||||||
|
config.setRuleSource(StrUtil.format("{}\\sub\\**\\*.xml",rootDir));
|
||||||
|
flowExecutor.reloadRule();
|
||||||
|
return flowExecutor.execute2Resp("chain1", "arg").isSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isWindows() {
|
||||||
|
try {
|
||||||
|
String osName = System.getProperty("os.name");
|
||||||
|
if (osName.isEmpty()) return false;
|
||||||
|
else {
|
||||||
|
return osName.contains("Windows");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void createFiles() {
|
public static void createFiles() {
|
||||||
rootDir = FileUtil.getAbsolutePath(ResourceUtil.getResource("").getPath());
|
rootDir = FileUtil.getAbsolutePath(ResourceUtil.getResource("").getPath());
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.yomahub.liteflow.core.FlowExecutor;
|
||||||
|
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||||
|
import com.yomahub.liteflow.test.BaseTest;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.*;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process方法上的fact映射参数测试
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
*/
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@TestPropertySource(value = "classpath:/processFact/application.properties")
|
||||||
|
@SpringBootTest(classes = ProcessFactELDeclMultiSpringbootTest.class)
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@ComponentScan({"com.yomahub.liteflow.test.processFact.cmp"})
|
||||||
|
public class ProcessFactELDeclMultiSpringbootTest extends BaseTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FlowExecutor flowExecutor;
|
||||||
|
|
||||||
|
// 最基本的情况
|
||||||
|
@Test
|
||||||
|
public void testFact1() throws Exception {
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg", createContext());
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
TestContext context = response.getContextBean(TestContext.class);
|
||||||
|
Assertions.assertEquals("jack", context.getUser().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多上下文自动搜寻
|
||||||
|
@Test
|
||||||
|
public void testFact2() throws Exception {
|
||||||
|
TestContext testContext = createContext();
|
||||||
|
Demo1Context demo1Context = new Demo1Context();
|
||||||
|
demo1Context.setData1("xxxx");
|
||||||
|
demo1Context.setData2(99);
|
||||||
|
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg", demo1Context, testContext);
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
TestContext context = response.getContextBean(TestContext.class);
|
||||||
|
Assertions.assertEquals(20, context.getUser().getCompany().getHeadCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多上下文都有user,指定上下文中的user
|
||||||
|
@Test
|
||||||
|
public void testFact3() throws Exception {
|
||||||
|
TestContext testContext = createContext();
|
||||||
|
Demo2Context demo2Context = createDemo2Context();
|
||||||
|
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg", testContext, demo2Context);
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
Demo2Context context = response.getContextBean(Demo2Context.class);
|
||||||
|
Assertions.assertEquals("rose", context.getUser().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多上下文都有user,指定上下文中的user
|
||||||
|
@Test
|
||||||
|
public void testFact4() throws Exception {
|
||||||
|
Demo3Context demo3Context = createDemo3Context();
|
||||||
|
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg", demo3Context);
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
Demo3Context context = response.getContextBean(Demo3Context.class);
|
||||||
|
Assertions.assertEquals("jelly", context.getUser().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private TestContext createContext(){
|
||||||
|
Company company = new Company("XXX有限公司", "黄河路34号303室", 400);
|
||||||
|
User user = new User("张三", 18, DateUtil.parseDate("1990-08-20"), company);
|
||||||
|
return new TestContext(user, "this is data");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Demo2Context createDemo2Context(){
|
||||||
|
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||||
|
User user = new User("李四", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||||
|
return new Demo2Context("xxx", user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Demo3Context createDemo3Context(){
|
||||||
|
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||||
|
User user = new User("王五", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||||
|
return new Demo3Context("xxx", user);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.cmp;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ConcurrentHashSet;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||||
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
|
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||||
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
|
import com.yomahub.liteflow.slot.DefaultContext;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.Company;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.User;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@LiteflowComponent
|
||||||
|
public class CmpConfig {
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "a")
|
||||||
|
public void processA(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("user") User user,
|
||||||
|
@LiteflowFact("user.company.address") String address) {
|
||||||
|
user.setName("jack");
|
||||||
|
}
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "b")
|
||||||
|
public void processB(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("user.company") Company company,
|
||||||
|
@LiteflowFact("data2") Integer data) {
|
||||||
|
company.setHeadCount(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "c")
|
||||||
|
public void processC(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("demo2Context.user") User user) {
|
||||||
|
user.setName("rose");
|
||||||
|
}
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "d")
|
||||||
|
public void processD(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("ctx.user") User user) {
|
||||||
|
user.setName("jelly");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class Company {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
private int headCount;
|
||||||
|
|
||||||
|
public Company(String name, String address, int headCount) {
|
||||||
|
this.name = name;
|
||||||
|
this.address = address;
|
||||||
|
this.headCount = headCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeadCount() {
|
||||||
|
return headCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadCount(int headCount) {
|
||||||
|
this.headCount = headCount;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class Demo1Context {
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
private Integer data2;
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getData2() {
|
||||||
|
return data2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData2(Integer data2) {
|
||||||
|
this.data2 = data2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class Demo2Context {
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public Demo2Context(String data1, User user) {
|
||||||
|
this.data1 = data1;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.context.ContextBean;
|
||||||
|
|
||||||
|
@ContextBean("ctx")
|
||||||
|
public class Demo3Context {
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public Demo3Context(String data1, User user) {
|
||||||
|
this.data1 = data1;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class TestContext {
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
public TestContext(User user, String data1) {
|
||||||
|
this.user = user;
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
private Date birthday;
|
||||||
|
|
||||||
|
private Company company;
|
||||||
|
|
||||||
|
public User(String name, int age, Date birthday, Company company) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
this.birthday = birthday;
|
||||||
|
this.company = company;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Company getCompany() {
|
||||||
|
return company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompany(Company company) {
|
||||||
|
this.company = company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getBirthday() {
|
||||||
|
return birthday;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBirthday(Date birthday) {
|
||||||
|
this.birthday = birthday;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
liteflow.rule-source=processFact/flow.xml
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<flow>
|
||||||
|
<chain name="chain1">
|
||||||
|
THEN(a);
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="chain2">
|
||||||
|
THEN(b);
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="chain3">
|
||||||
|
THEN(c);
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="chain4">
|
||||||
|
THEN(d);
|
||||||
|
</chain>
|
||||||
|
</flow>
|
|
@ -15,6 +15,7 @@ import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.EnabledIf;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -65,6 +66,29 @@ public class AbsoluteConfigPathELDeclSpringbootTest extends BaseTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@EnabledIf("isWindows")
|
||||||
|
public void testAbsPath() throws Exception{
|
||||||
|
Assertions.assertTrue(() -> {
|
||||||
|
LiteflowConfig config = LiteflowConfigGetter.get();
|
||||||
|
config.setRuleSource(StrUtil.format("{}\\sub\\**\\*.xml",rootDir));
|
||||||
|
flowExecutor.reloadRule();
|
||||||
|
return flowExecutor.execute2Resp("chain1", "arg").isSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isWindows() {
|
||||||
|
try {
|
||||||
|
String osName = System.getProperty("os.name");
|
||||||
|
if (osName.isEmpty()) return false;
|
||||||
|
else {
|
||||||
|
return osName.contains("Windows");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void createFiles() {
|
public static void createFiles() {
|
||||||
rootDir = FileUtil.getAbsolutePath(ResourceUtil.getResource("").getPath());
|
rootDir = FileUtil.getAbsolutePath(ResourceUtil.getResource("").getPath());
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.yomahub.liteflow.core.FlowExecutor;
|
||||||
|
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||||
|
import com.yomahub.liteflow.test.BaseTest;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.*;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process方法上的fact映射参数测试
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
*/
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@TestPropertySource(value = "classpath:/processFact/application.properties")
|
||||||
|
@SpringBootTest(classes = ProcessFactELDeclSpringbootTest.class)
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@ComponentScan({"com.yomahub.liteflow.test.processFact.cmp"})
|
||||||
|
public class ProcessFactELDeclSpringbootTest extends BaseTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FlowExecutor flowExecutor;
|
||||||
|
|
||||||
|
// 最基本的情况
|
||||||
|
@Test
|
||||||
|
public void testFact1() throws Exception {
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg", createContext());
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
TestContext context = response.getContextBean(TestContext.class);
|
||||||
|
Assertions.assertEquals("jack", context.getUser().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多上下文自动搜寻
|
||||||
|
@Test
|
||||||
|
public void testFact2() throws Exception {
|
||||||
|
TestContext testContext = createContext();
|
||||||
|
Demo1Context demo1Context = new Demo1Context();
|
||||||
|
demo1Context.setData1("xxxx");
|
||||||
|
demo1Context.setData2(99);
|
||||||
|
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg", demo1Context, testContext);
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
TestContext context = response.getContextBean(TestContext.class);
|
||||||
|
Assertions.assertEquals(20, context.getUser().getCompany().getHeadCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多上下文都有user,指定上下文中的user
|
||||||
|
@Test
|
||||||
|
public void testFact3() throws Exception {
|
||||||
|
TestContext testContext = createContext();
|
||||||
|
Demo2Context demo2Context = createDemo2Context();
|
||||||
|
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg", testContext, demo2Context);
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
Demo2Context context = response.getContextBean(Demo2Context.class);
|
||||||
|
Assertions.assertEquals("rose", context.getUser().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多上下文都有user,指定上下文中的user
|
||||||
|
@Test
|
||||||
|
public void testFact4() throws Exception {
|
||||||
|
Demo3Context demo3Context = createDemo3Context();
|
||||||
|
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg", demo3Context);
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
Demo3Context context = response.getContextBean(Demo3Context.class);
|
||||||
|
Assertions.assertEquals("jelly", context.getUser().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private TestContext createContext(){
|
||||||
|
Company company = new Company("XXX有限公司", "黄河路34号303室", 400);
|
||||||
|
User user = new User("张三", 18, DateUtil.parseDate("1990-08-20"), company);
|
||||||
|
return new TestContext(user, "this is data");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Demo2Context createDemo2Context(){
|
||||||
|
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||||
|
User user = new User("李四", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||||
|
return new Demo2Context("xxx", user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Demo3Context createDemo3Context(){
|
||||||
|
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||||
|
User user = new User("王五", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||||
|
return new Demo3Context("xxx", user);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* <p>Title: liteflow</p>
|
||||||
|
* <p>Description: 轻量级的组件式流程框架</p>
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
* @email weenyc31@163.com
|
||||||
|
* @Date 2020/4/1
|
||||||
|
*/
|
||||||
|
package com.yomahub.liteflow.test.processFact.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||||
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
|
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||||
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.User;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
@Component("a")
|
||||||
|
public class ACmp {
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||||
|
public void process(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("user") User user,
|
||||||
|
@LiteflowFact("user.company.address") String address) {
|
||||||
|
user.setName("jack");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* <p>Title: liteflow</p>
|
||||||
|
* <p>Description: 轻量级的组件式流程框架</p>
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
* @email weenyc31@163.com
|
||||||
|
* @Date 2020/4/1
|
||||||
|
*/
|
||||||
|
package com.yomahub.liteflow.test.processFact.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||||
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
|
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||||
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.Company;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component("b")
|
||||||
|
public class BCmp {
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||||
|
public void process(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("user.company") Company company,
|
||||||
|
@LiteflowFact("data2") Integer data) {
|
||||||
|
company.setHeadCount(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* <p>Title: liteflow</p>
|
||||||
|
* <p>Description: 轻量级的组件式流程框架</p>
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
* @email weenyc31@163.com
|
||||||
|
* @Date 2020/4/1
|
||||||
|
*/
|
||||||
|
package com.yomahub.liteflow.test.processFact.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||||
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
|
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||||
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.User;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component("c")
|
||||||
|
public class CCmp {
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||||
|
public void process(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("demo2Context.user") User user) {
|
||||||
|
user.setName("rose");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* <p>Title: liteflow</p>
|
||||||
|
* <p>Description: 轻量级的组件式流程框架</p>
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
* @email weenyc31@163.com
|
||||||
|
* @Date 2020/4/1
|
||||||
|
*/
|
||||||
|
package com.yomahub.liteflow.test.processFact.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||||
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
|
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||||
|
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||||
|
import com.yomahub.liteflow.test.processFact.context.User;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component("d")
|
||||||
|
public class DCmp {
|
||||||
|
|
||||||
|
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||||
|
public void process(NodeComponent bindCmp,
|
||||||
|
@LiteflowFact("ctx.user") User user) {
|
||||||
|
user.setName("jelly");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class Company {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
private int headCount;
|
||||||
|
|
||||||
|
public Company(String name, String address, int headCount) {
|
||||||
|
this.name = name;
|
||||||
|
this.address = address;
|
||||||
|
this.headCount = headCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeadCount() {
|
||||||
|
return headCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeadCount(int headCount) {
|
||||||
|
this.headCount = headCount;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class Demo1Context {
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
private Integer data2;
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getData2() {
|
||||||
|
return data2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData2(Integer data2) {
|
||||||
|
this.data2 = data2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class Demo2Context {
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public Demo2Context(String data1, User user) {
|
||||||
|
this.data1 = data1;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.context.ContextBean;
|
||||||
|
|
||||||
|
@ContextBean("ctx")
|
||||||
|
public class Demo3Context {
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public Demo3Context(String data1, User user) {
|
||||||
|
this.data1 = data1;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
public class TestContext {
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
private String data1;
|
||||||
|
|
||||||
|
public TestContext(User user, String data1) {
|
||||||
|
this.user = user;
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData1() {
|
||||||
|
return data1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData1(String data1) {
|
||||||
|
this.data1 = data1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.yomahub.liteflow.test.processFact.context;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
private Date birthday;
|
||||||
|
|
||||||
|
private Company company;
|
||||||
|
|
||||||
|
public User(String name, int age, Date birthday, Company company) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
this.birthday = birthday;
|
||||||
|
this.company = company;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Company getCompany() {
|
||||||
|
return company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompany(Company company) {
|
||||||
|
this.company = company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getBirthday() {
|
||||||
|
return birthday;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBirthday(Date birthday) {
|
||||||
|
this.birthday = birthday;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
liteflow.rule-source=processFact/flow.xml
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<flow>
|
||||||
|
<chain name="chain1">
|
||||||
|
THEN(a);
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="chain2">
|
||||||
|
THEN(b);
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="chain3">
|
||||||
|
THEN(c);
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="chain4">
|
||||||
|
THEN(d);
|
||||||
|
</chain>
|
||||||
|
</flow>
|
|
@ -14,6 +14,7 @@ import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.condition.EnabledIf;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ -50,6 +51,29 @@ public class AbsoluteConfigPathTest extends BaseTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@EnabledIf("isWindows")
|
||||||
|
public void testAbsPath() throws Exception{
|
||||||
|
Assertions.assertTrue(() -> {
|
||||||
|
LiteflowConfig config = new LiteflowConfig();
|
||||||
|
config.setRuleSource(StrUtil.format("{}\\sub\\**\\*.xml",rootDir));
|
||||||
|
flowExecutor = FlowExecutorHolder.loadInstance(config);
|
||||||
|
return flowExecutor.execute2Resp("chain1", "arg").isSuccess();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isWindows() {
|
||||||
|
try {
|
||||||
|
String osName = System.getProperty("os.name");
|
||||||
|
if (osName.isEmpty()) return false;
|
||||||
|
else {
|
||||||
|
return osName.contains("Windows");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void createFiles() {
|
public static void createFiles() {
|
||||||
rootDir = FileUtil.getAbsolutePath(ResourceUtil.getResource("").getPath());
|
rootDir = FileUtil.getAbsolutePath(ResourceUtil.getResource("").getPath());
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.yomahub.liteflow.test.namespace;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.core.FlowExecutor;
|
||||||
|
import com.yomahub.liteflow.exception.NoMatchedRouteChainException;
|
||||||
|
import com.yomahub.liteflow.exception.RouteChainNotFoundException;
|
||||||
|
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||||
|
import com.yomahub.liteflow.slot.DefaultContext;
|
||||||
|
import com.yomahub.liteflow.test.BaseTest;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
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 javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* springboot环境EL常规的例子测试
|
||||||
|
*
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
*/
|
||||||
|
@TestPropertySource(value = "classpath:/namespace/application.properties")
|
||||||
|
@SpringBootTest(classes = RouteSpringbootNamespaceTest.class)
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@ComponentScan({ "com.yomahub.liteflow.test.namespace.cmp" })
|
||||||
|
public class RouteSpringbootNamespaceTest extends BaseTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FlowExecutor flowExecutor;
|
||||||
|
|
||||||
|
// n1 space中的两个链路都能匹配
|
||||||
|
@Test
|
||||||
|
public void testNamespaceRoute1() throws Exception {
|
||||||
|
List<LiteflowResponse> responseList = flowExecutor.executeRouteChain("n1", 15, DefaultContext.class);
|
||||||
|
LiteflowResponse response1 = responseList.stream().filter(
|
||||||
|
liteflowResponse -> liteflowResponse.getChainId().equals("r_chain1")
|
||||||
|
).findFirst().orElse(null);
|
||||||
|
|
||||||
|
assert response1 != null;
|
||||||
|
Assertions.assertTrue(response1.isSuccess());
|
||||||
|
Assertions.assertEquals("b==>a", response1.getExecuteStepStr());
|
||||||
|
|
||||||
|
LiteflowResponse response2 = responseList.stream().filter(
|
||||||
|
liteflowResponse -> liteflowResponse.getChainId().equals("r_chain2")
|
||||||
|
).findFirst().orElse(null);
|
||||||
|
|
||||||
|
assert response2 != null;
|
||||||
|
Assertions.assertTrue(response2.isSuccess());
|
||||||
|
Assertions.assertEquals("a==>b", response2.getExecuteStepStr());
|
||||||
|
}
|
||||||
|
|
||||||
|
// n1这个namespace中没有规则被匹配上
|
||||||
|
@Test
|
||||||
|
public void testNamespaceRoute2() throws Exception {
|
||||||
|
Assertions.assertThrows(NoMatchedRouteChainException.class, () -> flowExecutor.executeRouteChain("n1", 8, DefaultContext.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没有n3这个namespace
|
||||||
|
@Test
|
||||||
|
public void testNamespaceRoute3() throws Exception {
|
||||||
|
Assertions.assertThrows(RouteChainNotFoundException.class, () -> flowExecutor.executeRouteChain("n3", 8, DefaultContext.class));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.namespace.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!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.namespace.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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.yomahub.liteflow.test.namespace.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||||
|
import com.yomahub.liteflow.core.NodeBooleanComponent;
|
||||||
|
|
||||||
|
@LiteflowComponent("r1")
|
||||||
|
public class R1 extends NodeBooleanComponent {
|
||||||
|
@Override
|
||||||
|
public boolean processBoolean() throws Exception {
|
||||||
|
int testInt = this.getRequestData();
|
||||||
|
return testInt >= 10 && testInt <= 20;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.yomahub.liteflow.test.namespace.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||||
|
import com.yomahub.liteflow.core.NodeBooleanComponent;
|
||||||
|
|
||||||
|
@LiteflowComponent("r2")
|
||||||
|
public class R2 extends NodeBooleanComponent {
|
||||||
|
@Override
|
||||||
|
public boolean processBoolean() throws Exception {
|
||||||
|
int testInt = this.getRequestData();
|
||||||
|
return testInt > 100;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
liteflow.rule-source=namespace/flow.el.xml
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||||
|
<flow>
|
||||||
|
<chain name="r_chain1" namespace="n1">
|
||||||
|
<route>
|
||||||
|
r1
|
||||||
|
</route>
|
||||||
|
<body>
|
||||||
|
THEN(b,a);
|
||||||
|
</body>
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="r_chain2" namespace="n1">
|
||||||
|
<route>
|
||||||
|
OR(r1,r2)
|
||||||
|
</route>
|
||||||
|
<body>
|
||||||
|
THEN(a,b);
|
||||||
|
</body>
|
||||||
|
</chain>
|
||||||
|
|
||||||
|
<chain name="r_chain3" namespace="n2">
|
||||||
|
<route>
|
||||||
|
r2
|
||||||
|
</route>
|
||||||
|
<body>
|
||||||
|
THEN(b,b);
|
||||||
|
</body>
|
||||||
|
</chain>
|
||||||
|
</flow>
|
|
@ -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>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue