3

Is it possible to try out the new PHREAKS algorithm but using the conventional API from Drools 5.5

* EDIT: to make the question more precise *

conventional 5.5 API

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.Resource;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

instead new Drools 6 API

  import org.kie.api.KieBase;
  import org.kie.api.KieBaseConfiguration;
  import org.kie.api.KieServices;
  import org.kie.api.builder.KieBuilder;
  import org.kie.api.builder.KieFileSystem;
  import org.kie.api.builder.KieScanner;
  import org.kie.api.builder.Message;
  import org.kie.api.builder.ReleaseId;
  import org.kie.api.builder.model.KieBaseModel;
  import org.kie.api.builder.model.KieModuleModel;
  import org.kie.api.builder.model.KieSessionModel;
  import org.kie.api.conf.EqualityBehaviorOption;
  import org.kie.api.conf.EventProcessingOption;
  import org.kie.api.runtime.KieContainer;
  import org.kie.api.runtime.KieSession;
  import org.kie.api.runtime.conf.ClockTypeOption;
MattRossmann
  • 85
  • 2
  • 7

4 Answers4

2

It's also possible with the 5 knowledge api in drools 6.0+ by setting a rule engine property:

drools.ruleEngine = phreak

Here's how you set in the 5 knowledge api:

knowledgeBaseConfiguration.setProperty("drools.ruleEngine", "phreak");
Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120
  • As OP wants to continue to use the 5.x API: the 6.0.0 Javadoc doesn't have the old package and class names any more. – laune Mar 05 '14 at 10:34
  • Updated the question because all answers use the new 6.0 API, I wanted to point out what I mean with conventional and new API. – MattRossmann Mar 05 '14 at 11:15
  • I have problems adding rules dynamically after initiating the session in Drools 6.0 thats the cause of the questition to work around that problem by using the 5.5 API. I tried it with a KieScanner in 6.0 but that did not work out, problem see here http://stackoverflow.com/questions/22181057/instanciating-kiescanner-in-drools-6-0-to-dynamically-add-rules-during-stateful. – MattRossmann Mar 05 '14 at 11:51
  • If the scanner is broken in 6.0.0, you'll have problems no matter with which API it is activated. – laune Mar 05 '14 at 12:39
  • LMGTFY KieBaseConfiguration was [KnowledgeBaseConfiguration](http://docs.jboss.org/jbpm/v5.1/javadocs/org/drools/KnowledgeBaseConfiguration.html) – Geoffrey De Smet Mar 05 '14 at 14:45
1

I'm copy-pasting the simplest Java code for launching a 6.0 session. Everything else - fact insertion, global definitions,... works using the same API, only with KieSession.

package simple;

import java.io.FileInputStream;
import org.kie.api.KieServices;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.builder.model.KieBaseModel;
import org.kie.api.builder.model.KieSessionModel;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Results;
import org.kie.api.builder.Message;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.KieContainer;

public class Main {

private KieSession kieSession;

public void build() throws Exception {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
    FileInputStream fis = new FileInputStream( "simple/simple.drl" );

    kfs.write( "src/main/resources/simple.drl",
                kieServices.getResources().newInputStreamResource( fis ) );

    KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();

    Results results = kieBuilder.getResults();
    if( results.hasMessages( Message.Level.ERROR ) ){
    System.out.println( results.getMessages() );
        throw new IllegalStateException( "### errors ###" );
}

    KieContainer kieContainer =
    kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );

    KieBase kieBase = kieContainer.getKieBase();

    kieSession = kieContainer.newKieSession();
}

public void exec(){
    kieSession.fireAllRules();
}

public static void main( String[] args ) throws Exception {
Main m = new Main();
    m.build();
    m.exec();
}

}
laune
  • 31,114
  • 3
  • 29
  • 42
1

the working code to preserve rules and facts by using the same KieSession and deploy Jars, the code is adapted from here https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test/java/org/drools/compiler/integrationtests/IncrementalCompilationTest.java.

package test.drools;

