Red Hat JBoss BPM Suite 6.4 Development Guide En US

Red_Hat_JBoss_BPM_Suite-6.4-Development_Guide-en-US

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 550

DownloadRed Hat JBoss BPM Suite 6.4 Development Guide Suite-6.4-Development Guide-en-US
Open PDF In BrowserView PDF
Red Hat JBoss BPM Suite 6.4
Development Guide
Red Hat JBoss BPM Suite Development Guide for Red Hat JBoss Developers

Last Updated: 2018-01-10

Red Hat JBoss BPM Suite 6.4 Development Guide
Red Hat JBoss BPM Suite Development Guide for Red Hat JBoss Developers
Red Customer Content Services
brms-docs@redhat.com
Emily Murphy
Gemma Sheldon
Michele Haglund
Mikhail Ramendik
Stetson Robinson
Vidya Iyengar

Legal Notice
Copyright © 2018 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons
Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is
available at
http://creativecommons.org/licenses/by-sa/3.0/
. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must
provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert,
Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity
logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other
countries.
Linux ® is the registered trademark of Linus Torvalds in the United States and other countries.
Java ® is a registered trademark of Oracle and/or its affiliates.
XFS ® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United
States and/or other countries.
MySQL ® is a registered trademark of MySQL AB in the United States, the European Union and
other countries.
Node.js ® is an official trademark of Joyent. Red Hat Software Collections is not formally related
to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack ® Word Mark and OpenStack logo are either registered trademarks/service marks
or trademarks/service marks of the OpenStack Foundation, in the United States and other
countries and are used with the OpenStack Foundation's permission. We are not affiliated with,
endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.

Abstract
A guide to using API's in Red Hat JBoss BPM Suite for developers.

Table of Contents

Table of Contents
. . . . . . .I.. .OVERVIEW
PART
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
.............
.CHAPTER
. . . . . . . . . . 1.
. .ABOUT
. . . . . . . . THIS
. . . . . .GUIDE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16
.............
1.1. AUDIENCE
16
1.2. PREREQUISITES
16
.CHAPTER
. . . . . . . . . . 2.
. . RED
. . . . . HAT
. . . . . JBOSS
. . . . . . . .BRMS
. . . . . . .AND
. . . . .RED
. . . . .HAT
. . . . .JBOSS
. . . . . . . BPM
. . . . . SUITE
. . . . . . . ARCHITECTURE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18
.............
2.1. RED HAT JBOSS BUSINESS RULES MANAGEMENT SYSTEM
18
2.1.1. Red Hat JBoss BRMS Key Components
18
2.1.2. Red Hat JBoss BRMS Features
19
2.2. RED HAT JBOSS BUSINESS PROCESS MANAGEMENT SUITE
19
2.2.1. Red Hat JBoss BPM Suite Key Components
19
2.2.2. Red Hat JBoss BPM Suite Features
20
2.3. SUPPORTED PLATFORMS AND APIS
21
2.4. USE CASES
21
2.4.1. Use Case: Business Decision Management in Insurance Industry with Red Hat JBoss BRMS
21
2.4.2. Use Case: Process​-Based Solution in Loan Industry
22
.CHAPTER
. . . . . . . . . . 3.
. . APACHE
. . . . . . . . . .MAVEN
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
..............
3.1. MAVEN REPOSITORIES
24
3.2. USING THE MAVEN REPOSITORY IN YOUR PROJECT
3.3. MAVEN PROJECT CONFIGURATION FILE

24
24

3.4. MAVEN SETTINGS FILE
3.5. DEPENDENCY MANAGEMENT
3.6. INTEGRATED MAVEN DEPENDENCIES

25
26
31

3.7. UPLOADING ARTIFACTS TO MAVEN REPOSITORY
Alternative Maven Approach

31
33

3.8. DEPLOYING RED HAT JBOSS BPM SUITE ARTIFACTS TO RED HAT JBOSS FUSE
Separating Assets and Code

34
34

. . . . . . . . . . . 4.
CHAPTER
. . .INSTALL
. . . . . . . . .AND
. . . . . SET
. . . . .UP
. . . RED
. . . . . HAT
. . . . . JBOSS
. . . . . . . .DEVELOPER
. . . . . . . . . . . . .STUDIO
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
..............
4.1. INSTALLING RED HAT JBOSS DEVELOPER STUDIO PLUG-INS
4.2. CONFIGURING RED HAT JBOSS BRMS/BPM SUITE SERVER

35
35

4.3. IMPORTING PROJECTS FROM GIT REPOSITORY INTO RED HAT JBOSS DEVELOPER STUDIO
4.4. KIE NAVIGATOR

36
37

. . . . . . .II.
PART
. . ALL
. . . . .ABOUT
. . . . . . . .RULES
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
..............
.CHAPTER
. . . . . . . . . . 5.
. . RULE
. . . . . . .ALGORITHMS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
..............
5.1. PHREAK ALGORITHM
39
5.2. RULE EVALUATION WITH PHREAK ALGORITHM
39
PHREAK and Sequential Mode
40
5.3. RETE ALGORITHM
5.3.1. ReteOO
Rete Root Node
ObjectTypeNode
AlphaNodes

41
41
41
41
41

Hashing
BetaNodes
Alpha Memory and Beta Memory
Lookups with BetaNodes

41
42
42
42

LeftInputNodeAdapters
Terminal Nodes

42
42

1

Red Hat JBoss BPM Suite 6.4 Development Guide
Node Sharing
5.4. SWITCHING BETWEEN PHREAK AND RETEOO
Switching Between PHREAK and ReteOO in System Properties
Switching Between PHREAK and ReteOO in KieBaseConfiguration

42
44
44
44

.CHAPTER
. . . . . . . . . . 6.
. . GETTING
. . . . . . . . . . STARTED
. . . . . . . . . . .WITH
. . . . . .RULES
. . . . . . . AND
. . . . . FACTS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
..............
Rules Processing Steps
46
6.1. CREATING AND EXECUTING RULES
46
6.1.1. Creating and Executing Rules Using Plain Java
46
6.1.2. Creating and Executing Rules Using Maven
6.1.3. Creating and Executing Rules Using Red Hat JBoss Developer Studio
6.1.4. Creating and Executing Rules Using Business Central
6.2. EXECUTION OF RULES
6.2.1. Agenda
6.2.2. Agenda Processing
6.2.3. Conflict Resolution
6.2.4. AgendaGroup
6.2.5. setFocus()
6.2.6. ActivationGroup
6.3. INFERENCE
6.3.1. The Inference Engine

49
53
56
60
60
60
60
60
61
61
61
61

6.3.2. Inference Example
6.4. TRUTH MAINTENANCE

61
62

6.5. USING DECISION TABLES IN SPREADSHEETS

66

6.5.1. OpenOffice Example
6.5.2. Rules and Spreadsheets

66
67

6.5.3. The RuleTable Keyword
6.5.4. The RuleSet Keyword

67
67

6.5.5. Data-Defining Cells

67

6.5.6. Rule Table Columns
6.5.7. Rule Set Entries

67
68

6.5.8. Rule Attribute Entries in Rule Set Area
6.5.9. The RuleTable Cell

69
70

6.5.10. Column Types

70

6.5.11. Conditional Elements
6.5.12. Action Statements

70
71

6.5.13. Metadata Statements
6.5.14. Interpolating Cell Data Example

72
72

6.5.15. Tips for Working Within Cells

72

6.5.16. The SpreadsheetCompiler Class
6.5.17. Using Spreadsheet-Based Decision Tables

73
73

6.5.18. Lists

73

6.5.19. Revision Control
6.5.20. Tabular Data Sources

73
73

6.6. DEPENDENCY MANAGEMENT FOR GUIDED DECISION TABLES, SCORECARDS, AND RULE TEMPLATES
6.7. LOGGING
6.7.1. Configuring Logging Level

74
74
74

. . . . . . . . . . . 7.
CHAPTER
. . COMPLEX
. . . . . . . . . . . EVENT
. . . . . . . .PROCESSING
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
..............
7.1. INTRODUCTION TO COMPLEX EVENT PROCESSING
7.2. EVENTS
7.2.1. Event Declaration

2

76
77
78

Table of Contents
7.2.2. Event Metadata
7.3. CLOCK IMPLEMENTATION IN COMPLEX EVENT PROCESSING
7.3.1. Session Clock
7.3.2. Available Clock Implementations
7.4. EVENT PROCESSING MODES

79
81
81
81
82

7.4.1. Cloud Mode
7.4.2. Stream Mode

82
83

7.5. EVENT STREAMS

84

7.5.1. Declaring and Using Entry Points
7.5.2. Negative Pattern in Stream Mode

84
86

7.6. TEMPORAL OPERATIONS
7.6.1. Temporal Reasoning

87
87

7.6.2. Temporal Operations

87

7.6.3. After
7.6.4. Before

88
89

7.6.5. Coincides
7.6.6. During

90
90

7.6.7. Finishes

91

7.6.8. Finishes By
7.6.9. Includes

92
92

7.6.10. Meets
7.6.11. Met By

93
94

7.6.12. Overlaps

94

7.6.13. Overlapped By
7.6.14. Starts

95
95

7.6.15. Started By

96

7.7. SLIDING WINDOWS
7.7.1. Sliding Time Windows

97
97

7.7.2. Sliding Length Windows
7.8. MEMORY MANAGEMENT FOR EVENTS

97
98

7.8.1. Explicit Expiration

99

7.8.2. Inferred Expiration

99

.CHAPTER
. . . . . . . . . . 8.
. . .WORKING
. . . . . . . . . . WITH
. . . . . . RULES
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
...............
8.1. ABOUT RULE FILES
100
8.1.1. Rule File
8.1.2. Structure of Rule Files
8.2. OPERATING ON FACTS
8.2.1. Accessing Working Memory
8.3. USING RULE KEYWORDS
8.3.1. Hard Keywords
8.3.2. Soft Keywords
8.3.3. List of Soft Keywords

100
100
100
100
101
101
101
101

8.4. ADDING COMMENTS TO RULE FILE

104

8.4.1. Single Line Comment Example
8.4.2. Multi-Line Comment Example

104
104

8.5. ERROR MESSAGES IN RULES

105

8.5.1. Error Message Format

105

8.5.2. Error Message Description

105

8.6. PACKAGING

107

8.6.1. Import Statements
8.6.2. Using Globals

107
107

8.6.3. From Element

108

3

Red Hat JBoss BPM Suite 6.4 Development Guide
8.6.4. Using Globals with E-Mail Service
8.7. FUNCTIONS IN RULES

108
108

8.7.1. Importing Static Method Example

109

8.7.2. Calling Function Declaration Example

109

8.7.3. Type Declarations

109

8.7.4. Declaring New Types
8.7.5. Declaring New Fact Type Example

110
110

8.7.6. Declaring New Fact Type Additional Example

110

8.7.7. Using Import Example

110

8.7.8. Generated Java Classes

110

8.7.9. Generated Java Class Example
8.7.10. Using Declared Types in Rules Example

111
111

8.7.11. Declaring Metadata

111

8.7.12. Working with Metadata Attributes

111

8.7.13. Declaring Metadata Attribute with Fact Types Example

112

8.7.14. @position Attribute

112

8.7.15. @position Example
8.7.16. Predefined Class Level Annotations

112
112

8.7.17. @key Attribute Functions

113

8.7.18. @key Declaration Example

113

8.7.19. Creating Instance with Key Constructor Example

113

8.7.20. Positional Arguments
8.7.21. Positional Argument Example

113
114

8.7.22. @position Annotation

114

8.7.23. Example Patterns

114

8.8. BACKWARD-CHAINING

114
114

8.8.3. Defining Query

116

8.8.4. Transitive Closure Example

117

8.8.5. Reactive Transitive Queries

119

8.8.6. Queries with Unbound Arguments
8.8.7. Multiple Unbound Arguments

120
121

8.9. TYPE DECLARATION

4

114

8.8.1. Backward-Chaining Systems
8.8.2. Cloning Transitive Closures

122

8.9.1. Declaring Metadata for Existing Types

122

8.9.2. Declaring Metadata for Existing Types Example

122

8.9.3. Declaring Metadata Using Fully Qualified Class Name Example
8.9.4. Parametrized Constructors for Declared Types Example

122
122

8.9.5. Non-Typesafe Classes

122

8.9.6. Accessing Declared Types from Application Code

123

8.9.7. Declaring Type

123

8.9.8. Handling Declared Fact Types Through API Example
8.9.9. Type Declaration Extends

123
124

8.9.10. Type Declaration Extends Example

124

8.9.11. Traits

124

8.9.12. Traits Example

124

8.9.13. Core Objects and Traits

125

8.9.14. @traitable Example
8.9.15. Writing Rules with Traits

125
125

8.9.16. Rules with Traits Example

125

8.9.17. Hidden Fields

126

8.9.18. Two-Part Proxy

126

8.9.19. Wrappers

126

Table of Contents
8.9.20. Wrapper Example

126

8.9.21. Wrapper with isA Annotation Example

126

8.9.22. Removing Traits

126

8.10. RULE ATTRIBUTES

127

8.10.1. Timer Attribute Example
8.10.2. Timers

127
127

8.10.3. Cron Timer Example

128

8.10.4. Calendars

128

8.10.5. Quartz Calendar Example

128

8.10.6. Registering Calendar
8.10.7. Left Hand Side

128
129

8.10.8. Conditional Elements

129

8.10.9. Rule Without Conditional Element Example

129

8.11. PATTERNS

129

8.11.1. Pattern Example

129

8.11.2. Pattern Matching
8.11.3. Pattern Binding

130
130

8.11.4. Pattern Binding with Variable Example

130

8.11.5. Constraints

130

8.12. ELEMENTS AND VARIABLES

130

8.12.1. Property Access on Java Beans (POJOs)
8.12.2. POJO Example

131
131

8.12.3. Working with POJOs

131

8.12.4. POJO Fallbacks

131

8.12.5. Fallback Example

132

8.12.6. Java Expressions
8.12.7. Comma-Separated Operators

132
134

8.12.8. Comma-Separated Operator Example

134

8.12.9. Binding Variables

134

8.12.10. Binding Variable Examples

134

8.12.11. Unification
8.12.12. Unification Example

135
135

8.12.13. Options and Operators in Red Hat JBoss BRMS

135

8.12.14. Operator Precedence

138

8.12.15. Fine Grained Property Change Listeners

138

8.12.16. Fine Grained Property Change Listener Example
8.12.17. Working with Fine Grained Property Change Listeners

139
139

8.12.18. Using Patterns with @watch

139

8.12.19. @watch Example

139

8.12.20. Using @PropertySpecificOption

140

8.12.21. Basic Conditional Elements
8.12.22. Conditional Element forall

140
142

8.12.23. forall Examples

142

8.12.24. Conditional Element from

143

8.12.25. from Examples

143

8.12.26. Conditional Element collect

144

8.12.27. Conditional Element accumulate
Top-Level accumulate Syntax

145
145

Built-in accumulate Functions

145

Accumulate Functions Pluggability

146

Alternative Syntax

148

accumulate with Inline Custom Code
Custom Objects

149
150

5

Red Hat JBoss BPM Suite 6.4 Development Guide
8.12.28. Conditional Element eval

151

8.12.29. eval Conditional Element Examples

151

8.12.30. Right Hand Side

151

8.12.31. RHS Convenience Methods
8.12.32. Convenience Methods Using Drools Variable

151
152

8.12.33. Convenience Methods Using kcontext Variable

152

8.12.34. Modify Statement

153

8.12.35. Query Examples

153

8.12.36. QueryResults Example
8.12.37. Queries Calling Other Queries

153
154

8.12.38. Queries Calling Other Queries Example

154

8.12.39. Unification for Derivation Queries

155

8.13. SEARCHING WORKING MEMORY USING QUERY

155

8.13.1. Queries

155

8.13.2. Live Queries
8.13.3. ViewChangedEventListener Implementation Example

155
155

8.14. DOMAIN SPECIFIC LANGUAGES (DSLS)

156

8.14.1. DSL Editor

156

8.14.2. Using DSLs

156

8.14.3. DSL Example

157

8.14.4. About DSL Parser
8.14.5. About DSL Compiler
8.14.6. DSL Syntax Examples

157
157
157

8.14.7. Chaining DSL Expressions
8.14.8. Adding Constraints to Facts

158
158

8.14.9. Tips for Developing DSLs
8.14.10. DSL and DSLR Reference
8.14.11. DSL Entry Description

159
160
160

8.14.12. Debug Options for DSL Expansion
8.14.13. DSL Definition Example

161
161

8.14.14. Transformation of DSLR File
8.14.15. String Transformation Functions

161
162

8.14.16. Stringing DSL Transformation Functions

163

.CHAPTER
. . . . . . . . . . 9.
. . USING
. . . . . . . .RED
. . . . .HAT
. . . . .JBOSS
. . . . . . .DEVELOPER
. . . . . . . . . . . . . STUDIO
. . . . . . . . .TO
. . . CREATE
. . . . . . . . . AND
. . . . . .TEST
. . . . . .RULES
. . . . . . . . . . . . . . . . . . . . . . 164
...............
9.1. RED HAT JBOSS DEVELOPER STUDIO DROOLS PERSPECTIVE
164
9.2. RED HAT JBOSS BRMS RUNTIMES
164
9.2.1. Defining a Red Hat JBoss BRMS Runtime
9.2.2. Selecting a Runtime for Your Red Hat JBoss BRMS Project

164
165

9.2.3. Changing the Runtime of Your Red Hat JBoss BRMS Project
9.2.4. Configuring the Red Hat JBoss BRMS Server
9.3. EXPLORING RED HAT JBOSS BRMS APPLICATION

165
165
166

9.4. CREATING A RED HAT JBOSS BRMS PROJECT
9.5. USING TEXTUAL RULE EDITOR

166
167

9.6. RED HAT JBOSS BRMS VIEWS
9.7. DEBUGGING RULES
9.7.1. Creating Breakpoints

167
168
169

. . . . . . .III.
PART
. . .ALL
. . . . ABOUT
. . . . . . . . PROCESSES
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .170
..............
. . . . . . . . . . . 10.
CHAPTER
. . . GETTING
. . . . . . . . . . STARTED
. . . . . . . . . . .WITH
. . . . . .PROCESSES
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
..............
10.1. THE RED HAT JBOSS BPM SUITE ENGINE
10.2. INTEGRATING BPM SUITE ENGINE WITH OTHER SERVICES

6

171
171

Table of Contents
.CHAPTER
. . . . . . . . . . 11.
. . .WORKING
. . . . . . . . . . .WITH
. . . . . .PROCESSES
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173
..............
11.1. BPMN 2.0 NOTATION
173
11.1.1. Business Process Model and Notation (BPMN) 2.0 Specification
BPMN 2.0 Supported Elements and Attributes (Events)
BPMN 2.0 Supported Elements and Attributes (Activities)
BPMN 2.0 Supported Elements and Attributes (Gateways)
BPMN 2.0 Supported Elements and Attributes (Data)

173
174
177
179
180

BPMN 2.0 Supported Elements and Attributes (BPMNDI)
11.1.2. BPMN 2.0 Process Example

182
183

11.1.3. Supported Elements and Attributes in BPMN 2.0 Specification
Flow Objects
Data

184
184
185

Connecting Objects
11.1.4. Loading and Executing a BPMN2 Process Into Repository

185
186

11.2. WHAT COMPRISES A BUSINESS PROCESS
11.2.1. Process Nodes
11.2.2. Process Properties

186
187
187

11.2.3. Defining Processes Using XML
11.3. ACTIVITIES

187
189

11.3.1. Tasks
11.3.2. Subprocesses
11.4. DATA

189
192
194

11.5. EVENTS
11.5.1. Start Events

195
196

11.5.2. End Events
11.5.3. Intermediate Events
11.5.3.1. Catching Intermediate Events

198
199
199

11.5.3.2. Throwing Intermediate Events
11.6. GATEWAYS

200
200

11.6.1. Gateway Types
11.6.1.1. Event-Based Gateway

201
201

11.6.1.2. Parallel Gateway
11.6.1.3. Inclusive Gateway
Attributes

201
201
201

11.6.1.4. Data-Based Exclusive Gateway
Attributes

201
202

11.7. VARIABLES
11.8. ASSIGNMENT
11.9. ACTION SCRIPTS

202
203
203

Process Instance Action Scripts
11.10. CONSTRAINTS

203
204

11.11. TIMERS
Configuring Timer with Delay and Period
Configuring Timer ISO-8601 Date Format

205
205
205

Configuring Timer with Process Variables
Updating Timer Within a Running Process Instance
Troubleshooting
11.12. MULTI-THREADING
11.12.1. Multi-Threading

205
205
206
207
207

11.12.2. Engine Execution
11.12.3. Job Executor for Asynchronous Execution

207
208

11.12.4. Using Job Executor in Embedded Mode
11.12.5. Hello World Example with Embedded Job Executor

209
213

7

Red Hat JBoss BPM Suite 6.4 Development Guide
11.12.6. Using Job Executor in Business Central

217

Executor Configuration
11.12.7. Multiple Sessions and persistence

220
220

11.12.8. Asynchronous Events
11.12.9. Technical exceptions
Code in Element properties

221
221
221

Code in WorkItemHandlers
11.12.9.1. Technical exception examples

222
222

11.12.9.1.1. Service Task handlers
11.12.9.1.2. Exception handling classes
11.12.9.1.3. Exception service

222
224
226

11.12.9.1.4. Handling errors with Signals
11.12.9.1.5. Extracting information from WorkflowRuntimeException

227
228

11.13. PROCESS FLUENT API
11.13.1. Using the Process Fluent API to Create Business Process
11.13.2. Process Fluent API Example

230
230
230

11.14. TESTING BUSINESS PROCESSES
11.14.1. JbpmJUnitBaseTestCase

231
233

11.14.2. Configuring Persistence
11.14.3. Testing Integration with External Services

238
238

.CHAPTER
. . . . . . . . . . 12.
. . . HUMAN
. . . . . . . . .TASKS
. . . . . . . .MANAGEMENT
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
...............
12.1. HUMAN TASKS
241
12.2. USING USER TASKS IN PROCESSES
12.3. DATA MAPPING

