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

This commit is contained in:
everywhere.z 2023-03-16 18:34:44 +08:00
parent e7b4c41ce9
commit 87295279c9
10 changed files with 88 additions and 19 deletions

View File

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

View File

@ -126,8 +126,6 @@ public class FlowExecutor {
//支持多类型的配置文件分别解析 //支持多类型的配置文件分别解析
if (BooleanUtil.isTrue(liteflowConfig.isSupportMultipleType())) { if (BooleanUtil.isTrue(liteflowConfig.isSupportMultipleType())) {
// 添加监听文件路径
addMonitorFilePaths(ListUtil.toList(path));
// 解析文件 // 解析文件
parser.parseMain(ListUtil.toList(path)); parser.parseMain(ListUtil.toList(path));
} }
@ -153,8 +151,6 @@ public class FlowExecutor {
//进行多个配置文件的一起解析 //进行多个配置文件的一起解析
try { try {
if (parser != null) { if (parser != null) {
// 添加监听文件路径
addMonitorFilePaths(rulePathList);
// 解析文件 // 解析文件
parser.parseMain(rulePathList); parser.parseMain(rulePathList);
} else { } else {
@ -189,7 +185,14 @@ public class FlowExecutor {
// 文件监听 // 文件监听
if (liteflowConfig.getEnableMonitorFile()) { 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);
}
} }
} }

View File

@ -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;
}
}

View File

@ -1,18 +1,31 @@
package com.yomahub.liteflow.monitor; package com.yomahub.liteflow.monitor;
import cn.hutool.core.collection.CollUtil; 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.SimpleWatcher;
import cn.hutool.core.io.watch.WatchMonitor; import cn.hutool.core.io.watch.WatchMonitor;
import cn.hutool.core.io.watch.watchers.DelayWatcher; import cn.hutool.core.io.watch.watchers.DelayWatcher;
import cn.hutool.core.lang.Singleton; import cn.hutool.core.lang.Singleton;
import com.yomahub.liteflow.core.FlowExecutorHolder; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.WatchEvent; import java.nio.file.WatchEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; 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 { public class MonitorFile {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); 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() { public static MonitorFile getInstance() {
return Singleton.get(MonitorFile.class); return Singleton.get(MonitorFile.class);
@ -31,10 +44,15 @@ public class MonitorFile {
/** /**
* 添加监听文件路径 * 添加监听文件路径
* *
* @param filePath 文件路径 * @param path 文件路径
*/ */
public void addMonitorFilePath(String filePath) { public void addMonitorFilePath(String path) {
PATH_LIST.add(filePath); 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 文件路径 * @param filePaths 文件路径
*/ */
public void addMonitorFilePaths(List<String> filePaths) { public void addMonitorFilePaths(List<String> filePaths) {
PATH_LIST.addAll(filePaths); filePaths.forEach(this::addMonitorFilePath);
} }
/** /**
* 创建文件监听 * 创建文件监听
*/ */
public void create() { public void create() throws Exception{
for (String filePath : CollUtil.distinct(PATH_LIST)) { for (String path : PATH_SET) {
WatchMonitor.createAll(filePath, new SimpleWatcher(){ long interval = TimeUnit.MILLISECONDS.toMillis(2);
//不使用过滤器
FileAlterationObserver observer = new FileAlterationObserver(new File(path));
observer.addListener(new FileAlterationListenerAdaptor() {
@Override @Override
public void onModify(WatchEvent<?> event, Path currentPath) { public void onFileChange(File file) {
logger.info("file modify,filePath={}", filePath); logger.info("file modify,filePath={}", file.getAbsolutePath());
FlowExecutorHolder.loadInstance().reloadRule(); 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();
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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