OSGI + PAX CDI + Drools + Karaf

Drools

Drools is a powerful rule engine. You define rules using .drl file or .xls as an decision table

In this post we will see how Drool is embedded in Karaf as OSGI.

Pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.frontend</groupId>
<artifactId>frontend-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>frontend-cmd2</artifactId>
<packaging>bundle</packaging>

<properties>
<runtime.version>6.5.0.Final</runtime.version>
<cdi.version>1.1</cdi.version>
<weld.version>2.3.2.Final</weld.version>
</properties>

<dependencies>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${runtime.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${runtime.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${runtime.version}</version>
</dependency>
<dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-decisiontables</artifactId>
            <version>${runtime.version}</version>
        </dependency>
        
<!-- CDI dependencies -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>${weld.version}</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>${runtime.version}</version>
</dependency>

</dependencies>

</project>


Model Object

package org.drools.example.model;

public class Person {

    private String name;
    private String likes;
    private String status;
    private int age;
    private boolean canDrink = false;
    private boolean alive;
    private char sex;
    private boolean happy;

    public Person() {

    }
    public Person(final String name) {
        this( name,
                "",
                0 );
    }

    public Person(final String name,
                  final String likes) {
        this( name,
                likes,
                0 );
    }

    public Person(final String name,
                  final String likes,
                  final int age) {
        this.name = name;
        this.likes = likes;
        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;
    }

    public boolean isCanDrink() {
        return canDrink;
    }

    public void setCanDrink(boolean canDrink) {
        this.canDrink = canDrink;
    }

    public String getStatus() {
        return this.status;
    }

    public void setStatus(final String status) {
        this.status = status;
    }

    public String getLikes() {
        return this.likes;
    }

    public boolean isAlive() {
        return this.alive;
    }

    public void setAlive(final boolean alive) {
        this.alive = alive;
    }

    public char getSex() {
        return this.sex;
    }

    public void setSex(final char sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age
                + ", canDrink=" + canDrink + '}';
    }

    public boolean isHappy() {
        return happy;
    }

    public void setHappy(boolean happy) {
        this.happy = happy;
    }
}


Helper Class

package org.drools.example.rule;

import org.drools.example.model.Person;

import java.util.Random;

public class PersonHelper {

    private static final Random random = new Random();

    public static Person createPerson() {
        Person person = new Person();
        if (random.nextBoolean()) {
            person.setName("Old Person");
            person.setAge(21);
        } else {
            person.setName("Young Person");
            person.setAge(18);
        }
        return person;
    }

    public static void canDrink(Person aPerson) {
        if (aPerson.isCanDrink()) {
            System.out.println("Person " + aPerson.getName() + " aged of " + aPerson.getAge() + " , can go to the Bar");
        } else {
            System.out.println("Person " + aPerson.getName() + " aged of " + aPerson.getAge() + ", can't go to the Bar");
        }
    }
}

OSGI Class

It initializes the OSGI Service and Configure the KieSession 

package org.drools.example.osgi;

import org.drools.example.model.Person;
import org.drools.example.rule.PersonHelper;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.cdi.KSession;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.ops4j.pax.cdi.api.ContainerInitialized;

import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;

@ApplicationScoped
public class CanDrinkRuleOsgiCdiWeld {

   /* @Inject
    @KSession("sampleKSession")
    KieSession ksession;*/

    public void onStartup(@Observes ContainerInitialized event) {

        KieServices ks = KieServices.Factory.get();
        KieContainer kcont = ks.newKieClasspathContainer(getClass().getClassLoader());
        KieBase kbase = kcont.getKieBase("sampleKBase");

        KieSession ksession = kbase.newKieSession();
        System.out.println("KieSession created.");

        for (int i = 0; i < 20; i++) {
            // Create a Person
            Person aPerson = PersonHelper.createPerson();
            ksession.insert(aPerson);

            // Fire the rules
            ksession.fireAllRules();

            // Check if it can drink
            PersonHelper.canDrink(aPerson);
        }
    }

    @PreDestroy
    public void onClose() {
        
            System.out.println("KieSession disposed.");
    }

}

The above class loads the xml file

kmodule.xml

SampleKBase loads the sampleKSession

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">

    <kbase name="sampleKBase" packages="rules" default="true">
        <ksession name="sampleKSession" default="true" />
    </kbase>

</kmodule>

which loads the DRL rule file below sample.drl

package org.drools.example.drink;

import org.drools.example.model.Person

rule "CanDrink"
when
    p : Person( age >= 21 )
then
p.setCanDrink(true);
end


Initialize PAX-CDI we have to create an empty META-INF\beans.xml

Deploying in Karaf

Do mvn clean install 

Karaf run the following commands

Install PAX-CDI & WELD

feature:install pax-cdi
feature:install pax-cdi-1.1-weld

Install the bundle

install -s mvn:com.frontend/frontend-cmd2/1.0


Person Young Person aged of 18, can't go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Young Person aged of 18, can't go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Old Person aged of 21 , can go to the Bar
Person Young Person aged of 18, can't go to the Bar

We can see next post how to use Decision Table

Comments

Popular posts from this blog

Apache Karaf + Pax CDI OSGI Service

Apache CXF CDI in Karaf (Using CXF and CDI 1.1 (JSR-346))