What is the new accepted way of programmatically creating new drools rules in Drools 6?
Asked Answered
C

3

15

In short I want to create, edit and delete rules from a rules repository at runtime. I'm having trouble figuring out how to do this in drools 6+.

I know in a previous version of drools (<= 5.6), that there was an XML representation of a .drl file and an API for working with it: https://docs.jboss.org/drools/release/5.6.0.Final/drools-expert-docs/html/ch04.html#d0e8052.

The drools documentation as of 5.6 indicates this deprecated and it appears to be completely removed at 6. I don't want to use an API that is already known to have no direct upgrade path.

Exposing the Guvnor or Workbench UIs to users for rules editing is also not a good fit here due to workflow requirements and due to the complexity of the web user interfaces. I want to create and manage the rules from Java code.

I want a better method than string templating to a .drl file for creating new rules and modifying rules. What exists for programmatically creating new rules from Java? I have done a lot of searching but can't seem to find a set of Java API calls for this.

Casabonne answered 19/12, 2014 at 16:51 Comment(0)
I
14

I don't know if this is the 'accepted' way, but with the following code I comine .drl files with programmatically created rules in Drools 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);
    }
}

I use the Guava Resources class.

Ictus answered 10/4, 2015 at 11:33 Comment(3)
Wow that DescFactory API for dynamic rule building seems so cool and flexible. Only, what is the use case for it? Why would you build a dynamic rule in Java? Isn't the point to have the DRL rule externalized in the first place?Borderline
It would be useful when migrating an existing set of rules to DRL files. That is what I am currently trying to accomplish.Fighterbomber
Checkout github.com/trmsmy/drools-example @Tim... is it yours?Pattiepattin
L
2

The built-in way to programmatically create rules is based on a "Descr" fluent API, which manipulates the compiler's AST directly, bypassing the parser.

see the class org.drools.compiler.lang.api.DescrFactory

and the class org.drools.compiler.lang.DrlDumper to retrieve a DRL approximation from the AST.

Lianneliao answered 23/12, 2014 at 17:36 Comment(1)
Ok, but how do you evaluate the built PackageDescr?Ictus
G
1

There is no stable API for building rules from Java code. There is, of course, an API for the DRL compiler's parser, but it isn't stable and as complex as DRL rule syntax, which is considerable.

XML was an option where at least left hand side syntax was simple enough, which ended with 5.2 (IIRC). Now you can use Java's full expression syntax and more, combined with the many varied ways to compose CEs.

If your rules are exceptionally simple, you might come up with a model for rules that could be manipulated with a manageable API. Otherwise, your best bet is a text editor (or, of course, the Kie Workbench).

Gastroenterology answered 23/12, 2014 at 10:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.