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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon May 31 19:48:36 EDT 2010


Author: tirelli
Date: 2010-05-31 19:48:35 -0400 (Mon, 31 May 2010)
New Revision: 33272

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EventExpiration.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/StreamsTest.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java
Log:
JBRULES-2395: JBRULES-2530: fixing expiration offset calculation for object types not used in rules. Fixing OTN persistence to properly persist expiration offset

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/StreamsTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/StreamsTest.java	2010-05-31 22:27:12 UTC (rev 33271)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/StreamsTest.java	2010-05-31 23:48:35 UTC (rev 33272)
@@ -17,15 +17,25 @@
  */
 package org.drools.integrationtests;
 
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.junit.internal.matchers.IsCollectionContaining.hasItems;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import junit.framework.TestCase;
 
 import org.drools.ClockType;
 import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseConfiguration;
 import org.drools.KnowledgeBaseFactory;
 import org.drools.SessionConfiguration;
 import org.drools.StockTick;
@@ -34,11 +44,15 @@
 import org.drools.builder.ResourceType;
 import org.drools.common.InternalFactHandle;
 import org.drools.compiler.DroolsParserException;
+import org.drools.conf.EventProcessingOption;
+import org.drools.event.rule.WorkingMemoryEventListener;
 import org.drools.io.ResourceFactory;
 import org.drools.rule.EntryPoint;
 import org.drools.runtime.KnowledgeSessionConfiguration;
 import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.conf.ClockTypeOption;
 import org.drools.runtime.rule.WorkingMemoryEntryPoint;
