Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 996
Peter Smith Avatar asked Dec 19 '14 16:12

Peter Smith


People also ask

How do you call one rule from another rule in Drools?

Well, the answer is we can't call a Rule from another Rule. Drools matches the Rules with incoming data/facts, and if the data satisfies the Rule condition, it stores the data in an Agenda. It might be possible for the same data or facts to be matched by different rules, so it stores matching facts in an Agenda.

What is .DRL file in Java?

A DRL file can contain one or more rules that define at minimum the rule conditions ( when ) and actions ( then ). The DRL designer in Decision Central provides syntax highlighting for Java, DRL, and XML. All data objects related to a DRL rule must be in the same project package as the DRL rule in Decision Central.

What is Drools rule engine used for?

Drools Rule Engine is a rule-based approach to implement an Expert system in the Drools software. The Rule engine provides Expert systems which are knowledge-based systems that help you to make decisions like what to do and how to do it. It gathers knowledge into a knowledge base that can be used for reasoning.


1 Answers

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.

like image 167
Tim Van Laer Avatar answered Sep 28 '22 06:09

Tim Van Laer