BRMS Complex Event Processing Guide
For JBoss Administrators
Edition 5.3.1
Abstract
Preface
Chapter 1. Introduction Copy linkLink copied to clipboard!
1.1. Introduction to Complex Event Processing Copy linkLink copied to clipboard!
- 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 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
- They usually process large numbers of events, but only a small percentage of the events are of interest.
- 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.
- 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).
Chapter 2. Features of JBoss BRMS Complex Event Processing Copy linkLink copied to clipboard!
2.1. Events Copy linkLink copied to clipboard!
- 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
- 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.
2.2. Event Declaration Copy linkLink copied to clipboard!
@role meta-data tag to the fact with the event parameter. The @role meta-data 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.
StockTick fact type will be handled as an event:
Example 2.1. Declaring a Fact Type as an Event
import some.package.StockTick
declare StockTick
@role( event )
end
StockTick was a fact type declared in the DRL instead of in a pre-existing class, the code would be as follows:
Example 2.2. Declaring a Fact Type and Assigning it to an Event Role
declare StockTick
@role( event )
datetime : java.util.Date
symbol : String
price : double
end
2.3. Event Meta-Data Copy linkLink copied to clipboard!
- @role
- @timestamp
- @duration
- @expires
Example 2.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 meta-data tag indicates whether a given fact type is either a regular fact or an event. It accepts either
factoreventas a parameter. The default isfact.@role( <fact|event> )Example 2.4. Declaring VoiceCall as an 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
@timestamptag.@timestamp( <attributeName> )Example 2.5. Declaring the 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
@durationtag.@duration( <attributeName> )Example 2.6. Declaring the 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( <timeOffset> )The value oftimeOffsetis 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 theVoiceCallfacts should expire one hour and thirty-five minutes after insertion into the working memory, use the following:Example 2.7. Declaring the Expiration Offset for the VoiceCall Events
declare VoiceCall @role( event ) @timestamp( callDateTime ) @duration( callDuration ) @expires( 1h35m ) end
2.4. Session Clock Copy linkLink copied to clipboard!
- 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.
2.5. Available Clock Implementations Copy linkLink copied to clipboard!
- Real-time clock.
- This clock is based on the system clock. This is the default.
- Psuedo-clock.
- This clock is controlled by the application.
- Real-Time Clock
- The real-time clock is the default. 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:KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); 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:KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); config.setOption( ClockTypeOption.get("pseudo") );This example shows how to control the pseudo-clock:KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption( ClockTypeOption.get( "pseudo" ) ); StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession( 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 );
2.6. Event Processing Modes Copy linkLink copied to clipboard!
2.7. Cloud Mode Copy linkLink copied to clipboard!
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( EventProcessingOption.CLOUD );
drools.eventProcessingMode = cloud
2.8. Stream Mode Copy linkLink copied to clipboard!
- Events in each stream must be ordered chronologically.
- A session clock must be present to synchronize event streams.
Note
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
drools.eventProcessingMode = stream
2.9. Support for Event Streams Copy linkLink copied to clipboard!
- 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).
2.10. Declaring and Using Entry Points Copy linkLink copied to clipboard!
Example 2.8. Example 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
WithdrawRequest events coming from the "ATM Stream."
WithdrawalRequest) from the stream with a fact from the main working memory (CheckingAccount).
Example 2.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
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".
Example 2.10. Inserting Facts into an Entry Point
// create your rulebase and your session as usual
StatefulKnowledgeSession session = ...
// get a reference to the entry point
WorkingMemoryEntryPoint atmStream = session.getWorkingMemoryEntryPoint( "ATM Stream" );
// and start inserting your facts into the entry point
atmStream.insert( aWithdrawRequest );
2.11. Negative Pattern in Stream Mode Copy linkLink copied to clipboard!
Example 2.11. A Rule with a Negative Pattern
rule "Sound the alarm"
when
$f : FireDetected( )
not( SprinklerActivated( ) )
then
// sound the alarm
end
Example 2.12. A Rule with a Negative Pattern with Temporal Constraints
rule "Sound the alarm"
when
$f : FireDetected( )
not( SprinklerActivated( this after[0s,10s] $f ) )
then
// sound the alarm
end
2.12. Temporal Reasoning Copy linkLink copied to clipboard!
2.12.1. Temporal Reasoning Copy linkLink copied to clipboard!
Note
2.12.2. Temporal Operations Copy linkLink copied to clipboard!
2.12.2.1. Temporal Operations Copy linkLink copied to clipboard!
- After
- Before
- Coincides
- During
- Finishes
- Finishes By
- Includes
- Meets
- Met By
- Overlaps
- Overlapped By
- Starts
- Started By
2.12.2.2. After Copy linkLink copied to clipboard!
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.
$eventA : EventA( this after[ 3m30s, 4m ] $eventB )
$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.
3m30s <= $eventA.startTimestamp - $eventB.endTimeStamp <= 4m
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.
after operator also accepts negative temporal distances.
$eventA : EventA( this after[ -3m30s, -2m ] $eventB )
$eventA : EventA( this after[ -3m30s, -2m ] $eventB )
$eventA : EventA( this after[ -2m, -3m30s ] $eventB )
2.12.2.3. Before Copy linkLink copied to clipboard!
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.
$eventA : EventA( this before[ 3m30s, 4m ] $eventB )
$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.
3m30s <= $eventB.startTimestamp - $eventA.endTimeStamp <= 4m
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.
before operator also accepts negative temporal distances.
$eventA : EventA( this before[ -3m30s, -2m ] $eventB )
$eventA : EventA( this before[ -3m30s, -2m ] $eventB )
$eventA : EventA( this before[ -2m, -3m30s ] $eventB )
2.12.2.4. Coincides Copy linkLink copied to clipboard!
coincides operator correlates two events and matches when both events happen at the same time.
$eventA : EventA( this coincides $eventB )
$eventA and $eventB are identical and the end timestamps of both $eventA and $eventB are also identical.
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.
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.
$eventA : EventA( this coincides[15s, 10s] $eventB )
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 15s &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 10s
Warning
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.
2.12.2.5. During Copy linkLink copied to clipboard!
during operator correlates two events and matches when the current event happens during the event being correlated.
$eventA : EventA( this during $eventB )
$eventA starts after $eventB and ends before $eventB ends.
$eventB.startTimestamp < $eventA.startTimestamp <= $eventA.endTimestamp < $eventB.endTimestamp
during operator accepts one, two, or four optional parameters:
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.
2.12.2.6. Finishes Copy linkLink copied to clipboard!
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.
$eventA : EventA( this finishes $eventB )
$eventA starts after $eventB starts and ends at the same time as $eventB ends.
$eventB.startTimestamp < $eventA.startTimestamp &&
$eventA.endTimestamp == $eventB.endTimestamp
finishes 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 finishes[ 5s ] $eventB )
$eventB.startTimestamp < $eventA.startTimestamp &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s
Warning
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.
2.12.2.7. Finishes By Copy linkLink copied to clipboard!
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.
$eventA : EventA( this finishedby $eventB )
$eventA starts before $eventB starts and ends at the same time as $eventB ends.
$eventA.startTimestamp < $eventB.startTimestamp &&
$eventA.endTimestamp == $eventB.endTimestamp
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 )
$eventA.startTimestamp < $eventB.startTimestamp &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s
Warning
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.
2.12.2.8. Includes Copy linkLink copied to clipboard!
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.
$eventA : EventA( this includes $eventB )
$eventB starts after $eventA and ends before $eventA ends.
$eventA.startTimestamp < $eventB.startTimestamp <= $eventB.endTimestamp < $eventA.endTimestamp
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.
2.12.2.9. Meets Copy linkLink copied to clipboard!
meets operator correlates two events and matches when the current event ends at the same time as the correlated event starts.
$eventA : EventA( this meets $eventB )
$eventA ends at the same time as $eventB starts.
abs( $eventB.startTimestamp - $eventA.endTimestamp ) == 0
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.
$eventA : EventA( this meets[ 5s ] $eventB )
abs( $eventB.startTimestamp - $eventA.endTimestamp) <= 5s
Warning
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.
2.12.2.10. Met By Copy linkLink copied to clipboard!
metby operator correlates two events and matches when the current event starts at the same time as the correlated event ends.
$eventA : EventA( this metby $eventB )
$eventA starts at the same time as $eventB ends.
abs( $eventA.startTimestamp - $eventB.endTimestamp ) == 0
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.
$eventA : EventA( this metby[ 5s ] $eventB )
abs( $eventA.startTimestamp - $eventB.endTimestamp) <= 5s
Warning
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.
2.12.2.11. Overlaps Copy linkLink copied to clipboard!
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.
$eventA : EventA( this overlaps $eventB )
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp
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.
2.12.2.12. Overlapped By Copy linkLink copied to clipboard!
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.
$eventA : EventA( this overlappedby $eventB )
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp
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.
2.12.2.13. Starts Copy linkLink copied to clipboard!
starts operator correlates two events and matches when they start at the same time, but the current event ends before the correlated event ends.
$eventA : EventA( this starts $eventB )
$eventA and $eventB start at the same time, and $eventA ends before $eventB ends.
$eventA.startTimestamp == $eventB.startTimestamp &&
$eventA.endTimestamp < $eventB.endTimestamp
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 )
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
$eventA.endTimestamp < $eventB.endTimestamp
Warning
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.
2.12.2.14. Started By Copy linkLink copied to clipboard!
startedby operator correlates two events. It matches when both events start at the same time and the correlating event ends before the current event.
$eventA : EventA( this startedby $eventB )
$eventA and $eventB start at the same time, and $eventB ends before $eventA ends.
$eventA.startTimestamp == $eventB.startTimestamp &&
$eventA.endTimestamp > $eventB.endTimestamp
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 )
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
$eventA.endTimestamp > $eventB.endTimestamp
Warning
startsby operator does not accept negative intervals, and the rules engine will throw an exception if an attempt is made to use negative distance intervals.
2.13. Sliding Time Windows Copy linkLink copied to clipboard!
2.13.1. Sliding Time Windows Copy linkLink copied to clipboard!
StockTick() over window:time( 2m )
over keyword to associate windows with patterns.
Example 2.13. 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
SensorReading more than ten minutes old and keep re-calculating the average.
2.14. Memory Management for Events Copy linkLink copied to clipboard!
2.14.1. Memory Management for Events Copy linkLink copied to clipboard!
- 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.
2.14.2. Explicit Expiration Copy linkLink copied to clipboard!
declare statement and the metadata @expires tag.
Example 2.14. Declaring Explicit Expiration
declare StockTick
@expires( 30m )
end
StockTick events, remove any StockTick events from the session automatically after the defined expiration time if no rules still need the events.
2.14.3. Inferred Expiration Copy linkLink copied to clipboard!
Example 2.15. A 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
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.
Appendix A. Revision History Copy linkLink copied to clipboard!
| Revision History | |||
|---|---|---|---|
| Revision 5.3.1-34.400 | 2013-10-31 | ||
| |||
| Revision 5.3.1-34 | Mon Dec 03 2012 | ||
| |||