Uploaded image for project: 'JBRULES'
  1. JBRULES
  2. JBRULES-2457

Wrong evaluation of rules and PseudoClock NPE

This issue belongs to an archived project. You can view it, but you can't modify it. Learn more

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • 6.0.0.Alpha1
    • 5.0.1.FINAL, 5.1.0.M1
    • None
    • None

      I've got a DRL file, having the following rules:

      • offline event for 3 minutes withou any online event meanwhile => send an offline notification
      • online event after offline event (within 3 minute range) => send an online notification

      I've also got an junit test:

      • insert offline event
      • pseudoclock advances 2m50s
      • insert online event
      • pseudoclock advances 15s
      • check if there's any notification

      And the result of the junit is:
      1) NPE when clock advances 15s
      java.lang.NullPointerException
      at org.drools.util.LinkedList.remove(LinkedList.java:113)
      at org.drools.common.Scheduler$DuractionJob.execute(Scheduler.java:71)
      at org.drools.time.impl.PseudoClockScheduler$ScheduledJob.call(PseudoClockScheduler.java:219)
      at org.drools.time.impl.PseudoClockScheduler.runCallBacks(PseudoClockScheduler.java:168)
      at org.drools.time.impl.PseudoClockScheduler.advanceTime(PseudoClockScheduler.java:130)

      2) When checking for a notification, it should have one online notification but has on offline notification

      At the bottom of this issue, there are snippets of junit code and drools rule file.
      Probably, the problem relies on Junit initialization code.

      T.I.A.

      – DRL file (snippet) –
      dialect "java"

      declare Event
      @role( event )
      @expires ( 7d )
      end

      global ISnmpNotifier snmpNotifier;

      /*************************/
      /* OFFLINE FOR 3 MINUTES */
      /*************************/
      rule "bit\dom - events offline (device offline for 3 minutes)"
      when
      $offline : Event( freeField == "101", $offlineLane : lane ) from entry-point "incoming"
      not ( $online : Event (freeField == "102", lane == $offlineLane, this after [0s,3m] $offline ) from entry-point "incoming" )
      then
      snmpNotifier.send( new Notification("101", "offline") );
      end
      rule "bit\dom - events online (device offline for 3 minutes)"
      when
      $offline: Event( freeField == "101", $lane : lane ) from entry-point "incoming"
      $online : Event( freeField == "102", lane == $lane, this after [3m] $offline ) from entry-point "incoming"
      then
      snmpNotifier.send( new Notification("102", "online") );
      end
      – DRL file (snippet) –

      – JUnit code (snippet) –
      package pt.brisa.sam.agent.rules.bit_dom;

      import java.util.concurrent.TimeUnit;

      import org.drools.KnowledgeBase;
      import org.drools.KnowledgeBaseConfiguration;
      import org.drools.KnowledgeBaseFactory;
      import org.drools.builder.KnowledgeBuilder;
      import org.drools.builder.KnowledgeBuilderFactory;
      import org.drools.builder.ResourceType;
      import org.drools.conf.EventProcessingOption;
      import org.drools.io.ResourceFactory;
      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;
      import org.junit.Assert;
      import org.junit.Before;
      import org.junit.Test;

      public class Jira_Drools {

      // values used to create test
      private String offlineEventCode = "101";
      private String onlineEventCode = "102";
      private String device = "device";

      // drools specific vars
      private WorkingMemoryEntryPoint workingMemoryEntryPoint;
      private PseudoClockScheduler clock = null;

      private StatefulKnowledgeSession kSession;

      /**

      • SnmpNotificationEventCase.getNumberOfNotificationsByExample(example)
      • .getNumberOfNotificationsByExample => from the notification queue, returns the number of notifications matching the given example
        */
        private SnmpNotificationEventCase snmpNotificationEventCase;

      @Before
      public void droolsSetup()

      { KnowledgeBaseConfiguration baseConfig; KnowledgeSessionConfiguration sessionConfig; KnowledgeBase kBase; KnowledgeBuilder kBuilder; baseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); baseConfig.setOption( EventProcessingOption.STREAM ); // Use stream mode kBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kBuilder.add(ResourceFactory.newFileResource( "test.drl"), ResourceType.DRL); kBase = KnowledgeBaseFactory.newKnowledgeBase(baseConfig); kBase.addKnowledgePackages(kBuilder.getKnowledgePackages()); sessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); sessionConfig.setOption( ClockTypeOption.get( "pseudo" ) ); kSession = kBase.newStatefulKnowledgeSession( sessionConfig, null ); kSession.setGlobal( "snmpNotifier", snmpNotificationEventCase ); workingMemoryEntryPoint = kSession.getWorkingMemoryEntryPoint("incoming"); clock = (PseudoClockScheduler) kSession.getSessionClock(); snmpNotificationEventCase = new SnmpNotificationEventCase(); }

      /* offline online 3min */
      /* ----|-----------------|----/--^---- */
      /* check */
      @Test
      public void deviceOffline_onlineBefore3minutes_checkAfter3minutes()

      { /* alocates OFFLINE and ONLINE events, EXAMPLE */ Event offlineEvent = new Event(); Event onlineEvent = new Event(); Notification example = new Notification(); /* configures the events */ offlineEvent.setFreeField( offlineEventCode ); offlineEvent.setEventType( (byte)5 ); offlineEvent.setEventCode( "0001000" + offlineEventCode ); offlineEvent.setFormattedMessage( "JUnit string test" ); offlineEvent.setLane( "102" ); onlineEvent.setFreeField( onlineEventCode ); onlineEvent.setEventType( (byte)3 ); onlineEvent.setEventCode( "0001000" + onlineEventCode ); onlineEvent.setFormattedMessage( "JUnit string test" ); onlineEvent.setLane( "102" ); /* insert offline event */ workingMemoryEntryPoint.insert( offlineEvent ); kSession.fireAllRules(); /* intermediary check - offline notification */ example.setRuleCode( "31" ); example.setEventCode( offlineEventCode ); Assert.assertTrue( "(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have", snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 ); /* advances the clock */ clock.advanceTime( 2, TimeUnit.MINUTES ); clock.advanceTime( 50, TimeUnit.SECONDS ); /* intermediary check - offline notification */ example.setRuleCode( "31" ); example.setEventCode( offlineEventCode ); Assert.assertTrue( "(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have", snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 ); /* insert online event */ workingMemoryEntryPoint.insert( onlineEvent ); kSession.fireAllRules(); /* intermediary check - offline notification */ example.setRuleCode( "31" ); example.setEventCode( offlineEventCode ); Assert.assertTrue( "(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have", snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 ); /* intermediary check - online notification */ example.setRuleCode( "31" ); example.setEventCode( onlineEventCode ); Assert.assertTrue( "(device "+device+")(ruleCode 31): There are ONLINE notifications, when it shouldn't have", snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 ); /* advances the clock */ clock.advanceTime( 15, TimeUnit.SECONDS ); /* since there's an ONLINE before the 3 minute's limit, there shouldn't be any trap regarding "last offline 3 minutes ago" */ example.setRuleCode( "31" ); example.setEventCode( offlineEventCode ); Assert.assertTrue( "(device "+device+")(ruleCode 31): There are OFFLINE notifications, when it shouldn't have", snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 0 ); example.setRuleCode( "31" ); example.setEventCode( onlineEventCode ); Assert.assertTrue( "(device "+device+")(ruleCode 31): There are ONLINE notifications, when it shouldn't have", snmpNotificationEventCase.getNumberOfNotificationsByExample(example) == 1 ); }

      }

      – JUnit code (snippet) –

            etirelli@redhat.com Edson Tirelli
            vitor.mendonca VĂ­tor Moreira (Inactive)
            Archiver:
            rhn-support-ceverson Clark Everson

              Created:
              Updated:
              Archived: