From 535c2b7c846ca31faed405ac248d30cd49762b62 Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Wed, 21 May 2025 17:58:07 +0800 Subject: [PATCH] =?UTF-8?q?bug=20#IC8UPJ=20=E8=A7=84=E5=88=99EL=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E5=9C=A8liteflow.parse-mode=3DPARSE=5FONE=5FON=5FFIRS?= =?UTF-8?q?T=5FEXEC=E6=97=B6=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/el/LiteFlowChainELBuilder.java | 61 ++++++++++--------- .../ValidateRuleELSpringbootTest.java | 14 ++++- .../resources/validate/application.properties | 1 + 3 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/validate/application.properties diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index c76fe8be4..0a4f426d7 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -146,13 +146,7 @@ public class LiteFlowChainELBuilder { } List errorList = new ArrayList<>(); try { - DefaultContext context = new DefaultContext<>(); - - // 往上下文里放入所有的node,使得el表达式可以直接引用到nodeId - FlowBus.getNodeMap().keySet().forEach(nodeId -> context.put(nodeId, FlowBus.getNode(nodeId))); - - // 解析route el成为一个executable - Executable routeExecutable = (Executable) EXPRESS_RUNNER.execute(routeEl, context, errorList, true, true); + Executable routeExecutable = compile(routeEl, errorList, false); // 判断routeEL是不是符合规范 if (!(routeExecutable instanceof AndOrCondition || routeExecutable instanceof NotCondition || routeExecutable instanceof Node)){ @@ -197,22 +191,7 @@ public class LiteFlowChainELBuilder { List errorList = new ArrayList<>(); try { - DefaultContext context = new DefaultContext<>(); - - // 这里一定要先放chain,再放node,因为node优先于chain,所以当重名时,node会覆盖掉chain - // 往上下文里放入所有的chain,是的el表达式可以直接引用到chain - FlowBus.getChainMap().values().forEach(chain -> context.put(chain.getChainId(), chain)); - - // 往上下文里放入所有的node,使得el表达式可以直接引用到nodeId - FlowBus.getNodeMap().keySet().forEach(nodeId -> context.put(nodeId, FlowBus.getNode(nodeId))); - - // 放入当前主chain的ID - context.put(ChainConstant.CURR_CHAIN_ID, this.chain.getChainId()); - - // 解析el成为一个Condition - // 为什么这里只是一个Condition,而不是一个List呢 - // 这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样 - Condition condition = (Condition) EXPRESS_RUNNER.execute(elStr, context, errorList, true, true); + Condition condition = compile(elStr, errorList, true); if (Objects.isNull(condition)){ throw new QLException(StrUtil.format("parse el fail,el:[{}]", elStr)); @@ -269,7 +248,6 @@ public class LiteFlowChainELBuilder { * @param elStr EL表达式 * @return true 校验成功 false 校验失败 */ - @Deprecated public static boolean validate(String elStr) { return validateWithEx(elStr).isSuccess(); } @@ -277,16 +255,16 @@ public class LiteFlowChainELBuilder { /** * 校验 * - * @param elStr - * @return + * @param elStr EL表达式 + * @return ValidationResp */ public static ValidationResp validateWithEx(String elStr) { try { - LiteFlowChainELBuilder.createChain().setEL(elStr); + LiteFlowChainELBuilder.createChain().compile(elStr, null, true); return ValidationResp.success(); } catch (Exception e) { - LOG.error("validate error", e); - return ValidationResp.fail(e); + String msg = buildDataNotFoundExceptionMsg(elStr); + return ValidationResp.fail(new ELParseException(msg)); } } @@ -460,4 +438,29 @@ public class LiteFlowChainELBuilder { } } + @SuppressWarnings("unchecked") + private T compile(String elStr, List errorList, boolean putChain2Context) throws Exception{ + DefaultContext context = new DefaultContext<>(); + + if (putChain2Context){ + // 这里一定要先放chain,再放node,因为node优先于chain,所以当重名时,node会覆盖掉chain + // 往上下文里放入所有的chain,是的el表达式可以直接引用到chain + FlowBus.getChainMap().values().forEach(chain -> context.put(chain.getChainId(), chain)); + } + + // 往上下文里放入所有的node,使得el表达式可以直接引用到nodeId + FlowBus.getNodeMap().keySet().forEach(nodeId -> context.put(nodeId, FlowBus.getNode(nodeId))); + + // 放入当前主chain的ID + if (this.chain != null){ + context.put(ChainConstant.CURR_CHAIN_ID, this.chain.getChainId()); + } + + // 解析el成为一个Condition + // 为什么这里只是一个Condition,而不是一个List呢 + // 这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样 + + return (T) EXPRESS_RUNNER.execute(elStr, context, errorList, true, true); + } + } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/validateRule/ValidateRuleELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/validateRule/ValidateRuleELSpringbootTest.java index 3511de711..38b1c4b39 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/validateRule/ValidateRuleELSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/validateRule/ValidateRuleELSpringbootTest.java @@ -2,8 +2,10 @@ package com.yomahub.liteflow.test.validateRule; import com.yomahub.liteflow.builder.LiteFlowNodeBuilder; import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; +import com.yomahub.liteflow.common.entity.ValidationResp; import com.yomahub.liteflow.enums.NodeTypeEnum; import com.yomahub.liteflow.test.BaseTest; +import com.yomahub.liteflow.test.url.LiteflowNodeELSpringbootTest; import com.yomahub.liteflow.test.validateRule.cmp.ACmp; import com.yomahub.liteflow.test.validateRule.cmp.BCmp; import com.yomahub.liteflow.test.validateRule.cmp.CCmp; @@ -11,13 +13,15 @@ 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.test.context.TestPropertySource; +@TestPropertySource(value = "classpath:/validate/application.properties") @SpringBootTest(classes = ValidateRuleELSpringbootTest.class) @EnableAutoConfiguration public class ValidateRuleELSpringbootTest extends BaseTest { @Test - public void testChainELExpressValidate() { + public void testChainELExpressValidate1() { LiteFlowNodeBuilder.createNode() .setId("a") .setName("组件A") @@ -36,8 +40,12 @@ public class ValidateRuleELSpringbootTest extends BaseTest { .setType(NodeTypeEnum.COMMON) .setClazz(CCmp.class) .build(); - Assertions.assertFalse(LiteFlowChainELBuilder.validate("THEN(a, b, h)")); - Assertions.assertTrue(LiteFlowChainELBuilder.validate("THEN(a, b, c)")); + + ValidationResp resp1 = LiteFlowChainELBuilder.validateWithEx("THEN(a, b, h)"); + ValidationResp resp2 = LiteFlowChainELBuilder.validateWithEx("THEN(a, b, c)"); + + Assertions.assertFalse(resp1.isSuccess()); + Assertions.assertTrue(resp2.isSuccess()); } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/validate/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/validate/application.properties new file mode 100644 index 000000000..0b38cf3a7 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/validate/application.properties @@ -0,0 +1 @@ +liteflow.parse-mode=PARSE_ONE_ON_FIRST_EXEC \ No newline at end of file