Hello Wolfgang,<br><br>Thanks for you answer. I changed my JUnit test method to the following :<br><br><span style="font-family: courier new,monospace;">@Test</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    public void testActivity() throws IOException, ParseException,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">            InterruptedException {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        // parse the log file</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">        Resource logFile = new ClassPathResource(</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">                &quot;activity/activite18h20-18h30-tpcnop01s-extract.log&quot;);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">        // converter and inject tracks in the session,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        List&lt;String&gt; logLines = FileUtils.readLines(logFile.getFile(), &quot;UTF-8&quot;);</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        // fire all rules</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        session.fireAllRules();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">        LOGGER.info(&quot;loading events&quot;);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        // load events from stream</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">        for (String logLine : logLines) {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            Operation operation = LineConverterUtil.getOperation(logLine);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">            LOGGER.debug(&quot;Moving clock from &quot;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">                    + (new Date(clock.getCurrentTime())).toString() + &quot; to &quot;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">                    + operation.getDate());</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            <b>clock.advanceTime(operation.getDate().getTime()</b></span><b><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">                    - clock.getCurrentTime(), TimeUnit.MILLISECONDS);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            session.fireAllRules();</span><br style="font-family: courier new,monospace;">
</b><span style="font-family: courier new,monospace;"><b>            </b>// clock.advanceTime(10, TimeUnit.SECONDS);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            LOGGER.debug(&quot;Inserting &quot; + operation);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">            FactHandle operationHandle = entryPoint.insert(operation);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">            LOGGER.debug(&quot;Insertion done: &quot; + operationHandle.toExternalForm());</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        LOGGER.info(&quot;done with events&quot;);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">        // check...</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">        Assert.assertTrue(&quot;Rule not fired...&quot;, listener</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">                .isRuleFired(&quot;overActivity&quot;));</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    }</span><br>
<br>But it still does not work : the first &quot;operation&quot; is retracted from the session when the clock is moved (see my logs below), yet the window of 60s is not expired (18:26:47 to 18:27:11)<br><br><span style="font-family: courier new,monospace;">Console&gt; 2010-05-17 14:08:22|DEBUG||DroolsRulesTestCase.testActivity|Moving clock from Thu Jan 01 01:00:00 CET 1970 to Fri Apr 30 18:26:47 CEST 2010</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Console&gt; 2010-05-17 14:08:22|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]</span><br style="font-family: courier new,monospace;">
<b style="font-family: courier new,monospace;">Console&gt; 2010-05-17 14:08:22|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, r</b><span style="font-family: courier new,monospace;">equestSize=0, responseSize=0]]</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Console&gt; 2010-05-17 14:08:22|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]]</span><br style="font-family: courier new,monospace;">
<b><span style="font-family: courier new,monospace;">Console&gt; 2010-05-17 14:08:22|DEBUG||DroolsRulesTestCase.testActivity|Moving clock from Fri Apr 30 18:26:47 CEST 2010 to Fri Apr 30 18:27:11 CEST 2010</span><br style="font-family: courier new,monospace;">
</b><span style="font-family: courier new,monospace;"><b>Console&gt; 2010-05-17 14:08:22|WARN ||TrackingWorkingMemoryEventListener.objectRetracted|Object retracted: [event fid:1:1:Operation [date=Fri Apr 30 18:26:47 CEST 2010, executionTime=1, </b>hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0, responseSize=0]]</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Console&gt; 2010-05-17 14:08:22|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]</span><br>
<br><br>My code is based on an example from the &quot;Drools JBoss Rules 5.0 
developer guide&quot; (chapt 7)<br><br>Any idea ? <br><br>Thank you in advance<br>Regards,<br>Xavier<br><br><div class="gmail_quote">2010/5/17 Wolfgang Laun <span dir="ltr">&lt;<a href="mailto:wolfgang.laun@gmail.com">wolfgang.laun@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">You are inserting Operation facts, interleaved with advancing the clock,<br>both of which correctly updates the agenda and eliminates the facts that<br>
are pseudo-too-old to matter.<br><br>But you are never goiving the Engine a chance to fire - until it is pseudo-too-late.<br>
<br>Either you call session.fireUntilHalt() in a separate thread or, for unit test, call<br>fireAllRules() after each clock manipulation.<br><br>HTH<br><font color="#888888">-W</font><div><div></div><div class="h5"><br><br>
<br><div class="gmail_quote">On Mon, May 17, 2010 at 11:18 AM, Xavier Coulon <span dir="ltr">&lt;<a href="mailto:xcoulon@gmail.com" target="_blank">xcoulon@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
Hello,<br>
<br>
I&#39;m new to Drools (5.0.1) and i&#39;ve tryied the following (basic) fusion rule<br>
for a few days now without success.<br>
The rule is to determine if a user performs 2 operations in the sliding<br>
window of 60s. In such a condition, a log message should be triggered.<br>
<br>
Here is my DRL code :<br>
<br>
# declare events<br>
declare Operation<br>
        @role(event)<br>
        @timestamp(date)<br>
