SlideShare una empresa de Scribd logo
1 de 120
JBoss Drools

         by Victor Polischuk
Business Problem
 Model and Requirements
Party               PartyDef
id                     partyId
                       startTime
                       stopTime
             Partici   publicCode
 PartyRole
              pant
partyId
roleId                    Role
startTime              id
stopTime               publicCode
Order                   ProductDef
id                        productId
time          Order       startTime
inParty                   stopTime
inRole                    publicCode
outParty
outRole       OrderItem
inPartyId    orderId
inRoleId     quantity
outPartyId   productId         Product
outRoleId    product      id
1)Start-stop intervals must not overlap.
2)Entity exists only within start-stop interval.
3)Order must have valid and existent in party.
4)Order must have valid and existent out party.
5)Order must have valid and existent in role.
6)Order must have valid and existent out role.
7)Order items must have valid and existent
 product.
8)Order in and out parties must not be the
 same.
9)Order roles must be: (buyer, seller), (buyer,
 repairer), (repairer, seller), (seller, buyer).
Frontal Assault
    Conditions
public void placeOrder(Order order) {
}
public void placeOrder(Order order) {
  PartyDef ip = dao.findPartyBy(...);
}
public void placeOrder(Order order) {
  PartyDef ip = dao.findPartyBy(...);
  if (ip == null) {
      throw new Rule3Exception(...);
  }
}
public void placeOrder(Order order) {
  PartyDef ip = dao.findPartyBy(...);
  if (ip == null) {
      throw new Rule3Exception(...);
  }
  PartyDef op = dao.findPartyBy(...);
  if (op == null) {
      throw new Rule4Exception(...);
  }
}
public void placeOrder(Order order) {
  PartyDef ip = dao.findPartyBy(...);
  if (ip == null) {
      throw new Rule3Exception(...);
  }
  PartyDef op = dao.findPartyBy(...);
  if (op == null) {
      throw new Rule4Exception(...);
  }
  PartyRole ir = dao.findRoleBy(...);
  if (ir == null) {
      throw new Rule5Exception(...);
  }
}
public void placeOrder(Order order) {
  PartyDef ip = dao.findPartyBy(...);

    assertRule3(ip);

    PartyDef op = dao.findPartyBy(...);

    assertRule4(op);

    PartyRole ir = dao.findRoleBy(...);

    assertRule5(ir);
}
public void placeOrder(Order order) {
  PartyDef ip = getValidatedByRule3(...);
  PartyDef op = getValidatedByRule4(...);
  PartyRole ir = getValidatedByRule5(...);
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    PartyRole ir = getValidatedByRule5(...); //???
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    if (ip != null) {
        PartyRole ir = getValidatedByRule5(...);
    }
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    if (ip != null) {
        PartyRole ir = getValidatedByRule5(...);
    }
    if (op != null) {
        PartyRole or = getValidatedByRule6(...);
    }
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    if (ip != null) {
        PartyRole ir = getValidatedByRule5(...);
    }
    if (op != null) {
        PartyRole or = getValidatedByRule6(...);
    }
    if (ip != null && op != null && ip == op) {
        problems.add(...); // Rule #8 violation
    }
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    PartyRole ir = getSafeValidatedByRule5(...);
    PartyRole or = getSafeValidatedByRule6(...);
    validateRule8(...);
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    PartyRole ir = getSafeValidatedByRule5(...);
    PartyRole or = getSafeValidatedByRule6(...);
    validateRule8(...);
    if (ir != null && or != null && (...)) {
        problems.add(...); // Rule #9 violation
    }
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    PartyRole ir = getSafeValidatedByRule5(...);
    PartyRole or = getSafeValidatedByRule6(...);
    validateRule8(...);
    validateRule9(...);
    if (problems.isEmpty()) {
        order.inPartyId = ip.partyId;
        ...
    }
}
public void placeOrder(Order order) {
  List<Problem> problems = …;

    PartyDef ip = getValidatedByRule3(...);
    PartyDef op = getValidatedByRule4(...);
    PartyRole ir = getSafeValidatedByRule5(...);
    PartyRole or = getSafeValidatedByRule6(...);
    validateRule8(...);
    validateRule9(...);
    fillOrderIdentifications(...);
    // TODO: Rule #7
}
Clean the Mess
 Independent Rules
Rule            RuleConfig




Context          RuleRunner




          Data
class RuleRunner...
public <T> List<Problem> run(<T> data) {
  List<Problem> problems = …;
  Context context = …;
  RuleConfig config = …;
  while (config.hasNext(context)) {
     Rule rule = config.next(context);
     try {
        rule.execute(context, data);
     } catch (…) {
        problems.add(...);
     }
  }
}
class RuleConfig...
private final List<Rule> rules = …;
public Rule next(Context context) {
  Rule rule = null;
  int i = context.getLatestRuleIndex();
  while (i < rules.size() && rule == null) {
     If (rules.get(i).accepts(context)) {
         rule = rules.get(i);
     }
     i++;
  }
  context.setLatestRuleIndex(i);
  return rules.get(i);
}
interface Rule<T> {

    boolean accepts(Context context);

    void execute(Context context, T data);

}
class RuleN3 implements Rule<Order>

public boolean accepts(Context ctx) {
  return true;
}
public void execute(Context ctx,Order data) {
  PartyDef ip = dao.findPartyBy(...);
  if (ip == null) {
      throw new Rule3Exception(...);
  }
  ctx.inPartyDef = ip;
  data.inPartyId = ip.partyId;
}
class RuleN8 implements Rule<Order>

public boolean accepts(Context ctx) {
  return ctx.inPartyDef != null &&
            ctx.outPartyDef != null;
}
public void execute(Context ctx,Order data) {
  PartyDef ip = dao.findPartyBy(...);
  if (ctx.inPartyDef == ctx.outPartyDef) {
      throw new Rule8Exception(...);
  }
}
One More Step
  Expert System
Rule            RuleConfig




Context          RuleRunner




          Data
KnowledgeBas
    Rule
                             e



WorkingMemor
                        RuleEngine
      y



               Facts
Simple Rule Engine

  Decision Block     3
                     1   Rule

  Decision Block     4   Rule

  Decision Block     5   Rule

  Decision Block     6   Rule

      Result
Expert System

Decision Block   3
                 1   Rule

Decision Block   4   Rule

Decision Block   5   Rule

Decision Block   6   Rule

   Result
Process
              Order


 Fix          Error
Routing         ?

Fixed
          End Processing
   ?
Rule 1       Fact 1
Rule 2       Fact 2
Rule 3       Fact 3
         *            * Repeats = ?
Rule 4       Fact 4
  ...          ...
Rule N       Fact M
Rule 1       Fact 1
Rule 2       Fact 2
Rule 3       Fact 3
         *            * Repeats = ?
Rule 4       Fact 4
  ...          ...
Rule N       Fact M

             Inefficient
To the Rescue
     Rete
Rete = Net

         Charles L. Forgy


             1979
1974
                    1982
                     © Wikipedia.org
Root Node

                  Start



All Facts Pass Through It
1-input Nodes

       Alpha Network

