400+ Java Interview Questions and Answers blog

400+ Java Interview Questions and Answers blog


Drools tutorial with Maven

Posted: 13 Dec 2012 08:10 PM PST

Drools is a popular open source business rules and work flow engine. It helps you externalize the rules as opposed to embedding within the Java code. This tutorial contains a a number of artifacts highlighted below.


Step 1: Create a new Maven project with the standard src/main/java, src/main/resources, src/test/java, etc source folder directories. Create a new src/main/rules folder to define the rules using the "mvel" expresion language.
Update the pom.xml file as shown below with relevant dependencies and also add the build/resources to tell maven that sr/main/rules is a source folder.

     <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>   <groupId>com.jpm</groupId>   <artifactId>drools-poc</artifactId>   <version>0.0.1-SNAPSHOT</version>   <packaging>war</packaging>     <properties>    <drools.version>5.3.1.Final</drools.version>    <junit.version>4.7</junit.version>   </properties>     <dependencies>    <dependency>     <groupId>junit</groupId>     <artifactId>junit</artifactId>     <version>${junit.version}</version>    </dependency>    <!-- drools library -->    <dependency>     <groupId>org.drools</groupId>     <artifactId>drools-core</artifactId>     <version>${drools.version}</version>    </dependency>    <dependency>     <groupId>org.drools</groupId>     <artifactId>drools-core</artifactId>     <version>${drools.version}</version>    </dependency>    <dependency>     <groupId>org.drools</groupId>     <artifactId>drools-compiler</artifactId>     <version>${drools.version}</version>    </dependency>    <!-- required for drools and spring integration -->    <dependency>     <groupId>org.drools</groupId>     <artifactId>drools-spring</artifactId>     <version>${drools.version}</version>    </dependency>    <dependency>     <groupId>com.thoughtworks.xstream</groupId>     <artifactId>xstream</artifactId>     <version>1.2.2</version>    </dependency>   </dependencies>         <build>      <resources>          <resource>             <directory>src/main/rules</directory>          </resource>      </resources>   </build>    </project>    


Step 2: Define the domain classes like Applicant.java.

     package com.company.license;    public class Applicant {     private Integer id;   private String name;   private int age;      public Applicant(Integer id, String name, int age) {    super();    this.id = id;    this.name = name;    this.age = age;   }     public Integer getId() {    return id;   }     public void setId(Integer id) {    this.id = id;   }     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;   }        @Override   public String toString() {    return "name=" + name + ", age=" + age;   }    }      
Step 3: Define the data access interface and implementation classes that retrieves data from a persistent source like file or database. The implementation is simplified to read from a pre-populated in-memory map.

     package com.company.license;    public interface ApplicantDao {      Applicant findApplicant(Integer applicantId);  }      
The implementation of the above interface.

package com.company.license;    import java.util.Map;  import java.util.concurrent.ConcurrentHashMap;    public class ApplicantDaoImpl implements ApplicantDao {      private static final Map<Integer, Applicant> data = new ConcurrentHashMap<Integer, Applicant>();      static {    data.put(1, new Applicant(1, "John", 16));    data.put(2, new Applicant(2, "Peter", 20));   }     public Applicant findApplicant(Integer applicantId) {    Applicant applicant = data.get(applicantId);    System.out.println("fetched applicant: " + applicant);    return applicant;   }  }      

Step 4: Define the value object class that captures the user entry via a GUI. For example, ApplicantForm.java as shown below.

package com.company.license;    public class ApplicantForm {      private Integer applicantId;   private boolean eligible = true; // eligible by default     public Integer getApplicantId() {    return applicantId;   }     public void setApplicantId(Integer applicantId) {    this.applicantId = applicantId;   }     public boolean isEligible() {    return eligible;   }     public void setEligible(boolean eligible) {    this.eligible = eligible;   }      @Override   public String toString() {    return "applicantId=" + applicantId + ", eligible=" + eligible;   }  }    
Step 5: Define the business rules via mvel expression language in a separate external file -- applicant-license.drl.

     package com.company.license;    import com.company.license.ApplicantForm;  import com.company.license.Applicant;  import com.company.license.ApplicantDao;  import com.company.license.ApplicantDaoImpl;    global ApplicantDao applicantDao;     rule "is eligible for licence"  when     $a : ApplicantForm();     $applicant: Applicant( age < 18 ) from applicantDao.findApplicant($a.getApplicantId());  then     $a.setEligible( false );  end    

Step 6: Finally, the junit test class that makes use of drools to validate applicants. We will create 2 applicants, one with age >= 18, and another one with age < 18, to test the business rules engine (aka expert systems) of drools in action.


     package com.company.license;    import org.drools.KnowledgeBase;  import org.drools.KnowledgeBaseFactory;  import org.drools.builder.KnowledgeBuilder;  import org.drools.builder.KnowledgeBuilderError;  import org.drools.builder.KnowledgeBuilderErrors;  import org.drools.builder.KnowledgeBuilderFactory;  import org.drools.builder.ResourceType;  import org.drools.io.ResourceFactory;  import org.drools.logger.KnowledgeRuntimeLogger;  import org.drools.logger.KnowledgeRuntimeLoggerFactory;  import org.drools.runtime.StatefulKnowledgeSession;  import org.junit.Assert;  import org.junit.Before;  import org.junit.Test;    public class ApplicantLicenseTest {     private KnowledgeBase kbase;     @Before   public void setup() {    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();    kbuilder.add(ResourceFactory.newClassPathResource("com/company/license/applicant-license.drl"),      ResourceType.DRL);    KnowledgeBuilderErrors errors = kbuilder.getErrors();    if (errors.size() > 0) {     for (KnowledgeBuilderError error : errors) {      System.err.println(error);     }     throw new IllegalArgumentException("Could not parse knowledge.");    }    kbase = KnowledgeBaseFactory.newKnowledgeBase();    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());     }     @Test   public void testApplicantLicense() {    StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();    KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();    kbase.newStatefulKnowledgeSession();      ApplicantForm applicant1 = new ApplicantForm();    applicant1.setApplicantId(1);        ApplicantForm applicant2 = new ApplicantForm();    applicant2.setApplicantId(2);          ksession.setGlobal("applicantDao", new ApplicantDaoImpl()); // assign the global dao        ksession.insert(applicant1);    ksession.insert(applicant2);    ksession.fireAllRules();        ksession.dispose();      Assert.assertTrue(applicant1.isEligible() == false);//John is not eligible    Assert.assertTrue(applicant2.isEligible() == true); //Peter is eligible   }    }      





Post a Comment