Java @ Desk: Drools Guvnor | Java at your desk

Drools Named KieSession example

Drools Named KieSession example

Drools 6.0 onwards a new approach is designed to create a Knowledge Base and a Knowledge Session compared to previous versions.

In our last post, we learned Drools Default KieSession example The below example will explain on how to create a Named KieSession

The Drools 6.0 project consists of a single meta data file META-INF/kmodule.xml. The file is located under the source folder as shown in below snapshot.


If the file is not located at the location
KieSession ksession = 

kc.newKieSession();

// will return null


If the named session is not defined in kmodule.xml
KieSession ksession = 
kc.newKieSession("namedKieSession");
// will return null


By default, kc.newKieSession("namedKieSession") returns the object of org.drools.core.impl.StatefulKnowledgeSessionImpl class.

Below are the files that are required to fire the rules using KieSession

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://jboss.org/kie/6.0.0/kmodule">

    <kbase name="DroolsTestKB" packages="org.drools.test">
        <ksession name="namedKieSession"/>
    </kbase>

</kmodule>


DRL File
package com.sample
 
import com.pojo.*;
 
rule "Check Circuit Limit"
when
 $stock : Stock()
then
 $stock.setHaltTrading(true);
 System.out.println("Rule Fired using KIE Default Session");
end




Client File
package com.sample;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.KnowledgeBase;

import com.pojo.Stock;

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

 public static final void main(String[] args) {
  try {
   KieServices ks = KieServices.Factory.get();

   KieContainer kc = ks.getKieClasspathContainer();

   KieSession ksession = kc.newKieSession("namedKieSession");
   System.out.println("KieSession - " +ksession);

   final Stock a = new Stock();

   ksession.insert(a);

   ksession.fireAllRules();

   ksession.dispose(); // Stateful rule session must always be disposed
   // when finished
  } catch (Throwable t) {
   t.printStackTrace();
  }
 }

}


Output:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
KieSession - org.drools.core.impl.StatefulKnowledgeSessionImpl@cab854
Rule Fired using KIE Named Session


Drools KieSession example

Drools KieSession example

Drools 6.0 onwards a new approach is designed to create a Knowledge Base and a Knowledge Session compared to previous versions.

The below example will explain on how to create a Default KieSession

The Drools 6.0 project consists of a single meta data file META-INF/kmodule.xml. The file is located under the source folder as shown in below snapshot.


If the file is not located at the location
KieSession ksession = 

kc.newKieSession();

// will return null


By default, kc.newKieSession() returns the object of org.drools.core.impl.StatefulKnowledgeSessionImpl class.

Below are the files that are required to fire the rules using KieSession

kmodule.xml file - Since we are creating a default KieSession, no need to define any kbase
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://jboss.org/kie/6.0.0/kmodule">
</kmodule>


DRL File
package com.sample
 
import com.pojo.*;
 
rule "Check Circuit Limit"
when
 $stock : Stock()
then
 $stock.setHaltTrading(true);
 System.out.println("Rule Fired using KIE Default Session");
end




Client File
package com.sample;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.KnowledgeBase;

import com.pojo.Stock;

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

 public static final void main(String[] args) {
  try {
   KieServices ks = KieServices.Factory.get();

   KieContainer kc = ks.getKieClasspathContainer();

   KieSession ksession = kc.newKieSession();
   System.out.println("KieSession - " +ksession);
   final Stock a = new Stock();

   ksession.insert(a);

   ksession.fireAllRules();

   ksession.dispose(); // Stateful rule session must always be disposed
   // when finished
  } catch (Throwable t) {
   t.printStackTrace();
  }
 }

}


Output:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
KieSession - org.drools.core.impl.StatefulKnowledgeSessionImpl@cab854
Rule Fired using KIE Default Session


Drools DRL date-effective example


Drools DRL date-effective example

date-effective attribute in a rule definition is required if the rule needs to be fired only if the date mentioned is prior to current date.


The date format dd-mmm-yyyy is supported by default. If required, the alternate date format can also be used. In order to do so, you need to mention the required format as shown below:


System.setProperty("drools.dateformat", "dd-mmm-yyyy hh:mm");


While the rule is getting fired, if the current time is after the time mentioned in the date-effective attribute, the rule will get fired else the rule will be ignored.

What if the date provided has invalid date format. For example :
1) date-effective "36-UN-2014"
2) date-effective "36-JUN/2014"

