diff --git a/liteflow-core/pom.xml b/liteflow-core/pom.xml index 537f03d64..c93d6578d 100644 --- a/liteflow-core/pom.xml +++ b/liteflow-core/pom.xml @@ -50,5 +50,9 @@ commons-beanutils commons-beanutils + + commons-io + commons-io + 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 655f1abef..2711c7538 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 @@ -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); + } + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/MonitorFileInitErrorException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/MonitorFileInitErrorException.java new file mode 100644 index 000000000..5194de01d --- /dev/null +++ b/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; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java b/liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java index cfbb5e206..cff488e6b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/monitor/MonitorFile.java +++ b/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 PATH_LIST = new ArrayList<>(); + private final Set 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 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 onModify(WatchEvent event, Path currentPath) { - logger.info("file modify,filePath={}", filePath); + public void onFileChange(File file) { + logger.info("file modify,filePath={}", file.getAbsolutePath()); FlowExecutorHolder.loadInstance().reloadRule(); } - }).start(); + + @Override + public void onFileDelete(File file) { + logger.info("file delete,filePath={}", file.getAbsolutePath()); + FlowExecutorHolder.loadInstance().reloadRule(); + } + }); + //创建文件变化监听器 + FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer); + // 开始监控 + monitor.start(); } } - } diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclMultiSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclMultiSpringbootTest.java index 9dfaeb2c9..87405f5c7 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-declare-multi-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclMultiSpringbootTest.java +++ b/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()); diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclSpringbootTest.java index 7f3e2f5e0..8e9973682 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELDeclSpringbootTest.java +++ b/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()); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java index 2b4a509d7..b8a7a55ba 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/monitorFile/LiteflowMonitorFileTest.java +++ b/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()); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java index 687cb14a4..04e060c66 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java +++ b/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()); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java index 164b1fd39..a4366b972 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java +++ b/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()); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties index 453d42ecd..361f7e90e 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/monitorFile/application.properties +++ b/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 \ No newline at end of file