BPM Events rules have the ability to process any event, whether generated from a business process or from an external source. We will call an "external event" any event that, unlike events of type BP Server::PI_ACTIVATED above, is not directly generated by the process execution, but rather reflects some change in the business context (for example, a sales promotion) or the state of a resource needed by the process (for example, the load of a server, the quantity of a product in stock, the price of a commodity). Usually, such events are generated by third party systems.
Let us assume that, in the order provisioning system, some products may be out of stock for an estimated period of time counted in business days. When this happens, the concerned customers should be immediately notified of the estimated delay, and proposals for a substitute product, if any, should be sent. It is assumed that an event of type Alarm::ProductOutOfStock is generated by the inventory system when a product is out of stock.
We can then use the following rule, named notify_if_out_of_stock, to capture such an event:
rule notify_if_out_of_stock
activated by
event1 of Alarm::ProductOutOfStock,
event2 of BP Server::PI_ACTIVATED {PROCESSTEMPLATE NAME : "PurchaseOrder"}
if (event1.product = event2.product)
then {
sendMail(event2.customeremail, "customerService@ACME.com",
"notification of delay",
"Sorry, your order may be late of " + event1.estimateddelay +
" days, due to inventory shortage of product: " + event1.product +
" . Would you like to order instead:" + event1.productalternative );
}
In fact, the rule above is activated by two events: one of type Alarm::ProductOutOfStock, and one of type BP Server::PI_ACTIVATED. We say that such a rule correlates two events. In this case, the correlation is done based on the product name that these events relate to. Note that events may also carry business data in their attributes, like product name, product alternative, and estimated delay.
The plain English version of the above rule is:
"On reception of an event of type Alarm and value ProductOutOfStock, if an event of type BP Server and value PI_ACTIVATED of PurchaseOrder business process that relates to the same product is present in the event log, then send an e-mail notification to the corresponding customer about the delay and possible alternative."
The rule detects all pairs of events that satisfy the correlation condition. Any time an event of the type: Alarm::ProductOutOfStock is generated, the rule correlates this alarm with all current customer orders that are concerned by this product. Each time a successful correlation is found, the rule automatically repeats its action statement for the corresponding customer, which is sending an e-mail.
Please note that:
The same rule can handle the shortage of any product,
When triggered by an event—for example, Alarm::ProductOutOfStock—, the rule is able to sort through past events, and select those events that correlate successfully with it.
Once the rule has identified the "out-of-stock" event, and sent mail to all customers concerned by the defaulting product, the same rule is now also triggered by all future customer orders as soon as they appear in the system (events of type BP Server::PI_ACTIVATED {PROCESSTEMPLATE NAME : "PurchaseOrder"}), and treats them similarly. Indeed, the rule above can also read:
"On reception of an event of type BP Server and value PI_ACTIVATED of PurchaseOrder business process, if an event of type Alarm and value ProductOutOfStock that relates to the same product is present in the event log, then send an e-mail notification to the corresponding customer, about the delay and possible alternative."
In other words, the order of the event profiles listed in the "activated by" clause does not matter. The rule may actually trigger on any of the event profiles. Each time a new customer order is activated, the rule tries to correlate its activation event with an alarm event of type Alarm::ProductOutOfStock.
As long as the alarm event (of type Alarm::ProductOutOfStock)has not been explicitly discarded from the event store (which may happen once the inventory is back to normal), the rule succeeds in correlating each new customer order with such an alarm, and generates an e-mail if the ordered product matches the out-of-stock event.
When the inventory level of a product is back to normal, it is sufficient to remove the alarm event for this product. We will define another rule, named stock_back_to_normal, to implement the reception of a "back-to-normal" event.
rule stock_back_to_normal
activated by
event1 of Alarm::ProductInvNormal,
event2 of Alarm::ProductOutOfStock
if (event2.product = event1.product)
then { discard (event1, event2); }
The rule above is also doing correlation, this time for correlating the "inventory back-to-normal" event (of type Alarm::ProductInvNormal) with any previous out-of-stock event for the same product. Once the correlation succeeds, both events are discarded, and the previous rule notify_if_out_of_stock will be unable to trigger successfully (and therefore will not notify customers anymore) for this product.
Important: The rules above do not require dynamic adding or removal depending on the inventory status. They are always there: they activate only if the right combination of events occurs. These events then automatically reflect any change in the inventory status, and further adding or removing of rules is not required. This example also shows how important it is for an application to manage the set of events properly, that is, decides when used events are discarded from the event store.