[jboss-svn-commits] JBL Code SVN: r28875 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/integrationtests and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Aug 7 17:41:40 EDT 2009


Author: tirelli
Date: 2009-08-07 17:41:39 -0400 (Fri, 07 Aug 2009)
New Revision: 28875

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CollectWithWindows.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/OrderEvent.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java
Log:
JBRULES-2237: fixing the interaction between collect and sliding windows

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/OrderEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/OrderEvent.java	2009-08-07 16:38:07 UTC (rev 28874)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/OrderEvent.java	2009-08-07 21:41:39 UTC (rev 28875)
@@ -63,4 +63,8 @@
         this.total = total;
     }
 
+    @Override
+    public String toString() {
+        return "OrderEvent( id="+id+" customer="+customer+" total="+total+" )";
+    }
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java	2009-08-07 16:38:07 UTC (rev 28874)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/CepEspTest.java	2009-08-07 21:41:39 UTC (rev 28875)
@@ -12,6 +12,7 @@
 
 import org.drools.ClockType;
 import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseConfiguration;
 import org.drools.KnowledgeBaseFactory;
 import org.drools.OrderEvent;
 import org.drools.RuleBase;
@@ -1084,7 +1085,7 @@
         conf.setClockType( ClockType.PSEUDO_CLOCK );
         StatefulSession wm = ruleBase.newStatefulSession( conf,
                                                           null );
-        WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(wm);
+        WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( wm );
         logger.setFileName( "audit" );
 
         try {
@@ -1099,16 +1100,18 @@
             SessionPseudoClock clock = (SessionPseudoClock) wm.getSessionClock();
             clock.advanceTime( 5,
                                TimeUnit.SECONDS ); // 5 seconds
-            
+
             // there is no next job, so returns -1
-            assertEquals( -1, iwm.getTimeToNextJob());
+            assertEquals( -1,
+                          iwm.getTimeToNextJob() );
             wm.insert( new OrderEvent( "1",
                                        "customer A",
                                        70 ) );
             assertEquals( 0,
                           iwm.getIdleTime() );
             // now, there is a next job in 30 seconds: expire the event
-            assertEquals( 30000, iwm.getTimeToNextJob());
+            assertEquals( 30000,
+                          iwm.getTimeToNextJob() );
 
             wm.fireAllRules();
             assertEquals( 1,
@@ -1120,8 +1123,9 @@
             clock.advanceTime( 10,
                                TimeUnit.SECONDS ); // 10 seconds
             // next job is in 20 seconds: expire the event
-            assertEquals( 20000, iwm.getTimeToNextJob());
-            
+            assertEquals( 20000,
+                          iwm.getTimeToNextJob() );
+
             wm.insert( new OrderEvent( "2",
                                        "customer A",
                                        60 ) );
@@ -1136,8 +1140,9 @@
             clock.advanceTime( 10,
                                TimeUnit.SECONDS ); // 10 seconds
             // next job is in 10 seconds: expire the event
-            assertEquals( 10000, iwm.getTimeToNextJob());
-            
+            assertEquals( 10000,
+                          iwm.getTimeToNextJob() );
+
             wm.insert( new OrderEvent( "3",
                                        "customer A",
                                        50 ) );
@@ -1186,4 +1191,129 @@
         }
     }
 
