The document discusses Drools and the JBoss Business Rules Management System (BRMS), including an overview of concepts like rules, facts, and the runtime execution environment. It also covers authoring rules with the guided rule editor in the web interface or with DRL, and integrating rules with Spring and Camel frameworks at runtime.
Report
Share
Report
Share
1 of 107
Download to read offline
More Related Content
Intro to Drools - St Louis Gateway JUG
1. Ray Ploski
Director - Developer Experience
Drools and
the BRMS
The Business Logic Integration Platform
2. Agenda
• The Concepts
• A Simple Example and Demo
• Projects Overview
• Best practices integrating Drools into
your development process
• Learning more, getting involved and
getting support
5. What is JBoss BRMS?
JBoss Enterprise BRMS BRMS
• Single, integrated, certified
distributions
• Extensive Q/A Process
• Industry-leading Support
• Documentation
• Secure, Production-level
Configurations JBoss Runtime
• Multi-year Errata Policy
A common and complete platform to model and govern the business logic of the
enterprise
6. JBoss Enterprise BRMS
n Each JBoss Enterprise Middleware platform goes through a 5 phase delivery methodology that
involves many traditional elements of the software development lifecyle:
1 2 3 4 5
Delivery Phase
Drools Projects Product Platform Testing, Platform Release
Platform Component
Requirements Certification & (General Availability)
Engineering & Integration
Definition Documentation
Platform Quality
JBoss
Candidate BRMS
Enterprise
Productization Team
Assurance
Release(s) BRMS
JBoss QA, Documentation JBoss Release
JBoss
Product Team, Certified Partners Engineering
Productization
Management Engineers
JBoss.org
Engineers
6
16. Extract the Logic
• Separate integration codebase
from business logic and into a
rules engine
17. Extract the Logic
• Separate integration codebase
from business logic and into a
rules engine
• Goal: Remove the requirements
churn and complexity
18. Extract the Logic
• Separate integration codebase
from business logic and into a
rules engine
• Goal: Remove the requirements
churn and complexity
• Goal: Empower your Domain
Experts to directly author rules
24. Why a Unified Approach?
• Extend Rules Engine to handle process State
• Extend the Engine to handle Events
• Integration provides
• Simplicity
• Performance
• Manageability
• Integration of Features
27. What is a Rules Engine?
• Ambiguous Term
• Inference Engine Concepts Clarify
• Scales to a large number of rules and
facts
• Matches facts against rules to infer
conclusions
• Conclusions result in actions
rule “XYZ”
when
<conditions>
• Simple two-part structure:
then
<actions>
28. Facts
• POJOs (Plain Old Java Objects)
• Rules engine uses to evaluate conditions
• Rules engine can execute POJO methods
• Can be loaded from a database via
Hibernate, JPA, etc...
• Rules engine can modify a fact’s state
• Dynamic Facts
• Can be modeled in the Web UI
29. Facts
• POJOs (Plain Old Java Objects)
• Rules engine uses to evaluate conditions
• Rules engine can execute POJO methods
• Can be loaded from a database via
Hibernate, JPA, etc...
• Rules engine can modify a fact’s state
• Dynamic Facts
• Can be modeled in the Web UI
30. Fact Model Example
public class Room { Model is multiple
private String name
// getter and setter methods here facts and their
} relationships
public class Sprinkler {
private Room room;
private boolean on;
// getter and setter methods here
}
public class Fire {
private Room room;
// getter and setter methods here
}
public class Alarm {
}
31. Fact Model Example
public class Room { Model is multiple
private String name
// getter and setter methods here facts and their
} relationships
public class Sprinkler {
private Room room;
private boolean on; • Must have setters/
// getter and setter methods here getters
}
public class Fire { • Must have a public
no-arg constructor
private Room room;
// getter and setter methods here • No mandatory
} inheritance/
public class Alarm { interface
}
34. Rules
• Form the “IF/Then” action defined as “When/Then”
• Must have a name that is unique for a rule
package
35. Rules
• Form the “IF/Then” action defined as “When/Then”
• Must have a name that is unique for a rule
package
• LHS (Left Hand Side)
• Conditional part of the rule
• Evaluate fact attributes based on criteria
36. Rules
• Form the “IF/Then” action defined as “When/Then”
• Must have a name that is unique for a rule
package
• LHS (Left Hand Side)
• Conditional part of the rule
• Evaluate fact attributes based on criteria
• RHS (Right Hand Side)
• Consequence or action part of the rule
• Invoke operations
• Modify Fact State
37. Rules
• Form the “IF/Then” action defined as “When/Then”
• Must have a name that is unique for a rule
package
• LHS (Left Hand Side)
• Conditional part of the rule
• Evaluate fact attributes based on criteria
• RHS (Right Hand Side)
• Consequence or action part of the rule
• Invoke operations
• Modify Fact State
38. Rules
• Form the “IF/Then” action defined as “When/Then”
• Must have a name that is unique for a rule
package
• LHS (Left Hand Side)
• Conditional part of the rule
• Evaluate fact attributes based on criteria
• RHS (Right Hand Side)
• Consequence or action part of the rule
• Invoke operations
• Modify Fact State
39. Rules
• Form the “IF/Then” action defined as “When/Then”
• Must have a name that is unique for a rule
package
• LHS (Left Hand Side)
• Conditional part of the rule
• Evaluate fact attributes based on criteria
• RHS (Right Hand Side)
• Consequence or action part of the rule
• Invoke operations
• Modify Fact State
Rules can be authored in multiple ways!
40. Rules in DRL
package com.sample
import com.sample.*;
rule "When there is a fire turn on the sprinkler"
dialect "mvel"
when Fire( $room: room)
$sprinkler: Sprinkler( room == $room, on == false )
then
modify ($sprinkler) {on = true};
println("Sprinkler activated in " + $room.name);
end
rule "When the fire is gone turn off the sprinkler"
dialect "mvel"
when
$room : Room()
$sprinkler : Sprinkler( room == $room, on == true )
not Fire( room == $room )
then
modify( $sprinkler ) { on = false };
println( "Turn off the sprinkler for room " + $room.name );
end
41. Conditional Elements
● and
✓ all attributes match (default of comma separated list)
● or
✓ either attribute matches
● eval
✓ catch all element
✓ wraps any primative returning semantic code
● not
✓ attribute does not match
● exists
✓ checks for the existence of something
● collect, memberOf, accumulate
✓ elements to reason over collections of data
● from
✓ element to retreive data from external sources like DBs, WebServices,
etc.
● matches, soundslike,
✓ regular expressions and English language phonetics
42. Rule Control
● no-loop
✓ short circuit rule recursion
● salience
✓ numeric value that represents rule importance
● agenda-group
✓ fire rules in group only when in focus
● auto-focus
✓ trigger focus change to the rule's agenda-group
● activation-group
✓ first matching rule fires
✓ all other rules in group are ignored lock-on-active
● date-effective, date-expires
✓ define rules that are only active at certain points in time
● template
✓ define templates that may be reused in multiple rules
43. Avenues for Authoring Rules
- Dynamic Facts
- Decision Tables
- Guided Rules
- English/Industry Specific Rules
- Guided Tests
- Scenario Tests
- Asset Search
- Browse by Category
- Browse by Status
Web Broswer
- Spreadsheet Decision Tables
Spread sheet
- Technical Rules (.drl)
- Enumerations
- Domain Specific Language
- Templates
- Rule Flow
- Step-debugging
- Agenda Views and Inspection
- Working Memory Inspection
- Rule Engine Audit Trails
- Technical Tests
- Technical Test Suites
JBoss Developer Studio
58. Runtime: Building
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("fire.drl"),
ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}
59. Runtime: Building
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("fire.drl"),
ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}
60. Runtime: Building
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("fire.drl"),
ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}
61. Runtime: Building
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("fire.drl"),
ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}
62. Runtime: Building
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("fire.drl"),
ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}
63. Camel & Spring Configuration
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:drools="http://drools.org/schema/drools-spring"
http://drools.org/schema/drools-spring http://verylongurl/drools-spring-1.0.0.xsd>
<drools:resource id="resource1" type="DRL" source="classpath:orgth:org/drools/container/spring/testSpring.drl"/>
<drools:kbase id="kbase1">
<drools:resources>
<drools:resource type="DRL" source="classpath:org/drools/container/spring/testSpring.drl"/>
<drools:resource ref="resource1"/>
<drools:resource source="classpath:org/drools/container/spring/IntegrationExampleTest.xls" type="DTABLE">
<drools:decisiontable-conf input-type="XLS" worksheet-name="Tables_2" />
</drools:resource>
</drools:resources>
<drools:configuration>
<drools:mbeans enabled="true" />
<drools:event-processing-mode mode="STREAM" />
</drools:configuration>
</drools:kbase>
</beans>
THE BRE now has extensive Spring support, the XSD
can be found in the the drools-spring jar. The
namespace is "http://drools.org/schema/drools-spring"
64. Runtime - Execution
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "test");
for( String name: ROOM_NAMES ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
// go !
ksession.fireAllRules();
65. Runtime - Execution
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "test");
for( String name: ROOM_NAMES ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
// go !
ksession.fireAllRules();
66. Runtime - Execution
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "test");
for( String name: ROOM_NAMES ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
// go !
ksession.fireAllRules();
67. Runtime - Execution
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "test");
for( String name: ROOM_NAMES ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
// go !
ksession.fireAllRules();
68. Runtime - Execution
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "test");
for( String name: ROOM_NAMES ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
// go !
ksession.fireAllRules();
69. Runtime - Execution
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "test");
for( String name: ROOM_NAMES ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
// go !
ksession.fireAllRules();
70. Runtime - Execution
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "test");
for( String name: ROOM_NAMES ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
// go !
ksession.fireAllRules();
> Everything is OK
71. Runtime - Execution
Fire kitchenFire = new Fire( name2room.get( "kitchen" ) );
Fire officeFire = new Fire( name2room.get( "office" ) );
FactHandle kitchenFireHandle = ksession.insert( kitchenFire );
FactHandle officeFireHandle = ksession.insert( officeFire );
ksession.fireAllRules();
72. Runtime - Execution
Fire kitchenFire = new Fire( name2room.get( "kitchen" ) );
Fire officeFire = new Fire( name2room.get( "office" ) );
FactHandle kitchenFireHandle = ksession.insert( kitchenFire );
FactHandle officeFireHandle = ksession.insert( officeFire );
ksession.fireAllRules();
> Raise the alarm
> Turn on the sprinkler for room kitchen
> Turn on the sprinkler for room office
74. Runtime - Execution
ksession.retract( kitchenFireHandle );
ksession.retract( officeFireHandle );
ksession.fireAllRules();
> Turn off the sprinkler for room office
> Turn off the sprinkler for room kitchen
> Cancel the alarm
> Everything is ok
75. Use FROM for external data
rule “Find Vehicles for a given zip code"
when
$zipCode : ZipCode() Vehicle() from $hibernate.getNamedQuery( “FindVehicles” )
.setParameters( [ “zipCode” : $zipCode ]) .list()
then
...
end
Can be a Web Service, Hibernate or any external system
76. Runtime Visibility - JMX
• Drools 5.3 brings support to the JMX standard and
enables knowledge base and knowledge session
monitoring and inspection using any JMX console.
KnowledgeBase Stats
88. CEP
Complex event processing
Real time events (concurrent events – thread
safe):
sliding windows:
Pattern(...) over window:time(3000)
89. Fusion Enables:
• Event Detection:
• From an event cloud or set of streams, select all the
meaningful events, and only them.
• [Temporal] Event Correlation:
• Ability to correlate events and facts declaring both
temporal and non-temporal constraints between them.
• Ability to reason over event aggregation
• Event Abstraction:
• Ability to compose complex events from atomic events
AND reason over them
90. Events
• (Usually) Immutable Facts
• Strong Temporal
Relationship
• Managed Lifecylce
• Use of sliding windows
• Can provide metadata on:
• @timestamp, @duration or
@expires
92. Temporal Reasoning
• Event and Time semantics:
• Point in Time
• Over an Interval
• Unified semantics for event
correlation over time
• Temporal Constraints:
• Set of 13 operators to express
temporal relationship between
events
93. Expressive Event Constraints
Point-Point Point-Interval Interval-Interval
A before B
A meets B
A overlaps B
A includes B
A finishes B
A starts B
A coincides B
94. Behaviors & Sliding Windows
• Behaviors: special semantics to certain patterns
• sliding windows, distinct, sort, etc
• SlidingWindow: Allows reasoning over a moving
window of “interest”
• Time
• Length
95. Memory Management
•CEP scenarios are stateful by nature.
•Events usually are only interesting
during a short period of time.
•Fusion manages the benefits
memory management while events
still in window of consideration
96. Rulebase Partitioning
• Achieves coarse
grained
parallelization
• No fundamental
changes in the
matching algorithm
(ReteOO)
• Preserves
optimizations,
especially node
sharing
98. What is Planner?
•Optimizes Automated Planning
•Use Cases:
• Space Planning
• Employee Shift Rostering
• Team Scheduling
•Still in development!
• Not commercially supported.
100. Patient Admission Schedule
• Hard constraints
• No 2 patients in same bed in same night
• Room gender limitation
• Department minimum or maximum age
• Patient requires specific room equipment(s)
• Soft constraints
• Patient prefers maximum room size
• Department specialization
• Room specialization
• Patient prefers specific room equipment(s)
101. Planner Syntax
// If a hospital patient prefers specific equipment, try to assign him/her a hospital
room with such equipment.
rule "preferredPatientEquipment"
when
// If a patient prefers specific equipment
PreferredPatientEquipment($patient : patient, $equipment : equipment);
// and that patient is assigned a room
BedDesignation(patient == $patient, $room : room);
// and that room doesn't have that equipment
not RoomEquipment(room == $room, equipment == $equipment);
then
... // lower the score with a certain weight
end
103. Needle in a Haystack
• How many possible
solutions?
• 310 beds
• in 105 rooms
• in 4 departments
• 84 nights
104. Needle in a Haystack
• How many possible
solutions?
• 310 beds
• in 105 rooms
• in 4 departments
• 84 nights
• 2750 patients
(admissions)
105. Needle in a Haystack
• How many possible
solutions?
• 310 beds
• in 105 rooms
• in 4 departments
• 84 nights
• 2750 patients
(admissions)
• Numbers from a real
dataset
106. Commercial Support
•Drools ships within several supported
platforms:
• JBoss Enterprise BRMS
• JBoss Enterprise SOA Platform *
• JBoss Enterprise Application Platform **
107. Support Open Source!
• We need You!
• JBoss User Groups
• Contribute
• Code
• Features
• Documentation
• Testing
• Let us continue our work that benefits so many.