IntraElement Conditions
2-input Nodes
Beta Network




 Two Element Comparison
Terminal Nodes
                     Stop
 Rules Have a Full Match
Drools
 Finally
Drools Rule Pattern
rule "Rule example" // Rule unique name
... // Rule attributes: grouping, priority, etc.
when
      ... // Left hand side. Condition.
then
      ... // Right hand side. Consequence.
end
THE <consequence
IF   <condition>
                    N        >
rule "Rule #3 violation"
when
  $o : Order($id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  eval( dao.findPartyBy($t, $pty)==null )
then
  log.info("Rule #3 violated for the order: " + $id);
  insert(new Problem($id, 3));
end
rule "Rule #3 fulfillment"
when
  $o : Order(inPartyId==null,
              $id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  eval( dao.findPartyBy($t, $pty)!=null )
then
  log.info("Rule #3 fulfilled for the order: " + $id);
  modify($o) {
     setInPartyId(
        dao.findPartyBy($t, $pty).getPartyId()
     )
  };
end
class RuleN3 implements Rule<Order>

public boolean accepts(Context ctx) {
  return true;
}
public void execute(Context ctx,Order data) {
  PartyDef ip = dao.findPartyBy(...);
  if (ip == null) {
      throw new Rule3Exception(...);
  }
  ctx.inPartyDef = ip;
  data.inPartyId = ip.partyId;
}
If Java Is Simpler
       Why Use Drools?
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
class RuleN7 implements Rule<Order>

public boolean accepts(Context ctx) {
  return true;
}
public void execute(Context ctx,Order data) {
  for (OrderItem item : data.items) {
    ProductDef pd = dao.findProductBy(...);

        if (pd == null) {
            throw new Rule7Exception(...); //???
        }
    }
}
Java Solution #1
   Complex Rule
class RuleN7_1 implements Rule<Order>

public boolean accepts(Context ctx) {
  return true;
}
public void execute(Context ctx,Order data) {
  for (OrderItem item : data.items) {
    ProductDef pd = dao.findProductBy(...);

        if (pd == null) {
            ctx.addRule7Error(...); //OK
        }
    }
}
Java Solution #2
Complex Runner and Configuration
class RuleN7_2 implements Rule<OrderItem>

public boolean accepts(Context ctx) {
  return true;
}
public void execute(Context ctx,OrderItem data) {
  ProductDef pd = dao.findProductBy(...);

    if (pd == null) {
        throw new Rule7Exception(...); //OK
    }
}
Drools
 Again?
rule "Rule #3 violation"
when
  $o : Order($id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  eval( dao.findPartyBy($t, $pty)==null )
then
  log.info("Rule #3 violated for the order: " + $id);
  insert(new Problem($id, 3));
end
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
Yet Another Validation Tool
           Or Not?
package com.victor.drools
dialect "mvel"
import com.victor.drools.*; // optional

global GeneralDao dao;
global org.slf4j.Logger log;

declare Problem
  orderId : long @key
  ruleId : int @key
end
declare OIProblem extends Problem
  product : String @key
end
Drools Class Declaration
declare ExampleClass // Class name
[extends ParentExampleClass] // Inheritance
    @stringMetadata("I am String") // Metadata
    @dateMetadata(01-Jan-1970)


    propertyName1 : ValidType, // Properties
    propertyName2 : AnotherValidType
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
Drools Function Declaration
function String hello(String name) {
    return "Hello "+name+"!";
}
rule "Function usage in LHS"
when
  eval( hello("Victor")!="Hello Victor!" )
then
  int faults = ++alexeyFaults.count;
  log.fatal("Alexey, fix hello(..) function");
  log.anger("You'd better be off");
  log.info("You've broken it " +faults+ " time(s)");
end
rule "Function usage in RHS"
when
  eval(true)
then
  log.happiness(hello("Victor"));
  log.worship(hello("Master"));
end
Drools Query Declaration
query "Orders with inParty"
  $o : Order(inParty != null)
end


query "Orders with inRole equals to" (String
 role)
  $o : Order(inRole == role)
end
Drools Templates
template header
field1... // Template fields
template “TemplateName”
rule "ExampleRule_@{row.rowNumber}"
... // Usage of declared fields
end
end template
Promotional       Age      Number of     Policy type    Discount %
 discount rules    Bracket     prior       applying for
                              claims

Rewards for safe    18,24       0        COMPREHENSIVE        1
    drivers


                    18,24       0          FIRE_THEFT         2



                    25,30       1        COMPREHENSIVE        5



                    25,30       2        COMPREHENSIVE        1



                    25,30       0        COMPREHENSIVE       20



                                                           © jboss.org
Pièce de Résistance
        DSL
rule "Rule #3 violation"
when
  $o : Order($id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  eval( dao.findPartyBy($t, $pty)==null )
then
  log.info("Rule #3 violated for the order: " + $id);
  insert(new Problem($id, 3));
end
rule "Rule #3 violation"
when
  Every Order
  Without violations of rule 3
  Which violates inParty constraints
then
  Add the violation of the rule 3
end
[when] Every Order = $o : Order($id:id, $t:time,
$inPty:inParty)

[when] Without violations of rule {ruleNumber} =
not(Problem(orderId==$id, ruleId=={ruleNumber}))
[when] Which violates inParty constraints =
eval( dao.findPartyBy($t, $inPty) == null )

[then] Add the violation of the rule {ruleNumber} =
log.info("Rule #" + {ruleNumber} + " violated for
order: " + $id); insert(new Problem($id,
{ruleNumber}));
rule "Rule #4 violation"
when
  Every Order
  Without violations of rule 4
  Which violates outParty constraints
then
  Add the violation of the rule 4
end
[when] Every Order = $o : Order($id:id, $t:time,
$inPty:inParty)

[when] Without violations of rule {ruleNumber} =
not(Problem(orderId==$id, ruleId=={ruleNumber}))
[when] Which violates inParty constraints =
eval( dao.findPartyBy($t, $inPty) == null )

[then] Add the violation of the rule {ruleNumber} =
log.info("Rule #" + {ruleNumber} + " violated for
order: " + $id); insert(new Problem($id,
{ruleNumber}));
[when] Every Order = $o : Order($id:id, $t:time,
$inPty:inParty,$outPty:outParty)

[when] Without violations of rule {ruleNumber} =
not(Problem(orderId==$id, ruleId=={ruleNumber}))
[when] Which violates inParty constraints =
eval( dao.findPartyBy($t, $inPty) == null )
[when] Which violates outParty constraints =
eval( dao.findPartyBy($t, $outPty) == null )
[then] Add the violation of the rule {ruleNumber} =
log.info("Rule #" + {ruleNumber} + " violated for
order: " + $id); insert(new Problem($id,
{ruleNumber}));
Seven?
Let's have fun
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
rule "Rule #7 violation"
when
  $o : Order(items!=null, $id:id, $t:time)
  $item : OrderItem($prd:product) from $o.items
  not( OIProblem(orderId==$id, ruleId==7,
                         product==$prd) )
  eval(dao.findProductBy($t, $prd)==null)
then
  log.info("Rule #7 violated for order: " + $id
         + " and product: " + $prd);
  insert(new OIProblem($id, 7, $prd));
end
rule "Rule #7 violation"
when
  Every Order
     - which has items
  And every OrderItem
  Without violations of order item rule 7
  Which violates product constraints
then
  Add the violation of the rule 7 for the order item
end
[when] Every Order =



[when] Without violations of rule {N} =
[when] Which violates inParty constraints =
[when] Which violates outParty constraints =




[then] Add the violation of the rule {N} =
[when] Every Order =
[when] - which has items = items != null

[when] And every OrderItem =
[when] Without violations of rule {N} =
[when] Which violates inParty constraints =
[when] Which violates outParty constraints =
[when] Without violations of order item rule {N} =
[when] Which violates product constraints =

[then] Add the violation of the rule {N} for order
item =
[then] Add the violation of the rule {N} =
I Do Believe
  Am I Alone?
Meanwhile in the Real World...
       Requirements Change
1)Start-stop intervals must not overlap.
2)Entity exists only within start-stop interval.
3)Order must have valid and existent in party.
4)Order must have valid and existent out party.
5)Order must have valid and existent in role.
6)Order must have valid and existent out role.
7)Order items must have valid and existent
 product.
