mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-15 04:22:09 +08:00
bug #I4LUQ5 默认的slot的dataMap无法放入值为null的对象
This commit is contained in:
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
package com.yomahub.liteflow.core;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
@@ -31,8 +30,6 @@ import com.yomahub.liteflow.flow.FlowBus;
|
||||
import com.yomahub.liteflow.parser.LocalXmlFlowParser;
|
||||
import com.yomahub.liteflow.parser.XmlFlowParser;
|
||||
import com.yomahub.liteflow.parser.ZookeeperXmlFlowParser;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -263,30 +260,14 @@ public class FlowExecutor {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* callback by implicit subflow
|
||||
*
|
||||
* @param chainId
|
||||
* @param param
|
||||
* @param slotClazz
|
||||
* @param slotIndex
|
||||
* @param <T>
|
||||
* @throws Exception
|
||||
*/
|
||||
//隐式流程的调用方法
|
||||
public <T extends Slot> void invoke(String chainId, Object param, Class<T> slotClazz,
|
||||
Integer slotIndex) throws Exception {
|
||||
this.execute(chainId, param, slotClazz, slotIndex, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 无参执行器
|
||||
* @Author LeoLee
|
||||
* @Date 17:52 2021/12/10
|
||||
* @param chainId 业务链id
|
||||
* @return com.yomahub.liteflow.entity.data.DefaultSlot
|
||||
*/
|
||||
public DefaultSlot execute(String chainId) throws Exception {
|
||||
return this.execute(chainId, DefaultSlot.class, null, false);
|
||||
return this.execute(chainId, null, DefaultSlot.class, null, false);
|
||||
}
|
||||
|
||||
public DefaultSlot execute(String chainId, Object param) throws Exception {
|
||||
@@ -297,39 +278,8 @@ public class FlowExecutor {
|
||||
return this.execute(chainId, param, slotClazz, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 有param的execute方法,将会对param进行判断,若为null,抛出逻辑异常NullParamException
|
||||
* @Author: LeoLee
|
||||
* @Date: 2021/12/11 15:34
|
||||
*/
|
||||
public <T extends Slot> T execute(String chainId, Object param, Class<T> slotClazz,
|
||||
Integer slotIndex, boolean isInnerChain) throws Exception {
|
||||
if (ObjectUtil.isNull(param)) {
|
||||
//data slot is a ConcurrentHashMap, so null value will trigger NullPointerException
|
||||
throw new NullParamException("data slot can't accept null param");
|
||||
}
|
||||
return this.execute0(chainId, param, slotClazz, slotIndex, isInnerChain);
|
||||
}
|
||||
|
||||
/**
|
||||
* 无param的execute方法,没有param参数
|
||||
* 调用execute0时,param默认给null,之后会在doExecute方法中进行判断,如果param为null,则不进行slot数据槽设置
|
||||
* @Author: LeoLee
|
||||
* @Date: 2021/12/11 15:35
|
||||
*/
|
||||
public <T extends Slot> T execute(String chainId, Class<T> slotClazz,
|
||||
Integer slotIndex, boolean isInnerChain) throws Exception {
|
||||
//默认param为null,在doExecute中会被过滤
|
||||
return this.execute0(chainId, null, slotClazz, slotIndex, isInnerChain);
|
||||
}
|
||||
|
||||
/**
|
||||
* doExecute私有封装
|
||||
* 为了区别无param和有param的执行方法
|
||||
* @Author LeoLee
|
||||
* @Date 17:53 2021/12/10
|
||||
*/
|
||||
private <T extends Slot> T execute0(String chainId, Object param, Class<T> slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception {
|
||||
T slot = this.doExecute(chainId, param, slotClazz, slotIndex, isInnerChain);
|
||||
if (ObjectUtil.isNotNull(slot.getException())) {
|
||||
throw slot.getException();
|
||||
@@ -338,15 +288,8 @@ public class FlowExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 无param执行器
|
||||
* @Param: [chainId] 业务链id
|
||||
* @Return: com.yomahub.liteflow.entity.data.LiteflowResponse<com.yomahub.liteflow.entity.data.DefaultSlot>
|
||||
* @Author: LeoLee
|
||||
* @Date: 2021/12/11 15:54
|
||||
*/
|
||||
public LiteflowResponse<DefaultSlot> execute2Resp(String chainId) {
|
||||
return this.execute2Resp(chainId, DefaultSlot.class, null, false);
|
||||
return this.execute2Resp(chainId, null, DefaultSlot.class);
|
||||
}
|
||||
|
||||
public LiteflowResponse<DefaultSlot> execute2Resp(String chainId, Object param) {
|
||||
@@ -359,39 +302,8 @@ public class FlowExecutor {
|
||||
|
||||
private final ArrayList<Class<? extends Exception>> notFailExceptionList = ListUtil.toList(ChainEndException.class);
|
||||
|
||||
/**
|
||||
* 带param参数的execute2Resp方法,会对param进行判断
|
||||
* 如果param为null,则抛出NullParamException
|
||||
* @Author: LeoLee
|
||||
* @Date: 2021/12/11 15:55
|
||||
*/
|
||||
public <T extends Slot> LiteflowResponse<T> execute2Resp(String chainId, Object param, Class<T> slotClazz, Integer slotIndex,
|
||||
boolean isInnerChain) {
|
||||
if (ObjectUtil.isNull(param)) {
|
||||
//data slot is a ConcurrentHashMap, so null value will trigger NullPointerException
|
||||
throw new NullParamException("data slot can't accept null param");
|
||||
}
|
||||
return execute2Resp0(chainId, param, slotClazz, slotIndex, isInnerChain);
|
||||
}
|
||||
|
||||
/**
|
||||
* 无param参数的execute2Resp方法
|
||||
* 调用doExecute方法时,param默认传递null,会在doExecute房中进行
|
||||
* @Author: LeoLee
|
||||
* @Date: 2021/12/11 16:10
|
||||
*/
|
||||
public <T extends Slot> LiteflowResponse<T> execute2Resp(String chainId, Class<T> slotClazz, Integer slotIndex,
|
||||
boolean isInnerChain) {
|
||||
//默认param为null,在doExecute中会被过滤
|
||||
return execute2Resp0(chainId, null, slotClazz, slotIndex, isInnerChain);
|
||||
}
|
||||
|
||||
/**
|
||||
* doExecute私有封装
|
||||
* @Author LeoLee
|
||||
* @Date 17:54 2021/12/10
|
||||
*/
|
||||
private <T extends Slot> LiteflowResponse<T> execute2Resp0(String chainId, Object param, Class<T> slotClazz, Integer slotIndex, boolean isInnerChain) {
|
||||
LiteflowResponse<T> response = new LiteflowResponse<>();
|
||||
|
||||
T slot = doExecute(chainId, param, slotClazz, slotIndex, isInnerChain);
|
||||
@@ -433,14 +345,12 @@ public class FlowExecutor {
|
||||
}
|
||||
|
||||
if (!isInnerChain) {
|
||||
//对param进行判空,如果为null,则不进行slot设置
|
||||
if (ObjectUtil.isNotNull(param)) {
|
||||
if (ObjectUtil.isNotNull(param)){
|
||||
slot.setRequestData(param);
|
||||
}
|
||||
slot.setChainName(chainId);
|
||||
} else {
|
||||
//对param进行判空,如果为null,则不进行slot设置
|
||||
if (ObjectUtil.isNotNull(param)) {
|
||||
if (ObjectUtil.isNotNull(param)){
|
||||
slot.setChainReqData(chainId, param);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
package com.yomahub.liteflow.entity.data;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.yomahub.liteflow.exception.NullParamException;
|
||||
import org.slf4j.Logger;
|
||||
@@ -29,7 +30,7 @@ public abstract class AbsSlot implements Slot {
|
||||
|
||||
private static final String RESPONSE = "_response";
|
||||
|
||||
private static final String CHAINNAME = "_chain_name";
|
||||
private static final String CHAIN_NAME = "_chain_name";
|
||||
|
||||
private static final String COND_NODE_PREFIX = "_cond_";
|
||||
|
||||
@@ -49,7 +50,7 @@ public abstract class AbsSlot implements Slot {
|
||||
|
||||
protected ConcurrentHashMap<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
|
||||
|
||||
private <T> void dataMapPut(String key, T t) {
|
||||
private <T> void putDataMap(String key, T t) {
|
||||
if (ObjectUtil.isNull(t)) {
|
||||
//data slot is a ConcurrentHashMap, so null value will trigger NullPointerException
|
||||
throw new NullParamException("data slot can't accept null param");
|
||||
@@ -66,11 +67,11 @@ public abstract class AbsSlot implements Slot {
|
||||
}
|
||||
|
||||
public <T> void setInput(String nodeId,T t){
|
||||
dataMapPut(NODE_INPUT_PREFIX + nodeId, t);
|
||||
putDataMap(NODE_INPUT_PREFIX + nodeId, t);
|
||||
}
|
||||
|
||||
public <T> void setOutput(String nodeId,T t){
|
||||
dataMapPut(NODE_OUTPUT_PREFIX + nodeId, t);
|
||||
putDataMap(NODE_OUTPUT_PREFIX + nodeId, t);
|
||||
}
|
||||
|
||||
public <T> T getRequestData(){
|
||||
@@ -78,7 +79,7 @@ public abstract class AbsSlot implements Slot {
|
||||
}
|
||||
|
||||
public <T> void setRequestData(T t){
|
||||
dataMapPut(REQUEST, t);
|
||||
putDataMap(REQUEST, t);
|
||||
}
|
||||
|
||||
public <T> T getResponseData(){
|
||||
@@ -86,7 +87,7 @@ public abstract class AbsSlot implements Slot {
|
||||
}
|
||||
|
||||
public <T> void setResponseData(T t){
|
||||
dataMapPut(RESPONSE, t);
|
||||
putDataMap(RESPONSE, t);
|
||||
}
|
||||
|
||||
public <T> T getChainReqData(String chainId) {
|
||||
@@ -94,7 +95,7 @@ public abstract class AbsSlot implements Slot {
|
||||
}
|
||||
|
||||
public <T> void setChainReqData(String chainId, T t) {
|
||||
dataMapPut(CHAIN_REQ_PREFIX + chainId, t);
|
||||
putDataMap(CHAIN_REQ_PREFIX + chainId, t);
|
||||
}
|
||||
|
||||
public boolean hasData(String key){
|
||||
@@ -106,7 +107,7 @@ public abstract class AbsSlot implements Slot {
|
||||
}
|
||||
|
||||
public <T> void setData(String key, T t){
|
||||
dataMapPut(key, t);
|
||||
putDataMap(key, t);
|
||||
}
|
||||
|
||||
public <T> void setPrivateDeliveryData(String nodeId, T t){
|
||||
@@ -134,7 +135,7 @@ public abstract class AbsSlot implements Slot {
|
||||
}
|
||||
|
||||
public <T> void setCondResult(String key, T t){
|
||||
dataMapPut(COND_NODE_PREFIX + key, t);
|
||||
putDataMap(COND_NODE_PREFIX + key, t);
|
||||
}
|
||||
|
||||
public <T> T getCondResult(String key){
|
||||
@@ -142,11 +143,11 @@ public abstract class AbsSlot implements Slot {
|
||||
}
|
||||
|
||||
public void setChainName(String chainName) {
|
||||
dataMapPut(CHAINNAME, chainName);
|
||||
putDataMap(CHAIN_NAME, chainName);
|
||||
}
|
||||
|
||||
public String getChainName() {
|
||||
return (String)dataMap.get(CHAINNAME);
|
||||
return (String)dataMap.get(CHAIN_NAME);
|
||||
}
|
||||
|
||||
public void addStep(CmpStep step){
|
||||
@@ -169,7 +170,7 @@ public abstract class AbsSlot implements Slot {
|
||||
|
||||
@Override
|
||||
public void generateRequestId() {
|
||||
dataMap.put(REQUEST_ID, new Long(System.nanoTime()).toString());
|
||||
dataMap.put(REQUEST_ID, IdUtil.nanoId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -188,6 +189,6 @@ public abstract class AbsSlot implements Slot {
|
||||
|
||||
@Override
|
||||
public void setException(Exception e) {
|
||||
dataMapPut(EXCEPTION, e);
|
||||
putDataMap(EXCEPTION, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.yomahub.liteflow.test.nullParam;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.entity.data.DefaultSlot;
|
||||
import com.yomahub.liteflow.entity.data.LiteflowResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -13,9 +16,8 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
/**
|
||||
* 单元测试:传递null param导致NPE的优化代码
|
||||
*
|
||||
* @Author LeoLee
|
||||
* @Date 2021/12/9 16:58
|
||||
* @Version 1.0
|
||||
* @author LeoLee
|
||||
* @since 2.6.6
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(value = "classpath:/nullParam/application.properties")
|
||||
@@ -29,15 +31,11 @@ public class NullParamTest {
|
||||
|
||||
/**
|
||||
* 支持无参的flow执行,以及param 为null时的异常抛出
|
||||
* @Author LeoLee
|
||||
* @Date 17:25 2021/12/9
|
||||
*/
|
||||
@Test
|
||||
public void testNullParam() throws Exception {
|
||||
//flowExecutor.execute("chain1", null);//NullParamException: data slot can't accept null param
|
||||
flowExecutor.execute("chain1");
|
||||
//flowExecutor.execute2Resp("chain1", null);//NullParamException: data slot can't accept null param
|
||||
flowExecutor.execute2Resp("chain1");
|
||||
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
liteflow.rule-source=nullParam/flow.xml
|
||||
liteflow.print-banner=true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
<!--同步执行-->
|
||||
<then value="a,b"/>
|
||||
<when value="c"/>
|
||||
</chain>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.yomahub.liteflow.test.nullParam;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.entity.data.DefaultSlot;
|
||||
import com.yomahub.liteflow.entity.data.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -11,10 +14,8 @@ import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 单元测试:传递null param导致NPE的优化代码
|
||||
*
|
||||
* @Author LeoLee
|
||||
* @Date 2021/12/11
|
||||
* @Version V1.0
|
||||
* @author LeoLee
|
||||
* @since 2.6.6
|
||||
**/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:/nullParam/application-local.xml")
|
||||
@@ -25,14 +26,10 @@ public class NullParamTest extends BaseTest {
|
||||
|
||||
/**
|
||||
* 支持无参的flow执行,以及param 为null时的异常抛出
|
||||
* @Author: LeoLee
|
||||
* @Date: 2021/12/11 21:38
|
||||
*/
|
||||
@Test
|
||||
public void testNullParam() throws Exception {
|
||||
//flowExecutor.execute("chain1", null);//NullParamException: data slot can't accept null param
|
||||
flowExecutor.execute("chain1");
|
||||
//flowExecutor.execute2Resp("chain1", null);//NullParamException: data slot can't accept null param
|
||||
flowExecutor.execute2Resp("chain1");
|
||||
LiteflowResponse<DefaultSlot> response = flowExecutor.execute2Resp("chain1");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user