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

How to scan dtable drool file if there is any changes in file and load it again using kiescanner drool version 7.4..final

我正在使用 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。

我只是想 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。