+    public void testCollectWithWindows() throws Exception {
+        // read in the source
+        final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
+        kbuilder.add( ResourceFactory.newInputStreamResource( getClass().getResourceAsStream( "test_CEP_CollectWithWindows.drl" ) ),
+                      ResourceType.DRL );
+
+        assertFalse( kbuilder.getErrors().toString(),
+                     kbuilder.hasErrors() );
+
+        final KnowledgeBaseConfiguration kbconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
+        kbconf.setOption( EventProcessingOption.STREAM );
+        final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+
+        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
+
+        KnowledgeSessionConfiguration ksconf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
+        ksconf.setOption( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) );
+
+        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession( ksconf,
+                                                                               null );
+        WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(ksession);
+        logger.setFileName( "audit" );
+
+        List<Number> timeResults = new ArrayList<Number>();
+        List<Number> lengthResults = new ArrayList<Number>();
+
+        ksession.setGlobal( "timeResults",
+                            timeResults );
+        ksession.setGlobal( "lengthResults",
+                            lengthResults );
+
+        SessionPseudoClock clock = (SessionPseudoClock) ksession.getSessionClock();
+
+        try {
+            // First interaction
+            clock.advanceTime( 5,
+                               TimeUnit.SECONDS ); // 5 seconds
+            ksession.insert( new OrderEvent( "1",
+                                             "customer A",
+                                             70 ) );
+
+            ksession.fireAllRules();
+
+            assertEquals( 1,
+                          timeResults.size() );
+            assertEquals( 1,
+                          timeResults.get( 0 ).intValue() );
+            assertEquals( 1,
+                          lengthResults.size() );
+            assertEquals( 1,
+                          lengthResults.get( 0 ).intValue() );
+
+            // Second interaction: advance clock and assert new data
+            clock.advanceTime( 10,
+                               TimeUnit.SECONDS ); // 10 seconds
+            ksession.insert( new OrderEvent( "2",
+                                             "customer A",
+                                             60 ) );
+            ksession.fireAllRules();
+
+            assertEquals( 2,
+                          timeResults.size() );
+            assertEquals( 2,
+                          timeResults.get( 1 ).intValue() );
+            assertEquals( 2,
+                          lengthResults.size() );
+            assertEquals( 2,
+                          lengthResults.get( 1 ).intValue() );
+
+            // Third interaction: advance clock and assert new data
+            clock.advanceTime( 10,
+                               TimeUnit.SECONDS ); // 10 seconds
+            ksession.insert( new OrderEvent( "3",
+                                             "customer A",
+                                             50 ) );
+            ksession.fireAllRules();
+
+            assertEquals( 3,
+                          timeResults.size() );
+            assertEquals( 3,
+                          timeResults.get( 2 ).intValue() );
+            assertEquals( 3,
+                          lengthResults.size() );
+            assertEquals( 3,
+                          lengthResults.get( 2 ).intValue() );
+
+            // Fourth interaction: advance clock and assert new data
+            clock.advanceTime( 10,
+                               TimeUnit.SECONDS ); // 10 seconds
+            ksession.insert( new OrderEvent( "4",
+                                             "customer A",
+                                             25 ) );
+            ksession.fireAllRules();
+
+            // first event should have expired now
+            assertEquals( 4,
+                          timeResults.size() );
+            assertEquals( 3,
+                          timeResults.get( 3 ).intValue() );
+            assertEquals( 4,
+                          lengthResults.size() );
+            assertEquals( 3,
+                          lengthResults.get( 3 ).intValue() );
+
+            // Fifth interaction: advance clock and assert new data
+            clock.advanceTime( 5,
+                               TimeUnit.SECONDS ); // 10 seconds
+            ksession.insert( new OrderEvent( "5",
+                                             "customer A",
+                                             70 ) );
+            ksession.fireAllRules();
+
+            assertEquals( 5,
+                          timeResults.size() );
+            assertEquals( 4,
+                          timeResults.get( 4 ).intValue() );
+            assertEquals( 5,
+                          lengthResults.size() );
+            assertEquals( 3,
+                          lengthResults.get( 4 ).intValue() );
+        } finally {
+            logger.writeToDisk();
+        }
+
+    }
 }

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CollectWithWindows.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CollectWithWindows.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_CEP_CollectWithWindows.drl	2009-08-07 21:41:39 UTC (rev 28875)
@@ -0,0 +1,27 @@
+package org.drools;
+
+import java.util.List
+
+global List timeResults;
+global List lengthResults;
+
+declare OrderEvent
+    @role( event )
+    @expires( 2m )
+end
+
+rule "collect with time window"
+when
+    $list : List( empty == false ) from collect(
+              $o : OrderEvent() over window:time(30s) )
+then
+    timeResults.add( $list.size() );
+end
+
+rule "collect with length window"
+when
+    $list : List( empty == false ) from collect(
+              $o : OrderEvent() over window:length(3) )
+then
+    lengthResults.add( $list.size() );
+end

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2009-08-07 16:38:07 UTC (rev 28874)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java	2009-08-07 21:41:39 UTC (rev 28875)
@@ -442,7 +442,7 @@
                                          workingMemory );
             }
         } else {
-            // retraction
+            // retraction and expiration
             this.accumulate.reverse( memory.workingMemoryContext,
                                      accctx.context,
                                      tuple,

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2009-08-07 16:38:07 UTC (rev 28874)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/CollectNode.java	2009-08-07 21:41:39 UTC (rev 28875)
@@ -20,6 +20,7 @@
 import org.drools.common.BetaConstraints;
 import org.drools.common.InternalFactHandle;
 import org.drools.common.InternalWorkingMemory;
+import org.drools.common.PropagationContextImpl;
 import org.drools.reteoo.builder.BuildContext;
 import org.drools.rule.Behavior;
 import org.drools.rule.Collect;
@@ -278,6 +279,12 @@
                                   final InternalWorkingMemory workingMemory) {
 
         final CollectMemory memory = (CollectMemory) workingMemory.getNodeMemory( this );
+        
+        final InternalFactHandle origin = (InternalFactHandle) context.getFactHandleOrigin();
+        if( context.getType() == PropagationContext.EXPIRATION ) {
+            ((PropagationContextImpl)context).setFactHandle( null );
+        }
+        
         behavior.retractRightTuple( memory.betaMemory.getBehaviorContext(), rightTuple, workingMemory );
         memory.betaMemory.getRightTupleMemory().remove( rightTuple );
 
@@ -291,6 +298,11 @@
                               memory );
             leftTuple = tmp;
         }
