[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