2012-05-31 16 views
8

Ich beginne ein Projekt mit Drools and Drools Guvnor.Drools deaktivieren eine Regel zur Laufzeit

Meine Regeln werden in drools guvnor eingesetzt. Meine Regel-Engine-Instanz kann auf diese Regeln über die pkg-Datei zugreifen, die von Drools Guvnor angezeigt wird, wenn Sie eine Paketversion erstellen und veröffentlichen.

Das ist alles in Ordnung, was ich suche ist eine Lösung zum Deaktivieren einer Regel zur Laufzeit.

Die einzige Lösung, die ich gerade habe, ist, nach Guvnor zu gehen, die Regel zu archivieren und ein Build + Release des Pakets zu erstellen, das diese Regel enthält.

Gibt es keine andere Strategie?

Antwort

5

Es gibt ein paar Möglichkeiten, dies zu lösen, je nach Ihren Anforderungen und Architektur.

  • Eine Möglichkeit ist, jede Teilmenge der Regeln in verschiedenen guvnor Pakete zu definieren. Wenn Sie Ihre kbase erstellen, können Sie nur die Pakete mit den Regeln laden, die Sie speziell für diese kbase möchten.

  • Eine andere Möglichkeit ist, immer alle Regeln zu laden, aber verwenden Sie einen "aktivierten" Ausdruck dynamisch Regeln aktivieren/deaktivieren. Bitte beachten Sie, dass die Regeln in diesem Fall noch ausgewertet werden, jedoch verhindert werden können, dass sie aktiviert werden. Dies ist eine nützliche Methode für Fälle, in denen Sie Regeln basierend auf den Fakten aktivieren/deaktivieren möchten, die Sie in Ihre Sitzung einfügen. ZB:

    Regel X aktiviert() dann ...

    Der Boolesche Ausdruck hat über den Zugriff auf die Variablenbindungen aus dem Zustand der Regel sowie Regel Attribute, Anmerkungen und natürlich können Sie greifen Sie auch auf statische Methoden in Hilfsklassen zu, wenn Sie die Bedingungen zum Aktivieren der Regel außerhalb der DRL-Datei definieren möchten.

  • Eine dritte Möglichkeit, dies zu tun ist mit Hilfe von Agenda-Filter. In diesem Fall laden Sie alle Ihre Regeln, erstellen die Sitzung mit den Fakten und verwenden bei der Ausführung der Regeln einen Agenda-Filter. Ein Agendafilter ist eine Schnittstelle, die Sie selbst implementieren können, oder Sie können einige der Filter verwenden, die mit Drools ausgeliefert werden. Der Filter wird aufgerufen, bevor jede Regel ausgelöst wird, und kann dann das Veto einlegen oder zulassen, dass die Engine die Regel ausführt. Bitte beachten Sie, dass in diesem Fall alle Regeln ausgewertet und aktiviert werden, aber nur die Regeln ausgelöst werden, die der Filter auslösen darf. Wenn Sie beispielsweise nur die Regeln auslösen möchten, die einen Namen haben, der mit "X" beginnt, können Sie die folgende Codezeile verwenden:

    ksession.fireAllRules (neuer RuleNameStartsWithAgendaFilter ("x"));

    Für mehr Informationen, hier ist die Schnittstelle:

    https://github.com/droolsjbpm/droolsjbpm-knowledge/blob/master/knowledge-api/src/main/java/org/drools/runtime/rule/AgendaFilter.java

    Hier ist die Dokumentation (Scrollen Sie zum Thema 3.3.3.4.1):

    http://docs.jboss.org/drools/release/5.4.0.Final/drools-expert-docs/html_single/index.html#d0e2792

+0

Danke, eigentlich habe ich die zweite Möglichkeit versucht, wie Sie vorgeschlagen, wie auf dieser Blogpost erläutert: http://fusionspan.blogspot.com/2012/02/jboss-drools-disabling -bestimmt-rules.html. Es funktionierte gut, wenn meine Regeln aus dem Dateisystem geladen wurden, aber nicht, wenn die Regel in Guvnor bereitgestellt wurde. In diesem Fall hatte ich eine NPE: java.lang.NullPointerException bei org.drools.base.mvel.MVELCompilationUnit.createFactory (MVELCompilationUnit.java:262) bei org.drools.base.mvel.MVELCompilationUnit.getFactory (MVELCompilationUnit .java: 276) –

+0

Das ist ein Fehler. Es sollte gleich funktionieren, egal wo es geladen wird. Es wäre großartig, wenn Sie ein Ticket mit Ihrem Problem öffnen könnten, damit es repariert werden kann. –

+0

Fehler im jboss issue tracker erstellt: https://issues.jboss.org/browse/GUVNOR-1904 –

0

Sie können die Existenz einiger Fakten im Arbeitsspeicher hinzufügen. Etwas wie:

rule "RuleA" 
when 
    not(RuleADisabled()) 
    .... 
then 
    .... 
end 

und die Regel in Java-Code deaktivieren:

ksession.insert(new RuleADisabled()); 
+0

Dank , aber das bedeutet, dass ich für jede neue Regel eine neue Art von Fakt RuleNameDisabled erstellen muss. Jedes Mal, wenn ich meine Regeln ausführen werde, muss ich zuerst die deaktivierten Regelfakten einfügen. –

+0

Sie können nur eine Art von Fakt erstellen, z. RuleDisabled mit dem Attribut ruleName oder mehreren Regeln kann von derselben Tatsache abhängen, z. nicht (RuleDisabled (group == "groupX")) –