Drools Hattingen

From Training Material
Jump to navigation Jump to search

Drools solutions

Basic

EX1

rule "Select Salgrade" enabled false
when 
 $s : Salgrade()
then    
  System.out.println( $s.grade + " " + $s.losal + " " + $s.hisal)
end

EX2

rule "e2" enabled false
when 
 $e : Emp(sal > 1000 && < 2000)
then    
  System.out.println(
       $e.id + " " + 
       $e.name + "\t" + 
       $e.job + "   \t" +
       $e.mgr  + "\t" +
       $e.hiredate + " " + 
       $e.sal + " " + 
       $e.deptno )
end

EX3

rule "example 3"
when
	$e : Emp(job == "CLERK" && deptno == 20)
then
	System.out.println($e.id + "\t" + $e.name + "\t" + $e.job + "\t" + $e.mgr + "\t" + $e.hiredate + "\t" + $e.sal + "\t" + $e.deptno)
end

EX4

rule "Excercise 04"
when
	$e: Emp(job != "PRESIDENT")
then
	System.out.println($e.id + " " + $e.name + " " + $e.job + " " + $e.mgr + " " + $e.hiredate + " " + $e.sal + " " + $e.deptno)
end

EX5

rule "5a" enabled true
when 
 $e : Emp(job == "MANAGER" && $y: (sal*12))
then    
  System.out.println($e.name + " " + $y)
end

rule "5b" enabled false
when 
 $e : Emp(job == "MANAGER")
then    
  System.out.println($e.name + " " + ($e.sal *12))
end

EX6

rule "Find employees with second letter “L” and third “A”." enabled true
when 
 $e : Emp(name matches ".LA.*")
then    
  System.out.println($e.name)
end

EX7

rule "Select ends with N and contains T" 
when
	e : Emp(name matches ".*T.*N")
then    
    System.out.println(
       e.id + " " + 
       e.name + "\t" + 
       e.job + "   \t" +
       e.mgr  + "\t" +
       e.hiredate + " " + 
       e.sal * 12 + " " + 
       e.deptno );
end

EX8

rule "e8"
when 
 $e : Emp(job == "MANAGER" && deptno != 10) or
 $e : Emp(job != "MANAGER" && deptno == 10)
then    
  System.out.println(
       $e.id + " " + 
       $e.name + "\t" + 
       $e.job + "   \t" +
       $e.mgr  + "\t" +
       $e.hiredate + " " + 
       $e.sal + " " + 
       $e.deptno )
end
rule "Find employees who either work as managers or work in department no 10, but not both." enabled true
when 
 $e : (Emp(job == "MANAGER" , deptno != 10 ) or Emp(job != "MANAGER" , deptno == 10 ))
then    
  System.out.println($e.name + " " + $e.job + " " + $e.deptno)
end

Advanced

EX31

rule "Select the name of the employee and the city (LOC column in DEPT table) in which they work. "  enabled false
when
	$d : Dept()
	$e : Emp($d.deptno == deptno)
then
	System.out.println($e.name + "\t" + $d.loc)
end

EX32

rule "Excercise 32"
when
	$e: Emp()
	$d: Dept($e.deptno == deptno)
then
	System.out.println($e.name + " " + $d.dname + " " + $d.deptno)
end

EX33

rule "33" enabled false
when 
 $e : Emp($e.sal > 2000)
 $s : Salgrade($e.sal >= losal && $e.sal <= hisal)
then    
  System.out.println($e.name + " " + $e.sal +" " + $s.grade)
end

EX34

rule "34: Select employees working in London. " enabled true
when 
 $e : Emp()
 $d : Dept(deptno==$e.deptno , loc=="LONDON")
then    
  System.out.println($e.name+" "+$d.loc)
end

EX35

rule "E35"
when
  s :Salgrade()
  d :Dept(loc != 'LONDON')
  e :Emp(d.deptno == deptno && sal >= s.losal && sal <= s.hisal)
then    
  System.out.println(e.name + "\t" + d.loc + "\t" + s.grade)
end

EX36

rule "e36" enabled false
when
   d :Dept()
   not (Emp(deptno == d.deptno))
then    
  System.out.println( d.dname )
end

EX37

rule "Select an employee’s name and his/her boss’s name  " enabled false
when
	$e : Emp()
	$m : Emp(id == $e.mgr)
then
	System.out.println($e.name + " boss is " + $m.name)
end

EX38

rule "Excercise 38"
when
	$e: Emp()
	not Emp($e.mgr == id)
