Как отсканировать файл dtable drool, если в файле есть какие-либо изменения, и загрузить его снова, используя kiescanner drool version 7.4..final
Я работаю над файлом drools dtable xls с пружиной. я реализовал бизнес-правила в файле xls, используя внешнее местоположение, а затем с помощью служб kie выполняю правила. Ниже приведен фрагмент кода, как я загружаю правила в движок. в начале инициализации пружины я вызываю метод init(), см. ниже конфигурацию пружины.
<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;
}
Все работает отлично, но проблема в том, что я не могу сканировать изменения файла. Если файлы изменены, то я должен перезагрузить сервер, чтобы синхронизировать изменения.
Я попытался слушатель загрузить конкретный метод init() после каких-либо изменений в xls dtable, но он не работает, приходит тот же старый результат.
Я попробовал kiescanner, но я не в состоянии понять концепцию. KieScanner загружает maven kjar, так как мне создать kjar?
Я просто хотел проверить ki api, если в файле drool есть изменения, и попытаться перезагрузить все изменения в kiecontainer без перезапуска сервера.
1 ответ
Нашел ответ сам, выложив, потому что это поможет кому-то, кому нужно.
Что я сделал, я использовал apache VFS File Monitor-
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.
Я выбрал кэшированный компонент (DroolServiceImpl) из ContextLoader.getCurrentWebApplicationContext(); и вызвал его метод init().
Так что это перезагрузит весь процесс и переинициализирует KieModule,KieRepository.