+
+        if( context.getType() == PropagationContext.EXPIRATION ) {
+            ((PropagationContextImpl)context).setFactHandle( origin );
+        }
+
     }
 
     /**
@@ -355,7 +367,7 @@
 
         if ( context.getType() == PropagationContext.ASSERTION ) {
             ((Collection) colctx.resultTuple.getFactHandle().getObject()).add( handle.getObject() );
-        } else if ( context.getType() == PropagationContext.RETRACTION ) {
+        } else if ( context.getType() == PropagationContext.RETRACTION || context.getType() == PropagationContext.EXPIRATION ) {
             ((Collection) colctx.resultTuple.getFactHandle().getObject()).remove( handle.getObject() );
         } else if ( context.getType() == PropagationContext.MODIFICATION || context.getType() == PropagationContext.RULE_ADDITION || context.getType() == PropagationContext.RULE_REMOVAL ) {
             if ( isAssert ) {

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java	2009-08-07 16:38:07 UTC (rev 28874)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/Collect.java	2009-08-07 21:41:39 UTC (rev 28875)
@@ -19,10 +19,13 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.drools.RuntimeDroolsException;
 import org.drools.base.ClassObjectType;
@@ -83,7 +86,8 @@
             // FactTemplateObject type is not allowed
             if ( this.cls == null ) {
                 ClassObjectType objType = ((ClassObjectType) this.resultPattern.getObjectType());
-                this.cls = ((InternalRuleBase)wm.getRuleBase()).getRootClassLoader().loadClass( objType.getClassName() );
+                String className = determineResultClassName( objType );
+                this.cls = ((InternalRuleBase)wm.getRuleBase()).getRootClassLoader().loadClass( className );
             }
             return (Collection) this.cls.newInstance();
         } catch ( final ClassCastException cce ) {
@@ -101,6 +105,29 @@
         }
     }
 
+    /**
+     * If the user uses an interface as a result type, use a default
+     * concrete class.
+     * 
+     * List -> ArrayList
+     * Collection -> ArrayList
+     * Set -> HashSet
+     * 
+     * @param objType
+     * @return
+     */
+    private String determineResultClassName(ClassObjectType objType) {
+        String className = objType.getClassName();
+        if( List.class.getName().equals( className ) ) {
+            className = ArrayList.class.getName();
+        } else if( Set.class.getName().equals( className ) ) {
+            className = HashSet.class.getName();
+        } else if( Collection.class.getName().equals( className ) ) {
+            className = ArrayList.class.getName();
+        }
+        return className;
+    }
+
     public Map getInnerDeclarations() {
         return this.sourcePattern.getInnerDeclarations();
     }



More information about the jboss-svn-commits mailing list