/* * 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.incrementalcompilation; import java.io.StringReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.drools.compiler.CommonTestMethodBase; import org.drools.compiler.FactA; import org.drools.compiler.Message; import org.drools.compiler.Person; import org.drools.compiler.kie.builder.impl.InternalKieModule; import org.drools.core.ClassObjectFilter; import org.drools.core.ClockType; import org.drools.core.command.runtime.rule.FireAllRulesCommand; import org.drools.core.definitions.rule.impl.RuleImpl; import org.drools.core.event.DefaultAgendaEventListener; import org.drools.core.impl.InternalKnowledgeBase; import org.drools.core.impl.KnowledgeBaseImpl; import org.drools.core.reteoo.EntryPointNode; import org.drools.core.reteoo.ObjectTypeNode; import org.drools.core.reteoo.Rete; import org.drools.core.reteoo.RuleTerminalNode; import org.drools.core.time.impl.PseudoClockScheduler; import org.junit.Ignore; import org.junit.Test; import org.kie.api.KieBase; import org.kie.api.KieServices; import org.kie.api.Service; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; import org.kie.api.builder.KieModule; import org.kie.api.builder.Message.Level; import org.kie.api.builder.ReleaseId; import org.kie.api.builder.Results; import org.kie.api.builder.model.KieBaseModel; import org.kie.api.builder.model.KieModuleModel; import org.kie.api.builder.model.KieSessionModel; import org.kie.api.command.BatchExecutionCommand; import org.kie.api.command.Command; import org.kie.api.conf.EventProcessingOption; import org.kie.api.definition.KiePackage; import org.kie.api.definition.rule.Rule; import org.kie.api.definition.type.FactType; import org.kie.api.event.rule.AfterMatchFiredEvent; import org.kie.api.io.ResourceType; import org.kie.api.logger.KieRuntimeLogger; import org.kie.api.runtime.Globals; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieSessionConfiguration; import org.kie.api.runtime.StatelessKieSession; import org.kie.api.runtime.conf.ClockTypeOption; import org.kie.api.runtime.conf.TimedRuleExecutionOption; import org.kie.api.runtime.conf.TimerJobFactoryOption; import org.kie.api.runtime.rule.FactHandle; import org.kie.api.time.SessionPseudoClock; import org.kie.internal.builder.IncrementalResults; import org.kie.internal.builder.InternalKieBuilder; import org.kie.internal.builder.conf.PropertySpecificOption; import org.kie.internal.command.CommandFactory; import static java.util.Arrays.asList; import static org.drools.core.util.DroolsTestUtil.rulestoMap; public class IncrementalCompilationTest extends CommonTestMethodBase { @Test public void testLoadOrderAfterRuleRemoval() throws Exception { String header = "package org.drools.compiler\n"; String drl1 = "rule R1 when\n" + " $m : Message( message == \"Hello World1\" )\n" + "then\n" + "end\n"; String drl2 = "rule R2 when\n" + " $m : Message( message == \"Hello World2\" )\n" + "then\n" + "end\n"; String drl3 = "rule R3 when\n" + " $m : Message( message == \"Hello World3\" )\n" + "then\n" + "end\n"; String drl4 = "rule R4 when\n" + " $m : Message( message == \"Hello World4\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1" ); KieModule km = createAndDeployJar( ks, releaseId1, header ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); createAndDeployAndTest( kc, "2", header, drl1 + drl2 + drl3, "R1", "R2", "R3" ); createAndDeployAndTest( kc, "3", header, drl1 + drl3, "R1", "R3" ); createAndDeployAndTest( kc, "4", header, drl2 + drl1 + drl4, "R2", "R1", "R4" ); createAndDeployAndTest( kc, "5", header, drl2 + drl1, "R2", "R1" ); createAndDeployAndTest( kc, "6", header, "" ); createAndDeployAndTest( kc, "7", header, drl3, "R3" ); } public static void createAndDeployAndTest( KieContainer kc, String version, String header, String drls, String... ruleNames ) { if ( ruleNames == null ) { ruleNames = new String[ 0 ]; } KieServices ks = KieServices.Factory.get(); StringBuilder sbuilder = new StringBuilder(); sbuilder.append( header ); sbuilder.append( drls ); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", version ); KieModule km = createAndDeployJar( ks, releaseId1, sbuilder.toString() ); kc.updateToVersion( km.getReleaseId() ); KiePackage kpkg = kc.getKieBase().getKiePackage( "org.drools.compiler" ); assertEquals( ruleNames.length, kpkg.getRules().size() ); Map<String, Rule> rules = rulestoMap( kpkg.getRules() ); int i = 0; for ( String ruleName : ruleNames ) { assertEquals( ruleName, i++, ( (RuleImpl) rules.get( ruleName ) ).getLoadOrder() ); } } @Test public void testKJarUpgrade() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( message == \"Hi Universe\" )\n" + "then\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1, drl2_1 ); // Create a session and fire rules KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); ksession.dispose(); // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl1, drl2_2 ); // try to update the container to version 1.1.0 kc.updateToVersion( releaseId2 ); // create and use a new session ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 2, ksession.fireAllRules() ); } @Test public void testKJarUpgradeSameSession() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( message == \"Hi Universe\" )\n" + "then\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1, drl2_1 ); // Create a session and fire rules KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl1, drl2_2 ); // try to update the container to version 1.1.0 kc.updateToVersion( releaseId2 ); // continue working with the session ksession.insert( new Message( "Hello World" ) ); assertEquals( 3, ksession.fireAllRules() ); } public static KieModule createAndDeployJar( KieServices ks, ReleaseId releaseId, String... drls ) { byte[] jar = createKJar( ks, releaseId, null, drls ); return deployJar( ks, jar ); } @Test public void testDeletedFile() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-delete", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1, drl2 ); KieContainer kieContainer = ks.newKieContainer( releaseId1 ); KieContainer kieContainer2 = ks.newKieContainer( releaseId1 ); KieSession ksession = kieContainer.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 2, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-delete", "1.0.1" ); km = createAndDeployJar( ks, releaseId2, null, drl2 ); kieContainer.updateToVersion( releaseId2 ); // test with the old ksession ... ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); // ... and with a brand new one ksession = kieContainer.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); // check that the second kieContainer hasn't been affected by the update of the first one KieSession ksession2 = kieContainer2.newKieSession(); ksession2.insert( new Message( "Hello World" ) ); assertEquals( 2, ksession2.fireAllRules() ); } @Test public void testIncrementalCompilationWithAddedError() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( message == \"Hi Universe\" )\n" + "then\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( nonExistentField == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ) .write( "src/main/resources/r2.drl", drl2_1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); KieContainer kieContainer = ks.newKieContainer( ks.getRepository().getDefaultReleaseId() ); KieSession ksession = kieContainer.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); kfs.write( "src/main/resources/r2.drl", drl2_2 ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 1, results.getAddedMessages().size() ); assertEquals( 0, results.getRemovedMessages().size() ); kieContainer.updateToVersion( ks.getRepository().getDefaultReleaseId() ); ksession = kieContainer.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); } @Test public void testIncrementalCompilationWithRemovedError() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( nonExistentField == \"Hello World\" )\n" + "then\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ) .write( "src/main/resources/r2.drl", drl2_1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 1, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); kfs.write( "src/main/resources/r2.drl", drl2_2 ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 0, results.getAddedMessages().size() ); assertEquals( 1, results.getRemovedMessages().size() ); KieContainer kieContainer = ks.newKieContainer( ks.getRepository().getDefaultReleaseId() ); KieSession ksession = kieContainer.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 2, ksession.fireAllRules() ); } @Test public void testIncrementalCompilationAddErrorThenRemoveError() throws Exception { //Valid String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; //Field is unknown ("nonExistentField" not "message") String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( nonExistentField == \"Hello World\" )\n" + "then\n" + "end\n"; //Valid String drl2_2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 0, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); //Add file with error - expect 1 "added" error message kfs.write( "src/main/resources/r2.drl", drl2_1 ); IncrementalResults addResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 1, addResults.getAddedMessages().size() ); assertEquals( 0, addResults.getRemovedMessages().size() ); //Update flawed file with correct version - expect 0 "added" error messages and removal of 1 previous error kfs.write( "src/main/resources/r2.drl", drl2_2 ); IncrementalResults removeResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 0, removeResults.getAddedMessages().size() ); assertEquals( 1, removeResults.getRemovedMessages().size() ); } @Test public void testIncrementalCompilationAddErrorThenRemoveIt() throws Exception { //Fact Type is unknown ("NonExistentClass" not "Message") String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : NonExistentClass()\n" + "then\n" + "end\n"; //Field is unknown ("nonExistentField" not "message") String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( nonExistentField == \"Hello World\" )\n" + "then\n" + "end\n"; //Valid String drl2_2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ); //Initial file contains errors KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 1, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); //Add file with error - expect 1 "added" error message kfs.write( "src/main/resources/r2.drl", drl2_1 ); IncrementalResults addResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 1, addResults.getAddedMessages().size() ); assertEquals( 0, addResults.getRemovedMessages().size() ); //Update flawed file with correct version - expect 0 "added" error messages and removal of 1 previous error relating to updated file kfs.write( "src/main/resources/r2.drl", drl2_2 ); IncrementalResults removeResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 0, removeResults.getAddedMessages().size() ); assertEquals( 1, removeResults.getRemovedMessages().size() ); } @Test public void testIncrementalCompilationWithDuplicatedRule() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2 = "package org.drools.compiler\n" + "rule R2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 0, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); kfs.write( "src/main/resources/r2_1.drl", drl2 ); IncrementalResults addResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2_1.drl" ).build(); assertEquals( 0, addResults.getAddedMessages().size() ); assertEquals( 0, addResults.getRemovedMessages().size() ); kfs.write( "src/main/resources/r2_2.drl", drl2 ); IncrementalResults removeResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2_2.drl" ).build(); assertEquals( 1, removeResults.getAddedMessages().size() ); assertEquals( 0, removeResults.getRemovedMessages().size() ); } @Test public void testIncrementalCompilationWithDuplicatedRuleInSameDRL() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n" + "rule R1 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 2, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); } @Test public void testIncrementalCompilationAddErrorBuildAllMessages() throws Exception { //Valid String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; //Field is unknown ("nonExistentField" not "message") String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( nonExistentField == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 0, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); //Add file with error - expect 1 "added" error message kfs.write( "src/main/resources/r2.drl", drl2_1 ); IncrementalResults addResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 1, addResults.getAddedMessages().size() ); assertEquals( 0, addResults.getRemovedMessages().size() ); //Check errors on a full build assertEquals( 1, ks.newKieBuilder( kfs ).buildAll().getResults().getMessages().size() ); } @Test public void testIncrementalCompilationAddErrorThenEmptyWithoutError() throws Exception { // BZ-1009369 //Invalid. Type "Smurf" is unknown String drl1 = "Smurf"; //Valid String drl2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); //Add file with error - expect 2 build messages KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 2, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); //Add empty file - expect no "added" messages and no "removed" messages kfs.write( "src/main/resources/r2.drl", "" ); IncrementalResults addResults1 = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 0, addResults1.getAddedMessages().size() ); assertEquals( 0, addResults1.getRemovedMessages().size() ); //Update file with no errors - expect no "added" messages and no "removed" messages kfs.write( "src/main/resources/r2.drl", drl2 ); IncrementalResults addResults2 = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 0, addResults2.getAddedMessages().size() ); assertEquals( 0, addResults2.getRemovedMessages().size() ); } @Test public void testRuleRemoval() throws Exception { String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2 = "rule R2 when\n" + " $m : Message( message == \"Hi Universe\" )\n" + "then\n" + "end\n"; String drl3 = "rule R3 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 + drl2 + drl3 ); // Create a session and fire rules KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KiePackage kpkg = kc.getKieBase().getKiePackage( "org.drools.compiler" ); assertEquals( 3, kpkg.getRules().size() ); Map<String, Rule> rules = rulestoMap( kpkg.getRules() ); assertNotNull( rules.get( "R1" ) ); assertNotNull( rules.get( "R2" ) ); assertNotNull( rules.get( "R3" ) ); RuleTerminalNode rtn1_1 = (RuleTerminalNode) ( (KnowledgeBaseImpl) kc.getKieBase() ).getReteooBuilder().getTerminalNodes( "org.drools.compiler.R1" )[ 0 ]; RuleTerminalNode rtn2_1 = (RuleTerminalNode) ( (KnowledgeBaseImpl) kc.getKieBase() ).getReteooBuilder().getTerminalNodes( "org.drools.compiler.R2" )[ 0 ]; RuleTerminalNode rtn3_1 = (RuleTerminalNode) ( (KnowledgeBaseImpl) kc.getKieBase() ).getReteooBuilder().getTerminalNodes( "org.drools.compiler.R3" )[ 0 ]; // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl1 + drl3 ); // try to update the container to version 1.1.0 kc.updateToVersion( releaseId2 ); KnowledgeBaseImpl rb_2 = ( (KnowledgeBaseImpl) kc.getKieBase() ); RuleTerminalNode rtn1_2 = (RuleTerminalNode) rb_2.getReteooBuilder().getTerminalNodes( "org.drools.compiler.R1" )[ 0 ]; RuleTerminalNode rtn3_2 = (RuleTerminalNode) rb_2.getReteooBuilder().getTerminalNodes( "org.drools.compiler.R3" )[ 0 ]; assertNull( rb_2.getReteooBuilder().getTerminalNodes( "org.drools.compiler.R2" ) ); assertSame( rtn3_1, rtn3_2 ); assertSame( rtn1_1, rtn1_2 ); kpkg = kc.getKieBase().getKiePackage( "org.drools.compiler" ); assertEquals( 2, kpkg.getRules().size() ); rules = rulestoMap( kpkg.getRules() ); assertNotNull( rules.get( "R1" ) ); assertNull( rules.get( "R2" ) ); assertNotNull( rules.get( "R3" ) ); } @Test public void testIncrementalCompilationWithSnapshots() throws Exception { // DROOLS-358 ReleaseId releaseId = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.0-SNAPSHOT" ); testIncrementalCompilation( releaseId, releaseId, false ); } @Test public void testIncrementalCompilationWithFixedVersions() throws Exception { // DROOLS-358 ReleaseId releaseId1 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.1" ); ReleaseId releaseId2 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.2" ); testIncrementalCompilation( releaseId1, releaseId2, false ); } @Test public void testIncrementalCompilationWithDeclaredType() throws Exception { // DROOLS-358 ReleaseId releaseId1 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.1" ); ReleaseId releaseId2 = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.2" ); testIncrementalCompilation( releaseId1, releaseId2, true ); } private void testIncrementalCompilation( ReleaseId releaseId1, ReleaseId releaseId2, boolean useDeclaredType ) { String drl1 = "package org.drools.compiler\n" + "global java.util.List list\n" + "rule R0 when then list.add( \"000\" ); end \n" + "" + "rule R1 when\n" + " $s : String() " + "then\n" + " list.add( \"a\" + $s );" + "end\n"; String drl2 = useDeclaredType ? "package org.drools.compiler\n" + "global java.util.List list\n" + "declare StringWrapper\n" + " s : String\n" + "end\n" + "rule RInit when\n" + " $s : String() \n" + "then\n" + " insert( new StringWrapper( $s ) );" + "end\n" + "rule R2 when\n" + " $s : StringWrapper() \n" + "then\n" + " list.add( \"b\" + $s.getS() );" + "end\n" : "package org.drools.compiler\n" + "global java.util.List list\n" + "rule R2 when\n" + " $s : String() \n" + "then\n" + " list.add( \"b\" + $s );" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( releaseId1 ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl1.txt" ) ); kieBuilder.buildAll(); assertEquals( 0, kieBuilder.getResults().getMessages().size() ); KieModule kieModule = kieBuilder.getKieModule(); assertEquals( releaseId1, kieModule.getReleaseId() ); KieContainer kc = ks.newKieContainer( releaseId1 ); KieSession ksession = kc.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "Foo" ); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertTrue( list.containsAll( asList( "000", "aFoo" ) ) ); list.clear(); kfs.generateAndWritePomXML( releaseId2 ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl2.txt" ) ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).incrementalBuild(); assertEquals( 0, results.getAddedMessages().size() ); kieModule = kieBuilder.getKieModule(); assertEquals( releaseId2, kieModule.getReleaseId() ); Results updateResults = kc.updateToVersion( releaseId2 ); assertEquals( 0, updateResults.getMessages().size() ); ksession.insert( "Bar" ); ksession.fireAllRules(); assertEquals( 3, list.size() ); assertTrue( list.containsAll( asList( "bBar", "bFoo", "aBar" ) ) ); } @Test public void testIncrementalCompilationWithRedeclares() { // DROOLS-363 String drl1 = "package org.drools.compiler\n" + "global java.util.List list\n" + "" + "declare Fooz id : int end \n" + "" + "rule R0 when then insert( new Fooz( 1 ) ); end \n" + "" + ""; String drl2 = "package org.drools.compiler\n" + "global java.util.List list\n" + "" + "declare Fooz id : int end \n" + "" + "declare Barz end \n" + "" + "rule R2 when then insert( new Fooz( 2 ) ); end \n" + "" + "rule R1 when\n" + " $f : Fooz() " + "then\n" + " list.add( $f.getId() );" + " System.out.println( \"Foo in \" + $f + \" >> \" + System.identityHashCode( $f.getClass() ) ); \n" + "end\n" + ""; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); ReleaseId id = ks.newReleaseId( "org.test", "myTest", "1.0-SNAPSHOT" ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( id ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl1.drl" ) ); kieBuilder.buildAll(); KieContainer kc = ks.newKieContainer( id ); KieSession ksession = kc.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.fireAllRules(); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl2.txt" ) ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).incrementalBuild(); assertEquals( 0, results.getAddedMessages().size() ); Results updateResults = kc.updateToVersion( id ); assertEquals( 0, updateResults.getMessages().size() ); ksession.fireAllRules(); assertEquals( 2, list.size() ); } @Test public void testIncrementalCompilationWithAmbiguousRedeclares() { String drl1 = "package domestic; " + "import foreign.*; " + "declare foreign.Score " + " id : String " + "end "; String drl2 = "\n" + "package domestic; " + "import foreign.*; " + "declare foreign.Score " + " id : String " + "end\n" + "declare Score " + " value : double " + "end " + ""; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); ReleaseId id = ks.newReleaseId( "org.test", "foo", "1.0-SNAPSHOT" ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( id ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl1.drl" ) ); kieBuilder.buildAll(); KieContainer kc = ks.newKieContainer( id ); KieSession ksession = kc.newKieSession(); ksession.fireAllRules(); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl2.drl" ) ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).incrementalBuild(); System.out.println( results.getAddedMessages() ); assertEquals( 0, results.getAddedMessages().size() ); Results updateResults = kc.updateToVersion( id ); assertEquals( 0, updateResults.getMessages().size() ); } @Test public void testIncrementalCompilationWithModuleOverride() { String drl1 = "package org.test.compiler; " + "global java.util.List list; " + "rule A when $s : String() then System.out.println( 'AAA' + $s ); list.add( 'A' + $s ); end " + ""; String drl2 = "package totally.unrelated.pack; " + "global java.util.List list; " + "rule B when $s : String() then System.out.println( 'BBB' + $s ); list.add( 'B' + $s ); end " + ""; String drl3 = "package totally.unrelated.pack; " + "global java.util.List list; " + "rule C when $s : String() then System.out.println( 'CCC' + $s ); list.add( 'C' + $s ); end " + ""; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); ReleaseId id = ks.newReleaseId( "org.test", "foo", "1.0-SNAPSHOT" ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( id ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl1.drl" ) ); kieBuilder.buildAll(); KieContainer kc = ks.newKieContainer( id ); KieSession ksession = kc.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "X" ); ksession.fireAllRules(); assertTrue( list.contains( "AX" ) ); KieFileSystem kfs2 = ks.newKieFileSystem(); KieBuilder kieBuilder2 = ks.newKieBuilder( kfs2 ); kfs2.generateAndWritePomXML( id ); kfs2.write( ks.getResources() .newReaderResource( new StringReader( drl2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drla.drl" ) ); kieBuilder2.buildAll(); KieContainer kc2 = ks.newKieContainer( id ); KieSession ksession2 = kc2.newKieSession(); ksession2.setGlobal( "list", list ); ksession2.insert( "X" ); ksession2.fireAllRules(); kfs2.write( ks.getResources() .newReaderResource( new StringReader( drl3 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drlb.drl" ) ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder2 ).incrementalBuild(); assertEquals( 0, results.getAddedMessages().size() ); kc2.updateToVersion( id ); ksession2.fireAllRules(); assertEquals( Arrays.asList( "AX", "BX", "CX" ), list ); } @Test public void testIncrementalCompilationWithMissingKSession() throws Exception { //https://bugzilla.redhat.com/show_bug.cgi?id=1066059 String pom = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + " <modelVersion>4.0.0</modelVersion>\n" + " <groupId>org.kie</groupId>\n" + " <artifactId>test</artifactId>\n" + " <version>1.0</version>\n" + " <packaging>jar</packaging>\n" + " <name>test</name>\n" + "</project>"; String kmodule = "<kmodule xmlns=\"http://www.drools.org/xsd/kmodule\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + "<kbase name=\"kbase\" includes=\"nonExistent\"/>\n" + "</kmodule>"; String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( message == \"Hi Universe\" )\n" + "then\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "rule R2_2 when\n" + " $m : Message( nonExistentField == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "pom.xml", pom ) .write( "src/main/resources/META-INF/kmodule.xml", kmodule ) .write( "src/main/resources/r2.drl", drl2_1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); kfs.write( "src/main/resources/r2.drl", drl2_2 ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); // since there's a missing include tha kiebase is not built at all assertEquals( 0, results.getAddedMessages().size() ); assertEquals( 0, results.getRemovedMessages().size() ); } @Test public void testIncrementalCompilationWithIncludes() throws Exception { // DROOLS-462 String drl1 = "global java.util.List list\n" + "rule R1 when\n" + " $s : String() " + "then\n" + " list.add( \"a\" + $s );" + "end\n"; String drl2 = "global java.util.List list\n" + "rule R1 when\n" + " $s : String() " + "then\n" + " list.add( \"b\" + $s );" + "end\n"; ReleaseId releaseId = KieServices.Factory.get().newReleaseId( "org.test", "test", "1.0.0-SNAPSHOT" ); KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ) .addPackage( "org.pkg1" ); kieBaseModel1.newKieSessionModel( "KSession1" ); KieBaseModel kieBaseModel2 = kproj.newKieBaseModel( "KBase2" ) .addPackage( "org.pkg2" ) .addInclude( "KBase1" ); kieBaseModel2.newKieSessionModel( "KSession2" ); KieFileSystem kfs = ks.newKieFileSystem() .generateAndWritePomXML( releaseId ) .write( "src/main/resources/KBase1/org/pkg1/r1.drl", drl1 ) .writeKModuleXML( kproj.toXML() ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kieBuilder.buildAll(); assertEquals( 0, kieBuilder.getResults().getMessages().size() ); KieContainer kc = ks.newKieContainer( releaseId ); KieSession ksession = kc.newKieSession( "KSession2" ); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "Foo" ); ksession.fireAllRules(); assertEquals( 1, list.size() ); assertEquals( "aFoo", list.get( 0 ) ); list.clear(); kfs.delete( "src/main/resources/KBase1/org/pkg1/r1.drl" ); kfs.write( "src/main/resources/KBase1/org/pkg1/r2.drl", drl2 ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).incrementalBuild(); assertEquals( 0, results.getAddedMessages().size() ); Results updateResults = kc.updateToVersion( releaseId ); assertEquals( 0, updateResults.getMessages().size() ); ksession.insert( "Bar" ); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertTrue( list.containsAll( asList( "bBar", "bFoo" ) ) ); } @Test public void testIncrementalCompilationWithInvalidDRL() throws Exception { String drl1 = "Smurf"; String drl2_1 = "package org.drools.compiler\n" + "rule R2\n" + "when\n" + " $m : NonExistentClass()\n" + "then\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "rule R2\n" + "when\n" + " $m : Message()\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); //First file contains errors kfs.write( "src/main/resources/r1.drl", drl1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); Results results1 = kieBuilder.getResults(); assertEquals( 2, results1.getMessages().size() ); //Second file also contains errors.. expect some added messages kfs.write( "src/main/resources/r2.drl", drl2_1 ); IncrementalResults results2 = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 1, results2.getAddedMessages().size() ); assertEquals( 0, results2.getRemovedMessages().size() ); //Correct second file... expect original errors relating to the file to be removed kfs.write( "src/main/resources/r2.drl", drl2_2 ); IncrementalResults results3 = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 0, results3.getAddedMessages().size() ); assertEquals( 1, results3.getRemovedMessages().size() ); //Remove first file... expect related errors to be removed kfs.delete( "src/main/resources/r1.drl" ); IncrementalResults results4 = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r1.drl" ).build(); assertEquals( 0, results4.getAddedMessages().size() ); assertEquals( 2, results4.getRemovedMessages().size() ); } @Test public void testKJarUpgradeSameSessionAddingGlobal() throws Exception { // DROOLS-523 String drl1 = "package org.drools.compiler\n" + "global java.lang.String foo\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2_1 = "package org.drools.compiler\n" + "rule R2_1 when\n" + " $m : Message( message == \"Hi Universe\" )\n" + "then\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "global java.lang.String foo\n" + "rule R2_2 when\n" + " $m : Message( message == foo )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1, drl2_1 ); // Create a session and fire rules KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl1, drl2_2 ); // try to update the container to version 1.1.0 kc.updateToVersion( releaseId2 ); ksession.setGlobal( "foo", "Hello World" ); // continue working with the session ksession.insert( new Message( "Hello World" ) ); assertEquals( 2, ksession.fireAllRules() ); } public static class FooEvent { private long mytime; public FooEvent(long mytime) { this.mytime = mytime; } public long getMytime() { return mytime; } } @Test public void testUpdateWithDeclarationPresent() throws Exception { // DROOLS-560 String header = "package org.drools.compiler\n" + "import org.drools.compiler.integrationtests.incrementalcompilation.IncrementalCompilationTest.FooEvent\n"; String declaration = "declare FooEvent\n" + " @timestamp( mytime )\n" + " @role( event )\n" + "end\n"; String rule1 = "rule R1 when\n" + " $e : FooEvent( )\n" + "then\n" + " insert(new Message(\"Hello R1\"));\n" + "end\n"; String rule2 = "rule R1 when\n" + " $e : FooEvent( )\n" + "then\n" + " insert(new Message(\"Hello R2\"));\n" + "end\n"; String file1 = header + declaration + rule1; String file2 = header + declaration + rule2; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, file1 ); // Create a session and fire rules KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new FooEvent( 0 ) ); assertEquals( 1, ksession.fireAllRules() ); // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, file2 ); // try to update the container to version 1.1.0 Results results = kc.updateToVersion( releaseId2 ); assertFalse("Errors detected on updateToVersion: " + results.getMessages(org.kie.api.builder.Message.Level.ERROR), results.hasMessages(org.kie.api.builder.Message.Level.ERROR)); // continue working with the session ksession.insert( new FooEvent( 1 ) ); assertEquals( 2, ksession.fireAllRules() ); } @Test public void testKJarUpgradeWithDSL() throws Exception { // DROOLS-718 String dsl = "[when][]There is a Message=Message()\n" + "[when][]-with message \"{factId}\"=message==\"{factId}\"\n" + "\n" + "[then][]Print \"{message}\"=System.out.println(\"{message}\");\n"; String drl2_1 = "package org.drools.compiler\n" + "rule \"bla\"\n" + "when\n" + "\tThere is a Message\t \n" + "\t-with message \"Hi Universe\"\n" + "then\n" + "\tPrint \"Found a Message Hi Universe.\"\n" + "end\n"; String drl2_2 = "package org.drools.compiler\n" + "rule \"bla\"\n" + "when\n" + "\tThere is a Message\t \n" + "\t-with message \"Hello World\"\n" + "then\n" + "\tPrint \"Found a Message Hello World.\"\n" + "end\n"; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJarWithDSL( ks, releaseId1, dsl, drl2_1 ); // Create a session and fire rules KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 0, ksession.fireAllRules() ); ksession.dispose(); // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJarWithDSL( ks, releaseId2, dsl, drl2_2 ); // try to update the container to version 1.1.0 kc.updateToVersion( releaseId2 ); // create and use a new session ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); } public static KieModule createAndDeployJarWithDSL( KieServices ks, ReleaseId releaseId, String... drls ) { KieFileSystem kfs = ks.newKieFileSystem(); kfs.generateAndWritePomXML(releaseId); for (int i = 0; i < drls.length; i++) { String extension = i == 0 ? "dsl" : "rdslr"; if (drls[i] != null) { kfs.write("src/main/resources/r" + i + "." + extension, drls[i]); } } KieBuilder kb = ks.newKieBuilder(kfs).buildAll(); if( kb.getResults().hasMessages( org.kie.api.builder.Message.Level.ERROR ) ) { for( org.kie.api.builder.Message result : kb.getResults().getMessages() ) { System.out.println(result.getText()); } return null; } InternalKieModule kieModule = (InternalKieModule) ks.getRepository() .getKieModule(releaseId); byte[] jar = kieModule.getBytes(); return deployJar( ks, jar ); } @Test public void testRemoveRuleAndThenFactInStreamMode() throws Exception { // DROOLS-731 String header = "package org.some.test\n" + "import org.drools.compiler.FactA\n"; String declaration = "declare FactA\n" + "@role(event)" + "end\n"; String rule2 = "rule R when\n" + " $FactA : FactA ($FactA_field2 : field2 == 105742)\n" + " not FactA($FactA_field2 == 105742)\n" + "then\n" + "end\n"; String file2 = header + declaration + rule2; KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId("org.kie", "test-upgrade", "1.0.0"); KieModule km = createAndDeployJarInStreamMode( ks, releaseId1, file2 ); // Create a session and fire rules KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); FactA factA = new FactA(105742); factA.setField1( "entry:" + 105742 ); FactHandle fh = ksession.insert( factA ); // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJarInStreamMode(ks, releaseId2); // try to update the container to version 1.1.0 kc.updateToVersion( releaseId2 ); ksession.delete(fh); } public static KieModule createAndDeployJarInStreamMode(KieServices ks, ReleaseId releaseId, String... drls) { KieFileSystem kfs = ks.newKieFileSystem(); kfs.generateAndWritePomXML(releaseId); KieModuleModel module = ks.newKieModuleModel(); KieBaseModel defaultBase = module.newKieBaseModel( "kBase1" ); defaultBase.setEventProcessingMode(EventProcessingOption.STREAM).setDefault( true ); defaultBase.newKieSessionModel("defaultKSession").setDefault(true); kfs.writeKModuleXML( module.toXML() ); for (int i = 0; i < drls.length; i++) { kfs.write("src/main/resources/rules" + i + ".drl", drls[i]); } KieBuilder kb = ks.newKieBuilder( kfs ); kb.buildAll(); if (kb.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) { System.out.println(kb.getResults().toString()); } return kb.getKieModule(); } @Test @Ignore("this test takes too long and cannot be emulated with a pseudo clock") public void testIncrementalCompilationWithFireUntilHalt() throws Exception { // DROOLS-782 String drl1 = getCronRule(3) + getCronRule(6); String drl2 = getCronRule( 8 ) + getCronRule(10) + getCronRule(5); KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-fireUntilHalt", "1.0.0" ); //KieModule km = createAndDeployJar( ks, releaseId1, testRuleAdd1, testRuleAdd2 ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); // Create a session and fire rules final KieContainer kc = ks.newKieContainer( km.getReleaseId() ); final KieSession kieSession = kc.newKieSession(); new Thread(new Runnable() { public void run() { kieSession.fireUntilHalt(); try { Thread.sleep( 20000 ); } catch (InterruptedException e) { throw new RuntimeException( e ); } kieSession.halt(); } }).start(); Thread.sleep( 10000 ); // Create a new jar for version 1.1.0 ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-fireUntilHalt", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl2 ); // try to update the container to version 1.1.0 Results results = kc.updateToVersion( releaseId2 ); assertFalse( "Errors detected on updateToVersion: " + results.getMessages( org.kie.api.builder.Message.Level.ERROR ), results.hasMessages( org.kie.api.builder.Message.Level.ERROR ) ); Thread.sleep( 10000 ); } private String getCronRule(int seconds) { return "rule R" + seconds + " " + "timer (cron: */" + seconds + " * * * * ?) " + "when then System.out.println('Hey there, I print every " + seconds + " seconds'); " + "end\n"; } @Test public void testKJarUpgradeSameSessionRemovingGlobal() throws Exception { // DROOLS-752 String drl1 = "package org.drools.compiler\n" + "global java.lang.String foo\n" + "global java.lang.String bar\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + "end\n"; String drl2 = "package org.drools.compiler\n" + "global java.lang.String foo\n" + "global java.lang.String baz\n" + "rule R2 when\n" + " $m : Message( )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.setGlobal( "foo", "foo" ); ksession.setGlobal( "bar", "bar" ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl2 ); kc.updateToVersion( releaseId2 ); ksession.setGlobal( "baz", "baz" ); Globals globals = ksession.getGlobals(); assertEquals( 2, globals.getGlobalKeys().size() ); assertEquals( "foo", ksession.getGlobal( "foo" ) ); assertNull( ksession.getGlobal( "bar" ) ); assertEquals( "baz", ksession.getGlobal( "baz" ) ); } @Test public void testUpdateVersionWithKSessionLogger() { // DROOLS-790 String drl1 = "import java.util.List\n" + "import java.util.ArrayList\n" + "\n" + "rule \"Test1\"\n" + "\n" + "when\n" + " $a : Integer()\n" + "then\n" + " insert(new ArrayList());\n" + "end\n"; String drl2 = "rule \"Test2\"\n" + "when\n" + " $b : List()\n" + " then\n" + " $b.isEmpty();\n" + "end"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); StatelessKieSession statelessKieSession = kc.newStatelessKieSession(); KieRuntimeLogger kieRuntimeLogger = ks.getLoggers().newConsoleLogger( statelessKieSession ); List<Command> cmds = new ArrayList<Command>(); cmds.add( CommandFactory.newInsertElements( new ArrayList() ) ); FireAllRulesCommand fireAllRulesCommand = (FireAllRulesCommand) CommandFactory.newFireAllRules(); cmds.add( fireAllRulesCommand ); cmds.add( CommandFactory.newGetObjects( "returnedObjects" ) ); BatchExecutionCommand batchExecutionCommand = CommandFactory.newBatchExecution( cmds ); statelessKieSession.execute( batchExecutionCommand ); kieRuntimeLogger.close(); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl1 + drl2 ); kc.updateToVersion( km.getReleaseId() ); } @Test public void testChangeParentRule() { String drl1 = "global java.util.List list;" + "rule B extends A when\n" + " $s : String()\n" + "then\n" + " list.add( $s );\n" + "end\n" + "\n" + "rule A when\n" + " $i : Integer( this > 3 )\n" + "then\n" + "end"; String drl2 = "global java.util.List list;" + "rule B extends A when\n" + " $s : String()\n" + "then\n" + " list.add( $s );\n" + "end\n" + "\n" + "rule A when\n" + " $i : Integer( this > 2 )\n" + "then\n" + "end"; String drl3 = "global java.util.List list;" + "rule B extends A when\n" + " $s : String()\n" + "then\n" + " list.add( $s );\n" + "end\n" + "\n" + "rule A when\n" + " $i : Integer( this > 5 )\n" + "then\n" + "end"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( 4 ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 1, list.size() ); list.clear(); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); createAndDeployJar( ks, releaseId2, drl2 ); kc.updateToVersion( releaseId2 ); ksession.fireAllRules(); assertEquals( 1, list.size() ); list.clear(); ReleaseId releaseId3 = ks.newReleaseId( "org.kie", "test-upgrade", "1.2.0" ); createAndDeployJar( ks, releaseId3, drl3 ); kc.updateToVersion( releaseId3 ); ksession.fireAllRules(); assertEquals( 0, list.size() ); } @Test public void testRuleRemovalAfterUpdate() { // DROOLS-801 String drl = "rule Rule1\n" + " when\n" + " Integer()\n" + " String()\n" + " Long()\n" + " not (Double())\n" + " then \n" + "end\n" + "\n" + "rule Rule2\n" + " when\n" + " Integer()\n" + " String()\n" + " then \n" + "end"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( "test" ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); createAndDeployJar( ks, releaseId2, drl ); kc.updateToVersion( releaseId2 ); FactHandle handle = ksession.insert( 1 ); ksession.fireAllRules(); ksession.update( handle, 1 ); ksession.fireAllRules(); ReleaseId releaseId3 = ks.newReleaseId( "org.kie", "test-upgrade", "1.2.0" ); createAndDeployJar( ks, releaseId3 ); kc.updateToVersion( releaseId3 ); } @Test public void testIncrementalTypeDeclarationOnInterface() { // DROOLS-861 String drl1 = "import " + Service.class.getCanonicalName() + "\n" + "rule A when\n" + " Service( )\n" + "then\n" + "end"; String drl2 = "import " + Service.class.getCanonicalName() + "\n" + "declare Service @role( event ) end\n" + "rule A when\n" + " Service( )\n" + "then\n" + "end"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer( releaseId1 ); KieSession ksession = kc.newKieSession(); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); createAndDeployJar( ks, releaseId2, drl2 ); kc.updateToVersion( releaseId2 ); } public static class MyEvent { private final int id; public MyEvent( int id ) { this.id = id; } public int getId() { return id; } @Override public String toString() { return "MyEvent: " + id; } } @Test public void testChangeWindowTime() { // DROOLS-853 String drl1 = "import " + MyEvent.class.getCanonicalName() + "\n" + "global java.util.concurrent.atomic.AtomicInteger result\n" + "declare MyEvent @expires(5m) @role( event ) end\n" + "rule A when\n" + " accumulate( $e : MyEvent() over window:time(10s), $result : count($e) )\n" + "then" + " System.out.println(\"Result-1: \" + $result);\n" + " result.set( $result.intValue() );\n" + "end"; String drl2 = "import " + MyEvent.class.getCanonicalName() + "\n" + "global java.util.concurrent.atomic.AtomicInteger result\n" + "declare MyEvent @expires(5m) @role( event ) end\n" + "rule A when\n" + " accumulate( $e : MyEvent() over window:time(5s), $result : count($e) )\n" + "then" + " System.out.println(\"Result-2: \" + $result);\n" + " result.set( $result.intValue() );\n" + "end"; KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ).setDefault( true ) .setEventProcessingMode(EventProcessingOption.STREAM); KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel("KSession1").setDefault(true) .setType(KieSessionModel.KieSessionType.STATEFUL) .setClockType( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() )); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1 ) ); KieContainer kc = ks.newKieContainer( releaseId1 ); KieSession ksession = kc.newKieSession(); PseudoClockScheduler clock = ksession.getSessionClock(); AtomicInteger result = new AtomicInteger( 0 ); ksession.setGlobal( "result", result ); ksession.insert( new MyEvent( 1 ) ); clock.advanceTime(4, TimeUnit.SECONDS); ksession.insert( new MyEvent( 2 ) ); clock.advanceTime(4, TimeUnit.SECONDS); ksession.insert( new MyEvent( 3 ) ); ksession.fireAllRules(); assertEquals( 3, result.get() ); // expires 1 clock.advanceTime(3, TimeUnit.SECONDS); ksession.fireAllRules(); assertEquals( 2, result.get() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); deployJar( ks, createKJar( ks, kproj, releaseId2, null, drl2 ) ); kc.updateToVersion( releaseId2 ); // shorter window: 2 is out ksession.fireAllRules(); assertEquals( 1, result.get() ); ksession.insert( new MyEvent( 4 ) ); ksession.insert( new MyEvent( 5 ) ); ksession.fireAllRules(); assertEquals( 3, result.get() ); // expires 3 clock.advanceTime(3, TimeUnit.SECONDS); ksession.fireAllRules(); assertEquals( 2, result.get() ); // expires 4 & 5 clock.advanceTime(3, TimeUnit.SECONDS); ksession.fireAllRules(); assertEquals( 0, result.get() ); } @Test public void testNonHashablePropertyWithIncrementalCompilation() { // DROOLS-870 String drl1 = "rule \"HelloGreetingService\"\n" + " when\n" + " $name : String(this == \"first\")\n" + " then\n" + " System.out.println(String.format(\"Hello %s!\", $name));\n" + "end\n" + "rule \"CiaoGreetingService\"\n" + " when\n" + " $name : String(this == \"second\")\n" + " then\n" + " System.out.println(String.format(\"Ciao %s!\", $name));\n" + "end\n"; String drl2 = "rule \"HelloGreetingService\"\n" + " when\n" + " $name : String(this == \"first\")\n" + " then\n" + " System.out.println(String.format(\"Modified Hello %s!\", $name));\n" + "end\n" + "rule \"CiaoGreetingService\"\n" + " when\n" + " $name : String(this == \"second\")\n" + " then\n" + " System.out.println(String.format(\"Modified Ciao %s!\", $name));\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer( releaseId1 ); KieSession ksession = kc.newKieSession(); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); createAndDeployJar( ks, releaseId2, drl2 ); kc.updateToVersion( releaseId2 ); } @Test public void testIncrementalCompilationWithSlidingWindow() { // DROOLS-881 String drl1 = "import " + MyEvent.class.getCanonicalName() + "\n" + "declare MyEvent @role( event ) end\n" + "rule A when\n" + " Number($number : intValue)\n" + " from accumulate( MyEvent($id : id) over window:time(10s), sum($id) )\n" + "then\n" + " System.out.println(\"1. SUM : \" + $number);\n" + "end\n" + "\n" + "rule B when\n" + " Number($number : intValue)\n" + " from accumulate( MyEvent($id : id) over window:time(10s), count($id) )\n" + "then\n" + " System.out.println(\"1. CNT : \" + $number);\n" + "end"; String drl2 = "import " + MyEvent.class.getCanonicalName() + "\n" + "declare MyEvent @role( event ) end\n" + "rule A when\n" + " Number($number : intValue)\n" + " from accumulate( MyEvent($id : id) over window:time(10s), sum($id) )\n" + "then\n" + " System.out.println(\"2. SUM : \" + $number);\n" + "end\n" + "\n" + "rule B when\n" + " Number($number : intValue)\n" + " from accumulate( MyEvent($id : id) over window:time(10s), count($id) )\n" + "then\n" + " System.out.println(\"2. CNT : \" + $number);\n" + "end"; KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ).setDefault( true ) .setEventProcessingMode(EventProcessingOption.STREAM); KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel("KSession1").setDefault(true) .setType(KieSessionModel.KieSessionType.STATEFUL) .setClockType( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() )); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1 ) ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); deployJar( ks, createKJar( ks, kproj, releaseId2, null, drl2 ) ); KieContainer kc = ks.newKieContainer( releaseId1 ); KieSession ksession = kc.newKieSession(); PseudoClockScheduler clock = ksession.getSessionClock(); ksession.insert( new MyEvent( 1 ) ); ksession.fireAllRules(); clock.advanceTime(7, TimeUnit.SECONDS); kc.updateToVersion( releaseId2 ); ksession.fireAllRules(); clock.advanceTime(7, TimeUnit.SECONDS); kc.updateToVersion( releaseId1 ); ksession.fireAllRules(); } @Test public void testConcurrentKJarDeployment() throws Exception { // DROOLS-923 int parallelThreads = 10; ExecutorService executor = Executors.newFixedThreadPool( parallelThreads ); CompletionService<Boolean> ecs = new ExecutorCompletionService<Boolean>(executor); for (Callable<Boolean> s : Deployer.getDeployer( parallelThreads )) { ecs.submit(s); } for (int i = 0; i < parallelThreads; ++i) { assertTrue( ecs.take().get() ); } } public static class Deployer implements Callable<Boolean> { private static final KieServices ks = KieServices.Factory.get(); private final int i; public Deployer( int i ) { this.i = i; } public Boolean call() throws Exception { String drl = "rule R when\n" + " Integer( this == " + i + " )\n" + "then\n" + "end\n"; ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-" + i, "1.0.0" ); try { for (int i = 0; i < 10; i++) { createAndDeployJar( ks, releaseId1, drl ); ks.getRepository().removeKieModule( releaseId1 ); } } catch (Exception e) { e.printStackTrace(); return false; } return true; } public static Collection<Callable<Boolean>> getDeployer( int nr ) { Collection<Callable<Boolean>> solvers = new ArrayList<Callable<Boolean>>(); for ( int i = 0; i < nr; ++i ) { solvers.add( new Deployer(i) ); } return solvers; } } @Test public void testSegmentSplitOnIncrementalCompilation() throws Exception { // DROOLS-930 String drl = "import " + Person.class.getCanonicalName() + "\n" + "global java.util.List list\n" + "rule R1 when\n" + " $s : String()" + " Person( name == $s ) \n" + "then\n" + " list.add(\"R1\");\n" + "end\n" + "rule R2 when\n" + " $s : String()" + " Person( name == $s ) \n" + "then\n" + " list.add(\"R2\");\n" + "end\n" + "rule R3 when\n" + " $s : String()" + " Person( name != $s ) \n" + "then\n" + " list.add(\"R3\");\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.1"); KieModule km = createAndDeployJar(ks, releaseId1); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); kc.updateToVersion(releaseId1); ksession.insert( new Person( "John", 26 ) ); ksession.insert( "John" ); ksession.fireAllRules(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar(ks, releaseId2, drl); kc.updateToVersion(releaseId2); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.fireAllRules(); assertEquals(2, list.size()); assertTrue( list.containsAll( asList("R1", "R2") ) ); } @Test public void testSegmentMergeOnRuleRemovalWithNotExistingSegment() throws Exception { // DROOLS-950 String drl1 = "rule R1 when\n" + " $i : Integer()\n" + " $s : String( length == $i )\n" + "then\n" + "end\n" + "rule R2 when\n" + " $i : Integer()\n" + " $l : Long( this > $i )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.1"); KieModule km = createAndDeployJar(ks, releaseId1, drl1); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); kc.updateToVersion(releaseId1); ksession.insert( "Test" ); ksession.insert( 4L ); ksession.fireAllRules(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar(ks, releaseId2); kc.updateToVersion(releaseId2); } @Test public void testRemoveRuleWithRia() throws Exception { // DROOLS-954 String drl1 = "import " + List.class.getCanonicalName() + "\n" + "rule R when\n" + " $list : List()\n" + " exists Integer( this == 1 ) from $list\n" + " exists Integer( this == 2 ) from $list\n" + "then \n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.1"); KieModule km = createAndDeployJar(ks, releaseId1, drl1); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar(ks, releaseId2); kc.updateToVersion(releaseId2); Rete rete = ( (InternalKnowledgeBase) (InternalKnowledgeBase) ksession.getKieBase() ).getRete(); EntryPointNode entryPointNode = rete.getEntryPointNodes().values().iterator().next(); for (ObjectTypeNode otns : entryPointNode.getObjectTypeNodes().values()) { assertEquals( 0, otns.getObjectSinkPropagator().getSinks().length ); } } @Test public void testRetractLogicalAssertedObjectOnRuleRemoval() throws Exception { // DROOLS-951 String drl1 = "rule R1 when\n" + " exists( Integer() )\n" + "then\n" + " insertLogical( \"found1\" );" + "end\n"; String drl2 = "package org.drools.compiler\n" + "rule R2 when\n" + " exists( Integer() )\n" + "then\n" + " insertLogical( \"found2\" );" + "end\n"; String drl3 = "package org.drools.compiler\n" + "rule R3 when\n" + " exists( Integer() )\n" + "then\n" + " insertLogical( \"found3\");" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.1"); KieModule km = createAndDeployJar(ks, releaseId1, drl1, drl2, drl3); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); ksession.insert( 4 ); ksession.fireAllRules(); assertEquals( 3, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar(ks, releaseId2, drl1, drl2); kc.updateToVersion(releaseId2); ksession.fireAllRules(); assertEquals( 2, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); ReleaseId releaseId3 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.3"); km = createAndDeployJar(ks, releaseId3, drl1); kc.updateToVersion(releaseId3); ksession.fireAllRules(); assertEquals( 1, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); ReleaseId releaseId4 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.4"); km = createAndDeployJar(ks, releaseId4); kc.updateToVersion(releaseId4); ksession.fireAllRules(); assertEquals( 0, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); } @Test public void testRetractLogicalAssertedObjectOnRuleRemovalWithSameObject() throws Exception { // DROOLS-951 String drl1 = "rule R1 when\n" + " exists( Integer() )\n" + "then\n" + " insertLogical( \"found\" );" + "end\n"; String drl2 = "package org.drools.compiler\n" + "rule R2 when\n" + " exists( Integer() )\n" + "then\n" + " insertLogical( \"found\" );" + "end\n"; String drl3 = "package org.drools.compiler\n" + "rule R3 when\n" + " exists( Integer() )\n" + "then\n" + " insertLogical( \"found\");" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.1"); KieModule km = createAndDeployJar(ks, releaseId1, drl1, drl2, drl3); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); ksession.insert( 4 ); ksession.fireAllRules(); assertEquals( 1, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar(ks, releaseId2, drl1, drl2); kc.updateToVersion(releaseId2); ksession.fireAllRules(); assertEquals( 1, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); ReleaseId releaseId3 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.3"); km = createAndDeployJar(ks, releaseId3, drl1); kc.updateToVersion(releaseId3); ksession.fireAllRules(); assertEquals( 1, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); ReleaseId releaseId4 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.4"); km = createAndDeployJar(ks, releaseId4); kc.updateToVersion(releaseId4); ksession.fireAllRules(); assertEquals( 0, ksession.getObjects( new ClassObjectFilter( String.class ) ).size() ); } @Test public void testDrlRenamingWithEvents() throws Exception { // DROOLS-965 String drl1 = "import " + SimpleEvent.class.getCanonicalName() + ";\n" + "\n" + "global java.util.concurrent.atomic.AtomicInteger counter1;\n" + "global java.util.concurrent.atomic.AtomicInteger counter2;\n" + "\n" + "declare SimpleEvent\n" + " @role( event )\n" + " @timestamp( timestamp )\n" + " @expires( 2d )\n" + "end\n" + "\n" + "rule R1 when\n" + " $s:SimpleEvent(code==\"MY_CODE\")\n" + "then\n" + " counter1.incrementAndGet();\n" + "end\n" + "\n" + "rule R2 when\n" + " $s:SimpleEvent(code==\"MY_CODE\")\n" + " not SimpleEvent(this != $s, this after [0,10s] $s)\n" + "then\n" + " counter2.incrementAndGet();\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ).setDefault( true ) .setEventProcessingMode(EventProcessingOption.STREAM); KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel("KSession1").setDefault(true) .setType(KieSessionModel.KieSessionType.STATEFUL) .setClockType( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) ); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.1" ); KieModule km = deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1 ) ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); PseudoClockScheduler clock = ksession.getSessionClock(); AtomicInteger counter1 = new AtomicInteger( 0 ); AtomicInteger counter2 = new AtomicInteger( 0 ); ksession.setGlobal( "counter1", counter1 ); ksession.setGlobal( "counter2", counter2 ); ksession.insert( new SimpleEvent("1", "MY_CODE", 0) ); ksession.fireAllRules(); clock.advanceTime(5, TimeUnit.SECONDS); ksession.insert( new SimpleEvent("2", "MY_CODE", 5) ); ksession.fireAllRules(); assertEquals( 2, counter1.get() ); assertEquals( 0, counter2.get() ); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); // the null drl placeholder is used to have the same drl with a different file name // this causes the removal and readdition of both rules km = deployJar( ks, createKJar( ks, kproj, releaseId2, null, (String)null, drl1 ) ); kc.updateToVersion(releaseId2); clock = ksession.getSessionClock(); clock.advanceTime(16, TimeUnit.SECONDS); ksession.insert( new SimpleEvent("3", "MY_CODE", 21) ); ksession.fireAllRules(); assertEquals( 5, counter1.get() ); assertEquals( 1, counter2.get() ); } public static class SimpleEvent { private final String id; private final String code; private final long timestamp; public SimpleEvent(String eventId, String code, long timestamp) { this.id = eventId; this.code = code; this.timestamp = timestamp * 1000L; } public String getId() { return id; } public String getCode() { return code; } public Date getTimestamp() { return new Date(timestamp); } @Override public String toString() { return "SimpleEvent(" + id + ")"; } } @Test public void testUpdateWithNewDrlAndChangeInOldOne() throws Exception { // BZ-1275378 String drl1 = "package org.kie.test\n" + "global java.util.List list\n" + "rule rule1\n" + "when\n" + "then\n" + "list.add( drools.getRule().getName() );\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.1" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.fireAllRules(); assertEquals( 1, list.size() ); assertTrue( list.contains( "rule1" ) ); drl1 = "package org.kie.test\n" + "global java.util.List list\n" + "rule rule1\n" + "when\n" + "Object()\n" + "then\n" + "list.add( drools.getRule().getName() );\n" + "end\n"; String drl2 = "package org.kie.test\n" + "global java.util.List list\n" + "rule rule2\n" + "when\n" + "then\n" + "list.add( drools.getRule().getName() );\n" + "end\n"; ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar( ks, releaseId2, drl1, drl2 ); kc.updateToVersion(releaseId2); list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.fireAllRules(); assertEquals( 1, list.size() ); assertTrue( list.contains( "rule2" ) ); } @Test public void testIncrementalCompilationWithEagerRules() throws Exception { // DROOLS-978 String drl1 = "rule R1 when\n" + "then\n" + " insert(\"test\");\n" + "end\n" + "\n" + "rule R2\n" + "no-loop true\n" + "when\n" + "then\n" + " insert(1);\n" + "end\n"; String drl2 = "rule R3\n" + "no-loop true\n" + "when\n" + "then\n" + " insert(1);\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.1" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); ksession.fireAllRules(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar( ks, releaseId2, drl2 ); kc.updateToVersion(releaseId2); ksession.fireAllRules(); } @Test public void testMultipleIncrementalCompilationWithExistentialRules() { // DROOLS-988 List<String> drls = new ArrayList<String>(); drls.add(getExistenzialRule("R0", "> 10")); // Create a session with the above rule KieServices ks = KieServices.Factory.get(); ReleaseId releaseId = ks.newReleaseId("org.kie", "test-upgrade", "1.0.0"); KieModule km = createAndDeployJar(ks, releaseId, drls.toArray(new String[drls.size()])); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); AtomicInteger counter = new AtomicInteger( 0 ); ksession.setGlobal( "counter", counter ); ksession.insert(3); ksession.fireAllRules(); assertEquals(0, counter.get()); for (int i = 1; i < 11; i++) { ReleaseId newReleaseId = ks.newReleaseId("org.kie", "test-upgrade", "1.1." + i); drls.add(getExistenzialRule("R" + i, "< 10")); km = createAndDeployJar(ks, newReleaseId, drls.toArray(new String[drls.size()])); kc.updateToVersion(newReleaseId); ksession.fireAllRules(); assertEquals(i, counter.get()); } } private String getExistenzialRule(String rulename, String condition) { return "global java.util.concurrent.atomic.AtomicInteger counter\n" + "rule " + rulename + " when\n" + " exists (Integer( this " + condition + ") )\n" + "then\n" + " counter.incrementAndGet();\n" + "end"; } @Test public void testRuleRemovalWithOR() throws Exception { // DROOLS-1007 String drl1 = "rule R1 when\n" + " $s : String()\n" + " (Integer(this == $s.length) or Long(this == $s.length))\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.1" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); ksession.fireAllRules(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar( ks, releaseId2 ); try { kc.updateToVersion( releaseId2 ); } catch (Exception e) { fail( "Incremental update should succeed, but failed with " + e.getLocalizedMessage() ); } ksession.fireAllRules(); } @Test public void testSplitAfterQuery() throws Exception { String drl1 = "global java.util.List list; " + "query foo( Integer $i ) " + " $i := Integer( this < 10 ) " + "end\n" + "\n" + "rule r2 when " + " foo( $i; ) " + " Integer( this == 20 ) " + "then " + " System.out.println(\"20 \" + $i);" + " list.add( 20 + $i );\n" + "end\n" + "rule r3 when " + " $i : Integer( this == 1 ) " + "then " + " System.out.println($i);" + " update( kcontext.getKieRuntime().getFactHandle( $i ), $i + 1 );" + "end\n" + "\n"; String drl2 = "global java.util.List list; " + "query foo( Integer $i ) " + " $i := Integer( this < 10 ) " + "end\n" + "\n" + "rule r1 when " + " foo( $i ; ) " + " Integer( this == 10 ) " + "then " + " System.out.println(\"10 \" + $i);" + " list.add( 10 + $i );\n" + "end\n" + "rule r2 when " + " foo( $i; ) " + " Integer( this == 20 ) " + "then " + " System.out.println(\"20 \" + $i);" + " list.add( 20 + $i );\n" + "end\n" + "rule r3 when " + " $i : Integer( this == 1 ) " + "then " + " System.out.println($i);" + " update( kcontext.getKieRuntime().getFactHandle( $i ), $i + 1 );" + "end\n" + "\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.1" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); List<Integer> list = new ArrayList<Integer>(); ksession.setGlobal( "list", list ); ksession.insert( 1 ); ksession.insert( 20 ); ksession.fireAllRules(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar( ks, releaseId2, drl2 ); kc.updateToVersion(releaseId2); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertEquals( 21, (int)list.get(0) ); assertEquals( 22, (int)list.get(1) ); } @Test public void testGetFactTypeOnIncrementalUpdate() throws Exception { // DROOLS-980 String drl1 = "package org.mytest\n" + "declare Person\n" + " name : String\n" + " age : Integer\n" + "end\n" + "\n" + "rule R when Person(age > 30) then end\n"; String drl2 = "package org.mytest\n" + "declare Person\n" + " name : String\n" + " age : Integer\n" + " address : String\n" + "end\n" + "\n" + "rule R when Person(age > 40) then end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.1" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieBase kbase = kc.getKieBase(); FactType fact = kbase.getFactType("org.mytest", "Person"); assertNotNull( fact.getField( "name" ) ); assertNotNull( fact.getField( "age" ) ); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar( ks, releaseId2, drl2 ); kc.updateToVersion(releaseId2); fact = kbase.getFactType("org.mytest", "Person"); assertNotNull( fact.getField( "name" ) ); assertNotNull( fact.getField( "age" ) ); assertNotNull( fact.getField( "address" ) ); } @Test public void testRuleRemovalWithSubnetworkAndOR() throws Exception { // DROOLS-1025 String drl1 = "global java.util.concurrent.atomic.AtomicInteger globalInt\n" + "rule R1 when\n" + " $s : String()\n" + " (or exists Integer(this == 1)\n" + " exists Integer(this == 2) )\n" + " exists Integer() from globalInt.get()\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.1" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1 ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); ksession.setGlobal( "globalInt", new AtomicInteger(0) ); ksession.insert( 1 ); ksession.insert( "1" ); ksession.fireAllRules(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.1.2"); km = createAndDeployJar( ks, releaseId2 ); try { kc.updateToVersion( releaseId2 ); } catch (Exception e) { e.printStackTrace(); fail( "Incremental update should succeed, but failed with " + e.getLocalizedMessage() ); } ksession.fireAllRules(); } @Test public void testIncrementalCompilationWithClassFieldReader() { // BZ-1318532 String personSrc = "package org.test;" + "import java.util.ArrayList;" + "import java.util.List;" + "public class Person {" + " private String name;" + " private List<String> addresses = new ArrayList<String>();" + " public Person() {}" + " public Person(final String name) { this.name = name; }" + " public List<String> getAddresses() { return addresses; }" + " public void setAddresses(List<String> addresses) { this.addresses = addresses; }" + " public void addAddress(String address) { this.addresses.add(address); }" + " public String getName() { return this.name; }" + " public void setName(final String name) { this.name = name; }" + "}"; String drl1 = "package org.drools.compiler\n" + "" + "import org.test.Person;\n" + "" + "rule R0 salience 100 when\n" + " String()" + "then\n" + " Person person = new Person(\"John\");" + " person.addAddress(\"A street\");" + " insert(person);" + "end\n" + "" + "rule R1 when\n" + " $p : Person($addresses : addresses) " + " $a : Address() from $addresses " + "then\n" + "end\n" + ""; String drl2 = drl1 + " "; // just a trivial update KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); ReleaseId id = ks.newReleaseId( "org.test", "myTest", "1.0.0" ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( id ); kfs.write("src/main/java/org/test/Person.java", ks.getResources().newReaderResource(new StringReader(personSrc))); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl1.drl" ) ); kieBuilder.buildAll(); KieContainer kc = ks.newKieContainer( id ); KieSession ksession = kc.newKieSession(); kfs.write( ks.getResources() .newReaderResource( new StringReader( drl2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drl1.drl" ) ); // update the drl1.drl file IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).incrementalBuild(); // don't call updateToVersion(). This test intends to prove that incrementalBuild doesn't do harm to existing ksession. ksession.insert( "start" ); int fired = ksession.fireAllRules(); } @Test public void testIncrementalCompilationRemovingParentRule() throws Exception { // DROOLS-1031 String drl1 = "package org.drools.compiler\n" + "rule R1 when\n" + " $s : String()\n" + "then\n" + "end\n"; String drl2 = "package org.drools.compiler\n" + "rule R2 extends R1 when\n" + " $i : Integer()\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ) .write( "src/main/resources/r2.drl", drl2 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); KieContainer kieContainer = ks.newKieContainer( ks.getRepository().getDefaultReleaseId() ); KieSession ksession = kieContainer.newKieSession(); ksession.insert( "test" ); ksession.insert( 1 ); assertEquals( 2, ksession.fireAllRules() ); kfs.delete( "src/main/resources/r1.drl" ); IncrementalResults results = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r1.drl", "src/main/resources/r2.drl" ).build(); assertEquals( 1, results.getAddedMessages().size() ); assertEquals( 0, results.getRemovedMessages().size() ); kieContainer.updateToVersion( ks.getRepository().getDefaultReleaseId() ); ksession = kieContainer.newKieSession(); ksession.insert( "test" ); ksession.insert( 1 ); assertEquals( 2, ksession.fireAllRules() ); } @Test public void testIncrementalCompilationChangeingParentRule() throws Exception { // DROOLS-1031 String drl1_1 = "rule R1 when\n" + " $s : String( this == \"s1\" )\n" + "then\n" + "end\n"; String drl1_2 = "rule R1 when\n" + " $s : String( this == \"s2\" )\n" + "then\n" + "end\n"; String drl2 = "rule R2 extends R1 when\n" + " $i : Integer()\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-extends", "1.1.1" ); KieModule km = createAndDeployJar( ks, releaseId1, drl1_1 + drl2 ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); ksession.insert( 1 ); ksession.insert( "s2" ); assertEquals( 0, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-extends", "1.1.2"); km = createAndDeployJar( ks, releaseId2, drl1_2 + drl2 ); kc.updateToVersion( releaseId2 ); assertEquals( 2, ksession.fireAllRules() ); } @Test public void testRemoveRuleWithNonInitializedPath() { // DROOLS-1177 String drl1 = "import " + MyEvent.class.getCanonicalName() + "\n" + "declare MyEvent @role( event ) end\n" + "rule \"RG_TEST_1\"\n" + " when\n" + " $dummy: MyEvent (id == 1)\n" + " $other: MyEvent (this != $dummy)\n" + " then\n" + " retract($other);\n" + "end\n" + "rule \"RG_TEST_2\"\n" + " when\n" + " $dummy: MyEvent (id == 1)\n" + " then\n" + " retract($dummy);\n" + "end\n"; String drl2 = "import " + MyEvent.class.getCanonicalName() + "\n" + "declare IMyEvent @role( event ) end\n" + "rule \"RG_TEST_2\"\n" + " when\n" + " $dummy: MyEvent (id == 1)\n" + " then\n" + " retract($dummy);\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ).setDefault( true ) .setEventProcessingMode(EventProcessingOption.STREAM); KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel("KSession1").setDefault(true) .setType(KieSessionModel.KieSessionType.STATEFUL); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1 ) ); KieContainer kc = ks.newKieContainer( releaseId1 ); KieSession ksession = kc.newKieSession(); ksession.insert( new MyEvent( 0 ) ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); deployJar( ks, createKJar( ks, kproj, releaseId2, null, drl2 ) ); kc.updateToVersion( releaseId2 ); } @Test public void testIncrementalCompilationWithTimerNode() throws Exception { // DROOLS-1195 String drl1 = "package fr.edf.distribution.brms.common.test\n" + "import " + DummyEvent.class.getCanonicalName() + "\n" + "declare DummyEvent\n" + " @role( event )\n" + " @timestamp( eventTimestamp )\n" + "end\n" + "rule \"RG_TEST_TIMER\"\n" + "timer (int: 0 1; start=$expirationTimestamp , repeat-limit=0 )\n" + " when\n" + " $dummy: DummyEvent (id == 'timer', $expirationTimestamp : systemTimestamp )\n" + " then\n " + "System.out.println(\"1\");\n" + "end\n"; String drl2 = "package fr.edf.distribution.brms.common.test\n" + "import " + DummyEvent.class.getCanonicalName() + "\n" + "declare DummyEvent\n" + " @role( event )\n" + " @timestamp( eventTimestamp )\n" + "end\n" + "rule \"RG_TEST_TIMER_NEW\"\n" + "timer (int: 0 1; start=$expirationTimestamp , repeat-limit=0 )\n" + " when\n" + " $dummy: DummyEvent (id == 'timer', $expirationTimestamp : systemTimestamp )\n" + " DummyEvent (id == 'timer_match')\n" + " then\n " + "System.out.println(\"1\");\n" + "end\n" + "rule \"RG_OTHER_RULE\"\n" + " when\n" + " $dummy: DummyEvent ( id == 'timer' )\n" + " then\n " + "System.out.println(\"2\");\n" + "end\n"; long now = System.currentTimeMillis(); KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ).setDefault( true ) .setEventProcessingMode(EventProcessingOption.STREAM); KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel("KSession1").setDefault(true) .setType(KieSessionModel.KieSessionType.STATEFUL) .setClockType( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) ); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1 ) ); KieContainer kc = ks.newKieContainer(releaseId1); KieSession kieSession = kc.newKieSession(); DummyEvent dummyEvent = new DummyEvent(); dummyEvent.setId("timer"); dummyEvent.setEventTimestamp(now); dummyEvent.setSystemTimestamp(now + TimeUnit.HOURS.toMillis(1)); DummyEvent other = new DummyEvent(); other.setId("timer_match"); other.setEventTimestamp(now); kieSession.insert(dummyEvent); kieSession.insert(other); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "2.0.0"); deployJar( ks, createKJar( ks, kproj, releaseId2, null, drl2 ) ); kc.updateToVersion(releaseId2); PseudoClockScheduler scheduler = kieSession.getSessionClock(); scheduler.setStartupTime(now); scheduler.advanceTime(1, TimeUnit.DAYS); assertEquals( 2, kieSession.fireAllRules() ); } public static class DummyEvent { private String id; private long eventTimestamp; private long systemTimestamp; public DummyEvent() {} public DummyEvent(String id) { this.id = id; } public long getEventTimestamp() { return eventTimestamp; } public void setEventTimestamp(long eventTimestamp) { this.eventTimestamp = eventTimestamp; } public long getSystemTimestamp() { return systemTimestamp; } public void setSystemTimestamp(long systemTimestamp) { this.systemTimestamp = systemTimestamp; } public String getId() { return id; } public void setId(String id) { this.id = id; } } public static class OtherDummyEvent { private String id; private long eventTimestamp; private long systemTimestamp; public OtherDummyEvent() {} public OtherDummyEvent(String id) { this.id = id; } public long getEventTimestamp() { return eventTimestamp; } public void setEventTimestamp(long eventTimestamp) { this.eventTimestamp = eventTimestamp; } public long getSystemTimestamp() { return systemTimestamp; } public void setSystemTimestamp(long systemTimestamp) { this.systemTimestamp = systemTimestamp; } public String getId() { return id; } public void setId(String id) { this.id = id; } } @Test public void testEventDeclarationInSeparatedDRL() throws Exception { // DROOLS-1241 String drl1 = "import " + SimpleEvent.class.getCanonicalName() + ";\n"+ "declare SimpleEvent\n" + " @role( event )\n" + " @timestamp( timestamp )\n" + " @expires( 2d )\n" + "end\n"; String drl2 = "import " + SimpleEvent.class.getCanonicalName() + ";\n" + "global java.util.List list;\n"+ "rule R1 when\n" + " $s:SimpleEvent(code==\"MY_CODE\") over window:time( 1s )\n" + "then\n" + " list.add(\"MY_CODE\");\n" + "end\n"; String drl3 = "import " + SimpleEvent.class.getCanonicalName() + ";\n"+ "global java.util.List list;\n"+ "rule R2 when\n" + " $s:SimpleEvent(code==\"YOUR_CODE\") over window:time( 1s )\n" + "then\n" + " list.add(\"YOUR_CODE\");\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ).setDefault( true ) .setEventProcessingMode( EventProcessingOption.STREAM ); KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel( "KSession1" ).setDefault( true ) .setType( KieSessionModel.KieSessionType.STATEFUL ) .setClockType( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) ); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-cep-upgrade", "1.1.1" ); KieModule km = deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1, drl2 ) ); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSession ksession = kc.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( new SimpleEvent("1", "MY_CODE", 0) ); ksession.insert( new SimpleEvent("2", "YOUR_CODE", 0) ); ksession.fireAllRules(); assertEquals( 1, list.size() ); assertEquals( "MY_CODE", list.get(0) ); list.clear(); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-cep-upgrade", "1.1.2"); // the null drl placeholder is used to have the same drl with a different file name // this causes the removal and readdition of both rules km = deployJar( ks, createKJar( ks, kproj, releaseId2, null, drl1, drl2, drl3 ) ); Results results = kc.updateToVersion(releaseId2); assertEquals( 0, results.getMessages().size() ); ksession.fireAllRules(); assertEquals( 1, list.size() ); assertEquals( "YOUR_CODE", list.get(0) ); } @Test public void testKeepBuilderConfAfterIncrementalUpdate() throws Exception { // DROOLS-1282 String drl1 = "import " + DummyEvent.class.getCanonicalName() + "\n" + "rule R1 when\n" + " DummyEvent() @watch(id)\n" + "then end\n"; String drl2 = "import " + DummyEvent.class.getCanonicalName() + "\n" + "rule R1 when\n" + " DummyEvent() @watch(*)\n" + "then end\n"; KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel() .setConfigurationProperty( PropertySpecificOption.PROPERTY_NAME, PropertySpecificOption.ALWAYS.toString() ); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-property-reactive-upgrade", "1" ); KieModule km = deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1 ) ); KieContainer container = ks.newKieContainer(releaseId1); container.newKieSession(); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-property-reactive-upgrade", "2" ); km = deployJar( ks, createKJar( ks, kproj, releaseId2, null, drl2 ) ); Results results = container.updateToVersion(releaseId2); assertEquals( 0, results.getMessages().size() ); } @Test public void testRemovePackageFromKieBaseModel() throws Exception { // DROOLS-1287 KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-remove-pkg", "1.0" ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-remove-pkg", "1.1" ); createKJarWIthPackages( ks, releaseId1, "pkg1", "pkg2" ); KieContainer container = ks.newKieContainer(releaseId1); KieSession ksession = container.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertTrue( list.containsAll( asList("R1", "R2") ) ); createKJarWIthPackages( ks, releaseId2, "pkg2" ); Results results = container.updateToVersion(releaseId2); assertEquals( 0, results.getMessages().size() ); ksession = container.newKieSession(); list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 1, list.size() ); assertTrue( list.containsAll( asList("R2") ) ); } @Test public void testAddPackageToKieBaseModel() throws Exception { // DROOLS-1287 KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-remove-pkg", "1.0" ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-remove-pkg", "1.1" ); createKJarWIthPackages( ks, releaseId1, "pkg2" ); KieContainer container = ks.newKieContainer(releaseId1); KieSession ksession = container.newKieSession(); List<String> list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 1, list.size() ); assertTrue( list.containsAll( asList("R2") ) ); createKJarWIthPackages( ks, releaseId2, "pkg1", "pkg2" ); Results results = container.updateToVersion(releaseId2); assertEquals( 0, results.getMessages().size() ); ksession = container.newKieSession(); list = new ArrayList<String>(); ksession.setGlobal( "list", list ); ksession.insert( "test" ); ksession.fireAllRules(); assertEquals( 2, list.size() ); assertTrue( list.containsAll( asList("R1", "R2") ) ); } @Test public void testAlphaNodeSharingIsOK() throws Exception { // inspired by drools-usage Fmt9wZUFi8g // check timer -scheduled activations are preserved if rule untouched by incremental compilation even with alpha node sharing. StringBuffer drl = new StringBuffer(); drl.append("package org.drools.compiler\n"); drl.append("global java.util.List list;\n"); drl.append("global java.util.List list2;\n"); drl.append("rule R1\n"); drl.append(" timer (int: 3s)\n"); drl.append(" when\n"); drl.append(" $m : String()\n"); drl.append(" then\n"); drl.append(" list.add( $m );\n"); drl.append(" retract( $m );\n"); drl.append("end\n"); drl.append("rule RS\n"); drl.append(" timer (int: 3s)\n"); drl.append(" salience 1\n"); drl.append(" when\n"); drl.append(" $i : Integer()\n"); drl.append(" $m : String()\n"); drl.append(" then\n"); drl.append(" System.out.println($i + \" \"+ $m);"); drl.append(" list2.add($i + \" \"+ $m);\n"); drl.append("end\n"); StringBuffer drl2 = new StringBuffer(); drl2.append("package org.drools.compiler\n"); drl2.append("global java.util.List list;\n"); drl2.append("global java.util.List list2;\n"); drl2.append("rule R1\n"); drl2.append(" timer (int: 3s)\n"); drl2.append(" when\n"); drl2.append(" $m : String()\n"); drl2.append(" then\n"); drl2.append(" list.add( $m );\n"); drl2.append(" list.add( $m );\n"); drl2.append(" retract( $m );\n"); drl2.append("end\n"); drl2.append("rule RS\n"); drl2.append(" timer (int: 3s)\n"); drl2.append(" salience 1\n"); drl2.append(" when\n"); drl2.append(" $i : Integer()\n"); drl2.append(" $m : String()\n"); drl2.append(" then\n"); drl2.append(" System.out.println($i + \" \"+ $m);"); drl2.append(" list2.add($i + \" \"+ $m);\n"); drl2.append("end\n"); KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId("org.kie", "test-upgrade", "1.0.0"); KieModule km = createAndDeployJarInStreamMode(ks, releaseId1, drl.toString()); KieContainer kc = ks.newKieContainer(km.getReleaseId()); KieSessionConfiguration ksconf = ks.newKieSessionConfiguration(); ksconf.setOption(TimedRuleExecutionOption.YES); ksconf.setOption(TimerJobFactoryOption.get("trackable")); ksconf.setOption(ClockTypeOption.get("pseudo")); KieSession ksession = kc.newKieSession(ksconf); SessionPseudoClock timeService = ksession.getSessionClock(); timeService.advanceTime(new Date().getTime(), TimeUnit.MILLISECONDS); List list = new ArrayList(); ksession.setGlobal("list", list); List list2 = new ArrayList(); ksession.setGlobal("list2", list2); ksession.insert(new String("A")); ksession.insert(1); ksession.fireAllRules(); assertEquals("1. Initial run: no message expected after rule fired immediately after fireAllRules due to duration of 5 sec", 0, list.size()); assertEquals("1. Initial run: no message expected after rule fired immediately after fireAllRules due to duration of 5 sec", 0, list2.size()); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "1.0.1"); km = createAndDeployJarInStreamMode(ks, releaseId2, drl2.toString()); kc.updateToVersion(releaseId2); timeService.advanceTime(3200, TimeUnit.MILLISECONDS); assertEquals("1. R1 is NOT preserved", 0, list.size()); assertEquals("1. RS is preserved", 1, list2.size()); } private void createKJarWIthPackages( KieServices ks, ReleaseId releaseId1, String... pkgs ) { String drl1 = "global java.util.List list;\n" + "rule R1 when\n" + " String()\n" + "then\n" + " list.add(\"R1\");" + "end\n"; String drl2 = "global java.util.List list;\n" + "rule R2 when\n" + " String()\n" + "then\n" + " list.add(\"R2\");" + "end\n"; KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "kbase1" ).setDefault( true ); for (String pkg : pkgs) { kieBaseModel1.addPackage( pkg ); } KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel( "ksession1" ).setDefault( true ); KieFileSystem kfs = ks.newKieFileSystem(); kfs.writeKModuleXML(kproj.toXML()); kfs.generateAndWritePomXML(releaseId1); kfs.write("src/main/resources/pkg1/r1.drl", drl1); kfs.write("src/main/resources/pkg2/r2.drl", drl2); KieModule km = deployJar( ks, buildKJar( ks, kfs, releaseId1 ) ); } @Test public void testIncrementalCompilationWithNewEvent() throws Exception { // DROOLS-1395 String drl1 = "package fr.edf.distribution.brms.common.test\n" + "import " + DummyEvent.class.getCanonicalName() + "\n" + "declare DummyEvent\n" + " @role( event )\n" + " @timestamp( eventTimestamp )\n" + "end\n" + "rule \"RG_TEST_1\"\n" + " when\n" + " $event: DummyEvent ()\n" + " then\n" + " System.out.println(\"RG_TEST_1 fired\");\n" + " retract($event);\n" + "end"; String drl2 = "package fr.edf.distribution.brms.common.test\n" + "import " + DummyEvent.class.getCanonicalName() + "\n" + "import " + OtherDummyEvent.class.getCanonicalName() + "\n" + "declare DummyEvent\n" + " @role( event )\n" + " @timestamp( eventTimestamp )\n" + "end\n" + "declare OtherDummyEvent\n" + " @role( event )\n" + " @timestamp( eventTimestamp )\n" + "end\n" + "rule \"RG_TEST_2\"\n" + " when\n" + " $event: DummyEvent ()\n" + " $other : OtherDummyEvent(id == $event.id, this after $event)\n" + " then\n" + " System.out.println(\"RG_TEST_2 fired\");\n" + " retract($other);\n" + "end\n" + "\n" + "rule \"RG_TEST_1\"\n" + " when\n" + " $event: DummyEvent ()\n" + " then\n" + " System.out.println(\"RG_TEST_1 fired\");\n" + " retract($event);\n" + "end\n"; KieServices ks = KieServices.Factory.get(); KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel( "KBase1" ).setDefault( true ) .setEventProcessingMode(EventProcessingOption.STREAM); KieSessionModel ksession1 = kieBaseModel1.newKieSessionModel("KSession1").setDefault(true) .setType(KieSessionModel.KieSessionType.STATEFUL) .setClockType( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) ); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); deployJar( ks, createKJar( ks, kproj, releaseId1, null, drl1 ) ); KieContainer kc = ks.newKieContainer(releaseId1); KieSession kieSession = kc.newKieSession(); DummyEvent evt = new DummyEvent("evt"); kieSession.insert(evt); assertEquals(1, kieSession.fireAllRules()); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-upgrade", "2.0.0"); deployJar( ks, createKJar( ks, kproj, releaseId2, null, drl2 ) ); kc.updateToVersion(releaseId2); evt = new DummyEvent("evt"); kieSession.insert(evt); OtherDummyEvent other = new OtherDummyEvent("evt"); kieSession.insert(other); assertEquals(1, kieSession.fireAllRules()); } @Test public void testKJarUpgradeWithSpace() throws Exception { // DROOLS-1399 String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n " + // <<- notice the EXTRA SPACE is the only change in this other version. "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 0, ksession.fireAllRules() ); } @Test public void testKJarUpgradeDRLWithSpace2() throws Exception { // DROOLS-1399 bis String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + // <<- notice the EXTRA SPACE is the only change in this other version. "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 0, ksession.fireAllRules() ); } @Test public void testKJarUpgradeDRLWithSpace3() throws Exception { // DROOLS-1399 ter String drl_1 = "package org.drools.compiler\n" + "rule Rs when $s : String() then System.out.println($s); end\n" + "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + " System.out.println($m); \n"+ "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rs when $s : String( this == \"x\") then System.out.println($s); end\n" + // <<- notice rule changed "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + // <<- notice the EXTRA SPACE is the an ADDITIONAL change in this other version. "then\n" + " System.out.println($m); \n"+ "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); final List<String> fired = new ArrayList<>(); ksession.addEventListener(new DefaultAgendaEventListener() { @Override public void afterMatchFired(AfterMatchFiredEvent event) { fired.add(event.getMatch().getRule().getName()); } }); ksession.insert( new Message( "Hello World" ) ); ksession.insert( "x" ); assertEquals( 2, ksession.fireAllRules() ); assertTrue( fired.contains("Rs") ); assertTrue( fired.contains("Rx") ); fired.clear(); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again // rule Rs is changed and should match again, and fire again. assertEquals( 1, ksession.fireAllRules() ); assertTrue( fired.contains("Rs") ); assertFalse( fired.contains("Rx") ); } @Test public void testKJarUpgradeDRLWithSpace4() throws Exception { // DROOLS-1399 quater String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == \"Hello World\" )\n" + // <<- notice the EXTRA SPACE typo was removed "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 0, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 1, ksession.fireAllRules() ); } @Test public void testKJarUpgradeDRLWithSpace5() throws Exception { // DROOLS-1399 quinquies String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == \"Hello' World\" )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == \"Hello' World\" )\n" + // <<- notice the EXTRA SPACE typo was removed "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello' World" ) ); // <<- notice the ' character assertEquals( 0, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 1, ksession.fireAllRules() ); } @Test public void testKJarUpgradeWithSpace_usingSingleQuote() throws Exception { // DROOLS-1399 (using single quote) String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n " + // <<- notice the EXTRA SPACE is the only change in this other version. "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 0, ksession.fireAllRules() ); } @Test public void testKJarUpgradeDRLWithSpace2_usingSingleQuote() throws Exception { // DROOLS-1399 bis (using single quote) String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + // <<- notice the EXTRA SPACE is the only change in this other version. "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 1, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 0, ksession.fireAllRules() ); } @Test public void testKJarUpgradeDRLWithSpace3_usingSingleQuote() throws Exception { // DROOLS-1399 ter (using single quote) String drl_1 = "package org.drools.compiler\n" + "rule Rs when $s : String() then System.out.println($s); end\n" + "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + "then\n" + " System.out.println($m); \n"+ "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rs when $s : String( this == 'x') then System.out.println($s); end\n" + // <<- notice rule changed "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + // <<- notice the EXTRA SPACE is the an ADDITIONAL change in this other version. "then\n" + " System.out.println($m); \n"+ "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); final List<String> fired = new ArrayList<>(); ksession.addEventListener(new DefaultAgendaEventListener() { @Override public void afterMatchFired(AfterMatchFiredEvent event) { fired.add(event.getMatch().getRule().getName()); } }); ksession.insert( new Message( "Hello World" ) ); ksession.insert( "x" ); assertEquals( 2, ksession.fireAllRules() ); assertTrue( fired.contains("Rs") ); assertTrue( fired.contains("Rx") ); fired.clear(); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again // rule Rs is changed and should match again, and fire again. assertEquals( 1, ksession.fireAllRules() ); assertTrue( fired.contains("Rs") ); assertFalse( fired.contains("Rx") ); } @Test public void testKJarUpgradeDRLWithSpace4_usingSingleQuote() throws Exception { // DROOLS-1399 quater (using single quote) String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == 'Hello World' )\n" + // <<- notice the EXTRA SPACE typo was removed "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello World" ) ); assertEquals( 0, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 1, ksession.fireAllRules() ); } @Test public void testKJarUpgradeDRLWithSpace5_usingSingleQuote() throws Exception { // DROOLS-1399 quinquies (using single quote) String drl_1 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == 'Hello\\' World' )\n" + "then\n" + "end\n"; String drl_2 = "package org.drools.compiler\n" + "rule Rx when\n" + " $m : Message( message == 'Hello\\' World' )\n" + // <<- notice the EXTRA SPACE typo was removed "then\n" + "end\n"; KieServices ks = KieServices.Factory.get(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); KieModule km = createAndDeployJar( ks, releaseId1, drl_1 ); KieContainer kc = ks.newKieContainer( km.getReleaseId() ); KieSession ksession = kc.newKieSession(); ksession.insert( new Message( "Hello' World" ) ); // <<- notice the ' character on this one assertEquals( 0, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); km = createAndDeployJar( ks, releaseId2, drl_2 ); kc.updateToVersion( releaseId2 ); // rule Rx is UNchanged and should NOT fire again assertEquals( 1, ksession.fireAllRules() ); } @Test public void testJavaClassRedefinition() { // DROOLS-1402 String JAVA1 = "package org.test;" + " public class MyBean {\n" + " private String firstName;\n" + " public MyBean() { /* empty constructor */ }\n" + " public MyBean(String firstName) { this.firstName = firstName; }\n" + " public String getFirstName() { return firstName; }\n" + " public void setFirstName(String firstName) { this.firstName = firstName; }\n" + " }"; String DRL1 = "package org.test;\n" + "\n" + "//from row number: 1\n" + "rule \"Row 1 HelloRules\"\n" + " when\n" + " $b : MyBean( firstName == null )\n" + " then\n" + " System.out.println($b);" + "end"; String INIT_DRL = "package org.test; rule RINIT when eval(true) then insert(new MyBean()); end"; String INIT_DRL_2 = "package org.test; rule RINIT when eval(1==1) then insert(new MyBean()); end"; String JAVA2 = "package org.test;" + " public class MyBean {\n" + " private String firstName;\n" + " private String lastName;\n" + " public MyBean() { /* empty constructor */ }\n" + " public MyBean(String firstName) { this.firstName = firstName; }\n" + " public MyBean(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }\n" + " public String getFirstName() { return firstName; }\n" + " public void setFirstName(String firstName) { this.firstName = firstName; }\n" + " public String getLastName() { return lastName; }\n" + " public void setLastName(String lastName) { this.lastName = lastName; }\n" + " }"; String DRL2 = "package org.test;\n" + "\n" + "//from row number: 1\n" + "rule \"Row 1 HelloRules\"\n" + " when\n" + " $b : MyBean( firstName == null , lastName == null )\n" + " then\n" + " System.out.println($b);" + "end"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); ReleaseId id = ks.newReleaseId( "org.test", "myTest", "1.0.0" ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( id ); kfs.write("src/main/java/org/test/MyBean.java", ks.getResources().newReaderResource(new StringReader(JAVA1))); kfs.write( ks.getResources() .newReaderResource( new StringReader( DRL1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "rules.drl" ) ); kfs.write( ks.getResources() .newReaderResource( new StringReader( INIT_DRL ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "INIT_DRL.drl" ) ); kieBuilder.buildAll(); KieContainer kc = ks.newKieContainer( id ); KieSession ksession = kc.newKieSession(); int fired = ksession.fireAllRules(); assertEquals( 2, fired ); ReleaseId id2 = ks.newReleaseId( "org.test", "myTest", "2.0.0" ); KieFileSystem kfs2 = ks.newKieFileSystem(); KieBuilder kieBuilder2 = ks.newKieBuilder( kfs2 ); kfs2.generateAndWritePomXML( id2 ); kfs2.write("src/main/java/org/test/MyBean.java", ks.getResources().newReaderResource(new StringReader(JAVA2))); kfs2.write( ks.getResources() .newReaderResource( new StringReader( DRL2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "rules.drl" ) ); kfs2.write( ks.getResources() .newReaderResource( new StringReader( INIT_DRL_2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "INIT_DRL.drl" ) ); kieBuilder2.buildAll(); Results updateResults = kc.updateToVersion(id2); assertFalse(updateResults.hasMessages(Level.ERROR)); fired = ksession.fireAllRules(); assertEquals( 2, fired ); } @Test public void testJavaClassRedefinitionJoined() { // DROOLS-1402 String JAVA1 = "package org.test;" + " public class MyBean {\n" + " private String firstName;\n" + " public MyBean() { /* empty constructor */ }\n" + " public MyBean(String firstName) { this.firstName = firstName; }\n" + " public String getFirstName() { return firstName; }\n" + " public void setFirstName(String firstName) { this.firstName = firstName; }\n" + " }"; String DRL1 = "package org.test;\n" + "\n" + "//from row number: 1\n" + "rule \"Row 1 HelloRules\"\n" + " when\n" + " $b : MyBean( firstName == null )\n" + " $s : String()\n" + " then\n" + " System.out.println($s + \" \" + $b);" + "end"; String INIT_DRL = "package org.test; rule RINIT when eval(true) then insert(new MyBean()); end"; String INIT_DRL_2 = "package org.test; rule RINIT when eval(1==1) then insert(new MyBean()); end"; String JAVA2 = "package org.test;" + " public class MyBean {\n" + " private String firstName;\n" + " private String lastName;\n" + " public MyBean() { /* empty constructor */ }\n" + " public MyBean(String firstName) { this.firstName = firstName; }\n" + " public MyBean(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }\n" + " public String getFirstName() { return firstName; }\n" + " public void setFirstName(String firstName) { this.firstName = firstName; }\n" + " public String getLastName() { return lastName; }\n" + " public void setLastName(String lastName) { this.lastName = lastName; }\n" + " }"; String DRL2 = "package org.test;\n" + "\n" + "//from row number: 1\n" + "rule \"Row 1 HelloRules\"\n" + " when\n" + " $b : MyBean( firstName == null , lastName == null )\n" + " $s : String()\n" + " then\n" + " System.out.println($s + \" \" + $b);" + "end"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); ReleaseId id = ks.newReleaseId( "org.test", "myTest", "1.0.0" ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kfs.generateAndWritePomXML( id ); kfs.write( "src/main/java/org/test/MyBean.java", ks.getResources().newReaderResource( new StringReader( JAVA1 ) ) ); kfs.write( ks.getResources() .newReaderResource( new StringReader( DRL1 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "rules.drl" ) ); kfs.write( ks.getResources() .newReaderResource( new StringReader( INIT_DRL ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "INIT_DRL.drl" ) ); kieBuilder.buildAll(); KieContainer kc = ks.newKieContainer( id ); KieSession ksession = kc.newKieSession(); ksession.insert( "This string joins with" ); int fired = ksession.fireAllRules(); assertEquals( 2, fired ); ReleaseId id2 = ks.newReleaseId( "org.test", "myTest", "2.0.0" ); KieFileSystem kfs2 = ks.newKieFileSystem(); KieBuilder kieBuilder2 = ks.newKieBuilder( kfs2 ); kfs2.generateAndWritePomXML( id2 ); kfs2.write( "src/main/java/org/test/MyBean.java", ks.getResources().newReaderResource( new StringReader( JAVA2 ) ) ); kfs2.write( ks.getResources() .newReaderResource( new StringReader( DRL2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "rules.drl" ) ); kfs2.write( ks.getResources() .newReaderResource( new StringReader( INIT_DRL_2 ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "INIT_DRL.drl" ) ); kieBuilder2.buildAll(); Results updateResults = kc.updateToVersion( id2 ); assertFalse( updateResults.hasMessages( Level.ERROR ) ); fired = ksession.fireAllRules(); assertEquals( 2, fired ); } @Test(timeout = 10000L) public void testMultipleIncrementalCompilationsWithFireUntilHalt() throws Exception { // DROOLS-1406 KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-fireUntilHalt", "1.0" ); KieModule km = createAndDeployJar( ks, releaseId1, getTestRuleForFireUntilHalt(0) ); // Create a session and fire rules final KieContainer kc = ks.newKieContainer( km.getReleaseId() ); final KieSession kieSession = kc.newKieSession(); DebugList<String> list = new DebugList<String>(); kieSession.setGlobal( "list", list ); kieSession.insert( new Message( "X" ) ); CountDownLatch done = new CountDownLatch( 1 ); list.done = done; new Thread( new Runnable() { public void run() { kieSession.fireUntilHalt(); } }).start(); done.await(); assertEquals( 1, list.size() ); assertEquals( "0 - X", list.get(0) ); list.clear(); for (int i = 1; i < 10; i++) { done = new CountDownLatch( 1 ); list.done = done; ReleaseId releaseIdI = ks.newReleaseId( "org.kie", "test-fireUntilHalt", "1."+i ); km = createAndDeployJar( ks, releaseIdI, getTestRuleForFireUntilHalt(i) ); kc.updateToVersion( releaseIdI ); done.await(); assertEquals( 1, list.size() ); assertEquals( i + " - X", list.get(0) ); list.clear(); } kieSession.halt(); } private String getTestRuleForFireUntilHalt(int i) { return "package org.drools.compiler\n" + "global java.util.List list;\n" + "rule Rx when\n" + " Message( $m : message )\n" + "then\n" + " list.add(\"" + i + " - \" + $m);\n" + "end\n"; } public static class DebugList<T> extends ArrayList<T> { CountDownLatch done; @Override public synchronized boolean add( T t ) { boolean result = super.add( t ); done.countDown(); return result; } } @Test public void testIncrementalCompilationWithExtendsRule() throws Exception { // DROOLS-1405 String drl1 = "rule \"test1\" when then end\n"; String drl2 = "rule \"test2\" extends \"test1\" when then end\n" + "rule \"test3\" extends \"test1\" when then end\n"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem() .write( "src/main/resources/r1.drl", drl1 ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ).buildAll(); assertEquals( 0, kieBuilder.getResults().getMessages( org.kie.api.builder.Message.Level.ERROR ).size() ); kfs.write( "src/main/resources/r2.drl", drl2 ); IncrementalResults addResults = ( (InternalKieBuilder) kieBuilder ).createFileSet( "src/main/resources/r2.drl" ).build(); assertEquals( 0, addResults.getAddedMessages().size() ); } public static class BaseClass { String baseField; public String getBaseField() { return baseField; } public void setBaseField(String baseField) { this.baseField = baseField; } } @Test public void testUpdateWithPojoExtensionDifferentPackages() throws Exception { // DROOLS-1491 String drlDeclare = "package org.drools.compiler.integrationtests\n" + "declare DroolsApplications extends " + BaseClass.class.getCanonicalName() + "\n" + " droolsAppName: String\n" + "end"; String drlRule = "package org.drools.compiler.test\n" + "rule R1 when\n" + " $fact : org.drools.compiler.integrationtests.DroolsApplications( droolsAppName == \"appName\" )\n" + "then\n" + "end"; KieServices ks = KieServices.Factory.get(); KieFileSystem kfs = ks.newKieFileSystem(); ReleaseId releaseId1 = ks.newReleaseId( "org.kie", "test-upgrade", "1.0.0" ); kfs.generateAndWritePomXML( releaseId1 ); kfs.write( ks.getResources() .newReaderResource( new StringReader( drlDeclare ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drlDeclare.drl" ) ); KieBuilder kieBuilder = ks.newKieBuilder( kfs ); kieBuilder.buildAll(); KieContainer kc = ks.newKieContainer( releaseId1 ); KieSession ksession = kc.newKieSession(); FactType factType = kc.getKieBase().getFactType( "org.drools.compiler.integrationtests", "DroolsApplications" ); Object fact = factType.newInstance(); factType.set( fact, "droolsAppName", "appName" ); ksession.insert( fact ); assertEquals( 0, ksession.fireAllRules() ); ReleaseId releaseId2 = ks.newReleaseId( "org.kie", "test-upgrade", "1.1.0" ); KieFileSystem kfs2 = ks.newKieFileSystem(); kfs2.generateAndWritePomXML( releaseId2 ); kfs2.write( ks.getResources() .newReaderResource( new StringReader( drlDeclare ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drlDeclare.drl" ) ); kfs2.write( ks.getResources() .newReaderResource( new StringReader( drlRule ) ) .setResourceType( ResourceType.DRL ) .setSourcePath( "drlRule.drl" ) ); KieBuilder kieBuilder2 = ks.newKieBuilder( kfs2 ); kieBuilder2.buildAll(); Results updateResults = kc.updateToVersion( releaseId2 ); assertEquals( 0, updateResults.getMessages().size() ); assertEquals( 1, ksession.fireAllRules() ); } }