我们在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正在 Boot 级别初始化,即)奇怪的是,当运行kieSession.fireallrules()
时,触发的规则总数总是0,事实并没有更新。
使用Akka,我们通过REST发送JSON格式的对象(类型为MyObject)。每个REST请求都会创建一个actor,并调用Drools模块,如下所示:
- 创建一个新的参与者来调用Drools引擎。
- 使用在 Boot 级别设置的KieServices创建新的KieSession。[对于那些看过我以前的帖子的人,是的,下面是Scala代码]
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()
- 然后通过
ksession.insert(testObject)
将通过REST接收到的对象(从JSON格式中提取)加载到DroolsMemory中,并保存对象的FactHandle - 然后触发规则,并使用其FactHandle返回更新的对象,如下所示:
ksession.fireAllRules() val getObject = ksession.getObject(myObjectFH) ksession.dispose() getObject.asInstanceOf[MyObject]
和以前一样,这在单独运行Drools模块时有效,但在使用如上所述的actor系统时无效。我甚至尝试过触发空规则并将文本打印到屏幕上以进行调试,但实际上没有触发任何规则。我确信我调用的是正确的DRL文件和正确的KieSession,但我不知道这里出了什么问题。(有没有办法检查KieSession中的规则数量?)
有什么想法吗
编辑:在研究了laune的建议后,我发现没有任何KiePackages被加载到KieBase中。我已经将范围缩小到没有作为KieResources在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()
1条答案
按热度按时间slsn1g291#
下面的代码不会解决您的问题,但它应该可以帮助您诊断您是否真的运行了您认为正在运行的规则和会话。我用的是Java符号。