我们在Scala中构建了一个Drools模块,当单独调用时运行得很好,但现在我们将它集成到我们构建的Akka actor系统中,以便能够通过REST启动规则调用
出于某种原因,没有任何规则可以解雇,甚至是空白规则,例如:
rule "sample 1"
salience 1000
auto-focus true
when
then
System.out.println("Well, that finally worked!");
end
KieContainer,Session等似乎没问题,并且正确插入了对象(事实)(通过检查事实计数来验证)。 (KieServices和KieContainer正在启动级别初始化,即在创建actor之前,并在稍后阶段使用。)奇怪的是,当运行kieSession.fireallrules()
时,触发的规则总数始终为0并且事实没有更新。
使用Akka,我们通过REST以JSON格式发送一个对象(MyObject类型)。每个REST请求都会创建一个actor,并按如下方式调用Drools模块:
val kieSession = DroolsMgt.getKieSession(List("myFile.drl"), Boot.kieServices)
其中getKieSession
正在调用以下内容:
val kfs = kieServices.newKieFileSystem()
for (filename <- drlFiles) {
val fis = new FileInputStream(filename)
kfs.write(filename, kieServices.getResources.newInputStreamResource(fis))
}
val kieBuilder = kieServices.newKieBuilder(kfs).buildAll()
val kieContainer = kieServices.newKieContainer(kieServices.getRepository.getDefaultReleaseId)
kieContainer.newKieSession()
然后通过REST(从JSON格式中提取)接收的对象通过ksession.insert(testObject)
加载到Drools Memory中,并保存对象的FactHandle
然后触发规则并使用其FactHandle返回更新的对象,如下所示:
ksession.fireAllRules()
val getObject = ksession.getObject(myObjectFH)
ksession.dispose()
getObject.asInstanceOf[MyObject]
和以前一样,这可以在运行Drools模块时自行运行,但在使用上述actor系统时则不行。我甚至尝试触发空规则并将文本打印到屏幕上以进行调试,但实际上并没有触发任何规则。我确信我正在调用正确的DRL文件和正确的KieSession,但无法弄清楚这里出了什么问题。 (有没有办法检查KieSession中的规则数量?)
有什么想法吗?
编辑:
在查看了laune的建议之后,我发现没有任何KiePackages被加载到KieBase中。我已将此范围缩小到未在kfs.write("src/main/resources/testFile.drl", kieServices.getResources().newInputStreamResource(fis))
知道可能导致这种情况的原因吗?
作为参考,我将DRL文件加载到KieContainer并创建KieSession(成功),如下所示:
val kieServices = KieServices.Factory.get()
val kfs = kieServices.newKieFileSystem()
val fis = new FileInputStream("src/main/resources/testFile.drl")
kfs.write("src/main/resources/testFile.drl", kieServices.getResources().newInputStreamResource(fis))
val kieBuilder = kieServices.newKieBuilder(kfs).buildAll()
val results = kieBuilder.getResults()
if (results.hasMessages(Message.Level.ERROR)) {
throw new RuntimeException(results.getMessages().toString())
}
val kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId())
kieContainer.newKieSession()
答案 0 :(得分:2)
以下代码不会解决您的问题,但它可以帮助您诊断您是否真正运行规则以及您认为自己执行的会话。我正在使用Java表示法。
KieSession kieSession = ...
KieBase kieBase = kieSession.getKieBase();
Collection<KiePackage> kiePackages = kieBase.getKiePackages();
for( KiePackage kiePackage: kiePackages ){
for( Rule rule: kiePackage.getRules() ){
System.out.println( rule.getName() );
}
}