mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 04:02:09 +08:00
Merge remote-tracking branch 'upstream/dev' into dev_rule_cache_2
This commit is contained in:
@@ -108,6 +108,10 @@ To join the LF CLUB, please scan the QR code below or click on the image to go d
|
||||
|
||||
<a href="https://www.jnpfsoft.com/index.html?from=liteflow"><img src="static/img/yinmai-banner.png"></a>
|
||||
|
||||
**速众 AI 低代码开发平台**
|
||||
|
||||
<a href="https://www.suconnect.com?hmsr=LiteFlow&hmpl=&hmcu=LiteFlow&hmkw=&hmci="><img src="static/img/suzhong-banner.jpg"></a>
|
||||
|
||||
**WECHAT OFFICIAL ACCOUNT**
|
||||
|
||||
Since the community group is over 200 people, you need to be invited to join the group. Follow the WECHAT OFFICIAL ACCOUNT and click `Personal WeChat` to add me, I can invite you into the group
|
||||
|
||||
@@ -102,6 +102,10 @@ LF CLUB里能解决你在使用LiteFlow框架时碰到的所有问题,并有
|
||||
|
||||
<a href="https://www.jnpfsoft.com/index.html?from=liteflow"><img src="static/img/yinmai-banner.png"></a>
|
||||
|
||||
**速众 AI 低代码开发平台**
|
||||
|
||||
<a href="https://www.suconnect.com?hmsr=LiteFlow&hmpl=&hmcu=LiteFlow&hmkw=&hmci="><img src="static/img/suzhong-banner.jpg"></a>
|
||||
|
||||
**微信公众号**
|
||||
|
||||
社区群需要邀请入群。关注公众号后点击`个人微信`加我,我可以拉你入群
|
||||
|
||||
@@ -114,4 +114,6 @@ public interface ChainConstant {
|
||||
String USER_DIR = "user.dir";
|
||||
|
||||
String BIND = "bind";
|
||||
|
||||
String CONTEXT_SEARCH_REGEX = "^\\$\\{(.*?)\\}$";
|
||||
}
|
||||
|
||||
@@ -9,10 +9,13 @@ package com.yomahub.liteflow.core;
|
||||
|
||||
import cn.hutool.core.date.StopWatch;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.common.ChainConstant;
|
||||
import com.yomahub.liteflow.core.proxy.LiteFlowProxyUtil;
|
||||
import com.yomahub.liteflow.enums.CmpStepTypeEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.ObjectConvertException;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.entity.CmpStep;
|
||||
@@ -26,6 +29,7 @@ import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.spi.holder.CmpAroundAspectHolder;
|
||||
import com.yomahub.liteflow.util.JsonUtil;
|
||||
import com.yomahub.liteflow.util.LiteflowContextRegexMatcher;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
@@ -446,10 +450,31 @@ public abstract class NodeComponent{
|
||||
if (StrUtil.isBlank(bindData)) {
|
||||
return null;
|
||||
}
|
||||
if (clazz.equals(String.class) || clazz.equals(Object.class)) {
|
||||
return (T) bindData;
|
||||
|
||||
//如果bind的value是一个正则表达式,说明要在上下文中进行搜索
|
||||
if (ReUtil.isMatch(ChainConstant.CONTEXT_SEARCH_REGEX, bindData)) {
|
||||
Object searchResult = LiteflowContextRegexMatcher.searchContext(
|
||||
this.getSlot().getContextBeanList(),
|
||||
ReUtil.getGroup1(ChainConstant.CONTEXT_SEARCH_REGEX, bindData)
|
||||
);
|
||||
|
||||
if (searchResult == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
//搜索到的对象一定要符合给定的clazz
|
||||
if (clazz.isAssignableFrom(searchResult.getClass())) {
|
||||
return (T) searchResult;
|
||||
}else{
|
||||
String errMsg = StrUtil.format("{} cannot convert to {}", searchResult.getClass().getName(), clazz.getName());
|
||||
throw new ObjectConvertException(errMsg);
|
||||
}
|
||||
}else{
|
||||
if (clazz.equals(String.class) || clazz.equals(Object.class)) {
|
||||
return (T) bindData;
|
||||
}
|
||||
return JsonUtil.parseObject(bindData, clazz);
|
||||
}
|
||||
return JsonUtil.parseObject(bindData, clazz);
|
||||
}
|
||||
|
||||
public <T> List<T> getBindDataList(Class<T> clazz) {
|
||||
@@ -514,4 +539,10 @@ public abstract class NodeComponent{
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
return originalClass.getName();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
boolean flag = ReUtil.isMatch(ChainConstant.CONTEXT_SEARCH_REGEX, "${user.name}");
|
||||
System.out.println(ReUtil.getGroup1(ChainConstant.CONTEXT_SEARCH_REGEX, "${user.name}"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.log.LFLog;
|
||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.util.LiteflowContextRegexMatcher;
|
||||
import com.yomahub.liteflow.util.SerialsUtil;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
|
||||
@@ -157,8 +158,6 @@ public class DeclComponentProxy {
|
||||
|
||||
}
|
||||
|
||||
private final ExpressRunner expressRunner = new ExpressRunner();
|
||||
|
||||
private Object[] loadMethodParameter(Object proxy, MethodWrapBean methodWrapBean, Object[] args){
|
||||
NodeComponent thisNodeComponent = (NodeComponent) proxy;
|
||||
|
||||
@@ -181,38 +180,9 @@ public class DeclComponentProxy {
|
||||
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;
|
||||
return LiteflowContextRegexMatcher.searchContext(
|
||||
DataBus.getSlot(thisNodeComponent.getSlotIndex()).getContextBeanList(),
|
||||
parameterWrapBean.getFact().value());
|
||||
}).toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.yomahub.liteflow.exception;
|
||||
|
||||
/**
|
||||
* 对象转型异常
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.13.0
|
||||
*/
|
||||
public class ObjectConvertException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 异常信息 */
|
||||
private String message;
|
||||
|
||||
public ObjectConvertException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -154,6 +154,7 @@ public class LiteflowMetaOperator {
|
||||
|
||||
/**
|
||||
* 通过chainId,nodeId,index去获取具体的Node节点
|
||||
* 只有打开liteflow.enable-node-instance-id=true才会正常调用这个
|
||||
* @param chainId chain的Id
|
||||
* @param nodeId 节点的Id
|
||||
* @param index 节点的序号下标,从0开始
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.yomahub.liteflow.util;
|
||||
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import com.ql.util.express.DefaultContext;
|
||||
import com.ql.util.express.ExpressRunner;
|
||||
import com.ql.util.express.InstructionSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* LiteFlow上下文正则表达式匹配器
|
||||
* 用来根据正则表达式去寻找上下文中符合的对象
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.13.0
|
||||
*/
|
||||
public class LiteflowContextRegexMatcher {
|
||||
|
||||
private static final ExpressRunner expressRunner = new ExpressRunner();
|
||||
|
||||
public static Object searchContext(List<Tuple> contextList, String regPattern){
|
||||
// 把上下文数据转换成map形式的,key为别名,value为上下文
|
||||
Map<String, Object> contextMap = contextList.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() + "." + regPattern);
|
||||
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." + regPattern);
|
||||
DefaultContext<String, Object> context = new DefaultContext<>();
|
||||
context.put("contextMap", contextMap);
|
||||
result = expressRunner.execute(instructionSet, context, errorList, false, false);
|
||||
}catch (Exception ignore){}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.yomahub.liteflow.builder.el;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 捕获异常表达式
|
||||
* Catch(a).do(b)
|
||||
@@ -35,6 +37,30 @@ public class CatchELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CatchELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CatchELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CatchELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CatchELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CatchELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -58,22 +58,25 @@ public class CommonNodeELWrapper extends ELWrapper {
|
||||
|
||||
@Override
|
||||
public CommonNodeELWrapper data(String dataName, Object object) {
|
||||
setData("'" + JsonUtil.toJsonString(object) + "'");
|
||||
setDataName(dataName);
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonNodeELWrapper data(String dataName, String jsonString) {
|
||||
setData("'" + jsonString + "'");
|
||||
setDataName(dataName);
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonNodeELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
setData("'" + JsonUtil.toJsonString(jsonMap) + "'");
|
||||
setDataName(dataName);
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -102,28 +105,4 @@ public class CommonNodeELWrapper extends ELWrapper {
|
||||
processWrapperProperty(sb, paramContext);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Node的公共属性不包括id,对父类方法重载。
|
||||
*
|
||||
* @param elContext EL 上下文
|
||||
* @param paramContext 参数上下文
|
||||
*/
|
||||
@Override
|
||||
protected void processWrapperProperty(StringBuilder elContext, StringBuilder paramContext){
|
||||
if(this.getTag() != null){
|
||||
elContext.append(StrUtil.format(".tag(\"{}\")", this.getTag()));
|
||||
}
|
||||
if(this.getData() != null){
|
||||
elContext.append(StrUtil.format(".data({})", this.getDataName()));
|
||||
paramContext.append(StrUtil.format("{} = {}", this.getDataName(), this.getData())).append(";\n");
|
||||
}
|
||||
if(this.getMaxWaitSeconds() != null){
|
||||
elContext.append(StrUtil.format(".maxWaitSeconds({})", String.valueOf(this.getMaxWaitSeconds())));
|
||||
}
|
||||
if (this.getRetry() != null){
|
||||
elContext.append(StrUtil.format(".retry({})", this.getRetry().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class ELBus {
|
||||
* @param nodeId 节点id
|
||||
* @return {@link CommonNodeELWrapper}
|
||||
*/
|
||||
public static CommonNodeELWrapper commonNode(String nodeId){
|
||||
public static CommonNodeELWrapper element(String nodeId){
|
||||
return new CommonNodeELWrapper(nodeId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package com.yomahub.liteflow.builder.el;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.builder.el.vo.RetryELVo;
|
||||
import com.yomahub.liteflow.util.JsonUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* ELWrapper是所有组件的抽象父类
|
||||
@@ -25,6 +24,7 @@ public abstract class ELWrapper {
|
||||
private String id;
|
||||
private String dataName;
|
||||
private String data;
|
||||
private final Map<String, String> bindData = new HashMap<>();
|
||||
private Integer maxWaitSeconds;
|
||||
private RetryELVo retry;
|
||||
|
||||
@@ -84,6 +84,18 @@ public abstract class ELWrapper {
|
||||
return this.dataName;
|
||||
}
|
||||
|
||||
protected String getBindData(String key) {
|
||||
return bindData.get(key);
|
||||
}
|
||||
|
||||
protected void putBindData(String key, String value) {
|
||||
this.bindData.put(key, value);
|
||||
}
|
||||
|
||||
protected Map<String, String> getBindData() {
|
||||
return bindData;
|
||||
}
|
||||
|
||||
protected void setMaxWaitSeconds(Integer maxWaitSeconds){
|
||||
this.maxWaitSeconds = maxWaitSeconds;
|
||||
}
|
||||
@@ -161,6 +173,11 @@ public abstract class ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected ELWrapper bind(String key, String value){
|
||||
putBindData(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
protected ELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
@@ -227,6 +244,13 @@ public abstract class ELWrapper {
|
||||
if(this.getTag() != null){
|
||||
elContext.append(StrUtil.format(".tag(\"{}\")", this.getTag()));
|
||||
}
|
||||
if(this.getData() != null){
|
||||
elContext.append(StrUtil.format(".data({})", this.getDataName()));
|
||||
paramContext.append(StrUtil.format("{} = {}", this.getDataName(), this.getData())).append(";\n");
|
||||
}
|
||||
if(MapUtil.isNotEmpty(this.getBindData())){
|
||||
this.getBindData().forEach((key, value) -> elContext.append(StrUtil.format(".bind(\"{}\", \"{}\")", key, value)));
|
||||
}
|
||||
if(this.getMaxWaitSeconds() != null){
|
||||
elContext.append(StrUtil.format(".maxWaitSeconds({})", String.valueOf(this.getMaxWaitSeconds())));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.yomahub.liteflow.builder.el;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 后置表达式
|
||||
* 只能在THEN组件中调用
|
||||
@@ -28,6 +30,30 @@ public class FinallyELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinallyELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinallyELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinallyELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FinallyELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后置组件无法设置maxWaitSeconds属性,重载用protected修饰
|
||||
*
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.yomahub.liteflow.builder.el;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -211,6 +212,30 @@ public class IfELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IfELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IfELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IfELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IfELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IfELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.yomahub.liteflow.builder.el;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FOR、WHILE、ITERATOR循环表达式的公共抽象父类
|
||||
*
|
||||
@@ -68,6 +70,30 @@ public class LoopELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoopELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoopELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoopELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoopELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoopELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 并行组件
|
||||
@@ -70,6 +71,30 @@ public class ParELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -30,6 +30,30 @@ public class PreELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 串行组件
|
||||
@@ -74,6 +75,30 @@ public class SerELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.yomahub.liteflow.builder.el;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 选择组件
|
||||
* SWITCH(a).TO(b,c,d...).default(x)
|
||||
@@ -47,6 +49,30 @@ public class SwitchELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwitchELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwitchELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwitchELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwitchELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwitchELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 串行组件
|
||||
@@ -74,6 +75,30 @@ public class ThenELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThenELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThenELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThenELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThenELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThenELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -68,6 +68,30 @@ public class WhenELWrapper extends ELWrapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhenELWrapper data(String dataName, Object object) {
|
||||
super.data(dataName, object);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhenELWrapper data(String dataName, String jsonString) {
|
||||
super.data(dataName, jsonString);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhenELWrapper data(String dataName, Map<String, Object> jsonMap) {
|
||||
super.data(dataName, jsonMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhenELWrapper bind(String key, String value) {
|
||||
super.bind(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhenELWrapper maxWaitSeconds(Integer maxWaitSeconds){
|
||||
setMaxWaitSeconds(maxWaitSeconds);
|
||||
|
||||
@@ -24,11 +24,7 @@ import java.util.Optional;
|
||||
public class BaoMiDouDynamicDsConn implements LiteFlowDataSourceConnect {
|
||||
@Override
|
||||
public boolean filter(SQLParserVO config) {
|
||||
// 是否配置苞米豆动态数据源配置
|
||||
boolean configFlag = Optional.ofNullable(config.getBaomidou())
|
||||
.map(SQLParserVO.DataSourceConfig::getDataSourceName)
|
||||
.isPresent();
|
||||
if (!configFlag) {
|
||||
if (StrUtil.isBlank(config.getBaomidouDataSource())) {
|
||||
return false;
|
||||
}
|
||||
boolean classLoadFlag = ClassLoaderUtil.isPresent(Constant.LOAD_CLASS_NAME);
|
||||
@@ -40,7 +36,7 @@ public class BaoMiDouDynamicDsConn implements LiteFlowDataSourceConnect {
|
||||
|
||||
@Override
|
||||
public Connection getConn(SQLParserVO config) throws Exception {
|
||||
String dataSourceName = config.getBaomidou().getDataSourceName();
|
||||
String dataSourceName = config.getBaomidouDataSource();
|
||||
ContextAware contextAware = ContextAwareHolder.loadContextAware();
|
||||
DynamicRoutingDataSource dynamicRoutingDataSource = contextAware.getBean(DynamicRoutingDataSource.class);
|
||||
Map<String, DataSource> dataSources = dynamicRoutingDataSource.getDataSources();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.yomahub.liteflow.parser.sql.datasource.impl;
|
||||
|
||||
import cn.hutool.core.util.ClassLoaderUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.exception.MissMavenDependencyException;
|
||||
import com.yomahub.liteflow.parser.sql.datasource.LiteFlowDataSourceConnect;
|
||||
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
|
||||
@@ -21,12 +22,7 @@ public class ShardingJdbcDsConn implements LiteFlowDataSourceConnect {
|
||||
|
||||
@Override
|
||||
public boolean filter(SQLParserVO config) {
|
||||
// 是否配置 sharding jdbc 动态数据源配置
|
||||
boolean configFlag = Optional.ofNullable(config.getShardingjdbc())
|
||||
.map(SQLParserVO.DataSourceConfig::getDataSourceName)
|
||||
.isPresent();
|
||||
|
||||
if (!configFlag) {
|
||||
if (StrUtil.isBlank(config.getShardingJdbcDataSource())) {
|
||||
return false;
|
||||
}
|
||||
boolean classLoadFlag = ClassLoaderUtil.isPresent(Constant.LOAD_CLASS_NAME);
|
||||
|
||||
@@ -169,12 +169,12 @@ public class SQLParserVO {
|
||||
/**
|
||||
* 苞米豆动态数据源配置
|
||||
*/
|
||||
private DataSourceConfig baomidou;
|
||||
private String baomidouDataSource;
|
||||
|
||||
/**
|
||||
* sharding jdbc 动态数据源配置
|
||||
*/
|
||||
private DataSourceConfig shardingjdbc;
|
||||
private String shardingJdbcDataSource;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
@@ -451,31 +451,19 @@ public class SQLParserVO {
|
||||
this.nodeInstanceIdMapJsonField = nodeInstanceIdMapJsonField;
|
||||
}
|
||||
|
||||
public DataSourceConfig getBaomidou() {
|
||||
return baomidou;
|
||||
public String getBaomidouDataSource() {
|
||||
return baomidouDataSource;
|
||||
}
|
||||
|
||||
public void setBaomidou(DataSourceConfig baomidou) {
|
||||
this.baomidou = baomidou;
|
||||
public void setBaomidouDataSource(String baomidouDataSource) {
|
||||
this.baomidouDataSource = baomidouDataSource;
|
||||
}
|
||||
|
||||
public DataSourceConfig getShardingjdbc() {
|
||||
return shardingjdbc;
|
||||
public String getShardingJdbcDataSource() {
|
||||
return shardingJdbcDataSource;
|
||||
}
|
||||
|
||||
public void setShardingjdbc(DataSourceConfig shardingjdbc) {
|
||||
this.shardingjdbc = shardingjdbc;
|
||||
}
|
||||
|
||||
public static class DataSourceConfig {
|
||||
private String dataSourceName;
|
||||
|
||||
public String getDataSourceName() {
|
||||
return dataSourceName;
|
||||
}
|
||||
|
||||
public void setDataSourceName(String dataSourceName) {
|
||||
this.dataSourceName = dataSourceName;
|
||||
}
|
||||
public void setShardingJdbcDataSource(String shardingJdbcDataSource) {
|
||||
this.shardingJdbcDataSource = shardingJdbcDataSource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.yomahub.liteflow.test.builder;
|
||||
|
||||
import com.yomahub.liteflow.builder.el.ELBus;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SpringBootTest(classes = BindELBuilderTest.class)
|
||||
@EnableAutoConfiguration
|
||||
public class BindELBuilderTest extends BaseTest {
|
||||
|
||||
@Test
|
||||
public void testBind1(){
|
||||
String actualEl = ELBus.then("a", ELBus.element("b").bind("k1", "v1")).toEL();
|
||||
String expected = "THEN(a,b.bind(\"k1\", \"v1\"));";
|
||||
System.out.println(actualEl);
|
||||
Assertions.assertEquals(expected, actualEl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBind2(){
|
||||
String actualEl = ELBus.then("a", "b").bind("k1","v1").toEL();
|
||||
String expected = "THEN(a,b).bind(\"k1\", \"v1\");";
|
||||
System.out.println(actualEl);
|
||||
Assertions.assertEquals(expected, actualEl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBind3(){
|
||||
String actualEl = ELBus.then("a", ELBus.node("b").bind("k1", "v1")).toEL();
|
||||
String expected = "THEN(a,node(\"b\").bind(\"k1\", \"v1\"));";
|
||||
System.out.println(actualEl);
|
||||
Assertions.assertEquals(expected, actualEl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBind4(){
|
||||
String actualEl = ELBus.then("a", ELBus.when("b","c").bind("k1", "v1")).bind("k2","v2").toEL();
|
||||
String expected = "THEN(a,WHEN(b,c).bind(\"k1\", \"v1\")).bind(\"k2\", \"v2\");";
|
||||
System.out.println(actualEl);
|
||||
Assertions.assertEquals(expected, actualEl);
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@ public class MaxWaitSecondBuilderTest extends BaseTest {
|
||||
// node层面
|
||||
@Test
|
||||
public void testMaxWaitSecond1(){
|
||||
CommonNodeELWrapper nodeA = ELBus.commonNode("a").maxWaitSeconds(4);
|
||||
CommonNodeELWrapper nodeB = ELBus.commonNode("b").maxWaitSeconds(4);
|
||||
CommonNodeELWrapper nodeA = ELBus.element("a").maxWaitSeconds(4);
|
||||
CommonNodeELWrapper nodeB = ELBus.element("b").maxWaitSeconds(4);
|
||||
WhenELWrapper whenELWrapper = ELBus.when(nodeA, nodeB);
|
||||
Assertions.assertEquals("WHEN(a.maxWaitSeconds(4),b.maxWaitSeconds(4));", whenELWrapper.toEL());
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ public class RetryBuilderTest extends BaseTest {
|
||||
// node上进行retry
|
||||
@Test
|
||||
public void testRetry1(){
|
||||
CommonNodeELWrapper nodeA = ELBus.commonNode("a").retry(2);
|
||||
CommonNodeELWrapper nodeB = ELBus.commonNode("b").retry(3);
|
||||
CommonNodeELWrapper nodeA = ELBus.element("a").retry(2);
|
||||
CommonNodeELWrapper nodeB = ELBus.element("b").retry(3);
|
||||
WhenELWrapper whenELWrapper = ELBus.when(nodeA, nodeB);
|
||||
Assertions.assertEquals("WHEN(a.retry(2),b.retry(3));", whenELWrapper.toEL());
|
||||
}
|
||||
@@ -25,8 +25,8 @@ public class RetryBuilderTest extends BaseTest {
|
||||
// node上进行retry,带exception
|
||||
@Test
|
||||
public void testRetry2(){
|
||||
CommonNodeELWrapper nodeA = ELBus.commonNode("a").retry(2, "java.lang.NullPointerException");
|
||||
CommonNodeELWrapper nodeB = ELBus.commonNode("b").retry(3, "java.lang.NullPointerException", "java.lang.ArrayIndexOutOfBoundsException");
|
||||
CommonNodeELWrapper nodeA = ELBus.element("a").retry(2, "java.lang.NullPointerException");
|
||||
CommonNodeELWrapper nodeB = ELBus.element("b").retry(3, "java.lang.NullPointerException", "java.lang.ArrayIndexOutOfBoundsException");
|
||||
WhenELWrapper whenELWrapper = ELBus.when(nodeA, nodeB);
|
||||
Assertions.assertEquals("WHEN(a.retry(2,\"java.lang.NullPointerException\"),b.retry(3,\"java.lang.NullPointerException\",\"java.lang.ArrayIndexOutOfBoundsException\"));",
|
||||
whenELWrapper.toEL());
|
||||
|
||||
@@ -28,7 +28,7 @@ public class ThenELBuilderTest extends BaseTest {
|
||||
name2Value.put("name", "zhangsan");
|
||||
name2Value.put("age", 18);
|
||||
String expected = "nodeData = '{\"name\":\"zhangsan\",\"age\":18}';\nTHEN(\n\ta.tag(\"tagA\").data(nodeData).maxWaitSeconds(10).retry(2),\n\tnode(\"b\")\n);";
|
||||
String actualEl = ELBus.then(ELBus.commonNode("a").data("nodeData", name2Value).tag("tagA").maxWaitSeconds(10).retry(2), ELBus.node("b")).toEL(true);
|
||||
String actualEl = ELBus.then(ELBus.element("a").data("nodeData", name2Value).tag("tagA").maxWaitSeconds(10).retry(2), ELBus.node("b")).toEL(true);
|
||||
System.out.println(actualEl);
|
||||
Assertions.assertEquals(expected, actualEl);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class LiteflowConfigTest1 extends BaseTest {
|
||||
Assertions.assertEquals(300000L, config.getDelay().longValue());
|
||||
Assertions.assertEquals(300000L, config.getPeriod().longValue());
|
||||
Assertions.assertFalse(config.getEnableLog());
|
||||
Assertions.assertEquals(16, config.getGlobalThreadPoolSize().longValue());
|
||||
Assertions.assertEquals(64, config.getGlobalThreadPoolSize().longValue());
|
||||
Assertions.assertEquals(512, config.getGlobalThreadPoolQueueSize().longValue());
|
||||
Assertions.assertEquals(ParseModeEnum.PARSE_ALL_ON_START, config.getParseMode());
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
<version>${revision}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-script-javax</artifactId>
|
||||
<version>${revision}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
@@ -12,16 +12,24 @@
|
||||
import com.yomahub.liteflow.test.script.javax.common.cmp.Person;
|
||||
import com.yomahub.liteflow.test.script.javax.common.cmp.TestDomain;
|
||||
import com.yomahub.liteflow.script.ScriptExecuteWrap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.ToIntFunction;
|
||||
|
||||
public class Demo implements CommonScriptBody {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
public Void body(ScriptExecuteWrap wrap) {
|
||||
int v1 = 2;
|
||||
int v2 = 3;
|
||||
DefaultContext ctx = wrap.getCmp().getFirstContextBean();
|
||||
ctx.setData("s1", v1 * v2);
|
||||
|
||||
log.info("---hello---");
|
||||
|
||||
TestDomain domain = ContextAwareHolder.loadContextAware().getBean(TestDomain.class);
|
||||
System.out.println(domain);
|
||||
String str = domain.sayHello("jack");
|
||||
|
||||
@@ -18,11 +18,11 @@ import javax.annotation.Resource;
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
@TestPropertySource(value = "classpath:/bindData/application.properties")
|
||||
@SpringBootTest(classes = BindDataSpringbootTest.class)
|
||||
@TestPropertySource(value = "classpath:/bindData/application1.properties")
|
||||
@SpringBootTest(classes = BindDataSpringbootTest1.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({ "com.yomahub.liteflow.test.bindData.cmp" })
|
||||
public class BindDataSpringbootTest extends BaseTest {
|
||||
@ComponentScan({ "com.yomahub.liteflow.test.bindData.cmp1" })
|
||||
public class BindDataSpringbootTest1 extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.yomahub.liteflow.test.bindData;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.exception.ObjectConvertException;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import com.yomahub.liteflow.test.bindData.context.Member;
|
||||
import com.yomahub.liteflow.test.bindData.context.MemberContext;
|
||||
import com.yomahub.liteflow.test.bindData.context.OrderContext;
|
||||
import com.yomahub.liteflow.test.bindData.context.UserInfoContext;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* springboot环境EL常规的例子测试
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
@TestPropertySource(value = "classpath:/bindData/application2.properties")
|
||||
@SpringBootTest(classes = BindDataSpringbootTest2.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({"com.yomahub.liteflow.test.bindData.cmp2"})
|
||||
public class BindDataSpringbootTest2 extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 测试动态bind,最简单的情况,2个上下文中搜索
|
||||
@Test
|
||||
public void testBindDynamic1() throws Exception {
|
||||
MemberContext memberContext = new MemberContext();
|
||||
memberContext.setId(31);
|
||||
memberContext.setName("jack");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg", memberContext, new DefaultContext());
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getContextBean(DefaultContext.class);
|
||||
Assertions.assertEquals("jack", context.getData("a1"));
|
||||
}
|
||||
|
||||
// 测试动态bind,多级取数据,2个上下文中搜索
|
||||
@Test
|
||||
public void testBindDynamic2() throws Exception {
|
||||
OrderContext orderContext = new OrderContext();
|
||||
orderContext.setOrderCode("SO1234");
|
||||
orderContext.setMember(new Member("M0001","jack"));
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg", orderContext, new DefaultContext());
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getContextBean(DefaultContext.class);
|
||||
Assertions.assertEquals("M0001", context.getData("a2"));
|
||||
}
|
||||
|
||||
// 测试动态bind,多个上下文,拥有相同的变量,指定上下文
|
||||
@Test
|
||||
public void testBindDynamic3() throws Exception {
|
||||
OrderContext orderContext = new OrderContext();
|
||||
orderContext.setId(1000);
|
||||
orderContext.setOrderCode("SO1234");
|
||||
orderContext.setMember(new Member("M0001","jack"));
|
||||
|
||||
MemberContext memberContext = new MemberContext();
|
||||
memberContext.setId(2000);
|
||||
memberContext.setName("jack");
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg", orderContext, memberContext, new DefaultContext());
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getContextBean(DefaultContext.class);
|
||||
Assertions.assertEquals(2000, (Integer) context.getData("a3"));
|
||||
}
|
||||
|
||||
// 测试动态bind,多个上下文,结合@ContextBean测试
|
||||
@Test
|
||||
public void testBindDynamic4() throws Exception {
|
||||
UserInfoContext userInfoContext = new UserInfoContext();
|
||||
userInfoContext.setInfo("test info");
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg", userInfoContext, new DefaultContext());
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getContextBean(DefaultContext.class);
|
||||
Assertions.assertEquals("test info", context.getData("a4"));
|
||||
}
|
||||
|
||||
// 测试动态bind,getBindData中的class给错,报错
|
||||
@Test
|
||||
public void testBindDynamic5() throws Exception {
|
||||
MemberContext memberContext = new MemberContext();
|
||||
memberContext.setId(31);
|
||||
memberContext.setName("jack");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg", memberContext, new DefaultContext());
|
||||
Assertions.assertFalse(response.isSuccess());
|
||||
Assertions.assertEquals(ObjectConvertException.class, response.getCause().getClass());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.bindData.cmp;
|
||||
package com.yomahub.liteflow.test.bindData.cmp1;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
@@ -5,7 +5,7 @@
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.bindData.cmp;
|
||||
package com.yomahub.liteflow.test.bindData.cmp1;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
@@ -5,7 +5,7 @@
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.bindData.cmp;
|
||||
package com.yomahub.liteflow.test.bindData.cmp1;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
@@ -5,7 +5,7 @@
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.bindData.cmp;
|
||||
package com.yomahub.liteflow.test.bindData.cmp1;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yomahub.liteflow.test.bindData.cmp;
|
||||
package com.yomahub.liteflow.test.bindData.cmp1;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBooleanComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yomahub.liteflow.test.bindData.cmp;
|
||||
package com.yomahub.liteflow.test.bindData.cmp1;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeSwitchComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
@@ -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.bindData.cmp2;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import com.yomahub.liteflow.test.bindData.context.Member;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a1")
|
||||
public class A1Cmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
DefaultContext defaultContext = this.getContextBean(DefaultContext.class);
|
||||
String bindValue = this.getBindData("k1", String.class);
|
||||
if (bindValue != null) {
|
||||
defaultContext.setData(this.getNodeId(), bindValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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.bindData.cmp2;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import com.yomahub.liteflow.test.bindData.context.Member;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a2")
|
||||
public class A2Cmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
DefaultContext context = this.getContextBean(DefaultContext.class);
|
||||
String bindValue = this.getBindData("k1", String.class);
|
||||
if (bindValue != null) {
|
||||
context.setData(this.getNodeId(), bindValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.bindData.cmp2;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a3")
|
||||
public class A3Cmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
DefaultContext context = this.getContextBean(DefaultContext.class);
|
||||
Integer bindValue = this.getBindData("k1", Integer.class);
|
||||
if (bindValue != null) {
|
||||
context.setData(this.getNodeId(), bindValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.bindData.cmp2;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a4")
|
||||
public class A4Cmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
DefaultContext context = this.getContextBean(DefaultContext.class);
|
||||
String bindValue = this.getBindData("k1", String.class);
|
||||
if (bindValue != null) {
|
||||
context.setData(this.getNodeId(), bindValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.bindData.cmp2;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a5")
|
||||
public class A5Cmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
DefaultContext context = this.getContextBean(DefaultContext.class);
|
||||
String bindValue = this.getBindData("k1", String.class);
|
||||
if (bindValue != null) {
|
||||
context.setData(this.getNodeId(), bindValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.yomahub.liteflow.test.bindData.context;
|
||||
|
||||
public class Member {
|
||||
private String memberCode;
|
||||
|
||||
private String memberName;
|
||||
|
||||
public Member(String memberCode, String memberName) {
|
||||
this.memberCode = memberCode;
|
||||
this.memberName = memberName;
|
||||
}
|
||||
|
||||
public String getMemberCode() {
|
||||
return memberCode;
|
||||
}
|
||||
|
||||
public void setMemberCode(String memberCode) {
|
||||
this.memberCode = memberCode;
|
||||
}
|
||||
|
||||
public String getMemberName() {
|
||||
return memberName;
|
||||
}
|
||||
|
||||
public void setMemberName(String memberName) {
|
||||
this.memberName = memberName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.yomahub.liteflow.test.bindData.context;
|
||||
|
||||
public class MemberContext {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.yomahub.liteflow.test.bindData.context;
|
||||
|
||||
public class OrderContext {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String orderCode;
|
||||
|
||||
private Member member;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getOrderCode() {
|
||||
return orderCode;
|
||||
}
|
||||
|
||||
public void setOrderCode(String orderCode) {
|
||||
this.orderCode = orderCode;
|
||||
}
|
||||
|
||||
public Member getMember() {
|
||||
return member;
|
||||
}
|
||||
|
||||
public void setMember(Member member) {
|
||||
this.member = member;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.yomahub.liteflow.test.bindData.context;
|
||||
|
||||
import com.yomahub.liteflow.context.ContextBean;
|
||||
|
||||
@ContextBean("userCx")
|
||||
public class UserInfoContext {
|
||||
|
||||
private String info;
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
}
|
||||
@@ -172,7 +172,7 @@ public class FallbackELSpringbootTest extends BaseTest {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("concurrent2", "arg");
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
String stepStr = response.getExecuteStepStrWithoutTime();
|
||||
Assertions.assertTrue("fb_comm_cmp==>fb_bool_cmp".equals(stepStr) || "ifn2==>c".equals(stepStr));
|
||||
Assertions.assertTrue("fb_comm_cmp==>fb_bool_cmp".equals(stepStr) || "fb_bool_cmp==>fb_comm_cmp".equals(stepStr) || "ifn2==>c".equals(stepStr));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
liteflow.rule-source=bindData/flow.el.xml
|
||||
@@ -0,0 +1 @@
|
||||
liteflow.rule-source=bindData/flow1.xml
|
||||
@@ -0,0 +1 @@
|
||||
liteflow.rule-source=bindData/flow2.xml
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<chain id="chain1">
|
||||
THEN(a1.bind("k1", "${name}"));
|
||||
</chain>
|
||||
|
||||
<chain id="chain2">
|
||||
THEN(a2.bind("k1", "${member.memberCode}"));
|
||||
</chain>
|
||||
|
||||
<chain id="chain3">
|
||||
THEN(a3.bind("k1", "${memberContext.id}"));
|
||||
</chain>
|
||||
|
||||
<chain id="chain4">
|
||||
THEN(a4.bind("k1", "${userCx.info}"));
|
||||
</chain>
|
||||
|
||||
<chain id="chain5">
|
||||
THEN(a5.bind("k1", "${id}"));
|
||||
</chain>
|
||||
</flow>
|
||||
@@ -1,6 +1,6 @@
|
||||
liteflow.rule-source-ext-data={\
|
||||
"applicationName":"demo",\
|
||||
"baomidou":{"dataSourceName":"h2-first"},\
|
||||
"baomidouDataSource":"h2-first",\
|
||||
"chainTableName":"EL_TABLE",\
|
||||
"chainApplicationNameField":"application_name",\
|
||||
"chainNameField":"chain_name",\
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
liteflow.rule-source-ext-data={\
|
||||
"applicationName":"demo",\
|
||||
"shardingjdbc":{"dataSourceName":"ds_1"},\
|
||||
"shardingJdbcDataSource":"ds_1",\
|
||||
"chainTableName":"EL_TABLE",\
|
||||
"chainApplicationNameField":"application_name",\
|
||||
"chainNameField":"chain_name",\
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -77,7 +77,7 @@
|
||||
<redisson.version>3.21.0</redisson.version>
|
||||
<janino.version>3.1.12</janino.version>
|
||||
<kotlin.version>1.9.23</kotlin.version>
|
||||
<liquor.version>1.3.10</liquor.version>
|
||||
<liquor.version>1.3.11</liquor.version>
|
||||
<dynamic-datasource.version>4.3.1</dynamic-datasource.version>
|
||||
<sharding-jdbc.version>4.1.1</sharding-jdbc.version>
|
||||
<caffeine.version>2.9.3</caffeine.version>
|
||||
|
||||
BIN
static/img/suzhong-banner.jpg
Normal file
BIN
static/img/suzhong-banner.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Reference in New Issue
Block a user