Presentation around the time of Beta3 for "What's new in Drools 6.0". Note some aspects have already changed, especially around the spring integration.
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
What's new in Drools 6 - London JBUG 2013
1. 1
●
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
Monday, 5 August 13
2. Agenda
•Quick Intro - What are Rule Based Systems
•KIE
•5.x Critique
•6.0 Improvements
•UI
•Content
•Deployment
•Spring and Camel
•API
•CDI
•ScoreCards and PMML
•JTMS
•Phreak
•Legacy Migrations
•Backward chaining Example
•UberFire
2
Monday, 5 August 13
4. 4
Vision
Robotics
Speech
Neural Nets Rule Base Systems/
Expert System Tools
Understanding
Natural
LanguageSome Areas of
Artificial
Intelligence
Some Areas of Artificial Intelligence
Monday, 5 August 13
5. 5
Knowledge Representation and Reasoning
The study of Knowledge is Epistemology
● Nature Structure and Origins of Knowledge
● Core or AI
Rule based systems
● Expert System tools
● Knowledge Representation and Reasoning
● Facilitate the codification of knowledge into a knowledge
base which can be used for reasoning
Monday, 5 August 13
6. 6
It All Started Here Birth of CDSS
Dendral
Mycin
Baobab
Guidon
Neomycin
Teiresias Emycin WM
Puff
Sacon
Centaur
Gravida
Wheeze Clot
Onccocin
1970s
1980s
Monday, 5 August 13
27. Changes
Conventions:
•droolsjbpm -> kie
•knowlege -> kie
Examples
•KnowledgeBase -> Kie
•StatefulKnowledgeSession -> KieSession
•StatelessKnowledgeSession - StatelesKieSession
Legacy API Adapter JAR
•Most API’s should work with legacy adapter
•KnowledegAgents have not been ported, PKG’s are not longer
the unit of deployment
DRL has not changed
27
Monday, 5 August 13
31. 5.x Critique
Content
•JCR
•Performance issues
•Everything stored as a blob
•No tagging, branching etc.
•Webdav, with limited Eclipse team provider integration.
•Single tree structure (packages)
•Packages created project deployment units
•no real alignment with industry stadard
•No easy rule use (only a single global area)
•Loading “model” jars into packages
•Poor hack, for dependency management
31
Monday, 5 August 13
38. 6.0 UI Content and Authoring
Improvements
39
Monday, 5 August 13
39. 6.0 Content
•GIT
•Industry standard tooling
•Multiple repositories and projects
•All projects are Maven multi-module projects
•Projects can be shared, via pom dependencies
•Both Kie projects, and any other maven jar
•Local Maven repository management for model jars
40
Monday, 5 August 13
46. 6.0 Deployment
48
Deployment
•Maven JARS
•All projects are just maven projects
•All projects compile to JARS
•JARS are installed to local M2_REPO, which is expose on http
•Can “deploy” to external repos.
•Uses Maven industry methdologies
Monday, 5 August 13
50. KieModules
Defaults and JAR on Classpath
•Creates one KieBase, adds all resources from that JAR
•See kmodule.xsd in kie-api jar
52
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jboss.org/kie/6.0.0/kmodule">
</kmodule>
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession();
kSession.setGlobal("out", out);
kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
Monday, 5 August 13
54. KieModules
Named Entities, with inheritence and JAR on Classpath
•Two projects, one “includes” from the other
56
<dependency>
<groupId>org.drools</groupId>
<artifactId>named-kiesession</artifactId>
<version>6.0.0-SNAPSHOT</version>
</dependency>
<kbase name="kiebaseinclusion" includes="namedkiebase">
<ksession name="ksession2"/>
</kbase>
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession2");
kSession.setGlobal("out", out);
kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
kSession.insert(new Message("Dave", "Open the pod bay doors, HAL."));
kSession.fireAllRules();
Monday, 5 August 13
55. KieModules
Package location can over-ride kbase name defaults
57
<kbase name="WumpusMainKB" packages="org.drools.games.wumpus.server,
org.drools.games.wumpus.server.view">
<ksession name="WumpusMainKS" />
</kbase>
<kbase name="WumpusClientKB" packages="org.drools.games.wumpus.client">
<ksession name="WumpusClientKS"/>
</kbase>
KieContainer kc = KieServices.Factory.get().getKieClasspathContainer();
final KieSession serverKsession = kc.newKieSession( "WumpusMainKS");
final KieSession clientKsession = kc.newKieSession("WumpusClientKS");
Monday, 5 August 13
56. Dynamic KieModules
•JARs can be loaded from URLs into KieRepository
•Once loaded they can be resolved via ReleaseId
58
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
KieModule kModule = kr.addKieModule(ks.getResources().newFileSystemResource(
getFile("default-kiesession")));
KieContainer kContainer = ks.newKieContainer(kModule.getReleaseId());
KieSession kSession = kContainer.newKieSession();
kSession.setGlobal("out", out);
Object msg1 = createMessage(kContainer,
"Dave", "Hello, HAL. Do you read me, HAL?");
kSession.insert(msg1);
kSession.fireAllRules();
Monday, 5 August 13
57. Dynamic KieModules
kie-ci use embedded maven for remote discovery
59
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
</dependency>
KieServices ks = KieServices.Factory.get();
// Install example1 in the local maven repo before to do this
KieContainer kContainer = ks.newKieContainer(
ks.newReleaseId("org.drools",
"named-kiesession",
"6.0.0-SNAPSHOT"));
KieSession kSession = kContainer.newKieSession("ksession1");
kSession.setGlobal("out", out);
Object msg1 = createMessage(kContainer,
"Dave", "Hello, HAL. Do you read me, HAL?");
kSession.insert(msg1);
kSession.fireAllRules();
Monday, 5 August 13
58. Dynamic Modules
•Kie-CI and Automatic updates with KieScanner
•Replaces KnowledgeAgent
•Mave resolves new artifacts dynamically at runtime
•SNAPSHOT, LATEST, STABLE and version ranges supported
•See KieRepositoryScannerTest
60
KieServices ks = KieServices.Factory.get();
ReleaseId releaseId = ks.newReleaseId("org.kie", "scanner-test", "1.0-SNAPSHOT");
InternalKieModule kJar1 = createKieJar(ks, releaseId, "rule1", "rule2");
KieContainer kieContainer = ks.newKieContainer(releaseId);
MavenRepository repository = getMavenRepository();
repository.deployArtifact(releaseId, kJar1, kPom);
// create a ksesion and check it works as expected
KieSession ksession = kieContainer.newKieSession("KSession1");
checkKSession(ksession, "rule1", "rule2");
Monday, 5 August 13
59. Dynamic Modules
61
// create a new kjar
InternalKieModule kJar2 = createKieJar(ks, releaseId, "rule2", "rule3");
// deploy it on maven
repository.deployArtifact(releaseId, kJar2, kPom);
// since I am not calling start() on the scanner it means it won't have
automatic scheduled scanning
KieScanner scanner = ks.newKieScanner(kieContainer);
// scan the maven repo to get the new kjar version and deploy it on the
kcontainer
scanner.scanNow();
// create a ksesion and check it works as expected
KieSession ksession2 = kieContainer.newKieSession("KSession1");
checkKSession(ksession2, "rule2", "rule3");
Monday, 5 August 13
60. Programmatic API
•Builder API, for tooling integration
•Incremental compilation, and problem reporting
62
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
KieFileSystem kfs = ks.newKieFileSystem();
kfs.write("src/main/resources/org/kie/example5/HAL5.drl", getRule());
KieBuilder kb = ks.newKieBuilder(kfs);
kb.buildAll(); // kieModule is automatically deployed to KieRepository if
successfully built.
if (kb.getResults().hasMessages(Level.ERROR)) {
throw new RuntimeException("Build Errors:n" + kb.getResults().toString());
}
KieContainer kContainer = ks.newKieContainer(kr.getDefaultReleaseId());
KieSession kSession = kContainer.newKieSession();
kSession.setGlobal("out", out);
kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
Monday, 5 August 13
68. CDI Context and Dependency Injection
CDI injects named entities from the kmodule.xml
Injectable types
•KieServices
•KieContainer
•KieBase
•KieSession
•StatelessKieSession
70
Monday, 5 August 13
77. Justification-based Truth Maintenace JTMS
Drools 5.x
•Simple logical insertion TMS, like Clips, Jess and others.
•Drools 6.0
•Contradiction handling with JTMS
•Clean separation of exception logic
•TMS now has pluggable Belief System
•Simple TMS support
•JTMS now possible.
•Defeasible Logic soon
•See drools-compiler
•JTMSTest for lots of example tests
•https://github.com/droolsjbpm/drools/blob/master/drools-compiler/
src/test/java/org/drools/compiler/beliefsystem/jtms/
JTMSTest.java
79
Monday, 5 August 13
78. 80
JTMS
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?
Monday, 5 August 13
80. 82
JTMS
•A rule “logically” inserts an object
•When the rule is no longer true, the object is retracted.
rule "IsChild"
when
$p : Person( age < 16 )
then
logicalInsert( new IsChild( $p ) )
end
rule "IsAdult"
when
$p : Person( age >= 16 )
then
logicalInsert( new IsAdult( $p ) )
end
de-couples the logic
Maintains the truth by
automatically retracting
Monday, 5 August 13
81. 83
JTMS
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()
IsAdult( person =$p )
then
logicalInsert(new AdultBusPass( $p ) );
end
The truth maintenance cascades
Monday, 5 August 13
82. 84
JTMS
rule "Issue Child Bus Pass"
when
$p : Person( )
not( ChildBusPass( person == $p ) )
then
requestChildBusPass( $p );
end The truth maintenance cascades
Monday, 5 August 13
83. 85
JTMS
• Good
• De-couple knowledge responsibilities
• Encapsulate knowledge
• Provide semantic abstractions for those encapsulation
• Integrity robustness – truth maintenance
Monday, 5 August 13
85. JTMS
87
rule "Do not issue to banned people"
when
$p : Person( )
Banned( person =$p )
then
logicalInsert(new ChildBusPass( $p ) , “neg” );
end
Monday, 5 August 13
89. Legacy Systems and Migration
Legacy API Adapter JAR
•Most API’s should work with legacy adapter
•KnowledegAgents have not been ported, PKG’s are not longer
the unit of deployment
JCR Migration Tool
•Command Line Java code
•Each Package maps to a GIT project
91
Monday, 5 August 13
90. Backward Chaining
Re-introducing an Advanced Feature
Detailed Tutorial here:
https://www.youtube.com/watch?v=fCjIRVSRFvA
92
Monday, 5 August 13
91. 93
Backward Chaining
query isChild( Person p )
$p := Person( age <= 16 )
end
rule "Issue Child Bus Pass"
when
$p : Person( )
isChild( $p; )
then
logicalInsert(new ChildBusPass( $p ) );
end
Monday, 5 August 13
92. 94
Reasoning with Graphs
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
93. 95
Backward Chaining
query isContainedIn( String x, String y )
Location( x, y; )
or
( Location( z, y; ) and isContainedIn( x, z; ) )
end
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
94. Backward Chaining
96
ksession.insert( new Location("Office", "House") );
ksession.insert( new Location("Kitchen", "House") );
ksession.insert( new Location("Knife", "Kitchen") );
ksession.insert( new Location("Cheese", "Kitchen") );
ksession.insert( new Location("Desk", "Office") );
ksession.insert( new Location("Chair", "Office") );
ksession.insert( new Location("Computer", "Desk") );
ksession.insert( new Location("Draw", "Desk") );
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
95. Backward Chaining
97
rule "go1"
when
String( this == "go1" )
isContainedIn("Office", "House"; )
then
System.out.println( "office is in the house" );
end
rule "go" salience 10
when
$s : String( )
then
System.out.println( $s );
end
ksession.insert( "go1" );
ksession.fireAllRules();
---
go1
office is in the house
query isContainedIn( String x, String y )
Location( x, y; )
or
( Location( z, y; ) and isContainedIn( x, z; ) )
end
Does not recurse.
Finds Location(“Office, House”)
on first call.
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
96. Backward Chaining
98
rule "go2"
when
String( this == "go2" )
isContainedIn("Draw", "House"; )
then
System.out.println( "Draw in the House" );
end
ksession.insert( "go2" );
ksession.fireAllRules();
---
go2
Desk in the House
query isContainedIn( String x, String y )
Location( x, y; )
or
( Location( z, y; ) and isContainedIn( x, z; ) )
end
Recursive 3 times, note the Z.
Location( “Office”, “House”)
Location( “Desk”, “Office”)
Location( “Draw”, “Desk”)
Out Var
(unbound) In Var
(bound)
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
97. Backward Chaining
99
rule "go3"
when
String( this == "go3" )
isContainedIn("Key", "Office"; )
then
System.out.println( "Key in the Office" );
end
ksession.insert( "go3" );
ksession.fireAllRules();
---
go3
ksession.insert( new Location("Key", "Draw") );
ksession.fireAllRules();
---
Key in the Office
Nothing returned.
There is no key at any point below
Office. But the query stays open and
reactive.
Key Inserted 3 levels below, but
system detects, reacts and bubbles
up the results.
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
98. Backward Chaining
100
rule "go4"
when
String( this == "go4" )
isContainedIn(thing, "Office"; )
then
System.out.println( "thing " + thing + " is in the Office" );
end
ksession.insert( "go4" );
ksession.fireAllRules();
---
go4
thing Key is in the Office
thing Computer is in the Office
thing Draw is in the Office
thing Desk is in the Office
thing Chair is in the Office
Finds all Things in the office, but
directly and transitively.
Out Var
(unbound)
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
99. Backward Chaining
101
rule "go5"
when
String( this == "go5" )
isContainedIn(thing, location; )
then
System.out.println( "thing " + thing + " is in " + location );
end
ksession.insert( "go5" );
ksession.fireAllRules();
---
go5
thing Knife is in House
thing Cheese is in House
thing Key is in House
thing Computer is in House
thing Draw is in House
thing Desk is in House
thing Chair is in House
thing Key is in Office
thing Computer is in Office
thing Draw is in Office
thing Key is in Desk
thing Office is in House
Find all things in all things.
Out Var
(unbound)
Out Var
(unbound)
thing Computer is in Desk
thing Knife is in Kitchen
thing Cheese is in Kitchen
thing Kitchen is in House
thing Key is in Draw
thing Draw is in Desk
thing Desk is in Office
thing Chair is in Office
House
Location("Office",
"House ")
Location("Kitchen",
"House")
Location("Desk",
"Office")
Location("Chair",
"Office")
Location("Computer",
"Desk")
Location("Draw",
"Desk")
Location("Knife",
"Kitchen")
Location("Cheese",
"Kitchen")
Location("Key",
"Draw")
Monday, 5 August 13
101. 103
Features
• Compile time composition of plugins
• modular components, each separate maven module.
• Lightweight
• Decoupled components
• Layout Manager and Perspectives
• Embeddable/Reusable (*)
• Unified API
• Security
• I/O
• VFS
• Metadata
• Menus, Toolbars, Panels, etc.
• Standard Life Cycle
UF UberFire
Monday, 5 August 13
102. UberFire
104
@Dependent
@WorkbenchScreen(identifier = "MyFirstPanel")
public class MyFirstPanel {
private final FlowPanel panel = new FlowPanel();
@PostConstruct
private void init() {
final Label label = new Label();
label.setText("Hello World!");
panel.add(label);
}
@WorkbenchPartTitle
public String myTitle() {
return "My First and Cool Panel!";
}
@WorkbenchPartView
public IsWidget getView() {
return panel;
}
}
Monday, 5 August 13
103. Proof is in the Pudding
•UI Rewrite started in November
•Entire BRMS ported
•New BPMS built, all integrated
•Tasks, Calendars, BPM Designer
•Only one person on core UI framework
•All team memebers distributed
•Despite aggressive schedule
•Code remains modular
•Easy to maintan and extend
•No one is complaining yet :)
105
UF UberFire
Monday, 5 August 13
104. 106
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.
Joshya: Greetings, Professor Falken.
Falken: Hello, Joshua.
Joshya: A strange game. The only winning move is not
to play. How about a nice game of chess?
Monday, 5 August 13