From a9e025ff9c9acad3ba73a7c3a5c7832b52effce0 Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Fri, 10 Dec 2021 17:19:23 +0800 Subject: [PATCH 1/9] =?UTF-8?q?1.=E5=88=9D=E6=AD=A5=E8=A7=A3=E5=86=B3null?= =?UTF-8?q?=20param=E5=AD=98=E5=85=A5data=20slot=E7=9A=84NPE=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 9 +++++- .../yomahub/liteflow/entity/data/AbsSlot.java | 9 ++++++ .../exception/NullParamException.java | 31 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/exception/NullParamException.java diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 0293f4058..909504009 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -288,6 +288,10 @@ public class FlowExecutor { public T execute(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception { + if (null == param) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot cann't accept null param"); + } T slot = this.doExecute(chainId, param, slotClazz, slotIndex, isInnerChain); if (ObjectUtil.isNotNull(slot.getException())) { throw slot.getException(); @@ -309,7 +313,10 @@ public class FlowExecutor { public LiteflowResponse execute2Resp(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) { LiteflowResponse response = new LiteflowResponse<>(); - + if (null == param) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot cann't accept null param"); + } T slot = doExecute(chainId, param, slotClazz, slotIndex, isInnerChain); if (ObjectUtil.isNotNull(slot.getException()) && !notFailExceptionList.contains(slot.getException().getClass())) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java index f2f95132a..e2255e6a5 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java @@ -7,6 +7,7 @@ */ package com.yomahub.liteflow.entity.data; +import com.yomahub.liteflow.exception.NullParamException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Iterator; @@ -56,10 +57,18 @@ public abstract class AbsSlot implements Slot { } public void setInput(String nodeId,T t){ + if (null == t) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot cann't accept null param"); + } dataMap.put(NODE_INPUT_PREFIX + nodeId, t); } public void setOutput(String nodeId,T t){ + if (null == t) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot cann't accept null param"); + } dataMap.put(NODE_OUTPUT_PREFIX + nodeId, t); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NullParamException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NullParamException.java new file mode 100644 index 000000000..295555ac5 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NullParamException.java @@ -0,0 +1,31 @@ +package com.yomahub.liteflow.exception; + +import java.io.Serializable; + +/** + * null param exception + * when param is null, dataMap (ConcurrentHashMap) cann't accept a null value + * + * @Author LeoLee + * @Date 2021/12/10 16:47 + * @Version 1.0 + */ +public class NullParamException extends RuntimeException implements Serializable { + + private static final long serialVersionUID = -864259139568071245L; + + private String message; + + public NullParamException(String message) { + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} From 84e204baacd9f3cc44097f3a35b40ae742040151 Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Fri, 10 Dec 2021 17:48:57 +0800 Subject: [PATCH 2/9] =?UTF-8?q?1.=E5=A2=9E=E5=8A=A0=E6=97=A0=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E5=8F=82=E6=95=B0=E7=9A=84=E6=89=A7=E8=A1=8C=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 909504009..501d4e7e9 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -278,6 +278,10 @@ public class FlowExecutor { this.execute(chainId, param, slotClazz, slotIndex, true); } + public DefaultSlot execute(String chainId) throws Exception { + return this.execute(chainId, DefaultSlot.class, null, false); + } + public DefaultSlot execute(String chainId, Object param) throws Exception { return this.execute(chainId, param, DefaultSlot.class, null, false); } @@ -292,6 +296,15 @@ public class FlowExecutor { //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException throw new NullParamException("data slot cann't accept null param"); } + return this.execute0(chainId, param, slotClazz, slotIndex, isInnerChain); + } + + public T execute(String chainId, Class slotClazz, + Integer slotIndex, boolean isInnerChain) throws Exception { + return this.execute0(chainId, null, slotClazz, slotIndex, isInnerChain); + } + + private T execute0(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception { T slot = this.doExecute(chainId, param, slotClazz, slotIndex, isInnerChain); if (ObjectUtil.isNotNull(slot.getException())) { throw slot.getException(); @@ -300,6 +313,10 @@ public class FlowExecutor { } } + public LiteflowResponse execute2Resp(String chainId) { + return this.execute2Resp(chainId, DefaultSlot.class, null, false); + } + public LiteflowResponse execute2Resp(String chainId, Object param) { return this.execute2Resp(chainId, param, DefaultSlot.class); } @@ -312,11 +329,21 @@ public class FlowExecutor { public LiteflowResponse execute2Resp(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) { - LiteflowResponse response = new LiteflowResponse<>(); if (null == param) { //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException throw new NullParamException("data slot cann't accept null param"); } + return execute2Resp0(chainId, param, slotClazz, slotIndex, isInnerChain); + } + + public LiteflowResponse execute2Resp(String chainId, Class slotClazz, Integer slotIndex, + boolean isInnerChain) { + return execute2Resp0(chainId, null, slotClazz, slotIndex, isInnerChain); + } + + private LiteflowResponse execute2Resp0(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) { + LiteflowResponse response = new LiteflowResponse<>(); + T slot = doExecute(chainId, param, slotClazz, slotIndex, isInnerChain); if (ObjectUtil.isNotNull(slot.getException()) && !notFailExceptionList.contains(slot.getException().getClass())) { @@ -356,10 +383,14 @@ public class FlowExecutor { } if (!isInnerChain) { - slot.setRequestData(param); + if (null != param) { + slot.setRequestData(param); + } slot.setChainName(chainId); } else { - slot.setChainReqData(chainId, param); + if (null != param) { + slot.setChainReqData(chainId, param); + } } Chain chain = null; From ea9038561d7143dedc72b304eb47c0832187d63e Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Fri, 10 Dec 2021 17:56:40 +0800 Subject: [PATCH 3/9] =?UTF-8?q?1.=E8=A1=A5=E5=85=85=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 501d4e7e9..e3f4eeae5 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -278,6 +278,13 @@ public class FlowExecutor { 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); } @@ -301,9 +308,15 @@ public class FlowExecutor { public T execute(String chainId, Class slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception { + //默认param为null,在doExecute中会被过滤 return this.execute0(chainId, null, slotClazz, slotIndex, isInnerChain); } + /** + * doExecute私有封装 + * @Author LeoLee + * @Date 17:53 2021/12/10 + */ private T execute0(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception { T slot = this.doExecute(chainId, param, slotClazz, slotIndex, isInnerChain); if (ObjectUtil.isNotNull(slot.getException())) { @@ -338,9 +351,15 @@ public class FlowExecutor { public LiteflowResponse execute2Resp(String chainId, Class 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 LiteflowResponse execute2Resp0(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) { LiteflowResponse response = new LiteflowResponse<>(); From 0dab06c803571d1d8b84b480709a02dc265ac6d0 Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Sat, 11 Dec 2021 16:12:35 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index e3f4eeae5..3c38b9080 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -297,6 +297,11 @@ 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 execute(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception { if (null == param) { @@ -306,6 +311,12 @@ public class FlowExecutor { 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 execute(String chainId, Class slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception { //默认param为null,在doExecute中会被过滤 @@ -314,6 +325,7 @@ public class FlowExecutor { /** * doExecute私有封装 + * 为了区别无param和有param的执行方法 * @Author LeoLee * @Date 17:53 2021/12/10 */ @@ -326,6 +338,13 @@ public class FlowExecutor { } } + /** + * 无param执行器 + * @Param: [chainId] 业务链id + * @Return: com.yomahub.liteflow.entity.data.LiteflowResponse + * @Author: LeoLee + * @Date: 2021/12/11 15:54 + */ public LiteflowResponse execute2Resp(String chainId) { return this.execute2Resp(chainId, DefaultSlot.class, null, false); } @@ -340,6 +359,12 @@ public class FlowExecutor { private final ArrayList> notFailExceptionList = ListUtil.toList(ChainEndException.class); + /** + * 带param参数的execute2Resp方法,会对param进行判断 + * 如果param为null,则抛出NullParamException + * @Author: LeoLee + * @Date: 2021/12/11 15:55 + */ public LiteflowResponse execute2Resp(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) { if (null == param) { @@ -349,6 +374,12 @@ public class FlowExecutor { return execute2Resp0(chainId, param, slotClazz, slotIndex, isInnerChain); } + /** + * 无param参数的execute2Resp方法 + * 调用doExecute方法时,param默认传递null,会在doExecute房中进行 + * @Author: LeoLee + * @Date: 2021/12/11 16:10 + */ public LiteflowResponse execute2Resp(String chainId, Class slotClazz, Integer slotIndex, boolean isInnerChain) { //默认param为null,在doExecute中会被过滤 From 1584644a790880f4d2d7974bafc5b76514125e37 Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Sat, 11 Dec 2021 16:19:26 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/core/FlowExecutor.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 3c38b9080..3d4b13950 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -433,11 +433,13 @@ public class FlowExecutor { } if (!isInnerChain) { + //对param进行判空,如果为null,则不进行slot设置 if (null != param) { slot.setRequestData(param); } slot.setChainName(chainId); } else { + //对param进行判空,如果为null,则不进行slot设置 if (null != param) { slot.setChainReqData(chainId, param); } From 273a9221e4c66ec4551d38a29e8ce514b1fddc5a Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Sat, 11 Dec 2021 21:17:44 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E5=BC=82=E5=B8=B8=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/core/FlowExecutor.java | 4 ++-- .../main/java/com/yomahub/liteflow/entity/data/AbsSlot.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 3d4b13950..c31ece721 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -306,7 +306,7 @@ public class FlowExecutor { Integer slotIndex, boolean isInnerChain) throws Exception { if (null == param) { //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot cann't accept null param"); + throw new NullParamException("data slot can't accept null param"); } return this.execute0(chainId, param, slotClazz, slotIndex, isInnerChain); } @@ -369,7 +369,7 @@ public class FlowExecutor { boolean isInnerChain) { if (null == param) { //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot cann't accept null param"); + throw new NullParamException("data slot can't accept null param"); } return execute2Resp0(chainId, param, slotClazz, slotIndex, isInnerChain); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java index e2255e6a5..10684c759 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java @@ -59,7 +59,7 @@ public abstract class AbsSlot implements Slot { public void setInput(String nodeId,T t){ if (null == t) { //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot cann't accept null param"); + throw new NullParamException("data slot can't accept null param"); } dataMap.put(NODE_INPUT_PREFIX + nodeId, t); } @@ -67,7 +67,7 @@ public abstract class AbsSlot implements Slot { public void setOutput(String nodeId,T t){ if (null == t) { //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot cann't accept null param"); + throw new NullParamException("data slot can't accept null param"); } dataMap.put(NODE_OUTPUT_PREFIX + nodeId, t); } From abb888e40ac0507b40d6f516a5d9240ccdadc1a5 Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Sat, 11 Dec 2021 21:39:19 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/nullParam/NullParamTest.java | 43 +++++++++++++++++++ .../liteflow/test/nullParam/cmp/ACmp.java | 22 ++++++++++ .../liteflow/test/nullParam/cmp/BCmp.java | 23 ++++++++++ .../liteflow/test/nullParam/cmp/CCmp.java | 22 ++++++++++ .../nullParam/application.properties | 2 + .../src/test/resources/nullParam/flow.xml | 8 ++++ .../test/nullParam/NullParamTest.java | 38 ++++++++++++++++ .../liteflow/test/nullParam/cmp/ACmp.java | 22 ++++++++++ .../liteflow/test/nullParam/cmp/BCmp.java | 23 ++++++++++ .../liteflow/test/nullParam/cmp/CCmp.java | 22 ++++++++++ .../resources/nullParam/application-local.xml | 23 ++++++++++ .../src/test/resources/nullParam/flow.xml | 8 ++++ 12 files changed, 256 insertions(+) create mode 100644 liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java create mode 100644 liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java create mode 100644 liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java create mode 100644 liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java create mode 100644 liteflow-testcase-springboot/src/test/resources/nullParam/application.properties create mode 100644 liteflow-testcase-springboot/src/test/resources/nullParam/flow.xml create mode 100644 liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java create mode 100644 liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java create mode 100644 liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java create mode 100644 liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java create mode 100644 liteflow-testcase-springnative/src/test/resources/nullParam/application-local.xml create mode 100644 liteflow-testcase-springnative/src/test/resources/nullParam/flow.xml diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java new file mode 100644 index 000000000..26bc2d2f8 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java @@ -0,0 +1,43 @@ +package com.yomahub.liteflow.test.nullParam; + +import com.yomahub.liteflow.core.FlowExecutor; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * 单元测试:传递null param导致NPE的优化代码 + * + * @Author LeoLee + * @Date 2021/12/9 16:58 + * @Version 1.0 + */ +@RunWith(SpringRunner.class) +@TestPropertySource(value = "classpath:/nullParam/application.properties") +@SpringBootTest(classes = NullParamTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.nullParam.cmp"}) +public class NullParamTest { + + @Autowired + private FlowExecutor flowExecutor; + + /** + * 支持无参的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"); + } + +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java new file mode 100644 index 000000000..3acf3c2c8 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java @@ -0,0 +1,22 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.nullParam.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!"); + System.out.println("get request data:" + this.getSlot().getRequestData()); + this.getSlot().setInput("BCmp", "param for BCmp"); + } +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java new file mode 100644 index 000000000..52bdc4633 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java @@ -0,0 +1,23 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.nullParam.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!"); + System.out.println("BCmp param:" + this.getSlot().getInput("BCmp")); + this.getSlot().setOutput("CCmp", "param for CCmp"); + } + +} diff --git a/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java new file mode 100644 index 000000000..5707caf27 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java @@ -0,0 +1,22 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.nullParam.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!"); + System.out.println("CCmp param:" + this.getSlot().getOutput("CCmp")); + } + +} diff --git a/liteflow-testcase-springboot/src/test/resources/nullParam/application.properties b/liteflow-testcase-springboot/src/test/resources/nullParam/application.properties new file mode 100644 index 000000000..e98eccac3 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/resources/nullParam/application.properties @@ -0,0 +1,2 @@ +liteflow.rule-source=nullParam/flow.xml +liteflow.print-banner=true diff --git a/liteflow-testcase-springboot/src/test/resources/nullParam/flow.xml b/liteflow-testcase-springboot/src/test/resources/nullParam/flow.xml new file mode 100644 index 000000000..cd45c1a17 --- /dev/null +++ b/liteflow-testcase-springboot/src/test/resources/nullParam/flow.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java new file mode 100644 index 000000000..709544449 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/NullParamTest.java @@ -0,0 +1,38 @@ +package com.yomahub.liteflow.test.nullParam; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.test.BaseTest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +/** + * 单元测试:传递null param导致NPE的优化代码 + * + * @Author LeoLee + * @Date 2021/12/11 + * @Version V1.0 + **/ +@RunWith(SpringRunner.class) +@ContextConfiguration("classpath:/nullParam/application-local.xml") +public class NullParamTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + /** + * 支持无参的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"); + } +} diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java new file mode 100644 index 000000000..3acf3c2c8 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/ACmp.java @@ -0,0 +1,22 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.nullParam.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!"); + System.out.println("get request data:" + this.getSlot().getRequestData()); + this.getSlot().setInput("BCmp", "param for BCmp"); + } +} diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java new file mode 100644 index 000000000..52bdc4633 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/BCmp.java @@ -0,0 +1,23 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.nullParam.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!"); + System.out.println("BCmp param:" + this.getSlot().getInput("BCmp")); + this.getSlot().setOutput("CCmp", "param for CCmp"); + } + +} diff --git a/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java new file mode 100644 index 000000000..5707caf27 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/java/com/yomahub/liteflow/test/nullParam/cmp/CCmp.java @@ -0,0 +1,22 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.nullParam.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!"); + System.out.println("CCmp param:" + this.getSlot().getOutput("CCmp")); + } + +} diff --git a/liteflow-testcase-springnative/src/test/resources/nullParam/application-local.xml b/liteflow-testcase-springnative/src/test/resources/nullParam/application-local.xml new file mode 100644 index 000000000..36bf18e53 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/resources/nullParam/application-local.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/liteflow-testcase-springnative/src/test/resources/nullParam/flow.xml b/liteflow-testcase-springnative/src/test/resources/nullParam/flow.xml new file mode 100644 index 000000000..cd45c1a17 --- /dev/null +++ b/liteflow-testcase-springnative/src/test/resources/nullParam/flow.xml @@ -0,0 +1,8 @@ + + + + + + + + From 93e94be107ec8f6ec7215d1ebef9dc04e27b5c31 Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Sat, 11 Dec 2021 22:00:26 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E5=A2=9E=E5=8A=A0put=E5=88=B0datamap?= =?UTF-8?q?=E7=9A=84value=E7=9A=84=E9=9D=9Enull=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/entity/data/AbsSlot.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java index 10684c759..f7d080db3 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java @@ -77,6 +77,10 @@ public abstract class AbsSlot implements Slot { } public void setRequestData(T t){ + if (null == t) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot can't accept null param"); + } dataMap.put(REQUEST, t); } @@ -85,6 +89,10 @@ public abstract class AbsSlot implements Slot { } public void setResponseData(T t){ + if (null == t) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot can't accept null param"); + } dataMap.put(RESPONSE, t); } @@ -93,6 +101,10 @@ public abstract class AbsSlot implements Slot { } public void setChainReqData(String chainId, T t) { + if (null == t) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot can't accept null param"); + } dataMap.put(CHAIN_REQ_PREFIX + chainId, t); } @@ -105,6 +117,10 @@ public abstract class AbsSlot implements Slot { } public void setData(String key, T t){ + if (null == t) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot can't accept null param"); + } dataMap.put(key, t); } @@ -133,6 +149,10 @@ public abstract class AbsSlot implements Slot { } public void setCondResult(String key, T t){ + if (null == t) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot can't accept null param"); + } dataMap.put(COND_NODE_PREFIX + key, t); } @@ -141,6 +161,10 @@ public abstract class AbsSlot implements Slot { } public void setChainName(String chainName) { + if (null == chainName) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot can't accept null param"); + } dataMap.put(CHAINNAME, chainName); } @@ -187,6 +211,10 @@ public abstract class AbsSlot implements Slot { @Override public void setException(Exception e) { + if (null == e) { + //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException + throw new NullParamException("data slot can't accept null param"); + } this.dataMap.put(EXCEPTION, e); } } From f80778e74440d4334c08dbcdd9f58aa2e7c01219 Mon Sep 17 00:00:00 2001 From: LeoLee <512240816@qq.com> Date: Mon, 13 Dec 2021 15:04:46 +0800 Subject: [PATCH 9/9] =?UTF-8?q?1.=E6=96=B0=E5=A2=9EdataMapPut=E7=A7=81?= =?UTF-8?q?=E6=9C=89=E6=96=B9=E6=B3=95=E8=BF=9B=E8=A1=8CdataMap=E7=9A=84pu?= =?UTF-8?q?t=E6=93=8D=E4=BD=9C=EF=BC=8C=E5=9C=A8=E8=AF=A5=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E4=B8=AD=E4=BC=9A=E6=9C=89value=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E7=A9=BA=E9=80=BB=E8=BE=91.2.=E4=BD=BF=E7=94=A8ObjectUtil?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=AF=B9=E8=B1=A1=E5=88=A4=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 8 +-- .../yomahub/liteflow/entity/data/AbsSlot.java | 63 ++++++------------- 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index c31ece721..5acda6a36 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -304,7 +304,7 @@ public class FlowExecutor { */ public T execute(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) throws Exception { - if (null == param) { + 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"); } @@ -367,7 +367,7 @@ public class FlowExecutor { */ public LiteflowResponse execute2Resp(String chainId, Object param, Class slotClazz, Integer slotIndex, boolean isInnerChain) { - if (null == param) { + 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"); } @@ -434,13 +434,13 @@ public class FlowExecutor { if (!isInnerChain) { //对param进行判空,如果为null,则不进行slot设置 - if (null != param) { + if (ObjectUtil.isNotNull(param)) { slot.setRequestData(param); } slot.setChainName(chainId); } else { //对param进行判空,如果为null,则不进行slot设置 - if (null != param) { + if (ObjectUtil.isNotNull(param)) { slot.setChainReqData(chainId, param); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java index f7d080db3..f6f24706d 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/entity/data/AbsSlot.java @@ -7,6 +7,7 @@ */ package com.yomahub.liteflow.entity.data; +import cn.hutool.core.util.ObjectUtil; import com.yomahub.liteflow.exception.NullParamException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,6 +49,14 @@ public abstract class AbsSlot implements Slot { protected ConcurrentHashMap dataMap = new ConcurrentHashMap(); + private void dataMapPut(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"); + } + dataMap.put(key, t); + } + public T getInput(String nodeId){ return (T)dataMap.get(NODE_INPUT_PREFIX + nodeId); } @@ -57,19 +66,11 @@ public abstract class AbsSlot implements Slot { } public void setInput(String nodeId,T t){ - if (null == t) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(NODE_INPUT_PREFIX + nodeId, t); + dataMapPut(NODE_INPUT_PREFIX + nodeId, t); } public void setOutput(String nodeId,T t){ - if (null == t) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(NODE_OUTPUT_PREFIX + nodeId, t); + dataMapPut(NODE_OUTPUT_PREFIX + nodeId, t); } public T getRequestData(){ @@ -77,11 +78,7 @@ public abstract class AbsSlot implements Slot { } public void setRequestData(T t){ - if (null == t) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(REQUEST, t); + dataMapPut(REQUEST, t); } public T getResponseData(){ @@ -89,11 +86,7 @@ public abstract class AbsSlot implements Slot { } public void setResponseData(T t){ - if (null == t) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(RESPONSE, t); + dataMapPut(RESPONSE, t); } public T getChainReqData(String chainId) { @@ -101,11 +94,7 @@ public abstract class AbsSlot implements Slot { } public void setChainReqData(String chainId, T t) { - if (null == t) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(CHAIN_REQ_PREFIX + chainId, t); + dataMapPut(CHAIN_REQ_PREFIX + chainId, t); } public boolean hasData(String key){ @@ -117,11 +106,7 @@ public abstract class AbsSlot implements Slot { } public void setData(String key, T t){ - if (null == t) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(key, t); + dataMapPut(key, t); } public void setPrivateDeliveryData(String nodeId, T t){ @@ -149,11 +134,7 @@ public abstract class AbsSlot implements Slot { } public void setCondResult(String key, T t){ - if (null == t) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(COND_NODE_PREFIX + key, t); + dataMapPut(COND_NODE_PREFIX + key, t); } public T getCondResult(String key){ @@ -161,11 +142,7 @@ public abstract class AbsSlot implements Slot { } public void setChainName(String chainName) { - if (null == chainName) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - dataMap.put(CHAINNAME, chainName); + dataMapPut(CHAINNAME, chainName); } public String getChainName() { @@ -211,10 +188,6 @@ public abstract class AbsSlot implements Slot { @Override public void setException(Exception e) { - if (null == e) { - //data slot is a ConcurrentHashMap, so null value will trigger NullPointerException - throw new NullParamException("data slot can't accept null param"); - } - this.dataMap.put(EXCEPTION, e); + dataMapPut(EXCEPTION, e); } }