import java.io.UnsupportedEncodingException;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.ReleaseId;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class Playground4 {

    private String newline = System.getProperty("line.separator");

    public static void main(String[] args) {
        Playground4 pg = new Playground4();
        try {
            pg.doRules();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private String generateDRLString(int start, int end) {
        StringBuilder sb;
        sb = new StringBuilder();
        sb.append("package performance.drools;" + newline);
        for (int i = start; i <= end; i++) {
            sb.append("rule \"R" + i + "\"" + newline);
            sb.append("when" + newline);
            sb.append("then" + newline);
            sb.append("System.out.println(\"rule" + i + " fired!\");" + newline);
            sb.append("end" + newline);
        }
        return sb.toString();
    }

    int count = 1;
    public void doRules() throws UnsupportedEncodingException {

        KieServices kieServices = KieServices.Factory.get();
        KieBaseConfiguration kieBaseConf = kieServices.newKieBaseConfiguration();
        //kieBaseConf.setProperty("drools.ruleEngine", "phreak");

        kieBaseConf.setProperty("drools.ruleEngine", "phreak");
        ReleaseId releaseId;
        KieModule kieModule;
        releaseId = kieServices.newReleaseId("performance.drools",
                "test-upgrade", "1.$v.0".replace("$v", String.valueOf(count)));

        // create session without rules for version 1.1.0
        kieModule = createAndDeployJar(releaseId);
        KieContainer kieContainer = kieServices.newKieContainer(kieModule
                .getReleaseId());
        kieContainer.newKieBase(kieBaseConf);
        KieSession kieSession = kieContainer.newKieSession();

        // Create an in-memory jar for version 1.2.0
        count++;
        releaseId = kieServices.newReleaseId("performance.drools",
                "test-upgrade", "1.$v.0".replace("$v", String.valueOf(count)));
        kieModule = createAndDeployJar(releaseId, generateDRLString(1, 3));
        kieContainer.updateToVersion(releaseId);
        kieSession.insert(new Object());

        // Create an in-memory jar for version 1.3.0
        count++;
        releaseId = kieServices.newReleaseId("performance.drools",
                "test-upgrade", "1.$v.0".replace("$v", String.valueOf(count)));
        kieModule = createAndDeployJar(releaseId, generateDRLString(4, 12));
        kieContainer.updateToVersion(releaseId);

        kieSession.fireAllRules();

        System.out.println(kieSession.getFactCount());
    }

    public KieModule createAndDeployJar(ReleaseId releaseId, String... drls) {
        KieServices kieServices = KieServices.Factory.get();
        byte[] jar = createKJar(kieServices, releaseId, null, drls);
        return deployJar(kieServices, jar);
    }

    KieFileSystem kfs;
    public byte[] createKJar(KieServices ks, ReleaseId releaseId,
            String pom, String... drls) {
        if (kfs == null) kfs = ks.newKieFileSystem();
        if (pom != null) {
            kfs.write("pom.xml", pom);
        } else {
            kfs.generateAndWritePomXML(releaseId);
        }
        for (int i = 0; i < drls.length; i++) {
            if (drls[i] != null) {
                kfs.write("src/main/resources/r" + 10 * count + i + ".drl", drls[i]);
            }
        }
        KieBuilder kb = ks.newKieBuilder(kfs).buildAll();
        if (kb.getResults()
                .hasMessages(org.kie.api.builder.Message.Level.ERROR)) {
            for (org.kie.api.builder.Message result : kb.getResults()
                    .getMessages()) {
                System.out.println(result.getText());
            }
            return null;
        }
        InternalKieModule kieModule = (InternalKieModule) ks.getRepository()
                .getKieModule(releaseId);
        byte[] jar = kieModule.getBytes();
        return jar;
    }

    public KieModule deployJar(KieServices ks, byte[] jar) {
        // Deploy jar into the repository
        Resource jarRes = ks.getResources().newByteArrayResource(jar);
        KieModule km = ks.getRepository().addKieModule(jarRes);
        return km;
    }

}
MattRossmann
  • 85
  • 2
  • 7
1

Yes, most of the API is still supported. You will need to add the knowledge-api jar to your classpath (https://github.com/droolsjbpm/drools/tree/master/knowledge-api-legacy5-adapter).

The main difference is that Drools 6 no longer uses PKG for deployment. It uses mavenized kjars now. If you are not using PKG files (built by guvnor in Drools 5), you should be fine.

Edson Tirelli
  • 3,891
  • 20
  • 23