241
242

12.4. TASK LIFECYCLE
12.5. TASK PERMISSIONS

242
244

12.5.1. Task Permissions Matrix
Permissions Matrices
12.6. TASK SERVICE

244
245
245

12.6.1. Task Service and Process Engine
12.6.2. Task Service API

245
246

12.6.3. Interacting with the Task Service
12.6.4. Accessing Task Variables Using TaskEventListener
12.6.5. Task Service Data Model

247
248
251

Tasks
Entities and People Assignments

251
254

Reassignments
Notifications
Attachments

254
255
255

Delegations
12.6.6. Connecting to Custom Directory Information Services
12.6.7. LDAP Connection
12.6.7.1. Connecting to LDAP
12.7. TASK ESCALATION

257
258
259

12.8. RETRIEVING PROCESS AND TASK INFORMATION
12.9. ADVANCED QUERIES WITH QUERYSERVICE

260
262

12.9.1. QueryResultMapper
12.9.2. QueryParamBuilder
12.9.3. Implementing QueryParamBuilder

263
264
264

12.9.4. QueryService in Embedded Mode
12.9.5. Advanced Queries Through Intelligent Process Server

265
267

12.10. PROCESS INSTANCE MIGRATION

8

256
256

273

Table of Contents
Migration Report
Known Limitations

276
277

. . . . . . . . . . . 13.
CHAPTER
. . . PERSISTENCE
. . . . . . . . . . . . . . . .AND
. . . . .TRANSACTIONS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
...............
13.1. PROCESS INSTANCE STATE
13.1.1. Runtime State
13.1.2. Binary Persistence

279
279
279

13.1.3. Data Model Description
13.1.4. Safe Points

279
283

13.2. AUDIT LOG
13.2.1. Audit Data Model
13.2.2. Audit Data Model Description

283
284
284

13.2.3. Storing Process Events in a Database
13.2.4. Storing Process Events in a JMS Queue

288
289

13.2.5. Auditing Variables
13.2.6. Building and Registering Custom Indexers
13.3. TRANSACTIONS

290
292
293

13.4. IMPLEMENTING CONTAINER MANAGED TRANSACTION
13.5. USING PERSISTENCE

294
295

13.5.1. Adding Dependencies
13.5.2. Manually Configuring Red Hat JBoss BPM Suite Engine to Use Persistence

295
296

.CHAPTER
. . . . . . . . . . 14.
. . . USING
. . . . . . . .RED
. . . . .HAT
. . . . JBOSS
. . . . . . . .DEVELOPER
. . . . . . . . . . . . . STUDIO
. . . . . . . . .TO
. . . CREATE
. . . . . . . . . AND
. . . . . .TEST
. . . . . PROCESSES
. . . . . . . . . . . . . . . . . . . . . .299
...............
14.1. RED HAT JBOSS BPM SUITE RUNTIME
299
14.1.1. Red Hat JBoss BPM Suite Runtime
14.1.2. Setting the Red Hat JBoss BPM Suite Runtime

299
299

14.1.3. Configuring Red Hat JBoss BPM Suite Server
299
14.2. IMPORTING AND CLONING PROJECTS FROM GIT REPOSITORY INTO RED HAT JBOSS DEVELOPER
STUDIO
302
14.3. COMPONENTS OF RED HAT JBOSS BPM SUITE APPLICATION
303
14.4. CREATING RED HAT JBOSS BPM SUITE PROJECT
303
14.5. CONVERTING EXISTING JAVA PROJECT TO RED HAT JBOSS BPM SUITE PROJECT
14.6. CREATING PROCESSES IN RED HAT JBOSS DEVELOPER STUDIO

304
304

14.7. MODELING AND VALIDATING PROCESSES IN RED HAT JBOSS DEVELOPER STUDIO
14.8. AUDIT VIEW
14.8.1. File Logger

304
305
305

14.9. SYNCHRONIZING RED HAT JBOSS DEVELOPER STUDIO WORKSPACE WITH BUSINESS CENTRAL
REPOSITORIES

306

14.9.1. Importing Business Central Repository
14.9.2. Committing Changes to Business Central

306
307

14.9.3. Retrieving Changes from Business Central Repository
14.9.4. Importing Individual Projects from Repository
14.9.5. Adding Red Hat JBoss BPM Suite Libraries to Project Class Path

307
307
308

. . . . . . . . . . . 15.
CHAPTER
. . . CASE
. . . . . . .MANAGEMENT
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .309
...............
15.1. INTRODUCTION
15.2. USE CASES

309
309

15.3. CASE MANAGEMENT IN RED HAT JBOSS BPM SUITE
15.4. STARTING A CASE
15.5. EXAMPLE CASE MODEL

310
311
312

. . . . . . .IV.
PART
. . .INTELLIGENT
. . . . . . . . . . . . . . PROCESS
. . . . . . . . . . .SERVER
. . . . . . . . .AND
. . . . . REALTIME
. . . . . . . . . . . DECISION
. . . . . . . . . . . SERVER
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
...............
. . . . . . . . . . . 16.
CHAPTER
. . . THE
. . . . . REST
. . . . . . API
. . . . FOR
. . . . . INTELLIGENT
. . . . . . . . . . . . . . .PROCESS
. . . . . . . . . .SERVER
. . . . . . . . . EXECUTION
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .315
..............
16.1. BRMS COMMANDS

316

9

Red Hat JBoss BPM Suite 6.4 Development Guide
16.2. MANAGING PROCESSES

317

16.3. MANAGING PROCESS DEFINITIONS
16.4. MANAGING USER TASKS
16.4.1. Managing Task Instances

321
323
323

16.4.2. Managing Task Instance Data
16.5. QUERYING PROCESS INSTANCES

327
331

16.6. QUERYING TASKS
16.7. ADVANCED QUERIES FOR THE INTELLIGENT PROCESS SERVER
16.8. MANAGING JOB EXECUTION

337
341
344

Job Execution Endpoints

345

.CHAPTER
. . . . . . . . . . 17.
. . . THE
. . . . .REST
. . . . . .API
. . . . FOR
. . . . . INTELLIGENT
. . . . . . . . . . . . . . PROCESS
. . . . . . . . . . .SERVER
. . . . . . . . .ADMINISTRATION
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .348
...............
17.1. MANAGED INTELLIGENT PROCESS SERVER ENVIRONMENT
348
17.2. UNMANAGED INTELLIGENT PROCESS SERVER ENVIRONMENT

353

.CHAPTER
. . . . . . . . . . 18.
. . . INTELLIGENT
. . . . . . . . . . . . . . .PROCESS
. . . . . . . . . . SERVER
. . . . . . . . . UI
. . .EXTENSION
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
...............
18.1. USING THE INTELLIGENT PROCESS SERVER UI EXTENSION
372
.CHAPTER
. . . . . . . . . . 19.
. . . INTELLIGENT
. . . . . . . . . . . . . . .PROCESS
. . . . . . . . . . SERVER
. . . . . . . . . JAVA
. . . . . . .CLIENT
. . . . . . . .API
. . . .OVERVIEW
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
...............
19.1. CLIENT CONFIGURATION
378
19.1.1. JMS Interaction Patterns
19.2. SERVER RESPONSE

380
381

19.3. INSERTING AND EXECUTING COMMANDS
19.4. LISTING SERVER CAPABILITIES
19.5. LISTING CONTAINERS

382
383
383

19.6. HANDLING CONTAINERS
19.7. AVAILABLE INTELLIGENT PROCESS SERVER CLIENTS

384
385

19.8. LISTING AVAILABLE BUSINESS PROCESSES
19.9. STARTING A BUSINESS PROCESSES

386
386

19.10. QUERYDEFINITION FOR INTELLIGENT PROCESS SERVER USING JAVA CLIENT API

387

. . . . . . .V.
PART
. . KIE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .389
...............
.CHAPTER
. . . . . . . . . . 20.
. . . .JAVA
. . . . . . APIS
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .390
...............
20.1. KIE API
390
20.1.1. KIE Framework
390
20.1.2. KIE Base
20.1.3. KIE Session

10

391
394

20.1.3.1. Process Runtime Interface
20.1.3.2. Event Listeners
20.1.3.2.1. Process Event Listeners

396
398
398

20.1.3.2.2. Rule Event Listeners
20.1.3.3. Loggers

399
401

20.1.3.4. Correlation Keys
20.1.3.5. Threads
20.1.3.6. Globals

401
404
404

20.1.4. KIE File System
20.1.5. KIE Module

405
407

20.1.6. KIE Container
20.1.6.1. KIE Base Configuration
20.1.7. KIE Maven Plug-in

409
411
412

20.1.8. KIE Repository
20.1.9. KIE Scanner

412
413

20.1.10. Command Executor

414

Table of Contents
20.1.10.1. Marshalling
20.1.10.1.1. XStream
JSON
JAXB
XSD File

416
416
416
416
416

Using POJO Model
20.1.10.2. Supported Commands
20.1.10.2.1. BatchExecutionCommand

417
417
418

20.1.10.2.2. InsertObjectCommand
20.1.10.2.3. RetractCommand

419
421

20.1.10.2.4. ModifyCommand
20.1.10.2.5. GetObjectCommand
20.1.10.2.6. InsertElementsCommand

421
422
423

20.1.10.2.7. FireAllRulesCommand
20.1.10.2.8. StartProcessCommand

425
426

20.1.10.2.9. SignalEventCommand
20.1.10.2.10. CompleteWorkItemCommand
20.1.10.2.11. AbortWorkItemCommand

427
428
428

20.1.10.2.12. QueryCommand
20.1.10.2.13. SetGlobalCommand

429
430

20.1.10.2.14. GetGlobalCommand
20.1.10.2.15. GetObjectsCommand
20.1.11. KIE Configuration

431
432
433

20.1.11.1. Build Result Severity
20.1.11.2. StatelessKieSession

433
433

20.1.11.2.1. Sequential Mode
20.1.11.3. Marshalling

435
437

20.1.11.4. KIE Persistence
20.1.12. KIE Sessions
20.1.12.1. Stateless KIE Sessions

439
441
441

20.1.12.1.1. Configuring Rules in Stateless Session
20.1.12.1.2. Configuring Rules with Multiple Objects

441
442

20.1.12.2. Stateful KIE Sessions
20.1.12.2.1. Common Use Cases for Stateful Sessions
20.1.12.2.2. Stateful Session Monitoring Example

444
444
444

20.2. RUNTIME MANAGER
20.2.1. Usage
20.2.1.1. Usage Scenario
20.2.1.2. Building Runtime Manager

445
447
447
447

Runtime Manager Identifier
20.2.2. Runtime Environment
20.2.3. Strategies
20.2.3.1. Singleton Strategy
20.2.3.2. Per Request Strategy

448
448
449
449
450

20.2.3.3. Per Process Instance Strategy
20.2.4. Handlers and Listeners
20.2.4.1. Registering Through Registerable Items Factory
20.2.4.2. Registering Through Configuration Files
20.2.4.3. Registering in CDI Environment

450
451
451
452
453

20.2.5. Control Parameters
20.2.6. Variable Persistence Strategy
JPA Placeholder Resolver Strategy
Creating Custom Strategy

455
459
460
460

11

Red Hat JBoss BPM Suite 6.4 Development Guide
20.3. KIE SERVICES
20.3.1. Deployment Service
20.3.2. Definition Service

461
462
462

20.3.3. Process Service
20.3.4. Runtime Data Service
20.3.5. User Task Service
20.3.6. Query Service
20.3.6.1. Terminology

463
463
464
465
465

20.3.6.2. Query Result Mapper
20.3.6.3. Query Parameter Builder
20.3.6.4. Typical usage scenario
20.3.7. Process Instance Migration Service
20.3.7.1. Migration report

465
466
468
469
470

20.3.7.2. Known limitations
20.3.7.3. Example
20.3.8. Form Provider Service
20.3.9. Executor Service
20.4. CDI INTEGRATION
20.4.1. Configuring CDI Integration
20.4.2. Deployment Service as CDI Bean
20.4.2.1. Saving and Removing Deployments from Database
20.4.2.2. Available Deployment Services
20.4.3. Runtime Manager as CDI Bean

470
470
471
472
472
472
474
474
474
475

. . . . . . . . . . . 21.
CHAPTER
. . . REMOTE
. . . . . . . . . .API
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
...............
21.1. REST API
21.1.1. Knowledge Store REST API
21.1.1.1. Job Calls
21.1.1.2. Organizational Unit Calls
21.1.1.3. Repository Calls
21.1.1.4. Maven Calls
21.1.2. Deployment REST API
21.1.2.1. Deployment Calls
21.1.2.2. Asynchronous Calls
21.1.3. Process Image REST API

483
484
484
487
487

21.1.4. Runtime REST API
21.1.4.1. Query Parameters
21.1.4.1.1. Map Parameters
21.1.4.1.2. Pagination
21.1.4.1.3. Object Data Type Parameters

488
488
488
489
489

21.1.4.2. Runtime Calls
21.1.4.2.1. Process Calls
21.1.4.2.2. Signal Calls
21.1.4.2.3. Work Item Calls
21.1.4.2.4. History Calls
History Variable Calls
21.1.4.3. Task Calls
21.1.4.3.1. Task Operations
21.1.4.3.2. Content Operations
21.1.5. REST Query API
21.1.5.1. URL Layout
21.1.5.2. Query Parameters
21.1.5.2.1. Range and Regular Expression Parameters

12

478
479
479
480
481

490
490
491
492
492
493
493
494
495
495
495
496
496

Table of Contents
21.1.5.2.2. Range Query Parameters
21.1.5.2.3. Regular Expression Query Parameters
21.1.5.3. List of Query Parameters
21.1.5.4. Query Output Format
21.1.6. Execute Operations
21.1.6.1. Execute Operation Commands
Simple Call Example

497
497
498
502
502
507
509

Custom Data Type Call Example
21.1.7. REST API Summary
21.1.8. Control of REST API
21.2. JMS
21.2.1. JMS Queue Setup

510
511
517
518
518

21.2.2. Example JMS Usage
21.3. SOAP API
21.3.1. CommandWebService
21.4. EJB INTERFACE
Deployment of EJB Client

519
525
526
526
527

21.4.1. EJB Interface Artifacts
21.4.2. Generating EJB Services WAR File
21.5. REMOTE JAVA API
Remote Java API Methods
Starting Project: Adding Dependencies

527
528
529
531
531

21.5.1. Common Configuration
21.5.2. REST Client
21.5.2.1. Retrieving Potential Owners of Human Task
21.5.2.2. Calling Tasks Without Deployment ID
21.5.2.3. Custom Model Objects and Remote API

531
532
534
534
535

21.5.3. JMS Client
Configuration Using InitialContext Instance
21.5.4. Supported Methods
Available Process-Related KieSession Methods
Available Rules-Related KieSession Methods

537
539
539
539
540

Available WorkItemManager Methods
Available Task Operation TaskService Methods
Available Task Retrieval and Query TaskService Methods
Available AuditService Methods
21.6. TROUBLESHOOTING
21.6.1. Serialization Issues
21.6.2. Insecure Task Operations

540
540
541
542
543
543
544

. . . . . . . . . . . . A.
APPENDIX
. . .VERSIONING
. . . . . . . . . . . . . INFORMATION
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .546
...............

13

Red Hat JBoss BPM Suite 6.4 Development Guide

14

PART I. OVERVIEW

PART I. OVERVIEW

15

Red Hat JBoss BPM Suite 6.4 Development Guide

CHAPTER 1. ABOUT THIS GUIDE
This guide is intended for users who are implementing a standalone Red Hat JBoss BRMS solution or
the complete Red Hat JBoss BPM Suite solution. It discusses the following topics:
Detailed Architecture of Red Hat JBoss BRMS and Red Hat JBoss BPM Suite.
Detailed description of how to author, test, debug, and package simple and complex business
rules and processes using Integrated Development environment (IDE).
Red Hat JBoss BRMS runtime environment.
Domain specific languages (DSLs) and how to use them in a rule.
Complex event processing.
This guide comprises the following sections:
1. Overview
This section provides detailed information on Red Hat JBoss BRMS and Red Hat JBoss BPM
suite, their architecture, key components. It also discusses the role of Maven in project building
and deploying.
2. All About Rules
This section provides details on all you have to know to author rules with Red Hat JBoss
Developer Studio. It describes the rule algorithms, rule structure, components, advanced
conditions, constraints, commands, Domain Specific Languages and Complex Event
Processing. It provides details on how to use the various views, editors, and perspectives that
Red Hat JBoss Developer Studio offers.
3. All About Processes
This section describes what comprises a business process and how you can author and test
them using Red Hat JBoss Developer Studio.
4. KIE
This section highlights the KIE API with detailed description of how to create, build, deploy, and
run KIE projects.
5. Appendix
This section comprises important reference material such as key knowledge terms, and
examples.

1.1. AUDIENCE
This book has been designed to be understood by:
Author of rules and processes who are responsible for authoring and testing business rules
and processes using Red Hat JBoss Developer Studio.
Java application developers responsible for developing and integrating business rules and
processes into Java and Java EE enterprise applications.

1.2. PREREQUISITES
Users of this guide must meet one or more of the following prerequisites:

16

CHAPTER 1. ABOUT THIS GUIDE

Basic Java/Java EE programming experience
Knowledge of the Eclipse IDE, Maven, and GIT

17

Red Hat JBoss BPM Suite 6.4 Development Guide

CHAPTER 2. RED HAT JBOSS BRMS AND RED HAT JBOSS
BPM SUITE ARCHITECTURE
2.1. RED HAT JBOSS BUSINESS RULES MANAGEMENT SYSTEM
Red Hat JBoss BRMS is an open source business rule management system that provides rules
development, access, change, and management capabilities. In today’s world, when IT organizations
consistently face changes in terms of policies, new products, government imposed regulations, a
system like JBoss BRMS makes it easy by separating business logic from the underlying code. It
includes a rule engine, a rules development environment, a management system, and a repository. It
allows both developers and business analysts to view, manage, and verify business rules as they are
executed within an IT application infrastructure.
Red Hat JBoss BRMS can be executed in any Java EE-compliant container. It supports an open choice
of authoring and management consoles and language and decision table inputs.

2.1.1. Red Hat JBoss BRMS Key Components
Red Hat JBoss BRMS comprises the following components:
Drools Expert
Drools Expert is a pattern matching based rule engine that runs on Java EE application
servers, Red Hat JBoss BRMS platform, or bundled with Java applications. It comprises an
inference engine, a production memory, and a working memory. Rules are stored in the
production memory and the facts that the inference engine matches the rules against, are
stored in the working memory.
Business Central
Business Central is a web-based application intended for business analysts for creation and
maintenance of business rules and rule artifacts. It is designed to ease creation, testing, and
packaging of rules for business users.
Drools Flow
Drools flow provides business process capabilities to the Red Hat JBoss BRMS platform. This
framework can be embedded into any Java application or can even run standalone on a server.
A business process provides stepwise tasks using a flow chart, for the Rule Engine to execute.
Drools Fusion
Drools Fusion provides event processing capabilities to the Red Hat JBoss BRMS platform.
Drools Fusion defines a set of goals to be achieved such as:
Support events as first class citizens.
Support detection, correlation, aggregation and composition of events.
Support processing streams of events.
Support temporal constraints in order to model the temporal relationships between
events.
Drools Integrated Development Environment (IDE)
We encourage you to use Red Hat JBoss Developer Studio (JBDS) with Red Hat JBoss BRMS
plug-ins to develop and test business rules. The Red Hat JBoss Developer Studio builds upon
an extensible, open source Java-based IDE Eclipse providing platform and framework
capabilities, making it ideal for Red Hat JBoss BRMS rules development.

18

CHAPTER 2. RED HAT JBOSS BRMS AND RED HAT JBOSS BPM SUITE ARCHITECTURE

2.1.2. Red Hat JBoss BRMS Features
The Red Hat JBoss BRMS provides the following key features:
Centralized repository of business assets (JBoss BRMS artifacts).
IDE tools to define and govern decision logic.
Building, deploying, and testing the decision logic.
Packages of business assets.
Categorization of business assets.
Integration with development tools.
Business logic and data separation.
Business logic open to reuse and changes.
Easy to maintain business logic.
Enables several stakeholders (business analysts, developer, administrators) to contribute in
defining the business logic.

2.2. RED HAT JBOSS BUSINESS PROCESS MANAGEMENT SUITE
Red Hat JBoss BPM Suite is an open source business process management system that combines
business process management and business rules management. Red Hat JBoss BRMS offers tools to
author rules and business processes, but does not provide tools to start or manage the business
processes. Red Hat JBoss BPM Suite includes all the Red Hat JBoss BRMS functionality, with
additional capabilities of business activity monitoring, starting business processes, and managing
tasks using Business Central. Red Hat JBoss BPM Suite also provides a central repository to store
rules and processes.

2.2.1. Red Hat JBoss BPM Suite Key Components
The Red Hat JBoss BPM Suite comprises the following components:
JBoss BPM Central (Business Central)
Business Central is a web-based application for creating, editing, building, managing, and
monitoring Red Hat JBoss BPM Suite business assets. It also allows execution of business
processes and management of tasks created by those processes.
Business Activity Monitoring Dashboards
The Business Activity Monitor (BAM) dashboard provides report generation capabilities. It
enables you to use a pre-defined dashboard and even create your own customized dashboard.
Maven Artifact Repository
Red Hat JBoss BPM Suite projects are built as Apache Maven projects and the default location
of the Maven repository is WORKING_DIRECTORY/repositories/kie. You can specify an
alternate repository location by changing the org.guvnor.m2repo.dir property.
Each project builds a JAR artifact file called a KJAR. You can store your project artifacts and
dependent JAR files in this repository.

19

Red Hat JBoss BPM Suite 6.4 Development Guide

Execution Engine
The Red Hat JBoss BPM Suite execution engine is responsible for executing business
processes and managing the tasks, which result from these processes. Business Central
provides a user interface for executing processes and managing tasks.

