2016-08-01 3 views
2

Hinweis: Dies verwendet die aktuelle 6.4.0.Finale Implementierung der Kie-Bibliothek.Externe DRL-Datei, die in mehrere KieBase-Instanzen geladen wird

Hey da. Ich versuche, Drools so zu benutzen, dass ich nicht viele Informationen online finde (oder ich suche nur die falschen Dinge, aber ich habe es schon seit ein paar Tagen versucht), also würde ich gerne einen fragen Frage zu meinem Anwendungsfall hier.

möchte ich mehrere KieBase Instanzen erstellen, wie ich das ist das ‚Niveau‘ annehmen sollte ich dies auf sein Umgang, dass jeder ihre eigenen abgeschiedenen Satz von vorab generierten Regeln auf Gebäude haben, irgendwo nicht in den Ordner Ressourcen (In diesem Moment der Stammordner der Anwendungsbereitstellung).

Also, wenn ich mehrere Instanzen des gleichen Objekts A, B oder C habe. Sie können alle unterschiedliche Eigenschaften und damit unterschiedliche Regeln pro Objekt haben.

Ich dachte, dass die Erstellung eines Ordners, in diesem Fall ./rules mit Unterordnern für jedes Ereignis wäre ein guter Ansatz hier. Jedes Mal, wenn ein Objekt erstellt wird, wird ein relativer Ordner in diesem Ordner ./rules erstellt.

  • ./rules/A/ für Objekt A.
  • ./rules/B/ für Objekt B.
  • ./rules/C/ für Objekt C.

Dann durch andere Mittel, erzeuge ich DRL-Dateien in diese Unterordner im Wesentlichen – mich korrigieren wenn ich falsch liege – Pakete erstellen. Jetzt

, wenn ich in den Teilobjekten für Objekt A beginnen Hinzufügen, würde Ich mag nur die Regeln innerhalb des ./rules/A Ordner auf sie anzuwenden.

Also habe ich die folgende Belastungsklasse geschrieben, online die folgenden Beispiele, würde Ich mag eine KieBase Instanz laden speziell auf die Regel-Dateien laden ich zu einem bestimmten Objekte Ordner hinzugefügt haben:

private KieBase loadKieBase(String identifier) { 
    KieServices kieServices = KieServices.Factory.get(); 
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); 

    List<String> drlFiles = fileHandler.loadFiles(identifier); 

    for (String drl : drlFiles) { 
     String path = "src/main/resources/drools/" + drl; 
     Resource resource = ResourceFactory.newFileResource(drl); 
     kieFileSystem.write(path, resource); 
    } 

    KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem); 
    kieBuilder.buildAll(); 
    Results results = kieBuilder.getResults(); 

    if (results.hasMessages(Message.Level.ERROR)) { 
     ... 
    } 

    KieContainer kieContainer = kieServices.newKieContainer(kieBuilder.getKieModule().getReleaseId()); 
    KieBaseConfiguration kieBaseConfiguration = kieServices.newKieBaseConfiguration(); 
    KieBase kieBase = kieContainer.newKieBase(kieBaseConfiguration); 
    return kieBase; 
} 

Logging enthüllt mir, dass die Ressourcen korrekt geladen werden, was bedeutet, dass die kieFileSystem.write(...) Zeile ein gültiges Resource Argument bekommt. Das Drucken der geladenen Datei enthält auch die Dateien, die ich für das Objekt sehen möchte, für das ich die Dateien angefordert habe. Dieser Teil funktioniert also. Allerdings bekomme ich die folgende Warnung:

WARN o.d.c.k.b.impl.AbstractKieModule - No files found for KieBase defaultKieBase

Es scheint in der Tat keine Dateien in die src/main/resources/drools/ Ordner geschrieben werden, die ich in meinen Ressourcen gemacht habe. Ich halte das nicht einmal für notwendig – sollten sie nicht sowieso einfach in den Speicher geladen werden? Warum die Notwendigkeit, sie wieder zu schreiben, wenn ich sie von ihren vorgenerierten Dateipositionen laden kann?

Könnte das vielleicht meine kmodule.xml Datei sein, die inkorrekt ist (eher – sollte ich sogar eine haben, wenn ich KieBases grundsätzlich im Speicher verwenden möchte? Meiner Meinung nach macht es keinen Sinn, diese 'physische' Referenz zu haben ein Wissenspaket, das Sie im laufenden Betrieb erstellen ...)?Dies ist die Datei als Referenz:

<?xml version="1.0" encoding="UTF-8"?> 
<kmodule 
    xmlns="http://jboss.org/kie/6.0.0/kmodule" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

    <kbase name="KnowledgeBase" packages="drools"> 
     <ksession name="KnowledgeSession"></ksession> 
    </kbase> 
</kmodule> 

Könnte dies korrekt sein, stoße ich als nächstes ein anderes Problem, das verwandt sein könnte.

Meine erzeugt DRL-Dateien verwenden Sie die folgende Vorlage für die ‚Header‘ der Datei:

package drools 

import org.droolstest.TestTicket 

global org.slf4j.Logger logger 

rule "same-ticket" 
    ... 
end 

Nach dem ich versuche, die folgenden Aufrufe zu verwenden:

KieBase kieBase = loadKieBase(eventToken); 
KieSession kieSession = kieBase.newKieSession(); 
kieSession.setGlobal("logger", logger); 

, die die Anwendung geben abstürzt mir diese Ausnahme:

INFO o.d.c.k.b.impl.KieRepositoryImpl - KieModule was added: MemoryKieModule[releaseId=org.default:artifact:1.0.0-SNAPSHOT] 
INFO c.p.a.c.m.r.RuleGroupClusterModule - KieBase: [email protected] 
INFO c.p.a.c.m.r.RuleGroupClusterModule - KieSession: KieSession[0] 
Exception in thread "Thread-4" java.lang.RuntimeException: Unexpected global [logger] 
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1162) 

Das verwirrt mich auch. Ich nehme an, die KieBase hat die Datei nicht korrekt geladen, oder so ähnlich (weshalb ich den riesigen Aufbau für dieses Problem eingefügt habe – Es tut mir leid, ich habe nur keine Ahnung, wo die Ursache meines Problems liegt) .

Ich finde es wirklich schwer, meinen Kopf einzuwickeln, was mein Problem hier sein könnte – abgesehen von der kmodule.xml Datei scheint alles gut, oder? So würde jede Form der Hilfe sehr geschätzt werden! :)

Vielen Dank im Voraus!

PS: Ein plötzlicher Blick auf die Ähnliche Fragen hat mich über this thread informiert. Es scheint sehr ähnlich zu sein, aber ich glaube nicht, dass ich die Dateien im Ressourcen-Ordner erzeugen möchte, was die Selbst-Antwort um mich herum zu drehen scheint.

+1

Ihr bester Plan die Einbeziehung sein könnte * alle * DRL-Dateien in der Last-und-Kompilierung Code in Ihrer Methode 'loadKieBase'. Der Fehler, den Sie erhalten, legt nahe, dass das DRL, in dem der globale Logger deklariert ist, nicht im Build dieser KieBase enthalten ist - stellen Sie daher sicher (indem Sie explizit auf das KIE-Dateisystem schreiben). – laune

+0

Danke für den Kommentar. Im Moment habe ich nur 1 Test 'Unterordner' mit 1 Regeldatei. Ich bin mir ziemlich sicher, dass geladen wird und die in einem Aufruf der kieFileSystem.write() -Methode verwendet wird. Könnte ich das Kompilieren von Komponenten oder etwas ähnliches vermissen? Es scheint nirgendwo Fehler zu haben, obwohl ich alles eingerichtet habe. Sie scheinen auch der Autor von [diese Antwort] zu sein (http://stackoverflow.com/a/24570355/5347955), was der Ansatz zu sein scheint, den ich auch versucht habe, also wirklich, warum konnte dieses Laden falsch gehen, andere als DRL Dateikompilierungsprobleme? – Xheory

+0

Der Ansatz, den ich in "diese Antwort" beschrieben habe, funktioniert und es wird dir sagen, ob es Fehler im DRL gibt. Es besteht natürlich immer die Möglichkeit, dass Sie einen weiteren Fehler gemacht haben. - Um zu erfahren, ob DRLs aus dieser oder jener Datei korrekt geladen sind, verwenden Sie nur eine Regel pro DRL-Datei: 'rule 'in DRL x.drl, wenn dann System.out.println (...); Ende. – laune

Antwort

1

Ich denke, dass in der Tat gibt es einen Konflikt zwischen Ihrem Weg, um kiebase (programmgesteuert) mit der kmodule.xml zu konfigurieren. Haben Sie versucht, ohne die kmodule.xml zu kompilieren und zu laufen? Die vernünftigste Erklärung für mich ist, dass die Kiebase in XML Vorrang vor den anderen hat. Ich denke auch, dass dies für Sie nützlich sein kann:

http://planet.jboss.org/post/configuration_and_convention_based_building_and_utilization

Verwandte Themen