then
	System.out.println("E38 " + $e.name)
end

EX39

rule "39" enabled false
when 
 $e : Emp()
 not ( Emp($e.id == mgr))
then    
  System.out.println($e.name  )
end

EX41

rule "Select employees hired earlier than their bosses." enabled true
when 
 $e : Emp()
 $eb: Emp($e.mgr == id , $e.hiredate < $eb.hiredate)
then    
  System.out.println($e.name + " was hired in " + $e.hiredate + ", her boss "+$eb.name+" who was hired in "+$eb.hiredate)
end
rule "41. Select employees hired earlier than their bosses." enabled true
when 
	$emp : Emp($mgr : mgr, $empHireDate : hiredate)
	$boss : Emp(id == $mgr, $empHireDate < hiredate)
then    
  	System.out.println($emp.name + " hired in " + $empHireDate + " whose boss is " + $boss.name + " hired in " + $boss.hiredate)
end

EX44

rule "***Exercise" enabled true
when 
 $e : Emp(deptno==10)
 not (Emp(deptno==20 , job==$e.job))
 
then    
  System.out.println($e.job)
end

EX23

rule "Find the minimal, maximal and average salaries of people employed in 1981. "
when
  accumulate (e :Emp(hiredate == 1981), 
  	$avg : average(e.sal),
  	$min : min(e.sal),
  	$max : max(e.sal)
  	) 
then    
  System.out.println(
   "Average salary: " + $avg + "\n" +
  "Min salary: " + $min + "\n" +
  "Max salary: " + $max + "\n"
  )
end

EX24

rule "e24" enabled false
when
  accumulate (e :Emp(), 
  	$min : min(e.sal),
  	$max : max(e.sal)
  	) 
then    
  System.out.println(
   "Salary range: " + ($max - $min)
  )
end

EX26

rule "How many managers work for the company? "
when
	accumulate (
		$e : Emp(job == "MANAGER"),
		$count: count($e.job)
	)
then
	System.out.println(
  		"Managers: " + $count + "\n"
  )
end

EX25

// Excercise 25
declare SalByJob
   job : String
end

rule "Excercise 25"
when
   $e: Emp(j: job) and
   not SalByJob(job == $e.job)
   accumulate (e :Emp(job == j), 	$avg : average(e.sal)   	) 
then    
   System.out.println("E25 " + $e.job + " " + $avg)
   insert(new SalByJob(j))
end

EX27

declare DeptNo
   no : int
end
rule "27" enabled true
when
   Emp(d:deptno) and  not DeptNo(no == d)
   accumulate (e :Emp(deptno == d), $avgSal : average(e.sal)) 
then    
   System.out.println(  "Avg salary for deept " + d + " is " + ($avgSal*12) ) 
   insert(new DeptNo(d))
end

EX43

declare Jobs
	name: String
end

rule "43. *Exercise Find post filled in 1982 and 1983." enabled true
when 

e: Emp(hiredate==1982)
e2: Emp(hiredate==1983)
ee: Emp(job==e.job , job==e2.job)
not Jobs(name==ee.job)
then    
  System.out.println(ee.job)
  insert(new Jobs(ee.job))
end
rule "43+"
when
	e1 : Emp(hiredate == 1982)
	e2 : Emp(hiredate == 1983)
	exists (Emp(e1.job == job, e2.job == job))
then
   System.out.println( e1.job)
end

EX28

declare Depts
   dept : Integer
end

rule "Find departments with more than 3 workers."
when
  Emp(d: deptno) and  not Depts(d == dept)
  accumulate (e :Emp(deptno == d), 
  	$c : count(e)
   	) 
  Number(doubleValue > 3) from $c
then
   System.out.println("deptno: " + d + " count: " + $c)   
    insert(new Depts(d))
end

EX45

rule "45. Exercise Find employees earning more than the manager’s (job=='MANAGER') average." enabled true
when 
Number(avg : longValue) from accumulate (Emp(job=="MANAGER" , s: sal),average(s))
e: Emp(sal > avg) 
then    
  System.out.println(e.name+' earns '+e.sal)
end
rule "Exercise 45 Find employees earning more than the manager’s (job=='MANAGER') average." enabled false
when
  Number($avgNumber : longValue) from accumulate (e:Emp(job=='MANAGER'), average(e.sal))
  $e:Emp(sal > $avgNumber)
then
  System.out.println($e.name + ":" + $e.sal)
end

EX46

declare RichJobs
	job: String
	name: String
