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 <xcou...@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-detect-2-occurrences-with-sliding-window-tp823141p823141.html > Sent from the Drools - User mailing list archive at Nabble.com. > _______________________________________________ > rules-users mailing list > rules-users@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/rules-users >
_______________________________________________ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users