2016-04-08 7 views
4

Ich versuche, von Drools 5.x auf 6.x zu aktualisieren und die Dinge so einfach wie möglich zu halten. Die neuen kie APIs machen diese einfache Aufgabe schwierig.Wie funktioniert die neue Drools 6.x KIE API?

Nach vielen Versuchen gelang es mir, das Standard-Drools 5.x-Beispiel in das 6.x-Äquivalent umzuwandeln. Beachten Sie, dass ich absichtlich XML-Konfigurationsdateien, Dependency-Injection usw. vermieden habe, aber einige Passagen immer noch nicht verstehe.

Ich schließe beide Versionen der Anwendung ein, um möglicherweise anderen Menschen zu helfen, die das gleiche Problem haben, das ich hatte.

Der folgende Code ist mehr oder weniger das, was wir in geifert 5.x zu tun verwendet wurden:

// Obtain a builder for knowledge base 
KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 

// Load a DRL resource from src/main/resources into the builder 
String location = "/drools/HelloWorld.drl"; 
InputStream stream = getClass().getResourceAsStream(location); 
Resource resource = ResourceFactory.newInputStreamResource(stream); 
builder.add(resource, ResourceType.DRL); 

// Check for errors, print them and stop if any 
if (builder.hasErrors()) { 
    for (KnowledgeBuilderError error : builder.getErrors()) { 
     System.out.println(error); 
    } 
    System.exit(0); 
} 

// Create a new knowledge base out of the builder 
KnowledgeBase base = KnowledgeBaseFactory.newKnowledgeBase(); 
base.addKnowledgePackages(builder.getKnowledgePackages()); 

// Start a new working session 
StatefulKnowledgeSession session = base.newStatefulKnowledgeSession(); 

// Inject a new message object into the session 
final Message message = new Message(); 
message.setMessage("Hello World"); 
message.setStatus(Message.HELLO); 
session.insert(message); 

// Apply the rules in the knowledge base to the objects in the session 
session.fireAllRules(); 

// Close the working session 
session.dispose(); 

Seit geifert 6.x KnowledgeBase worden ist veraltet, so wird es wahrscheinlich Phase aus der Code-Basis in in naher Zukunft, gezwungen, die neuen APIs zu verwenden. Das obige Beispiel in geifert 6.x wird:

// Get access to Drools services 
KieServices services = KieServices.Factory.get(); 

// Obtain a new empty virtual file system 
KieFileSystem fileSystem = services.newKieFileSystem(); 

// Load a DRL resource from src/main/resources into the virtual file system 
// The prefix 'src/main/resources' is required since Drools 6.2.x 
String location = "/drools/HelloWorld.drl"; 
InputStream stream = getClass().getResourceAsStream(location); 
Resource resource = ResourceFactory.newInputStreamResource(stream); 
fileSystem.write("src/main/resources" + location, resource); 

// Convert the files in the virtual file system into a builder 
KieBuilder builder = services.newKieBuilder(fileSystem).buildAll(); 

// Check for errors, print them and stop if any 
Results results = builder.getResults(); 
if (results.hasMessages(ERROR)) { 
    System.out.println(results.getMessages()); 
    System.exit(0); 
} 

// Create a new kie base out of a repository and a container 
KieRepository repository = services.getRepository(); // <---= HERE! 
KieContainer container = services.newKieContainer(repository.getDefaultReleaseId()); 
KieBase base = container.getKieBase(); 

// Start a new working session 
KieSession session = base.newKieSession(); 

// Inject a new message object into the session 
final Message message = new Message(); 
message.setMessage("Hello World"); 
message.setStatus(Message.HELLO); 
session.insert(message); 

// Apply the rules in the kie base to the objects in the session 
session.fireAllRules(); 

// Close the working session 
session.dispose(); 

Ich denke, dass diese neuen APIS zu ausführlich und ein bisschen dunkel zu verstehen. Ich weiß, dass einer der Gründe hinter ihnen ist, eine einfachere Verwaltung der Regelbasen (z. B. Pakete) zu ermöglichen, aber die Implementierung ist ein wenig verworren und wird dem Tool nicht gerecht (d. H .: Anpassung ist schwieriger).