end<br>
<br>
rule &quot;overActivity&quot;<br>
dialect &quot;mvel&quot;<br>
        when<br>
                #condition : 2 operation in less than 1 minute<br>
                $operation1 : Operation()<br>
                        over window:time(60s) from entry-point &quot;OperationStream&quot;<br>
                $operation2 : Operation(this != $operation1, ipAddress ==<br>
$operation1.ipAddress)<br>
                        over window:time(60s) from entry-point &quot;OperationStream&quot;<br>
        then<br>
                #actions<br>
                System.out.println(&quot;over-active user &quot; + $operation1.ipAddress );<br>
end<br>
<br>
<br>
And my JUnit test, using a PSEUDO Clock :<br>
<br>
public class DroolsRulesTestCase {<br>
<br>
        static KnowledgeBase knowledgeBase;<br>
        StatefulKnowledgeSession session;<br>
        // FactHandle handle;<br>
        SessionPseudoClock clock;<br>
        WorkingMemoryEntryPoint entryPoint;<br>
        private TrackingAgendaEventListener listener;<br>
<br>
        private static final Logger LOGGER = Logger<br>
                        .getLogger(DroolsRulesTestCase.class);<br>
<br>
        @BeforeClass<br>
        public static void globalSetup() throws IOException {<br>
                KnowledgeBuilder builder = KnowledgeBuilderFactory<br>
                                .newKnowledgeBuilder();<br>
                ClassPathResource classPathResource = new ClassPathResource(<br>
                                &quot;rules/activity-fusion.drl&quot;);<br>
                Assert.assertTrue(&quot;Rules resource not found&quot;, classPathResource<br>
                                .exists());<br>
                builder.add(ResourceFactory.newInputStreamResource(classPathResource<br>
                                .getInputStream()), ResourceType.DRL);<br>
                Assert.assertFalse(&quot;Errors in builder:&quot;<br>
                                + builder.getErrors().toString(), builder.hasErrors());<br>
                KnowledgeBaseConfiguration configuration = KnowledgeBaseFactory<br>
                                .newKnowledgeBaseConfiguration();<br>
                configuration.setOption(EventProcessingOption.STREAM);<br>
                knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase(configuration);<br>
                knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());<br>
        }<br>
<br>
        @Before<br>
        public void setup() {<br>
                KnowledgeSessionConfiguration configuration = KnowledgeBaseFactory<br>
                                .newKnowledgeSessionConfiguration();<br>
                configuration.setOption(ClockTypeOption.get(&quot;pseudo&quot;));<br>
<br>
                session = knowledgeBase<br>
                                .newStatefulKnowledgeSession(configuration, null);<br>
                clock = (SessionPseudoClock) session.getSessionClock();<br>
                listener = new TrackingAgendaEventListener();<br>
                session.addEventListener(listener);<br>
                session.addEventListener(new TrackingWorkingMemoryEventListener());<br>
                entryPoint = session.getWorkingMemoryEntryPoint(&quot;OperationStream&quot;);<br>
        }<br>
