首页 > 解决方案 > 如果没有其他规则触发,如何在 Drools 中创建“最后一个”规则以撤回事件?

问题描述

我有两条规则:一条生成警报消息并将其附加到事件的字符串属性列表中(将来会有多个此类规则),另一条如果没有生成警报则撤回事件。

salience用于设置规则优先级(“最后一个”规则应该最后触发)。但是由于某些原因,规则顺序是错误的,因此警报列表仍然是空的,并且所有事件都被撤回。请在下面查看我的示例。

MainHello.scala

import org.json4s._
import org.json4s.jackson.Serialization.write
import org.kie.api.KieServices
import org.kie.api.builder.Message
import org.kie.internal.io.ResourceFactory

object MainHello {

  implicit val formats = DefaultFormats

  val events = List(
    new Event(123L, null, null),
    new Event(456L, null, null),
    new Event(789L, null, null),
    new Event(688723L, null, null),
    new Event(12L, null, null),
    new Event(13L, null, null))


  def main(args: Array[String]): Unit = {
    val kieService = KieServices.get()
    val repository = kieService.getRepository
    val kfs = kieService.newKieFileSystem

    kfs.write(ResourceFactory.newClassPathResource("hello.drl", this.getClass))

    val kb = kieService.newKieBuilder(kfs)

    kb.buildAll

    if (kb.getResults.hasMessages(Message.Level.ERROR)) {
      throw new RuntimeException("Build Errors:\n" + kb.getResults.toString)
    }

    val kContainer = kieService.newKieContainer(repository.getDefaultReleaseId)
    val session = kContainer.newKieSession()

    events.foreach { item =>
      println("INPUT OBJECT: " + write(item))
      val facthandle = session.insert(item)
      session.fireAllRules()
      println("result object:  " + write(session.getObject(facthandle)))
    }

  }
}

事件.java

import java.util.ArrayList;
import java.util.List;

public class Event implements java.io.Serializable {

    static final long serialVersionUID = 1L;

    private java.lang.Long event_id;
    private java.lang.String alert;
    private java.util.List<java.lang.String> alerts;

    public Event() {
    }

    public java.lang.Long getEvent_id() {
        return this.event_id;
    }

    public void setEvent_id(java.lang.Long event_id) {
        this.event_id = event_id;
    }

    public java.lang.String getAlert() {
        return this.alert;
    }

    public void setAlert(java.lang.String alert) {
        if (alerts == null) {
            alerts = new java.util.ArrayList<java.lang.String>();
        }
        alerts.add(alert);
        this.alert = alert;
    }

    public java.util.List<java.lang.String> getAlerts() {
        return this.alerts;
    }

    public void setAlerts(java.util.List<java.lang.String> alerts) {
        this.alerts = alerts;
    }

    public Event(java.lang.Long event_id, java.lang.String alert,
                 java.util.List<java.lang.String> alerts) {
        this.event_id = event_id;
        this.alert = alert;
        this.alerts = alerts;
    }

}

你好.drl

rule "alert"
when
  e: ru.test.Event(event_id == 123)
then
  modify(e) {
    setAlert("alert")
  }
end

rule "Retract" salience -1
when
  e: ru.test.Event (alerts == null || alerts.empty == true)
then
  retract(e);
end

控制台输出

INPUT OBJECT: {"event_id":12,"alert":null,"alerts":null}
result object:  null
INPUT OBJECT: {"event_id":13,"alert":null,"alerts":null}
result object:  null
INPUT OBJECT: {"event_id":123,"alert":null,"alerts":null}  // This object should not be retracted because "123" event_id generates alert
result object:  null

如您所见,所有事件都变为null.

Drools 版本是7.8.0.Final.

我究竟做错了什么?谢谢!

标签: droolsrule-enginekie

解决方案


推荐阅读