瀏覽代碼

优化代码逻辑,调整测试用例

jay li 7 月之前
父節點
當前提交
ec8f7aaa8d

+ 5 - 0
liteflow-core/pom.xml

@@ -18,6 +18,11 @@
 			<groupId>cn.hutool</groupId>
 			<groupId>cn.hutool</groupId>
 			<artifactId>hutool-core</artifactId>
 			<artifactId>hutool-core</artifactId>
 		</dependency>
 		</dependency>
+		<dependency>
+			<groupId>cn.hutool</groupId>
+			<artifactId>hutool-crypto</artifactId>
+			<version>${hutool.version}</version>
+		</dependency>
 		<dependency>
 		<dependency>
 			<groupId>org.slf4j</groupId>
 			<groupId>org.slf4j</groupId>
 			<artifactId>slf4j-api</artifactId>
 			<artifactId>slf4j-api</artifactId>

+ 41 - 36
liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java

@@ -3,9 +3,9 @@ package com.yomahub.liteflow.builder.el;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.*;
 import cn.hutool.core.util.*;
-import cn.hutool.crypto.SecureUtil;
-import cn.hutool.crypto.digest.Digester;
+import cn.hutool.crypto.digest.MD5;
 import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.ql.util.express.DefaultContext;
 import com.ql.util.express.DefaultContext;
 import com.ql.util.express.ExpressRunner;
 import com.ql.util.express.ExpressRunner;
@@ -33,11 +33,15 @@ import java.io.File;
 import java.util.*;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicInteger;
 
 
+import static com.yomahub.liteflow.util.JsonUtil.*;
+import static com.yomahub.liteflow.util.SerialsUtil.generateShortUUID;
+
 
 
 /**
 /**
  * Chain基于代码形式的组装器 EL表达式规则专属组装器
  * Chain基于代码形式的组装器 EL表达式规则专属组装器
  *
  *
  * @author Bryan.Zhang
  * @author Bryan.Zhang
+ * @author Jay li
  * @since 2.8.0
  * @since 2.8.0
  */
  */
 public class LiteFlowChainELBuilder {
 public class LiteFlowChainELBuilder {
@@ -217,7 +221,7 @@ public class LiteFlowChainELBuilder {
 				throw new QLException(StrUtil.format("parse el fail,el:[{}]", elStr));
 				throw new QLException(StrUtil.format("parse el fail,el:[{}]", elStr));
 			}
 			}
 
 
-            setNodesInstanceId(condition, liteflowConfig);
+            setNodesInstanceId(condition);
 
 
 			// 把主要的condition加入
 			// 把主要的condition加入
 			this.conditionList.add(condition);
 			this.conditionList.add(condition);
@@ -239,30 +243,41 @@ public class LiteFlowChainELBuilder {
 		}
 		}
 	}
 	}
 
 