NOTE
To execute your business processes, you can use Business Central web
application that bundles the execution engine, enabling a ready-to-use process
execution environment. Alternatively, you can create your own execution server
and embed the Red Hat JBoss BPM Suite and Red Hat JBoss BRMS libraries
with your application using Java EE.
For example, if you are developing a web application, include the Red Hat JBoss
BPM Suite or Red Hat JBoss BRMS libraries in the WEB-INF/lib folder of your
application.
Business Central Repository
The business artifacts of a Red Hat JBoss BPM Suite project, such as process models, rules,
and forms, are stored in Git repositories managed through the Business Central. You can also
access these repositories outside of Business Central through the Git or SSH protocols.

2.2.2. Red Hat JBoss BPM Suite Features
Red Hat JBoss BPM Suite provides the following features:
Pluggable human task service for including tasks that need to be performed by human actors
(based on the WS-HumanTask specification).
Pluggable persistence and transactions (based on JPA/JTA).
Web-based process designer to support the graphical creation and simulation of your business
processes (drag and drop).
Web-based data modeler and form modeler to support the creation of data models and
process and task forms.
Web-based, customizable dashboards and reporting.
A web-based workbench called Business Central, supporting the complete BPM life cycle:
Modeling and deployment: to author your processes, rules, data models, forms and other
assets.
Execution: to execute processes, tasks, rules and events on the core runtime engine.
Runtime Management: to work on assigned task, manage process instances.
Reporting: to monitor the execution using Business Activity Monitoring capabilities.
Eclipse-based developer tools to support the modeling, testing and debugging of processes.
Remote API to process engine as a service (REST, JMS, Remote Java API).
Integration with Maven, Spring, and OSGi.

20

CHAPTER 2. RED HAT JBOSS BRMS AND RED HAT JBOSS BPM SUITE ARCHITECTURE

2.3. SUPPORTED PLATFORMS AND APIS
For a list of supported containers and configurations, see section Supported Platforms of Red Hat JBoss
BPM Suite Installation Guide.
The kie-api is a fully supported API and it is the recommended way to interact with your project. For
further information about API supportability, see Knowledgebase article What Are the Public and
Internal APIs for BPM Suite and BRMS 6?.

2.4. USE CASES
2.4.1. Use Case: Business Decision Management in Insurance Industry with Red Hat
JBoss BRMS
Red Hat JBoss BRMS comprises a high performance rule engine, a rule repository, easy to use rule
authoring tools, and complex event processing rule engine extensions. The following use case
describes how these features of Red Hat JBoss BRMS are implemented in insurance industry.
The consumer insurance market is extremely competitive, and it is imperative that customers receive
efficient, competitive, and comprehensive services when visiting an online insurance quotation
solution. An insurance provider increased revenue from their online quotation solution by upselling
relevant, additional products during the quotation process to the visitors of the solution.
The diagram below shows integration of Red Hat JBoss BRMS with the insurance provider’s
infrastructure. This integration is fruitful in such a way that when a request for insurance is processed,
Red Hat JBoss BRMS is consulted and appropriate additional products are presented with the
insurance quotation.

21

Red Hat JBoss BPM Suite 6.4 Development Guide

Figure 2.1. JBoss BRMS Use Case: Insurance Industry Decision Making

Red Hat JBoss BRMS provides the decision management functionality, that automatically determines
the products to present to the applicant based on the rules defined by the business analysts. The rules
are implemented as decision tables, so they can be easily understood and modified without requiring
additional support from IT.

2.4.2. Use Case: Process​-Based Solution in Loan Industry
This section describes a use case of deploying Red Hat JBoss BPM Suite to automate business
processes (such as loan approval process) at a retail bank. This use case is a typical process-based
specific deployment that might be the first step in a wider adoption of Red Hat JBoss BPM Suite
throughout an enterprise. It leverages features of both business rules and processes of Red Hat JBoss
BPM Suite.
A retail bank offers several types of loan products each with varying terms and eligibility
requirements. Customers requiring a loan must file a loan application with the bank. The bank then
processes the application in several steps, such as verifying eligibility, determining terms, checking for
fraudulent activity, and determining the most appropriate loan product. Once approved, the bank
creates and funds a loan account for the applicant, who can then access funds. The bank must be sure
to comply with all relevant banking regulations at each step of the process, and has to manage its loan
portfolio to maximize profitability. Policies are in place to aid in decision making at each step, and
those policies are actively managed to optimize outcomes for the bank.
Business analysts at the bank model the loan application processes using the BPMN2 authoring tools
(Process Designer) in Red Hat JBoss BPM Suite. Here is the process flow:

22

CHAPTER 2. RED HAT JBOSS BRMS AND RED HAT JBOSS BPM SUITE ARCHITECTURE

High-Level Loan Application Process Flow

Business rules are developed with the rule authoring tools in Red Hat JBoss BPM Suite to enforce
policies and make decisions. Rules are linked with the process models to enforce the correct policies
at each process step.
The bank’s IT organization deploys the Red Hat JBoss BPM Suite so that the entire loan application
process can be automated.
Figure 2.2. Loan Application Process Automation

The entire loan process and rules can be modified at any time by the bank’s business analysts. The
bank is able to maintain constant compliance with changing regulations, and is able to quickly
introduce new loan products and improve loan policies in order to compete effectively and drive
profitability.

23

Red Hat JBoss BPM Suite 6.4 Development Guide

CHAPTER 3. APACHE MAVEN
Apache Maven is a distributed build automation tool used in Java application development to build and
manage software projects. Apart from building, publishing, and deploying capabilities, using Maven for
your Red Hat JBoss BRMS and Red Hat JBoss BPM suite projects ensures the following:
The build process is easy and a uniform build system is implemented across projects.
All of the required JAR files for a project are made available at compile time.
A proper project structure is configured.
Dependencies and versions are well managed.
No need for additional build processing, as Maven builds output into a number of predefined
types, such as JAR and WAR.

3.1. MAVEN REPOSITORIES
Maven uses repositories to store Java libraries, plug-ins, and other build artifacts. These repositories
can be local or remote. Red Hat JBoss BRMS and Red Hat JBoss BPM Suite products maintain local
and remote maven repositories that you can add to your project for accessing the rules, processes,
events, and other project dependencies. You must configure Maven to use these repositories and the
Maven Central Repository to provide correct build functionality.
When building projects and archetypes, Maven dynamically retrieves Java libraries and Maven plug-ins
from local or remote repositories. Doing so promotes sharing and reuse of dependencies across
projects.

3.2. USING THE MAVEN REPOSITORY IN YOUR PROJECT
You can direct Maven to use the Red Hat JBoss Enterprise Application Platform Maven repository in
your project in one of the following ways:
Configure the Project Object Model (POM) file (pom.xml).
Modify the Maven settings file (settings.xml).
The recommended approach is to direct Maven to use the Red Hat JBoss Enterprise Application
Platform Maven repository across all projects by using the Maven global or user settings.
From version 6.1.0 onwards, Red Hat JBoss BPM Suite and Red Hat JBoss BRMS are designed to be
used in combination with Red Hat JBoss Middleware Maven Repository and Maven Central repository
as dependency sources. Ensure that both repositories are available for project builds.

3.3. MAVEN PROJECT CONFIGURATION FILE
To use Maven for building and managing your Red Hat JBoss BRMS and Red Hat JBoss BPM Suite
projects, you must configure your projects to be built with Maven. To do so, Maven provides the POM
file (pom.xml) that holds configuration details for your project.
pom.xml is an XML file that contains information about the project (such as project name, version,
description, developers, mailing list, and license), and build details (such as dependencies, location of
the source, test, target directories, repositories, and plug-ins).

24

CHAPTER 3. APACHE MAVEN

When you generate a Maven project, a pom.xml file is automatically generated. You can edit pom.xml
to add more dependencies and new repositories. Maven downloads all of the JAR files and the
dependent JAR files from the Maven repository when you compile and package your project.
Find the schema for the pom.xml file at http://maven.apache.org/maven-v4_0_0.xsd.
For more information about POM files, see Apache Maven Project POM Reference .

3.4. MAVEN SETTINGS FILE
The Maven settings file (settings.xml) is used to configure Maven execution. You can locate this file
in the following locations:
In the Maven install directory at $M2_HOME/conf/settings.xml. These settings are called
global settings.
In the user’s install directory at $USER_HOME/.m2/settings.xml. These settings are called
user settings.
A custom location specified by the system property kie.maven.settings.custom.

NOTE
The settings used is a merge of the files located in these locations.
The following is an example of a Maven settings.xml file. Note the activeByDefault tag, which
specifies the default profile. In the following example, it is a profile with a remote Maven repository.



my-profile

true



fusesource
http://repo.fusesource.com/nexus/content/groups/public/

false


true


...



...


25

Red Hat JBoss BPM Suite 6.4 Development Guide

3.5. DEPENDENCY MANAGEMENT
In order to use the correct Maven dependencies in your Red Hat JBoss BPM Suite project, you must
add relevant Bill Of Materials (BOM) files to the project’s pom.xml file. Adding the BOM files ensures
that the correct versions of transitive dependencies from the provided Maven repositories are included
in the project.
See the Supported Component Versions chapter of Red Hat JBoss BPM Suite Installation Guideto view
the supported BOM components.
Declare the BOM in pom.xml. For example:
Example 3.1. BOM for Red Hat JBoss BPM Suite 6.4.0



org.jboss.bom.brms
jboss-brms-bpmsuite-platform-bom
6.4.2.GA-redhat-2
pom
import







To check the current BOM version, see the Supported Component Versions chapter of Red Hat JBoss
BPM Suite Installation Guide.
Furthermore, declare dependencies needed for your project in the dependencies tag.
For a basic Red Hat JBoss BPM Suite project, declare the following dependencies:

Embedded jBPM Engine Dependencies

org.jbpm
jbpm-kie-services



org.jbpm
jbpm-workitems



ch.qos.logback

26

CHAPTER 3. APACHE MAVEN

logback-classic
${logback.version}


org.kie
kie-api

For a Red Hat JBoss BPM Suite project that uses CDI, declare the following dependencies:

CDI-Enabled jBPM Engine dependencies

org.kie
kie-api


org.jbpm
jbpm-kie-services


org.jbpm
jbpm-services-cdi

For a basic Red Hat JBoss BRMS project, declare the following dependencies:

Embedded Drools Engine Dependencies

org.drools
drools-compiler



org.drools
drools-persistence-jpa



org.drools
drools-decisiontables


org.drools
drools-templates



27

Red Hat JBoss BPM Suite 6.4 Development Guide

org.drools
drools-scorecards



org.kie
kie-ci



org.kie
kie-ci-osgi


org.kie
kie-api

Do not use both kie-ci and kie-ci-osgi in one pom.xml file.
To use the Intelligent Process Server, declare the following dependencies:

Client Application Intelligent Process Server Dependencies

org.kie.server
kie-server-client


org.kie.server
kie-server-api



org.drools
drools-core


org.kie
kie-api

To create a remote client for Red Hat JBoss BPM Suite or Red Hat JBoss BRMS, declare the
following dependencies:

Client Dependencies


28

CHAPTER 3. APACHE MAVEN

org.kie.remote
kie-remote-client

To use assets in KJAR packaging, the preferred way is to include kie-maven-plugin:

Kie Maven Plugin

kjar



org.kie
kie-maven-plugin
6.5.0.Final-redhat-7
true



For testing purposes, declare the following dependencies:

Testing Dependencies


junit
junit
${junit.version}
test



org.jbpm
jbpm-shared-services
btm
test



ch.qos.logback
logback-classic
${logback.version}
test



org.hibernate

29

Red Hat JBoss BPM Suite 6.4 Development Guide

hibernate-entitymanager
${hibernate.version}
test


org.hibernate
hibernate-core
${hibernate.core.version}
test


com.h2database
h2
${h2.version}
test


org.codehaus.btm
btm
${btm.version}
test


org.kie
kie-api

Alternatively, for extensive testing of Red Hat JBoss BPM Suite, include the jbpm-test
dependency. Note that jbpm-test includes some of the previous dependencies, for example
the junit dependency, dependencies required for persistence tests, and others.

Declaring jbpm-test Dependency

org.jbpm
jbpm-test

To include the jbpm-test dependency as part of your KJAR, set the dependency scope to
provided. Doing so ensures that the dependency is available at runtime, thereby avoiding
unresolved dependency errors. The recommended practice is to use only business resources
in your KJAR and not include jbpm-test dependency in it. It is a best practice to keep the
test suite for the KJAR in a separate project.

NOTE
If you are deploying Red Hat JBoss BRMS or Red Hat JBoss BPM Suite on Red
Hat JBoss EAP 7, you must make changes to the project BOM files. For more
information on the BOM changes, see the Red Hat JBoss EAP Migration chapter
in the Red Hat JBoss BPM Suite Migration Guide.
For more information on BOM usage in Red Hat JBoss EAP 7, see the Using
Maven with JBoss EAP chapter in the Red Hat JBoss EAP Development Guide.

30

CHAPTER 3. APACHE MAVEN

3.6. INTEGRATED MAVEN DEPENDENCIES
Throughout the Red Hat JBoss BRMS and BPM Suite documentation, various code samples are
presented with KIE API for the 6.1.x releases. These code samples will require Maven dependencies in
the various pom.xml file and should be included like the following example:

commons-logging
commons-logging
1.1.1-redhat-2
compile

All the Red Hat JBoss related product dependencies can be found at the following location: Red Hat
Maven Repository.

3.7. UPLOADING ARTIFACTS TO MAVEN REPOSITORY
There may be scenarios when your project may fail to fetch dependencies from a remote repository
configured in its pom.xml. In such cases, you can programmatically upload dependencies to Red Hat
JBoss BPM Suite by uploading artifacts to the embedded maven repository through Business Central.
Red Hat JBoss BPM Suite uses a servlet for the maven repository interactions. This servlet processes a
GET request to download an artifact and a POST request to upload one. You can leverage the servlet’s
POST request to upload an artifact to the repository using REST. To do this, implement the Http basic
authentication and issue an HTTP POST request in the following format:
PROTOCOL://HOST_NAME:PORT/CONTEXT_ROOT/maven2/[GROUP_ID replacing '.' with
'/']/ARTIFACT_ID/VERSION/ARTIFACT_ID-VERSION.jar
For example, to upload the org.slf4j:slf4j-api:1.7.7.jar, where ARTIFACT_ID is slf4japi, GROUP_ID is slf4j, and VERSION is 1.7.7, the URI must be:
http://localhost:8080/business-central/maven2/org/slf4j/slf4japi/1.7.7/slf4j-api-1.7.7.jar
The following example illustrates uploading a JAR located at /tmp directory as a user bpmsAdmin with
the password abcd1234!, to an instance of Red Hat JBoss BPM Suite running locally:
package com.rhc.example;
import java.io.File;
import java.io.IOException;
import
import
import
import
import
import
import
import
import
import
import

org.apache.http.HttpEntity;
org.apache.http.HttpHost;
org.apache.http.auth.AuthScope;
org.apache.http.auth.UsernamePasswordCredentials;
org.apache.http.client.AuthCache;
org.apache.http.client.ClientProtocolException;
org.apache.http.client.CredentialsProvider;
org.apache.http.client.methods.CloseableHttpResponse;
org.apache.http.client.methods.HttpPost;
org.apache.http.client.protocol.HttpClientContext;
org.apache.http.entity.mime.HttpMultipartMode;

31

Red Hat JBoss BPM Suite 6.4 Development Guide

import
import
import
import
import
import
import
import
import

org.apache.http.entity.mime.MultipartEntityBuilder;
org.apache.http.entity.mime.content.FileBody;
org.apache.http.impl.auth.BasicScheme;
org.apache.http.impl.client.BasicAuthCache;
org.apache.http.impl.client.BasicCredentialsProvider;
org.apache.http.impl.client.CloseableHttpClient;
org.apache.http.impl.client.HttpClients;
org.slf4j.Logger;
org.slf4j.LoggerFactory;

public class UploadMavenArtifact {
private static final Logger LOG =
LoggerFactory.getLogger(UploadMavenArtifact.class);
public static void main(String[] args) {
// Maven coordinates:
String groupId = "com.rhc.example";
String artifactId = "bpms-upload-jar";
String version = "1.0.0-SNAPSHOT";
// File to upload:
File file = new File("/tmp/" + artifactId + "-" + version + ".jar");
// Server properties:
String protocol = "http";
String hostname = "localhost";
Integer port = 8080;
String username = "bpmsAdmin";
String password = "abcd1234!";
// Create the HttpEntity (body of our POST):
FileBody fileBody = new FileBody(file);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("upfile", fileBody);
HttpEntity entity = builder.build();
// Calculate the endpoint from the Maven coordinates:
String resource = "/business-central/maven2/" + groupId.replace('.',
'/') + "/" + artifactId +"/" + version + "/" + artifactId + "-" + version
+ ".jar";
LOG.info("POST " + hostname + ":" + port + resource);
// Set up HttpClient to use Basic pre-emptive authentication with the
provided credentials:
HttpHost target = new HttpHost(hostname, port, protocol);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
new UsernamePasswordCredentials(username,password));
CloseableHttpClient httpclient =
HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
HttpPost httpPost = new HttpPost(resource);
httpPost.setEntity(entity);

32

CHAPTER 3. APACHE MAVEN

AuthCache authCache = new BasicAuthCache();
BasicScheme basicAuth = new BasicScheme();
authCache.put(target, basicAuth);
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
try {
// Perform the HTTP POST:
CloseableHttpResponse response = httpclient.execute(target,
httpPost, localContext);
LOG.info(response.toString());
// Now check your artifact repository!
} catch (ClientProtocolException e) {
LOG.error("Protocol Error", e);
throw new RuntimeException(e);
} catch (IOException e) {
LOG.error("IOException while getting response", e);
throw new RuntimeException(e);
}
}
}

Alternative Maven Approach

An alternative Maven approach is to configure your projects pom.xml by adding the repository as
shown below:


guvnor-m2-repo
maven repo
http://localhost:8080/business-central/maven2/
default


Once you specify the repository information in the pom.xml, add the corresponding configuration in
settings.xml as shown below:

guvnor-m2-repo
bpmsAdmin
abcd1234!

httpclient


true




Now when you run the mvn deploy command, the JAR file gets uploaded.

33

Red Hat JBoss BPM Suite 6.4 Development Guide

3.8. DEPLOYING RED HAT JBOSS BPM SUITE ARTIFACTS TO RED HAT
JBOSS FUSE
Red Hat JBoss Fuse is an open source Enterprise Service Bus (ESB) with an elastic footprint and is
based on Apache Karaf. The 6.4 version of Red Hat JBoss BPM Suite supports deployment of runtime
artifacts to Fuse.
With the 6.1 release, Red Hat JBoss BPM Suite runtime components (in the form of JARs) are OSGi
enabled. The runtime engines JARs MANIFEST.MF files describe their dependencies, amongst other
things. You can plug these JARs directly into an OSGi environment, like Fuse.



POM PARSER LIMITATIONS IN OSGI ENVIRONMENTS
Red Hat JBoss BPM Suite uses a scanner to enable continuous integration,
resolution, and fetching of artifacts from remote Maven repositories. This scanner,
called KIE-CI, uses a native Maven parser called Plexus to parse Maven POMs.
However, this parser is not OSGi compatible and fails to instantiate in an OSGi
environment. KIE-CI automatically switches to a simpler POM parser called
MinimalPomParser.
The MinimalPomParser is a very simple POM parser implementation provided
by Drools and is limited in what it can parse. It ignores some POM file parts, such
as the parent POM of a KJAR. This means that users must not rely on those POM
features (such as dependencies declared in the parent POM in their KJARs) when
using KIE-CI in an OSGi environment.

Separating Assets and Code

One of the main advantage of deploying Red Hat JBoss BPM Suite artifacts on Red Hat JBoss Fuse is
that each bundle is isolated, running in its own classloader. This allows you to separate the logic (code)
from the assets. Business users can produce and change the rules and processes (assets) and package
them in their own bundle, keeping them separate from the project bundle (code), created by the
developer team. Assets can be updated without needing to change the project code.

34

CHAPTER 4. INSTALL AND SET UP RED HAT JBOSS DEVELOPER STUDIO

CHAPTER 4. INSTALL AND SET UP RED HAT JBOSS
DEVELOPER STUDIO
Red Hat JBoss Developer Studio is the JBoss Integrated Development Environment (IDE) based on
Eclipse. Get the latest Red Hat JBoss Developer Studio from the Red Hat Customer Portal . Red Hat
JBoss Developer Studio provides plug-ins with tools and interfaces for Red Hat JBoss BRMS and Red
Hat JBoss BPM Suite. These plugins are based on the community version of these products. So, the
Red Hat JBoss BRMS plug-in is called the Drools plug-in and the Red Hat JBoss BPM Suite plug-in is
called the jBPM plug-in.
See the Red Hat JBoss Developer Studiodocumentation for installation and setup instructions.



WARNING
Due to an issue in the way multi-byte rule names are handled, you must ensure
that the instance of Red Hat JBoss Developer Studio is started with the file
encoding set to UTF-8. You can do this by editing the
$JBDS_HOME/studio/jbdevstudio.ini file and adding the following property:
"-Dfile.encoding=UTF-8".

4.1. INSTALLING RED HAT JBOSS DEVELOPER STUDIO PLUG-INS
Get the latest Red Hat JBoss Developer Studio from the Red Hat Customer Portal . The Red Hat JBoss
BRMS and Red Hat JBoss BPM Suite plug-ins for Red Hat JBoss Developer Studio are available using
the update site.
Installing Red Hat JBoss BRMS and Red Hat JBoss BPM Suite Plug-ins in Red Hat JBoss Developer
Studio
1. Start Red Hat JBoss Developer Studio.
2. Click Help → Install New Software .
3. Click Add to enter the Add Repository menu.
4. Provide a name next to the Name field and add the following URL in the Location field:
https://devstudio.jboss.com/10.0/stable/updates/integration-stack/.
5. Click OK.
6. Select the JBoss Business Process and Rule Development feature from the available options,
click Next and then Next again.
7. Read the license and accept it by selecting the appropriate radio button, and click Finish.
8. Restart Red Hat JBoss Developer Studio after the installation process finishes.

4.2. CONFIGURING RED HAT JBOSS BRMS/BPM SUITE SERVER

35

Red Hat JBoss BPM Suite 6.4 Development Guide