In above case, following exception will be thrown
java.lang.IllegalArgumentException: Invalid date input format: [36-JUN/2014] it should follow: [dd-MMM-yyyy]
 at org.drools.core.util.DateUtils.parseDate(DateUtils.java:73)
 at org.drools.rule.builder.RuleBuilder.buildAttributes(RuleBuilder.java:161)
 at org.drools.rule.builder.RuleBuilder.build(RuleBuilder.java:95)
 at org.drools.compiler.PackageBuilder.addRule(PackageBuilder.java:2830)
 at org.drools.compiler.PackageBuilder.compileRules(PackageBuilder.java:970)
 at org.drools.compiler.PackageBuilder.compileAllRules(PackageBuilder.java:879)
 at org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:871)
 at org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:466)
 at org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.java:694)
 at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:51)
 at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:40)
 at com.sample.DrlDateEffective.readKnowledgeBase(DrlDateEffective.java:32)
 at com.sample.DrlDateEffective.main(DrlDateEffective.java:19)


Complete Example Code

DrlDateEffective.drl - File contains 2 rules
1) Date Effective Valid - date-effective is AFTER Current Date
2) Date Effective InValid - date-effective is BEFORE Current Date



package com.sample
 
rule "Date Effective Valid"
date-effective "06-JUN-2014"
    when
 then
  System.out.println("Rule Fired because Current Date is AFTER date-effective");
end

rule "Date Effective InValid"
date-effective "06-JUN-2015"
    when
 then
 System.out.println("Rule Fired because Current Date is BEFORE date-effective");
end


DrlDateEffective.java
package com.sample;

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;

public class DrlDateEffective {
 public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            
            ksession.fireAllRules();
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("DrlDateEffective.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.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }

}


Output
Rule Fired because Current Date is AFTER date-effective


Drools DRL date-expires example

Drools DRL date-expires example

date-expires attribute in a rule definition is required if the rule needs to be fired only if the date mentioned is after the current date. If the current date is greater than date-expires attribute, then rule will not be fired.

The date format dd-mmm-yyyy is supported by default. If required, the alternate date format can also be used. In order to do so, you need to mention the required format as shown below:

System.setProperty("drools.dateformat", "dd-mmm-yyyy hh:mm");


While the rule is getting fired, if the current time is before the time mentioned in the date-expires attribute, the rule will get fired else the rule will be ignored.

What if the date provided has invalid date format. For example :
1) date-expires "36-UN-2014"
2) date-expires "36-JUN/2014"

In above case, following exception will be thrown
java.lang.IllegalArgumentException: Invalid date input format: [36-JUN/2014] it should follow: [dd-MMM-yyyy]
 at org.drools.core.util.DateUtils.parseDate(DateUtils.java:73)
 at org.drools.rule.builder.RuleBuilder.buildAttributes(RuleBuilder.java:161)
 at org.drools.rule.builder.RuleBuilder.build(RuleBuilder.java:95)
 at org.drools.compiler.PackageBuilder.addRule(PackageBuilder.java:2830)
 at org.drools.compiler.PackageBuilder.compileRules(PackageBuilder.java:970)
 at org.drools.compiler.PackageBuilder.compileAllRules(PackageBuilder.java:879)
 at org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:871)
 at org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:466)
 at org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.java:694)
 at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:51)
 at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:40)
 at com.sample.DrlDateExpires.readKnowledgeBase(DrlDateExpires.java:32)
 at com.sample.DrlDateExpires.main(DrlDateExpires.java:19)


Complete Example Code

DrlDateExpires.drl - File contains 2 rules
1) Date Expires InValid - date-expires is BEFORE Current Date
2) Date Expires Valid - date-expires is AFTER Current Date

package com.sample
 
rule "Date Expires InValid"
date-expires "06-JUN-2014"
    when
 then
  System.out.println("Rule Fired because Current Date is AFTER date-expires");
end

rule "Date Expires Valid"
date-expires "06-JUN-2015"
    when
 then
 System.out.println("Rule Fired because Current Date is BEFORE date-expires");
end




DrlDateExpires.java
package com.sample;

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;



public class DrlDateExpires {
 public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            
            ksession.fireAllRules();
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("DrlDateExpires.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.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }

}


Output
Rule Fired because Current Date is BEFORE date-expires


Drools Drl activation group

Drools Drl activation group

activation-group is a reserved keyword in drools drl file. There can be a single rule or multiple rules that can belong to a particular activation-group.

Rules that belong to activation-group fire in similar fashion to "if..else if..else" block in java. activation-group must contains set of those rules from which 1 and only 1 rule needs to be fired.

For example, a business requirement is
1) If age < 18, do X
2) If age > 20 && age < 32, do Y
3) If age > 32 && age < 48, do Z

or some more

1) If sale > 10,500 units && sale < 15,500 units, set commission = 5%
2) If sale > 15,500 units && sale < 25,500 units, set commission = 7.25%
3) If sale > 20,500 units && sale < 35,500 units, set commission = 9.5%

