/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.compiler.integrationtests; import org.drools.compiler.Alarm; import org.drools.compiler.CommonTestMethodBase; import org.drools.compiler.Person; import org.drools.compiler.Sensor; import org.drools.core.event.DefaultAgendaEventListener; import org.junit.Test; import org.kie.api.KieServices; import org.kie.api.definition.rule.Rule; import org.kie.api.event.rule.AgendaEventListener; import org.kie.api.event.rule.MatchCancelledEvent; import org.kie.api.event.rule.MatchCreatedEvent; import org.kie.api.io.ResourceType; import org.kie.api.runtime.ClassObjectFilter; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieSessionConfiguration; import org.kie.api.runtime.rule.FactHandle; import org.kie.internal.KnowledgeBaseFactory; import org.kie.internal.runtime.conf.ForceEagerActivationFilter; import org.kie.internal.runtime.conf.ForceEagerActivationOption; import org.kie.internal.utils.KieHelper; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static java.util.Arrays.asList; /** * see JBPM-4764 */ public class ActivateAndDeleteOnListenerTest extends CommonTestMethodBase { @Test public void testActivateOnMatchAndDelete() throws Exception { String str = ""; str += "package org.drools.compiler.integrationtests \n"; str += "import " + Alarm.class.getCanonicalName() + " \n"; str += "import " + Sensor.class.getCanonicalName() + " \n"; str += "rule StringRule @Propagation(EAGER) ruleflow-group \"DROOLS_SYSTEM\"\n"; str += " when \n"; str += " $a : Alarm() \n"; str += " $s : Sensor() \n"; str += " then \n"; str += "end \n"; KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption( ForceEagerActivationOption.YES ); KieSession ksession = new KieHelper().addContent( str, ResourceType.DRL ) .build() .newKieSession(conf, null); ksession.addEventListener(new DefaultAgendaEventListener(){ @Override public void matchCreated(MatchCreatedEvent event) { Collection<? extends FactHandle> alarms = event.getKieRuntime().getFactHandles(new ClassObjectFilter(Alarm.class)); for (FactHandle alarm : alarms) { event.getKieRuntime().delete(alarm); } } }); // go ! Alarm alarm = new Alarm(); alarm.setMessage("test"); alarm.setNumber(123); ksession.insert(alarm); Sensor sensor = new Sensor(); sensor.setPressure(1); sensor.setTemperature(25); ksession.insert(sensor); ksession.fireAllRules(); } @Test public void testActivateOnMatchAndUpdate() throws Exception { String str = ""; str += "package org.drools.compiler.integrationtests \n"; str += "import " + Alarm.class.getCanonicalName() + " \n"; str += "import " + Sensor.class.getCanonicalName() + " \n"; str += "rule StringRule @Propagation(EAGER) ruleflow-group \"DROOLS_SYSTEM\"\n"; str += " when \n"; str += " $a : Alarm() \n"; str += " $s : Sensor() \n"; str += " then \n"; str += "end \n"; KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption( ForceEagerActivationOption.YES ); KieSession ksession = new KieHelper().addContent( str, ResourceType.DRL ) .build() .newKieSession( conf, null ); ksession.addEventListener(new DefaultAgendaEventListener(){ @Override public void matchCreated(MatchCreatedEvent event) { Collection<? extends FactHandle> alarms = event.getKieRuntime().getFactHandles(new ClassObjectFilter(Alarm.class)); for (FactHandle alarm : alarms) { event.getKieRuntime().update(alarm, new Alarm()); } } }); // go ! Alarm alarm = new Alarm(); alarm.setMessage("test"); alarm.setNumber(123); ksession.insert(alarm); Sensor sensor = new Sensor(); sensor.setPressure(1); sensor.setTemperature(25); ksession.insert(sensor); } @Test public void testEagerEvaluationWith2Paths() throws Exception { String str = "package org.simple \n" + "rule xxx \n" + "when \n" + " $s : String()\n" + " $i : Integer()\n" + "then \n" + "end \n" + "rule yyy \n" + "when \n" + " $s : String()\n" + " $i : Integer()\n" + "then \n" + "end \n"; KieServices ks = KieServices.Factory.get(); KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption(ForceEagerActivationOption.YES); KieSession ksession = new KieHelper() .addContent(str, ResourceType.DRL) .build() .newKieSession(conf, null); final List list = new ArrayList(); AgendaEventListener agendaEventListener = new org.kie.api.event.rule.DefaultAgendaEventListener() { @Override public void matchCreated(org.kie.api.event.rule.MatchCreatedEvent event) { list.add("activated"); } @Override public void matchCancelled( MatchCancelledEvent event ) { list.add("cancelled"); } }; ksession.addEventListener(agendaEventListener); ksession.insert("test"); assertEquals(0, list.size()); FactHandle fh = ksession.insert(1); assertEquals(2, list.size()); assertEquals("activated", list.get(0)); assertEquals("activated", list.get(1)); list.clear(); ksession.delete( fh ); assertEquals(2, list.size()); assertEquals("cancelled", list.get(0)); assertEquals("cancelled", list.get(1)); } @Test public void testEagerEvaluationWith2SubPaths() throws Exception { String str = "package org.simple \n" + "rule xxx \n" + "when \n" + " $s : String()\n" + " exists( Integer() or Long() )\n" + "then \n" + "end \n" + "rule yyy \n" + "when \n" + " $s : String()\n" + " exists( Integer() or Long() )\n" + "then \n" + "end \n"; KieServices ks = KieServices.Factory.get(); KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption(ForceEagerActivationOption.YES); KieSession ksession = new KieHelper() .addContent(str, ResourceType.DRL) .build() .newKieSession(conf, null); final List list = new ArrayList(); AgendaEventListener agendaEventListener = new org.kie.api.event.rule.DefaultAgendaEventListener() { public void matchCreated(org.kie.api.event.rule.MatchCreatedEvent event) { list.add("activated"); } }; ksession.addEventListener(agendaEventListener); ksession.insert("test"); assertEquals(0, list.size()); ksession.insert(1); assertEquals(2, list.size()); } @Test public void testOneLinkedAndOneUnlinkedPath() throws Exception { String str = "package org.simple \n" + "rule xxx \n" + "when \n" + " String()\n" + " Integer()\n" + " Long()\n" + "then \n" + "end \n" + "rule yyy \n" + "when \n" + " String()\n" + " Integer()\n" + " Boolean()\n" + "then \n" + "end \n"; KieServices ks = KieServices.Factory.get(); KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption(ForceEagerActivationOption.YES); KieSession ksession = new KieHelper() .addContent(str, ResourceType.DRL) .build() .newKieSession(conf, null); final List list = new ArrayList(); AgendaEventListener agendaEventListener = new org.kie.api.event.rule.DefaultAgendaEventListener() { public void matchCreated(org.kie.api.event.rule.MatchCreatedEvent event) { list.add(event.getMatch().getRule().getName()); } }; ksession.addEventListener(agendaEventListener); ksession.insert("test"); assertEquals(0, list.size()); ksession.insert(Boolean.TRUE); assertEquals(0, list.size()); ksession.insert(1); assertEquals(1, list.size()); assertEquals("yyy", list.get(0)); } @Test public void testOneLazyAndOneImmediateSubPath() throws Exception { String str = "package org.simple \n" + "rule xxx \n" + "when \n" + " $s : String()\n" + " exists( Integer() or Long() )\n" + "then \n" + "end \n" + "rule yyy \n" + "when \n" + " $s : String()\n" + " exists( Integer() or Long() )\n" + "then \n" + "end \n"; KieServices ks = KieServices.Factory.get(); KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption( new ForceEagerActivationOption.FILTERED( new ForceEagerActivationFilter() { @Override public boolean accept(Rule rule ) { return rule.getName().equals("yyy"); } })); KieSession ksession = new KieHelper() .addContent(str, ResourceType.DRL) .build() .newKieSession(conf, null); final List list = new ArrayList(); AgendaEventListener agendaEventListener = new org.kie.api.event.rule.DefaultAgendaEventListener() { public void matchCreated(org.kie.api.event.rule.MatchCreatedEvent event) { list.add(event.getMatch().getRule().getName()); } }; ksession.addEventListener(agendaEventListener); ksession.insert("test"); assertEquals(0, list.size()); ksession.insert(1); assertEquals(1, list.size()); assertEquals("yyy", list.get(0)); } @Test public void testEagerEvaluationWithSubSubPath() throws Exception { String str = "package org.simple \n" + "rule xxx \n" + "when \n" + " $s : String()\n" + " exists( Boolean() and not(not(Integer()) and not(Double())) )\n" + "then \n" + "end \n"; KieServices ks = KieServices.Factory.get(); KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); conf.setOption(ForceEagerActivationOption.YES); KieSession ksession = new KieHelper() .addContent(str, ResourceType.DRL) .build() .newKieSession(conf, null); final List list = new ArrayList(); AgendaEventListener agendaEventListener = new org.kie.api.event.rule.DefaultAgendaEventListener() { public void matchCreated(org.kie.api.event.rule.MatchCreatedEvent event) { list.add("activated"); } }; ksession.addEventListener(agendaEventListener); ksession.insert(Boolean.TRUE); assertEquals(0, list.size()); ksession.insert("test"); assertEquals(0, list.size()); ksession.insert(1); assertEquals(1, list.size()); } @Test(timeout = 10000L) public void testSegMemInitializationWithForceEagerActivation() throws InterruptedException { // DROOLS-1247 String drl = "global java.util.List list\n" + "declare SimpleFact end\n" + "declare AnotherFact end\n" + "\n" + "rule Init when\n" + " not (SimpleFact())\n" + " not (AnotherFact())\n" + "then\n" + " insert(new SimpleFact());\n" + " insert(new AnotherFact());\n" + "end\n" + "\n" + "rule R1 no-loop when\n" + " $f : SimpleFact() \n" + " $h : AnotherFact() \n" + " $s : String() \n" + " eval(true)\n" + "then\n" + " list.add(\"1\");\n" + "end\n" + "\n" + "rule R2 no-loop when\n" + " $f : SimpleFact() \n" + " $h : AnotherFact() \n" + " $s : String() \n" + "then\n" + " list.add(\"2\");\n" + "end"; KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration(); config.setOption( ForceEagerActivationOption.YES ); final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL ) .build() .newKieSession( config, null ); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertTrue( list.containsAll( asList("1", "2") ) ); } @Test(timeout = 10000L) public void testSegMemInitializationWithForceEagerActivationAndAcc() throws InterruptedException { // DROOLS-1247 String drl = "global java.util.List list\n" + "declare SimpleFact end\n" + "declare AnotherFact end\n" + "\n" + "rule Init when\n" + " not (SimpleFact())\n" + " not (AnotherFact())\n" + "then\n" + " insert(new SimpleFact());\n" + " insert(new AnotherFact());\n" + "end\n" + "\n" + "rule R1 no-loop when\n" + " $f : SimpleFact() \n" + " $h : AnotherFact() \n" + " $s : String() \n" + " accumulate($i: Integer(), $res : count($i))\n" + "then\n" + " list.add(\"1\");\n" + "end\n" + "\n" + "rule R2 no-loop when\n" + " $f : SimpleFact() \n" + " $h : AnotherFact() \n" + " $s : String() \n" + "then\n" + " list.add(\"2\");\n" + "end"; KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration(); config.setOption( ForceEagerActivationOption.YES ); final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL ) .build() .newKieSession( config, null ); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertTrue( list.containsAll( asList("1", "2") ) ); } @Test(timeout = 10000L) public void testSegMemInitializationWithForceEagerActivationAndExistsWithNots() throws InterruptedException { // DROOLS-1247 String drl = "global java.util.List list\n" + "declare SimpleFact end\n" + "declare AnotherFact end\n" + "\n" + "rule Init when\n" + " not (SimpleFact())\n" + " not (AnotherFact())\n" + "then\n" + " insert(new SimpleFact());\n" + " insert(new AnotherFact());\n" + "end\n" + "\n" + "rule R1 no-loop when\n" + " $f : SimpleFact() \n" + " $h : AnotherFact() \n" + " $s : String() \n" + " exists(not(Integer()) or not(Double()))\n" + "then\n" + " list.add(\"1\");\n" + "end\n" + "\n" + "rule R2 no-loop when\n" + " $f : SimpleFact() \n" + " $h : AnotherFact() \n" + " $s : String() \n" + "then\n" + " list.add(\"2\");\n" + "end"; KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration(); config.setOption( ForceEagerActivationOption.YES ); final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL ) .build() .newKieSession( config, null ); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertTrue( list.containsAll( asList("1", "2") ) ); } @Test(timeout = 10000L) public void testNoLoopWithForceEagerActivation() throws InterruptedException { // DROOLS-1349 String drl = "import " + Person.class.getCanonicalName() + "\n" + "\n" + "rule Birthday no-loop when\n" + " $p: Person()\n" + "then\n" + " modify($p) { setAge($p.getAge()+1) };\n" + "end"; KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration(); config.setOption( ForceEagerActivationOption.YES ); final KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL ) .build() .newKieSession( config, null ); Person mario = new Person("mario", 42); ksession.insert( mario ); ksession.fireAllRules(); assertEquals( 43, mario.getAge() ); } }