Java tutorial
/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.compiler.integrationtests; import java.io.IOException; import java.io.StringReader; import java.lang.reflect.Constructor; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.IOUtils; import org.assertj.core.api.Assertions; import org.drools.compiler.CommonTestMethodBase; import org.drools.compiler.compiler.io.Folder; import org.drools.compiler.compiler.io.memory.MemoryFileSystem; import org.drools.core.impl.InternalKieContainer; import org.drools.compiler.kie.builder.impl.MemoryKieModule; import org.junit.Test; import org.kie.api.KieServices; 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.KieSessionModel; import org.kie.api.definition.type.FactType; import org.kie.api.io.Resource; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import static org.drools.core.util.DroolsAssert.assertEnumerationSize; import static org.drools.core.util.DroolsAssert.assertUrlEnumerationContainsMatch; import static org.junit.Assert.*; public class KieContainerTest extends CommonTestMethodBase { @Test public void testMainKieModule() { KieServices ks = KieServices.Factory.get(); // Create an in-memory jar for version 1.0.0 ReleaseId releaseId = ks.newReleaseId("org.kie", "test-delete", "1.0.0"); createAndDeployJar(ks, releaseId, createDRL("ruleA")); KieContainer kieContainer = ks.newKieContainer(releaseId); KieModule kmodule = ((InternalKieContainer) kieContainer).getMainKieModule(); assertEquals(releaseId, kmodule.getReleaseId()); } @Test public void testUpdateToNonExistingRelease() { // DROOLS-1562 KieServices ks = KieServices.Factory.get(); ReleaseId releaseId = ks.newReleaseId("org.kie", "test-release", "1.0.0"); createAndDeployJar(ks, releaseId, createDRL("ruleA")); KieContainer kieContainer = ks.newKieContainer(releaseId); Results results = kieContainer.updateToVersion(ks.newReleaseId("org.kie", "test-release", "1.0.1")); assertEquals(1, results.getMessages(Level.ERROR).size()); assertEquals("1.0.0", ((InternalKieContainer) kieContainer).getContainerReleaseId().getVersion()); } @Test public void testReleaseIdGetters() { KieServices ks = KieServices.Factory.get(); ReleaseId releaseId = ks.newReleaseId("org.kie", "test-delete-v", "1.0.1"); createAndDeployJar(ks, releaseId, createDRL("ruleA")); ReleaseId configuredReleaseId = ks.newReleaseId("org.kie", "test-delete-v", "RELEASE"); KieContainer kieContainer = ks.newKieContainer(configuredReleaseId); InternalKieContainer iKieContainer = (InternalKieContainer) kieContainer; assertEquals(configuredReleaseId, iKieContainer.getConfiguredReleaseId()); assertEquals(releaseId, iKieContainer.getResolvedReleaseId()); assertEquals(releaseId, iKieContainer.getReleaseId()); // demonstrate internal API behavior, in the future shall this be enforced? assertEquals(configuredReleaseId, iKieContainer.getContainerReleaseId()); ReleaseId newReleaseId = ks.newReleaseId("org.kie", "test-delete-v", "1.0.2"); createAndDeployJar(ks, newReleaseId, createDRL("ruleA")); iKieContainer.updateToVersion(newReleaseId); assertEquals(configuredReleaseId, iKieContainer.getConfiguredReleaseId()); assertEquals(newReleaseId, iKieContainer.getResolvedReleaseId()); assertEquals(newReleaseId, iKieContainer.getReleaseId()); // demonstrate internal API behavior, in the future shall this be enforced? assertEquals(newReleaseId, iKieContainer.getContainerReleaseId()); } @Test public void testSharedTypeDeclarationsUsingClassLoader() throws Exception { String type = "package org.drools.test\n" + "declare Message\n" + " message : String\n" + "end\n"; String drl1 = "package org.drools.test\n" + "rule R1 when\n" + " $o : Object()\n" + "then\n" + " if ($o.getClass().getName().equals(\"org.drools.test.Message\") && $o.getClass() != new Message(\"Test\").getClass()) {\n" + " throw new RuntimeException();\n" + " }\n" + "end\n"; String drl2 = "package org.drools.test\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + " if ($m.getClass() != new Message(\"Test\").getClass()) {\n" + " throw new RuntimeException();\n" + " }\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, type, drl1, drl2); KieContainer kieContainer = ks.newKieContainer(releaseId1); KieContainer kieContainer2 = ks.newKieContainer(releaseId1); KieSession ksession = kieContainer.newKieSession(); KieSession ksession2 = kieContainer2.newKieSession(); Class cls1 = kieContainer.getClassLoader().loadClass("org.drools.test.Message"); Constructor constructor = cls1.getConstructor(String.class); ksession.insert(constructor.newInstance("Hello World")); assertEquals(2, ksession.fireAllRules()); Class cls2 = kieContainer2.getClassLoader().loadClass("org.drools.test.Message"); Constructor constructor2 = cls2.getConstructor(String.class); ksession2.insert(constructor2.newInstance("Hello World")); assertEquals(2, ksession2.fireAllRules()); assertNotSame(cls1, cls2); } @Test public void testSharedTypeDeclarationsUsingFactTypes() throws Exception { String type = "package org.drools.test\n" + "declare Message\n" + " message : String\n" + "end\n"; String drl1 = "package org.drools.test\n" + "rule R1 when\n" + " $m : Message()\n" + "then\n" + " if ($m.getClass() != new Message(\"Test\").getClass()) {\n" + " throw new RuntimeException();\n" + " }\n" + "end\n"; String drl2 = "package org.drools.test\n" + "rule R2_2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + " if ($m.getClass() != new Message(\"Test\").getClass()) {\n" + " throw new RuntimeException();\n" + " }\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"); createAndDeployJar(ks, releaseId1, type, drl1, drl2); KieContainer kieContainer = ks.newKieContainer(releaseId1); KieContainer kieContainer2 = ks.newKieContainer(releaseId1); KieSession ksession = kieContainer.newKieSession(); KieSession ksession2 = kieContainer2.newKieSession(); insertMessageFromTypeDeclaration(ksession); assertEquals(2, ksession.fireAllRules()); ReleaseId releaseId2 = ks.newReleaseId("org.kie", "test-delete", "1.0.1"); createAndDeployJar(ks, releaseId2, type, null, drl2); kieContainer.updateToVersion(releaseId2); // test with the old ksession ... ksession = kieContainer.newKieSession(); insertMessageFromTypeDeclaration(ksession); assertEquals(1, ksession.fireAllRules()); // ... and with a brand new one ksession = kieContainer.newKieSession(); insertMessageFromTypeDeclaration(ksession); assertEquals(1, ksession.fireAllRules()); // check that the second kieContainer hasn't been affected by the update of the first one insertMessageFromTypeDeclaration(ksession2); assertEquals(2, ksession2.fireAllRules()); ksession2 = kieContainer2.newKieSession(); insertMessageFromTypeDeclaration(ksession2); assertEquals(2, ksession2.fireAllRules()); } private void insertMessageFromTypeDeclaration(KieSession ksession) throws InstantiationException, IllegalAccessException { FactType messageType = ksession.getKieBase().getFactType("org.drools.test", "Message"); Object message = messageType.newInstance(); messageType.set(message, "message", "Hello World"); ksession.insert(message); } @Test(timeout = 20000) public void testIncrementalCompilationSynchronization() { final KieServices kieServices = KieServices.Factory.get(); ReleaseId releaseId = kieServices.newReleaseId("org.kie.test", "sync-scanner-test", "1.0.0"); createAndDeployJar(kieServices, releaseId, createDRL("rule0")); final KieContainer kieContainer = kieServices.newKieContainer(releaseId); KieSession kieSession = kieContainer.newKieSession(); List<String> list = new ArrayList<>(); kieSession.setGlobal("list", list); kieSession.fireAllRules(); kieSession.dispose(); assertEquals(1, list.size()); Thread t = new Thread(() -> { for (int i = 1; i < 10; i++) { ReleaseId releaseId1 = kieServices.newReleaseId("org.kie.test", "sync-scanner-test", "1.0." + i); createAndDeployJar(kieServices, releaseId1, createDRL("rule" + i)); kieContainer.updateToVersion(releaseId1); } }); t.setDaemon(true); t.start(); while (true) { kieSession = kieContainer.newKieSession(); list = new ArrayList<>(); kieSession.setGlobal("list", list); kieSession.fireAllRules(); kieSession.dispose(); // There can be multiple items in the list if an updateToVersion is triggered during a fireAllRules // (updateToVersion can be called multiple times during fireAllRules, especially on slower machines) // in that case it may fire with the old rule and multiple new ones Assertions.assertThat(list).isNotEmpty(); if (list.get(0).equals("rule9")) { break; } } } @Test public void testMemoryFileSystemFolderUniqueness() { KieServices kieServices = KieServices.Factory.get(); String drl = "package org.drools.test\n" + "rule R1 when\n" + " $m : Object()\n" + "then\n" + "end\n"; Resource resource = kieServices.getResources().newReaderResource(new StringReader(drl), "UTF-8"); resource.setTargetPath("org/drools/test/rules.drl"); String kmodule = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<kmodule xmlns=\"http://www.drools.org/xsd/kmodule\">\n" + " <kbase name=\"testKbase\" packages=\"org.drools.test\">\n" + " <ksession name=\"testKsession\"/>\n" + " </kbase>\n" + "</kmodule>"; // Create an in-memory jar for version 1.0.0 ReleaseId releaseId = kieServices.newReleaseId("org.kie", "test-delete", "1.0.0"); createAndDeployJar(kieServices, kmodule, releaseId, resource); KieContainer kieContainer = kieServices.newKieContainer(releaseId); KieModule kieModule = ((InternalKieContainer) kieContainer).getMainKieModule(); MemoryFileSystem memoryFileSystem = ((MemoryKieModule) kieModule).getMemoryFileSystem(); Folder rootFolder = memoryFileSystem.getFolder(""); Object[] members = rootFolder.getMembers().toArray(); assertEquals(2, members.length); Folder firstFolder = (Folder) members[0]; Folder secondFolder = (Folder) members[1]; assertEquals(firstFolder.getParent(), secondFolder.getParent()); } @Test public void testClassLoaderGetResources() throws IOException { KieServices kieServices = KieServices.Factory.get(); String drl1 = "package org.drools.testdrl;\n" + "rule R1 when\n" + " $m : Object()\n" + "then\n" + "end\n"; Resource resource1 = kieServices.getResources().newReaderResource(new StringReader(drl1), "UTF-8"); resource1.setTargetPath("org/drools/testdrl/rules1.drl"); String drl2 = "package org.drools.testdrl;\n" + "rule R2 when\n" + " $m : Object()\n" + "then\n" + "end\n"; Resource resource2 = kieServices.getResources().newReaderResource(new StringReader(drl2), "UTF-8"); resource2.setTargetPath("org/drools/testdrl/rules2.drl"); String java3 = "package org.drools.testjava;\n" + "public class Message {}"; Resource resource3 = kieServices.getResources().newReaderResource(new StringReader(java3), "UTF-8"); resource3.setTargetPath("org/drools/testjava/Message.java"); resource3.setResourceType(ResourceType.JAVA); String kmodule = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<kmodule xmlns=\"http://www.drools.org/xsd/kmodule\">\n" + " <kbase name=\"testKbase\" packages=\"org.drools.testdrl\">\n" + " <ksession name=\"testKsession\"/>\n" + " </kbase>\n" + "</kmodule>"; // Create an in-memory jar for version 1.0.0 ReleaseId releaseId = kieServices.newReleaseId("org.kie", "test-delete", "1.0.0"); createAndDeployJar(kieServices, kmodule, releaseId, resource1, resource2, resource3); KieContainer kieContainer = kieServices.newKieContainer(releaseId); ClassLoader classLoader = kieContainer.getClassLoader(); assertEnumerationSize(1, classLoader.getResources("org/drools/testjava")); // no trailing "/" assertEnumerationSize(1, classLoader.getResources("org/drools/testdrl/")); // trailing "/" to test both variants // make sure the package resource correctly lists all its child resources (files in this case) URL url = classLoader.getResources("org/drools/testdrl").nextElement(); List<String> lines = IOUtils.readLines(url.openStream()); Assertions.assertThat(lines).contains("rules1.drl", "rules1.drl.properties", "rules2.drl", "rules2.drl.properties"); assertUrlEnumerationContainsMatch("^mfs\\:/$", classLoader.getResources("")); } @Test public void testGetDefaultKieSessionModel() { KieServices kieServices = KieServices.Factory.get(); String drl = "package org.drools.test\n" + "rule R1 when\n" + " $m : Object()\n" + "then\n" + "end\n"; Resource resource = kieServices.getResources().newReaderResource(new StringReader(drl), "UTF-8"); resource.setTargetPath("org/drools/test/rules.drl"); String kmodule = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<kmodule xmlns=\"http://www.drools.org/xsd/kmodule\">\n" + " <kbase name=\"testKbase\" packages=\"org.drools.test\">\n" + " <ksession name=\"testKsession\" default=\"true\"/>\n" + " </kbase>\n" + "</kmodule>"; // Create an in-memory jar for version 1.0.0 ReleaseId releaseId = kieServices.newReleaseId("org.kie", "test-testGetDefaultKieSessionModel", "1.0.0"); createAndDeployJar(kieServices, kmodule, releaseId, resource); KieContainer kieContainer = kieServices.newKieContainer(releaseId); KieSessionModel sessionModel = kieContainer.getKieSessionModel(null); assertNotNull(sessionModel); assertEquals("testKsession", sessionModel.getName()); } @Test public void testGetDefaultKieSessionModelEmptyKmodule() { KieServices kieServices = KieServices.Factory.get(); String drl = "package org.drools.test\n" + "rule R1 when\n" + " $m : Object()\n" + "then\n" + "end\n"; Resource resource = kieServices.getResources().newReaderResource(new StringReader(drl), "UTF-8"); resource.setTargetPath("org/drools/test/rules.drl"); String kmodule = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<kmodule xmlns=\"http://www.drools.org/xsd/kmodule\">\n" + "</kmodule>"; // Create an in-memory jar for version 1.0.0 ReleaseId releaseId = kieServices.newReleaseId("org.kie", "test-testGetDefaultKieSessionModelEmptyKmodule", "1.0.0"); createAndDeployJar(kieServices, kmodule, releaseId, resource); KieContainer kieContainer = kieServices.newKieContainer(releaseId); KieSessionModel sessionModel = kieContainer.getKieSessionModel(null); assertNotNull(sessionModel); } private String createDRL(String ruleName) { return "package org.kie.test\n" + "global java.util.List list\n" + "rule " + ruleName + "\n" + "when\n" + "then\n" + "list.add( drools.getRule().getName() );\n" + "end\n"; } }