from within accumulate <src regex pattern>
That is *not* true. The engine is consistent. Wherever you have a pattern,
you can write any kind of constraint, does not matter if the pattern is
nested in an accumulate, it it is a top level pattern, or whatever.
You have a different problem there. It is not the literal constraint for
sure.
Edson
2010/4/13 Badrinath, Shyam <sbadrinath(a)sonusnet.com>
Hi
I figured out how to make the <src regex pattern> in ‘accumulate’ match the
criteria I am interested in. In the example below, I was matching against a
literal string from within ‘accumulate’, but apparently that doesn’t work.
Instead, if I give it as follows:
$c: Cpu(srcIp == '10.155.21.86' && destIp == '10.6.35.120')
$cpuMin: Number(intValue >=80) from accumulate(Cpu(srcIp == $c.srcIp &&
destIp == $c.destIp, $val:value) over window:time(5s), min($val)
)
So, it looks like it binds a subset of the Cpu objects that match the
criteria to $c and then we need to use that variable to compare against,
within our accumulate function.
I guess the rule engine doesn’t allow matching against literal strings from
within accumulate <src regex pattern>
$cpuMin: Number(intValue >=80) from accumulate(Cpu(srcIp == ’10.155.21.86’
&& destIp == ’10.6.35.120’, $val:value) over window:time(5s), min($val)
Also, is it possible to configure the firing policy in the first sliding
window as you suggested below?
Thanks
Shyam
------------------------------
*From:* Badrinath, Shyam
*Sent:* Monday, April 12, 2010 1:26 PM
*To:* 'Rules Users List'
*Subject:* RE: [rules-users] drools-fusion: rule firing erroneously for
thefirst time in a sliding window
Hi Edson
Thanks for the clarification. The sliding window implementation does wait
for 5s, later on during a test, before activating the rule. So,
theoretically, there shouldn’t be any difference in behavior, even at the
beginning, whether the clock is in pseudo or real mode.
Lets assume t(0) is the start, then nothing should fire atleast until
t(0+5) and it should be the same for the window between t(n) and t(n+5).
Also, I noticed that the accumulate function seems to ignore the regex in
the <src pattern>. For example, given the rule below, if I insert Cpu events
with no matching srcIp and destIp, then I would expect no rule to fire,
since the window would look at only the Cpu objects in working memory that
match the criteria below. Am I missing something?
$cpuMin : Number(intValue >= 80) from accumulate(
$cpu : Cpu($v : value, srcIp ==’<val1>’ && destIp == ‘<val2>’) over
window:time(5s), min($v)
------------------------------
*From:* rules-users-bounces(a)lists.jboss.org [mailto:
rules-users-bounces(a)lists.jboss.org] *On Behalf Of *Edson Tirelli
*Sent:* Monday, April 12, 2010 12:10 PM
*To:* Rules Users List
*Subject:* Re: [rules-users] drools-fusion: rule firing erroneously for
thefirst time in a sliding window
Hi,
Yes, the current implementation for sliding time windows does not wait
for a window to move before starting to fire rules. As soon as the
constraint is met, it will activate the rule. The question is: should the
sliding window delay before firing? should it be configurable?
I need to do some research on that. Comments are welcome.
Edson
2010/4/12 Badrinath, Shyam <sbadrinath(a)sonusnet.com>
Hi
I am using Drools 5.1.0 M1 within Eclipse. I am trying out a sample rule,
which fires if the minimum cpu is over 80 for 5s using sliding windows. I
see that it works well over a running window of 5s, but for the first time,
it fires even before reaching 5s.
It seems to ignore the fact that 5s hasn’t elapsed yet. I am using the
engine in STREAM mode and using a pseudo clock to advance the time manually.
Is this the expected behavior? Thanks!
sb
Here is the rule:
package org.drools.examples
import org.drools.examples.CpuMetric.Cpu;
import org.drools.examples.CpuMetric.Alarm;
global org.apache.log4j.Logger logger
declare Cpu
@role(event)
@expires(5s)
end
rule "Above Cpu threshold of 80 for 5s"
dialect "java"
when
not Alarm()
$cpuMin : Number(intValue >= 80) from accumulate(
$cpu : Cpu($v : value) over window:time(5s), min($v)
)
then
logger.info("Cpu above 80 for 5 s, raising alarm. min cpu:
"+$cpuMin);
Alarm a = new Alarm();
a.setReason("raised alarm as we hit cpu threshold");
a.setTime(System.currentTimeMillis());
insert(a);
end
Here is the snippet of the class that declares the Cpu and Alarm class as
well inserts events into the rule engine. The other thing I noticed is the
accumulate function seems to ignore the regex in the <src pattern>. For
example, in the rule above, if I give
$cpuMin : Number(intValue >= 80) from accumulate(
$cpu : Cpu($v : value, srcIp ==’<val1>’ && destIp == ‘<val2>’) over
window:time(5s), min($v)
And insert cpu events, with no matching srcIp and destIp, I shouldn’t see
any alarm raised, but I do and right at the beginning.
. . ... (code before this..)
//to use sliding windows, have to run the engine in stream mode
//default is cloud mode..where there are no concept of time and
//event ordering
KnowledgeBaseConfiguration kbaseconfig =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kbaseconfig.setOption(EventProcessingOption.STREAM);
// add the packages to a knowledgebase (deploy the knowledge
packages).
KnowledgeBase kbase =
KnowledgeBaseFactory.newKnowledgeBase(kbaseconfig);
kbase.addKnowledgePackages(pkgs);
KnowledgeSessionConfiguration conf =
KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
conf.setOption(ClockTypeOption.get("pseudo"));
StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession(conf, null);
//get clock to manually advance and test firing..
SessionPseudoClock clock = ksession.getSessionClock();
logger.info("Pseudo clock current time: "+clock.getCurrentTime());
ksession.setGlobal("logger", logger);
ksession.addEventListener(new DebugAgendaEventListener());
ksession.addEventListener(new DebugWorkingMemoryEventListener());
// setup the audit logging
KnowledgeRuntimeLogger krlogger = KnowledgeRuntimeLoggerFactory
.newFileLogger(ksession, "log/cpu");
BufferedReader bf = new BufferedReader(new
FileReader("/opt/cpumetricdata.txt"));
String s;
long time=0;
int count=0;
long lastime=0;
int delta=0;
//logger.info("Advancing 5s right at the start");
//clock.advanceTime(5000, TimeUnit.MILLISECONDS);
while((s = bf.readLine()) != null)
{
String[] vals = s.split(",");
Cpu cpumetric = new Cpu();
cpumetric.setValue(Integer.parseInt(vals[1]));
//set in ms
//for the first time, initialize time and lastime
//to the value read in from the first line.
time = Long.parseLong(vals[0]);
if(count ==0)
{
lastime = time;
logger.info("Initialized lastime to "+lastime);
}
cpumetric.setTime(time);
cpumetric.setSrcIp("10.155.21.86");
cpumetric.setDestIp("10.6.35.120");
logger.info("Inserted cpu metric "+cpumetric);
logger.info("Count: "+count+" Pseudo clock current time:
"+clock.getCurrentTime());
ksession.insert(cpumetric);
ksession.fireAllRules();
//advance based on the read in time in ms
//do it only from the second insert onwards
delta=(int) (time-lastime);
if(count >=1)
{
clock.advanceTime(delta, TimeUnit.MILLISECONDS);
logger.info("Pseudo clock advanced "+delta+ "ms");
}
count++;
lastime=time;
}
System.out.println("Inserted facts, current time is "+new Date());
krlogger.close();
ksession.dispose();
bf.close();
}
public static class Alarm
{
private String reason;
private long time;
private String type;
/**
* @return the reason
*/
public String getReason()
{
return reason;
}
/**
* @param reason the reason to set
*/
public void setReason(String reason)
{
this.reason = reason;
}
/**
* @return the time
*/
public long getTime()
{
return time;
}
/**
* @return the type
*/
public String getType()
{
return type;
}
/**
* @param type the type to set
*/
public void setType(String type)
{
this.type = type;
}
/**
* @param time the time to set
*/
public void setTime(long time)
{
this.time = time;
}
}
public static class Cpu implements Serializable
{
private long time;
private int value;
private String srcIp;
private String destIp;
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return "Cpu [time=" + time + ", value=" + value +
"]";
}
/**
* @return the time
*/
public long getTime()
{
return time;
}
/**
* @param time the time to set
*/
public void setTime(long time)
{
this.time = time;
}
/**
* @return the srcIp
*/
public String getSrcIp()
{
return srcIp;
}
/**
* @param srcIp the srcIp to set
*/
public void setSrcIp(String srcIp)
{
this.srcIp = srcIp;
}
/**
* @return the destIp
*/
public String getDestIp()
{
return destIp;
}
/**
* @param destIp the destIp to set
*/
public void setDestIp(String destIp)
{
this.destIp = destIp;
}
/**
* @return the value
*/
public int getValue()
{
return value;
}
/**
* @param value the value to set
*/
public void setValue(int value)
{
this.value = value;
}
}
}
Data that drives the insertion:
1358,81
2359,86
3360,88
4361,80
5362,84
6363,80
7364,83
8365,99
9366,97
10367,99
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
--
Edson Tirelli
JBoss Drools Core Development
JBoss by Red Hat @
www.jboss.com
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users