Red Hat JBoss Developer Studio can be configured to run the Red Hat JBoss BRMS and Red Hat JBoss
BPM Suite server.
Configuring Red Hat JBoss BRMS and Red Hat JBoss BPM Suite Server
1. Open the Drools view: click Window → Open Perspective → Other, select Drools and click OK.
To open the Red Hat JBoss BPM Suite view, go to Window → Open Perspective → Other,
select jBPM and click OK.
2. Click Window → Show View → Other…​ and select Server → Servers to add the server view.
3. Right click the Servers panel and select New → Server to open the server menu.
4. Click JBoss Enterprise Middleware → JBoss Enterprise Application Platform 6.1+ and click
Next to define the server.
5. Set the home directory by clicking Browse button. Navigate to the Red Hat JBoss EAP
directory which has Red Hat JBoss BRMS installed.
For configuring Red Hat JBoss BPM Suite server, select the Red Hat JBoss EAP directory
which has Red Hat JBoss BPM Suite installed.
6. Provide a name for the server in the Name field, ensure that the configuration file is set, and
click Finish.

4.3. IMPORTING PROJECTS FROM GIT REPOSITORY INTO RED HAT
JBOSS DEVELOPER STUDIO
You can configure Red Hat JBoss Developer Studio to connect to a central Git asset repository. The
repository stores rules, models, functions, and processes.
You can either clone a remote Git repository or import a local Git repository.
Cloning Remote Git Repository
1. Select the server from the Server tab and click the start icon to start your server.
2. Start the Secure Shell server, if not running already, by using the following command. The
command is Linux and Mac specific only. On these platforms, if sshd has already been started,
this command fails. In that case, you may safely ignore this step.
/sbin/service sshd start
3. In Red Hat JBoss Developer Studio , select File → Import…​ and navigate to the Git folder.
Open the Git folder to select Projects from Git and click Next.
4. Select the repository source as Clone URI and click Next.
5. Enter the details of the Git repository in the next window and click Next.
6. Select the branch you wish to import in the following window and click Next.
7. To define the local storage for this project, enter (or select) a non-empty directory, make any
configuration changes and click Next.
8. Import the project as a general project in the following window and click Next.

36

CHAPTER 4. INSTALL AND SET UP RED HAT JBOSS DEVELOPER STUDIO

9. Name the project and click Finish.
Importing Local Git Repository
1. Select your server from the Server tab and click the start icon to start the server.
2. In Red Hat JBoss Developer Studio, select File → Import…​ and navigate to the Git folder. Open
the Git folder to select Projects from Git and click Next.
3. Select the repository source as Existing local repository and click Next.
4. Select the repository that is to be configured from the list of available repositories and click
Next.
5. In the dialog window that opens, select the Import as general project radio button from the
Wizard for project import group and click Next.
6. Name the project and click Finish.

4.4. KIE NAVIGATOR
Kie Navigator enables you to browse, change, and deploy the content of your Red Hat JBoss BPM Suite
server. As a result, you can integrate Red Hat JBoss Developer Studio with Red Hat JBoss BPM Suite.
For further information about Kie Navigator, see chapter Kie Navigator of the Red Hat JBoss BPM Suite
Getting Started Guide.

37

Red Hat JBoss BPM Suite 6.4 Development Guide

PART II. ALL ABOUT RULES

38

CHAPTER 5. RULE ALGORITHMS

CHAPTER 5. RULE ALGORITHMS
5.1. PHREAK ALGORITHM
The new PHREAK algorithm is evolved from the RETE algorithm. While RETE is considered eager and
data oriented, PHREAK on the other hand follows lazy and goal oriented approach. The RETE
algorithm does a lot of work during the insert, update and delete actions in order to find partial
matches for all rules. In case of PHREAK, this partial matching of rule is delayed deliberately.
The eagerness of RETE algorithm during rule matching wastes a lot of time in case of large systems as
it does result in a rule firing eventually. PHREAK algorithm addresses this issue and therefore is able to
handle large data more efficiently.
PHREAK is derived from a number of algorithms including the following LEAPS, RETE/UL and
Collection-Oriented Match algorithms.
In addition to the enhancements listed in the Rete00 algorithm, PHREAK algorithm adds the following
set of enhancements:
Three layers of contextual memory: Node, Segment, and Rule memories.
Rule, segment, and node based linking.
Lazy (delayed) rule evaluation.
Stack-based evaluations with pause and resume.
Isolated rule evaluation.
Set-oriented propagations.

5.2. RULE EVALUATION WITH PHREAK ALGORITHM
When the rule engine starts, all the rules are unlinked. At this stage, there is no rule evaluation. The
insert, update, and delete actions are queued before entering the beta network. The rule engine uses a
simple heuristic—​based on the rule most likely to result in firings—​to calculate and select the next rule
for evaluation. This delays the evaluation and firing of the other rules. When a rule has all the right
input values populated, it gets linked in—​a goal representing this rule is created and placed into a
priority queue, which is ordered by salience. Each queue is associated with an AgendaGroup. The
engine only evaluates rules for the active AgendaGroup by inspecting the queue and popping the goal
for the rule with the highest salience. This means the work done shifts from the insert, update, delete
phase to the fireAllRules phase. Only the rule for which the goal was created is evaluated, and
other potential rule evaluations are delayed. While individual rules are evaluated, node sharing is still
achieved through the process of segmentation.
Unlike the tuple-oriented RETE, the PHREAK propagation is collection-oriented. For the rule that is
being evaluated, the engine accesses the first node and processes all queued insert, update, and delete
actions. The results are added to a set, and the set is propagated to the child node. In the child node, all
queued insert, update, and delete actions are processed, adding the results to the same set. Once
finished, this set is propagated to the next child node and the same process repeats until it reaches the
terminal node. This creates a batch process effect, which can provide performance advantages for
certain rule constructs.
This linking and unlinking of rules happens through a layered bit mask system, based on network
segmentation. When the rule network is built, segments are created for nodes that are shared by the

39

Red Hat JBoss BPM Suite 6.4 Development Guide

same set of rules. A rule itself is made up from a path of segments. In case a rule does not share any
node with any other rule, it becomes a single segment.
A bit-mask offset is assigned to each node in the segment. Furthermore, another bit mask is assigned
to each segment in the rule’s path according to these rules:
If there is at least one input, the node’s bit is set to the on state.
If each node in a segment has its bit set to the on state, the segment’s bit is also set to the on
state.
If any node’s bit is set to the off state, the segment is also set to the off state.
If each segment in the rule’s path is set to the on state, the rule is said to be linked in, and a
goal is created to schedule the rule for evaluation.
The same bit-mask technique is used to also track dirty nodes, segments, and rules. This allows for an
already linked rule to be scheduled for evaluation if it has been considered dirty since it was last
evaluated. This ensures that no rule will ever evaluate partial matches.
As opposed to a single unit of memory in RETE, PHREAK has three levels of memory. This allows for
much more contextual understanding during the evaluation of a rule.

PHREAK and Sequential Mode

The sequential mode is supported for the PHREAK algorithm: the modify and update rule statements
are now allowed. Any rule that has not yet been evaluated will have access to data modified by the
previous rules that used modify or update. This results in a more intuitive behavior of the sequential
mode.
For example, consider the following rule:
rule "Rule1"
salience 100
when
$fact : MyFact( field1 == false )
then
System.out.println("Rule1 : " + $fact);
$fact.setField1(true);
update($fact);
end

rule "Rule2"
salience 95
when
$fact : MyFact( field1 == true )
then
System.out.println("Rule2 : " + $fact);
update($fact);
end
When you insert a MyFact with the value field1==false:
The ReteOO algorithm executes only Rule1.
The PHREAK algorithm executes both Rule1 and Rule2.

40

CHAPTER 5. RULE ALGORITHMS

For more information about the sequential mode, see Section 20.1.11.2.1, “Sequential Mode”.

5.3. RETE ALGORITHM
5.3.1. ReteOO
The Rete implementation used in BRMS is called ReteOO. It is an enhanced and optimized
implementation of the Rete algorithm specifically for object-oriented systems. The Rete Algorithm has
now been deprecated, and PHREAK is an enhancement of Rete. However, Rete can still be used by
developers. This section describes how the Rete Algorithm functions.

Rete Root Node

When using ReteOO, the root node is where all objects enter the network. From there, it immediately
goes to the ObjectTypeNode.
Figure 5.1. ReteNode

ObjectTypeNode

The ObjectTypeNode helps to reduce the workload of the rules engine. If there are several objects,
the rule engine wastes a lot of cycles trying to evaluate every node against every object. To make
things efficient, the ObjectTypeNode is used so that the engine only passes objects to the nodes that
match the object’s type. This way, if an application asserts a new Account, it does not propagate to the
nodes for the Order object.
In Red Hat JBoss BRMS, an inserted object retrieves a list of valid ObjectTypesNodes through a
lookup in a HashMap from the object’s class. If this list does not exist, it scans all the
ObjectTypeNodes to find valid matches. It then caches these matched nodes in the list. This enables
Red Hat JBoss BRMS to match against any class type that matches with an instanceof check.

AlphaNodes

AlphaNodes are used to evaluate literal conditions. When a rule has multiple literal conditions for a
single object type, they are linked together. This means that if an application asserts an Account object,
it must first satisfy the first literal condition before it can proceed to the next AlphaNode.
AlphaNodes are propagated using ObjectTypeNodes.

Hashing

Red Hat JBoss BRMS uses hashing to extend Rete by optimizing the propagation from
ObjectTypeNode to AlphaNode. Each time an AlphaNode is added to an ObjectTypeNode, it adds
the literal value as a key to the HashMap with the AlphaNode as the value. When a new instance
enters the ObjectType node, rather than propagating to each AlphaNode, it retrieves the correct
AlphaNode from the HashMap. This avoids unnecessary literal checks.
When facts enter from one side, you may do a hash lookup returning potentially valid candidates
(referred to as indexing). At any point a valid join is found, the Tuple joins with the Object (referred to
as a partial match) and then propagates to the next node.

41

Red Hat JBoss BPM Suite 6.4 Development Guide

BetaNodes

BetaNodes are used to compare two objects and their fields. The objects may be of the same or
different types.

Alpha Memory and Beta Memory

Alpha memory refers to the left input on a BetaNode. In Red Hat JBoss BRMS, this input remembers all
incoming objects.
Beta memory is the term used to refer to the right input of a BetaNode. It remembers all incoming
tuples.

Lookups with BetaNodes

When facts enter from one side, you can do a hash lookup returning potentially valid candidates
(referred to as indexing). If a valid join is found, the Tuple joins with the Object (referred to as a partial
match) and then propagates to the next node.

LeftInputNodeAdapters

A LeftInputNodeAdapter takes an Object as an input and propagates a single Object Tuple.

Terminal Nodes

Terminal nodes are used to indicate when a single rule matches all its conditions (that is, the rule has a
full match). A rule with an OR conditional disjunctive connective results in a sub-rule generation for
each possible logical branch. Because of this, one rule can have multiple terminal nodes.

Node Sharing

Node sharing is used to prevent redundancy. As many rules repeat the same patterns, node sharing
allows users to collapse those patterns so that the patterns need not be reevaluated for every single
instance.
The following rules share the first pattern but not the last:
rule
when
Cheese($cheddar : name == "cheddar")
$person: Person(favouriteCheese == $cheddar)
then
System.out.println($person.getName() + "likes cheddar");
end
rule
when
Cheese($cheddar : name == "cheddar")
$person : Person(favouriteCheese != $cheddar)
then
System.out.println($person.getName() + " does not like cheddar");
end
The Rete network displayed below denotes that the alpha node is shared but the beta nodes are not.
Each beta node has its own TerminalNode.

42

CHAPTER 5. RULE ALGORITHMS

Figure 5.2. Node Sharing

43

Red Hat JBoss BPM Suite 6.4 Development Guide

5.4. SWITCHING BETWEEN PHREAK AND RETEOO
It is possible to switch between PHREAK and ReteOO either by setting system properties, or in
KieBase configuration. PHREAK is the default algorithm in both cases.
Switching to ReteOO requires the drools-reteoo-VERSION.jar file to be available on the class
path. To include the file, add the following ReteOO Maven dependency to the pom.xml file in your
project:

org.drools
drools-reteoo
DROOLS_VERSION

For the supported Maven artifact version, see the Supported Component Versions section of the Red
Hat JBoss BPM Suite Installation Guide.

NOTE
If the ReteOO Maven dependency is not specified in the pom.xml file in your project, the
BRMS engine uses PHREAK instead and issues a warning.

Switching Between PHREAK and ReteOO in System Properties

To switch between the PHREAK and ReteOO algorithms, edit the drools.ruleEngine system
property to contain one the following values:
drools.ruleEngine=phreak
drools.ruleEngine=reteoo
The default value is phreak.

Switching Between PHREAK and ReteOO in KieBaseConfiguration

When creating a KieBase, specify the rule engine algorithm in KieBaseConfiguration. See the
following example:
import
import
import
import
import
...

org.kie.api.KieBase;
org.kie.api.KieBaseConfiguration;
org.kie.api.KieServices;
org.kie.api.runtime.KieContainer;
org.kie.internal.builder.conf.RuleEngineOption;

KieServices kservices = KieServices.Factory.get();
KieBaseConfiguration kconfig =
kieServices.Factory.get().newKieBaseConfiguration();
// You can either specify PHREAK (default):
kconfig.setOption(RuleEngineOption.PHREAK);
// or legacy ReteOO:
kconfig.setOption(RuleEngineOption.RETEOO);

44

CHAPTER 5. RULE ALGORITHMS

// ... and then create a KieBase for the selected algorithm
// (getKieClasspathContainer() is just an example):
KieContainer container = kservices.getKieClasspathContainer();
KieBase kbase = container.newKieBase(kieBaseName, kconfig);
For a list of Maven dependencies, see example Embedded jBPM Engine Dependencies . If you use Red
Hat JBoss BRMS, see example Embedded Drools Engine Dependencies .
Additionally, if you want to switch to ReteOO, use the drools-reteoo dependency:

org.drools
drools-reteoo
6.5.0.Final-redhat-2

For the current Maven artifact version, see chapter Supported Component Versions of the Red Hat
JBoss BPM Suite Installation Guide.

NOTE
Switching to ReteOO requires drools-reteoo-(version).jar to exist on the
classpath. If not present, the BRMS Engine reverts back to PHREAK and issues a
warning. This applies for switching with KieBaseConfiguration and system
properties.

45

Red Hat JBoss BPM Suite 6.4 Development Guide

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS
To create business rules, an appropriate fact model on which the business rules operate must be
present. A fact is an instance of an application object represented as POJO. Rules that contain the
business logic can then be authored by using either the Business Central web user interface or Red Hat
JBoss Developer Studio.
The structure of a rule is as follows:
rule "NAME"
when
RULE CONDITIONS
then
RULE CONSEQUENCES
end
Conditions inside the when clause of a rule query for fact combinations that match the criteria. If such a
fact combination is found, consequences specified in the then clause are executed. These actions can
assert a fact, retract a fact, or update a fact within the rule engine. As a result, other rules can be fired
as well.

Rules Processing Steps
1. BRMS parses all .drl rule files into the knowledge base.
2. Each fact is asserted into the working memory. As the facts are being asserted, BRMS uses the
PHREAK or ReteOO algorithm to infer how the facts relate to the rules. After that, the working
memory contains copies of the parsed rules and a reference to the facts.
3. The fireAllRules() method is called. All rules and facts are evaluated by the rule engine
and rule-facts pairs are created, based on which rules match against which set of facts.
4. All the rule-facts combinations are queued within a data construct called an agenda.
5. Finally, activations are processed one by one from the agenda, calling the rule consequences
on the facts. Note that executing an activation can modify the contents of the agenda before
the next activation is performed. The PHREAK and ReteOO algorithms handle such situations
efficiently.

6.1. CREATING AND EXECUTING RULES
In this section, procedures describing how to create and execute rules using plain Java, Maven, Red Hat
JBoss Developer Studio, and Business Central in Red Hat JBoss BPM Suite are provided.

6.1.1. Creating and Executing Rules Using Plain Java
1. Create a fact model.
Create a Plain old Java object (POJO) on which a rule will operate. In this example, a
Person.java file in a directory my-project is created. The Person class contains getter
and setter methods to set and retrieve the first name, last name, hourly rate, and the wage of a
person:
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;

46

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

import org.kie.api.runtime.KieSession;
public class Person {
private String firstName;
private String lastName;
private Integer hourlyRate;
private Integer wage;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getHourlyRate() {
return hourlyRate;
}
public void setHourlyRate(Integer hourlyRate) {
this.hourlyRate = hourlyRate;
}
public Integer getWage(){
return wage;
}
public void setWage(Integer wage){
this.wage = wage;
}
}
2. Create a rule.
Create a rule file in the .drl format under the my-project directory. The following
Person.drl rule calculates the wage and hourly rate values and displays a message based on
the result afterwards.
dialect "java"
rule "Wage"
when
Person(hourlyRate * wage > 100)
Person(name : firstName, surname : lastName)
then
System.out.println("Hello" + " " + name + " " + surname + "!");
System.out.println("You are rich!");
end

47

Red Hat JBoss BPM Suite 6.4 Development Guide