-    private void setNodesInstanceId(Condition condition, LiteflowConfig liteflowConfig) {
-        File nodeDir = new File(System.getProperty("user.dir") + "/." + liteflowConfig.getRuleSource() + "/" + this.chain.getChainId());
-        String elTrim = chain.getEl().replaceAll("\n", "").trim();
+    private void setNodesInstanceId(Condition condition) {
+        File nodeDir = new File(System.getProperty("user.dir")+  File.separator + ".node_instance_id" + File.separator + this.chain.getChainId());
+        String elMd5 = MD5.create().digestHex(chain.getEl());
 
 
         // 如果文件不存在,或者文件内容不是当前el,则写入
         // 如果文件不存在,或者文件内容不是当前el,则写入
-        if (FileUtil.isEmpty(nodeDir) || !FileUtil.readLines(nodeDir.getPath(), CharsetUtil.UTF_8).get(0).equals(elTrim)) {
-            writeNodeInstanceId(nodeDir, condition);
+        if (FileUtil.isEmpty(nodeDir) || !FileUtil.readLines(nodeDir.getPath(), CharsetUtil.UTF_8).get(0).equals(elMd5)) {
+            writeNodeInstanceId(nodeDir, condition, elMd5);
         } else {
         } else {
             // 文件存在,则直接读取
             // 文件存在,则直接读取
             List<String> nodeList = FileUtil.readLines(nodeDir.getPath(), CharsetUtil.UTF_8);
             List<String> nodeList = FileUtil.readLines(nodeDir.getPath(), CharsetUtil.UTF_8);
 
 
-            Map<String, String[]> executableMap = new HashMap<>();
+            Map<String, List<String>> executableMap = new HashMap<>();
             for (int i = 1; i < nodeList.size(); i++) {
             for (int i = 1; i < nodeList.size(); i++) {
-                String info = nodeList.get(i);
-                int index = info.indexOf(",");
-                executableMap.put(info.substring(0, index), info.substring(index + 1).split(","));
-            }
+                JsonNode groupKeyAndInstanceIds = parseObject(nodeList.get(i));
+
+				Iterator<String> fieldNames = groupKeyAndInstanceIds.fieldNames();
+				while (fieldNames.hasNext()) {
+					String key = fieldNames.next();
+					JsonNode valueNode = groupKeyAndInstanceIds.get(key);
+					if (valueNode.isArray()) {
+						List<String> valueList = new ArrayList<>();
+						for (JsonNode item : valueNode) {
+							valueList.add(item.asText());
+						}
+						executableMap.put(key, valueList);
+					}
+	            }
+			}
 
 
             condition.getExecutableGroup().forEach((key, executables) -> {
             condition.getExecutableGroup().forEach((key, executables) -> {
                 AtomicInteger index = new AtomicInteger(0);
                 AtomicInteger index = new AtomicInteger(0);
                 executables.forEach(executable -> {
                 executables.forEach(executable -> {
                     if (executableMap.containsKey(key)) {
                     if (executableMap.containsKey(key)) {
                         if (executable instanceof Node) {
                         if (executable instanceof Node) {
-                            ((Node) executable).setInstanceId((executableMap.get(key)[index.getAndIncrement()]));
+                            ((Node) executable).setInstanceId((executableMap.get(key).get(index.getAndIncrement())));
                         }
                         }
                     }
                     }
                 });
                 });
@@ -270,20 +285,25 @@ public class LiteFlowChainELBuilder {
         }
         }
     }
     }
 
 
-    private void writeNodeInstanceId(File nodeDir, Condition condition) {
+    // 写入时第一行为el的md5,第二行为json格式的groupKey和对应的实例id
+    private void writeNodeInstanceId(File nodeDir, Condition condition, String elMd5) {
         ArrayList<String> writeList = new ArrayList<>();
         ArrayList<String> writeList = new ArrayList<>();
-        writeList.add(chain.getEl().replaceAll("\n", "").trim());
+        writeList.add(elMd5);
 
 
         condition.getExecutableGroup().forEach((key, executables) -> {
         condition.getExecutableGroup().forEach((key, executables) -> {
-            StringBuilder instanceIds = new StringBuilder();
+            Map<String, List<String>> groupKeyAndInstanceIds = new HashMap<>();
+            List<String> instanceIds = new ArrayList<>();
+
             executables.forEach(executable -> {
             executables.forEach(executable -> {
                 if (executable instanceof Node) {
                 if (executable instanceof Node) {
-                    ((Node) executable).setInstanceId(generateInstanceId(executable.getId()));
-                    instanceIds.append(",").append(((Node) executable).getInstanceId());
+                    ((Node) executable).setInstanceId(generateShortUUID());
+                    instanceIds.add(((Node) executable).getInstanceId());
                 }
                 }
             });
             });
-            writeList.add(key + instanceIds);
-        });
+
+			groupKeyAndInstanceIds.put(key, instanceIds);
+			writeList.add(toJsonString(groupKeyAndInstanceIds));
+		});
 
 
         FileUtil.writeLines(writeList, nodeDir.getPath(), CharsetUtil.UTF_8);
         FileUtil.writeLines(writeList, nodeDir.getPath(), CharsetUtil.UTF_8);
     }
     }
@@ -491,19 +511,4 @@ public class LiteFlowChainELBuilder {
 		}
 		}
 	}
 	}
 
 
-	private String generateInstanceId(String nodeId) {
-		Digester sha256 = SecureUtil.sha256();
-		byte[] hashBytes = sha256.digest(nodeId + System.nanoTime());
-
-		StringBuilder sb = new StringBuilder();
-		for (byte b : hashBytes) {
-			if (sb.length() >= 8) {
-				break;
-			}
-			sb.append(String.format("%02x", b));
-		}
-
-		return sb.toString();
-	}
-
 }
 }

