Transcript
●The SkyNet funding bill is passed. ●The system goes online on August 4th, 1997.●Human decisions are removed from strategic defense. ●SkyNet begins to learn at a geometric rate.●It becomes self-aware at 2:14am Eastern time, August 29th ●In a panic, they try to pull the plug. ●And, Skynet fights back
Mark Proctor
Project Lead
2
Business Logic integration Platform
DroolsGuvnor
DroolsFusion
DroolsFlow
DroolsExpert
Introduction
Drools Expert
Learn by Example
5
D a t e d a t ed o u b l e a m o u n ti n t t y p el o n g a c c o u n t N o
C a s h f l o w
l o n g a c c o u n t N od o u b l e b a l a n c e
A c c o u n t
D a t e s t a r tD a t e e n d
A c c o u n t i n g P e r i o d
Classes
6
AccountaccountNo balance
1 0
increase balance for AccountPeriod Credits
select * from Account acc, Cashflow cf, AccountPeriod apwhere acc.accountNo == cf.accountNo and cf.type == CREDIT cf.date >= ap.start and cf.date <= ap.end
decrease balance for AccountPeriod Debits
select * from Account acc, Cashflow cf, AccountPeriod apwhere acc.accountNo == cf.accountNo and cf.type == DEBIT cf.date >= ap.start and cf.date <= ap.end
AccountingPeriodstart end
01-Jan-07 31-Mar-07
trigger : acc.balance += cf.amount trigger : acc.balance -= cf.amount
Accountbalance
1 -25accountNo
Creating Views with Triggers
date amount type12-Jan-07 100 CREDIT 12-Feb-07 200 DEBIT 118-May-07 50 CREDIT 19-Mar-07 75 CREDIT 1
accountNo
date amount type12-Jan-07 100 CREDIT9-Mar-07 75 CREDIT
CashFlow
date amount type2-Feb-07 200 DEBIT
CashFlow
7
What is a Rule
• rule “<name>” <attribute> <value> when <LHS> then <RHS>end
Quotes on Rule names are optional if the rule name has no spaces.
salience <int>agenda-group <string>no-loop <boolean>auto-focus <boolean>duration <long>....
RHS can be any valid java. Or MVEL. Other languages could be added.
8
Imperative vs Declarative
• public void helloMark(Person person) { if ( person.getName().equals( “mark” ) { System.out.println( “Hello Mark” ); }}
• rule “Hello Mark” when Person( name == “mark” ) then System.out.println( “Hello Mark” );end
LHS
RHS
specific passing of instances
Methods that must be called directly
Rules can never be called directly
Specific instances cannot be passed.
9
S h o w e r ( t e m p e r a t u r e = = “ h o t ” )
P a t t e r n
F i e l d C o n s t r a i n t
R e s t r i c t i o n
E v a l u a t o r V a l u e
O b j e c t T y p e
F i e l d N a m e
What is a Pattern
10
rule “increase balance for AccountPeriod Credits” when ap : AccountPeriod() acc : Account( $accountNo : accountNo ) CashFlow( type == CREDIT, accountNo == $accountNo, date >= ap.start && <= ap.end, $ammount : ammount ) then acc.balance += $amount; end
select * from Account acc, Cashflow cf, AccountPeriod apwhere acc.accountNo == cf.accountNo and cf.type == CREDIT cf.date >= ap.start and cf.date <= ap.end
trigger : acc.balance += cf.amountPattern
Pattern Binding
field Binding
Literal Restriction
Variable Restriction
Multri Restriction - Variable Restriction
field Binding
Consequence (RHS)
Bringing it Together
11
AccountaccountNo balance
1 0
rule “increase balance for AccountPeriod Credits” when ap : AccountPeriod() acc : Account( $accountNo : accountNo ) CashFlow( type == CREDIT, accountNo == $accountNo, date >= ap.start && <= ap.end, $ammount : ammount ) then acc.balance += $amount; end
AccountingPeriodstart end
01-Jan-07 31-Mar-07
rule “decrease balance for AccountPeriod Debits” when ap : AccountPeriod() acc : Account( $accountNo : accountNo ) CashFlow( type == DEBIT, accountNo == $accountNo, date >= ap.start && <= ap.end, $ammount : ammount ) then acc.balance -= $amount; end
Rules as a “view”
Accountbalance
1 -25accountNo
date amount type12-Jan-07 100 CREDIT 12-Feb-07 200 DEBIT 118-May-07 50 CREDIT 19-Mar-07 75 CREDIT 1
accountNo
date amount type12-Jan-07 100 CREDIT9-Mar-07 75 CREDIT
CashFlowdate amount type
2-Feb-07 200 DEBIT
CashFlow
12
Patterns in more details
CashFlow( type == “credit” )
$ap : AccountPeriod()
CashFlow( date >= $ap.start )
$ap : AccountPeriod()
CashFlow( date >= $ap.start && <= $ap.end )
$ap : AccountPeriod()
CashFlow( type == “credit”,
date >= $ap.start && <= $ap.end )
13
More Pattern Examples
Person( $age : age )
Person( age == ( $age + 1 ) )
Person( $age : age )
Person( eval( age == $age + 1 ) )
Person( $age1 : age )
Person( $age2 : age )
eval( $age2 == $age1 + 1 )
14
Person(age > 30 && < 40 || hair == “black”)
Person(pets[’rover’].type == “dog”)
Person(pets[0].type == “dog”)
Person(age > 30 && < 40 || hair in (“black”, “brown”) )
Person(pets contain $rover )
Person( (age > 30 && < 40 && hair == “black”)
||
(age > 50 && hair == “grey”) )
More Pattern Examples
15
What is a Production Rule System
ProductionMemory
WorkingMemory
Inference Engine
Pattern Matcher
Agenda(rules) (facts)
insertupdateretract
Repository of inserted Java instances
Codification of the business knowledge
Rules can changeon the fly
16
A c c o u n t A c c o u n t i n g P e r i o d C a s h f l o w
v i e w 1 v i e w 2
m a i n v i e w
T a b l e s
V i e w s
V i e w
A c c o u n t A c c o u n t i n g P e r i o d C a s h f l o w
r u l e 1 r u l e 2
a g e n d a
O b j e c t T y p e s
R u l e s
a g e n d a
Production Rule SystemApproximated by SQL and Views
17
rule “Print blance for AccountPeriod” salience -50 when ap : AccountPeriod() acc : Account( ) then System.out.println( acc.accountNo + “ : “ acc.balance ); end
Salience
Agenda1 increase balance
arbitrary2 decrease balance3 increase balance4 print balance
Conflict Resolution with Salience
18
rule “increase balance for AccountPeriod Credits” ruleflow-group “calculation” when ap : AccountPeriod() acc : Account( $accountNo : accountNo ) CashFlow( type == CREDIT, accountNo == $accountNo, date >= ap.start && <= ap.end, $ammount : ammount ) then acc.balance += $amount; end
rule “Print blance for AccountPeriod” ruleflow-group “report” when ap : AccountPeriod() acc : Account( ) then System.out.println( acc.accountNo + “ : “ acc.balance ); end
ruleflow-group
RuleFlow
19
Two Phase System
Working Memory Action
retract
modifyinsert
Agenda Evaluation
Select Rule to Fire
exit
No RuleFound
Fire Rule
Determine possible rules to
fire
RuleFound
Conditional Elements
21
not Bus( color = “red” )
From CE for Expressions
exists Bus( color = “red” )
forall ( $bus : Bus( floors == 2 )
Bus( this == $bus, color == “red” ) )
forall ( $bus : Bus( color == “red” ) )
From CEfor Expressions
23
From CE for Expressions
rule “Find all the pets for a given owner”when $owner : Person( name == “mark” ) Pet( name == “rover” ) from $owner.pets
Using 'from' to reason over the nested list
24
'from' can work on any expression, not just a nested field on a bound variable.
From CE for Expressions
rule “Find People for given zip code”when $zipCode : ZipCode() Person( ) from $hbn.getNamedQuery(“Find People”) .setParameters( [ “zipCode” : $zipCode ] ) .list()
Hibernate session
Collect CE
26
Collect CE
rule "accumulate"
when
$list : List( intValue > 100 )
from collect( Bus( color == "red" ) )
then
print "red buses “ + $list;
end
Accumulate CE
28
Accumulate CE
rule "accumulate"
when
$sum : Number( intValue > 100 )
from accumulate( Bus( color == "red", $t : takings )
init( sum = 0 ),
action( sum += $t ),
result( sum ) )
then
print "sum is “ + $sum;
end
29
Accumulate CE
rule "accumulate"
when
$sum : Number( intValue > 100 )
from accumulate( Bus( color == "red", $t : takings ) sum( $t ) )
then
print "sum is “ + $sum;
end
30
Accumulate CE
Patterns and CE's can be chained with 'from'
rule "collect"
when
$zipCode : ZipCode()
$sum : Number( intValue > 100 )
from accumulate( Bus( color == "red", $t : takings )
from $hbn.getNamedQuery(“Find Buses”)
.setParameters( [ “zipCode” : $zipCode ] )
.list(),
sum( $t ) )
then
print "sum is “ + $sum;
end
TimersCalendars
32
Timers
rule “name” timer 1m30swhen $l : Light( status == “on” )then SendEmail( “turn the light off” )
rule “name” timer (int: 0 1m30)when $l : Light( status == “on” )then SendEmail( “turn the light off” )
33
Timers
rule “name” timer ( cron: 0 0/15 * * * * )when $l : Light( status == “on” )then sendEmail( “turn the light off” )
Field Name Mandatory? Allowed Values Allowed Special CharactersSeconds YES 0-59 , - * /Minutes YES 0-59 , - * /Hours YES 0-23 , - * /Day of month YES 1-31 , - * ? / L WMonth YES 1-12 or JAN-DEC , - * /Day of week YES 1-7 or SUN-SAT , - * ? / L #Year NO empty, 1970-2099 , - * /
34
Calendars
rule "weekdays are high priority" calendars "weekday" timer (int:0 1h)when Alarm()then send( "priority high - we have an alarm” );end
rule "weekend are low priority" calendars "weekend" timer (int:0 4h)when Alarm()then send( "priority low - we have an alarm” );end
Truth MaintenanceInference
36
TMS and Inference
rule "Issue Child Bus Pass"
when
$p : Person( age < 16 )
then
insert(new ChildBusPass( $p ) );
end
rule "Issue Adult Bus Pass"
when
$p : Person( age >= 16 )
then
insert(new AdultBusPass( $p ) );
end
Couples the logic
What happens when the Child stops being 16?
37
TMS and Inference
Bad● Monolithic● Leaky● Brittle integrity - manual maintenance
38
TMS and Inference
A rule “logically” inserts an object When the rule is no longer true, the object is
retracted.
when
$p : Person( age < 16 )
then
logicalInsert( new IsChild( $p ) )
end
when
$p : Person( age >= 16 )
then
logicalInsert( new IsAdult( $p ) )
end
de-couples the logic
Maintains the truth by automatically retracting
39
TMS and Inference
rule "Issue Child Bus Pass"
when
$p : Person( )
IsChild( person =$p )
then
logicalInsert(new ChildBusPass( $p ) );
end
rule "Issue Adult Bus Pass"
when
$p : Person( age >= 16 )
IsAdult( person =$p )
then
logicalInsert(new AdultBusPass( $p ) );
end
The truth maintenance cascades
40
TMS and Inference
rule "Issue Child Bus Pass"
when
$p : Person( )
not( ChildBusPass( person == $p ) )
then
requestChildBusPass( $p );
End The truth maintenance cascades
41
TMS and Inference
Good● De-couple knowledge responsibilities● Encapsulate knowledge● Provide semantic abstractions for those encapsulation● Integrity robustness – truth maintenance
Tooling
43
Guided Editor
44
Interactive Debugging
45
Decision Tables
46
DSLs
47
DSLs
48
Rule Flow
Drools Fusion
50
$c : Custumer( type == “VIP” )BuyOrderEvent( customer == $c )
session.insert( event ) ;
Rule engines do not scale for CEP. They have a single point of insertion and are single threaded, CEP has concurrent streams of events.
Single Point of entry
Patterns, evaluate facts sequentially in a
single thread.
Scalability
51
$c : Custumer( type == “VIP )BuyOrderEvent( customer == $c ) from entry-point “Home Broker Stream”
Scalability
EntryPoint entryPoint = session.getEntryPoint( “Home Broker Stream” );entryPoint.insert( event ) ;
So lets allow multiple named entry points for
those streams
So now we can insert different streams
concurrently
Patterns can now optional specify their entry-point.
When not specified uses the “default” entry-point
52
All Fact life-cycles must be managed by the user, so retractions are manual.
declare StockTick @role( event )end
declare StockTick @role( event ) @timestamp( timestampAttr )
companySymbol : String stockPrice : double timestampAttr : longend
Automatic Life-Cycle Management
Just use the declare statement to declare a type as an event and it
will be retracted when it is no longer needed
The declare statement can also specify an internal model, that
external objects/xml/csv map on to. We support Smooks and JAXB
53
$c : Custumer( type == “VIP )$oe : BuyOrderEvent( customer == $c ) from entry-point “Home Broker Stream” BuyAckEvent( relatedEvent == $oe.id, this after[1s, 10s] $oe ) from entry-point “Stock Trader Stream”
● coincides
● before
● after
● meets
● metby
● overlaps
● overlappedby
● during
● includes
● starts
● startedby
● finishes
● finishedby
Operators
Rule engines do not have rich enough set of temporal comparison operators
BackAckEvent must occur between 1s and 10s 'after'
BuyOrderEvent
The Full set of Operators are supported
54
Operators
55
$c : Custumer( type == “VIP )$oe : BuyOrderEvent( customer == $c ) from entry-point “Home Broker Stream” not BuyAckEvent( relatedEvent == $oe.id, this after[1s, 10s] $oe ) from entry-point “Stock Trader Stream”
Operators
Existing Drools 'not' Conditional Elements can
be used to detect non-occurrence of events
56
Rule engines react to events happening now, there is no temporal understanding of changes over time.
That isn't much without the ability to deal with aggregations, rules engines suck.
Sliding time windows
StockTicker( symbol == “RHAT” ) over window:time( 5s )
StockTicker( symbol == “RHAT” ) over window:length( 1000 )
5s
1000 tickers
57
Aggregations
Rule Engines do not deal with aggregations
$n : Number( intValue > 100 ) from accumulate( $s : StockTicker( symbol == “RHAT” ) over window:time( 5s ), average( $s.price ) )
Over 5 seconds
Aggregate ticker price for RHAT over last 5
seconds
The pattern 'Number' reasons 'from' the accumulate result
$n : accumulate( $s : StockTicker( symbol == “RHAT” ) over window:time( 5s ), average( $s.price ) > 100 )
We can use some sugar to reduce verbosity
Drools Flow
59
Drools Flow
Integration● From loose coupling (decision services)● To advance integration (process rules)
Unification● Rules and processes are different types of business
knowledge assets● Infrastructure
● Timers/Schedulers● Testing● Communication/Services
● Tooling ● IDE● repository, management● Auditing●
A workflow engine combining processes and rules
Truth MaintenanceInference
61
Rules and processes
loosely coupledtightly coupled
spec
ific
gene
ric
DecisionServices
ProcessRules
SC
OP
E
COUPLING
?
62
Business Logic Lifecycle
63
Example
64
RuleFlowGroup
Workflow can control my rules?
65
RuleFlowGroup
Rule Flow Group
66
RuleFlowGroup
67
Constraints
Java code constraint
68
Constraints
Rules can control my workflow?
LHS “when”Rule Constraint
69
Example
Business decisions are externalized using a decision service
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
70
Example
What if there is a lot of business logic like this?
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
rule Decision1 when // conditions then // actionsend
71
RulesEngine
Flow of Control
ProcessEngine
72
RulesEngine
Inversion of Control
ProcessEngine
Age
nda
73
Self monitoring and adaptive
declare ProcessStartedEvent
@role( event )
end
rule "Number of process instances above threshold" when
Number( nbProcesses : intValue > 1000 )
from accumulate(
e: ProcessStartedEvent( processInstance.processId == "com.sample.order.OrderProcess" )
over window:size(1h),
count(e) )
then
System.err.println( "WARNING: Nb of order processes in the last hour > 1000: " + nbProcesses );
end
74
Domain Specific Processes
75
Domain Specific Processes
76
Integrated debug and audit
Unified API
DefinitionsRuntime
Language
78
jBPMFile file = new File (“.....”); // file to XML process definition
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( IoUtils.FileToString( file ) );
ProcessInstance processInstance = new ProcessInstance(processDefinition);
JessRete engine = new Rete();
FileReader file = new FileReader("myfile.clp");
Jesp parser = new Jesp(file, engine);
parser.parse(false);
Esper
EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
EPStatement countStmt = admin.createEPL( "...." );
countStmt.start();
Definitions
79
Drools Flow
KnowledegBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBulider();
kbuilder.addResource( ResourceFactory.newClassPathResource( “myflow.drf”, ResourceType.DRF );
If ( kbuilder.hasErrors() ) { log.error( kbuilder.hasErrors().toString() );}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages( kbase.getKnowledgePackages() );
Definitions
80
Drools Expert
KnowledegBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBulider();
kbuilder.addResource( ResourceFactory.newClassPathResource( “myrules.drl”, ResourceType.DRL );
If ( kbuilder.hasErrors() ) { log.error( kbuilder.hasErrors().toString() );}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();kbase.addKnowledgePackages( kbase.getKnowledgePackages() );
Definitions
81
Drools Integration Deployment Descriptors
<change-set> <add> <resource source='classpath:myapp/data/myflow.drf' type='DRF' /> <resource source='http:myapp/data/myrules.drl' type='DRL' />
<resource source='classpath:data/IntegrationExampleTest.xls' type="DTABLE">
<decisiontable-conf input-type="XLS" worksheet-name="Tables_2" />
</resource> <add></change-set>
KnowledegBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBulider();kbuilder.addResource( ResourceFactory.newFileResource( “changeset.xml”, ResourceType.ChangeSet );
Unified Event Model
Mixins Interface Markers
85
Stateful KnowledgeSession
86
Knowledge Runtime
87
Coming in 5.1
BPMN2 (80% of Workflow) Integration
● OSGi ready● Spring● Camel
Seamless Remoting Simulation/Testing New Rete Algorithm “true modify”
88
Spring + camel
from("direct:test-with-session").to("drools:sm/ksession1?dataFormat=drools-xstream");
89
Questions?Questions?
• Dave Bowman: All right, HAL; I'll go in through the emergency airlock.
• HAL: Without your space helmet, Dave, you're going to find that rather difficult.
• Dave Bowman: HAL, I won't argue with you anymore! Open the doors!
• HAL: Dave, this conversation can serve no purpose anymore. Goodbye. Joshua: Greetings, Professor Falken.
Stephen Falken: Hello, Joshua.Joshua: A strange game. The only winning move is not to play. How about a nice game of chess?