Search code examples
spring-bootdrools

Set event processing to STREAM with rules from a Maven project (KieScanner)


I have a Maven project with rules in .drl files and another project, which is a SpringBoot web server. The rules can be sent by a POST request to the server, after which they are added to the Maven project and can be activated like they were there from the start.

The rules are "noticed" because I update the Maven rules project (by calling its mvn clean install) each time a new rule is submitted.

I tried a lot of configurations, the most "logical" shots being these two below:

First try:

@Bean
public KieSession kieSession() {
    KieServices ks = KieServices.Factory.get();
    KieContainer kContainer = ks.newKieContainer(ks.newReleaseId("ftn.bsep9","drools-spring-kjar", "0.0.1-SNAPSHOT"));

    KieBaseConfiguration config = ks.newKieBaseConfiguration();
    config.setOption(EventProcessingOption.STREAM);

    KieBase kieBase = kContainer.newKieBase("myKBase", config);
    KieSession kSession = kieBase.newKieSession();

    KieScanner kScanner = ks.newKieScanner(kContainer);
    kScanner.start(10000); // check for rule changes every 10 seconds

    return kSession;
}

...

N-th try:

@Bean
public KieSession kieSession() {
    KieServices ks = KieServices.Factory.get();
    KieFileSystem kfs = ks.newKieFileSystem();
    KieModuleModel kModule = ks.newKieModuleModel();

    KieBaseModel baseModel = kModule.newKieBaseModel("defaultKieBase")
            .setDefault(true)
            .setEventProcessingMode(EventProcessingOption.STREAM);
    baseModel.newKieSessionModel("defaultKSession")
            .setDefault(true)
            .setClockType(ClockTypeOption.get("pseudo"));

    kfs.writeKModuleXML(kModule.toXML());
    KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll();
    System.out.println("ERRORS: " + kieBuilder.getResults().getMessages(Message.Level.ERROR).size());

    KieContainer kContainer = ks.newKieContainer(ks.newReleaseId(
            "ftn.bsep9","drools-spring-kjar", "0.0.1-SNAPSHOT"));
    KieSession kSession = kContainer.newKieSession();

    KieScanner kScanner = ks.newKieScanner(kContainer);
    kScanner.start(10000); // check for rule changes every 10 seconds

    return kSession;
}

Any help is appreciated, especially with an explanation of why Your code works and my doesn't. :)


Note: the code below works, but I can't use the over window:time(5m) drools' expression, since it requires the STREAM EventProcessing.

@Bean
    public KieSession kieSession() {
        KieServices ks = KieServices.Factory.get();
        KieContainer kContainer = ks.newKieContainer(ks.newReleaseId("ftn.bsep9","drools-spring-kjar", "0.0.1-SNAPSHOT"));
        KieScanner kScanner = ks.newKieScanner(kContainer);
        kScanner.start(10000);
        return kContainer.newKieSession();
}

Solution

  • I finally managed to solve the the problem by setting the dependencies correctly. I am using 6.2.0.Final version of the kie-ci and kie-spring artifacts. I tried versions: 7.7.0, 7.2.0, 6.5.0 and 6.4.0, but none of them worked.

    KieSession Bean is being created as follows:

    @Bean
    public KieSession kieSession() {
        final KieServices kieServices = KieServices.Factory.get();
        final ReleaseId releaseId = kieServices.newReleaseId(groupId, artifactId, version);
        final KieContainer kieContainer = kieServices.newKieContainer(releaseId);
        final KieSession kieSession = kieContainer.newKieSession();
    
        final KieScanner kieScanner = kieServices.newKieScanner(kieContainer);
        kieScanner.start(10000);
    
        log.warn(":) created a KIE Container - returning...");
        return kieSession;
    }
    

    Part of the pom.xml file containing KIE artifacts' version is below:

    ...
    <properties>
        <kie.version>6.2.0.Final</kie.version>
    </properties>
    ...
    <dependencies>
    ...
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-ci</artifactId>
        <version>${kie.version}</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-spring</artifactId>
        <version>${kie.version}</version>
    </dependency>
    ...
    </dependencies>
    

    What helped in the process was running mvn dependency:tree and checking which versions of which artifacts/projects are being used.

    Here is the link to the complete pom.xml file which worked for me. Dependency tree generated from mvn dependency:tree can be found ||here||.