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).
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
}
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
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
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
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} =
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
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
...
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