8)Order in and out parties CAN be the same.
 ONLY IF they have roles (seller, repairer).
9)Order roles must be: (buyer, seller), (buyer,
 repairer), (repairer, seller), (seller, buyer). OR
 (seller, repairer) if they are the same.
rule "Rule #8 violation"
when
  $o : Order(
             inPartyId != null, outPartyId != null,
             outPartyId == inPartyId,
             $id : id)
  not( Problem(orderId == $id,
                        ruleId in (3, 4, 8)) )
then
  log.info("Rule #8 violated for order: " + $id);
  insert(new Problem($id, 8));
end
rule "Rule #8 violation"
when
  $o : Order(!(inRole == "S" && outRole == "R"),
             inPartyId != null, outPartyId != null,
             outPartyId == inPartyId,
             $id : id)
  not( Problem(orderId == $id,
                        ruleId in (3, 4, 8)) )
then
  log.info("Rule #8 violated for order: " + $id);
  insert(new Problem($id, 8));
end
rule "Rule #8 violation"
when
  Every Order
     - with inPartyId
     - with outPartyId
     - where inPartyId equals outPartyId
     - and inRole not "S" and outRole not "R"
  Without violations of rules [3,4,8]
then
  Add the violation of the rule 8
end
rule "Rule #8 exceptional case"
// salience 100
when
   $o : Order(inRole == "S", outRole == "R",
              inPartyId != null, outPartyId != null,
              outPartyId == inPartyId,
              $id : id)
then
   log.info("Rule #8 special case for order: " +
$id);
   insertLogical(new SkipRule($id, 8));
end
rule "Rule #8 violation"
when
  $o : Order(
             inPartyId != null, outPartyId != null,
             outPartyId == inPartyId,
             $id : id)
  not( SkipRule(orderId == $id, ruleId == 8) )
  not(Problem(orderId == $id,
                        ruleId in (3, 4, 8)) )
then
  log.info("Rule #8 violated for order: " + $id);
  insert(new Problem($id, 8));
end
rule "Cleanup skipped rules"
when
  $o : Order($id : id)
  SkipRule(orderId == $id,
               $rId : ruleId)
  $p : Problem(orderId == $id, ruleId == $rId)
then
  log.info("Retract #" + $rId + " for order: " + $id);
  retract($p);
end
Houston, we've got a problem
      Performance & Resources
Rete          Adapters/Eval


Entry Point            Join


Object Type            Not


Alpha              Terminal
Rete

 Entry Point     Entry Point Node
Scope 1      EntryPointNode#1
Scope 2      EntryPointNode#2
Scope 3      EntryPointNode#3
Entry Point Node

Object Type      Object Type Node
Order         ObjectTypeNode#1
PartyDef      ObjectTypeNode#2
Problem       ObjectTypeNode#3
OIProblem     ObjectTypeNode#4
Object Type Node (Order)

             Fact Set
Order#112
Order#113
Order#114
Order#115
...
Object Type Node (Order)

     Literal            Alpha Node
inParty == null    AlphaNode#1
inParty != null    AlphaNode#2
outParty == null   AlphaNode#3
outParty != null   AlphaNode#4
Alpha Node

            Fact Set
Order#1
Order#5
Order#6
...
Join Node

         Left              Right
Order#1, SkipRule#5    Problem#1
Order#5, SkipRule#15   Problem#5
Order#6, SkipRule#11   Problem#6
...                    ...
                       Problem#11
                       Problem#12
Not Node

         Left              Right
Order#1, OrderItem#5   Problem#1
Order#1, OrderItem#1   Problem#5
Order#1, OrderItem#3   Problem#6
...                    ...
                       Problem#11
                       Problem#12
Eval



       No Cache
       No Memory
