Drools 规则不从 Akka actor 系统触发

Drools rules not firing from Akka actor system

我们在 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 在引导级别初始化,即在创建演员之前,并在稍后阶段使用。)奇怪的是,当 运行 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()

和以前一样,这在 运行 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()

以下代码不会解决您的问题,但它应该可以帮助您诊断您是否确实 运行 您认为的规则和会话。我正在使用 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() );
    }
}