end
//Example 46
rule "Select employees earning the maximum salaries in their positions (jobs). "
when
	Emp($job: job, $name: name, $sal: sal) and not RichJobs($job == job, $name == name)
	accumulate (
		$e: Emp(job == $job),
		$max: max($e.sal)
	)
	Number($sal == $max) from $max
then
	System.out.println(
  		$name + " | " + $job + " | " + $max + "\n"
  	)
  	insert(new RichJobs($job, $name))
end
rule "46. Exercise* Select employees earning the maximum salaries in their positions. " enabled true
when
  Emp($job:job,$name:name)
  Number($max : longValue) from accumulate (Emp(job==$job,  $s: sal),max($s))
  $e : Emp(sal==$max, name==$name)
then    
  System.out.println($e.name+' as '+$e.job+' earns '+$e.sal)
end

EX51

rule "e51" enabled false
when
  Dept(dn :deptno)
  Number($avg : longValue) from accumulate (Emp(s: sal,deptno == dn ), average(s))
e : Emp(deptno == dn,sal > $avg)
then    
  System.out.println(e.name + " " + e.deptno +" " + e.sal )
end

EX55

declare AvgDep
	deptno: int
	avg: long
end

rule "55.a *Exercise Find the maximum average salary of departments. " enabled true
when 
		$dept : Dept($deptno:deptno,$dname:dname)
		Number($avg : longValue) from accumulate (Emp(deptno==$deptno,  $s: sal),average($s))
then    
  insert(new AvgDep($deptno,$avg))
end

rule "55.b " enabled true
when 
		Number($max : longValue) from accumulate (AvgDep($avg: avg),max($avg))
		AvgDep(avg==$max,$deptno:deptno)
		$d: Dept(deptno==$deptno)
then    
  System.out.println($d.dname+' '+$d.deptno+' '+ $max)
end
rule "55. Find the maximum average salary of departments." enabled true
when 
	Number($max : doubleValue) from accumulate(
		$dep : Dept($depId : deptno)
		and
		Number($avg : doubleValue) 
			from accumulate($emp : Emp(deptno == $depId),
		   		average($emp.sal)
			),
		max($avg)
	)
    d:Dept()
    Number($avgOfDept : doubleValue) from accumulate(e:Emp(deptno == d.deptno), average(e.sal))
    Number(doubleValue == $max) from $avgOfDept
then   
  	System.out.println(d.deptno + " Salary: " + $max)
end

DSL

EX1

[condition][]There are employees earning more than {salary}=e:Emp(sal > {salary})
[*][]Show name and salary=System.out.println("Name: " + e.name + " Salary: " + e.sal)
package rules1
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel" 

expander  Exercise01.dsl

rule "Rule 1"
 
when
 There are employees earning more than 2000
then
 Show name and salary

end
[condition][]There are employees=e : Emp()
[condition][]- earning more than {salary}=sal > {salary}
[consequence][]Show name and salary=System.out.println(e.name + "\t" + e.sal)
package rules1
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel" 

expander  Exercise01.dsl

rule "Rule 1"
 
when
 There are employees 
 - earning more than 2000
then
 Show name and salary

end

EX2

[condition][]There is a department which:=d:Dept()
[consequence][]Show department name=System.out.println(d.dname)
[condition][]has at least {c} employees working in it=accumulate(e:Emp(deptno == d.deptno), $countOfEmployees : count(e)) && Number(intValue >= {c}) from $countOfEmployees
[condition][]average salary is greater than {sal}=accumulate(e2:Emp(deptno == d.deptno), $avgSal: average(e2.sal)) &&  Number(doubleValue > {sal}) from $avgSal
package rules2
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel" 

expander  Exercise02.dsl

rule "Rule 2"
when
 There is a department which:
   has at least 3 employees working in it
   average salary is greater than 2000
then
 Show department name
end

EX3

[condition][]There are departments where:=d : Dept()
[condition][]there are analysts working in=exists Emp(job == 'ANALYST', deptno == d.deptno)
[consequence][]Show department name=System.out.println(d.dname)
package rules3
import com.nobleprog.FactModel.*;
import java.lang.Math
dialect "mvel" 

expander Exercise03.dsl


rule "Rule 3"
when
// Make sure that the rule will work for both cases
 There are departments where:
//  There is a department where:
	there are analysts working in 
	//also there is an anlyst working in it
then
 Show department name
end

insertLogical

Ex5.2

rules

declare Department10
	emp: Emp
end

declare AccessToSecretFiles
	emp: Emp