Ich weiß, dass die Verwendung von XML-Konfigurationsdateien oder Dependency-Injection den Code viel einfacher macht, jedoch ersteres bricht den Fluss und letzteres zwingt die Einbeziehung von (vielen) weiteren Abhängigkeiten. Außerdem wird es in beiden Fällen noch schwieriger zu verstehen, was vor sich geht.

jedoch auf die Frage zurück, die Zeile in dem zweiten Schnipsel bemerken, wo die KieRepository eingeführt:

KieRepository repository = services.getRepository(); // <---= HERE! 

Die services kehrt ein KieRepository dessen Standard Release-ID verwendet wird, ein KieContainer zu initialisieren. Dieser Container erzeugt einen KieBase, der bei Bedarf KieSession s erstellt. Beachten Sie, dass das zuvor initialisierte KieBuilder, das das Dateisystem mit der DRL-Datei enthält, nirgends verwendet wird, um die KieBase zu erhalten.Wie die KieBase über die DRL-Datei weiß? Durch einige Nebenwirkungen in KieServices? Wenn ja, ist das nicht schlimm?

Vielen Dank im Voraus für jede Idee oder Erklärung, die Sie haben können.

+0

Hier gibt es nichts zu beantworten: Sie haben alles sehr schön in Ihrer Frage!Und ich bin geneigt, Ihnen zuzustimmen, dass diese inhärente Beziehung zwischen einem Builder, der an einem Dateisystem arbeitet, und einem Container, der mit einem Repository ReleaseId erstellt wurde und eine KieBase erzeugt (was genau das sein muss, was der Builder zusammengebraut hat) absolut verwirrend ist. Ich habe die Drools-Dokumentation durchgesehen, und es erklärt einfach nicht die * Verbindungen * zwischen diesen Entitäten - es beschreibt nur die Eigenschaften jeder Entität, aus der Sie das Wesentliche ableiten sollen. – laune

+0

@laune Ich freue mich, dass Sie meine Meinung teilen! Um ehrlich zu sein, die Drools-Dokumentation wurde nie in Erinnerung behalten, weil sie genau und umfassend ist (zumindest seit v4.3, dem ersten, das ich verwendet habe). Ich bin gerade über Easy Rules (http://www.easyrules.org) gestolpert, die dumm sein könnten (d. H .: RETE/OO, PHREAK), aber viel kompakter und ohne Schnickschnack! Ich mag es, obwohl die Art und Weise, in der Regeln und Beta-Knoten behandelt werden, nicht optimiert ist. –

+0

Eigentlich ist EasyRules nicht funktional vergleichbar mit einem vollwertigen Production Rules System, aber einer seiner Ports - Mintrules (https://github.com/augusto/Mintrules) - ist vielversprechend. –

Antwort

0

Stefano, wenn Sie nur ein paar drl in Ihrer Anwendung laden möchten und sich keine Gedanken über KieContainer, Maven Artefakte oder den KieScanner machen, können Sie die KieHelper Klasse verwenden.

Weitere Informationen finden Sie unter my answer to this other post.

Der einzige Nachteil ist, dass der KieHelper nicht Teil der öffentlichen API von Drools ist.

Hoffe es hilft,

+1

Hallo Esteban, es ist schön, wieder von dir zu lesen! Danke, die Helfer-Klasse vereinfacht den Code wirklich, aber es hilft immernoch nicht zu verstehen, was unter der Haube passiert ... Wie kann man 'KieHelper' Regeln zur Laufzeit hinzufügen? (Siehe diese Frage: http://stackoverflow.com/questions/36502310/how-to-dynamically-change-the-rules-of-a-iven-drools-6-3-session) –

+0

Hallo Stefano. Nein, wenn Sie Ihre KieBases in Runtime modifizieren möchten, sollten Sie sich die Drogerie-Klasse 'KieScanner' in Drools 6.x ansehen. –