In both the cases, there is no need to fire all the three scenarios because 1 and only 1 input will fit in the given criteria.
The same thing in Java can be implemented using "if..else if..else".
Any rule fired within a activation-group will stop the other rules from getting fired.

Sample Code

DrlActivationGroup.drl
package com.sample
 
import com.sample.*;

rule "Platinum Customer"
lock-on-active true
activation-group "activation test"
salience 60
    when
     c : Customer()
 then
  c.setCustType("Platinum");
        System.out.println("Customer : " + c.getCustId() + " is a Platinum Customer");
end

rule "Gold Customer"
lock-on-active true
salience 50
activation-group "activation test"
    when
     c : Customer()
 then
  c.setCustType("Gold");
        System.out.println("Customer : " + c.getCustId() + " is a Gold Customer");
end




Java Standalone file to test the activation group
package com.sample;

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;

public class DrlActivationGroup {
 public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            
            Customer customer = new Customer();
   customer.setCustId("C1500564");
            
            ksession.insert(customer);
            
            ksession.fireAllRules();
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("DrlActivationGroup.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.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }

}


Output

Run the above client file will generate this output
Customer : C1500564 is a Platinum Customer


As shown, since the salience of rule "Platinum Customer" is high, it gets fired and thus it stopped execution of the rule "Gold Customer" because it belongs to same activation group.
If the salience of rule "Platinum Customer" will be changed to value that is lesser than the salience rule "Gold Customer", then "Platinum Customer" rule will not be fired.

How to create a Drools Knowledge Base as Singleton

How to create a Drools Knowledge Base as Singleton

Running a drools application in a web application would be similar to the one while running in a standalone java application.

It is advisable to create a Knowledge Base within an application as a Singleton class. For each client request, a new StatefulKnowledgeSession or StatelessKnowledgeSession is created based on the requirement.

Advantages of creating a KnowledgeBase as Singleton class :

1) There will be only 1 instance of KnowledgeBase across the whole application
2) Different requests will use the same instance to create knowledge session
3) Loading of all the DRL files happens at once saving a lot of time
4) KnowledgeBase initialization can be eagerly loaded. Thus as soon as the application starts in the server, KnowledgeBase is created. So on first client request for rule firing, processing time will be saved as the KnowledgeBase is already in place, just to create a Session out of it.

Sample singleton class for KnowledgeBase

Spring Bean Entry configuration : In a spring configuration XML, following entry helps in eager initialization of the KnowledgeBase.

<bean id="knowledgeBase" class="com.sample.DroolsSingletonKnowledgeBase" init-method="getKnowledgeBase()">


package com.sample;

import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;

public class DroolsSingletonKnowledgeBase {

 private static KnowledgeBase knowledgeBase;
 
 private DroolsSingletonKnowledgeBase() {
  
 }
 
 public static KnowledgeBase getKnowledgeBase() {
  if(knowledgeBase == null) {
   knowledgeBase = createKnowledgeBase();
  }
  return knowledgeBase;
 }
 
 private static KnowledgeBase createKnowledgeBase() {
  KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
  
  // Add Drools Files
  // knowledgeBuilder.add(arg0, arg1);
  
  KnowledgeBuilderErrors knowledgeBuilderErrors = knowledgeBuilder.getErrors();
  if(knowledgeBuilderErrors.size() > 0) {
   for(KnowledgeBuilderError knowledgeBuilderError : knowledgeBuilderErrors) {
    System.out.println("Error : " + knowledgeBuilderError);
   }
   throw new RuntimeException("Could not parse Knowledge Base");
  }
  
  KnowledgeBase knowledgeBase = knowledgeBuilder.newKnowledgeBase();
  knowledgeBase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages());
  return knowledgeBase;
 }
}

Drools Function in DRL files

Drools Function in DRL files

Function in a DRL file is similar to a java function.

Inside a function, a plain java code can be easily written. Functions in a DRL file can be used for both action(when) and consequence(then) part.

When used in a when part of a rule, a function should return a boolean value i.e. true or false. If a function is returning any other object then the evaluation to true or false need to be taken care in the rule. For example, if a function is returning String, in that case in the when part, its required to use

eval(returnedString == "XYZ")

In case of then part of a rule, a function can return any object.

Advantages of using function :
1) Easy to write java code and maintain.
2) If the function is getting used in multiple DRL files, then no need to write the function in all DRL. The function is required in only one DRL file that is being loaded 1st in the knowledge session
3) Can implement complex logic

Function syntax

function RETURN_TYPE functionName() {
 return RETURN_TYPE; // return to be used in case other than void
}


Function usage :

The function checks if the user has taken Personal Loan from any bank.

function boolean isPersonalLoan() {
 return true;
}

rule "funtionTest"
when
 eval(isPersonalLoan())
then
 System.out.println("Function retured true");
end