3. Create a main class.
Create a main class and save it to the same directory as the POJO created earlier. The main
class will load the knowledge base and fire rules. In the following example, a main class
DroolsTest.java is created.
In the main class:
a. Add the following import statements to import KIE services, a KIE container, and a KIE
session:
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
b. Load the knowledge base, insert facts, and fire the rule from the main() method which
passes the fact model to the rule:
public class DroolsTest {
public static final void main(String[] args) {
try {
// Load the knowledge base:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession();
// Go!
Person p = new Person();
p.setWage(12);
p.setFirstName("Tom");
p.setLastName("Summers");
p.setHourlyRate(10);
kSession.insert(p);
kSession.fireAllRules();
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
4. Download the Red Hat JBoss BRMS 6.4 Core Engine ZIP file from the Red Hat Customer
Portal and extract it under my-project/BRMS-engine-jars/.
5. In the my-project/META-INF directory, create a kmodule.xml metadata file with the
following content:



6. Build the example.

48

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

To compile and build your Java files, navigate to the my-project directory on the command
line and run the following command:
javac -classpath "./BRMS-engine-jars/*:." DroolsTest.java
7. Run the example.
If there are no compilation errors, run the following command to execute the rule:
java -classpath "./BRMS-engine-jars/*:." DroolsTest
The expected output looks similar to the following:
Hello Tom Summers!
You are rich!

6.1.2. Creating and Executing Rules Using Maven
1. Create a basic Maven archetype.
Navigate to a directory where you want to create a Maven archetype and run the following
command:
mvn archetype:generate -DgroupId=com.sample.app -DartifactId=my-app
-DarchetypeArtifactId=maven-archetype-quickstart DinteractiveMode=false
This creates a directory my-app with the following structure:
my-app
|-- pom.xml
`-- src
|-- main
|
`-- java
|
`-- com
|
`-- mycompany
|
`-- app
|
`-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java
The my-app directory contains:
A src/main directory for storing the application’s sources.
A src/test directory for storing the test sources.
A pom.xml file with the project’s configuration.
2. Create a fact model.
A fact model is a POJO, based on which a rule will operate. Create a Person.java file under

49

Red Hat JBoss BPM Suite 6.4 Development Guide

the my-app/src/main/java/com/mycompany/app directory. The Person class contains
getter and setter methods to set and retrieve the first name, last name, hourly rate, and the
wage of a person.
package com.mycompany.app;
public class Person {
private
private
private
private

String firstName;
String lastName;
Integer hourlyRate;
Integer wage;

public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getHourlyRate() {
return hourlyRate;
}
public void setHourlyRate(Integer hourlyRate) {
this.hourlyRate = hourlyRate;
}
public Integer getWage(){
return wage;
}
public void setWage(Integer wage){
this.wage = wage;
}
}
3. Create a rule.
Create a rule file in the .drl format under the my-app/src/main/resources/rules
directory. See the following example with a simple rule Person.drl which imports the
Person class:
package com.mycompany.app;
import com.mycompany.app.Person;
dialect "java"

50

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

rule "Wage"
when
Person(hourlyRate * wage > 100)
Person(name : firstName, surname : lastName)
then
System.out.println("Hello " + name + " " + surname + "!");
System.out.println("You are rich!");
end
The rule above calculates the wage and hourly rate values and displays a message based on
the result afterwards.
4. In the my-app/src/main/resources/META-INF directory, create a metadata file
kmodule.xml with the following content:



5. Set project dependencies.
Specify the libraries your application requires in the my-app/pom.xml configuration file.
Provide the Red Hat JBoss BRMS dependencies as well as the group ID, artifact ID, and version
(GAV) of your application as shown below:


4.0.0
com.mycompany.app
my-app
1.0.0


jboss-ga-repository
http://maven.repository.redhat.com/ga/




org.drools
drools-compiler
VERSION


org.kie
kie-api
VERSION


junit
junit
4.11

51

Red Hat JBoss BPM Suite 6.4 Development Guide

test



For the supported Maven artifact version, see section Supported Component Versions of the
Red Hat JBoss BPM Suite Installation Guide.
6. Test the example.
Use the testApp method in myapp/src/test/java/com/mycompany/app/AppTest.java to test the rule. The
AppTest.java file is created by Maven by default.
In the AppTest.java file:
a. Add the following import statements to import KIE services, a KIE container, and a KIE
session:
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
b. Load the knowledge base, insert facts, and fire the rule from the testApp() method which
passes the fact model to the rule:
public void testApp() {
// Load the knowledge base:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession();
// Set up the fact model:
Person p = new Person();
p.setWage(12);
p.setFirstName("Tom");
p.setLastName("Summers");
p.setHourlyRate(10);
// Insert the person into the session:
kSession.insert(p);
// Fire all rules:
kSession.fireAllRules();
}
7. Build the example.
On the command line, navigate to the my-app directory and run the following command:
mvn clean install
Note that executing this command for the first time may take a while.
The expected output looks similar to the following:

52

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

Hello Tom Summers!
You are rich!
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:
1.194 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
...
[INFO]
---[INFO]
[INFO]
---[INFO]
...
[INFO]
----

---------------------------------------------------------BUILD SUCCESS
---------------------------------------------------------Total time: 6.393 s
----------------------------------------------------------

6.1.3. Creating and Executing Rules Using Red Hat JBoss Developer Studio
NOTE
Make sure you have Red Hat JBoss Developer Studio properly set before proceeding
further. See chapter Red Hat JBoss Developer Studio of Red Hat JBoss BPM Suite
Installation Guide for more information.
1. Create a BRMS project.
To create a BRMS project in Red Hat JBoss Developer Studio:
a. Start Red Hat JBoss Developer Studio and click File → New → Project.
b. In the New Project dialog window that opens, select Drools → Drools Project and click
Next.
c. Click on the second icon to create a project and populate it with some example files to help
you get started quickly. Click Next.
d. Enter a name of the project a select the Maven radio button as the project building option.
Specify the GAV values which form the project’s fully qualified name, for example:
Group ID: com.mycompany.app
Artifact ID : my-app
Version: 1.0.0
e. Click Finish.
This configuration sets up a basic project structure, class path, and sample rules. The project
structure is as follows:
My-Project

53

Red Hat JBoss BPM Suite 6.4 Development Guide

`-- src/main/java
| `-- com.sample
|
`-- DecisionTable.java
|
`-- DroolsTest.java
|
`-- ProcessTest.java
|
`-- src/main/resources
| `-- dtables
|
`-- Sample.xls
| `-- process
|
`-- sample.bpmn
| `-- rules
|
`-- Sample.drl
| `-- META-INF
|
`-- JRE System Library
|
`-- Maven Dependencies
|
`-- Drools Library
|
`-- src
|
`-- target
|
`-- pom.xml
Notice the following:
A Sample.drl rule file in the src/main/resources directory, containing an example
Hello World and GoodBye rules.
A DroolsTest.java file under the src/main/java directory in the com.sample
package. The DroolsTest class can be used to execute rules.
The Drools Library directory which acts as a custom class path containing JAR files
necessary for execution.
2. Create a fact model.
The DroolsTest.java file contains a sample POJO Message with getter and setter
methods. You can edit this class or create a different POJO. In this example, a class Person
containing methods to set and retrieve the first name, last name, hourly rate, and wage of a
person is used.
public static class Person {
private
private
private
private

String firstName;
String lastName;
Integer hourlyRate;
Integer wage;

public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {

54

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Integer getHourlyRate() {
return hourlyRate;
}
public void setHourlyRate(Integer hourlyRate) {
this.hourlyRate = hourlyRate;
}
public Integer getWage(){
return wage;
}
public void setWage(Integer wage){
this.wage = wage;
}
}
3. Update the main() method.
The DroolsTest.java file contains a main() method that loads the knowledge base, inserts
facts, and fires rules. Update the method to pass the object Person to a rule:
public static final void main(String[] args) {
try {
// Load the knowledge base:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksessionrules");
// Go!
Person p = new Person();
p.setWage(12);
p.setFirstName("Tom");
p.setLastName("Summers");
p.setHourlyRate(10);
kSession.insert(p);
kSession.fireAllRules();
}
catch (Throwable t) {
t.printStackTrace();
}
}

55

Red Hat JBoss BPM Suite 6.4 Development Guide

To load the knowledge base, get a KieServices instance and a class-path-based
KieContainer and build the KieSession with the KieContainer. In the example above, a
session ksession-rules matching the one defined in kmodule.xml file is passed.
4. Create a rule.
The rule file Sample.drl contains an example of two rules. Edit this file or create a new one.
In your rule file:
a. Specify the package name:
package com.sample
b. Import facts:
import com.sample.DroolsTest.Person;
c. Write the rule:
dialect "java"
rule "Wage"
when
Person(hourlyRate * wage > 100)
Person(name : firstName, surname : lastName)
then
System.out.println("Hello" + " " + name + " " + surname +
"!");
System.out.println("You are rich!");
end
5. Test the rule.
Right-click the DroolsTest.java file and select Run As → Java Application.
The expected output looks similar to the following:
Hello Tom Summers!
You are rich!

6.1.4. Creating and Executing Rules Using Business Central
NOTE
Make sure you have Red Hat JBoss BPM Suite successfully installed before proceeding
further.
1. Start the server and log in to Business Central. For more information how to do so, see
sections Starting Server and Logging into Business Central of Red Hat JBoss BPM Suite
Installation Guide.
2. Create a repository structure and a project.
a. In Business Central, click Authoring → Administration.

56

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

b. Click Organizational Units → Manage Organizational Units.
c. In the displayed Organizational Unit Manager , click Add.
d. In the Add New Organizational Unit dialog window, define the unit properties. For
example:
Name: EmployeeWage
Owner: Employee
e. Click Ok.
f. Click Repositories → New repository .
g. In the New Repository dialog window, define the repository properties. For example:
Repository Name: EmployeeRepo
In Organizational Unit : EmployeeWage
h. Click Finish.
i. In the main menu, click Authoring → Project Authoring.
j. In Project Explorer, navigate to the EmployeeWage organizational unit and the
EmployeeRepo repository.
k. Click New Item → Project.
l. In the New Project dialog window, enter a name of the project, for example MyProject,
and specify project’s Maven properties. For example:
Group ID: org.bpms
Artifact ID : MyProject
Version: 1.0.0
m. Click Finish.
3. Create a fact model.
a. Click New Item → Data Object.
b. In the Create new Data Object dialog window, enter the object’s name and specify a
package. For example:
Data Object: Person
Package: org.bpms.myproject
c. Click Ok.
d. In the Editor than opens, click Add field and create four fields with the following values by
clicking Create and continue:
Id: firstName, Type: String

57

Red Hat JBoss BPM Suite 6.4 Development Guide

Id: lastName, Type: String
Id: hourlyRate, Type: Integer
Id: wage, Type: Integer
e. Save the project.
4. Create a rule.
a. Click New Item → DRL file.
b. In the Create new DRL file dialog window, enter a name of the rule and specify a package.
For example:
DRL file: MyRule
Package: org.bpms.myproject
c. Click Ok.
d. Paste the definition of a rule shown below into the DRL Editor or create your own rule.
package org.bpms.myproject;
rule "MyRule"
ruleflow-group "MyProjectGroup"
when
Person(hourlyRate * wage > 100)
Person(name : firstName, surname : lastName)
then
System.out.println("Hello" + " " + name + " " + surname +
"!");
System.out.println("You are rich!");
end
e. Click Save.
5. Create a business process with a business rule task.
a. Click New Item → Business Process.
b. In the Create new Business Process dialog window, enter a name of the business process
and specify a package. For example:
Business Process: MyProcess
Package: org.bpms.myproject
c. Click Ok. The Business Process Editor opens with a Start Event element on the canvas.
d. Expand the Object Library palette on the left and drag and drop a Business Rule task
(Tasks → Business Rule) on the canvas.
e. Click on an empty space on the canvas and open the Properties panel on the right. Click
on the Value text field of the Variable Definitions property. Click on the arrow that
appears on the right to open the Editor for Variable Definitions dialog window.

58

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

f. Click Add Variable and define the following variable:
Name: person
Defined Types: Person [org.bpms.myproject]
g. Click Ok.
h. Click on the Business Rule task on the canvas and in the Properties panel on the right, set
the Name of the task, for example My_Rule.
i. Click on the Value text field of the Ruleflow Group property. Click on the arrow that
appears on the right to open the Editor for RuleFlow Groups dialog window. Select
MyProjectGroup and click Save.
j. Click on the Value text field of the Assignments property. Click on the arrow that appears
on the right to open the My_Rule Data I/O dialog window and click Add next to the Data
Inputs and Assignments option to add the following:
Name: Person
Data Type : Person [org.bpms.myproject]
Source: person
k. Click Save.
You have now successfully created an object that maps to the variables you set before in
your fact model. Your business process passes this object as an input to the rule.
l. Add an End Event and connect all events on the canvas to complete the process.
m. Click

and select Generate all Forms .

n. Save the process.
6. Build and deploy the rule.
a. Click Open Project Editor on the left, change the version of the project and click Build →
Build & Deploy.
A notification appears in the upper part of the screen informing you that the project has
been built successfully.
b. Click Process Management → Process Definitions.
c. Click Start next to the newly built process.
d. In the opened MyProcess dialog window, provide the following values of the variables
defined in your fact model and click Submit:
firstName: Tom
lastName: Summers
hourlyRate: 12
wage: 10

59

Red Hat JBoss BPM Suite 6.4 Development Guide

As these values satisfy the rule condition, the expected output looks similar to the
following:
16:19:58,479 INFO
[org.jbpm.kie.services.impl.store.DeploymentSynchronizer] (http/127.0.0.1:8080-1) Deployment unit org.bpms:MyProject:1.0 stored
successfully
16:26:56,119 INFO [stdout] (http-/127.0.0.1:8080-5) Hello Tom
Summers!
16:26:56,119 INFO [stdout] (http-/127.0.0.1:8080-5) You are
rich!

6.2. EXECUTION OF RULES
6.2.1. Agenda
The Agenda is a Rete feature. During actions on the WorkingMemory, rules may become fully matched
and eligible for execution. A single Working Memory Action can result in multiple eligible rules. When a
rule is fully matched an Activation is created, referencing the rule and the matched facts, and placed
onto the Agenda. The Agenda controls the execution order of these Activations using a Conflict
Resolution strategy.

6.2.2. Agenda Processing
The engine cycles repeatedly through two phases:
1. Working Memory Actions. This is where most of the work takes place, either in the
Consequence (the RHS itself) or the main Java application process. Once the Consequence has
finished or the main Java application process calls fireAllRules() the engine switches to
the Agenda Evaluation phase.
2. Agenda Evaluation. This attempts to select a rule to fire. If no rule is found it exits, otherwise it
fires the found rule, switching the phase back to Working Memory Actions.
The process repeats until the agenda is clear, in which case control returns to the calling application.
When Working Memory Actions are taking place, no rules are being fired.

6.2.3. Conflict Resolution
Conflict resolution is required when there are multiple rules on the agenda. As firing a rule may have
side effects on the working memory, the rule engine needs to know in what order the rules should fire
(for instance, firing ruleA may cause ruleB to be removed from the agenda).

6.2.4. AgendaGroup
Agenda groups are a way to partition rules on the agenda. At any one time, only one group has "focus"
which means that activations for rules in that group only will take effect. You can also have rules with
"auto focus" which means that the focus is taken for its agenda group when that rule’s conditions are
true.
Agenda groups are known as "modules" in CLIPS terminology. Agenda groups provide a way to create
a "flow" between grouped rules. You can switch the group which has focus either from within the rule
engine, or via the API. If your rules have a clear need for multiple "phases" or "sequences" of
processing, consider using agenda-groups for this purpose.

60

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

6.2.5. setFocus()
Each time setFocus() is called it pushes the specified Agenda Group onto a stack. When the focus
group is empty it is popped from the stack and the focus group that is now on top evaluates. An
Agenda Group can appear in multiple locations on the stack. The default Agenda Group is "MAIN", with
all rules which do not specify an Agenda Group being in this group. It is also always the first group on
the stack, given focus initially, by default.
The setFocus() method call looks like follows:
ksession.getAgenda().getAgendaGroup("Group A").setFocus();

6.2.6. ActivationGroup
An activation group is a set of rules bound together by the same activation-group rule attribute. In
this group only one rule can fire, and after that rule has fired all the other rules are cancelled from the
agenda. The clear() method can be called at any time, which cancels all of the activations before one
has had a chance to fire.
An activation group looks like follows:
ksession.getAgenda().getActivationGroup("Group B").clear();

6.3. INFERENCE
6.3.1. The Inference Engine
The inference engine is the part of the Red Hat JBoss BRMS engine which matches production facts and
data to rules. It is often called the brain of a Production Rules System as it is able to scale to a large
number of rules and facts. It makes inferences based on its existing knowledge and performs the
actions based on what it infers from the information.
The rules are stored in the production memory and the facts that the inference engine matches
against, are stored in the working memory. Facts are asserted into the working memory where they
may get modified or retracted. A system with a large number of rules and facts may result in many
rules being true for the same fact assertion. Such conflicting rules are managed using a conflict
resolution strategy. This strategy determines the order of execution of the rules by assigning a priority
level to each rule.
Inferences can be forward chaining or backward chaining. In a forward chaining inference mechanism,
when some data gets inserted into the working memory, the related rules are triggered and if the data
satisfies the rule conditions, corresponding actions are taken. These actions may insert new data into
the working memory and therefore trigger more rules and so on. Thus, the forward chaining inference
is data driven. On the contrary, the backward chaining inference is goal driven. In this case, the system
looks for a particular goal, which the engine tries to satisfy. If it cannot do so it searches for sub-goals,
that is, conclusions that will complete part of the current goal. It continues this process until either the
initial conclusion is satisfied or there are no more unsatisfied sub-goals. Correct use of inference can
create agile and less error prone business rules, which are easier to maintain.

6.3.2. Inference Example

61

Red Hat JBoss BPM Suite 6.4 Development Guide

The following example illustrates how an inference is made about whether a person is eligible to have a
bus pass based on the rule conditions. Here is a rule that provides the age policy for a person to hold a
bus pass:
rule "Infer Adult"
when
$p : Person(age >= 18)
then
insert(new IsAdult($p))
end
Based on this rule, a rule engine infers whether a person is an adult or a child and act on it. Every
person who is 18 years or above will have an instance of IsAdult inserted for them in the working
memory. This inferred relation of age and bus pass can be inferred in any rule, such as:
$p : Person()
IsAdult(person == $p)

6.4. TRUTH MAINTENANCE
The inference engine is responsible for logical decisions on assertions and retractions of facts. After
regular insertions, facts are generally retracted explicitly. However, in case of logical assertions, the
facts that were asserted are automatically retracted when the conditions that asserted the facts in the
first place are no longer true. In other words, the facts are retracted when there is no single condition
that supports the logical assertion.
The inference engine uses a mechanism of truth maintenance to efficiently handle the inferred
information from rules. A Truth Maintenance System (TMS) refers to an inference engine’s ability to
enforce truthfulness when applying rules. It provides justified reasoning for each and every action
taken by the inference engine and validates the conclusions of the engine. If the inference engine
asserts data as a result of firing a rule, the engine uses the truth maintenance to justify the assertion.
A Truth Maintenance System also helps to identify inconsistencies and handle contradictions. For
example, if there are two rules to be fired, each resulting in a contradictory action, the Truth
Maintenance System enables the inference engine to decide its actions based on assumptions and
derivations of previously calculated conclusions.
The usual insertion of facts, referred to as stated insertions, are straightforward and do not need a
reasoning. However, the logical assertions need to be justified. If the inference engine tries to logically
insert an object when there is an equal stated object, it fails as it cannot justify a stated fact. If the
inference engine tries for a stated insertion of an existing equal object that is justified, then it
overrides the justified insertion, and removes the justifications.
The following flowcharts illustrate the lifecycle of stated and logical insertions:

62

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

Figure 6.1. Stated Assertion

63

Red Hat JBoss BPM Suite 6.4 Development Guide

Figure 6.2. Logical Assertion

IMPORTANT
For the Truth Maintenance System and logical assertions to work, your fact objects
(POJOs) must override the equals and hashCode methods from java.lang.Object
as per the Java standard. Two objects are equal if and only if their equals methods
return true for each other and if their hashCode methods return the same values. For
more information, see the Java API documentation.
The following example illustrates how the Truth Maintenance System helps in the inference
mechanism. The rules in the example provide information on basic policies on issuing child and adult
bus passes.
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)

64

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

then
insert(new AdultBusPass($p));
end
These rules are monolithic and provide poor separation of concerns. The truth maintenance
mechanism in an inference engine makes the system become more robust and have a clear separation
of concerns. For example, the following rule uses logical insertion of facts, which makes the fact
dependent on the truth of the when clause:
rule "Infer Child"
when
$p : Person(age < 16)
then
insertLogical(new IsChild($p))
end
rule "Infer Adult"
when
$p : Person(age >= 16)
then
insertLogical(new IsAdult($p))
end
When the condition in the rule is false, the fact is automatically retracted. This works particularly well
as the two rules are mutually exclusive. In the above rules, if the person is under 16 years, it inserts an
IsChild fact. Once the person is 16 years or above, the IsChild fact is automatically retracted and
the IsAdult fact inserted.
Now the two rules for issuing child and adult bus pass can logically insert the ChildBusPass and
AdultBusPass facts, as the Truth Maintenance System supports chaining of logical insertions for a
cascading set of retracts.
rule "Issue Child Bus Pass"
when
$p : Person()
IsChild(person == $p)
then
insertLogical(new ChildBusPass($p));
end
rule "Issue Adult Bus Pass"
when
$p : Person(age >= 16)
IsAdult(person =$p)
then
insertLogical(new AdultBusPass($p));
end
When a person turns 16 years old, the IsChild fact as well as the person’s ChildBusPass fact is
retracted. To these set of conditions, you can relate another rule which states that a person must
return the child pass after turning 16 years old. When the Truth Maintenance System automatically
retracts the ChildBusPass object, this rule triggers and sends a request to the person:
rule "Return ChildBusPass Request"
when

65

Red Hat JBoss BPM Suite 6.4 Development Guide

$p : Person()
not(ChildBusPass(person == $p))
then
requestChildBusPass($p);
end

6.5. USING DECISION TABLES IN SPREADSHEETS
Decision tables are a way of representing conditional logic in a precise manner, and are well suited to
business-level rules.
Red Hat JBoss BRMS supports managing rules in a spreadsheet format. Since two formats are
currently supported, XLS and CSV, a variety of spreadsheet programs, such as Microsoft Excel, Apache
OpenOffice Calc, and LibreOffice Calc, can be utilized.

NOTE
Use the XLS format if you are building and uploading decision tables using Business
Central. Business Central does not support decision tables in the CSV format.

6.5.1. OpenOffice Example
Figure 6.3. OpenOffice Screenshot

In the above examples, the technical aspects of the decision table have been collapsed away (using a
standard spreadsheet feature).

66

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

The rules start from row 17, with each row resulting in a rule. The conditions are in columns C, D, E, and
the actions are off-screen. The values' meanings are indicated by the headers in Row 16. Column B is
just a description.

NOTE
Although the decision tables look like they process top down, this is not necessarily the
case. Ideally, rules are authored without regard for the order of rows. This makes
maintenance easier, as rows will not need to be shifted around all the time.

6.5.2. Rules and Spreadsheets
Rules Inserted into Rows
As each row is a rule, the same principles apply as with written code. As the rule engine processes
the facts, any rules that match may fire.
Agendas
It is possible to clear the agenda when a rule fires and simulate a very simple decision table where
only the first match effects an action.
Multiple Tables
You can have multiple tables on one spreadsheet. This way, rules can be grouped where they share
common templates, but are still all combined into one rule package.

6.5.3. The RuleTable Keyword
When using decision tables, the spreadsheet searches for the RuleTable keyword to indicate the start
of a rule table (both the starting row and column).

IMPORTANT
Keywords should all be in the same column.

6.5.4. The RuleSet Keyword
The RuleSet keyword indicates the name to be used in the rule package that will encompass all the
rules. This name is optional, using a default, but it must have the RuleSet keyword in the cell
immediately to the right.

6.5.5. Data-Defining Cells
There are two types of rectangular areas defining data that is used for generating a DRL file. One,
marked by a cell labelled RuleSet, defines all DRL items except rules. The other one may occur
repeatedly and is to the right and below a cell whose contents begin with RuleTable. These areas
represent the actual decision tables, each area resulting in a set of rules of similar structure.
A Rule Set area may contain cell pairs, one below the RuleSet cell and containing a keyword
designating the kind of value contained in the other one that follows in the same row.

6.5.6. Rule Table Columns
The columns of a Rule Table area define patterns and constraints for the left hand sides of the rules
derived from it, actions for the consequences of the rules, and the values of individual rule attributes. A
Rule Table area should contain one or more columns, both for conditions and actions, and an arbitrary

67

Red Hat JBoss BPM Suite 6.4 Development Guide

selection of columns for rule attributes, at most one column for each of these. The first four rows
following the row with the cell marked with RuleTable are earmarked as header area, mostly used for
the definition of code to construct the rules. It is any additional row below these four header rows that
spawns another rule, with its data providing for variations in the code defined in the Rule Table
header.

NOTE
All keywords are case insensitive.
Only the first worksheet is examined for decision tables.

6.5.7. Rule Set Entries
Entries in a Rule Set area may define DRL constructs (except rules), and specify rule attributes. While
entries for constructs may be used repeatedly, each rule attribute may be given at most once, and it
applies to all rules unless it is overruled by the same attribute being defined within the Rule Table area.
Entries must be given in a vertically stacked sequence of cell pairs. The first one contains a keyword
and the one to its right the value. This sequence of cell pairs may be interrupted by blank rows or even
a Rule Table, as long as the column marked by RuleSet is upheld as the one containing the keyword.
Table 6.1. Entries in the Rule Set area
Keyword

Value

Usage

RuleSet

The package name for the generated DRL file.
Optional, the default is rule_table.

Must be the first entry.

Sequential

true or false. If true, then salience is used

Optional, at most once. If
omitted, no firing order is
imposed.

to ensure that rules fire from the top down.

marks are escaped so that they appear
literally in the DRL.

Optional, at most once. If
omitted, quotation marks are
escaped.

Import

A comma-separated list of Java classes to
import.

Optional, may be used
repeatedly.

Variables

Declarations of DRL globals, for example a
type followed by a variable name. Multiple
global definitions must be separated with a
comma.

Optional, may be used
repeatedly.

Functions

One or more function definitions, according to
DRL syntax.

Optional, may be used
repeatedly.

Queries

One or more query definitions, according to
DRL syntax.

Optional, may be used
repeatedly.

EscapeQuotes

68

true or false. If true, then quotation

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

Keyword

Value

Usage

Declare

One or more declarative types, according to
DRL syntax.

Optional, may be used
repeatedly.

6.5.8. Rule Attribute Entries in Rule Set Area
IMPORTANT
Rule attributes specified in a Rule Set area will affect all rule assets in the same package
(not only in the spreadsheet). Unless you are sure that the spreadsheet is the only one
rule asset in the package, the recommendation is to specify rule attributes not in a Rule
Set area but in a Rule Table columns for each rule instead.
Table 6.2. Rule Attribute Entries in Rule Set Area
Keyword

Initial

Value

PRIORITY

P

An integer defining the "salience" value for the rule.
Overridden by the "Sequential" flag.

DURATION

D

A long integer value defining the "duration" value for the
rule.

TIMER

T

A timer definition. See Section 8.10.2, “Timers”.

CALENDARS

E

A calendars definition. See Section 8.10.4, “Calendars”.

NO-LOOP

U

A Boolean value. true inhibits looping of rules due to
changes made by its consequence.

LOCK-ON-ACTIVE

L

A Boolean value. true inhibits additional activations of all
rules with this flag set within the same ruleflow or agenda
group.

AUTO-FOCUS

F

A Boolean value. true for a rule within an agenda group
causes activations of the rule to automatically give the
focus to the group.

ACTIVATION-GROUP

X

A string identifying an activation (or XOR) group. Only one
rule within an activation group will fire, for example the
first one to fire cancels any existing activations of other
rules within the same group.

AGENDA-GROUP

G

A string identifying an agenda group, which has to be
activated by giving it the "focus", which is one way of
controlling the flow between groups of rules.

RULEFLOW-GROUP

R

A string identifying a rule-flow group.

69

Red Hat JBoss BPM Suite 6.4 Development Guide

Keyword

Initial

Value

DATE-EFFECTIVE

V

A string containing a date and time definition. A rule can
only activate if the current date and time is after DATEEFFECTIVE attribute.

DATE-EXPIRES

Z

A string containing a date and time definition. A rule
cannot activate if the current date and time is after the
DATE-EXPIRES attribute.

6.5.9. The RuleTable Cell
All Rule Tables begin with a cell containing RuleTable, optionally followed by a string within the same
cell. The string is used as the initial part of the name for all rules derived from this Rule Table, with the
row number appended for distinction. This automatic naming can be overridden by using a NAME
column. All other cells defining rules of this Rule Table are below and to the right of this cell.

6.5.10. Column Types
The next row after the RuleTable cell defines the column type. Each column results in a part of the
condition or the consequence, or provides some rule attribute, the rule name or a comment. Each
attribute column may be used at most once.
Table 6.3. Column Headers in the Rule Table
Keyword

Initial

Value

Usage

NAME

N

Provides the name for the rule
generated from that row. The
default is constructed from the
text following the RuleTable tag
and the row number.

At most one column.

DESCRIPTION

I

A text, resulting in a comment
within the generated rule.

At most one column.

CONDITION

C

Code snippet and interpolated
values for constructing a
constraint within a pattern in a
condition.

At least one per rule
table.

ACTION

A

Code snippet and interpolated
values for constructing an action
for the consequence of the rule.

At least one per rule
table.

METADATA

@

Code snippet and interpolated
values for constructing a metadata
entry for the rule.

Optional, any number of
columns.

6.5.11. Conditional Elements

70

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

Given a column headed CONDITION, the cells in successive lines result in a conditional element.
Text in the first cell below CONDITION develops into a pattern for the rule condition, with the
snippet in the next line becoming a constraint. If the cell is merged with one or more
neighbours, a single pattern with multiple constraints is formed: all constraints are combined
into a parenthesized list and appended to the text in this cell. The cell may be left blank, which
means that the code snippet in the next row must result in a valid conditional element on its
own.
To include a pattern without constraints, you can write the pattern in front of the text for
another pattern.
The pattern may be written with or without an empty pair of parentheses. A "from" clause may
be appended to the pattern.
If the pattern ends with "eval", code snippets are supposed to produce boolean expressions for
inclusion into a pair of parentheses after "eval".
Text in the second cell below CONDITION is processed in two steps.
The code snippet in this cell is modified by interpolating values from cells farther down in
the column. If you want to create a constraint consisting of a comparison using "==" with
the value from the cells below, the field selector alone is sufficient. Any other comparison
operator must be specified as the last item within the snippet, and the value from the cells
below is appended. For all other constraint forms, you must mark the position for including
the contents of a cell with the symbol $param. Multiple insertions are possible by using the
symbols $1, $2, etc., and a comma-separated list of values in the cells below.
A text according to the pattern forall(DELIMITER){SNIPPET} is expanded by
repeating the SNIPPET once for each of the values of the comma-separated list of values
in each of the cells below, inserting the value in place of the symbol $ and by joining these
expansions by the given DELIMITER. Note that the forall construct may be surrounded by
other text.
If the cell in the preceding row is not empty, the completed code snippet is added to the
conditional element from that cell. A pair of parentheses is provided automatically, as well
as a separating comma if multiple constraints are added to a pattern in a merged cell.
If the cell above is empty, the interpolated result is used as is.
Text in the third cell below CONDITION is for documentation only. It should be used to indicate
the column’s purpose to a human reader.
From the fourth row on, non-blank entries provide data for interpolation as described above. A
blank cell results in the omission of the conditional element or constraint for this rule.

6.5.12. Action Statements
Given a column headed ACTION, the cells in successive lines result in an action statement:
Text in the first cell below ACTION is optional. If present, it is interpreted as an object
reference.
Text in the second cell below ACTION is processed in two steps.
The code snippet in this cell is modified by interpolating values from cells farther down in
the column. For a singular insertion, mark the position for including the contents of a cell
with the symbol $param. Multiple insertions are possible by using the symbols $1, $2, etc.,
and a comma-separated list of values in the cells below.

71

Red Hat JBoss BPM Suite 6.4 Development Guide

A method call without interpolation can be achieved by a text without any marker symbols.
In this case, use any non-blank entry in a row below to include the statement.
The forall construct is available here, too.
If the first cell is not empty, its text, followed by a period, the text in the second cell and a
terminating semicolon are stringed together, resulting in a method call which is added as
an action statement for the consequence.
If the cell above is empty, the interpolated result is used as is.
Text in the third cell below ACTION is for documentation only. It should be used to indicate the
column’s purpose to a human reader.
From the fourth row on, non-blank entries provide data for interpolation as described above. A
blank cell results in the omission of the action statement for this rule.

NOTE
Using $1 instead of $param will fail if the replacement text contains a comma.

6.5.13. Metadata Statements
Given a column headed METADATA, the cells in successive lines result in a metadata annotation for the
generated rules:
Text in the first cell below METADATA is ignored.
Text in the second cell below METADATA is subject to interpolation, as described above, using
values from the cells in the rule rows. The metadata marker character @ is prefixed
automatically, and should not be included in the text for this cell.
Text in the third cell below METADATA is for documentation only. It should be used to indicate
the column’s purpose to a human reader.
From the fourth row on, non-blank entries provide data for interpolation as described above. A
blank cell results in the omission of the metadata annotation for this rule.

6.5.14. Interpolating Cell Data Example
If the template is Foo(bar == $param) and the cell is 42, then the result is Foo(bar ==
42).
If the template is Foo(bar < $1, baz == $2) and the cell contains 42,43, the result will
be Foo(bar < 42, baz ==43).
The template forall(&&){bar != $} with a cell containing 42,43 results in bar != 42
&& bar != 43.

6.5.15. Tips for Working Within Cells
Multiple package names within the same cell must be comma-separated.
Pairs of type and variable names must be comma-separated.

72

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS

Functions must be written as they appear in a DRL file. This should appear in the same column
as the RuleSet keyword. It can be above, between or below all the rule rows.
You can use Import, Variables, Functions and Queries repeatedly instead of packing several
definitions into a single cell.
Trailing insertion markers can be omitted.
You can provide the definition of a binding variable.
Anything can be placed in the object type row. Apart from the definition of a binding variable, it
could also be an additional pattern that is to be inserted literally.
The cell below the ACTION header can be left blank. Using this style, anything can be placed in
the consequence, not just a single method call. The same technique is applicable within a
CONDITION column.

6.5.16. The SpreadsheetCompiler Class
The SpreadsheetCompiler class is the main class used with API spreadsheet-based decision tables
in the drools-decisiontables module. This class takes spreadsheets in various formats and generates
rules in DRL.
The SpreadsheetCompiler can be used to generate partial rule files and assemble them into a
complete rule package after the fact. This allows the separation of technical and non-technical aspects
of the rules if needed.

6.5.17. Using Spreadsheet-Based Decision Tables
Procedure: Task
1. Generate a sample spreadsheet that you can use as the base.
2. If the Red Hat JBoss BRMS plug-in is being used, use the wizard to generate a spreadsheet
from a template.
3. Use an XSL-compatible spreadsheet editor to modify the XSL.

6.5.18. Lists
In Excel, you can create lists of values. These can be stored in other worksheets to provide valid lists
of values for cells.

6.5.19. Revision Control
When changes are being made to rules over time, older versions are archived. Some applications in
Red Hat JBoss BRMS provide a limited ability to keep a history of changes, but it is recommended to
use an alternative means of revision control.

6.5.20. Tabular Data Sources
A tabular data source can be used as a source of rule data. It can populate a template to generate many
rules. This can allow both for more flexible spreadsheets, but also rules in existing databases for
instance (at the cost of developing the template up front to generate the rules).

73

Red Hat JBoss BPM Suite 6.4 Development Guide

6.6. DEPENDENCY MANAGEMENT FOR GUIDED DECISION TABLES,
SCORECARDS, AND RULE TEMPLATES
When you build your own application with the embedded Drools or jBPM engine, that uses guided
decision tables, guided scorecards, or guided templates, you need to add the drools-workbenchmodels-guided-dtable, drools-workbench-models-guided-scorecard, and droolsworkbench-models-guided-template dependencies respectively, on the class path.
If you want to use a kJAR in the Intelligent Process server, you do not need to add these dependencies,
as the server already has them.
When using Maven, declare the dependencies in the pom.xml file as shown below:

org.drools
drools-workbench-models-guided-dtable


org.drools
drools-workbench-models-guided-scorecard


org.drools
drools-workbench-models-guided-template


6.7. LOGGING
The logging feature enables you to investigate what the Rule Engine does at the back-end. The rule
engine uses Java logging API SLF4J for logging. The underlying logging back-end can be Logback,
Apache Commons Logging, Log4j, or java.util.logging. You can add a dependency to the logging
adaptor for your logging framework of choice.
Here is an example of how to use Logback by adding a Maven dependency:

ch.qos.logback
logback-classic
1.x


NOTE
If you are developing for an ultra light environment, use slf4j-nop or slf4j-simple.

6.7.1. Configuring Logging Level
Here is an example of how you can configure the logging level on the package org.drools in your
logback.xml file when you are using Logback:


74

CHAPTER 6. GETTING STARTED WITH RULES AND FACTS


...
...

Here is an example of how you can configure the logging level in your log4j.xml file when you are
using Log4J:




...


75

Red Hat JBoss BPM Suite 6.4 Development Guide

CHAPTER 7. COMPLEX EVENT PROCESSING
7.1. INTRODUCTION TO COMPLEX EVENT PROCESSING
JBoss BRMS Complex Event Processing provides the JBoss Enterprise BRMS Platform with complex
event processing capabilities.
For the purpose of this guide, Complex Event Processing, or CEP, refers to the ability to process multiple
events and detect interesting events from within a collection of events, uncover relationships that
exist between events, and infer new data from the events and their relationships.
An event can best be described as a record of a significant change of state in the application domain.
Depending on how the domain is modeled, the change of state may be represented by a single event,
multiple atomic events, or even hierarchies of correlated events. Using a stock broker application as an
example, a change in security prices, a change in ownership from seller to buyer, or a change in an
account holder’s balance are all considered to be events as a change has occurred in the state of the
application domain.
Event processing use cases, in general, share several requirements and goals with business rules use
cases.
From a business perspective, business rule definitions are often defined based on the occurrence of
scenarios triggered by events. For example:
On an algorithmic trading application: Take an action if the security price increases X% above
the day’s opening price.
The price increases are denoted by events on a stock trade application.
On a monitoring application: Take an action if the temperature in the server room increases X
degrees in Y minutes.
The sensor readings are denoted by events.
Both business rules and event processing queries change frequently and require an immediate
response for the business to adapt to new market conditions, regulations, and corporate policies.
From a technical perspective:
Both business rules and event processing require seamless integration with the enterprise
infrastructure and applications. This is particularly important with regard to life-cycle
management, auditing, and security.
Both business rules and event processing have functional requirements like pattern matching
and non-functional requirements like response time limits and query/rule explanations.

NOTE
JBoss BRMS Complex Event Processing provides the complex event processing
capabilities of JBoss Business Rules Management System. The Business Rules
Management and Business Process Management capabilities are provided by other
modules.
Complex event processing scenarios share these distinguishing characteristics:
They usually process large numbers of events, but only a small percentage of the events are of
interest.

76

CHAPTER 7. COMPLEX EVENT PROCESSING

The events are usually immutable, as they represent a record of change in state.
The rules and queries run against events and must react to detected event patterns.
There are usually strong temporal relationships between related events.
Individual events are not important. The system is concerned with patterns of related events
and the relationships between them.
It is often necessary to perform composition and aggregation of events.
As such, JBoss BRMS Complex Event Processing supports the following behaviors:
Support events, with their proper semantics, as first class citizens.
Allow detection, correlation, aggregation, and composition of events.
Support processing streams of events.
Support temporal constraints in order to model the temporal relationships between events.
Support sliding windows of interesting events.
Support a session-scoped unified clock.
Support the required volumes of events for complex event processing use cases.
Support reactive rules.
Support adapters for event input into the engine (pipeline).

7.2. EVENTS
Events are a record of significant change of state in the application domain. From a complex event
processing perspective, an event is a special type of fact or object. A fact is a known piece of data. For
instance, a fact could be a stock’s opening price. A rule is a definition of how to react to the data. For
instance, if a stock price reaches $X, sell the stock.
The defining characteristics of events are the following:
Events are immutable
An event is a record of change which has occurred at some time in the past, and as such it cannot
be changed.

NOTE
The rules engine does not enforce immutability on the Java objects representing
events; this makes event data enrichment possible.
The application should be able to populate un-populated event attributes, which can
be used to enrich the event with inferred data; however, event attributes that have
already been populated should not be changed.
Events have strong temporal constraints

77

Red Hat JBoss BPM Suite 6.4 Development Guide

Rules involving events usually require the correlation of multiple events that occur at different
points in time relative to each other.
Events have managed life-cycles
Because events are immutable and have temporal constraints, they are usually only of interest for a
specified period of time. This means the engine can automatically manage the life-cycle of events.
Events can use sliding windows
It is possible to define and use sliding windows with events since all events have timestamps
associated with them. Therefore, sliding windows allow the creation of rules on aggregations of
values over a time period.
Events can be declared as either interval-based events or point-in-time events. Interval-based events
have a duration time and persist in working memory until their duration time has lapsed. Point-in-time
events have no duration and can be thought of as interval-based events with a duration of zero.

7.2.1. Event Declaration
To declare a fact type as an event, assign the @role metadata tag to the fact with the event
parameter. The @role metadata tag can accept two possible values:
fact: assigning the fact role declares the type is to be handled as a regular fact. Fact is the
default role.
event: assigning the event role declares the type is to be handled as an event.
This example declares that a stock broker application’s StockTick fact type will be handled as an
event:
Example 7.1. Declaring Fact Type as Event
import some.package.StockTick
declare StockTick
@role( event )
end

Facts can also be declared inline. If StockTick was a fact type declared in the DRL instead of in a preexisting class, the code would be as follows:
Example 7.2. Declaring Fact Type and Assigning it to Event Role
declare StockTick
@role(event)
datetime : java.util.Date
symbol : String
price : double
end

For more information about type declarations, see Section 8.9, “Type Declaration” .

78

CHAPTER 7. COMPLEX EVENT PROCESSING

7.2.2. Event Metadata
Every event has associated metadata. Typically, the metadata is automatically added as each event is
inserted into working memory. The metadata defaults can be changed on an event-type basis using the
metadata tags:
@role
@timestamp
@duration
@expires
The following examples assume the application domain model includes the following class:
Example 7.3. The VoiceCall Fact Class
/**
* A class that represents a voice call in a Telecom domain model.
*/
public class VoiceCall {
private String originNumber;
private String destinationNumber;
private Date
callDateTime;
private long
callDuration; // in milliseconds
// Constructors, getters, and setters.
}

@role
The @role metadata tag indicates whether a given fact type is either a regular fact or an event. It
accepts either fact or event as a parameter. The default is fact.
@role()
Example 7.4. Declaring VoiceCall as Event Type
declare VoiceCall
@role(event)
end

@timestamp
A timestamp is automatically assigned to every event. By default, the time is provided by the
session clock and assigned to the event at insertion into the working memory. Events can have their
own timestamp attribute, which can be included by telling the engine to use the attribute’s
timestamp instead of the session clock.
To use the attribute’s timestamp, use the attribute name as the parameter for the @timestamp tag.
@timestamp()

79

Red Hat JBoss BPM Suite 6.4 Development Guide

Example 7.5. Declaring VoiceCall Timestamp Attribute
declare VoiceCall
@role(event)
@timestamp(callDateTime)
end

@duration
JBoss BRMS Complex Event Processing supports both point-in-time and interval-based events. A
point-in-time event is represented as an interval-based event with a duration of zero time units. By
default, every event has a duration of zero. To assign a different duration to an event, use the
attribute name as the parameter for the @duration tag.
@duration()
Example 7.6. Declaring VoiceCall Duration Attribute
declare VoiceCall
@role(event)
@timestamp(callDateTime)
@duration(callDuration)
end

@expires
Events may be set to expire automatically after a specific duration in the working memory. By
default, this happens when the event can no longer match and activate any of the current rules. You
can also explicitly define when an event should expire. The @expires tag is only used when the
engine is running in stream mode.
@expires()
The value of timeOffset is a temporal interval that sets the relative duration of the event.
[#d][#h][#m][#s][#[ms]]
All parameters are optional and the # parameter should be replaced by the appropriate value.
To declare that the VoiceCall facts should expire one hour and thirty-five minutes after insertion
into the working memory, use the following:
Example 7.7. Declaring Expiration Offset for VoiceCall Events
declare VoiceCall
@role(event)
@timestamp(callDateTime)
@duration(callDuration)
@expires(1h35m)
end

80

CHAPTER 7. COMPLEX EVENT PROCESSING

7.3. CLOCK IMPLEMENTATION IN COMPLEX EVENT PROCESSING
7.3.1. Session Clock
Events have strong temporal constraints making it is necessary to use a reference clock. If a rule needs
to determine the average price of a given stock over the last sixty minutes, it is necessary to compare
the stock price event’s timestamp with the current time. The reference clock provides the current
time.
Because the rules engine can simultaneously run an array of different scenarios that require different
clocks, multiple clock implementations can be used by the engine.
Scenarios that require different clocks include the following:
Rules testing: Testing always requires a controlled environment, and when the tests include
rules with temporal constraints, it is necessary to control the input rules, facts, and the flow of
time.
Regular execution: A rules engine that reacts to events in real time needs a real-time clock.
Special environments: Specific environments may have specific time control requirements. For
instance, clustered environments may require clock synchronization or JEE environments may
require you to use an application server-provided clock.
Rules replay or simulation: In order to replay or simulate scenarios, it is necessary that the
application controls the flow of time.

7.3.2. Available Clock Implementations
JBoss BRMS Complex Event Processing comes equipped with two clock implementations:
Real-Time Clock
The real-time clock is the default implementation based on the system clock. The real-time clock
uses the system clock to determine the current time for timestamps.
To explicitly configure the engine to use the real-time clock, set the session configuration
parameter to realtime:
import org.kie.api.KieServices.Factory;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.KieSessionConfiguration;
KieSessionConfiguration config =
KieServices.Factory.get().newKieSessionConfiguration();
config.setOption(ClockTypeOption.get("realtime"));
Pseudo-Clock
The pseudo-clock is useful for testing temporal rules since it can be controlled by the application.
To explicitly configure the engine to use the pseudo-clock, set the session configuration parameter
to pseudo:

81

Red Hat JBoss BPM Suite 6.4 Development Guide

import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.KieServices.Factory;
KieSessionConfiguration config =
KieServices.Factory.get().newKieSessionConfiguration();
config.setOption(ClockTypeOption.get("pseudo"));
This example shows how to control the pseudo-clock:
import java.util.concurrent.TimeUnit;
import
import
import
import
import
import

org.kie.api.runtime.KieSessionConfiguration;
org.kie.api.KieServices.Factory;
org.kie.api.runtime.KieSession;
org.drools.core.time.SessionPseudoClock;
org.kie.api.runtime.rule.FactHandle;
org.kie.api.runtime.conf.ClockTypeOption;

KieSessionConfiguration conf =
KieServices.Factory.get().newKieSessionConfiguration();
conf.setOption( ClockTypeOption.get("pseudo"));
KieSession session = kbase.newKieSession(conf, null);
SessionPseudoClock clock = session.getSessionClock();
// Then, while inserting facts, advance the clock as necessary:
FactHandle handle1 = session.insert(tick1);
clock.advanceTime(10, TimeUnit.SECONDS);
FactHandle handle2 = session.insert(tick2);
clock.advanceTime(30, TimeUnit.SECONDS);
FactHandle handle3 = session.insert(tick3);

For a list of Maven dependencies, see example Embedded jBPM Engine Dependencies . If you use Red
Hat JBoss BRMS, see Embedded Drools Engine Dependencies .

7.4. EVENT PROCESSING MODES
Rules engines process facts and rules to provide applications with results. Regular facts (facts with no
temporal constraints) are processed independent of time and in no particular order. Red Hat JBoss
BRMS processes facts of this type in cloud mode. Events (facts which have strong temporal
constraints) must be processed in real-time or near real-time. Red Hat JBoss BRMS processes these
events in stream mode. Stream mode deals with synchronization and makes it possible for Red Hat
JBoss BRMS to process events.

7.4.1. Cloud Mode
Cloud mode is the default operating mode of Red Hat JBoss Business Rules Management System.
Running in Cloud mode, the engine applies a many-to-many pattern matching algorithm, which treats

82

CHAPTER 7. COMPLEX EVENT PROCESSING

the events as an unordered cloud. Events still have timestamps, but there is no way for the rules engine
running in Cloud mode to draw relevance from the timestamp because Cloud mode is unaware of the
present time.
This mode uses the rules constraints to find the matching tuples, activate, and fire rules.
Cloud mode does not impose any kind of additional requirements on facts; however, because it has no
concept of time, it cannot take advantage of temporal features such as sliding windows or automatic lifecycle management. In Cloud mode, it is necessary to explicitly retract events when they are no longer
needed.
Certain requirements that are not imposed include the following:
No need for clock synchronization since there is no notion of time.
No requirement on ordering events since the engine looks at the events as an unordered cloud
against which the engine tries to match rules.
Cloud mode can be specified either by setting a system property, using configuration property files, or
using the API.
The API call follows:
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices.Factory;
KieBaseConfiguration config =
KieServices.Factory.get().newKieBaseConfiguration();
config.setOption(EventProcessingOption.CLOUD);
The equivalent property follows:
drools.eventProcessingMode = cloud
For a list of Maven dependencies, see example Embedded jBPM Engine Dependencies . If you use Red
Hat JBoss BRMS, see Embedded Drools Engine Dependencies .

7.4.2. Stream Mode
Stream mode processes events chronologically as they are inserted into the rules engine. Stream mode
uses a session clock that enables the rules engine to process events as they occur in time. The session
clock enables processing events as they occur based on the age of the events. Stream mode also
synchronizes streams of events (so events in different streams can be processed in chronological
order), implements sliding windows of interest, and enables automatic life-cycle management.
The requirements for using stream mode are the following:
Events in each stream must be ordered chronologically.
A session clock must be present to synchronize event streams.

83

Red Hat JBoss BPM Suite 6.4 Development Guide

NOTE
The application does not need to enforce ordering events between streams, but the use
of event streams that have not been synchronized may cause unexpected results.
Stream mode can be enabled by setting a system property, using configuration property files, or using
the API.
The API call follows:
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices.Factory;
KieBaseConfiguration config =
KieServices.Factory.get().newKieBaseConfiguration();
config.setOption(EventProcessingOption.STREAM);
The equivalent property follows:
drools.eventProcessingMode = stream
For a list of Maven dependencies, see example Embedded jBPM Engine Dependencies . If you use Red
Hat JBoss BRMS, see Embedded Drools Engine Dependencies .

7.5. EVENT STREAMS
Complex event processing use casesdeal with streams of events. The streams can be provided to the
application using JMS queues, flat text files, database tables, raw sockets, or even web service calls.
Streams share a common set of characteristics:
Events in the stream are ordered by timestamp. The timestamps may have different semantics
for different streams, but they are always ordered internally.
There is usually a high volume of events in the stream.
Atomic events contained in the streams are rarely useful by themselves.
Streams are either homogeneous (they contain a single type of event) or heterogeneous (they
contain events of different types).
A stream is also known as an entry point.
Facts from one entry point, or stream, may join with facts from any other entry point in addition to
facts already in working memory. Facts always remain associated with the entry point through which
they entered the engine. Facts of the same type may enter the engine through several entry points, but
facts that enter the engine through entry point A will never match a pattern from entry point B.

7.5.1. Declaring and Using Entry Points
Entry points are declared implicitly by making direct use of them in rules. Referencing an entry point in
a rule will make the engine, at compile time, identify and create the proper internal structures to
support that entry point.

84

CHAPTER 7. COMPLEX EVENT PROCESSING

For example, a banking application that has transactions fed into the engine using streams could have
one stream for all of the transactions executed at ATMs. A rule for this scenario could state, "A
withdrawal is only allowed if the account balance is greater than the withdrawal amount the customer has
requested."
Example 7.8. ATM Rule
rule "Authorize Withdraw"
when
WithdrawRequest($ai : accountId, $am : amount) from entry-point "ATM
Stream"
CheckingAccount(accountId == $ai, balance > $am)
then
// authorize withdraw
end

When the engine compiles this rule, it will identify that the pattern is tied to the entry point ATM
Stream. The engine will create all the necessary structures for the rule-base to support the ATM Stream,
and this rule will only match WithdrawRequest events coming from the ATM Stream.
Note the ATM example rule joins the event (WithdrawalRequest) from the stream with a fact from
the main working memory (CheckingAccount).
The banking application may have a second rule that states, "A fee of $2 must be applied to a withdraw
request made using a branch teller."
Example 7.9. Using Multiple Streams
rule "Apply Fee on Withdraws on Branches"
when
WithdrawRequest($ai : accountId, processed == true) from entry-point
"Branch Stream"
CheckingAccount(accountId == $ai)
then
// apply a $2 fee on the account
end

This rule matches events of the same type (WithdrawRequest) as the example ATM rule but from a
different stream. Events inserted into the ATM Stream will never match the pattern on the second rule,
which is tied to the Branch Stream; accordingly, events inserted into the Branch Stream will never
match the pattern on the example ATM rule, which is tied to the ATM Stream.
Declaring the stream in a rule states that the rule is only interested in events coming from that stream.
Events can be inserted manually into an entry point instead of directly into the working memory.
Example 7.10. Inserting Facts into Entry Point
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.EntryPoint;
// Create your rulebase and your session as usual:

85

Red Hat JBoss BPM Suite 6.4 Development Guide

KieSession session = ...
// Get a reference to the entry point:
EntryPoint atmStream = session.getEntryPoint("ATM Stream");
// ...and start inserting your facts into the entry point:
atmStream.insert(aWithdrawRequest);

For a list of Maven dependencies, see example Embedded jBPM Engine Dependencies . If you use Red
Hat JBoss BRMS, see Embedded Drools Engine Dependencies .

7.5.2. Negative Pattern in Stream Mode
A negative pattern is concerned with conditions that are not met. Negative patterns make reasoning in
the absence of events possible. For instance, a safety system could have a rule that states "If a fire is
detected and the sprinkler is not activated, sound the alarm."
In Cloud mode, the engine assumes all facts (regular facts and events) are known in advance and
evaluates negative patterns immediately.
Example 7.11. Rule with Negative Pattern
rule "Sound the Alarm"
when
$f : FireDetected()
not(SprinklerActivated())
then
// sound the alarm
end

An example in stream mode is displayed below. This rule keeps consistency when dealing with
negative patterns and temporal constraints at the same time interval.
Example 7.12. Rule with Negative Pattern, Temporal Constraints, and Explicit Duration
Parameter
rule "Sound the Alarm"
duration(10s)
when
$f : FireDetected()
not(SprinklerActivated(this after[0s,10s] $f))
then
// sound the alarm
end

In stream mode, negative patterns with temporal constraints may force the engine to wait for a set
time before activating a rule. A rule may be written for an alarm system that states, "If a fire is detected
and the sprinkler is not activated after 10 seconds, sound the alarm." Unlike the previous stream mode
example, this one does not require the user to calculate and write the duration parameter.

86

CHAPTER 7. COMPLEX EVENT PROCESSING

Example 7.13. Rule with Negative Pattern with Temporal Constraints
rule "Sound the Alarm"
when
$f : FireDetected()
not(SprinklerActivated(this after[0s,10s] $f))
then
// sound the alarm
end

The rule depicted below expects one "Heartbeat" event to occur every 10 seconds; if not, the rule fires.
What is special about this rule is that it uses the same type of object in the first pattern and in the
negative pattern. The negative pattern has the temporal constraint to wait between 0 to 10 seconds
before firing, and it excludes the Heartbeat bound to $h. Excluding the bound Heartbeat is important
since the temporal constraint [0s, …​] does not exclude by itself the bound event $h from being
matched again, thus preventing the rule to fire.
Example 7.14. Excluding Bound Events in Negative Patterns
rule "Sound the Alarm"
when
$h: Heartbeat() from entry-point "MonitoringStream"
not(Heartbeat(this != $h, this after[0s,10s] $h) from entry-point
"MonitoringStream")
then
// sound the alarm
end

7.6. TEMPORAL OPERATIONS
7.6.1. Temporal Reasoning
Complex Event Processing requires the rules engine to engage in temporal reasoning. Events have
strong temporal constraints so it is vital the rules engine can determine and interpret an event’s
temporal attributes, both as they relate to other events and the 'flow of time' as it appears to the rules
engine. This makes it possible for rules to take time into account; for instance, a rule could state
"Calculate the average price of a stock over the last 60 minutes."

NOTE
JBoss BRMS Complex Event Processing implements interval-based time events, which
have a duration attribute that is used to indicate how long an event is of interest. Pointin-time events are also supported and treated as interval-based events with a duration
of 0 (zero).

7.6.2. Temporal Operations
JBoss BRMS Complex Event Processing implements the following temporal operators and their logical
complements (negation):

87

Red Hat JBoss BPM Suite 6.4 Development Guide

after
before
coincides
during
finishes
finishes by
includes
meets
met by
overlaps
overlapped by
starts
started by

7.6.3. After
The after operator correlates two events and matches when the temporal distance (the time
between the two events) from the current event to the event being correlated falls into the distance
range declared for the operator.
For example:
$eventA : EventA(this after[3m30s, 4m] $eventB)
This pattern only matches if the temporal distance between the time when $eventB finished and the
time when $eventA started is between the lower limit of three minutes and thirty seconds and the
upper limit of four minutes.
This can also be represented as follows:
3m30s <= $eventA.startTimestamp - $eventB.endTimeStamp <= 4m
The after operator accepts one or two optional parameters:
If two values are defined, the interval starts on the first value (3 minutes and 30 seconds in the
example) and ends on the second value (4 minutes in the example).
If only one value is defined, the interval starts on the provided value and runs indefinitely with
no end time.
If no value is defined, the interval starts at one millisecond and runs indefinitely with no end
time.

88

CHAPTER 7. COMPLEX EVENT PROCESSING

The after operator also accepts negative temporal distances.
For example:
$eventA : EventA(this after[-3m30s, -2m] $eventB)
If the first value is greater than the second value, the engine will automatically reverse them.
The following two patterns are equivalent to each other:
$eventA : EventA(this after[-3m30s, -2m] $eventB)
$eventA : EventA(this after[-2m, -3m30s] $eventB)

7.6.4. Before
The before operator correlates two events and matches when the temporal distance (time between
the two events) from the event being correlated to the current event falls within the distance range
declared for the operator.
For example:
$eventA : EventA(this before[3m30s, 4m] $eventB)
This pattern only matches if the temporal distance between the time when $eventA finished and the
time when $eventB started is between the lower limit of three minutes and thirty seconds and the
upper limit of four minutes.
This can also be represented as follows:
3m30s <= $eventB.startTimestamp - $eventA.endTimeStamp <= 4m
The before operator accepts one or two optional parameters:
If two values are defined, the interval starts on the first value (3 minutes and 30 seconds in the
example) and ends on the second value (4 minutes in the example).
If only one value is defined, the interval starts on the provided value and runs indefinitely with
no end time.
If no value is defined, the interval starts at one millisecond and runs indefinitely with no end
time.
The before operator also accepts negative temporal distances.
For example:
$eventA : EventA(this before[-3m30s, -2m] $eventB)
If the first value is greater than the second value, the engine will automatically reverse them.
The following two patterns are equivalent to each other:
$eventA : EventA(this before[-3m30s, -2m] $eventB)
$eventA : EventA(this before[-2m, -3m30s] $eventB)

89

Red Hat JBoss BPM Suite 6.4 Development Guide

7.6.5. Coincides
The coincides operator correlates two events and matches when both events happen at the same
time.
For example:
$eventA : EventA(this coincides $eventB)
This pattern only matches if both the start timestamps of $eventA and $eventB are identical and the
end timestamps of both $eventA and $eventB are also identical.
The coincides operator accepts optional thresholds for the distance between the events' start times
and the events' end times, so the events do not have to start at exactly the same time or end at exactly
the same time, but they need to be within the provided thresholds.
The following rules apply when defining thresholds for the coincides operator:
If only one parameter is given, it is used to set the threshold for both the start and end times of
both events.
If two parameters are given, the first is used as a threshold for the start time and the second
one is used as a threshold for the end time.
For example:
$eventA : EventA(this coincides[15s, 10s] $eventB)
This pattern will only match if the following conditions are met:
abs($eventA.startTimestamp - $eventB.startTimestamp) <= 15s
&&
abs($eventA.endTimestamp - $eventB.endTimestamp) <= 10s



WARNING
The coincides operator does not accept negative intervals, and the rules engine
will throw an exception if an attempt is made to use negative distance internals.

7.6.6. During
The during operator correlates two events and matches when the current event happens during the
event being correlated.
For example:
$eventA : EventA(this during $eventB)

90

CHAPTER 7. COMPLEX EVENT PROCESSING

This pattern only matches if $eventA starts after $eventB and ends before $eventB ends.
This can also be represented as follows:
$eventB.startTimestamp < $eventA.startTimestamp <= $eventA.endTimestamp <
$eventB.endTimestamp
The during operator accepts one, two, or four optional parameters:
The following rules apply when providing parameters for the during operator:
If one value is defined, this value will represent the maximum distance between the start times
of the two events and the maximum distance between the end times of the two events.
If two values are defined, these values represent a threshold that the current event’s start time
and end time must occur between in relation to the correlated event’s start and end times.
If the values 5s and 10s are provided, the current event must start between 5 and 10 seconds
after the correlated event, and similarly the current event must end between 5 and 10 seconds
before the correlated event.
If four values are defined, the first and second values will be used as the minimum and
maximum distances between the starting times of the events, and the third and fourth values
will be used as the minimum and maximum distances between the end times of the two events.

7.6.7. Finishes
The finishes operator correlates two events and matches when the current event’s start timestamp
post-dates the correlated event’s start timestamp and both events end simultaneously.
For example:
$eventA : EventA(this finishes $eventB)
This pattern only matches if $eventA starts after $eventB starts and ends at the same time as
$eventB ends.
This can be represented as follows:
$eventB.startTimestamp < $eventA.startTimestamp
&&
$eventA.endTimestamp == $eventB.endTimestamp
The finishes operator accepts one optional parameter. If defined, the optional parameter sets the
maximum time allowed between the end times of the two events.
For example:
$eventA : EventA(this finishes[5s] $eventB)
This pattern matches if these conditions are met:
$eventB.startTimestamp < $eventA.startTimestamp
&&
abs($eventA.endTimestamp - $eventB.endTimestamp) <= 5s

91

Red Hat JBoss BPM Suite 6.4 Development Guide



WARNING
The finishes operator does not accept negative intervals, and the rules engine
will throw an exception if an attempt is made to use negative distance intervals.

7.6.8. Finishes By
The finishedby operator correlates two events and matches when the current event’s start time
predates the correlated event’s start time but both events end simultaneously. finishedby is the
symmetrical opposite of the finishes operator.
For example:
$eventA : EventA(this finishedby $eventB)
This pattern only matches if $eventA starts before $eventB starts and ends at the same time as
$eventB ends.
This can be represented as follows:
$eventA.startTimestamp < $eventB.startTimestamp
&&
$eventA.endTimestamp == $eventB.endTimestamp
The finishedby operator accepts one optional parameter. If defined, the optional parameter sets the
maximum time allowed between the end times of the two events.
$eventA : EventA(this finishedby[5s] $eventB)
This pattern matches if these conditions are met:
$eventA.startTimestamp < $eventB.startTimestamp
&&
abs($eventA.endTimestamp - $eventB.endTimestamp) <= 5s



WARNING
The finishedby operator does not accept negative intervals, and the rules
engine will throw an exception if an attempt is made to use negative distance
intervals.

7.6.9. Includes

92

CHAPTER 7. COMPLEX EVENT PROCESSING

The includes operator examines two events and matches when the event being correlated happens
during the current event. It is the symmetrical opposite of the during operator.
For example:
$eventA : EventA(this includes $eventB)
This pattern only matches if $eventB starts after $eventA and ends before $eventA ends.
This can be represented as follows:
$eventA.startTimestamp < $eventB.startTimestamp <= $eventB.endTimestamp <
$eventA.endTimestamp
The includes operator accepts 1, 2 or 4 optional parameters:
If one value is defined, this value will represent the maximum distance between the start times
of the two events and the maximum distance between the end times of the two events.
If two values are defined, these values represent a threshold that the current event’s start time
and end time must occur between in relation to the correlated event’s start and end times.
If the values 5s and 10s are provided, the current event must start between 5 and 10 seconds
after the correlated event, and similarly the current event must end between 5 and 10 seconds
before the correlated event.
If four values are defined, the first and second values will be used as the minimum and
maximum distances between the starting times of the events, and the third and fourth values
will be used as the minimum and maximum distances between the end times of the two events.

7.6.10. Meets
The meets operator correlates two events and matches when the current event ends at the same time
as the correlated event starts.
For example:
$eventA : EventA(this meets $eventB)
This pattern matches if $eventA ends at the same time as $eventB starts.
This can be represented as follows:
abs($eventB.startTimestamp - $eventA.endTimestamp) == 0
The meets operator accepts one optional parameter. If defined, it determines the maximum time
allowed between the end time of the current event and the start time of the correlated event.
For example:
$eventA : EventA(this meets[5s] $eventB)
This pattern matches if these conditions are met:

93

Red Hat JBoss BPM Suite 6.4 Development Guide

abs($eventB.startTimestamp - $eventA.endTimestamp) <= 5s



WARNING
The meets operator does not accept negative intervals, and the rules engine will
throw an exception if an attempt is made to use negative distance intervals.

7.6.11. Met By
The metby operator correlates two events and matches when the current event starts at the same
time as the correlated event ends.
For example:
$eventA : EventA(this metby $eventB)
This pattern matches if $eventA starts at the same time as $eventB ends.
This can be represented as follows:
abs($eventA.startTimestamp - $eventB.endTimestamp) == 0
The metby operator accepts one optional parameter. If defined, it sets the maximum distance between
the end time of the correlated event and the start time of the current event.
For example:
$eventA : EventA(this metby[5s] $eventB)
This pattern matches if these conditions are met:
abs($eventA.startTimestamp - $eventB.endTimestamp) <= 5s



WARNING
The metby operator does not accept negative intervals, and the rules engine will
throw an exception if an attempt is made to use negative distance intervals.

7.6.12. Overlaps
The overlaps operator correlates two events and matches when the current event starts before the
correlated event starts and ends after the correlated event starts, but it ends before the correlated
event ends.

94

CHAPTER 7. COMPLEX EVENT PROCESSING

For example:
$eventA : EventA(this overlaps $eventB)
This pattern matches if these conditions are met:
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp <
$eventB.endTimestamp
The overlaps operator accepts one or two optional parameters:
If one parameter is defined, it will define the maximum distance between the start time of the
correlated event and the end time of the current event.
If two values are defined, the first value will be the minimum distance, and the second value will
be the maximum distance between the start time of the correlated event and the end time of
the current event.

7.6.13. Overlapped By
The overlappedby operator correlates two events and matches when the correlated event starts
before the current event, and the correlated event ends after the current event starts but before the
current event ends.
For example:
$eventA : EventA(this overlappedby $eventB)
This pattern matches if these conditions are met:
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp <
$eventA.endTimestamp
The overlappedby operator accepts one or two optional parameters:
If one parameter is defined, it sets the maximum distance between the start time of the
correlated event and the end time of the current event.
If two values are defined, the first value will be the minimum distance, and the second value will
be the maximum distance between the start time of the correlated event and the end time of
the current event.

7.6.14. Starts
The starts operator correlates two events and matches when they start at the same time, but the
current event ends before the correlated event ends.
For example:
$eventA : EventA(this starts $eventB)
This pattern matches if $eventA and $eventB start at the same time, and $eventA ends before
$eventB ends.

95

Red Hat JBoss BPM Suite 6.4 Development Guide

This can be represented as follows:
$eventA.startTimestamp == $eventB.startTimestamp
&&
$eventA.endTimestamp < $eventB.endTimestamp
The starts operator accepts one optional parameter. If defined, it determines the maximum distance
between the start times of events in order for the operator to still match:
$eventA : EventA(this starts[5s] $eventB)
This pattern matches if these conditions are met:
abs($eventA.startTimestamp - $eventB.startTimestamp) <= 5s
&&
$eventA.endTimestamp < $eventB.endTimestamp



WARNING
The starts operator does not accept negative intervals, and the rules engine will
throw an exception if an attempt is made to use negative distance intervals.

7.6.15. Started By
The startedby operator correlates two events. It matches when both events start at the same time
and the correlating event ends before the current event.
For example:
$eventA : EventA(this startedby $eventB)
This pattern matches if $eventA and $eventB start at the same time, and $eventB ends before
$eventA ends.
This can be represented as follows:
$eventA.startTimestamp == $eventB.startTimestamp
&&
$eventA.endTimestamp > $eventB.endTimestamp
The startedby operator accepts one optional parameter. If defined, it sets the maximum distance
between the start time of the two events in order for the operator to still match:
$eventA : EventA( this starts[5s] $eventB)
This pattern matches if these conditions are met:

96

CHAPTER 7. COMPLEX EVENT PROCESSING

abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s
&&
$eventA.endTimestamp > $eventB.endTimestamp



WARNING
The startedby operator does not accept negative intervals, and the rules engine
will throw an exception if an attempt is made to use negative distance intervals.

7.7. SLIDING WINDOWS
7.7.1. Sliding Time Windows
Stream mode allows events to be matched over a sliding time window. A sliding window is a time period
that stretches back in time from the present. For instance, a sliding window of two minutes includes any
events that have occurred in the past two minutes. As events fall out of the sliding time window (in this
case because they occurred more than two minutes ago), they will no longer match against rules using
this particular sliding window.
For example:
StockTick() over window:time(2m)
JBoss BRMS Complex Event Processing uses the over keyword to associate windows with patterns.
Sliding time windows can also be used to calculate averages and over time. For instance, a rule could
be written that states "If the average temperature reading for the last ten minutes goes above a certain
point, sound the alarm."
Example 7.15. Average Value over Time
rule "Sound the Alarm in Case Temperature Rises Above Threshold"
when
TemperatureThreshold($max : max)
Number(doubleValue > $max) from accumulate(
SensorReading($temp : temperature) over window:time(10m),
average($temp))
then
// sound the alarm
end

The engine will automatically discard any SensorReading more than ten minutes old and keep recalculating the average.

7.7.2. Sliding Length Windows

97

Red Hat JBoss BPM Suite 6.4 Development Guide

Similar to Time Windows, Sliding Length Windows work in the same manner; however, they consider
events based on order of their insertion into the session instead of flow of time.
The pattern below demonstrates this order by only considering the last 10 RHT Stock Ticks
independent of how old they are. Unlike the previous StockTick from the Sliding Time Windows pattern,
this pattern uses window:length.
StockTick(company == "RHT") over window:length(10)
The example below portrays window length instead of window time; that is, it allows the user to sound
an alarm in case the average temperature over the last 100 readings from a sensor is above the
threshold value.
Example 7.16. Average Value over Length
rule "Sound the Alarm in Case Temperature Rises Above Threshold"
when
TemperatureThreshold($max : max)
Number(doubleValue > $max) from accumulate(
SensorReading($temp : temperature) over window:length(100),
average($temp))
then
// sound the alarm
end

NOTE
The engine disregards events that fall off a window when calculating that window, but it
does not remove the event from the session based on that condition alone as there
might be other rules that depend on that event.

NOTE
Length based windows do not define temporal constraints for event expiration from the
session, and the engine will not consider them. If events have no other rules defining
temporal constraints and no explicit expiration policy, the engine will keep them in the
session indefinitely.

7.8. MEMORY MANAGEMENT FOR EVENTS
Automatic memory management for events is available when running the rules engine in Stream
mode. Events that no longer match any rule due to their temporal constraints can be safely retracted
from the session by the rules engine without any side effects, releasing any resources held by the
retracted events.
The rules engine has two ways of determining if an event is still of interest:
Explicitly
Event expiration can be explicitly set with the @expires.
Implicitly
The rules engine can analyze the temporal constraints in rules to determine the window of interest
for events.

98

CHAPTER 7. COMPLEX EVENT PROCESSING

7.8.1. Explicit Expiration
Explicit expiration is set with a declare statement and the metadata @expires tag.
For example:
Example 7.17. Declaring Explicit Expiration
declare StockTick
@expires(30m)
end

Declaring expiration against an event-type will, in the above example StockTick events, remove any
StockTick events from the session automatically after the defined expiration time if no rules still
need the events.

7.8.2. Inferred Expiration
The rules engine can calculate the expiration offset for a given event implicitly by analyzing the
temporal constraints in the rules.
For example:
Example 7.18. Rule with Temporal Constraints
rule "correlate orders"
when
$bo : BuyOrder($id : id)
$ae : AckOrder(id == $id, this after[0,10s] $bo)
then
// do something
end

For the example rule, the rules engine automatically calculates that whenever a BuyOrder event
occurs it needs to store the event for up to ten seconds to wait for the matching AckOrder event,
making the implicit expiration offset for BuyOrder events ten seconds. An AckOrder event can only
match an existing BuyOrder event making its implicit expiration offset zero seconds.
The engine analyzes the entire rule-base to find the offset for every event-type. Whenever an implicit
expiration clashes with an explicit expiration the engine uses the greater value of the two.

99

Red Hat JBoss BPM Suite 6.4 Development Guide

CHAPTER 8. WORKING WITH RULES
8.1. ABOUT RULE FILES
8.1.1. Rule File
A rule file is typically a file with a .drl extension. In a DRL file you can have multiple rules, queries and
functions, as well as some resource declarations like imports, globals, and attributes that are assigned
and used by your rules and queries. However, you are also able to spread your rules across multiple
rule files (in that case, the extension .rule is suggested, but not required) - spreading rules across
files can help with managing large numbers of rules. A DRL file is simply a text file.

8.1.2. Structure of Rule Files
The overall structure of a rule file is the following:
Example 8.1. Rule File
package package-name
imports
globals
functions
queries
rules

The order in which the elements are declared is not important, except for the package name that, if
declared, must be the first element in the rules file. All elements are optional, so you will use only those
you need.

8.2. OPERATING ON FACTS
Facts are domain model objects that BRMS uses to evaluate conditions and execute consequences. A
rule specifies that when a particular set of conditions occur, then the specified list of actions must be
executed. The inference engine matches facts against rules, and when matches are found, rule actions
are placed on the agenda. The agenda is the place where rules are queued ready to have their actions
fired. The rule engine then determines which eligible rules on the agenda must fire.

8.2.1. Accessing Working Memory
The working memory is a stateful object that provides temporary storage and enables manipulation of
facts. The working memory includes an API that contains methods which enable access to the working
memory from rule files. The available methods are:
update(OBJECT, HANDLE)
Used to inform the engine that an object has changed and rules can need to be reconsidered.

100

CHAPTER 8. WORKING WITH RULES

update(OBJECT)
This method causes KieSession to search for a fact handle of the passed object using an
identity check. You do not have to call this method when the object changes if property
change listeners are provided. For more infomartion, see Section 8.12.15, “Fine Grained
Property Change Listeners”.
If field values of a fact have changed, call this method or use the modify keyword before
changing another fact to avoid issues with indexing within the engine.
insert(OBJECT)
Used to place a new object into the working memory.
insertLogical(OBJECT)
This method is similar to the insert method. The newly inserted object is automatically
retracted from the working memory if there are no more facts supporting the truth of the rule
that inserted the fact.
retract(HANDLE)
Used to remove an object from the working memory. This method is mapped to the delete
method in KieSession.
halt()
Used to terminate a rule execution immediately. Calling fireUntilHalt() causes
continuous firing of the rules. To stop the firing, call halt().
getKieRuntime()
The whole KIE API is exposed through a predefined kcontext variable of type RuleContext.
The inherited getKieRuntime() method returns a KieRuntime object that provides access
to various methods, many of which are useful for coding the rule logic.
For example, calling kcontext.getKieRuntime().halt() terminates a rule execution
immediately.

8.3. USING RULE KEYWORDS
8.3.1. Hard Keywords
Hard keywords are words which you cannot use when naming your domain objects, properties, methods,
functions, and other elements that are used in the rule text. The hard keywords are true, false, and
null.

8.3.2. Soft Keywords
Soft keywords can be used for naming domain objects, properties, methods, functions, and other
elements. The rules engine recognizes their context and processes them accordingly.

8.3.3. List of Soft Keywords
Rule attributes can be both simple and complex properties that provide a way to influence the behavior
of the rule. They are usually written as one attribute per line and can be optional to the rule. Listed
below are various rule attributes:

101

Red Hat JBoss BPM Suite 6.4 Development Guide

Figure 8.1. Rule Attributes

no-loop BOOLEAN
When a rule’s consequence modifies a fact, it may cause the rule to activate again, causing an
infinite loop. Setting no-loop to true will skip the creation of another activation for the rule with
the current set of facts.
Default value: false.
lock-on-active BOOLEAN
Whenever a ruleflow-group becomes active or an agenda-group receives the focus, any rule
within that group that has lock-on-active set to true will not be activated any more.
Regardless of the origin of the update, the activation of a matching rule is discarded. This is a
stronger version of no-loop because the change is not only caused by the rule itself. It is ideal for
calculation rules where you have a number of rules that modify a fact, and you do not want any rule
re-matching and firing again. Only when the ruleflow-group is no longer active or the agendagroup loses the focus, those rules with lock-on-active set to true become eligible again for
their activations to be placed onto the agenda.
Default value: false.
salience INTEGER
Each rule has an integer salience attribute which defaults to zero and can be negative or positive.
Salience is a form of priority where rules with higher salience values are given higher priority when
ordered in the activation queue.
Default value: 0.

102

CHAPTER 8. WORKING WITH RULES

Red Hat JBoss BRMS also supports dynamic salience where you can use an expression involving
bound variables like the following:
rule "Fire in rank order 1,2,.."
salience(-$rank)
when
Element($rank : rank,...)
then
...
end
ruleflow-group STRING
Ruleflow is a BRMS feature that lets you exercise control over the firing of rules. Rules that are
assembled by the same ruleflow-group identifier fire only when their group is active. This
attribute has been merged with agenda-group and the behaviours are basically the same.
agenda-group STRING
Agenda groups enable you to partition the agenda, which provides more execution control. Only
rules in the agenda group that have acquired the focus are allowed to fire. This attribute has been
merged with ruleflow-group and the behaviours are basically the same.
Default value: MAIN.
auto-focus BOOLEAN
When a rule is activated where the auto-focus value is true and the rule’s agenda group does
not have focus yet, it is automatically given focus, allowing the rule to potentially fire.
Default value: false.
activation-group STRING
Rules that belong to the same activation-group identified by this attribute’s String value, will
only fire exclusively. More precisely, the first rule in an activation-group to fire will cancel all
pending activations of all rules in the group, for example stop them from firing.
dialect STRING
Java and MVEL are the possible values of the dialect attribute. This attribute specifies the
language to be used for any code expressions in the LHS or the RHS code block. While the dialect
can be specified at the package level, this attribute allows the package definition to be overridden
for a rule.
Default value: specified by the package.
date-effective STRING
A rule can only activate if the current date and time is after the date-effective attribute. Note
that STRING is a date and time definition. An example date-effective attribute is displayed
below:
rule "Start Exercising"
date-effective "4-Sep-2014"
when
$m : org.drools.compiler.Message()
then
$m.setFired(true);
end

103

Red Hat JBoss BPM Suite 6.4 Development Guide

date-expires STRING
A rule cannot activate if the current date and time is after the date-expires attribute. Note that
STRING is a date and time definition. An example date-expires attribute is displayed below:
rule "Run 4km"
date-effective "4-Sep-2014"
date-expires "9-Sep-2014"
when
$m : org.drools.compiler.Message()
then
$m.setFired(true);
end
duration LONG
If a rule is still true, the duration attribute will dictate that the rule will fire after a specified
duration.

NOTE
The attributes ruleflow-group and agenda-group have been merged and now
behave the same. The GET methods have been left the same, for deprecations reasons,
but both attributes return the same underlying data.

8.4. ADDING COMMENTS TO RULE FILE
Comments are sections of text that are ignored by the rule engine. They are stripped out when they
are encountered, except inside semantic code blocks (like a rule’s RHS).

8.4.1. Single Line Comment Example
This is what a single line comment looks like. To create single line comments, you can use //. The
parser will ignore anything in the line after the comment symbol:
rule "Testing Comments"
when
// this is a single line comment
eval(true) // this is a comment in the same line of a pattern
then
// this is a comment inside a semantic code block
end

8.4.2. Multi-Line Comment Example
This is what a multi-line comment looks like. This configuration comments out blocks of text, both in
and outside semantic code blocks:
rule "Test Multi-Line Comments"
when
/* this is a multi-line comment
in the left hand side of a rule */
eval( true )
then

104

CHAPTER 8. WORKING WITH RULES

/* and this is a multi-line comment
in the right hand side of a rule */
end

8.5. ERROR MESSAGES IN RULES
Red Hat JBoss BRMS provides standardized error messages. This standardization aims to help users to
find and resolve problems in a easier and faster way.

8.5.1. Error Message Format
This is the standard error message format.
Figure 8.2. Error Message Format Example

1st Block: This area identifies the error code.
2nd Block: Line and column information.
3rd Block: Some text describing the problem.
4th Block: This is the first context. Usually indicates the rule, function, template, or query where the
error occurred. This block is not mandatory.
5th Block: Identifies the pattern where the error occurred. This block is not mandatory.

8.5.2. Error Message Description
[ERR 101] Line 4:4 no viable alternative at input 'exits' in rule one
Indicates when the parser came to a decision point but couldn’t identify an alternative. For example:
1: rule one
2: when
3:
exists Foo()
4:
exits Bar()
5: then
6: end
[ERR 101] Line 3:2 no viable alternative at input 'WHEN
This message means the parser has encountered the token WHEN (a hard keyword) which is in the
wrong place, since the rule name is missing. For example:
1: package org.drools;
2: rule
3:
when
4:
Object()
5:
then
6:
System.out.println("A RHS");
7: end

105

Red Hat JBoss BPM Suite 6.4 Development Guide

[ERR 101] Line 0:-1 no viable alternative at input '' in rule simple_rule in pattern [name]
Indicates an open quote, apostrophe or parentheses. For example:
1: rule simple_rule
2:
when
3:
Student(name == "Andy)
4:
then
5: end
[ERR 102] Line 0:-1 mismatched input '' expecting ')' in rule simple_rule in pattern Bar
Indicates that the parser was looking for a particular symbol that it didn’t end at the current input
position.
1: rule simple_rule
2:
when
3:
foo3 : Bar(
[ERR 102] Line 0:-1 mismatched input '' expecting ')' in rule simple_rule in pattern [name]
This error is the result of an incomplete rule statement. Usually when you get a 0:-1 position, it
means that parser reached the end of source. To fix this problem, it is necessary to complete the
rule statement.
1: package org.drools;
2:
3: rule "Avoid NPE on wrong syntax"
4:
when
5:
not(Cheese((type == "stilton", price == 10) \|\| (type ==
"brie", price == 15)) from $cheeseList)
6:
then
7:
System.out.println("OK");
8: end
[ERR 103] Line 7:0 rule 'rule_key' failed predicate: {(validateIdentifierKey(
DroolsSoftKeywords.RULE ))}? in rule
A validating semantic predicate evaluated to false. Usually these semantic predicates are used to
identify soft keywords.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

106

package nesting;
dialect "mvel"
import org.drools.Person
import org.drools.Address
fdsfdsfds
rule "test something"
when
p: Person(name=="Michael")
then
p.name = "other";
System.out.println(p.name);
end

CHAPTER 8. WORKING WITH RULES

[ERR 104] Line 3:4 trailing semi-colon not allowed in rule simple_rule
This error is associated with the eval clause, where its expression may not be terminated with a
semicolon. This problem is simple to fix: just remove the semi-colon.
1: rule simple_rule
2:
when
3:
eval(abc();)
4:
then
5: end
[ERR 105] Line 2:2 required (…​)+ loop did not match anything at input 'aa' in template test_error
The recognizer came to a subrule in the grammar that must match an alternative at least once, but
the subrule did not match anything. To fix this problem it is necessary to remove the numeric value
as it is neither a valid data type which might begin a new template slot nor a possible start for any
other rule file construct.
1: template test_error
2:
aa s 11;
3: end

8.6. PACKAGING
A package is a collection of rules and other related constructs, such as imports and globals. The
package members are typically related to each other, such as HR rules. A package represents a
namespace, which ideally is kept unique for a given grouping of rules. The package name itself is the
namespace, and is not related to files or folders in any way.
It is possible to assemble rules from multiple rule sources, and have one top-level package
configuration that all the rules are kept under (when the rules are assembled). It is not possible to
merge into the same package resources declared under different names. A single Rulebase may,
however, contain multiple packages built on it. A common structure is to have all the rules for a
package in the same file as the package declaration (so that is it entirely self-contained).

8.6.1. Import Statements
Import statements work like import statements in Java. You need to specify the fully qualified paths and
type names for any objects you want to use in the rules. Red Hat JBoss BRMS automatically imports
classes from the Java package of the same name, and also from the package java.lang.

8.6.2. Using Globals
In DRL files, globals represent global variables. To use globals in rules:
1. Declare the global variable:
global java.util.List myGlobalList;
rule "Using a Global"
when
eval(true)

107

Red Hat JBoss BPM Suite 6.4 Development Guide

then
myGlobalList.add("Hello World");
end
2. Set the global value in the working memory. The best practice is to set all global values before
asserting any fact into the working memory. For example:
List list = new ArrayList();
KieSession kieSession = kieBase.newKieSession();
kieSession.setGlobal("myGlobalList", list);

8.6.3. From Element
The from element allows you to pass a Hibernate session as a global. It also lets you pull data from a
named Hibernate query.

8.6.4. Using Globals with E-Mail Service
Procedure: Task
1. Open the integration code that is calling the rule engine.
2. Obtain your emailService object and then set it in the working memory.
3. In the DRL, declare that you have a global of type emailService and give it the name email.
4. In your rule consequences, you can use things like email.sendSMS(number, message).



WARNING
Globals are not designed to share data between rules and they should
never be used for that purpose. Rules always reason and react to the
working memory state, so if you want to pass data from rule to rule, assert
the data as facts into the working memory.

IMPORTANT
Do not set or change a global value from inside the rules. We recommend to you
always set the value from your application using the working memory interface.

8.7. FUNCTIONS IN RULES
Functions are a way to put semantic code in a rule source file, as opposed to in normal Java classes. The
main advantage of using functions in a rule is that you can keep the logic all in one place. You can
change the functions as needed.
Functions are most useful for invoking actions on the consequence (then) part of a rule, especially if
that particular action is used repeatedly.

108

CHAPTER 8. WORKING WITH RULES

A typical function declaration looks like the following:
function String hello(String name) {
return "Hello " + name + "!";
}

NOTE
Note that the function keyword is used, even though it is not technically part of Java.
Parameters to the function are defined as for a method. You do not have to have
parameters if they are not needed. The return type is defined just like in a regular
method.

8.7.1. Importing Static Method Example
In the following example, a static method Foo.hello() from a helper class is imported as a function.
To import a method, enter the following into your DRL file:
import function my.package.Foo.hello

8.7.2. Calling Function Declaration Example
Irrespective of the way the function is defined or imported, you use a function by calling it by its name,
in the consequence or inside a semantic code block. This is shown below:
rule "Using a Static Function"
when
eval(true)
then
System.out.println(hello("Bob"));
end

8.7.3. Type Declarations
Type declarations have two main goals in the rules engine: to allow the declaration of new types, and to
allow the declaration of metadata for types.
Table 8.1. Type Declaration Roles
Role

Description

Declaring new types

Red Hat JBoss BRMS uses plain Java objects as facts out of the box. However, if
you wish to define the model directly to the rules engine, you can do so by
declaring a new type. You can also declare a new type when there is a domain
model already built and you want to complement this model with additional
entities that are used mainly during the reasoning process.

109

Red Hat JBoss BPM Suite 6.4 Development Guide

Role

Description

Declaring metadata

Facts may have meta information associated to them. Examples of meta
information include any kind of data that is not represented by the fact
attributes and is consistent among all instances of that fact type. This meta
information may be queried at runtime by the engine and used in the reasoning
process.

8.7.4. Declaring New Types
To declare a new type, the keyword declare is used, followed by the list of fields and the keyword
end. A new fact must have a list of fields, otherwise the engine will look for an existing fact class in the
classpath and raise an error if not found.

8.7.5. Declaring New Fact Type Example
In this example, a new fact type called Address is used. This fact type will have three attributes:
number, streetName and city. Each attribute has a type that can be any valid Java type, including
any other class created by the user or other fact types previously declared:
declare Address
number : int
streetName : String
city : String
end

8.7.6. Declaring New Fact Type Additional Example
This fact type declaration uses a Person example. dateOfBirth is of the type java.util.Date
(from the Java API) and address is of the fact type Address.
declare Person
name : String
dateOfBirth : java.util.Date
address : Address
end

8.7.7. Using Import Example
To avoid using fully qualified class names, use the import statement:
import java.util.Date
declare Person
name : String
dateOfBirth : Date
address : Address
end

8.7.8. Generated Java Classes

110

CHAPTER 8. WORKING WITH RULES

When you declare a new fact type, Red Hat JBoss BRMS generates bytecode that implements a Java
class representing the fact type. The generated Java class is a one-to-one Java Bean mapping of the
type definition.

8.7.9. Generated Java Class Example
This is an example of a generated Java class using the Person fact type:
public class Person implements Serializable {
private String name;
private java.util.Date dateOfBirth;
private Address address;
// empty constructor
public Person() {...}
// constructor with all fields
public Person(String name, Date dateOfBirth, Address address) {...}
// if keys are defined, constructor with keys
public Person( ...keys... ) {...}
// getters and setters
// equals/hashCode
// toString
}

8.7.10. Using Declared Types in Rules Example
Since the generated class is a simple Java class, it can be used transparently in the rules like any other
fact:
rule "Using a declared Type"
when
$p : Person(name == "Bob")
then
// Insert Mark, who is Bob's manager.
Person mark = new Person();
mark.setName("Mark");
insert(mark);
end

8.7.11. Declaring Metadata
Metadata may be assigned to several different constructions in Red Hat JBoss BRMS, such as fact
types, fact attributes and rules. Red Hat JBoss BRMS uses the at sign (@) to introduce metadata and it
always uses the form:
@metadata_key(metadata_value)
The parenthesized metadata_value is optional.

8.7.12. Working with Metadata Attributes

111

Red Hat JBoss BPM Suite 6.4 Development Guide

Red Hat JBoss BRMS allows the declaration of any arbitrary metadata attribute. Some have special
meaning to the engine, while others are available for querying at runtime. Red Hat JBoss BRMS allows
the declaration of metadata both for fact types and for fact attributes. Any metadata that is declared
before the attributes of a fact type are assigned to the fact type, while metadata declared after an
attribute are assigned to that particular attribute.

8.7.13. Declaring Metadata Attribute with Fact Types Example
This is an example of declaring metadata attributes for fact types and attributes. There are two
metadata items declared for the fact type (@author and @dateOfCreation) and two more defined
for the name attribute (@key and @maxLength). The @key metadata has no required value, and so the
parentheses and the value were omitted:
import java.util.Date
declare Person
@author(Bob)
@dateOfCreation(01-Feb-2009)
name : String @key @maxLength(30)
dateOfBirth : Date
address : Address
end

8.7.14. @position Attribute
The @position attribute can be used to declare the position of a field, overriding the default declared
order. This is used for positional constraints in patterns.

8.7.15. @position Example
This is what the @position attribute looks like in use:
declare Cheese
name : String @position(1)
shop : String @position(2)
price : int @position(0)
end

8.7.16. Predefined Class Level Annotations
@role( )
This attribute can be used to assign roles to facts and events.
@typesafe()
By default, all type declarations are compiled with type safety enabled. @typesafe(false)
provides a means to override this behavior by permitting a fall-back, to type unsafe evaluation
where all constraints are generated as MVEL constraints and executed dynamically. This is useful
when dealing with collections that do not have any generics or mixed type collections.
@timestamp()
Creates a timestamp.
@duration()

112

CHAPTER 8. WORKING WITH RULES

Sets a duration for the implementation of an attribute.
@expires(

Navigation menu