Reputation: 3288
I have the following POJO:
public class Transaction {
@Id
private long id;
private String organisationId;
private String resposibleName;
private DateTime transactionTime;
private BigDecimal amount;
...
}
that I would like to apply my rules to. For example, a sample rule might be on its amount:
rule "SampleRule"
when
$transaction : Transaction( amount > 10)
then
$transaction.setStatus(Status.INVALID);
end
and I also want to apply some more complex rules such as:
WHEN
the sum of amount fields of Transactions per same organisationId
within the last week (based on transactionTime
) is greaten than x
, THEN
$transaction.setStatus(Status.INVALID);
WHEN
there is a past transaction with same responsibleName
as the current transaction being evaluated, but different organisationId
than the current one, THEN
$transaction.setStatus(Status.INVALID);
When there's a query being made to a RESTful endpoint:
KieSession
Transaction
object to the session,PastTransaction
as the exact copy with the same fields with Transaction
, I am adding multiple transactions made by the same organisationId
with PastTransaction
POJO so that I can accumulate amount field on those while being able to apply more elementary rules on my Transaction
object.responsibleName
with ResponsibleNameTransaction
POJO, and write a rule to check if any of these is not equal to the one of my single Transaction
object in the KieSession
.I was wondering if there might be an easier/more optimal way to achieve what I have been doing, and optimizing per which entity I am forming my KieSession
s for. I have though of writing methods to my Transaction
POJO and hit the db within the rule execution (e.g. write a method getAllTransactionsByTheResponsibleName
which returns a list, then check if there's an object with different organisationId
). In a same way I can add related transactions as a list to KieSession
then query the list within the rule, which might at least save me from using the same POJO under different names.
Update:
Elaborating further based on comments, would that be feasible to keep about a billion Transaction
s in working memory (a session for all transactions)? Or alternatively, I can put transactions per responsible/organisation into KieSession
(session per responsible/organisation). Then how can I apply some rules solely on the fields of the latest transaction being evaluated (or even set a field on it) when there are multiple transactions in session (e.g. $transaction.setStatus(Status.INVALID);
when #1 is true, $transaction
being the one that is currently evaluated)?
Upvotes: 0
Views: 688
Reputation: 31300
It may not be possible to let your non-techies romp completely unaided. A full discussion of what you may have to add would require full knowledge of all the rules, which I don't have. However, #1 and #2 from your Q can be handled even with billions of Transactions passing through your Working Memory.
Use case 1: Checking for a threshold per account in a time range can be done by keeping an auxiliary fact ("AccountSums") per account with n daily sums. With any new Transaction, either update the last sum, or "shift" sums adding 0 sums and set last sum, or create new AccountSums; maintain total of last n sums- The techies can write the check based on just AccountSums (or in combination with the (last) matching Transaction.
rule "check 7 days limit"
when
$t: Transaction( $orgId: organisationId,
$transT: transactionTime,
amount > 0, status == Status.VALID )
AccountSums( organisationId == $orgId,
lastTransactionTime == $transT,
runningWeeklySum > 1000000 )
then
modify( $t ){ setStatus( Status.INVALId ) }
end
rule "create AccountSums"
when
$t: Transaction( $orgId: organisationId,
amount > 0 )
not AccountSums( organisationId == $orgId )
then
insert( new AccountSums( $orgId ) );
end
You'll need at least one additional rule for "shifting" the sums, etc.
Use case 2: Maintain an auxiliary fact ("NameId"), with instances containing a responsible name and an organisationId (or a single instance containing a Map.) If another Transaction arrives, create a new NameId (or Map entry), or compare for equal and not equal Id.
History must be condensed if the volume of your data is as you indicate. It may be possible to let the boffins write simple evaluation rules, but devising rule patterns along the lines I've outlined here is, at least for condensing the meta-data, not something you can leave to the Muggles.
Upvotes: 1