[rules-users] Using Drools Flow with Multiple Fact Types

Jason Jason.sroka at healthrageous.com
Mon Oct 24 20:19:08 EDT 2011


I'm a relatively new user to Flows, but I have worked with a colleague to
instantiate flows that control a sequence of rule sets being applied to a
set of data in a meaningful order (e.g. I do pruning to limit the set of
facts as a first step, then generate sets of hypotheses, then score the
hypotheses and select the highest-scoring instance as a winner), so I do
have some experience and a baseline working Flow that is successfully
operating.

My next big challenge is to try to use Drools Flow to control which sets of
rules will be applied to which subsets of data - this goes beyond the uses I
have put it to before, which was just to control the single ordering of rule
sets that was then applied to all data.

My question has to do with the syntax of fact constraints used for
controlling flow, and how to control the flow using constraints that reflect
data characteristics when there are many different fact types that will be
going through the Flow.  I will use an analogy to the actual problem to make
it a little simpler to describe.

What I want to do is to apply different rules based on the Program that a
particular Customer belongs to.  If a customer is part of Program A, then I
want to apply RuleSet A, and if the Customer belongs to Program B then I
want to apply a different set of rules, RuleSet B.  

My problem is twofold:

1.)  I have not been able to demonstrate constraints working as I expected,
even when I simplified the data flow to its most basic form.  The 'debug'
version of the flow that I created has a diverging OR gateway (specifically
OR, not an XOR gateway) with two criteria; the first is always true and
therefore all instances should result in an instance of LogStatementA, and
the second one has a constraint on the UserID associated with the customer
and thereby limits the set that should be exposed to a rule that generates
an instance of LogStatementB:  "Customer(userId > 100)" as an example of
something I've tried, where any Customers with a UserID above 100 would then
trigger an instance of both LogStatementA and LogStatementB, while customers
with a UserID <= 100 would only trigger an instance of LogStatementA.

What I find is that if I set the constraint such that at least one Customer
instance in the data should trigger the selection, then ALL of the instances
of Customer in the data end up triggering an instance of LogStatementB (even
those instances that do not individually meet the constraint), while if I
set the constraint such that none of the Customer instances meets it, I get
zero instances of LogStatementB.  In both cases, I get an instance of
LogStatementA for each Customer (as expected).

I don't understand why the existence of a single match to the Flow Control
rule (Customer(userId>100)) would trigger all instances of Customers
(including those with UserID's less than 100) to be routed to that path,
while having no matching instances correctly avoids sending any Customers
down this path.

Is there a common type of error that I might have perpetrated that would
cause this?  I have tried a variety of combinations of the Type: and
Dialect: settings, though intuitively it seems like Type: Rule and
Dialect:mvel are correct given that I'm formulating the constraint as
"Customer(userId>100)".  Also, if I introduce a typo in either the Customer
or userId elements of the rule, I get errors that make it clear the POJO for
this constraint is definitely being correctly imported.

2.)  Assuming there is a fix to the underlying issue I'm seeing in #1, I
will want to extend this example so that I am pushing more than just
instances of Customer through my Flow.  In particular, the rules that i want
to expose the data to after the diverging gateway represent different
flavors of the same type of logic, so what I want in the end is for all
Customer facts to be sent either one way or the other, and all non-Customer
facts to be sent BOTH ways.  This will allow me, for instance, to apply
different thresholds to customers depending on which Program they are part
of.

I first formulated an attempt at the control rule for this as:
Customer(userId>100) or not Customer
with the idea that if the data coming through the flow is an instance of a
Customer, then I want the constraint to be applied to determine if it
proceeds down this flow, but if the data is not an instance of Customer then
I always want it to proceed down the path (e.g. all Account instances, all
RewardThreshold instances, etc.).  

Is this a valid way to expect to use Drools Flow?  In the examples I've
seen, there is only a single type of object that is going through a flow -
am I breaking the spirit of Drools Flow in trying to get multiple types of
facts flowing through?

Assuming I'm not committing heresy in this basic desire of what I'm trying
to do, is there an example anywhere of what the appropriate syntax for this
kind of constraint would/could be?  Any of the variants I have tried (and
believe me, I've tried a bunch) have resulted in parsing errors (often of
the "unmatched then" or "unmatched (" sort when the flow is initially read
in).  Can anyone point me to an example of a flow where multiple types of
facts are sent through?  In fact, any pointers to examples of the syntax
that has been used within the Constraint Editor Textual Editor field could
help a lot in illustrating how to apply this element of Drools Flow control.

Any help or guidance will be greatly appreciated!

-Jason


--
View this message in context: http://drools.46999.n3.nabble.com/Using-Drools-Flow-with-Multiple-Fact-Types-tp3449939p3449939.html
Sent from the Drools: User forum mailing list archive at Nabble.com.



More information about the rules-users mailing list