0
votes

Need some help !! I don't have a clear understanding on stateful and stateless sessions in Drools. I am trying to understand this , so attempted an example .

I have tested the below drl with stateful and stateless sessions on drools6.5 version and it resulted with same output in both the cases.From what I understood with stateless session it should execute only first rule and second rule should not be activated when the Application object is modified in the first rule("Is of valid age"). Attaching the source code. Appreciate any help on this.

package com.company.license

import com.sample.dto.Applicant;
import com.sample.dto.Application;
import java.util.Date;


rule "Is of valid age"
no-loop
    when 
        Applicant( age < 18 )
        $a : Application()
    then
        $a.setValid( false );
        modify($a){setDateApplied(new Date())};
        System.out.println("from rule Is of Valid age --  " +$a.isValid() );
    end

rule "Application was made this year"
    when 
        $a : Application( dateApplied > "01-jan-2009" )
    then 
    $a.setValid( true);
    System.out.println("from rule made this year --  " +$a.isValid() );
end


package com.sample.dto;

import java.util.Date;

public class Application {
    public Date dateApplied;
    public boolean valid;

    // getter and setter methods here
    public Date getDateApplied() {
        return dateApplied;
    }
    public void setDateApplied(Date dateApplied) {
        this.dateApplied = dateApplied;
    }
    public boolean isValid() {
        return valid;
    }
    public void setValid(boolean valid) {
        this.valid = valid;
    }
}


package com.sample.dto;
public class Applicant {
    public String name;
    public int age;

    public Applicant(String name,int age){
        this.name =  name;
        this.age=age;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public int getAge() {
        return age;
    }


    public void setAge(int age) {
        this.age = age;
    }
}

package com.sample;

import java.util.Arrays;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;

import com.sample.dto.Applicant;
import com.sample.dto.Application;

/**
 * This is a sample class to launch a rule.
 */
public class LicenseTestStateful {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            KieSession ksession = kContainer.newKieSession("ksession-rules");
            Applicant applicant = new Applicant( "Mr John Smith", 16);
            Application application = new Application();
            ksession.execute(ks.getCommands().newInsertElements(Arrays.asList(new Object[]{application,applicant})));
            ksession.fireAllRules();
            ksession.dispose();

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}


package com.sample;

import java.util.Arrays;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;

import com.sample.dto.Applicant;
import com.sample.dto.Application;

/**
 * This is a sample class to launch a rule.
 */
public class LicenseTestStateless {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            StatelessKieSession ksession = kContainer.newStatelessKieSession();
            Applicant applicant = new Applicant( "Mr John Smith", 16);
            Application application = new Application();
            ksession.execute(ks.getCommands().newInsertElements(Arrays.asList(new Object[]{application,applicant})));       
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
        <ksession name="statelesssession" type="stateless" default="true"/>
    </kbase>
    <kbase name="dtables" packages="dtables">
        <ksession name="ksession-dtables"/>
    </kbase>
    <kbase name="process" packages="process">
        <ksession name="ksession-process"/>
    </kbase>
</kmodule>


Output:
from rule Is of Valid age --  false
from rule made this year --  true
2

2 Answers

0
votes

The difference between a stateless and a stateful KieSession is in the API for utilising the session. A stateless session is activated using one of the execute methods where a set of commands is passed to the session to be executed, and dispose is called at the end to return all resources; thus the session cannot be re-used and its state is lost.

With a statefull session you have the option of executing all sorts of API calls in any order you like, call some "fire" method as often as necessary, etc.

StatelessKieSession is just a wrapper for KieSession.

0
votes

I think I got it right . If the changes in the facts happens in the same request then all the other rules associated with that change will fire irrespective of any stateless/stateful session.