-
Language:
English
-
Language:
English
BRMS Complex Event Processing Guide
For JBoss Administrators
Edition 5.3.1
Red Hat Content Services
Abstract
Preface
Chapter 1. Introduction
1.1. Introduction to Complex Event Processing
- 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
2.1. Events
- 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
@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
- @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
fact
orevent
as 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
@timestamp
tag.@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
@duration
tag.@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 oftimeOffset
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 theVoiceCall
facts 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
- 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
- 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
2.7. Cloud Mode
KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); config.setOption( EventProcessingOption.CLOUD );
drools.eventProcessingMode = cloud
2.8. Stream Mode
- 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
- 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
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
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
2.12.1. Temporal Reasoning
Note
2.12.2. Temporal Operations
2.12.2.1. Temporal Operations
- After
- Before
- Coincides
- During
- Finishes
- Finishes By
- Includes
- Meets
- Met By
- Overlaps
- Overlapped By
- Starts
- Started By
2.12.2.2. After
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
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
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
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
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
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
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
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
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
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
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
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
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
2.13.1. Sliding Time Windows
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
2.14.1. Memory Management for Events
- 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
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
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
Revision History | |||
---|---|---|---|
Revision 5.3.1-34.400 | 2013-10-31 | Rüdiger Landmann | |
| |||
Revision 5.3.1-34 | Mon Dec 03 2012 | L Carlon | |
|