end

rule "Is in department 10"
when
	$e: Emp(deptno == 10)
then
	insertLogical(new Department10($e))
end

rule "Gets access to X Files"
when
	Department10($e: emp)
then
	insertLogical(new AccessToSecretFiles($e))
end

jUnit

Emp $blair = new Emp(7698, "BLAIR", "MANAGER", 7839, 1981, 2850, 10);
FactHandle $blairFH = ksession.insert($blair);

KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger((KnowledgeRuntimeEventManager) ksession, "/tmp/logicalinsert_exercise");
		
ksession.fireAllRules();
$blair.setDeptno(30);
ksession.update($blairFH, $blair);
ksession.fireAllRules();

Shopping Example 1

JUNIT

Customer customer = new Customer("heinz", 0);
kSession.insert(customer);
            
Product product1 = new Product("tomaten", 600);
kSession.insert(product1);
Product product2 = new Product("äpfel", 600);
kSession.insert(product2);
            
Purchase purchase1 = new Purchase(customer, product1);
kSession.insert(purchase1);
Purchase purchase2 = new Purchase(customer, product2);
FactHandle handle = kSession.insert(purchase2);
kSession.fireAllRules();
kSession.delete(handle);
kSession.fireAllRules();

RULES

package com.sample
 
import com.sample.DroolsTest.*;
 
rule "Notify about Purchase"
    when
        p : Purchase()
    then
        System.out.println( "New purchase " + p.getCustomer().getName() + " " + p.getProduct().getName() + " " + p.getProduct().getPrice() );
end

rule "Set Discount"
    when
    	$customer : Customer()
        Number($sum : longValue > 1000) from accumulate (Purchase(customer == $customer, $price: product.price),sum($price))
    then
        System.out.println( "Total purchase is " + $sum + ", add discount" );
        insertLogical(new Discount($customer, 10));
end

rule "Notify Discount"
	when
		d : Discount()
	then
		System.out.println( "Discount applied to " + d.getCustomer().getName() + " of " + d.getAmount() );
end

rule "Notify Discount removed"
	when
		not (Discount())
	then
		System.out.println( "Discount removed" );
end

Shopping Example 2

JUNIT

	    KieServices ks = KieServices.Factory.get();
    	    KieContainer kContainer = ks.getKieClasspathContainer();
        	KieSession kSession = kContainer.newKieSession("ksession-rules");

            // go !
        	Customer customer = new Customer("Christian", 99);
        	kSession.insert(customer);
        	
        	Product prod1 = new Product("Product 1", 600);
        	kSession.insert(prod1);
        	Product prod2 = new Product("Product 2", 600);
        	kSession.insert(prod2);
        	
        	Purchase purch1 = new Purchase(customer, prod1);
        	kSession.insert(purch1);
        	Purchase purch2 = new Purchase(customer, prod2);
        	FactHandle handle =kSession.insert(purch2);
            kSession.fireAllRules();
            
            kSession.delete(handle);
            kSession.fireAllRules();

RULES

rule "Notify" 
    no-loop true
    when
        c: Customer()
        p: Purchase(customer==c)
    then
        System.out.println(c.name+ " purchased " +p.product.name );
end

rule "2"
    when
        c: Customer() 
        accumulate (
        	u: Purchase(customer == c),
         	$sum: sum(u.product.price)
        )
        Number(intValue > 1000) from $sum
    then
    	c.setDiscount(10);
     	insertLogical(new Discount(c, 10));
        System.out.println( "Discount 10 for customer "+c.name );
end

rule "3"
    when
        c: Customer() and
        not Discount()
    then
    	c.setDiscount(0);
        System.out.println( "Discount 10 removed for customer "+c.name );
end

CEP

rules

package chapter06.cep;

import org.drools.devguide.eshop.events.TransactionEvent;

declare SuspiciousCustomerEvent
    @role(event)
    customerId: Long
    reason: String
end

declare AlarmTriggered
    customerId: Long
end

rule "More than 10 transactions in an hour from one client"
    when
        $t1: TransactionEvent($cId: customerId)
        Number(intValue >= 10) from accumulate(
            $t2: TransactionEvent(
                this != $t1, 
                customerId == $cId, 
                this meets[1h] $t1
            ),
            count($t2)
        )
        not (SuspiciousCustomerEvent(customerId == $cId, reason == "Many transactions"))
    then
        insert(new SuspiciousCustomerEvent($cId, "Many transactions"));
end