Drools Stateful vs Stateless Knowledge Session

Drools Stateful vs Stateless Knowledge Session

Knowledge Session in Drools is the core component to fire the rules. Its the knowledge session that holds all the rules and other recources.

Knowledge Session is created from the KnowledgeBase which includes all the rules.

Knowledge Session in Drools is of 2 types :
1) Stateful Knowledge Session
2) Stateless Knowledge Session

Difference between the 2 :

1) In case of Stateless Knowledge Session, while rules execution i.e. once fireRules method is called, and modification in the inserted facts (in the then part) is not available to the rules engine. In case of Stateful Knowledge Session, any changes in the facts is available to the rule engine.

2) Once rules are fired, Stateful Knowledge Session object must call the method dispose() to release the session and avoid memory leaks.

3) In case of Stateful Knowledge Session, any changes to facts is available to the rule engine. So the rules are called iteratively. If Fact A is modified in last rule of DRL, then this change will re-activate all the rules and fire the rules that are build on Fact A. This is not the case with Stateless Knowledge Session.

The hidden fact is Stateless session uses a Stateful session behind it

Drools Interview Questions And Answers - One

Drools DRL forall example

Drools DRL forall example

forall is a conditional element in a DRL file that gets used in the LHS part of the rule.

forall as the name suggest applies the condition to all the facts in the working memory.

Basic example for forall is:
1) Find all the customers where the holding pattern is like : quantity of each stock > 100 units, price of each stock > 10$. Categorize such customers as Platinum
2) Find the companies where each board of director earns a monthly salary > 50000$ and years of experience < 9 Years. Categorize such company in a Fortune 500 company

Complete Code:
Refer Customer and Stocks Java Pojo classes in this post : Drools DRL Collect List Example

Client Code :

package com.sample;

import java.util.ArrayList;
import java.util.List;

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;

public class DroolsDrlForAll {
 public static final void main(String[] args) {
  try {
   // load up the knowledge base
   KnowledgeBase kbase = readKnowledgeBase();
   StatefulKnowledgeSession ksession = kbase
     .newStatefulKnowledgeSession();
   KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
     .newFileLogger(ksession, "test");
   // go !
   List<Stocks> stocks = new ArrayList<Stocks>();
   stocks.add(new Stocks("Apple", 10, 100));
   stocks.add(new Stocks("Google", 35, 28));
   stocks.add(new Stocks("Larsen", 100, 780));
   stocks.add(new Stocks("TCS", 180, 1100));
   stocks.add(new Stocks("Tata Motors", 160, 200));
   
   Customer customer = new Customer();
   customer.setStocks(stocks);
   customer.setCustId("C1500564");
   
   
   List<Stocks> stocks2 = new ArrayList<Stocks>();
   stocks2.add(new Stocks("Apple", 10, 100));
   stocks2.add(new Stocks("Google", 35, 28));
   stocks2.add(new Stocks("Larsen", 100, 780));
   stocks2.add(new Stocks("TCS", 180, 1100));
   stocks2.add(new Stocks("Tata Motors", 160, 200));
   stocks2.add(new Stocks("Bhel", 60, 80));
   stocks2.add(new Stocks("NTPC", 160, 40));
   
   Customer customer2 = new Customer();
   customer2.setStocks(stocks2);
   customer2.setCustId("C1506585");
   
   
   List<Stocks> stocks3 = new ArrayList<Stocks>();
   stocks3.add(new Stocks("Apple", 150, 100));
   stocks3.add(new Stocks("Google", 350, 28));
   stocks3.add(new Stocks("Larsen", 120, 780));
   stocks3.add(new Stocks("TCS", 180, 1100));
   stocks3.add(new Stocks("Tata Motors", 160, 200));
   
   Customer customer3 = new Customer();
   customer3.setStocks(stocks3);
   customer3.setCustId("C1506825");
   
   ksession.insert(customer);
   ksession.insert(customer2);
   ksession.insert(customer3);
   ksession.fireAllRules();
   logger.close();
  } catch (Throwable t) {
   t.printStackTrace();
  }
 }

 private static KnowledgeBase readKnowledgeBase() throws Exception {
  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
    .newKnowledgeBuilder();
  kbuilder.add(ResourceFactory.newClassPathResource("DroolsDrlForAll.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.");
  }
  KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
  kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
  return kbase;
 }

}




Below is the sample rule for 1st requirement

rule "Platinum Customer"
salience 100
lock-on-active true
    when
     c : Customer()
  forall( $stock : Stocks( quantity > 100, buyPrice > 10 ) from c.stocks)
 then
  c.setCustType("Platinum");
        System.out.println("Customer : " + c.getCustId() + " is a Platinum Customer");
        update(c);
end
Below is the output

Customer : C1506825 is a Platinum Customer