+import org.drools.time.impl.PseudoClockScheduler;
 
 /**
  * Tests related to the stream support features
@@ -64,16 +78,24 @@
     private KnowledgeBase loadKnowledgeBase(final String fileName) throws IOException,
                                                                   DroolsParserException,
                                                                   Exception {
+        return loadKnowledgeBase( fileName,
+                                  KnowledgeBaseFactory.newKnowledgeBaseConfiguration() );
+    }
+
+    private KnowledgeBase loadKnowledgeBase(final String fileName,
+                                            KnowledgeBaseConfiguration kconf) throws IOException,
+                                                                             DroolsParserException,
+                                                                             Exception {
         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
         kbuilder.add( ResourceFactory.newClassPathResource( fileName,
-                                                                    getClass() ),
-                              ResourceType.DRL );
-        
-        if( kbuilder.hasErrors() ) {
-            System.out.println(kbuilder.getErrors());
+                                                            getClass() ),
+                      ResourceType.DRL );
+
+        if ( kbuilder.hasErrors() ) {
+            System.out.println( kbuilder.getErrors() );
             return null;
         }
-        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kconf );
         kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
 
         return SerializationHelper.serializeObject( kbase );
@@ -86,7 +108,8 @@
 
         KnowledgeSessionConfiguration conf = new SessionConfiguration();
         ((SessionConfiguration) conf).setClockType( ClockType.PSEUDO_CLOCK );
-        StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession( conf, null );
+        StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession( conf,
+                                                                              null );
 
         final List results = new ArrayList();
 
@@ -224,13 +247,13 @@
                     results.get( 0 ) );
 
     }
-    
+
     public void testModifyRetracOnEntryPointFacts() throws Exception {
         // read in the source
         KnowledgeBase kbase = loadKnowledgeBase( "test_modifyRetractEntryPoint.drl" );
         StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();
 
-        final List<? extends Number> results = new ArrayList<Number>();
+        final List< ? extends Number> results = new ArrayList<Number>();
         session.setGlobal( "results",
                            results );
 
@@ -270,38 +293,86 @@
 
         session.fireAllRules();
 
-        System.out.println(results);
+        System.out.println( results );
         assertEquals( 2,
                       results.size() );
         assertEquals( 30,
-                      ((Number)results.get( 0 )).intValue() );
+                      ((Number) results.get( 0 )).intValue() );
         assertEquals( 110,
-                      ((Number)results.get( 1 )).intValue() );
-        
+                      ((Number) results.get( 1 )).intValue() );
+
         // the 3 non-matched facts continue to exist in the entry point
-        assertEquals( 3, 
+        assertEquals( 3,
                       entry.getObjects().size() );
         // but no fact was inserted into the main session
-        assertEquals( 0, 
+        assertEquals( 0,
                       session.getObjects().size() );
 
     }
-    
+
     public void testGetEntryPointList() throws Exception {
         // read in the source
         KnowledgeBase kbase = loadKnowledgeBase( "test_EntryPointReference.drl" );
         StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();
-        
+
         WorkingMemoryEntryPoint def = session.getWorkingMemoryEntryPoint( EntryPoint.DEFAULT.getEntryPointId() );
         WorkingMemoryEntryPoint s1 = session.getWorkingMemoryEntryPoint( "stream1" );
         WorkingMemoryEntryPoint s2 = session.getWorkingMemoryEntryPoint( "stream2" );
         WorkingMemoryEntryPoint s3 = session.getWorkingMemoryEntryPoint( "stream3" );
-        Collection<? extends WorkingMemoryEntryPoint> eps = session.getWorkingMemoryEntryPoints();
-        
-        assertEquals( 4, eps.size() );
+        Collection< ? extends WorkingMemoryEntryPoint> eps = session.getWorkingMemoryEntryPoints();
+
+        assertEquals( 4,
+                      eps.size() );
         assertTrue( eps.contains( def ) );
         assertTrue( eps.contains( s1 ) );
         assertTrue( eps.contains( s2 ) );
         assertTrue( eps.contains( s3 ) );
     }
+
+    public void testEventDoesNotExpireIfNotInPattern() throws Exception {
+        KnowledgeBaseConfiguration kconf = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
+        kconf.setOption( EventProcessingOption.STREAM );
+        KnowledgeBase kbase = loadKnowledgeBase( "test_EventExpiration.drl",
+                                                 kconf );
+
+        KnowledgeSessionConfiguration ksessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
+        ksessionConfig.setOption( ClockTypeOption.get( "pseudo" ) );
+        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession( ksessionConfig,
+                                                                               null );
+
+        WorkingMemoryEventListener wml = mock( WorkingMemoryEventListener.class );
+        ksession.addEventListener( wml );
+
+        PseudoClockScheduler clock = ksession.getSessionClock();
+
+        final StockTick st1 = new StockTick( 1,
+                                             "RHT",
+                                             100,
+                                             1000 );
+        final StockTick st2 = new StockTick( 2,
+                                             "RHT",
+                                             100,
+                                             1000 );
+
+        ksession.insert( st1 );
+        ksession.insert( st2 );
+
+        verify( wml,
+                times( 2 ) ).objectInserted( any( org.drools.event.rule.ObjectInsertedEvent.class ) );
+        assertThat( ksession.getObjects().size(),
+                    equalTo( 2 ) );
+        assertThat( ksession.getObjects(),
+                    hasItems( (Object) st1,
+                              st2 ) );
+
+        ksession.fireAllRules();
+
+        clock.advanceTime( 3,
+                           TimeUnit.SECONDS );
+        ksession.fireAllRules();
+
+        assertThat( ksession.getObjects().size(),
+                    equalTo( 0 ) );
+    }
+
 }

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EventExpiration.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EventExpiration.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_EventExpiration.drl	2010-05-31 23:48:35 UTC (rev 33272)
@@ -0,0 +1,15 @@
+package org.drools
+
+declare StockTick
+    @role( event )
+    @expires( 1s )
+end
+
+rule X
+when
+    eval( true )
+then 
+    // no-op
+end
+
+

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java	2010-05-31 22:27:12 UTC (rev 33271)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ObjectTypeNode.java	2010-05-31 23:48:35 UTC (rev 33272)
@@ -136,6 +136,7 @@
 
         skipOnModify = in.readBoolean();
         objectMemoryEnabled = in.readBoolean();
+        expirationOffset = in.readLong();
     }
 
     public void writeExternal(ObjectOutput out) throws IOException {
@@ -143,6 +144,7 @@
         out.writeObject( objectType );
         out.writeBoolean( skipOnModify );
         out.writeBoolean( objectMemoryEnabled );
+        out.writeLong( expirationOffset );
     }
 
     /**

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java	2010-05-31 22:27:12 UTC (rev 33271)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/BuildUtils.java	2010-05-31 23:48:35 UTC (rev 33272)
@@ -106,10 +106,9 @@
             partition = RuleBasePartitionId.MAIN_PARTITION;
         } else if ( candidate instanceof ObjectTypeNode ) {
             // object type nodes are always shared
-            ObjectTypeNode otn = (ObjectTypeNode) candidate;
             Map<ObjectType, ObjectTypeNode> map = context.getRuleBase().getRete().getObjectTypeNodes( context.getCurrentEntryPoint() );
             if ( map != null ) {
-                otn = map.get( otn.getObjectType() );
+                ObjectTypeNode otn = map.get( ((ObjectTypeNode) candidate).getObjectType() );
                 if ( otn != null ) {
                     // adjusting expiration offset
                     otn.setExpirationOffset( Math.max( otn.getExpirationOffset(),
@@ -160,7 +159,6 @@
         }
         node.addAssociation( context.getRule(), context.peekRuleComponent() );
         return node;
-
     }
 
     /**

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java	2010-05-31 22:27:12 UTC (rev 33271)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/builder/PatternBuilder.java	2010-05-31 23:48:35 UTC (rev 33272)
@@ -57,7 +57,7 @@
 public class PatternBuilder
     implements
     ReteooComponentBuilder {
-    
+
     /**
      * @inheritDoc
      */