rule "Rule #3 violation"
when
  $o : Order($id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  eval( dao.findPartyBy($t, $pty)==null )
then
  log.info("Rule #3 violated for the order: " + $id);
  insert(new Problem($id, 3));
end
rule "Rule #3 fulfillment"
when
  $o : Order(inPartyId==null,
              $id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  eval( dao.findPartyBy($t, $pty)!=null )
then
  log.info("Rule #3 fulfilled for the order: " + $id);
  modify($o) {
     setInPartyId(
        dao.findPartyBy($t, $pty).getPartyId()
     )
  };
end
Hard to Test            Inefficient

      High Cost of Refactoring

    Impossible Exception Handling

Can Change State Between Invocations

       Usually Less Readable
Replace EVAL
  Prefetch Data
rule "Rule #3 violation"
when
  $o : Order($id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  not( PartyDef(publicCode == $pty,
               startTime <= $t, stopTime > $t) )
then
  log.info("Rule #3 violated for the order: " + $id);
  insert(new Problem($id, 3));
end
rule "Rule #3 fulfillment"
when
  $o : Order(inPartyId==null,
             $id:id, $t:time, $pty:inParty)
  not( Problem(orderId==$id, ruleId==3) )
  $p : PartyDef(publicCode == $pty,
               startTime <= $t, stopTime > $t)
then
  log.info("Rule #3 fulfilled for the order: " + $id);
  modify($o) {
     inPartyId = $p.getPartyId();
  };
end
rule "Prefetch inParty PartyDef"
salience 100
when
  Order(inParty!=null, $t:time, $pCode:inParty)
  not( PartyDef(publicCode == $pCode,
                startTime <= $t, stopTime > $t) )
then
  PartyDef pd = dao.findPartyBy($t, $pCode);

  if (pd != null) {
      log.info("insert party: " + pd.getPartyId());
      insert(pd);
  }
end
rule "Prefetch inParty PartyDef"
salience 100
when
  Order(inParty!=null, $t:time, $pCode:inParty)
  not( PartyDef(publicCode == $pCode,
                startTime <= $t, stopTime > $t) )
then
  PartyDef pd = dao.findPartyBy($t, $pCode);
  log.info("insert party (if exists): " + pd);
  insert(pd); // null won't be inserted
end
Hard to Test            Inefficient

      High Cost of Refactoring

    Impossible Exception Handling

Can Change State Between Invocations

       Usually Less Readable

    Several More Rules to Support
???

      http://docs.jboss.org/

      http://akinator.com/

Más contenido relacionado

La actualidad más candente

R. herves. clean code (theme)2
R. herves. clean code (theme)2R. herves. clean code (theme)2
R. herves. clean code (theme)2saber tabatabaee
 
Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)Oliver Klee
 
The Anatomy of an Exploit (NDC TechTown 2019)
The Anatomy of an Exploit (NDC TechTown 2019)The Anatomy of an Exploit (NDC TechTown 2019)
The Anatomy of an Exploit (NDC TechTown 2019)Patricia Aas
 
The Macronomicon
The MacronomiconThe Macronomicon
The MacronomiconMike Fogus
 
Towards Reusable Components With Aspects [ICSE 2008]
Towards Reusable Components With Aspects [ICSE 2008]Towards Reusable Components With Aspects [ICSE 2008]
Towards Reusable Components With Aspects [ICSE 2008]Kevin Hoffman
 
The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88Mahmoud Samir Fayed
 
DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)cruisercoder
 
The Ring programming language version 1.6 book - Part 184 of 189
The Ring programming language version 1.6 book - Part 184 of 189The Ring programming language version 1.6 book - Part 184 of 189
The Ring programming language version 1.6 book - Part 184 of 189Mahmoud Samir Fayed
 
The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189Mahmoud Samir Fayed
 
Scripting
ScriptingScripting
Scriptingaztack
 
The Ring programming language version 1.5.4 book - Part 32 of 185
The Ring programming language version 1.5.4 book - Part 32 of 185The Ring programming language version 1.5.4 book - Part 32 of 185
The Ring programming language version 1.5.4 book - Part 32 of 185Mahmoud Samir Fayed
 
Executable documentation
Executable documentationExecutable documentation
Executable documentationRussell Gold
 
The Ring programming language version 1.5 book - Part 5 of 31
The Ring programming language version 1.5 book - Part 5 of 31The Ring programming language version 1.5 book - Part 5 of 31
The Ring programming language version 1.5 book - Part 5 of 31Mahmoud Samir Fayed
 

La actualidad más candente (20)

R. herves. clean code (theme)2
R. herves. clean code (theme)2R. herves. clean code (theme)2
R. herves. clean code (theme)2
 
Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)
 
1 d array
1 d array1 d array
1 d array
 
The Anatomy of an Exploit (NDC TechTown 2019)
The Anatomy of an Exploit (NDC TechTown 2019)The Anatomy of an Exploit (NDC TechTown 2019)
The Anatomy of an Exploit (NDC TechTown 2019)
 
Clean code
Clean codeClean code
Clean code
 
Python & Stuff
Python & StuffPython & Stuff
Python & Stuff
 
The Macronomicon
The MacronomiconThe Macronomicon
The Macronomicon
 
Towards Reusable Components With Aspects [ICSE 2008]
Towards Reusable Components With Aspects [ICSE 2008]Towards Reusable Components With Aspects [ICSE 2008]
Towards Reusable Components With Aspects [ICSE 2008]
 
The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88
 
DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)DConf 2016 std.database (a proposed interface & implementation)
DConf 2016 std.database (a proposed interface & implementation)
 
The Ring programming language version 1.6 book - Part 184 of 189
The Ring programming language version 1.6 book - Part 184 of 189The Ring programming language version 1.6 book - Part 184 of 189
The Ring programming language version 1.6 book - Part 184 of 189
 
The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189The Ring programming language version 1.6 book - Part 34 of 189
The Ring programming language version 1.6 book - Part 34 of 189
 
Scripting
ScriptingScripting
Scripting
 
Pdr ppt
Pdr pptPdr ppt
Pdr ppt
 
Google guava
Google guavaGoogle guava
Google guava
 
The Ring programming language version 1.5.4 book - Part 32 of 185
The Ring programming language version 1.5.4 book - Part 32 of 185The Ring programming language version 1.5.4 book - Part 32 of 185
The Ring programming language version 1.5.4 book - Part 32 of 185
 
Executable documentation
Executable documentationExecutable documentation
Executable documentation
 
Unit Testing with Foq
Unit Testing with FoqUnit Testing with Foq
Unit Testing with Foq
 
The Ring programming language version 1.5 book - Part 5 of 31
The Ring programming language version 1.5 book - Part 5 of 31The Ring programming language version 1.5 book - Part 5 of 31
The Ring programming language version 1.5 book - Part 5 of 31
 
Java Generics - by Example
Java Generics - by ExampleJava Generics - by Example
Java Generics - by Example
 

Destacado

JEEConf JBoss Drools
JEEConf JBoss DroolsJEEConf JBoss Drools
JEEConf JBoss DroolsVictor_Cr
 
JBoss Drools - Open-Source Business Logic Platform
JBoss Drools - Open-Source Business Logic PlatformJBoss Drools - Open-Source Business Logic Platform
JBoss Drools - Open-Source Business Logic Platformelliando dias
 
Jboss jbpm and drools 1 introduction to drools architecture
Jboss jbpm and drools   1 introduction to drools architectureJboss jbpm and drools   1 introduction to drools architecture
Jboss jbpm and drools 1 introduction to drools architectureZoran Hristov
 
Jboss drools 4 scope - benefits, shortfalls
Jboss drools   4 scope - benefits, shortfalls Jboss drools   4 scope - benefits, shortfalls
Jboss drools 4 scope - benefits, shortfalls Zoran Hristov
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep diveMario Fusco
 
JBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule EngineJBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule EngineAnil Allewar
 
Rules Programming tutorial
Rules Programming tutorialRules Programming tutorial
Rules Programming tutorialSrinath Perera
 
Rule Engine & Drools
Rule Engine & DroolsRule Engine & Drools
Rule Engine & DroolsSandip Jadhav
 
JBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTE
JBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTEJBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTE
JBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTEtsurdilovic
 

Destacado (14)

JEEConf JBoss Drools
JEEConf JBoss DroolsJEEConf JBoss Drools
JEEConf JBoss Drools
 
Rule engine
Rule engineRule engine
Rule engine
 
JBoss Drools - Open-Source Business Logic Platform
JBoss Drools - Open-Source Business Logic PlatformJBoss Drools - Open-Source Business Logic Platform
JBoss Drools - Open-Source Business Logic Platform
 
Jboss jbpm and drools 1 introduction to drools architecture
Jboss jbpm and drools   1 introduction to drools architectureJboss jbpm and drools   1 introduction to drools architecture
Jboss jbpm and drools 1 introduction to drools architecture
 
JBoss World 2011 - Drools
JBoss World 2011 - DroolsJBoss World 2011 - Drools
JBoss World 2011 - Drools
 
Rule engine
Rule engineRule engine
Rule engine
 
