spring-mvc - 如果文件有任何更改,如何扫描 dtable drool 文件并使用 kiescanner drool 版本 7.4..final 再次加载它

标签 spring-mvc drools kie drools-kie-server

我正在使用 spring 处理 drool dtable xls 文件。 我已经使用外部位置在 xls 文件中实现了业务规则,然后在 kie 服务的帮助下我正在执行规则。 以下是我在引擎中加载规则的代码片段。 在 spring 初始化开始时我调用 init() 方法 请参阅下面的 Spring 配置。

<bean id="droolsService" class="com.example.drools.DroolsServiceImpl" init-method="init">

Java 代码

public void init() {
    LOG.info("inside init");
    KieSession kieSession;
    for (RequestType type : droolsMap.keySet()) {
        try {

            kieSession = getKieSession(this.getDroolsMap().get(type));
            droolsRules.put(type, kieSession);

        } catch (Exception e) {
            LOG.error("Failed to load kiesession:", e);
            throw new RuntimeException(e);
        }

    }

}


private KieSession getKieSession(final String file) throws DroolsParserException, IOException, BiffException {
    KieServices kieServices = KieServices.Factory.get();
    KieFileSystem kfs = kieServices.newKieFileSystem();

    InputStream stream = null;
    String drl = null;
    String RULE_PATH = "src/main/resources/";

    SpreadsheetCompiler converter = new SpreadsheetCompiler();

    //Workbook workbook = Workbook.getWorkbook(DroolsServiceImpl.class.getResourceAsStream(file));
    Workbook workbook = Workbook.getWorkbook(new FileInputStream(file));

    LOG.info("Loading rule file " + file);


    for (Sheet sheet : workbook.getSheets()) {
        LOG.info("Loading Sheet " + sheet.getName());
        stream = new FileInputStream(file);
        drl = converter.compile(stream, sheet.getName());
        //StringReader reader = new StringReader(drl);
        String DRL_FILE = RULE_PATH + sheet.getName() + ".drl";
        System.out.println("Drool file added ::: " + DRL_FILE);
        kfs.write(DRL_FILE, ResourceFactory.newReaderResource(new StringReader(drl)));
        stream.close();
    }

    KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
    KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
    KieSessionConfiguration conf = SessionConfiguration.newInstance();
    KieSession ksession = kieContainer.newKieSession(conf);
    if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) {
        List<Message> errors = kieBuilder.getResults().getMessages(Message.Level.ERROR);
        StringBuilder sb = new StringBuilder("Errors:");
        for (Message msg : errors) {
            sb.append("\n  " + msg);
        }
        try {
            throw new Exception(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stream != null)
                stream.close();
            if (workbook != null)
                workbook.close();
        }
    }
    return ksession;
}

一切正常,但问题是我无法扫描文件更改。如果文件被修改,那么我必须重新启动服务器才能同步更改。

我尝试在 xls dtable 发生任何更改后监听器加载特定的 init() 方法,但它不起作用,相同的旧结果即将到来。

我尝试过 kiescanner,但我无法理解这个概念。 KieScanner 正在加载 Maven kjar,那么我该如何创建 kjar。

我只是想 kie api 扫描 drool 文件中是否有任何更改,并尝试在不重新启动服务器的情况下重新加载 kiecontainer 中的全部更改。

最佳答案

我自己找到了答案,发帖是因为它会帮助需要的人。

我做了什么,我使用了 apache VFS 文件监视器 -

DefaultFileMonitor fm = new DefaultFileMonitor(new CustomFileListener());

当文件被修改、创建或删除时,它将调用 CustomFileListener。

以下是CustomFileListener的实现。

import org.apache.commons.vfs2.FileChangeEvent;
import org.apache.commons.vfs2.FileListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.support.XmlWebApplicationContext;

public class CustomFileListener implements FileListener {

private static final Logger LOG = LoggerFactory.getLogger(CustomFileListener.class);

@Override
public void fileCreated(FileChangeEvent fileChangeEvent) throws Exception {

}

@Override
public void fileDeleted(FileChangeEvent fileChangeEvent) throws Exception {

}

@Override
public void fileChanged(FileChangeEvent fileChangeEvent) throws Exception {


    LOG.debug(" Under FileChanged Method");
    LOG.debug(" File has been changed hence reinitializing init method = " + fileChangeEvent.getFile().getName().getPath());
    XmlWebApplicationContext xmlWebApplicationContext =
            (XmlWebApplicationContext) ContextLoader.getCurrentWebApplicationContext();
    DefaultListableBeanFactory defaultListableBeanFactory =
            (DefaultListableBeanFactory) xmlWebApplicationContext.getBeanFactory();
    DroolsServiceImpl droolsService = (DroolsServiceImpl) defaultListableBeanFactory.getBean("droolsService");
    droolsService.init();
}

}

当文件发生更改时我做了什么,它将调用 fileChanged 方法。

因为我已经从 ContextLoader.getCurrentWebApplicationContext(); 获取了缓存的 bean(DroolServiceImpl) 并调用了它的 init() 方法。

因此它将重新加载整个过程并重新初始化 KieModule、KieRepository。

关于spring-mvc - 如果文件有任何更改,如何扫描 dtable drool 文件并使用 kiescanner drool 版本 7.4..final 再次加载它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48908309/

相关文章:

java - Spring MVC 缺少静态资源

java - java 构建速度慢,我喜欢进行小的增量更改并在浏览器中查看页面

java - 通过 spring rest 模板获取异常的堆栈跟踪

grails - Grails:插件:Drools vs Drools-Gorm

java - 将规则添加到现有的 KiePackage 和 KieBase 中

java - jBPM 和 JPA 事务管理器 : no local transaction to join

java - 无法 Autowiring Spring

drools - 如何编辑和更新 Drools 规则文件?

git - 推送到从 KIE Workbench 存储库克隆的 git 存储库

java - 如何顺序地为同一类型的事实编写规则?