You are inserting Operation facts, interleaved with advancing the clock,
both of which correctly updates the agenda and eliminates the facts that
are pseudo-too-old to matter.
But you are never goiving the Engine a chance to fire - until it is
pseudo-too-late.
Either you call session.fireUntilHalt() in a separate thread or, for unit
test, call
fireAllRules() after each clock manipulation.
HTH
-W
On Mon, May 17, 2010 at 11:18 AM, Xavier Coulon <xcoulon(a)gmail.com> wrote:
Hello,
I'm new to Drools (5.0.1) and i've tryied the following (basic) fusion rule
for a few days now without success.
The rule is to determine if a user performs 2 operations in the sliding
window of 60s. In such a condition, a log message should be triggered.
Here is my DRL code :
# declare events
declare Operation
@role(event)
@timestamp(date)
end
rule "overActivity"
dialect "mvel"
when
#condition : 2 operation in less than 1 minute
$operation1 : Operation()
over window:time(60s) from entry-point
"OperationStream"
$operation2 : Operation(this != $operation1, ipAddress ==
$operation1.ipAddress)
over window:time(60s) from entry-point
"OperationStream"
then
#actions
System.out.println("over-active user " +
$operation1.ipAddress );
end
And my JUnit test, using a PSEUDO Clock :
public class DroolsRulesTestCase {
static KnowledgeBase knowledgeBase;
StatefulKnowledgeSession session;
// FactHandle handle;
SessionPseudoClock clock;
WorkingMemoryEntryPoint entryPoint;
private TrackingAgendaEventListener listener;
private static final Logger LOGGER = Logger
.getLogger(DroolsRulesTestCase.class);
@BeforeClass
public static void globalSetup() throws IOException {
KnowledgeBuilder builder = KnowledgeBuilderFactory
.newKnowledgeBuilder();
ClassPathResource classPathResource = new ClassPathResource(
"rules/activity-fusion.drl");
Assert.assertTrue("Rules resource not found",
classPathResource
.exists());
builder.add(ResourceFactory.newInputStreamResource(classPathResource
.getInputStream()), ResourceType.DRL);
Assert.assertFalse("Errors in builder:"
+ builder.getErrors().toString(),
builder.hasErrors());
KnowledgeBaseConfiguration configuration =
KnowledgeBaseFactory
.newKnowledgeBaseConfiguration();
configuration.setOption(EventProcessingOption.STREAM);
knowledgeBase =
KnowledgeBaseFactory.newKnowledgeBase(configuration);
knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
}
@Before
public void setup() {
KnowledgeSessionConfiguration configuration =
KnowledgeBaseFactory
.newKnowledgeSessionConfiguration();
configuration.setOption(ClockTypeOption.get("pseudo"));
session = knowledgeBase
.newStatefulKnowledgeSession(configuration,
null);
clock = (SessionPseudoClock) session.getSessionClock();
listener = new TrackingAgendaEventListener();
session.addEventListener(listener);
session.addEventListener(new
TrackingWorkingMemoryEventListener());
entryPoint =
session.getWorkingMemoryEntryPoint("OperationStream");
}
@SuppressWarnings("unchecked")
@Test
public void testActivity() throws IOException, ParseException,
InterruptedException {
// parse the log file
Resource logFile = new ClassPathResource(
"activity/extract.log");
// converter and inject tracks in the session,
List<String> logLines =
FileUtils.readLines(logFile.getFile(), "UTF-8");
// fire all rules
session.fireAllRules();
LOGGER.info("loading events");
// load events from stream
for (String logLine : logLines) {
Operation operation =
LineConverterUtil.getOperation(logLine);
LOGGER.debug("Inserting " + operation);
LOGGER.debug("Moving clock from "
+ (new
Date(clock.getCurrentTime())).toString() + " to "
+ operation.getDate());
clock.advanceTime(operation.getDate().getTime()
- clock.getCurrentTime(),
TimeUnit.MILLISECONDS);
// clock.advanceTime(10, TimeUnit.SECONDS);
FactHandle operationHandle =
entryPoint.insert(operation);
LOGGER.debug("Insertion done: " +
operationHandle.toExternalForm());
}
LOGGER.info("done with events");
// check...
Assert.assertTrue("Rule not fired...", listener
.isRuleFired("overActivity"));
}
}
I also use a TrackingWorkingMemoryEventListener to track events.
The test because since the rule is not fired, and the log contains the
following lines :
Console> 2010-05-17 11:15:15|INFO
||DroolsRulesTestCase.testActivity|loading
events
Console> 2010-05-17
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Inserting Operation
[date=Fri Apr 30 18:26:47 CEST 2010, executionTime=1, hostname=server1,
ipAddress=1.2.3.4, operation=null, requestSize=0, responseSize=0]
Console> 2010-05-17 11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Moving
clock from Thu Jan 01 01:00:00 CET 1970 to Fri Apr 30 18:26:47 CEST 2010
Console> 2010-05-17 11:15:15|WARN
||TrackingWorkingMemoryEventListener.objectInserted|Object inserted: [event
fid:1:1:Operation [date=Fri Apr 30 18:26:47 CEST 2010, executionTime=1,
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,
responseSize=0]]
Console> 2010-05-17
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Insertion done: [event
fid:1:1:Operation [date=Fri Apr 30 18:26:47 CEST 2010, executionTime=1,
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,
responseSize=0]]
Console> 2010-05-17
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Inserting Operation
[date=Fri Apr 30 18:27:11 CEST 2010, executionTime=164, hostname=server1,
ipAddress=1.2.3.4, operation=CONSULTATION, requestSize=1299,
responseSize=895]
Console> 2010-05-17 11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Moving
clock from Fri Apr 30 18:26:47 CEST 2010 to Fri Apr 30 18:27:11 CEST 2010
Console> 2010-05-17 11:15:15|WARN
||TrackingWorkingMemoryEventListener.objectRetracted|Object retracted:
[event fid:1:1:Operation [date=Fri Apr 30 18:26:47 CEST 2010,
executionTime=1, hostname=server1, ipAddress=1.2.3.4, operation=null,
requestSize=0, responseSize=0]]
Console> 2010-05-17 11:15:15|WARN
||TrackingWorkingMemoryEventListener.objectInserted|Object inserted: [event
fid:2:2:Operation [date=Fri Apr 30 18:27:11 CEST 2010, executionTime=164,
hostname=server1, ipAddress=1.2.3.4, operation=CONSULTATION,
requestSize=1299, responseSize=895]]
Console> 2010-05-17
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Insertion done: [event
fid:2:2:Operation [date=Fri Apr 30 18:27:11 CEST 2010, executionTime=164,
hostname=server1, ipAddress=1.2.3.4, operation=CONSULTATION,
requestSize=1299, responseSize=895]]
Console> 2010-05-17
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Inserting Operation
[date=Fri Apr 30 18:28:47 CEST 2010, executionTime=1, hostname=server1,
ipAddress=1.2.3.4, operation=null, requestSize=0, responseSize=0]
Console> 2010-05-17 11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Moving
clock from Fri Apr 30 18:27:11 CEST 2010 to Fri Apr 30 18:28:47 CEST 2010
Console> 2010-05-17 11:15:15|WARN
||TrackingWorkingMemoryEventListener.objectRetracted|Object retracted:
[event fid:2:2:Operation [date=Fri Apr 30 18:27:11 CEST 2010,
executionTime=164, hostname=server1, ipAddress=1.2.3.4,
operation=CONSULTATION, requestSize=1299, responseSize=895]]
Console> 2010-05-17 11:15:15|WARN
||TrackingWorkingMemoryEventListener.objectInserted|Object inserted: [event
fid:3:3:Operation [date=Fri Apr 30 18:28:47 CEST 2010, executionTime=1,
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,
responseSize=0]]
Console> 2010-05-17
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Insertion done: [event
fid:3:3:Operation [date=Fri Apr 30 18:28:47 CEST 2010, executionTime=1,
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,
responseSize=0]]
Console> 2010-05-17 11:15:15|INFO ||DroolsRulesTestCase.testActivity|done
with events
I guess there is something wrong with my use of the PseudoClock, since
previous operations are retracted before a new one is inserted, which I
believe prevents the rule to be fired.
Can you help me ?
Thank you in advance
Regards,
Xavier
--
View this message in context:
http://drools-java-rules-engine.46999.n3.nabble.com/Drools-Fusion-Can-t-d...
Sent from the Drools - User mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users