Search code examples
droolsrule-engine

I need help for implementing Drool Fluent ApI for dynamically generated DRL file usi ng Kie file system


I was successfully able to generate drool file dynamically using drool fluent api.But my issue is I am not able to write this file in memory area using KieFileSystem API.That is resulting in runtime exception can not find kie module.Below is the same

package com.nagarro;

global fact.OutputData output;

rule "rule1" when GenericEvent( cost>500 )
then output.setDiscount(10) end

Exception in thread "main" java.lang.RuntimeException: Cannot find KieModule: org.default:artifact:1.0.0-SNAPSHOT at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieContainer(KieServicesImpl.java:97) at main.Launcher.evaluate(Launcher.java:67) at main.Launcher.main(Launcher.java:58)

I have already validate the structure of drl file using drool verifier.

Below is code I am using for the same.

public class Launcher {

    public static void main(final String[] args) throws Exception {

     /*   PackageDescr pkg = DescrFactory.newPackage()
            .name("org.drools.example").newImport().target("java.util.ArrayList").end()  
            .newImport().target("java.util.ArrayList").end()
            .newImport().target("java.util.Vector").end()
            .newRule().name("alert")
            .lhs()
                .and()
                    .pattern("Foo").id( "$foo", false ).constraint("bar==baz").constraint("x>y").end()
                    .not().pattern("Bar").constraint("a+b==c").end().end()
                .end()
            .end()
            .rhs("System.out.println;"+"/n"+"System.out.println;").end()
            .getDescr();*/
         PackageDescr desc2 = DescrFactory
             .newPackage()
             .name("com.nagarro;")
             .newGlobal().type("fact.OutputData").identifier("output;")
             .end()
             .newRule().name("rule1")
                 .lhs()
                 .pattern("GenericEvent").constraint("cost>500")
                 .end()
                 .end()
                 .rhs("    output.setDiscount(10)")
                 .end()
             .getDescr();
         DrlDumper dumper=new DrlDumper();
         String drl=dumper.dump(desc2);
         System.out.print(drl);
      //   verify(drl);
         evaluate(drl, new OrderEvent());
    }

    static private void evaluate(final String drl, final Event event) throws Exception {
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        kieFileSystem.write("src/main/resources/rule.drl", drl);
        kieServices.newKieBuilder(kieFileSystem).buildAll();

        KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
        StatelessKieSession statelessKieSession = kieContainer.getKieBase().newStatelessKieSession();
        //HashMap<String,Object> outputMap = new HashMap<>();
        OutputData outData = new OutputData();
        statelessKieSession.getGlobals().set("output", outData);
        HashMap<String, Object> inputMap = new HashMap<>();
        inputMap.put("price", 1000);
        GenericEvent evt = new GenericEvent();
        evt.setInputmap(inputMap);
        evt.setCost(1000);
        statelessKieSession.execute(evt);
        System.out.println(outData.getDiscount());

    }

    public static void verify(final String drl) {
     // Create verifier builder [1]
        VerifierBuilder vBuilder = VerifierBuilderFactory.newVerifierBuilder();


        // Create verifier [2]
        Verifier verifier = vBuilder.newVerifier();


        // Add Resources you want to verify [3]  
        verifier.addResourcesToVerify(new ClassPathResource("generic.drl",Launcher.class),
                                       ResourceType.DRL );


        // Run the verification rules [4]
        verifier.fireAnalysis();


        // Get the result object [5]
        VerifierReport result = verifier.getResult();
        System.out.println(result);
        // Print the the errors [6]
        for(VerifierMessageBase base: result.getBySeverity( Severity.ERROR ) ){
            System.out.println( base );
        }
    }

}

Solution

  • For writing the drl as file use:

    kieFileSystem.write("src/main/resources/rule2.drl", kieServices.getResources().newReaderResource(
                new StringReader(drl)));
    

    For validating the drl

    KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
    
    // check there have been no errors for rule setup
    Results results = kieBuilder.getResults();
    if (results.hasMessages(Message.Level.ERROR)) {
        System.out.println(results.getMessages());
        throw new IllegalStateException("### errors ###");
    }
    
    KieContainer kieContainer = kieServices.newKieContainer( kieBuilder.getKieModule().getReleaseId());
    
    
    KieSession kieSession = kieContainer.newKieSession();
    

    For evaluating rules:

    kieSession.insert(inputData);
    kieSession.setGlobal("output", outData);
    kieSession.fireAllRules();
    kieSession.dispose();