Try this sequence:

advance clock from 0 to Fri Apr 30 18:26:47 CEST 2010
insert 1st operation
advance clock to next time
insert 2nd operation
fireAllRules

-W



2010/5/17 Xavier Coulon <xcoulon@gmail.com>
Hello Wolfgang,

Thanks for you answer. I changed my JUnit test method to the following :


@Test
    public void testActivity() throws IOException, ParseException,
            InterruptedException {
        // parse the log file
        Resource logFile = new ClassPathResource(
                "activity/activite18h20-18h30-tpcnop01s-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("Moving clock from "
                    + (new Date(clock.getCurrentTime())).toString() + " to "
                    + operation.getDate());
            clock.advanceTime(operation.getDate().getTime()

                    - clock.getCurrentTime(), TimeUnit.MILLISECONDS);
            session.fireAllRules();
            // clock.advanceTime(10, TimeUnit.SECONDS);
            LOGGER.debug("Inserting " + operation);

            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"));
    }

But it still does not work : the first "operation" 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)

Console> 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
Console> 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]
Console> 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, requestSize=0, responseSize=0]]
Console> 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]]
Console> 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
Console> 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, hostname=server1, ipAddress=1.2.3.4, operation=null, requestSize=0, responseSize=0]]
Console> 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]


My code is based on an example from the "Drools JBoss Rules 5.0 developer guide" (chapt 7)

Any idea ?

Thank you in advance
Regards,
Xavier

2010/5/17 Wolfgang Laun <wolfgang.laun@gmail.com>

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@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




--
Xavier

_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users