<br>
        @SuppressWarnings(&quot;unchecked&quot;)<br>
        @Test<br>
        public void testActivity() throws IOException, ParseException,<br>
                        InterruptedException {<br>
                // parse the log file<br>
                Resource logFile = new ClassPathResource(<br>
                                &quot;activity/extract.log&quot;);<br>
                // converter and inject tracks in the session,<br>
                List&lt;String&gt; logLines = FileUtils.readLines(logFile.getFile(), &quot;UTF-8&quot;);<br>
<br>
                // fire all rules<br>
                session.fireAllRules();<br>
                LOGGER.info(&quot;loading events&quot;);<br>
                // load events from stream<br>
                for (String logLine : logLines) {<br>
                        Operation operation = LineConverterUtil.getOperation(logLine);<br>
                        LOGGER.debug(&quot;Inserting &quot; + operation);<br>
                        LOGGER.debug(&quot;Moving clock from &quot;<br>
                                        + (new Date(clock.getCurrentTime())).toString() + &quot; to &quot;<br>
                                        + operation.getDate());<br>
                        clock.advanceTime(operation.getDate().getTime()<br>
                                        - clock.getCurrentTime(), TimeUnit.MILLISECONDS);<br>
                        // clock.advanceTime(10, TimeUnit.SECONDS);<br>
                        FactHandle operationHandle = entryPoint.insert(operation);<br>
<br>
                        LOGGER.debug(&quot;Insertion done: &quot; + operationHandle.toExternalForm());<br>
<br>
                }<br>
                LOGGER.info(&quot;done with events&quot;);<br>
                // check...<br>
                Assert.assertTrue(&quot;Rule not fired...&quot;, listener<br>
                                .isRuleFired(&quot;overActivity&quot;));<br>
        }<br>
}<br>
<br>
I also use a TrackingWorkingMemoryEventListener to track events.<br>
<br>
The test because since the rule is not fired, and the log contains the<br>
following lines :<br>
<br>
Console&gt; 2010-05-17 11:15:15|INFO ||DroolsRulesTestCase.testActivity|loading<br>
events<br>
Console&gt; 2010-05-17<br>
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Inserting Operation<br>
[date=Fri Apr 30 18:26:47 CEST 2010, executionTime=1, hostname=server1,<br>
ipAddress=1.2.3.4, operation=null, requestSize=0, responseSize=0]<br>
Console&gt; 2010-05-17 11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Moving<br>
clock from Thu Jan 01 01:00:00 CET 1970 to Fri Apr 30 18:26:47 CEST 2010<br>
Console&gt; 2010-05-17 11:15:15|WARN<br>
||TrackingWorkingMemoryEventListener.objectInserted|Object inserted: [event<br>
fid:1:1:Operation [date=Fri Apr 30 18:26:47 CEST 2010, executionTime=1,<br>
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,<br>
responseSize=0]]<br>
Console&gt; 2010-05-17<br>
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Insertion done: [event<br>
fid:1:1:Operation [date=Fri Apr 30 18:26:47 CEST 2010, executionTime=1,<br>
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,<br>
responseSize=0]]<br>
Console&gt; 2010-05-17<br>
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Inserting Operation<br>
[date=Fri Apr 30 18:27:11 CEST 2010, executionTime=164, hostname=server1,<br>
ipAddress=1.2.3.4, operation=CONSULTATION, requestSize=1299,<br>
responseSize=895]<br>
Console&gt; 2010-05-17 11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Moving<br>
clock from Fri Apr 30 18:26:47 CEST 2010 to Fri Apr 30 18:27:11 CEST 2010<br>
Console&gt; 2010-05-17 11:15:15|WARN<br>
||TrackingWorkingMemoryEventListener.objectRetracted|Object retracted:<br>
[event fid:1:1:Operation [date=Fri Apr 30 18:26:47 CEST 2010,<br>
executionTime=1, hostname=server1, ipAddress=1.2.3.4, operation=null,<br>
requestSize=0, responseSize=0]]<br>
Console&gt; 2010-05-17 11:15:15|WARN<br>
||TrackingWorkingMemoryEventListener.objectInserted|Object inserted: [event<br>
fid:2:2:Operation [date=Fri Apr 30 18:27:11 CEST 2010, executionTime=164,<br>
hostname=server1, ipAddress=1.2.3.4, operation=CONSULTATION,<br>
requestSize=1299, responseSize=895]]<br>
Console&gt; 2010-05-17<br>
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Insertion done: [event<br>
fid:2:2:Operation [date=Fri Apr 30 18:27:11 CEST 2010, executionTime=164,<br>
hostname=server1, ipAddress=1.2.3.4, operation=CONSULTATION,<br>
requestSize=1299, responseSize=895]]<br>
Console&gt; 2010-05-17<br>
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Inserting Operation<br>
[date=Fri Apr 30 18:28:47 CEST 2010, executionTime=1, hostname=server1,<br>
ipAddress=1.2.3.4, operation=null, requestSize=0, responseSize=0]<br>
Console&gt; 2010-05-17 11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Moving<br>
clock from Fri Apr 30 18:27:11 CEST 2010 to Fri Apr 30 18:28:47 CEST 2010<br>
Console&gt; 2010-05-17 11:15:15|WARN<br>
||TrackingWorkingMemoryEventListener.objectRetracted|Object retracted:<br>
[event fid:2:2:Operation [date=Fri Apr 30 18:27:11 CEST 2010,<br>
executionTime=164, hostname=server1, ipAddress=1.2.3.4,<br>
operation=CONSULTATION, requestSize=1299, responseSize=895]]<br>
Console&gt; 2010-05-17 11:15:15|WARN<br>
||TrackingWorkingMemoryEventListener.objectInserted|Object inserted: [event<br>
fid:3:3:Operation [date=Fri Apr 30 18:28:47 CEST 2010, executionTime=1,<br>
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,<br>
responseSize=0]]<br>
Console&gt; 2010-05-17<br>
11:15:15|DEBUG||DroolsRulesTestCase.testActivity|Insertion done: [event<br>
fid:3:3:Operation [date=Fri Apr 30 18:28:47 CEST 2010, executionTime=1,<br>
hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0,<br>
responseSize=0]]<br>
Console&gt; 2010-05-17 11:15:15|INFO ||DroolsRulesTestCase.testActivity|done<br>
with events<br>
<br>
<br>
I guess there is something wrong with my use of the PseudoClock, since<br>
previous operations are retracted before a new one is inserted, which I<br>
believe prevents the rule to be fired.<br>
<br>
Can you help me ?<br>
<br>
Thank you in advance<br>
Regards,<br>
Xavier<br>
<font color="#888888">--<br>
View this message in context: <a href="http://drools-java-rules-engine.46999.n3.nabble.com/Drools-Fusion-Can-t-detect-2-occurrences-with-sliding-window-tp823141p823141.html" target="_blank">http://drools-java-rules-engine.46999.n3.nabble.com/Drools-Fusion-Can-t-detect-2-occurrences-with-sliding-window-tp823141p823141.html</a><br>


Sent from the Drools - User mailing list archive at Nabble.com.<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</font></blockquote></div><br>
</div></div><br>_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br>Xavier<br>