Drools / JBoss Rules in the medical field
by Nathan Bell
We are in the early stages of a project that will be using several
facets of the Drools platform. Based on our current research and
prototyping work we know we will use at least Drools Expert, and may end
up using all four components. I'm new to this user group, so I apologize
if the questions I am about to ask have been asked (and answered)
before. I did spend some time searching for these answers before I sent
this email if that helps any. J
1. I could not locate a forum for the Drools community. There seem
to be forums for a number of things here (http://community.jboss.org/),
but no forum for Drools. Am I missing something?
2. I spent some time today reading articles about the use of "Rule
Engines"/"Expert Systems"/"Complex Event Processing"/"CEP" in
healthcare. I found a few things, but I would like to find more data
about what people are actually doing in the medical/clinical field with
rules engines & CEP. Does anyone have any resources they can point me
to? Things like white papers, case studies, and research would be great.
Of particular interest to me are recent articles and information about
the use of Drools to build event driven systems for the healthcare
industry.
Thank You,
Nathan Bell
14 years, 10 months
Events facts in process constraints
by paulB
Hi,
I am starting out with RuleFlow this week. I have created a flow that uses
rules I had created in the past. The issue began when I tried to define a
Rule Constraint for a Split. The Fact I am referencing in that Rule
Constraint is defined as an Event fact in my rules file. When I attempt to
insert the fact into WorkingMemory (using ksession.insert(object);), I get
the error below. It appears to me that the fact is being inserted as
"default" fact, but somewhere along the chain it's interpreted as an Event
fact? Is this conflicts in the process' definition of the fact to the rule's
definition? Did I miss some tie-up between the rules and process? Is there
a way in the process to declare a fact as an event? Thanks!
Using Drools 5.0
RULE FILE SNIPPET:
package PostEventProcessor
...
import com.company.TrxQueueIn
...
declare TrxQueueIn
@role( event )
@timestamp( releaseTime )
end
...
RULE FLOW SNIPPET:
<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://drools.org/drools-5.0/process"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/drools-5.0/process
drools-processes-5.0.xsd"
type="RuleFlow" name="Post Event Processor post event"
id="PEPpostEvent" package-name="PostEventProcessor" >
<header>
<imports>
<import name="org.drools.runtime.process.WorkflowProcessInstance" />
<import name="com.company.TrxSurvey" />
<import name="com.company.TrxQueueIn" />
</imports>
<variables>
<variable name="SurveyComplete" >
<type
name="org.drools.process.core.datatype.impl.type.BooleanDataType" />
<value>false</value>
</variable>
<variable name="MaxAttempts" >
<type
name="org.drools.process.core.datatype.impl.type.BooleanDataType" />
<value>false</value>
</variable>
<variable name="trxDetail" >
<type
name="org.drools.process.core.datatype.impl.type.ObjectDataType"
className="com.sironahealth.database.intelliview.domain.TrxDetail" />
</variable>
<variable name="SurveyFlow" >
<type
name="org.drools.process.core.datatype.impl.type.StringDataType" />
</variable>
</variables>
</header>
<nodes>
<start id="1" name="Start" x="137" y="16" width="80" height="40" />
<ruleSet id="2" name="Max Attempts" x="137" y="88" width="80"
height="40" ruleFlowGroup="MaxAttempts" />
<ruleSet id="3" name="Reason Actions" x="54" y="232" width="117"
height="40" ruleFlowGroup="ReasonActions" />
<subProcess id="4" name="Next Survey" x="406" y="585" width="129"
height="40" processId="PEPSurevysBIO" >
<mapping type="in" from="trxDetail" to="trxDetail" />
</subProcess>
<split id="5" name="Survey Completed?" x="211" y="392" width="141"
height="40" type="2" >
<constraints>
<!-- THIS IS THE CONSTRAINT THAT GIVES ME PROBLEMS - SECOND LINE OF
RULE -->
<constraint toNodeId="10" toType="DROOLS_DEFAULT" name="Survey
Completed" priority="1" type="rule" dialect="mvel" >processInstance :
WorkflowProcessInstance()
TrxQueueIn(queueStatus == "CLO", trxDetail ==
(processInstance.getVariable("trxDetail"))) </constraint>
<constraint toNodeId="6" toType="DROOLS_DEFAULT" name="Survey Not
Complete" priority="2" type="rule" dialect="mvel" >eval(true)</constraint>
</constraints>
</split>
<end id="6" name="End" x="182" y="503" width="80" height="40" />
<end id="7" name="End" x="430" y="657" width="80" height="40" />
<end id="8" name="End" x="279" y="238" width="80" height="40" />
<split id="9" name="Max Attempts?" x="124" y="160" width="106"
height="40" type="2" >
<constraints>
<constraint toNodeId="8" toType="DROOLS_DEFAULT" name="Maxed"
priority="1" type="code" dialect="java" >return MaxAttempts;</constraint>
<constraint toNodeId="3" toType="DROOLS_DEFAULT" name="Not Maxed"
priority="1" type="code" dialect="java" >return !MaxAttempts;</constraint>
</constraints>
</split>
<actionNode id="10" name="Action" x="430" y="513" width="80" height="40"
>
<action type="expression" dialect="java" >SurveyFlow =
"PEPSurevysBIO";</action>
</actionNode>
<split id="11" name="Is Survey?" x="73" y="315" width="80" height="40"
type="2" >
<constraints>
<constraint toNodeId="12" toType="DROOLS_DEFAULT" name="Not a
survey" priority="2" type="rule" dialect="mvel" >eval(true)</constraint>
<constraint toNodeId="5" toType="DROOLS_DEFAULT" name="Surveyed"
priority="1" type="rule" dialect="mvel" >processInstance :
WorkflowProcessInstance()
TrxSurvey(trxDetail == (processInstance.getVariable("trxDetail"))
)</constraint>
</constraints>
</split>
<end id="12" name="End" x="18" y="396" width="80" height="40" />
</nodes>
<connections>
<connection from="1" to="2" />
<connection from="9" to="3" bendpoints="[113,179]" />
<connection from="10" to="4" />
<connection from="11" to="5" bendpoints="[280,335]" />
<connection from="5" to="6" bendpoints="[]" />
<connection from="4" to="7" />
<connection from="9" to="8" bendpoints="[317,181]" />
<connection from="2" to="9" />
<connection from="5" to="10" bendpoints="[467,412]" />
<connection from="3" to="11" />
<connection from="11" to="12" bendpoints="[59,335]" />
</connections>
</process>
STACK TRACE:
java.lang.ClassCastException: org.drools.common.DefaultFactHandle cannot be
cast to org.drools.common.EventFactHandle
at
org.drools.rule.SlidingTimeWindow.updateNextExpiration(SlidingTimeWindow.java:192)
at
org.drools.rule.SlidingTimeWindow.assertRightTuple(SlidingTimeWindow.java:119)
at
org.drools.rule.BehaviorManager.assertRightTuple(BehaviorManager.java:87)
at org.drools.reteoo.JoinNode.assertObject(JoinNode.java:153)
at
org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:360)
at
org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:344)
at org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:147)
at
org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:360)
at
org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:337)
at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:185)
at org.drools.reteoo.EntryPointNode.assertObject(EntryPointNode.java:146)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:1046)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:1001)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:788)
at
org.drools.impl.StatefulKnowledgeSessionImpl.insert(StatefulKnowledgeSessionImpl.java:216)
--
View this message in context: http://n3.nabble.com/Events-facts-in-process-constraints-tp187826p187826....
Sent from the Drools - User mailing list archive at Nabble.com.
14 years, 10 months
CEP Question
by Glenn Macgregor
Hi All,
I am still working through a CEP use case which is going fairly well. I have a few rules and it seems they are working as I expect. Is there a way to get called back when events go out of a time window? My current use case is alerting, I have a stream of events (param updates) coming in and I create a ParamUpdateEvent for each. I have a rule which averages the values in the ParamUpdateEvent and tests against a threshold, that is working fine. The problem is when I don't receive any events for a period of time over the window size I really want to the rule which calculates the average to fire when anything is moved out of the window as well as when an update arrives, is this possible?
Thanks
Glenn
14 years, 10 months
Out Of Memory with static Rulebase
by James Williams
Hi,
I hope someone can help me with this.
I are running Drools 5.0.0.CR1 using JANINO to compile a spreadsheet
into rules. I have lots of tests that prove the compilation is working
properly and the rules are correct.
Every now and then (twice in two months) we have had the following
exception start appearing and the rules stop working at all. The error
occurs after the system has been running for a while and at a point in
the application that has been visited many many times before the error
appears.
Caused by: java.lang.OutOfMemoryError
2010-02-16 02:28:38,143 ERROR [STDERR] at
java.util.zip.ZipFile.open(Native Method)
2010-02-16 02:28:38,143 ERROR [STDERR] at
java.util.zip.ZipFile.<init>(ZipFile.java:203)
2010-02-16 02:28:38,143 ERROR [STDERR] at
java.util.jar.JarFile.<init>(JarFile.java:132)
2010-02-16 02:28:38,143 ERROR [STDERR] at
java.util.jar.JarFile.<init>(JarFile.java:97)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org
.apache
.catalina.loader.WebappClassLoader.openJARs(WebappClassLoader.java:1724)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org
.apache
.catalina
.loader.WebappClassLoader.findResources(WebappClassLoader.java:991)
2010-02-16 02:28:38,143 ERROR [STDERR] at
java.lang.ClassLoader.getResources(ClassLoader.java:1015)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org.drools.util.ChainedProperties.getResources(ChainedProperties.java:
155)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org.drools.util.ChainedProperties.<init>(ChainedProperties.java:79)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org.drools.util.ChainedProperties.<init>(ChainedProperties.java:41)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org.drools.util.ChainedProperties.<init>(ChainedProperties.java:35)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org.drools.SessionConfiguration.init(SessionConfiguration.java:112)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org.drools.SessionConfiguration.<init>(SessionConfiguration.java:106)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org
.drools
.reteoo
.ReteooStatelessSession.newWorkingMemory(ReteooStatelessSession.java:86)
2010-02-16 02:28:38,143 ERROR [STDERR] at
org
.drools
.reteoo.ReteooStatelessSession.execute(ReteooStatelessSession.java:185)
2010-02-16 02:28:38,143 ERROR [STDERR] at
com
.base2
.ecm.just.service.product.LocalRulesEngine.apply(LocalRulesEngine.java:
49)
2010-02-16 02:28:38,143 ERROR [STDERR] at
com
.base2
.ecm
.just
.service
.product
.PublishingDetailsServiceImpl
.getPublishingDetails(PublishingDetailsServiceImpl.java:41)
Here is the code:
private static RuleBase ruleBase;
public void apply(PublishingDetails publishingDetails,
Advertisement advertisment)
{
StatelessSession statelessSession = getStatelessSession();
statelessSession.setGlobal("du",new DateUtils());
Object[] facts = {publishingDetails, advertisment};
statelessSession.execute(facts);
}
public void apply(Publication publication)
{
StatelessSession statelessSession = getStatelessSession();
statelessSession.setGlobal("du",new DateUtils());
statelessSession.execute(publication);
}
private StatelessSession getStatelessSession()
{
if (ruleBase == null)
{
initRuleBase();
}
StatelessSession statelessSession =
ruleBase.newStatelessSession();
return statelessSession;
}
private void initRuleBase()
{
Properties properties = new Properties();
properties.setProperty("drools.dialect.java.compiler",
"JANINO");
PackageBuilderConfiguration conf = new
PackageBuilderConfiguration(properties);
PackageBuilder builder = new PackageBuilder(conf);
try
{
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(getSpreadsheetStream(),
InputType.XLS);
builder.addPackageFromDrl(new StringReader(drl));
}
catch (DroolsParserException e)
{
throw new RuntimeException("DroolsParserException when
parsing the drools package", e);
}
catch (IOException e)
{
throw new RuntimeException("IOException when loading the
drools package", e);
}
PackageBuilderErrors errors = builder.getErrors();
if (errors != null && !errors.isEmpty())
{
for (KnowledgeBuilderError error : errors)
{
LOG.error(error.getMessage());
}
throw new RuntimeException("There were errors in the drl
file");
}
Package pkg = builder.getPackage();
ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(pkg);
}
As I said before the loading of the rules is OK. I'm wondering if
keeping a static reference to the RuleBase might be the issue?
The exception looks like Drools is trying to load a jar file at
runtime. Maybe there is a problem with the container (Jboss 4.2.2)?
If someone could confirm that I'm not doing anything wrong by keeping
a static reference to the RuleBase that would be appreciated. Note
that the system runs perfectly and then starts throwing this exception
with no apparent pattern to the failure.
Cheers
James
14 years, 10 months
Accessing rule flow names
by J Michael Dean
To do testing, I have an event listener that keeps track of which nodes have been activated, etc. by accessing the ProcessNodeEvent where I can either get the NodeID or the NodeName, but cannot get the associated rule flow. The NodeID appears to be numeric and always automatically assigned, so perhaps I should be tracking these values, but I had hoped to keep track of which RuleFlowGroup was activated. Is there a way to access this variable?
Thanks.
- Mike
14 years, 10 months
Is Drools the right choice for my use case?
by Tong Wang
I'll use a university's library system to explain my use case. Students
register in the library system and provide their profile: gender, age,
department, previously completed courses, currectly registered courses,
books already borrowed, etc. Each book in the library system will define
some borrowing rules based on students' profile, for example, a textbook for
the computer algorithm can only be borrowed by students currently registered
with that class; another textbook may only be borrowed by students in the
math department; there could also be rules such that students can only
borrow 2 computer networking book at most. As a result of the borrowing
rules, when a student searches/browses in the library system, he will only
see the books that can be borrowed by him. So, the requirement really comes
down to the line of efficiently generating the list of books that a student
is eligible to borrow.
Here is how I vision the design using Drools - each book will have a rule
with a few field constraints on the student profile as LHS, the RHS of the
book rule simply adds the book id to a global result list, then all the book
rules are loaded into a RuleBase. When a student searches/browsers the
library system, a stateless session is created from the RuleBase and the
student's profile is asserted as the fact, then every book that the student
can borrow will fire its book rule and you get the complete list of books
that the students can borrow in the global result list.
A few assumptions: the library will handle millions of books; I don't
expect the book rule be too complicated, 3 simple field constraints for each
rule on average at the most; the number of students that the system needs to
handle is in the range of 100K, so the load is fairly heavy. My questions
are: how much memory will Drools take if loaded with a million book rules?
How fast will it be for all those million rules to fire? If Drools is the
right fit, I'd like to hear some best practices in designing such a system
from you experienced users. Thanks.
14 years, 10 months
Triggers on Start node
by paulB
I have created a start node in my RuleFlow as follows:
<start id="1" name="Start" x="171" y="16" width="80" height="40">
<triggers>
<trigger type="event">
<eventFilters>
<eventFilter type="eventType"
eventType="SurveyCompleted" />
</eventFilters>
</trigger>
</triggers>
</start>
I'm additionally using the following code snippet in RHS of a rule:
drools.getKnowledgeRuntime().signalEvent( type, eventData );
Works great, but I am unsure how to get eventData and assign it to a
variable in the started process. I see there is an element under <trigger>:
<mapping type="in" from="something" to="SomeVar" />
However, I am unsure if this is the element to use. If so, what would be
the appropriate value in the "from" attribute?
Thanks!
--
View this message in context: http://n3.nabble.com/Triggers-on-Start-node-tp209420p209420.html
Sent from the Drools - User mailing list archive at Nabble.com.
14 years, 10 months
Rules writing best practice?
by Brice Figureau
Hi,
Is there a rules writing best practice document somewhere?
I'm asking the question because as a newbie rule writer (which doesn't
know anything about the underlying drools matching algorithm), I'm
wondering if my rules will behave gracefully.
For instance, I (ab)use a lot the from/accumulate to bring in the
knowledge some external facts coming from some DAO.
All my rules use one time or more the same "from
dao.getInformationFromDatabase( <inserted fact> )" structure and I'm not
sure the algorithm is smart enough to cache this information which is
constant for a given inserted fact.
Should I instead insert all this information as facts prior to the rules
firing?
--
Brice Figureau
My Blog: http://www.masterzen.fr/
14 years, 10 months
"not contains" on Java5 enumeration
by Ray Ploski
I'm not certain, but it looks like the Operator "not contains"[1] works
fine with strings but not Enumerations. Would someone please confirm or
correct the rule syntax? Thank you.
Given:
rule "Absence_Accumulation_Rule"
when
$slice : TimeSlice(
classifiers contains(TimeSliceClassifiers.ABSENCE),
classifiers contains(TimeSliceClassifiers.OT),
classifiers not contains (TimeSliceClassifiers.COUNT_TO_FLSA),
then
System.out.println("Absence: Count to overtime but not FLSA");
end
public enum TimeSliceClassifiers {
INSIDE_SCHEDULE,
OUTSIDE_SCHEDULE,
WORKED,
ABSENCE,
APPROVED,
OVERTIME_REQUEST,
CASH,INVOLUNTARY,
COUNT_TO_OT,
COUNT_TO_FLSA,
OT,
STRAIGHT,
PREMIUM,
EC0100,
EC1400,
EC1405
}
public class TimeSlice {
private Date start;
private Date end;
private int elapsed;
private Set<TimeSliceClassifiers> classifiers;
private boolean sliceCreatedByRules = false;
}
Provides the following error:
[ERR 103] Line 110:21 rule 'in_key' failed predicate:
{(validateIdentifierKey(DroolsSoftKeywords.IN))}? in rule
"Absence_Accumulation_Rule" in pattern TimeSlice
14 years, 10 months