2014-12-19 18 views
7

Kurz gesagt, ich möchte Regeln erstellen, bearbeiten und löschen aus einem Regel-Repository zur Laufzeit. Ich habe Probleme herauszufinden, wie man das in Drools 6+ macht.Was ist die neue akzeptierte Methode, neue Drools-Regeln in Drools 6 programmatisch zu erstellen?

Ich weiß in einer früheren Version von Drools (< = 5.6), dass es eine XML-Darstellung einer .drl-Datei und eine API zum Arbeiten mit ihm gab: https://docs.jboss.org/drools/release/5.6.0.Final/drools-expert-docs/html/ch04.html#d0e8052.

Die Drools-Dokumentation ab 5.6 weist darauf hin, dass dies veraltet ist und bei 6 vollständig entfernt zu werden scheint. Ich möchte keine API verwenden, von der bereits bekannt ist, dass sie keinen direkten Upgradepfad enthält.

Das Freilegen der Benutzeroberflächen von Guvnor oder Workbench zur Bearbeitung von Regeln ist aufgrund der Workflowanforderungen und der Komplexität der Webbenutzerschnittstellen ebenfalls nicht geeignet. Ich möchte die Regeln aus Java-Code erstellen und verwalten.

Ich möchte eine bessere Methode als String-Templating zu einer .drl-Datei zum Erstellen neuer Regeln und Ändern von Regeln. Was gibt es zum programmatischen Erstellen neuer Regeln aus Java? Ich habe viele Suchen durchgeführt, aber ich kann anscheinend keine Java-API-Aufrufe dafür finden.

Antwort

1

Es gibt keine stabile API für Bauvorschriften aus Java-Code. Es gibt natürlich eine API für den Parser des DRL-Compilers, aber sie ist nicht stabil und so komplex wie die DRL-Regelsyntax, was beträchtlich ist.

XML war eine Option, bei der zumindest die Linksyntax einfach genug war und mit 5,2 (IIRC) endete. Jetzt können Sie die vollständige Ausdruckssyntax von Java und mehr verwenden, kombiniert mit den vielen verschiedenen Möglichkeiten zum Erstellen von CEs.

Wenn Ihre Regeln außergewöhnlich einfach sind, könnten Sie ein Modell für Regeln entwickeln, das mit einer verwaltbaren API manipuliert werden könnte. Ansonsten ist Ihre beste Wette ein Texteditor (oder natürlich die Kie Workbench).

1

Die integrierte Möglichkeit zum programmgesteuerten Erstellen von Regeln basiert auf einer "Descr" -Flüssigkeits-API, die den AST des Compilers unter Umgehung des Parsers direkt manipuliert ( ).

finden Sie in der Klasse org.drools.compiler.lang.api.DescrFactory

und die Klasse org.drools.compiler.lang.DrlDumper eine DRL Annäherung aus dem AST abzurufen.

+0

Ok, aber wie bewerten Sie den eingebauten PackageDescr? – Esk

6

Ich weiß nicht, ob dies der ‚akzeptiert‘ Art und Weise ist, aber mit dem folgenden Code comine ich .drl Dateien mit programmatisch erstellt Regeln in geifert 6.

public KieContainer build(KieServices kieServices) { 
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); 
    ReleaseId rid = kieServices.newReleaseId("com.example.rulesengine", 
     "model-test", "1.0-SNAPSHOT"); 
    kieFileSystem.generateAndWritePomXML(rid); 

    kieFileSystem.write("src/main/resources/rules.drl", 
     getResource(kieServices, "rules.drl")); 

    addRule(kieFileSystem); 

    KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem); 
    kieBuilder.buildAll(); 
    if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) { 
     throw new RuntimeException("Build Errors:\n" + 
      kieBuilder.getResults().toString()); 
    } 

    return kieServices.newKieContainer(rid); 
} 

private void addRule(KieFileSystem kieFileSystem) { 
    PackageDescrBuilder packageDescrBuilder = DescrFactory.newPackage(); 
    packageDescrBuilder 
      .name("com.example.model") 
      .newRule() 
      .name("Is of valid age") 
      .lhs() 
      .pattern("Person").constraint("age < 18").end() 
      .pattern().id("$a", false).type("Action").end() 
      .end() 
      .rhs("$a.showBanner(false);") 
      .end(); 

    String rules = new DrlDumper().dump(packageDescrBuilder.getDescr()); 
    kieFileSystem.write("src/main/resources/rule-1.drl", rules); 
} 

private Resource getResource(KieServices kieServices, String resourcePath) { 
    try { 
     InputStream is = Resources.getResource(resourcePath).openStream(); //guava 
     return kieServices.getResources() 
        .newInputStreamResource(is) 
        .setResourceType(ResourceType.DRL); 
    } catch (IOException e) { 
     throw new RuntimeException("Failed to load drools resource file.", e); 
    } 
} 

verwende ich die Guava Klasse Ressourcen.

+0

Wow, dass DescFactory API für dynamische Regelbildung so cool und flexibel scheint. Nur, was ist der Anwendungsfall dafür? Warum würden Sie eine dynamische Regel in Java erstellen? Ist es nicht wichtig, dass die DRL-Regel überhaupt externalisiert wird? –

+0

Es wäre nützlich, wenn ein vorhandener Satz von Regeln in DRL-Dateien migriert wird. Das versuche ich gerade zu erreichen. – nixnayak