Procházet zdrojové kódy

feature #I6BDLN 是否能绝对路径的目录位置及其所有子目录下规则配置文件的侦听

everywhere.z před 2 roky
rodič
revize
87295279c9

+ 4 - 0
liteflow-core/pom.xml

@@ -50,5 +50,9 @@
 			<groupId>commons-beanutils</groupId>
 			<artifactId>commons-beanutils</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+		</dependency>
 	</dependencies>
 </project>

+ 8 - 5
liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java

@@ -126,8 +126,6 @@ public class FlowExecutor {
 
                 //支持多类型的配置文件,分别解析
                 if (BooleanUtil.isTrue(liteflowConfig.isSupportMultipleType())) {
-                    // 添加监听文件路径
-                    addMonitorFilePaths(ListUtil.toList(path));
                     // 解析文件
                     parser.parseMain(ListUtil.toList(path));
                 }
@@ -153,8 +151,6 @@ public class FlowExecutor {
             //进行多个配置文件的一起解析
             try {
                 if (parser != null) {
-                    // 添加监听文件路径
-                    addMonitorFilePaths(rulePathList);
                     // 解析文件
                     parser.parseMain(rulePathList);
                 } else {
@@ -189,7 +185,14 @@ public class FlowExecutor {
 
         // 文件监听
         if (liteflowConfig.getEnableMonitorFile()) {
-            MonitorFile.getInstance().create();
+            try{
+                addMonitorFilePaths(rulePathList);
+                MonitorFile.getInstance().create();
+            }catch (Exception e){
+                String errMsg = StrUtil.format("file monitor init error for path:{}", rulePathList);
+                throw new MonitorFileInitErrorException(errMsg);
+            }
+
         }
     }
 

+ 28 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/exception/MonitorFileInitErrorException.java

@@ -0,0 +1,28 @@
+
+package com.yomahub.liteflow.exception;
+
+/**
+ * 文件监听异常
+ * @author Bryan.Zhang
+ * @since 2.10.0
+ */
+public class MonitorFileInitErrorException extends RuntimeException {
+
+	private static final long serialVersionUID = 1L;
+
+	/** 异常信息 */
+	private String message;
+
+	public MonitorFileInitErrorException(String message) {
+		this.message = message;
+	}
+
+	@Override
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+}

+ 42 - 12
liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java

@@ -1,18 +1,31 @@
 package com.yomahub.liteflow.monitor;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.watch.SimpleWatcher;
 import cn.hutool.core.io.watch.WatchMonitor;
 import cn.hutool.core.io.watch.watchers.DelayWatcher;
 import cn.hutool.core.lang.Singleton;
 import com.yomahub.liteflow.core.FlowExecutorHolder;
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.HiddenFileFilter;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.io.monitor.FileAlterationListener;
+import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
+import org.apache.commons.io.monitor.FileAlterationMonitor;
+import org.apache.commons.io.monitor.FileAlterationObserver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
 import java.nio.file.Path;
 import java.nio.file.WatchEvent;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 /**
  * 规则文件监听器
@@ -22,7 +35,7 @@ import java.util.List;
 public class MonitorFile {
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
-    private final List<String> PATH_LIST = new ArrayList<>();
+    private final Set<String> PATH_SET = new HashSet<>();
 
     public static MonitorFile getInstance() {
         return Singleton.get(MonitorFile.class);
@@ -31,10 +44,15 @@ public class MonitorFile {
     /**
      * 添加监听文件路径
      *
-     * @param filePath 文件路径
+     * @param path 文件路径
      */
-    public void addMonitorFilePath(String filePath) {
-        PATH_LIST.add(filePath);
+    public void addMonitorFilePath(String path) {
+        if (FileUtil.isFile(path)){
+            String parentFolder = FileUtil.getParent(path, 1);
+            PATH_SET.add(parentFolder);
+        }else{
+            PATH_SET.add(path);
+        }
     }
 
     /**
@@ -43,22 +61,34 @@ public class MonitorFile {
      * @param filePaths 文件路径
      */
     public void addMonitorFilePaths(List<String> filePaths) {
-        PATH_LIST.addAll(filePaths);
+        filePaths.forEach(this::addMonitorFilePath);
     }
 
     /**
      * 创建文件监听
      */
-    public void create() {
-        for (String filePath : CollUtil.distinct(PATH_LIST)) {
-            WatchMonitor.createAll(filePath, new SimpleWatcher(){
+    public void create() throws Exception{
+        for (String path : PATH_SET) {
+            long interval = TimeUnit.MILLISECONDS.toMillis(2);
+            //不使用过滤器
+            FileAlterationObserver observer = new FileAlterationObserver(new File(path));
+            observer.addListener(new FileAlterationListenerAdaptor() {
+                @Override
+                public void onFileChange(File file) {
+                    logger.info("file modify,filePath={}", file.getAbsolutePath());
+                    FlowExecutorHolder.loadInstance().reloadRule();
+                }
+
                 @Override
-                public void onModify(WatchEvent<?> event, Path currentPath) {
-                    logger.info("file modify,filePath={}", filePath);
+                public void onFileDelete(File file) {
+                    logger.info("file delete,filePath={}", file.getAbsolutePath());
                     FlowExecutorHolder.loadInstance().reloadRule();
                 }
-            }).start();
+            });
+            //创建文件变化监听器
+            FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
+            // 开始监控
+            monitor.start();
         }
     }
-
 }

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclMultiSpringbootTest.java

@@ -33,6 +33,7 @@ public class MonitorFileELDeclMultiSpringbootTest extends BaseTest {
         String content = FileUtil.readUtf8String(absolutePath);
         String newContent = content.replace("THEN(a, b, c);", "THEN(a, c, b);");
         FileUtil.writeString(newContent,new File(absolutePath), CharsetUtil.CHARSET_UTF_8);
+        Thread.sleep(2500);
         LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
         Assert.assertEquals("a==>c==>b", response.getExecuteStepStr());
 

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclSpringbootTest.java

@@ -33,6 +33,7 @@ public class MonitorFileELDeclSpringbootTest extends BaseTest {
         String content = FileUtil.readUtf8String(absolutePath);
         String newContent = content.replace("THEN(a, b, c);", "THEN(a, c, b);");
         FileUtil.writeString(newContent,new File(absolutePath), CharsetUtil.CHARSET_UTF_8);
+        Thread.sleep(2500);
         LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
         Assert.assertEquals("a==>c==>b", response.getExecuteStepStr());
     }

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java

@@ -32,6 +32,7 @@ public class LiteflowMonitorFileTest extends BaseTest {
         String content = FileUtil.readUtf8String(absolutePath);
         String newContent = content.replace("THEN(a, b, c);", "THEN(a, c, b);");
         FileUtil.writeString(newContent, new File(absolutePath), CharsetUtil.CHARSET_UTF_8);
+        Thread.sleep(2500);
         LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
         Assert.assertEquals("a==>c==>b", response.getExecuteStepStr());
     }

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java

@@ -28,6 +28,7 @@ public class MonitorFileELSpringbootTest extends BaseTest {
         String content = FileUtil.readUtf8String(absolutePath);
         String newContent = content.replace("THEN(a, b, c);", "THEN(a, c, b);");
         FileUtil.writeString(newContent,new File(absolutePath), CharsetUtil.CHARSET_UTF_8);
+        Thread.sleep(2500);
         LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
         Assert.assertEquals("a==>c==>b", response.getExecuteStepStr());
     }

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java

@@ -34,6 +34,7 @@ public class MonitorFileELSpringbootTest extends BaseTest {
         String content = FileUtil.readUtf8String(absolutePath);
         String newContent = content.replace("THEN(a, b, c);", "THEN(a, c, b);");
         FileUtil.writeString(newContent,new File(absolutePath), CharsetUtil.CHARSET_UTF_8);
+        Thread.sleep(2500);
         LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
         Assert.assertEquals("a==>c==>b", response.getExecuteStepStr());
     }

+ 1 - 2
liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties

@@ -1,3 +1,2 @@
-#???monitorFile??????rule.xml???????????????????????
-liteflow.rule-source=monitorFile/rule.xml
+liteflow.rule-source=monitorFile/flow.el.xml
 liteflow.enable-monitor-file=true