+ 1 - 2
liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java

@@ -26,8 +26,6 @@ import com.yomahub.liteflow.slot.DataBus;
 import com.yomahub.liteflow.slot.Slot;
 import com.yomahub.liteflow.slot.Slot;
 import com.yomahub.liteflow.spi.holder.CmpAroundAspectHolder;
 import com.yomahub.liteflow.spi.holder.CmpAroundAspectHolder;
 import com.yomahub.liteflow.util.JsonUtil;
 import com.yomahub.liteflow.util.JsonUtil;
-import cn.hutool.crypto.*;
-import cn.hutool.crypto.digest.*;
 
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Method;
 import java.util.Date;
 import java.util.Date;
@@ -39,6 +37,7 @@ import java.util.Stack;
  *
  *
  * @author Bryan.Zhang
  * @author Bryan.Zhang
  * @author luo yi
  * @author luo yi
+ * @author Jay li
  */
  */
 public abstract class NodeComponent{
 public abstract class NodeComponent{
 
 

+ 1 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java

@@ -33,6 +33,7 @@ import java.util.Stack;
  *
  *
  * @author Bryan.Zhang
  * @author Bryan.Zhang
  * @author luo yi
  * @author luo yi
+ * @author Jay li
  */
  */
 public class Node implements Executable, Cloneable, Rollbackable{
 public class Node implements Executable, Cloneable, Rollbackable{
 
 

+ 0 - 48
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/base/BaseCommonELSpringTest.java

@@ -10,10 +10,6 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 
 @ExtendWith(SpringExtension.class)
 @ExtendWith(SpringExtension.class)
 @ContextConfiguration("classpath:/base/application.xml")
 @ContextConfiguration("classpath:/base/application.xml")
@@ -29,48 +25,4 @@ public class BaseCommonELSpringTest extends BaseTest {
 		Assertions.assertEquals("a==>b==>c==>d", response.getExecuteStepStr());
 		Assertions.assertEquals("a==>b==>c==>d", response.getExecuteStepStr());
 	}
 	}
 
 
-	@Test
-	public void testBaseCommon2() {
-		LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
-		Assertions.assertTrue(response.isSuccess());
-		Assertions.assertEquals("a==>a==>a==>a", response.getExecuteStepStr());
-
-		String executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
-		Set<String> strings = extractValues(executeStepStrWithInstanceId);
-
-		Assertions.assertEquals(strings.size(), 4);
-	}
-
-	@Test
-	public void testBaseCommonInstanceId() {
-		LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
-		Assertions.assertTrue(response.isSuccess());
-		Assertions.assertEquals("a==>a==>a==>a", response.getExecuteStepStr());
-
-		String executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
-		Set<String> set1 = extractValues(executeStepStrWithInstanceId);
-
-		Assertions.assertEquals(set1.size(), 4);
-
-		response = flowExecutor.execute2Resp("chain2", "arg");
-		Assertions.assertTrue(response.isSuccess());
-		Assertions.assertEquals("a==>a==>a==>a", response.getExecuteStepStr());
-
-		executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
-		Set<String> set2 = extractValues(executeStepStrWithInstanceId);
-
-		Assertions.assertEquals(set2.size(), 4);
-		Assertions.assertEquals(set1, set2);
-	}
-
-	public static Set<String> extractValues(String input) {
-		Set<String> values = new HashSet<>();
-		Pattern pattern = Pattern.compile("\\[(.*?)]");
-		Matcher matcher = pattern.matcher(input);
-		while (matcher.find()) {
-			values.add(matcher.group(1));
-		}
-		return values;
-	}
-
 }
 }

+ 76 - 0
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/instanceIds/InstanceIdELSpringTest.java

@@ -0,0 +1,76 @@
+package com.yomahub.liteflow.test.instanceIds;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+/**
+ * 测试生成 instanceId
+ * @author Jay li
+ */
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration("classpath:/instanceIds/application.xml")
+public class InstanceIdELSpringTest extends BaseTest {
+
+	@Resource
+	private FlowExecutor flowExecutor;
+
+    // 文件保存实例id
+	@Test
+	public void testInstanceIds1() {
+		LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+		Assertions.assertTrue(response.isSuccess());
+		Assertions.assertEquals("a==>a==>a==>a", response.getExecuteStepStr());
+
+		String executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
+		Set<String> strings = extractValues(executeStepStrWithInstanceId);
+		System.out.println(executeStepStrWithInstanceId);
+		Assertions.assertEquals(strings.size(), 4);
+	}
+
+	// 重复调用实例id不变
+	@Test
+	public void testInstanceIds2() {
+		LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+		Assertions.assertTrue(response.isSuccess());
+		Assertions.assertEquals("a==>a==>a==>a", response.getExecuteStepStr());
+
+		String executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
+		Set<String> set1 = extractValues(executeStepStrWithInstanceId);
+		System.out.println(executeStepStrWithInstanceId);
+
+		Assertions.assertEquals(set1.size(), 4);
+
+		response = flowExecutor.execute2Resp("chain2", "arg");
+		Assertions.assertTrue(response.isSuccess());
+		Assertions.assertEquals("a==>a==>a==>a", response.getExecuteStepStr());
+
+		executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
+		Set<String> set2 = extractValues(executeStepStrWithInstanceId);
+		System.out.println(executeStepStrWithInstanceId);
+
+		Assertions.assertEquals(set2.size(), 4);
+		Assertions.assertEquals(set1, set2);
+	}
+
+	public static Set<String> extractValues(String input) {
+		Set<String> values = new HashSet<>();
+		Pattern pattern = Pattern.compile("\\[(.*?)]");
+		Matcher matcher = pattern.matcher(input);
+		while (matcher.find()) {
+			values.add(matcher.group(1));
+		}
+		return values;
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/instanceIds/cmp/ACmp.java

@@ -0,0 +1,21 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.instanceIds.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!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/instanceIds/cmp/BCmp.java

@@ -0,0 +1,21 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.instanceIds.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!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/instanceIds/cmp/CCmp.java

@@ -0,0 +1,21 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.instanceIds.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!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/instanceIds/cmp/DCmp.java

@@ -0,0 +1,21 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.instanceIds.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("d")
+public class DCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 0 - 4
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/base/flow.el.xml

@@ -3,8 +3,4 @@
     <chain name="chain1">
     <chain name="chain1">
         THEN(a,b,c,d);
         THEN(a,b,c,d);
     </chain>
     </chain>
-
-    <chain name="chain2">
-        THEN(a,a,a,a);
-    </chain>
 </flow>
 </flow>

+ 23 - 0
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/instanceIds/application.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://www.springframework.org/schema/beans"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
+       http://www.springframework.org/schema/context
+       http://www.springframework.org/schema/context/spring-context-4.0.xsd">
+
+    <context:component-scan base-package="com.yomahub.liteflow.test.base.cmp" />
+
+    <bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
+
+    <bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
+
+    <bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
+        <property name="ruleSource" value="base/flow.el.xml"/>
+    </bean>
+
+    <bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
+        <constructor-arg name="liteflowConfig" ref="liteflowConfig"/>
+    </bean>
+</beans>

+ 10 - 0
liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/instanceIds/flow.el.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+    <chain name="chain1">
+        THEN(a,b,c,d);
+    </chain>
+
+    <chain name="chain2">
+        THEN(a,a,a,a);
+    </chain>
+</flow>