The rules you add in this section work together as follows:
When a Debit
event is asserted into the Rete
network, TIBCO BusinessEvents® Extreme
checks rules with the Debit
event in their scope.
The ApplyDebit
rule has the
Debit
event and the Account
concept in its scope. It’s priority 1 so it will execute before any
other lower priority rule based on rule conditions. A query on account
identifier is done in the ApplyDebit
rule condition
to try to find an account with the identifier specified in a
Debit
event. If the account is found, it is
asserted into the Rete network, making it available for rule
execution.
If an Account instance whose identifier matches the
identifier in the debit event is found, the
ApplyDebit
rule executes if the account is not
Disabled
. The account balance is debited and a
history concept is recorded to track that a debit has
occurred.
If the Rete network does not contain a matching
Account
instance because the query in the
ApplyDebit
rule condition did not find the
account, then other rules in the agenda — those that have
Debit
or AccountOperations
events in their scope — are eligible to execute.
InvalidAccount
is the only rule with the
AccountOperations
event in its scope, and no
account, so it is eligible and it executes. It sends a message to
the console that no matching account is found.
The CheckBalance
rule has an
Account
concept in its scope. When an account is
debited the Account
concept is changed, and so the
CheckBalance
rule becomes newly
true. The effect is similar to assertion of a new concept
into the Rete Network. If the debit has made the account balance zero,
this rule sets the status to Disabled
.
It’s important to understand how conflict resolution and run to completion (RTC) cycles work. If you understand what triggers rules to execute, and why a rule may not execute, you can design rules more effectively. For a reminder, carefully reread Understanding Conflict Resolution and Run to Completion Cycles in TIBCO BusinessEvents® Extreme Application Architect’s Guide.
![]() | |
See Run-time Inferencing Behavior in TIBCO BusinessEvents® Extreme Application Architect’s Guide. |
If you have completed the section called “Add the DuplicateAccountCheck Rule” and the section called “Add the CreateAccount Rule”, you will be familiar with adding rules. This section shows the source code for the three rules you will add.
The main purpose for showing the form view is so you can compare it with the source view when creating your own rule.
Example 2.1. ApplyDebit Rule Source View Code
// $Revision: 1.1.4.7 $ /** * @description Debit the matching account by the specified amount. */ rule Rules.ApplyDebit { attribute { priority = 1; forwardChain = true; } declare { Events.Debit debit; Concepts.Account account; } when { Account.lookupByIdentifier("write", debit.identifier) != null; account.status != "Disabled"; Instance.isModified(account) == false; } then { // // Remove all old history objects for this account older than 2 minutes // Object results = History.lookupByAccount("read", "ascending", account.identifier, null); DateTime now = DateTime.now(); Concepts.History history = Query.next(results); Double debitSum = 0; while (history != null) { if ((DateTime.getTimeInMillis(now) - DateTime.getTimeInMillis(history.at)) > 120000) { System.debugOut( "INFO: Removing expired history for " + account.identifier + ". History amount is " + history.amount); Instance.deleteInstance(history); history = Query.next(results); continue; } debitSum = debitSum + history.amount; history = Query.next(results); } // // Create a history object and debit the account // history = Concepts.History.History( "", debit.amount, DateTime.now(), account.identifier); // // Update the recent debit sum for this account // account.recentDebitBalance = debitSum + debit.amount; // // Maximum debit is current balance // long newBalance = account.balance - debit.amount; long debitAmount = debit.amount; if (newBalance > 0) { account.balance = newBalance; } else { debitAmount = account.balance; account.balance = 0; } System.debugOut( "INFO: Debited account " + account.identifier + " by $" + debitAmount + ". New balance is $" + account.balance); } }
Example 2.2. InvalidAccount Rule Source View Code
// $Revision: 1.1.4.4 $ /** * @description Reports account not found message for debit */ rule Rules.InvalidAccount { attribute { priority = 10; forwardChain = true; } declare { Events.AccountOperations accountoperations; } when { Account.lookupByIdentifier("none", accountoperations.identifier) == null; } then { System.debugOut("WARNING: Account " + accountoperations.identifier + " not found."); // // All done // Event.consumeEvent(accountoperations); } }
Example 2.3. CheckBalance Rule Source View Code
// $Revision: 1.1.4.3 $ /** * @description Disable an account with zero balance. */ rule Rules.CheckBalance { attribute { priority = 4; forwardChain = true; } declare { Events.Debit debitevent; Concepts.Account account; } when { account.balance == 0; account.status != "Disabled"; } then { // // Disable the account // account.status = "Disabled"; System.debugOut("WARNING: " + account.identifier + " account balance is zero."); } }