rule "More than 1 transaction of 200 dollars in an hour from the same client"
    when
        $t1: TransactionEvent($cId: customerId, totalAmount >= 200.0)
        $t2: TransactionEvent(
            this != $t1, 
            this meets[1h] $t1, 
            customerId == $cId, 
            totalAmount >= 200.0
        )
        not (SuspiciousCustomerEvent(customerId == $cId, reason == "Two large transactions"))
    then
        insert(new SuspiciousCustomerEvent($cId, "Two large transactions"));
end

rule "More than 3 suspicious cases in the day and we warn the owner"
    when
        SuspiciousCustomerEvent($cId: customerId)
        not (AlarmTriggered(customerId == $cId))
        Number(intValue >= 2) from accumulate(
            $s: SuspiciousCustomerEvent(customerId == $cId),
            count($s)
        )
    then
        //warn the owner
        System.out.println("WARNING: Suspicious fraud case. Client " + $cId);
        insert(new AlarmTriggered($cId));
end


rule "More than 10 transactions in an hour from small client portal"
    when
        $t1: TransactionEvent($cId: customerId) from entry-point "small-client-portal"
        Number(intValue >= 10) from accumulate(
            $t2: TransactionEvent(
                this != $t1, 
                customerId == $cId, 
                this meets[1h] $t1
            ) from entry-point "small-client-portal",
            count($t2)
        )
        not (SuspiciousCustomerEvent(customerId == $cId, reason == "Many transactions"))
    then
        insert(new SuspiciousCustomerEvent($cId, "Many transactions"));
end

rule "More than 100 transactions in an hour from big client portal"
    when
        $t1: TransactionEvent($cId: customerId) from entry-point "big-client-portal"
        Number(intValue >= 100) from accumulate(
            $t2: TransactionEvent(
                this != $t1, 
                customerId == $cId, 
                this meets[1h] $t1
            ) from entry-point "big-client-portal",
            count($t2)
        )
        not (SuspiciousCustomerEvent(customerId == $cId, reason == "Many transactions"))
    then
        insert(new SuspiciousCustomerEvent($cId, "Many transactions"));
end

jUnit

package org.drools.devguide;

import org.drools.devguide.eshop.events.TransactionEvent;
import org.junit.Test;
import org.kie.api.runtime.KieSession;

public class CEPRulesTest extends BaseTest {

    @Test
    public void testCEPRules() {
        KieSession ksession = createSession("cepKsession");
        Long customerId = 1L;
        ksession.insert(new TransactionEvent(customerId, 10.00));
        ksession.insert(new TransactionEvent(customerId, 12.00));
        ksession.insert(new TransactionEvent(customerId, 14.00));
        ksession.insert(new TransactionEvent(customerId, 10.50));
        ksession.insert(new TransactionEvent(customerId, 10.99));
        ksession.insert(new TransactionEvent(customerId, 9.00));
        ksession.insert(new TransactionEvent(customerId, 11.00));
        ksession.insert(new TransactionEvent(customerId, 15.00));
        ksession.insert(new TransactionEvent(customerId, 18.00));
        ksession.insert(new TransactionEvent(customerId, 201.00));
        long ruleFireCount = ksession.fireAllRules();
        System.out.println(ruleFireCount);
        ksession.insert(new TransactionEvent(customerId, 202.00));
        ruleFireCount = ksession.fireAllRules();
        System.out.println(ruleFireCount);
    }
}

fact model

package org.drools.devguide.eshop.events;

import java.io.Serializable;
import java.util.Date;

import org.kie.api.definition.type.Expires;
import org.kie.api.definition.type.Role;
import org.kie.api.definition.type.Timestamp;

@Role(Role.Type.EVENT)
@Timestamp("executionTime")
@Expires("2h30m")
public class TransactionEvent implements Serializable {

    private static final long serialVersionUID = 1L;
    private Date executionTime;
    private Long customerId;
    private Double totalAmount;

    public TransactionEvent() {
        super();
    }
    
    public TransactionEvent(Long customerId, Double totalAmount) {
        super();
        this.executionTime = new Date();
        this.customerId = customerId;
        this.totalAmount = totalAmount;
    }



    public Date getExecutionTime() {
        return executionTime;
    }

    public void setExecutionTime(Date executionTime) {
        this.executionTime = executionTime;
    }

    public Long getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Long customerId) {
        this.customerId = customerId;
    }

    public Double getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(Double totalAmount) {
        this.totalAmount = totalAmount;
    }
}

Code

File:Mastering Drools_Code.zip