[rules-users] Question about the Nature of Ruleflows
BenjaminWolfe
benjamin.e.wolfe at gmail.com
Tue Aug 21 17:14:14 EDT 2012
Thanks Wolfgang.
My original post was a conceptual analogy. But this still isn't working
right for me, so I've written out a full-fledged example to see if you or
anyone else can help. The full example is behaving exactly the way my real
(important) code is -- which is the wrong way for the business application.
:-/ I should add that in real life, the ruleflow groups each have multiple
rules within them.
So without further ado, here's my code -- two POJOs, a bpmn file, a rule
resource, and a test class -- along with the expected output and actual
output.
*User.java*
package com.examples.ruleflow;
public class User {
private int id;
public User() {}
public User(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
*Dog.java*
package com.examples.ruleflow;
public class Dog {
private int id;
private int ownerId;
private boolean hasDogTag;
public Dog() {}
public Dog(int id) {
this.id = id;
}
public int getId() {
return id;
}
public int getOwnerId() {
return ownerId;
}
public boolean isHasDogTag() {
return hasDogTag;
}
public void setId(int id) {
this.id = id;
}
public void setOwnerId(int ownerId) {
this.ownerId = ownerId;
}
public void setHasDogTag(boolean hasDogTag) {
this.hasDogTag = hasDogTag;
}
}
*dog_owner_flow.bpmn*
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="Definition"
targetNamespace="http://www.jboss.org/drools"
typeLanguage="http://www.java.com/javaTypes"
expressionLanguage="http://www.mvel.org/2.0"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
BPMN20.xsd"
xmlns:g="http://www.jboss.org/drools/flow/gpd"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:tns="http://www.jboss.org/drools">
<process processType="Private" isExecutable="true"
id="com.examples.ruleflow.dogProcess" name="Dog Owner Process"
tns:packageName="com.examples.ruleflow" tns:version="1" >
<startEvent id="_1" name="StartProcess" />
<exclusiveGateway id="_2" name="Gateway" gatewayDirection="Diverging" />
<businessRuleTask id="_3" name="Branch A" g:ruleFlowGroup="flowA"
></businessRuleTask>
<businessRuleTask id="_4" name="Branch B" g:ruleFlowGroup="flowB"
></businessRuleTask>
<exclusiveGateway id="_5" name="Gateway" gatewayDirection="Converging"
/>
<endEvent id="_6" name="End" ><terminateEventDefinition/></endEvent>
<sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
<sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" name="dog tags
OK" tns:priority="1" >
<conditionExpression xsi:type="tFormalExpression"
language="http://www.jboss.org/drools/rule" >
/$u : User()
not ( Dog( ownerId == $u.id, hasDogTag == false ) )/
</conditionExpression>
</sequenceFlow>
<sequenceFlow id="_2-_4" sourceRef="_2" targetRef="_4" name="dog tag
issue" tns:priority="1" >
<conditionExpression xsi:type="tFormalExpression"
language="http://www.jboss.org/drools/rule" >
/$u : User()
exists ( Dog( ownerId == $u.id, hasDogTag == false ) )/
</conditionExpression>
</sequenceFlow>
<sequenceFlow id="_3-_5" sourceRef="_3" targetRef="_5" />
<sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5" />
<sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6" />
</process>
<bpmndi:BPMNDiagram>
<bpmndi:BPMNPlane bpmnElement="com.examples.ruleflow.dogProcess" >
<bpmndi:BPMNShape bpmnElement="_1" >
<dc:Bounds x="16" y="16" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_2" >
<dc:Bounds x="180" y="15" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_3" >
<dc:Bounds x="42" y="162" width="80" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_4" >
<dc:Bounds x="296" y="162" width="80" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_5" >
<dc:Bounds x="180" y="306" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_6" >
<dc:Bounds x="188" y="384" width="48" height="48" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_1-_2" >
<di:waypoint x="40" y="40" />
<di:waypoint x="204" y="39" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-_3" >
<di:waypoint x="204" y="39" />
<di:waypoint x="82" y="186" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_2-_4" >
<di:waypoint x="204" y="39" />
<di:waypoint x="336" y="186" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_3-_5" >
<di:waypoint x="82" y="186" />
<di:waypoint x="204" y="330" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_4-_5" >
<di:waypoint x="336" y="186" />
<di:waypoint x="204" y="330" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_5-_6" >
<di:waypoint x="204" y="330" />
<di:waypoint x="212" y="408" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
*dog_owners.drl*
package com.examples.ruleflow
rule "sample A"
ruleflow-group "flowA"
no-loop true
dialect "mvel"
when
$u : User()
then
System.out.println("User " + $u.id + " took branch A.");
end
rule "sample B"
ruleflow-group "flowB"
no-loop true
dialect "mvel"
when
$u : User()
then
System.out.println("User " + $u.id + " took branch B.");
end
*DogTest.java*
package com.examples.ruleflow;
import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;
/import java.util.List;
import java.util.ArrayList;/
public class DogTest {
public static final void main(String[] args) {
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger =
KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
/// create and insert facts
List<User> users = new ArrayList<User>();
List<Dog> dogs = new ArrayList<Dog>();
users.add(new User(0));
dogs.add(new Dog(0));
dogs.get(0).setOwnerId(1);
dogs.get(0).setHasDogTag(true);
dogs.add(new Dog(1));
dogs.get(1).setOwnerId(0);
dogs.get(1).setHasDogTag(true);
users.add(new User(1));
dogs.add(new Dog(2));
dogs.get(2).setOwnerId(1);
dogs.get(2).setHasDogTag(true);
dogs.add(new Dog(3));
dogs.get(3).setOwnerId(1);
dogs.get(3).setHasDogTag(true);
dogs.add(new Dog(4));
dogs.get(4).setOwnerId(1);
dogs.get(4).setHasDogTag(false);
for (User u:users) {
ksession.insert(u);
}
for (Dog d:dogs) {
ksession.insert(d);
}/
// start a new process instance
/ksession.startProcess("com.examples.ruleflow.dogProcess");
ksession.fireAllRules();/
logger.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
/kbuilder.add(ResourceFactory.newClassPathResource("dog_owners.drl"),
ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("dog_owner_flow.bpmn"),
ResourceType.BPMN2);/
return kbuilder.newKnowledgeBase();
}
}
*/Expected/ Console Output...*
User /0/ took branch /A/.
User /1/ took branch /B/.
*/Actual/ Console Output...*
User /1/ took branch /A/.
User /0/ took branch /A/.
laune wrote
>
> On 21/08/2012, BenjaminWolfe <benjamin.e.wolfe@> wrote:
>> I'm trying to wrap my mind around the nature of ruleflows -- and I think
>> this
>> question sums up a bit of my confusion.
>>
>> I have a stateful knowledge session. The stateful knowledge session has
>> a
>> ruleflow associated with it. That ruleflow diverges into two branches --
>> branch A and branch B -- based on a rule constraint. It's an XOR, and
>> the
>> mvel rule constraints are something like this:
>>
>> to branch A
>> $u : User( $i : userId )
>> exists ( Dog( owner == $i, hasDogTag == false) )
>>
>> to branch B
>> $u : User( $i : userId )
>> not ( Dog( owner == $i, hasDogTag == false) )
>>
>> Then the two branches converge again. I insert two facts: user 1, whose
>> dogs all have dog tags, and user 2 whose third dog is missing a tag.
>> Then,
>> after I insert both facts, I fire all rules.
>
> If you don't insert any Dogs, only the condition for branch B is true,
> since there no Dogs at all, tag or no tag.
>
> If you insert Dogs according to your statement, both conditions are
> true, A for user 2 and B for user 1 (which is not what you describe
> below, but I think this is an oversight).
>
> Anyway, a "flow" will not cycle automatically if there are several
> fact groups, with some of them requiring this or that processing. To
> notify Users with untagged dogs, a simple rule with the conditions
> you've posted and with a consequence notifying the user would be
> sufficient.
>
> For an overall decision between "there are tagless dogs" and "all dogs
> are tagged" you'd need conditions like these:
>
> exists( Dog( hasDogTag == false) )
>
> not( Dog( hasDogTag == false) )
>
> -W
>
>
>>
>> Should the flow be like this?
>>
>> user 1: start --> diverge --> branch A (tell him to buy dog tags) -->
>> converge --> end
>> user 2: start --> diverge --> branch B (leave him alone) --> converge -->
>> end
>>
>> Or does a ruleflow look at the whole session rather than each fact -- in
>> which case either both users would pass through branch A, or both would
>> pass
>> through branch B?
>>
>> If I want the first case to happen, is there something I'm missing in the
>> implementation? And are there any more details I can add to make my post
>> more specific? Thank you for your help.
>>
>>
>>
>> --
>> View this message in context:
>> http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292.html
>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>> _______________________________________________
>> rules-users mailing list
>> rules-users at .jboss
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
> _______________________________________________
> rules-users mailing list
> rules-users at .jboss
> https://lists.jboss.org/mailman/listinfo/rules-users
>
--
View this message in context: http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292p4019325.html
Sent from the Drools: User forum mailing list archive at Nabble.com.
More information about the rules-users
mailing list