Rules Manager is a feature of Oracle Database that uses the Expression Filter and object relational features to provide the features of a special-purpose rules engine with greater scalability and better operational characteristics.
Rules Manager uses the following terminology:
An event structure is an object (abstract) type that is defined with a set of attributes that describes the specific features of an event. For example, it is the data structure that captures the customer flight information, using variables, such as Airline, Customer Id, From City, and so forth. The object type definition of the AddFlight event structure is as follows:
TYPE AddFlight AS OBJECT ( CustId NUMBER, Airline VARCHAR2(20), FromCity VARCHAR2(30), ToCity VARCHAR2(30), Depart DATE, Return DATE);
AddFlight (123, 'Abcair', 'Boston', 'Orlando', '01-Apr-2003', '08-Apr-2003'); AddFlight (234, 'Acbair', 'Chicago', 'San Jose', '01-Aug-2003', '10-Aug-2003'); AddFlight (345, 'Acbair', 'New York', 'San Jose', '22-Jun-2003', '24-Jun-2003');
Events are classified into two types:
Primitive event - represents an event that is assumed to be instantaneous and atomic in an application. A primitive event cannot be further broken down into other events and it either occurs completely or not at all. Each primitive event is typically bound to a specific point in time and the rules defined for the corresponding event structure can be fully evaluated with the event. For example, the
AddFlight event is an example of a primitive event:
AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return)
Composite event - represents the combination of two or more primitive events. All primitive events included in the composite event can be bound to a time window and thus generated at different points in time. So the rules defined for the composite event structure cannot be fully evaluated until all the corresponding primitive events are generated. For example, adding a second primitive event AddRentalCar to the AddFlight primitive event creates a composite event:
AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) AddRentalCar (CustId, CarType, Checkout, Checkin, Options)
Because evaluation of rules for composite event structures must be deferred until all parts of a composite event are available, Rules Manager provides several ways of efficiently evaluating composite events.
See Chapter2 for more information about composite events and complex rule applications.
ON AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) IF Airline = 'Abcair', and ToCity = 'Orlando' THEN OfferPromtion (CustId, 'RentalCar', 'Acar') ON AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) IF Airline = 'Acbair', and ToCity = 'Houston' THEN OfferPromtion (CustId, 'RentalCar', 'Bcar') ON AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) IF ToCity = 'Orlando' and Return-Depart >7 THEN OfferPromtion (CustId, 'ThemePark', 'Ocean World')
Rules are evaluated for an instance of the corresponding event structure. For example, the following event is used to evaluate the rules defined using the
AddFlight event structure:
AddFlight (123, 'Abcair', 'Boston', 'Orlando', '01-Apr-2003', '08-Apr-2003');
The rule condition, which is a conditional expression that is formed using the attributes defined in the event structure. For example, this is a rule condition using the attributes: Airline, ToCity, Return, and Depart:
Airline = 'Abcair' and ToCity = 'Orlando' and Return-Depart >= 7
Typically, the actions associated with rules in the rule class are homogenous. For example, if a rule class is used to determine the discount offered during a checkout process, each rule in the class is associated with a specific discount percentage. For rules that match an event instance, these values are used to determine the appropriate action for the rule.
Action preferences can come in different forms, such as:
A list of literals that are bound as arguments to the common procedure, such as:
'RentalCar', 'Acar', 'Bcar',...
Dynamic PL/SQL commands, such as:
BEGIN OfferRentalPromotion(:1,'Acar'); END;
An action callback procedure is a procedure that acts as an entry point for executing actions for all the rules in a rule class. This procedure is implemented to execute the action for each rule in the rule class based on the action preferences associated with the rule and the event attributes. For the previous example, the action callback procedure can be implemented to invoke the OfferPromotion procedure with the appropriate arguments.
A results view configures a rule class for external action execution when the actions for each matching rule cannot be executed by means of an action callback procedure, such as applications that span multiple tiers.
The rules matching an event are available by querying this preconfigured view and the corresponding actions can be executed by the component issuing the query. This is useful when the action for certain rules is implemented in the application on multiple tiers. See Chapter2 for more information.
The results from a rule evaluation are available through the results view until the end of the rule session. By default, the database session (from connect to disconnect) is considered the rule session. Alternatively, the reset session procedure (
dbms_rlmgr.reset_session( )) can be used to end a rule session and start a new session within a database session. Note that at the beginning of a rule session, the results view is empty.
Rule class properties define the event management policies that Rules Manager enforces for each rules application. Two main policies discussed in this chapter are consumption and conflict resolution. Consumption refers to whether an event can be used for multiple rule executions or for just a single rule execution (see Chapter3). Conflict resolution, or ordering, determines the order in which matching rules with various events are to be executed (see Chapter3). Chapter2 and Chapter 3 describe the complete set of event management policies that Rules Manager supports.
Rules Manager uses a relational table to hold the contents of a rule class with each row in the table representing a rule. The rule class table minimally has three columns, one for rule identifiers (
rlm$ruleid), one for rule conditions (
rlm$rulecond), and one for the description of the rule (
rlm$ruledesc). In addition, the rule class table can have one or more columns to store rule action preferences.
Figure 2-1 shows a database representation of the TravelPromotion rule class and its rules for processing the AddFlight event instances.
The TravelPromotion rule class consists of the following columns:
rlm$ruleid -- contains the unique rule identifier that identifies each rule within a rule class.
rlm$rulecond -- contains the rule condition describing each rule; in this case, the rule condition, when satisfied, allows the promotion specified to be offered.
PromoType -- contains one action preference that is used when the rule condition is satisfied, and in each case, the action callback procedure is called that executes the actions for the rules in the rule class; in this case, the type of promotion to be offered, such as a car rental promotion or hotel stay promotion is stored in this column. This value is used by the PromoAction action callback procedure to invoke the OfferPromotion procedure with the appropriate arguments.
OfferedBy -- contains another action preference that is associated with the previous action preference column; in this case, it contains the name of the company offering the promotion.
rlm$ruledesc -- contains a description of the rule in plain text provided by the person defining the rule.
An ECA rule is stored in a row of the TravelPromotion rule class table. The event structure, defined as an object type in the database, is associated with the rule condition column and this provides the necessary vocabulary for the rule conditions (stored in the column). The event structure, the rule class table, and the action callback procedure are all created as part of rule class creation.
Once all the rules are added to the rule class, events are ready to be processed and rules evaluated. At runtime, each rule in the rule class is processed against each instance of the event structure. When a rule evaluates to true for a particular event, the
PromoAction action callback procedure calls the designated
OfferPromotion procedure using rule action preferences to execute the prescribed action of offering a specific type of promotion from a particular vendor. Rules Manager enforces various event management policies, such as conflict resolution when an event matches more than one rule, or immediate event consumption when the first match is found and no further evaluation is necessary. These and other event management policies are described in more detail in Chapter 3.
Chapter2, Chapter2, and Chapter2 describe the process of creating rules applications that use a simple event, that span multiple tiers, and that use composite events, respectively. Though the basic five steps are the same for all three cases, the details vary, and some additional steps are necessary for multiple tier applications.
AddFlight example, the event structure is defined as:
CREATE TYPE AddFlight AS OBJECT ( CustId NUMBER, Airline VARCHAR2(20), FromCity VARCHAR2(30), ToCity VARCHAR2(30), Depart DATE, Return DATE);
Create the rule class for the event structure.
Note:For successful creation of a rule class, you should have sufficient privileges to create views, object types, tables, packages, and procedures.
For this example, create the
TravelPromotion rule class for the
AddFlight event structure and define the
OfferedBy columns as its action preferences. This procedure takes the name of the rule class, the name of the existing event structure created in Step 1, the name of the action callback procedure, and the action preference specification as arguments. The action preferences specification defines the data types of action preferences that are associated with each rule in the rule class.
BEGIN dbms_rlmgr.create_rule_class ( rule_class => 'TravelPromotion', event_struct => 'AddFlight', action_cbk => 'PromoAction', actprf_spec => 'PromoType VARCHAR2(20), OfferedBy VARCHAR2(20)'); END;
Rule class creation creates a table to store the corresponding rule definitions and action preferences. The rule class table uses the same name as the rule class and it is created in the user's schema. The rule class table defines three columns to store the rule identifiers, rule descriptions, and the rule conditions. In this example, the table also creates the rule action preferences columns specified with the previous command to store the action preferences.
TABLE TravelPromotion ( rlm$ruleid VARCHAR2(100), rlm$rulecond VARCHAR2(4000), rlm$ruledesc VARCHAR2(1000), PromoType VARCHAR2(20), OfferedBy VARCHAR2(20));
You can query the table to see the rules defined in the rule class as well as perform SQL INSERT,
DELETE operations to add, update, and delete rules.
Rule class creation implicitly creates the skeleton for a callback procedure to perform the action. The action callback procedure acts as an entry point for executing actions for all the rules in the rule class. The action callback is called once for every rule that matches an event. The implementation of the action callback procedure can rely on values in the event instance and the action preferences associated with the matching rule.
PROCEDURE PromoAction (rlm$event AddFlight, rlm$rule TravelPromotion%ROWTYPE) is BEGIN null; --- The action for the matching rules can be performed here. --- The appropriate action can be determined from the event --- instance and the action preferences associated with each rule. END;
The action callback procedure, in this case, is created with the name the user provides and has two arguments:
The event as an instance of the corresponding object type.
The action preferences as a ROWTYPE of the corresponding rule class table. The %ROWTYPE attribute provides a record type that represents a row in a table.
Replace the system-generated callback procedure with the user implementation to perform the appropriate action for each matching rule. The following action callback procedure can be implemented to invoke the
OfferPromotion procedure with arguments obtained from the event instance and the rule definition:
For this example,
PROCEDURE PromoAction ( rlm$event AddFlight, rlm$rule TravelPromotion%ROWTYPE) is BEGIN OfferPromotion (rlm$event.CustId, rlm$rule.PromoType, rlm$rule.OfferedBy); END;
In this example, the procedure
OfferPromotion performs the action and each matching rule provides the appropriate action preferences. Appendix G shows alternate ways for implementing the action callback procedure for a different choice of action preferences.
Add rules to the rule class.
Adding rules consists of using the
SQL INSERT statement to add a row for each rule. Each row inserted typically contains a rule identifier, a condition, and values for action preferences. The following rule is inserted into the
INSERT INTO TravelPromotion (rlm$ruleid, PromoType, OfferedBy, rlm$rulecond) VALUES ('UN_AV_FL', 'Rental Car', 'Acar', 'Airline= ''Abcair'' and ToCity = ''Orlando'' and Return-Depart >= 7');
Process the rules for an event.
dbms_rlmgr.process_rules( ) procedure to process the rules in a rule class for an event instance. Processing the rules consists of passing in an event instance as a string of name-value pairs (generated using the
getVarchar( ) procedure) or as an AnyData instance for an event consisting of binary data types as described in Chapter10. Recall that the Oracle supplied
getVarchar( ) method is used to represent the data item as string-formatted name-value pairs when this is possible and that
AnyData is an Oracle supplied object type that can hold instances of any Oracle data type, both Oracle supplied and user-defined.
The following example processes the rules in the
TravelPromotion rule class for an
AddFlight event instance using the
getVarchar( ) function.
BEGIN dbms_rlmgr.process_rules ( rule_class => 'TravelPromotion', event_inst => AddFlight.getVarchar(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003')); END;
The following example processes the rules in the
TravelPromotion rule class for an
AddFlight event instance using the
AnyData.ConvertObject( ) procedure.
BEGIN dbms_rlmgr.process_rules ( rule_class => 'TravelPromotion', event_inst => AnyData.convertObject(AddFlight(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003'))); END;
The previous command processes the rules in the
TravelPromotion rule class for an
AddFlight event instance and performs the action associated with each matching rule through the action callback procedure.
Probably the more common types of rules applications are those that use a composite event structure that combines two or more primitive events. Evaluating rule classes for composite events creates additional requirements. Rules Manager addresses these requirements by:
Aggregating events for rule execution
When two or more primitive events are brought together, each primitive event may be generated by the application at different points in time. This often means a rule cannot be evaluated conclusively until all the primitive events are available. Rules Manager manages the primitive events and joins them together before evaluating the rules. Rules Manager hides the complexity of managing composite events by maintaining the association between the primitive events and the composite event. See Chapter 4 for more information.
Maintaining intermediate state of event processing
When composite events are completely formed in the user application, some parts of rule conditions may need to be evaluated repeatedly with some parts of the composite events. This may lead to multiple evaluations of one primitive event for each instance of a second primitive event, and so forth to find matching rules. This evaluation becomes complex very quickly as the number of primitive events exceeds two. XML tags support incremental evaluation of rules for composite events resulting in Rules Manager improving the performance of the system. Rules Manager maintains the intermediate state of rule evaluation persistently for efficient processing. See Chapter4 for more information.
Supporting complex rule constructs
Rules Manager enables you to build complex rules with negation, Any n, and Set semantics in conditional expressions. Using XML tags within rule conditions, Rules Manager can support these complex rule constructs that are commonly used in applications. See Chapter 4 for more information.
The basic steps to create a rules application with composite events are the same as those described for simple events in Chapter2, with accommodations for multiple primitive events.
The steps to create a rules application with composite events are as follows:
Create the composite event structure as an object type in the database.
First, each primitive event structure is created as an object type. For example:
CREATE or REPLACE TYPE AddFlight AS OBJECT ( CustId NUMBER, Airline VARCHAR2(20), FromCity VARCHAR2(30), ToCity VARCHAR2(30), Depart DATE, Return DATE); CREATE or REPLACE TYPE AddRentalCar AS OBJECT ( CustId NUMBER, CarType VARCHAR2(20), CheckOut DATE, CheckIn DATE, Options VARCHAR2(30));
Next, all the primitive event structures that constitute the composite event are created as (first level) embedded types in this object type. For example:
CREATE or REPLACE TYPE TSCompEvent AS OBJECT (Flt AddFlight, Car AddRentalCar);
The attribute names,
Car, are used in the rule conditions for identifying the predicates on individual primitive events and for specifying join conditions between primitive events;
Car are the primitive event variables used for composite events.
Create the rule class for the composite event structure. The rule class is configured for composite events using an XML properties document that is assigned to the properties argument of the
BEGIN dbms_rlmgr.create_rule_class ( rule_class => 'CompTravelPromo', event_struct => 'TSCompEvent', action_cbk => 'CompPromoAction', rslt_viewnm => 'CompMatchingPromos', actprf_spec => 'PromoType VARCHAR2(20), OfferedBy VARCHAR2(20)', rlcls_prop => '<composite/>'); END;
The previous code example creates the rule class for the composite event structure. The
rlcls_prop argument specifies the default settings for composite event management using an empty
<composite> XML element. This step re-creates each object type representing a primitive event structure to include a timestamp attribute,
rlm$CrtTime, which captures the corresponding event creation times. This attribute is created with the
TIMESTAMP data type and its value is defaulted to the database timestamp (
SYSTIMESTAMP) at the time of event instantiation. Alternately, an application can explicitly set an event creation time by assigning a valid timestamp value to this attribute.
As previously mentioned, this rule class creation also creates the action callback procedure with the specified name as follows:
PROCEDURE CompPromotion (Flt AddFlight, Car AddRentalCar, rlm$rule CompTravelPromo%ROWTYPE) is BEGIN null; --- The action for the matching rules can be performed here. --- The appropriate action can be determined from the event --- instance and the action preferences associated with each rule. END;
Note:The primitive events within the composite events are passed in as separate arguments to the callback procedure.
Replace the system generated action callback procedure with the user implementation to perform the appropriate action for each matching rule. For example:
PROCEDURE CompPromoAction (Flt AddFlight, Car AddRentalCar, rlm$rule CompTravelPromo%ROWTYPE) is BEGIN OfferPromotion (Flt.CustId, rlm$rule.PromoType, rlm$rule.OfferedBy); END;
Add the rules to the rule class. In this case, add a rule with a conditional expression that uses XML tags. See Chapter4 for more information about using XML tag extensions in rule conditions to support complex rule constructs.
INSERT INTO CompTravelPromo (rlm$ruleid, PromoType, OfferedBy, rlm$rulecond) VALUES ('UN-HT-FL', 'RentalCar', 'Acar', '<condition> <and join="Flt.CustId = Car.CustId"> <object name="Flt"> Airline=''Abcair'' and ToCity=''Orlando'' </object> <object name="Car"> CarType = ''Luxury'' </object> </and> </condition>');
Process the rules using one primitive event at a time. For example:
BEGIN dbms_rlmgr.process_rules ( rule_class => 'CompTravelPromo', event_inst => AnyData.ConvertObject( AddFlight(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003'))); dbms_rlmgr.process_rules ( rule_class => 'CompTravelPromo', event_inst => AnyData.ConvertObject( AddFlight(567, 'Abdair', 'Boston', 'Miami', '03-APR-2003', '09-APR-2003'))); dbms_rlmgr.process_rules ( rule_class => 'CompTravelPromo', event_inst => AnyData.ConvertObject( AddRentalCar(987, 'Luxury', '03-APR-2003', '08-APR-2003', NULL))); END;
This command adds three primitive events to the Rules Manager. For the rule defined in Step 4, the first event matches the primitive rule condition for the
AddFlight event and the third event matches the condition for the
AddRentalCar event. Additionally, these two events satisfy the join predicate in the rule condition. So for the previous example, the first and last primitive events together form a composite event that matches the rule condition specified in Step 4. These primitive event instances are passed to the action callback procedure for action execution. The type information for the primitive events that is passed in is embedded in the corresponding
AnyData instance. However, when a string-formatted event is used, the primitive event type information should be explicitly passed in as follows:
BEGIN dbms_rlmgr.process_rules ( rule_class => 'TravelPromotion', event_type => 'AddFlight', event_inst => AddFlight.getVarchar(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003')); END;
Incremental evaluation of rules by allowing predicate joins between and among primitive events
Negation in rule conditions to raise exceptions in processes (that is, when something does not happen, do something)
Sequencing in rule conditions by tracking primitive event creation time and enforcing or detecting sequencing among events
Set semantics in rule conditions to allow instances of primitive events of the same type to be monitored as a group
Any n in rule conditions to allow matching of a subset of primitive events
Rules Manager supports incremental evaluation of rules involving composite events. To support complex rule conditions, the conditional expressions in the SQL
WHERE clause are extended with some XML tags that identify different parts of a conditional expression and add special semantics to these expressions. Chapter 4 describes more about each type of complex rule condition. Chapter4 describes implementing incremental evaluation of rules.
Consumption -- determines if an event can be used for multiple rule executions or a single rule execution
Conflict resolution or ordering -- determines the order in which matching rules with various events are to be executed
Duration -- determines the lifetime of unconsumed primitive events
Auto-commit -- determines if each interaction with a rule class should be committed automatically
Storage -- determines the storage characteristics of the rule class in the database
Equal -- specifies the common equality join predicates for all the rules in a rule class, that is, what are the lists of primitive event attributes that are equal in the composite events configured for a rule class
DML Events -- specifies when an event structure is created with one or more table alias attributes, that the corresponding rule class should consider the data manipulation language (DML) operations (
INSERT) on the corresponding tables as the events for which the rules are evaluated
Rule class properties are specified at the time of rule class creation using an XML properties document that is assigned to the
rlcls_prop argument of the
dbms_rlmgr.create_rule_set( ) procedure. For rule classes configured for composite events these properties can be specified at the composite event level (for all the primitive events). In addition, you can specify overrides for one or more primitive events in the properties document. Chapter3 through Chapter3 describe each of these rules properties in more detail and how each is implemented.
For rules applications that span multiple tiers and where rule management is handled in the database, but the action execution for the rules is handled in the application server, the actions for the rules matching an event cannot be invoked from an action callback procedure. Instead, a results view is populated with the events and the matching rules, both of which are available for external action execution. The results view can be queried to determine the rules that match an event and their corresponding actions can then be executed.
To handle rules applications with certain rules having their action execution occurring on the application server, you must also configure the rule class for external execution (in addition to configuring the action callback procedure). The steps to do this are similar to those described in Chapter2, but are modified and briefly described as follows (see Chapter 5 for a complete description of each step):
Create the event structure as an object type in the database (same as Step 1 in Chapter2).
Create the rule class and also define the results view. See Step 2 in Chapter5 for the details.
Implement the action callback procedure (same as Step 3 in Chapter2).
Add rules to the rule class (same as Step 4 in Chapter2).
Identify the matching rules for an event. Use the add event procedure (
dbms_rlmgr.add_event( )) that adds each event to the rule class one at a time and identifies the matching rules for a given event that is later accessed using the results view. See Step 5 in Chapter5 for the details.
Find the matching rules by querying the results view. See Step 6 in Chapter5 for the details.
Consume the event that is used in a rule execution. See Step 7 in Chapter5 for the details.
SQL*Loader can be used to bulk load data from an ASCII file into a rule class table. For the loader operations, the rule conditions stored in the
rlm$rulecond column of the rule class table are treated as strings loaded into a
VARCHAR2 column. The data file can hold the XML and SQL based rule conditions in any format allowed for VARCHAR2 data and the values for the action preference columns in the rule class table are loaded using normal SQL*Loader semantics.
The data loaded into the rule condition column is automatically validated using the event structure associated with the rule class. The validation is done by a trigger defined on the rule condition column, due to which, a direct load cannot be used while loading rule definitions into a rule class table.
A rules application defined using a set of event structures and a rule class can be exported and imported back to the same database or a different Oracle database. A rule class in a schema is automatically exported when the corresponding rule class table is exported using the export command's (
tables parameter or when the complete schema is exported. When a rule class is exported, definitions for the associated primitive and composite event structures and the rules defined in the rule class are all placed in the export dump file. However, the internal database objects that maintain the information about event instances and incremental states for partially matched rules are not exported with the rule class. When the
tables parameter is used to export a particular rule class, the implementation for the action callback procedure is not written to the export dump file. The action callback procedure is only exported with the schema export.
The dump file created with the export of a rule class can be used to import the rule class and its event structures into the same or a different Oracle database. At the time of import, the internal database objects used for the rule class state maintenance are re-created. Due to the order in which certain objects are created and skipped in an import session, the rule class creation raises some errors and warnings that can be safely ignored. In the case of a schema level import of the rule class, the implementation for action callback procedure is also re-created on the import site However, in the case of a table-level import, only the skeleton for the action callback procedure is created.