@@ -94,7 +94,7 @@
 
         // Create BetaConstraints object
         context.setBetaconstraints( betaConstraints );
-        
+
         // set behaviors list
         behaviors.addAll( pattern.getBehaviors() );
         context.setBehaviors( behaviors );
@@ -142,7 +142,7 @@
                                    List<Constraint> alphaConstraints,
                                    List<Constraint> betaConstraints) {
 
-        final List<?> constraints = pattern.getConstraints();
+        final List< ? > constraints = pattern.getConstraints();
 
         // check if cross products for identity patterns should be disabled
         checkRemoveIdentities( context,
@@ -151,8 +151,8 @@
 
         // checks if this pattern is nested inside a NOT CE
         final boolean isNegative = isNegative( context );
-        
-        for ( final Iterator<?> it = constraints.iterator(); it.hasNext(); ) {
+
+        for ( final Iterator< ? > it = constraints.iterator(); it.hasNext(); ) {
             final Object object = it.next();
             // Check if its a declaration
             if ( object instanceof Declaration ) {
@@ -165,31 +165,30 @@
                 alphaConstraints.add( constraint );
             } else if ( constraint.getType().equals( Constraint.ConstraintType.BETA ) ) {
                 betaConstraints.add( constraint );
-                if( isNegative && 
-                    context.getRuleBase().getConfiguration().getEventProcessingMode() == EventProcessingOption.STREAM && 
-                    pattern.getObjectType().isEvent() && 
-                    constraint.isTemporal() ) {
-                    checkDelaying( context, constraint );
+                if ( isNegative && context.getRuleBase().getConfiguration().getEventProcessingMode() == EventProcessingOption.STREAM && pattern.getObjectType().isEvent() && constraint.isTemporal() ) {
+                    checkDelaying( context,
+                                   constraint );
                 }
             } else {
-                throw new RuntimeDroolsException( "Unknown constraint type: "+constraint.getType()+". This is a bug. Please contact development team.");
+                throw new RuntimeDroolsException( "Unknown constraint type: " + constraint.getType() + ". This is a bug. Please contact development team." );
             }
         }
     }
 
-    private void checkDelaying( final BuildContext context, final Constraint constraint ) {
-        if( constraint instanceof VariableConstraint ) {
+    private void checkDelaying(final BuildContext context,
+                               final Constraint constraint) {
+        if ( constraint instanceof VariableConstraint ) {
             // variable constraints always require a single declaration
             Declaration target = constraint.getRequiredDeclarations()[0];
-            if( target.isPatternDeclaration() && target.getPattern().getObjectType().isEvent() ) {
+            if ( target.isPatternDeclaration() && target.getPattern().getObjectType().isEvent() ) {
                 long uplimit = ((VariableConstraint) constraint).getInterval().getUpperBound();
-                
-                Timer timer = context.getRule().getTimer();                
-                DurationTimer durationTimer = new DurationTimer(uplimit);                
-                
+
+                Timer timer = context.getRule().getTimer();
+                DurationTimer durationTimer = new DurationTimer( uplimit );
+
                 if ( timer instanceof CompositeMaxDurationTimer ) {
                     // already a composite so just add
-                    ((CompositeMaxDurationTimer)timer).addDurationTimer( durationTimer );
+                    ((CompositeMaxDurationTimer) timer).addDurationTimer( durationTimer );
                 } else {
                     if ( timer == null ) {
                         // no timer exists, so ok on it's own
@@ -199,10 +198,10 @@
                         CompositeMaxDurationTimer temp = new CompositeMaxDurationTimer();
                         if ( timer instanceof DurationTimer ) {
                             // previous timer was a duration, so add another DurationTimer
-                            temp.addDurationTimer( ( DurationTimer ) timer );                            
+                            temp.addDurationTimer( (DurationTimer) timer );
                         } else {
                             // previous timer was not a duration, so set it as the delegate Timer.
-                            temp.setTimer( context.getRule().getTimer() );    
+                            temp.setTimer( context.getRule().getTimer() );
                         }
                         // now add the new durationTimer
                         temp.addDurationTimer( durationTimer );
@@ -216,9 +215,9 @@
     }
 
     private boolean isNegative(final BuildContext context) {
-        for( ListIterator<RuleConditionElement> it = context.stackIterator(); it.hasPrevious(); ) {
+        for ( ListIterator<RuleConditionElement> it = context.stackIterator(); it.hasPrevious(); ) {
             RuleConditionElement rce = it.previous();
-            if( rce instanceof GroupElement && ((GroupElement)rce).isNot() ) {
+            if ( rce instanceof GroupElement && ((GroupElement) rce).isNot() ) {
                 return true;
             }
         }
@@ -246,7 +245,11 @@
                                                      epn,
                                                      objectType,
                                                      context );
-            
+
+            long expirationOffset = getExpiratioOffsetForType( context,
+                                                               objectType );
+            otn.setExpirationOffset( expirationOffset );
+
             if ( wms.length > 0 ) {
                 otn.attach( wms );
             } else {
@@ -257,6 +260,18 @@
         }
     }
 
+    private static long getExpiratioOffsetForType(BuildContext context,
+                                                  ObjectType objectType) {
+        long expirationOffset = -1;
+        for ( TypeDeclaration type : context.getRuleBase().getTypeDeclarations() ) {
+            if ( type.getObjectType().isAssignableFrom( objectType ) ) {
+                expirationOffset = Math.max( type.getExpirationOffset(),
+                                             expirationOffset );
+            }
+        }
+        return expirationOffset;
+    }
+
     public void attachAlphaNodes(final BuildContext context,
                                  final BuildUtils utils,
                                  final Pattern pattern,
@@ -288,20 +303,16 @@
                                                  (EntryPointNode) context.getObjectSource(),
                                                  objectType,
                                                  context );
-        if( objectType.isEvent() && EventProcessingOption.STREAM.equals( context.getRuleBase().getConfiguration().getEventProcessingMode() ) ) {
-            long expirationOffset = 0;
-            for( TypeDeclaration type : context.getRuleBase().getTypeDeclarations() ) {
-                if( type.getObjectType().isAssignableFrom( objectType ) ) {
-                    expirationOffset = Math.max( type.getExpirationOffset(), expirationOffset );
+        if ( objectType.isEvent() && EventProcessingOption.STREAM.equals( context.getRuleBase().getConfiguration().getEventProcessingMode() ) ) {
+            long expirationOffset = getExpiratioOffsetForType( context,
+                                                               objectType );
+            for ( Behavior behavior : pattern.getBehaviors() ) {
+                if ( behavior.getExpirationOffset() != -1 ) {
+                    expirationOffset = Math.max( behavior.getExpirationOffset(),
+                                                 expirationOffset );
                 }
-                
             }
-            for( Behavior behavior : pattern.getBehaviors() ) {
-                if( behavior.getExpirationOffset() != -1 ) {
-                    expirationOffset = Math.max( behavior.getExpirationOffset(), expirationOffset );
-                }
-            }
-            if( expirationOffset == 0) {
+            if ( expirationOffset == 0 ) {
                 otn.setExpirationOffset( context.getTemporalDistance().getExpirationOffset( pattern ) );
             } else {
                 otn.setExpirationOffset( expirationOffset );
@@ -340,10 +351,10 @@
         if ( context.getRuleBase().getConfiguration().isRemoveIdentities() && pattern.getObjectType().getClass() == ClassObjectType.class ) {
             // Check if this object type exists before
             // If it does we need stop instance equals cross product
-            final Class<?> thisClass = ((ClassObjectType) pattern.getObjectType()).getClassType();
+            final Class< ? > thisClass = ((ClassObjectType) pattern.getObjectType()).getClassType();
             for ( final Iterator<Pattern> it = context.getObjectType().iterator(); it.hasNext(); ) {
                 final Pattern previousPattern = it.next();
-                final Class<?> previousClass = ((ClassObjectType) previousPattern.getObjectType()).getClassType();
+                final Class< ? > previousClass = ((ClassObjectType) previousPattern.getObjectType()).getClassType();
                 if ( thisClass.isAssignableFrom( previousClass ) ) {
                     betaConstraints.add( new InstanceNotEqualsConstraint( previousPattern ) );
                 }
@@ -359,6 +370,6 @@
      */
     public boolean requiresLeftActivation(final BuildUtils utils,
                                           final RuleConditionElement rce) {
-        return  ((Pattern) rce).getSource() != null;
+        return ((Pattern) rce).getSource() != null;
     }
 }



More information about the jboss-svn-commits mailing list