Jboss drools 4 scope - benefits, shortfalls
Jboss drools   4 scope - benefits, shortfalls Jboss drools   4 scope - benefits, shortfalls
Jboss drools 4 scope - benefits, shortfalls
 
Rules With Drools
Rules With DroolsRules With Drools
Rules With Drools
 
Drools
DroolsDrools
Drools
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep dive
 
JBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule EngineJBoss Drools - Pure Java Rule Engine
JBoss Drools - Pure Java Rule Engine
 
Rules Programming tutorial
Rules Programming tutorialRules Programming tutorial
Rules Programming tutorial
 
Rule Engine & Drools
Rule Engine & DroolsRule Engine & Drools
Rule Engine & Drools
 
JBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTE
JBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTEJBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTE
JBoss Drools and Drools Fusion (CEP): Making Business Rules react to RTE
 

Similar a JBoss Drools

Unit 6
Unit 6Unit 6
Unit 6siddr
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code DevelopmentPeter Gfader
 
Python fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanPython fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanWei-Yuan Chang
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartGabriele Lana
 
OrderTest.javapublic class OrderTest {       Get an arra.pdf
OrderTest.javapublic class OrderTest {         Get an arra.pdfOrderTest.javapublic class OrderTest {         Get an arra.pdf
OrderTest.javapublic class OrderTest {       Get an arra.pdfakkhan101
 
Ida python intro
Ida python introIda python intro
Ida python intro小静 安
 
Programming JVM Bytecode with Jitescript
Programming JVM Bytecode with JitescriptProgramming JVM Bytecode with Jitescript
Programming JVM Bytecode with JitescriptJoe Kutner
 
ORMLite Android
ORMLite AndroidORMLite Android
ORMLite Android哲偉 楊
 
Programming JVM Bytecode
Programming JVM BytecodeProgramming JVM Bytecode
Programming JVM BytecodeJoe Kutner
 
Trying to learn C# (NDC Oslo 2019)
Trying to learn C# (NDC Oslo 2019)Trying to learn C# (NDC Oslo 2019)
Trying to learn C# (NDC Oslo 2019)Patricia Aas
 
Spring Data for KSDG 2012/09
Spring Data for KSDG 2012/09Spring Data for KSDG 2012/09
Spring Data for KSDG 2012/09永昇 陳
 
Python Peculiarities
Python PeculiaritiesPython Peculiarities
Python Peculiaritiesnoamt
 
C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewPaulo Morgado
 
Richard wartell malware is hard. let's go shopping!!
Richard wartell   malware is hard.  let's go shopping!!Richard wartell   malware is hard.  let's go shopping!!
Richard wartell malware is hard. let's go shopping!!Shakacon
 
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...adrianoalmeida7
 
Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113SOAT
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 

Similar a JBoss Drools (20)

Unit 6
Unit 6Unit 6
Unit 6
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code Development
 
Python fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanPython fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuan
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing Part
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 
OrderTest.javapublic class OrderTest {       Get an arra.pdf
OrderTest.javapublic class OrderTest {         Get an arra.pdfOrderTest.javapublic class OrderTest {         Get an arra.pdf
OrderTest.javapublic class OrderTest {       Get an arra.pdf
 
Ida python intro
Ida python introIda python intro
Ida python intro
 
Programming JVM Bytecode with Jitescript
Programming JVM Bytecode with JitescriptProgramming JVM Bytecode with Jitescript
Programming JVM Bytecode with Jitescript
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Process management
Process managementProcess management
Process management
 
ORMLite Android
ORMLite AndroidORMLite Android
ORMLite Android
 
Programming JVM Bytecode
Programming JVM BytecodeProgramming JVM Bytecode
Programming JVM Bytecode
 
Trying to learn C# (NDC Oslo 2019)
Trying to learn C# (NDC Oslo 2019)Trying to learn C# (NDC Oslo 2019)
Trying to learn C# (NDC Oslo 2019)
 
Spring Data for KSDG 2012/09
Spring Data for KSDG 2012/09Spring Data for KSDG 2012/09
Spring Data for KSDG 2012/09
 
Python Peculiarities
Python PeculiaritiesPython Peculiarities
Python Peculiarities
 
C# 6.0 - April 2014 preview
C# 6.0 - April 2014 previewC# 6.0 - April 2014 preview
C# 6.0 - April 2014 preview
 
Richard wartell malware is hard. let's go shopping!!
Richard wartell   malware is hard.  let's go shopping!!Richard wartell   malware is hard.  let's go shopping!!
Richard wartell malware is hard. let's go shopping!!
 
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi constr...
 
Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 

Más de Victor_Cr

Data Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backData Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backVictor_Cr
 
Data Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backData Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backVictor_Cr
 
Type War: Weak vs Strong [JEEConf 2016]
Type War: Weak vs Strong [JEEConf 2016]Type War: Weak vs Strong [JEEConf 2016]
Type War: Weak vs Strong [JEEConf 2016]Victor_Cr
 
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Victor_Cr
 
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Victor_Cr
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Victor_Cr
 
Web-application I’ve always dreamt of (Kharkiv)
Web-application I’ve always dreamt of (Kharkiv)Web-application I’ve always dreamt of (Kharkiv)
Web-application I’ve always dreamt of (Kharkiv)Victor_Cr
 
Web application I have always dreamt of (Lviv)
Web application I have always dreamt of (Lviv)Web application I have always dreamt of (Lviv)
Web application I have always dreamt of (Lviv)Victor_Cr
 
Web application I have always dreamt of
Web application I have always dreamt ofWeb application I have always dreamt of
Web application I have always dreamt ofVictor_Cr
 
Legacy projects: how to win the race
Legacy projects: how to win the raceLegacy projects: how to win the race
Legacy projects: how to win the raceVictor_Cr
 
Legacy projects: how to win the race
Legacy projects: how to win the raceLegacy projects: how to win the race
Legacy projects: how to win the raceVictor_Cr
 
Jboss drools expert (ru)
Jboss drools expert (ru)Jboss drools expert (ru)
Jboss drools expert (ru)Victor_Cr
 
XPDays Ukraine: Legacy
XPDays Ukraine: LegacyXPDays Ukraine: Legacy
XPDays Ukraine: LegacyVictor_Cr
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Victor_Cr
 

Más de Victor_Cr (15)

Data Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backData Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes back
 
Data Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes backData Wars: The Bloody Enterprise strikes back
Data Wars: The Bloody Enterprise strikes back
 
Type War: Weak vs Strong [JEEConf 2016]
Type War: Weak vs Strong [JEEConf 2016]Type War: Weak vs Strong [JEEConf 2016]
Type War: Weak vs Strong [JEEConf 2016]
 
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
 
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
Types: Weak/Duck/Optional vs Strong/Strict. Let the War Begin!
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)
 
Web-application I’ve always dreamt of (Kharkiv)
Web-application I’ve always dreamt of (Kharkiv)Web-application I’ve always dreamt of (Kharkiv)
Web-application I’ve always dreamt of (Kharkiv)
 
Web application I have always dreamt of (Lviv)
Web application I have always dreamt of (Lviv)Web application I have always dreamt of (Lviv)
Web application I have always dreamt of (Lviv)
 
Web application I have always dreamt of
Web application I have always dreamt ofWeb application I have always dreamt of
Web application I have always dreamt of
 
Legacy projects: how to win the race
Legacy projects: how to win the raceLegacy projects: how to win the race
Legacy projects: how to win the race
 
Legacy projects: how to win the race
Legacy projects: how to win the raceLegacy projects: how to win the race
Legacy projects: how to win the race
 
Jboss drools expert (ru)
Jboss drools expert (ru)Jboss drools expert (ru)
Jboss drools expert (ru)
 
JEEConf WEB
JEEConf WEBJEEConf WEB
JEEConf WEB
 
XPDays Ukraine: Legacy
XPDays Ukraine: LegacyXPDays Ukraine: Legacy
XPDays Ukraine: Legacy
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"
 

JBoss Drools

  • 1. JBoss Drools by Victor Polischuk
  • 2. Business Problem Model and Requirements
  • 3. Party PartyDef id partyId startTime stopTime Partici publicCode PartyRole pant partyId roleId Role startTime id stopTime publicCode
  • 4. Order ProductDef id productId time Order startTime inParty stopTime inRole publicCode outParty outRole OrderItem inPartyId orderId inRoleId quantity outPartyId productId Product outRoleId product id
  • 5. 1)Start-stop intervals must not overlap. 2)Entity exists only within start-stop interval. 3)Order must have valid and existent in party. 4)Order must have valid and existent out party. 5)Order must have valid and existent in role. 6)Order must have valid and existent out role. 7)Order items must have valid and existent product. 8)Order in and out parties must not be the same. 9)Order roles must be: (buyer, seller), (buyer, repairer), (repairer, seller), (seller, buyer).
  • 6. Frontal Assault Conditions
  • 8. public void placeOrder(Order order) { PartyDef ip = dao.findPartyBy(...); }
  • 9. public void placeOrder(Order order) { PartyDef ip = dao.findPartyBy(...); if (ip == null) { throw new Rule3Exception(...); } }
  • 10. public void placeOrder(Order order) { PartyDef ip = dao.findPartyBy(...); if (ip == null) { throw new Rule3Exception(...); } PartyDef op = dao.findPartyBy(...); if (op == null) { throw new Rule4Exception(...); } }
  • 11. public void placeOrder(Order order) { PartyDef ip = dao.findPartyBy(...); if (ip == null) { throw new Rule3Exception(...); } PartyDef op = dao.findPartyBy(...); if (op == null) { throw new Rule4Exception(...); } PartyRole ir = dao.findRoleBy(...); if (ir == null) { throw new Rule5Exception(...); } }
  • 12. public void placeOrder(Order order) { PartyDef ip = dao.findPartyBy(...); assertRule3(ip); PartyDef op = dao.findPartyBy(...); assertRule4(op); PartyRole ir = dao.findRoleBy(...); assertRule5(ir); }
  • 13. public void placeOrder(Order order) { PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); PartyRole ir = getValidatedByRule5(...); }
  • 14. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); PartyRole ir = getValidatedByRule5(...); //??? }
  • 15. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); if (ip != null) { PartyRole ir = getValidatedByRule5(...); } }
  • 16. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); if (ip != null) { PartyRole ir = getValidatedByRule5(...); } if (op != null) { PartyRole or = getValidatedByRule6(...); } }
  • 17. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); if (ip != null) { PartyRole ir = getValidatedByRule5(...); } if (op != null) { PartyRole or = getValidatedByRule6(...); } if (ip != null && op != null && ip == op) { problems.add(...); // Rule #8 violation } }
  • 18. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); PartyRole ir = getSafeValidatedByRule5(...); PartyRole or = getSafeValidatedByRule6(...); validateRule8(...); }
  • 19. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); PartyRole ir = getSafeValidatedByRule5(...); PartyRole or = getSafeValidatedByRule6(...); validateRule8(...); if (ir != null && or != null && (...)) { problems.add(...); // Rule #9 violation } }
  • 20. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); PartyRole ir = getSafeValidatedByRule5(...); PartyRole or = getSafeValidatedByRule6(...); validateRule8(...); validateRule9(...); if (problems.isEmpty()) { order.inPartyId = ip.partyId; ... } }
  • 21. public void placeOrder(Order order) { List<Problem> problems = …; PartyDef ip = getValidatedByRule3(...); PartyDef op = getValidatedByRule4(...); PartyRole ir = getSafeValidatedByRule5(...); PartyRole or = getSafeValidatedByRule6(...); validateRule8(...); validateRule9(...); fillOrderIdentifications(...); // TODO: Rule #7 }
  • 22. Clean the Mess Independent Rules
  • 23. Rule RuleConfig Context RuleRunner Data
  • 24. class RuleRunner... public <T> List<Problem> run(<T> data) { List<Problem> problems = …; Context context = …; RuleConfig config = …; while (config.hasNext(context)) { Rule rule = config.next(context); try { rule.execute(context, data); } catch (…) { problems.add(...); } } }
  • 25. class RuleConfig... private final List<Rule> rules = …; public Rule next(Context context) { Rule rule = null; int i = context.getLatestRuleIndex(); while (i < rules.size() && rule == null) { If (rules.get(i).accepts(context)) { rule = rules.get(i); } i++; } context.setLatestRuleIndex(i); return rules.get(i); }
  • 26. interface Rule<T> { boolean accepts(Context context); void execute(Context context, T data); }
  • 27. class RuleN3 implements Rule<Order> public boolean accepts(Context ctx) { return true; } public void execute(Context ctx,Order data) { PartyDef ip = dao.findPartyBy(...); if (ip == null) { throw new Rule3Exception(...); } ctx.inPartyDef = ip; data.inPartyId = ip.partyId; }
  • 28. class RuleN8 implements Rule<Order> public boolean accepts(Context ctx) { return ctx.inPartyDef != null && ctx.outPartyDef != null; } public void execute(Context ctx,Order data) { PartyDef ip = dao.findPartyBy(...); if (ctx.inPartyDef == ctx.outPartyDef) { throw new Rule8Exception(...); } }
  • 29. One More Step Expert System
  • 30. Rule RuleConfig Context RuleRunner Data
  • 31. KnowledgeBas Rule e WorkingMemor RuleEngine y Facts
  • 32.
  • 33. Simple Rule Engine Decision Block 3 1 Rule Decision Block 4 Rule Decision Block 5 Rule Decision Block 6 Rule Result
  • 34. Expert System Decision Block 3 1 Rule Decision Block 4 Rule Decision Block 5 Rule Decision Block 6 Rule Result
  • 35. Process Order Fix Error Routing ? Fixed End Processing ?
  • 36. Rule 1 Fact 1 Rule 2 Fact 2 Rule 3 Fact 3 * * Repeats = ? Rule 4 Fact 4 ... ... Rule N Fact M
  • 37. Rule 1 Fact 1 Rule 2 Fact 2 Rule 3 Fact 3 * * Repeats = ? Rule 4 Fact 4 ... ... Rule N Fact M Inefficient
  • 39. Rete = Net Charles L. Forgy 1979 1974 1982 © Wikipedia.org
  • 40.
  • 41.
  • 42.
  • 43. Root Node Start All Facts Pass Through It
  • 44. 1-input Nodes Alpha Network IntraElement Conditions
  • 45. 2-input Nodes Beta Network Two Element Comparison
  • 46. Terminal Nodes Stop Rules Have a Full Match
  • 47.
  • 49. Drools Rule Pattern rule "Rule example" // Rule unique name ... // Rule attributes: grouping, priority, etc. when ... // Left hand side. Condition. then ... // Right hand side. Consequence. end
  • 50. THE <consequence IF <condition> N >
  • 51. rule "Rule #3 violation" when $o : Order($id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) eval( dao.findPartyBy($t, $pty)==null ) then log.info("Rule #3 violated for the order: " + $id); insert(new Problem($id, 3)); end
  • 52. rule "Rule #3 fulfillment" when $o : Order(inPartyId==null, $id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) eval( dao.findPartyBy($t, $pty)!=null ) then log.info("Rule #3 fulfilled for the order: " + $id); modify($o) { setInPartyId( dao.findPartyBy($t, $pty).getPartyId() ) }; end
  • 53.
  • 54. class RuleN3 implements Rule<Order> public boolean accepts(Context ctx) { return true; } public void execute(Context ctx,Order data) { PartyDef ip = dao.findPartyBy(...); if (ip == null) { throw new Rule3Exception(...); } ctx.inPartyDef = ip; data.inPartyId = ip.partyId; }
  • 55. If Java Is Simpler Why Use Drools?
  • 56. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 57. class RuleN7 implements Rule<Order> public boolean accepts(Context ctx) { return true; } public void execute(Context ctx,Order data) { for (OrderItem item : data.items) { ProductDef pd = dao.findProductBy(...); if (pd == null) { throw new Rule7Exception(...); //??? } } }
  • 58. Java Solution #1 Complex Rule
  • 59. class RuleN7_1 implements Rule<Order> public boolean accepts(Context ctx) { return true; } public void execute(Context ctx,Order data) { for (OrderItem item : data.items) { ProductDef pd = dao.findProductBy(...); if (pd == null) { ctx.addRule7Error(...); //OK } } }
  • 60. Java Solution #2 Complex Runner and Configuration
  • 61. class RuleN7_2 implements Rule<OrderItem> public boolean accepts(Context ctx) { return true; } public void execute(Context ctx,OrderItem data) { ProductDef pd = dao.findProductBy(...); if (pd == null) { throw new Rule7Exception(...); //OK } }
  • 63. rule "Rule #3 violation" when $o : Order($id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) eval( dao.findPartyBy($t, $pty)==null ) then log.info("Rule #3 violated for the order: " + $id); insert(new Problem($id, 3)); end
  • 64. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 65. Yet Another Validation Tool Or Not?
  • 66. package com.victor.drools dialect "mvel" import com.victor.drools.*; // optional global GeneralDao dao; global org.slf4j.Logger log; declare Problem orderId : long @key ruleId : int @key end declare OIProblem extends Problem product : String @key end
  • 67. Drools Class Declaration declare ExampleClass // Class name [extends ParentExampleClass] // Inheritance @stringMetadata("I am String") // Metadata @dateMetadata(01-Jan-1970) propertyName1 : ValidType, // Properties propertyName2 : AnotherValidType
  • 68. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 69. Drools Function Declaration function String hello(String name) { return "Hello "+name+"!"; }
  • 70. rule "Function usage in LHS" when eval( hello("Victor")!="Hello Victor!" ) then int faults = ++alexeyFaults.count; log.fatal("Alexey, fix hello(..) function"); log.anger("You'd better be off"); log.info("You've broken it " +faults+ " time(s)"); end
  • 71. rule "Function usage in RHS" when eval(true) then log.happiness(hello("Victor")); log.worship(hello("Master")); end
  • 72. Drools Query Declaration query "Orders with inParty" $o : Order(inParty != null) end query "Orders with inRole equals to" (String role) $o : Order(inRole == role) end
  • 73. Drools Templates template header field1... // Template fields template “TemplateName” rule "ExampleRule_@{row.rowNumber}" ... // Usage of declared fields end end template
  • 74. Promotional Age Number of Policy type Discount % discount rules Bracket prior applying for claims Rewards for safe 18,24 0 COMPREHENSIVE 1 drivers 18,24 0 FIRE_THEFT 2 25,30 1 COMPREHENSIVE 5 25,30 2 COMPREHENSIVE 1 25,30 0 COMPREHENSIVE 20 © jboss.org
  • 76. rule "Rule #3 violation" when $o : Order($id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) eval( dao.findPartyBy($t, $pty)==null ) then log.info("Rule #3 violated for the order: " + $id); insert(new Problem($id, 3)); end
  • 77. rule "Rule #3 violation" when Every Order Without violations of rule 3 Which violates inParty constraints then Add the violation of the rule 3 end
  • 78. [when] Every Order = $o : Order($id:id, $t:time, $inPty:inParty) [when] Without violations of rule {ruleNumber} = not(Problem(orderId==$id, ruleId=={ruleNumber})) [when] Which violates inParty constraints = eval( dao.findPartyBy($t, $inPty) == null ) [then] Add the violation of the rule {ruleNumber} = log.info("Rule #" + {ruleNumber} + " violated for order: " + $id); insert(new Problem($id, {ruleNumber}));
  • 79. rule "Rule #4 violation" when Every Order Without violations of rule 4 Which violates outParty constraints then Add the violation of the rule 4 end
  • 80. [when] Every Order = $o : Order($id:id, $t:time, $inPty:inParty) [when] Without violations of rule {ruleNumber} = not(Problem(orderId==$id, ruleId=={ruleNumber})) [when] Which violates inParty constraints = eval( dao.findPartyBy($t, $inPty) == null ) [then] Add the violation of the rule {ruleNumber} = log.info("Rule #" + {ruleNumber} + " violated for order: " + $id); insert(new Problem($id, {ruleNumber}));
  • 81. [when] Every Order = $o : Order($id:id, $t:time, $inPty:inParty,$outPty:outParty) [when] Without violations of rule {ruleNumber} = not(Problem(orderId==$id, ruleId=={ruleNumber})) [when] Which violates inParty constraints = eval( dao.findPartyBy($t, $inPty) == null ) [when] Which violates outParty constraints = eval( dao.findPartyBy($t, $outPty) == null ) [then] Add the violation of the rule {ruleNumber} = log.info("Rule #" + {ruleNumber} + " violated for order: " + $id); insert(new Problem($id, {ruleNumber}));
  • 83. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 84. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 85. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 86. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 87. rule "Rule #7 violation" when $o : Order(items!=null, $id:id, $t:time) $item : OrderItem($prd:product) from $o.items not( OIProblem(orderId==$id, ruleId==7, product==$prd) ) eval(dao.findProductBy($t, $prd)==null) then log.info("Rule #7 violated for order: " + $id + " and product: " + $prd); insert(new OIProblem($id, 7, $prd)); end
  • 88. rule "Rule #7 violation" when Every Order - which has items And every OrderItem Without violations of order item rule 7 Which violates product constraints then Add the violation of the rule 7 for the order item end
  • 89. [when] Every Order = [when] Without violations of rule {N} = [when] Which violates inParty constraints = [when] Which violates outParty constraints = [then] Add the violation of the rule {N} =
  • 90. [when] Every Order = [when] - which has items = items != null [when] And every OrderItem = [when] Without violations of rule {N} = [when] Which violates inParty constraints = [when] Which violates outParty constraints = [when] Without violations of order item rule {N} = [when] Which violates product constraints = [then] Add the violation of the rule {N} for order item = [then] Add the violation of the rule {N} =
  • 91. I Do Believe Am I Alone?
  • 92. Meanwhile in the Real World... Requirements Change
  • 93.
  • 94. 1)Start-stop intervals must not overlap. 2)Entity exists only within start-stop interval. 3)Order must have valid and existent in party. 4)Order must have valid and existent out party. 5)Order must have valid and existent in role. 6)Order must have valid and existent out role. 7)Order items must have valid and existent product. 8)Order in and out parties CAN be the same. ONLY IF they have roles (seller, repairer). 9)Order roles must be: (buyer, seller), (buyer, repairer), (repairer, seller), (seller, buyer). OR (seller, repairer) if they are the same.
  • 95. rule "Rule #8 violation" when $o : Order( inPartyId != null, outPartyId != null, outPartyId == inPartyId, $id : id) not( Problem(orderId == $id, ruleId in (3, 4, 8)) ) then log.info("Rule #8 violated for order: " + $id); insert(new Problem($id, 8)); end
  • 96. rule "Rule #8 violation" when $o : Order(!(inRole == "S" && outRole == "R"), inPartyId != null, outPartyId != null, outPartyId == inPartyId, $id : id) not( Problem(orderId == $id, ruleId in (3, 4, 8)) ) then log.info("Rule #8 violated for order: " + $id); insert(new Problem($id, 8)); end
  • 97. rule "Rule #8 violation" when Every Order - with inPartyId - with outPartyId - where inPartyId equals outPartyId - and inRole not "S" and outRole not "R" Without violations of rules [3,4,8] then Add the violation of the rule 8 end
  • 98. rule "Rule #8 exceptional case" // salience 100 when $o : Order(inRole == "S", outRole == "R", inPartyId != null, outPartyId != null, outPartyId == inPartyId, $id : id) then log.info("Rule #8 special case for order: " + $id); insertLogical(new SkipRule($id, 8)); end
  • 99. rule "Rule #8 violation" when $o : Order( inPartyId != null, outPartyId != null, outPartyId == inPartyId, $id : id) not( SkipRule(orderId == $id, ruleId == 8) ) not(Problem(orderId == $id, ruleId in (3, 4, 8)) ) then log.info("Rule #8 violated for order: " + $id); insert(new Problem($id, 8)); end
  • 100. rule "Cleanup skipped rules" when $o : Order($id : id) SkipRule(orderId == $id, $rId : ruleId) $p : Problem(orderId == $id, ruleId == $rId) then log.info("Retract #" + $rId + " for order: " + $id); retract($p); end
  • 101. Houston, we've got a problem Performance & Resources
  • 102. Rete Adapters/Eval Entry Point Join Object Type Not Alpha Terminal
  • 103. Rete Entry Point Entry Point Node Scope 1 EntryPointNode#1 Scope 2 EntryPointNode#2 Scope 3 EntryPointNode#3
  • 104. Entry Point Node Object Type Object Type Node Order ObjectTypeNode#1 PartyDef ObjectTypeNode#2 Problem ObjectTypeNode#3 OIProblem ObjectTypeNode#4
  • 105. Object Type Node (Order) Fact Set Order#112 Order#113 Order#114 Order#115 ...
  • 106. Object Type Node (Order) Literal Alpha Node inParty == null AlphaNode#1 inParty != null AlphaNode#2 outParty == null AlphaNode#3 outParty != null AlphaNode#4
  • 107. Alpha Node Fact Set Order#1 Order#5 Order#6 ...
  • 108. Join Node Left Right Order#1, SkipRule#5 Problem#1 Order#5, SkipRule#15 Problem#5 Order#6, SkipRule#11 Problem#6 ... ... Problem#11 Problem#12
  • 109. Not Node Left Right Order#1, OrderItem#5 Problem#1 Order#1, OrderItem#1 Problem#5 Order#1, OrderItem#3 Problem#6 ... ... Problem#11 Problem#12
  • 110. Eval No Cache No Memory
  • 111. rule "Rule #3 violation" when $o : Order($id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) eval( dao.findPartyBy($t, $pty)==null ) then log.info("Rule #3 violated for the order: " + $id); insert(new Problem($id, 3)); end
  • 112. rule "Rule #3 fulfillment" when $o : Order(inPartyId==null, $id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) eval( dao.findPartyBy($t, $pty)!=null ) then log.info("Rule #3 fulfilled for the order: " + $id); modify($o) { setInPartyId( dao.findPartyBy($t, $pty).getPartyId() ) }; end
  • 113. Hard to Test Inefficient High Cost of Refactoring Impossible Exception Handling Can Change State Between Invocations Usually Less Readable
  • 114. Replace EVAL Prefetch Data
  • 115. rule "Rule #3 violation" when $o : Order($id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) not( PartyDef(publicCode == $pty, startTime <= $t, stopTime > $t) ) then log.info("Rule #3 violated for the order: " + $id); insert(new Problem($id, 3)); end
  • 116. rule "Rule #3 fulfillment" when $o : Order(inPartyId==null, $id:id, $t:time, $pty:inParty) not( Problem(orderId==$id, ruleId==3) ) $p : PartyDef(publicCode == $pty, startTime <= $t, stopTime > $t) then log.info("Rule #3 fulfilled for the order: " + $id); modify($o) { inPartyId = $p.getPartyId(); }; end
  • 117. rule "Prefetch inParty PartyDef" salience 100 when Order(inParty!=null, $t:time, $pCode:inParty) not( PartyDef(publicCode == $pCode, startTime <= $t, stopTime > $t) ) then PartyDef pd = dao.findPartyBy($t, $pCode); if (pd != null) { log.info("insert party: " + pd.getPartyId()); insert(pd); } end
  • 118. rule "Prefetch inParty PartyDef" salience 100 when Order(inParty!=null, $t:time, $pCode:inParty) not( PartyDef(publicCode == $pCode, startTime <= $t, stopTime > $t) ) then PartyDef pd = dao.findPartyBy($t, $pCode); log.info("insert party (if exists): " + pd); insert(pd); // null won't be inserted end
  • 119. Hard to Test Inefficient High Cost of Refactoring Impossible Exception Handling Can Change State Between Invocations Usually Less Readable Several More Rules to Support
  • 120. ??? http://docs.jboss.org/ http://akinator.com/