diff options
Diffstat (limited to 'policy-core')
15 files changed, 761 insertions, 63 deletions
diff --git a/policy-core/drools-artifact-1.1/pom.xml b/policy-core/drools-artifact-1.1/pom.xml new file mode 100644 index 00000000..24a6d37d --- /dev/null +++ b/policy-core/drools-artifact-1.1/pom.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP Policy Engine - Drools PDP + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + 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. + ============LICENSE_END========================================================= + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <artifactId>drools-artifact1</artifactId> + <version>17.1.0-SNAPSHOT</version> + <description>supports Junit tests in policy-core</description> + + <parent> + <groupId>org.onap.policy.drools-pdp</groupId> + <artifactId>drools-pdp</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> +</project> diff --git a/policy-core/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml b/policy-core/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 00000000..22319689 --- /dev/null +++ b/policy-core/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> + <kbase name="rules"> + <ksession name="session1"/> + </kbase> +</kmodule> diff --git a/policy-core/drools-artifact-1.1/src/main/resources/rules.drl b/policy-core/drools-artifact-1.1/src/main/resources/rules.drl new file mode 100644 index 00000000..9dac208b --- /dev/null +++ b/policy-core/drools-artifact-1.1/src/main/resources/rules.drl @@ -0,0 +1,30 @@ +package org.onap.policy.drools.core.test; + +rule "Initialization" + when + then + { + System.out.println("Initialization rule running"); + } +end + +rule "Add elements of an int array" + when + $object : Object() + then + { + if ($object instanceof int[]) + { + int[] array = (int[])($object); + + System.out.println("Received array of length " + array.length); + int sum = 0; + for (int i = 1 ; i < array.length ; i += 1) + { + sum += array[i]; + } + array[0] = sum; + retract($object); + } + } +end diff --git a/policy-core/drools-artifact-1.2/pom.xml b/policy-core/drools-artifact-1.2/pom.xml new file mode 100644 index 00000000..6b39d7c4 --- /dev/null +++ b/policy-core/drools-artifact-1.2/pom.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP Policy Engine - Drools PDP + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + 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. + ============LICENSE_END========================================================= + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <artifactId>drools-artifact1</artifactId> + <version>17.2.0-SNAPSHOT</version> + <description>supports Junit tests in policy-core</description> + + <parent> + <groupId>org.onap.policy.drools-pdp</groupId> + <artifactId>drools-pdp</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> +</project> diff --git a/policy-core/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml b/policy-core/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 00000000..22319689 --- /dev/null +++ b/policy-core/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> + <kbase name="rules"> + <ksession name="session1"/> + </kbase> +</kmodule> diff --git a/policy-core/drools-artifact-1.2/src/main/resources/rules.drl b/policy-core/drools-artifact-1.2/src/main/resources/rules.drl new file mode 100644 index 00000000..e69b6597 --- /dev/null +++ b/policy-core/drools-artifact-1.2/src/main/resources/rules.drl @@ -0,0 +1,29 @@ +package org.onap.policy.drools.core.test; + +rule "Initialization" + when + then + { + System.out.println("Initialization rule running"); + } +end + +rule "Multiply elements of an int array" + when + $object : Object() + then + { + if ($object instanceof int[]) + { + int[] array = (int[])($object); + + System.out.println("Received array of length " + array.length); + int product = 1; + for (int i = 1 ; i < array.length ; i += 1) + { + product *= array[i]; + } + array[0] = product; + } + } +end diff --git a/policy-core/pom.xml b/policy-core/pom.xml index 076a4bf2..53e6f4aa 100644 --- a/policy-core/pom.xml +++ b/policy-core/pom.xml @@ -30,6 +30,57 @@ <version>1.1.0-SNAPSHOT</version> </parent> + <build> + <plugins> + + <!-- + 'maven-invoker-plugin' is used to build and install two versions of a + Drools artifact, both of which are used in Junit tests. These Maven + projects are invisible to Sonar and SonarQube, so there are no + complaints about multiple projects with the same artifact, and they + don't show up in the list of files or code line counts. + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-invoker-plugin</artifactId> + <version>3.0.1</version> + <executions> + + <execution> + <id>drools-artifact-1.1</id> + <goals> + <goal>run</goal> + </goals> + <phase>test-compile</phase> + <configuration> + <pom>drools-artifact-1.1/pom.xml</pom> + <goals> + <goal>install</goal> + </goals> + <streamLogs>true</streamLogs> + </configuration> + </execution> + + <execution> + <id>drools-artifact-1.2</id> + <goals> + <goal>run</goal> + </goals> + <phase>test-compile</phase> + <configuration> + <pom>drools-artifact-1.2/pom.xml</pom> + <goals> + <goal>install</goal> + </goals> + <streamLogs>true</streamLogs> + </configuration> + </execution> + + </executions> + </plugin> + </plugins> + </build> + <dependencies> <dependency> <groupId>org.kie</groupId> @@ -61,5 +112,5 @@ <artifactId>junit</artifactId> <scope>test</scope> </dependency> - </dependencies> + </dependencies> </project> diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java b/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java index 9fc2c837..2da53468 100644 --- a/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java +++ b/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java @@ -51,11 +51,11 @@ public class PolicyContainer implements Startable // set of all 'PolicyContainer' instances static private HashSet<PolicyContainer> containers = - new HashSet<PolicyContainer>(); + new HashSet<>(); // maps feature objects to per-PolicyContainer data private ConcurrentHashMap<Object, Object> adjuncts = - new ConcurrentHashMap<Object, Object>(); + new ConcurrentHashMap<>(); // 'KieContainer' associated with this 'PolicyContainer' private KieContainer kieContainer; @@ -66,7 +66,7 @@ public class PolicyContainer implements Startable // maps session name into the associated 'PolicySession' instance private HashMap<String, PolicySession> sessions = - new HashMap<String, PolicySession>(); + new HashMap<>(); // if not null, this is a 'KieScanner' looking for updates private KieScanner scanner = null; @@ -104,21 +104,22 @@ public class PolicyContainer implements Startable */ public PolicyContainer(ReleaseId releaseId) { - if (releaseId.getVersion().contains(",")) + ReleaseId newReleaseId = releaseId; + if (newReleaseId.getVersion().contains(",")) { // this is actually a comma-separated list of release ids - releaseId = loadArtifact(releaseId.getGroupId(), - releaseId.getArtifactId(), - releaseId.getVersion()); + newReleaseId = loadArtifact(newReleaseId.getGroupId(), + newReleaseId.getArtifactId(), + newReleaseId.getVersion()); } else { - kieContainer = kieServices.newKieContainer(releaseId); + kieContainer = kieServices.newKieContainer(newReleaseId); } synchronized(containers) { - if(releaseId != null){ - logger.info("Add a new kieContainer in containers: releaseId: " + releaseId.toString()); + if(newReleaseId != null){ + logger.info("Add a new kieContainer in containers: releaseId: " + newReleaseId.toString()); }else{ logger.warn("input releaseId is null"); } @@ -182,9 +183,9 @@ public class PolicyContainer implements Startable { // all of the 'newKieContainer' invocations failed -- throw the // most recent exception - throw(exception); + throw exception; } - return(releaseId); + return releaseId; } /** @@ -198,7 +199,7 @@ public class PolicyContainer implements Startable */ public String getName() { - return(kieContainer.getReleaseId().toString()); + return kieContainer.getReleaseId().toString(); } /** @@ -206,7 +207,7 @@ public class PolicyContainer implements Startable */ public KieContainer getKieContainer() { - return(kieContainer); + return kieContainer; } /** @@ -214,7 +215,7 @@ public class PolicyContainer implements Startable */ public ClassLoader getClassLoader() { - return(kieContainer.getClassLoader()); + return kieContainer.getClassLoader(); } /** @@ -223,7 +224,7 @@ public class PolicyContainer implements Startable */ public String getGroupId() { - return(kieContainer.getReleaseId().getGroupId()); + return kieContainer.getReleaseId().getGroupId(); } /** @@ -232,7 +233,7 @@ public class PolicyContainer implements Startable */ public String getArtifactId() { - return(kieContainer.getReleaseId().getArtifactId()); + return kieContainer.getReleaseId().getArtifactId(); } /** @@ -241,7 +242,7 @@ public class PolicyContainer implements Startable */ public String getVersion() { - return(kieContainer.getReleaseId().getVersion()); + return kieContainer.getReleaseId().getVersion(); } /** @@ -253,7 +254,7 @@ public class PolicyContainer implements Startable */ public PolicySession getPolicySession(String name) { - return(sessions.get(name)); + return sessions.get(name); } /** @@ -325,7 +326,7 @@ public class PolicyContainer implements Startable logger.info("activatePolicySession:session - " + (session == null ? "null" : session.getFullName()) + " is returned."); - return(session); + return session; } } @@ -352,14 +353,14 @@ public class PolicyContainer implements Startable if(name == null){ logger.warn("adoptKieSession:input name is null"); - throw(new IllegalArgumentException + throw new IllegalArgumentException ("KieSession input name is null " - + getName())); + + getName()); }else if(kieSession == null){ logger.warn("adoptKieSession:input kieSession is null"); - throw(new IllegalArgumentException + throw new IllegalArgumentException ("KieSession '" + name + "' is null " - + getName())); + + getName()); }else { logger.info("adoptKieSession:name: " + name + " kieSession: " + kieSession); } @@ -381,17 +382,17 @@ public class PolicyContainer implements Startable // default KieBase, if it exists if (!match && kieBase != kieContainer.getKieBase()) { - throw(new IllegalArgumentException + throw new IllegalArgumentException ("KieSession '" + name + "' does not reside within container " - + getName())); + + getName()); } synchronized (sessions) { if (sessions.get(name) != null) { - throw(new IllegalStateException - ("PolicySession '" + name + "' already exists")); + throw new IllegalStateException + ("PolicySession '" + name + "' already exists"); } // create the new 'PolicySession', add it to the table, @@ -415,7 +416,7 @@ public class PolicyContainer implements Startable + feature.getClass().getName(), e); } } - return(policySession); + return policySession; } } @@ -437,8 +438,8 @@ public class PolicyContainer implements Startable releaseId.getArtifactId(), newVersion)); - List<Message> messages = (results == null ? null : results.getMessages()); - return(messages == null ? null : messages.toString()); + List<Message> messages = results == null ? null : results.getMessages(); + return messages == null ? null : messages.toString(); } /** @@ -473,7 +474,7 @@ public class PolicyContainer implements Startable session.updated(); } - return(results); + return results; } /** @@ -483,7 +484,7 @@ public class PolicyContainer implements Startable { synchronized(containers) { - return(new HashSet<PolicyContainer>(containers)); + return new HashSet<>(containers); } } @@ -495,7 +496,7 @@ public class PolicyContainer implements Startable // KLUDGE WARNING: this is a temporary workaround -- if there are // no features, we don't have persistence, and 'activate' is never // called. In this case, make sure the container is started. - if (PolicySessionFeatureAPI.impl.getList().size() == 0) + if (PolicySessionFeatureAPI.impl.getList().isEmpty()) { start(); } @@ -503,7 +504,7 @@ public class PolicyContainer implements Startable // return current set of PolicySessions synchronized(sessions) { - return(new HashSet<PolicySession>(sessions.values())); + return new HashSet<>(sessions.values()); } } @@ -518,7 +519,7 @@ public class PolicyContainer implements Startable { String version = releaseId.getVersion(); if (scannerStarted == false && scanner == null && version != null - && (version.equals("LATEST") || version.equals("RELEASE") + && ("LATEST".equals(version) || "RELEASE".equals(version) || version.endsWith("-SNAPSHOT"))) { // create the scanner, and poll at 60 second intervals @@ -529,6 +530,7 @@ public class PolicyContainer implements Startable // start this in a separate thread -- it can block for a long time new Thread("Scanner Starter " + getName()) { + @Override public void run() { scanner = kieServices.newKieScanner(kieContainer); @@ -562,10 +564,10 @@ public class PolicyContainer implements Startable if (session != null) { session.getKieSession().insert(object); - return(true); + return true; } } - return(false); + return false; } /** @@ -586,7 +588,7 @@ public class PolicyContainer implements Startable rval = true; } } - return(rval); + return rval; } /*************************/ @@ -596,6 +598,7 @@ public class PolicyContainer implements Startable /** * {@inheritDoc} */ + @Override public synchronized boolean start() { if (!isStarted) @@ -619,12 +622,13 @@ public class PolicyContainer implements Startable } isStarted = true; } - return(true); + return true; } /** * {@inheritDoc} */ + @Override public synchronized boolean stop() { if (isStarted) @@ -634,7 +638,7 @@ public class PolicyContainer implements Startable synchronized (sessions) { // local set containing all of the sessions - localSessions = new HashSet<PolicySession>(sessions.values()); + localSessions = new HashSet<>(sessions.values()); // clear the 'name->session' map in 'PolicyContainer' sessions.clear(); @@ -664,12 +668,13 @@ public class PolicyContainer implements Startable } isStarted = false; } - return(true); + return true; } /** * {@inheritDoc} */ + @Override public synchronized void shutdown() { // Note that this method does not call 'destroy' on the 'KieSession' @@ -689,9 +694,10 @@ public class PolicyContainer implements Startable /** * {@inheritDoc} */ + @Override public boolean isAlive() { - return(isStarted); + return isStarted; } /*************************/ @@ -710,7 +716,7 @@ public class PolicyContainer implements Startable synchronized (sessions) { // local set containing all of the sessions - localSessions = new HashSet<PolicySession>(sessions.values()); + localSessions = new HashSet<>(sessions.values()); // clear the 'name->session' map in 'PolicyContainer' sessions.clear(); @@ -831,7 +837,7 @@ public class PolicyContainer implements Startable */ public Object getAdjunct(Object object) { - return(adjuncts.get(object)); + return adjuncts.get(object); } /** diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/PolicySession.java b/policy-core/src/main/java/org/onap/policy/drools/core/PolicySession.java index c18c1343..2a949c0b 100644 --- a/policy-core/src/main/java/org/onap/policy/drools/core/PolicySession.java +++ b/policy-core/src/main/java/org/onap/policy/drools/core/PolicySession.java @@ -62,7 +62,7 @@ public class PolicySession // maps feature objects to per-PolicyContainer data private ConcurrentHashMap<Object, Object> adjuncts = - new ConcurrentHashMap<Object, Object>(); + new ConcurrentHashMap<>(); // associated 'KieSession' instance private KieSession kieSession; @@ -72,7 +72,7 @@ public class PolicySession // supports 'getCurrentSession()' method static private ThreadLocal<PolicySession> policySession = - new ThreadLocal<PolicySession>(); + new ThreadLocal<>(); /** * Internal constructor - create a 'PolicySession' instance @@ -96,7 +96,7 @@ public class PolicySession */ public PolicyContainer getPolicyContainer() { - return(container); + return container; } /** @@ -104,7 +104,7 @@ public class PolicySession */ public KieSession getKieSession() { - return(kieSession); + return kieSession; } /** @@ -114,7 +114,7 @@ public class PolicySession */ public String getName() { - return(name); + return name; } /** @@ -123,7 +123,7 @@ public class PolicySession */ public String getFullName() { - return(container.getName() + ":" + name); + return container.getName() + ":" + name; } /** @@ -204,7 +204,7 @@ public class PolicySession */ public static PolicySession getCurrentSession() { - return(policySession.get()); + return policySession.get(); } /** @@ -218,7 +218,7 @@ public class PolicySession */ public Object getAdjunct(Object object) { - return(adjuncts.get(object)); + return adjuncts.get(object); } /** @@ -555,19 +555,19 @@ public class PolicySession // We want to continue looping, despite any exceptions that occur // while rules are fired. - KieSession kieSession = session.getKieSession(); + KieSession kieSession1 = session.getKieSession(); while (repeat) { try { - kieSession.fireUntilHalt(); + kieSession1.fireUntilHalt(); - // if we fall through, it means 'KieSession.halt()' was called, + // if we fall through, it means 'kieSession1.halt()' was called, // but this may be a result of 'KieScanner' doing an update } catch (Exception | LinkageError e) { - logger.error("startThread error in kieSession.fireUntilHalt", e); + logger.error("startThread error in kieSession1.fireUntilHalt", e); } } logger.info("fireUntilHalt() returned"); diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/PolicySessionFeatureAPI.java b/policy-core/src/main/java/org/onap/policy/drools/core/PolicySessionFeatureAPI.java index 6777eb59..39377ab7 100644 --- a/policy-core/src/main/java/org/onap/policy/drools/core/PolicySessionFeatureAPI.java +++ b/policy-core/src/main/java/org/onap/policy/drools/core/PolicySessionFeatureAPI.java @@ -39,7 +39,7 @@ public interface PolicySessionFeatureAPI extends OrderedService * implementing the 'FeatureAPI' interface. */ static public OrderedServiceImpl<PolicySessionFeatureAPI> impl = - new OrderedServiceImpl<PolicySessionFeatureAPI>(PolicySessionFeatureAPI.class); + new OrderedServiceImpl<>(PolicySessionFeatureAPI.class); /** * This method is called during initialization at a point right after @@ -68,7 +68,7 @@ public interface PolicySessionFeatureAPI extends OrderedService default public KieSession activatePolicySession (PolicyContainer policyContainer, String name, String kieBaseName) { - return(null); + return null; } /** @@ -86,7 +86,7 @@ public interface PolicySessionFeatureAPI extends OrderedService default public PolicySession.ThreadModel selectThreadModel (PolicySession session) { - return(null); + return null; } /** diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java b/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java index d3cf2e9d..19f6afb4 100644 --- a/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java +++ b/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java @@ -31,16 +31,21 @@ public class PdpJmx implements PdpJmxMBean { public static PdpJmx getInstance() { return instance; } - + + @Override public long getUpdates(){ return updates.longValue(); } + + @Override public long getRulesFired(){ return actions.longValue(); } + public void updateOccured(){ updates.incrementAndGet(); } + public void ruleFired(){ actions.incrementAndGet(); } diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmxListener.java b/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmxListener.java index ceb7049e..9136defb 100644 --- a/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmxListener.java +++ b/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmxListener.java @@ -36,7 +36,10 @@ import org.slf4j.LoggerFactory; public class PdpJmxListener { public static final Logger logger = LoggerFactory.getLogger(PdpJmxListener.class); - + + private PdpJmxListener() { + } + public static void stop() { final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); try { diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java new file mode 100644 index 00000000..e83f026c --- /dev/null +++ b/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java @@ -0,0 +1,334 @@ +/*- + * ============LICENSE_START======================================================= + * policy-core + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.core; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * These tests focus on the following classes: + * PolicyContainer + * PolicySession + * PolicySessionFeatureAPI + */ +public class DroolsContainerTest +{ + /** + * This test is centered around the creation of a 'PolicyContainer' + * and 'PolicySession', and the updating of that container to a new + * version. + */ + @Test + public void createAndUpdate() throws Exception + { + // make sure feature log starts out clean + TestPolicySessionFeatureAPI.getLog(); + + // run 'globalInit', and verify expected feature hook fired + PolicyContainer.globalInit(new String[0]); + assertEquals(buildArrayList("globalInit"), + TestPolicySessionFeatureAPI.getLog()); + + // initial conditions -- there should be no containers + assertEquals(0, PolicyContainer.getPolicyContainers().size()); + + // create the container, and start it + PolicyContainer container = + new PolicyContainer("org.onap.policy.drools-pdp", + "drools-artifact1", "17.1.0-SNAPSHOT"); + container.start(); + assertTrue(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("activatePolicySession", + "newPolicySession", + "selectThreadModel"), + TestPolicySessionFeatureAPI.getLog()); + + // this container should be on the list + { + Collection<PolicyContainer> containers = + PolicyContainer.getPolicyContainers(); + assertEquals(1, containers.size()); + assertTrue(containers.contains(container)); + } + + // verify initial container attributes + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT", + container.getName()); + assertEquals("org.onap.policy.drools-pdp", container.getGroupId()); + assertEquals("drools-artifact1", container.getArtifactId()); + assertEquals("17.1.0-SNAPSHOT", container.getVersion()); + + try + { + // fetch the session, and verify that it exists + PolicySession session = container.getPolicySession("session1"); + assertTrue(session != null); + + // get all sessions, and verify that this one is the only one + { + Collection<PolicySession> sessions = container.getPolicySessions(); + assertEquals(1, sessions.size()); + assertTrue(sessions.contains(session)); + } + + // verify session attributes + assertEquals(container, session.getPolicyContainer()); + assertEquals("session1", session.getName()); + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1", + session.getFullName()); + + // insert a new fact + int[] a = new int[]{0, 3, 8, 2}; + session.getKieSession().insert(a); + + // the Drools rules should add 3 + 8 + 2, and store 13 in a[0] + assertTrue(waitForChange(a) == 13); + + // update the container to a new version -- + // the rules will then multiply values rather than add them + assertEquals("[]", + container.updateToVersion("17.2.0-SNAPSHOT").toString()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("selectThreadModel"), + TestPolicySessionFeatureAPI.getLog()); + + // verify new container attributes + assertEquals + ("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT", + container.getName()); + assertEquals("org.onap.policy.drools-pdp", container.getGroupId()); + assertEquals("drools-artifact1", container.getArtifactId()); + assertEquals("17.2.0-SNAPSHOT", container.getVersion()); + + // verify new session attributes + assertEquals(container, session.getPolicyContainer()); + assertEquals("session1", session.getName()); + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT:session1", + session.getFullName()); + + // the updated rules should now multiply 3 * 8 * 2, and return 48 + + a[0] = 0; + container.insert("session1", a); + assertTrue(waitForChange(a) == 48); + } + finally + { + container.shutdown(); + assertFalse(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("disposeKieSession"), + TestPolicySessionFeatureAPI.getLog()); + } + + // final conditions -- there should be no containers + assertEquals(0, PolicyContainer.getPolicyContainers().size()); + } + + /** + * This test create a 'PolicyContainer' and 'PolicySession', and verifies + * their behavior, but uses alternate interfaces to increase code coverage. + * In addition, feature hook invocations will trigger exceptions in this + * test, also to increase code coverage. + */ + @Test + public void versionList() throws Exception + { + // make sure feature log starts out clean + TestPolicySessionFeatureAPI.getLog(); + + // trigger exceptions in all feature hooks + TestPolicySessionFeatureAPI.setExceptionTrigger(true); + + // run 'globalInit', and verify expected feature hook fired + PolicyContainer.globalInit(new String[0]); + assertEquals(buildArrayList("globalInit-exception"), + TestPolicySessionFeatureAPI.getLog()); + + // initial conditions -- there should be no containers + assertEquals(0, PolicyContainer.getPolicyContainers().size()); + + String versionList = + "17.3.0-SNAPSHOT,17.1.0-SNAPSHOT,17.2.0-SNAPSHOT"; + + // versions should be tried in order -- the 17.1.0-SNAPSHOT should "win", + // given the fact that '17.3.0-SNAPSHOT' doesn't exist + PolicyContainer container = + new PolicyContainer("org.onap.policy.drools-pdp", + "drools-artifact1", versionList); + // the following should be equivalent to 'container.start()' + PolicyContainer.activate(); + assertTrue(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("activatePolicySession-exception", + "newPolicySession-exception", + "selectThreadModel-exception"), + TestPolicySessionFeatureAPI.getLog()); + + // this container should be on the list + { + Collection<PolicyContainer> containers = + PolicyContainer.getPolicyContainers(); + assertEquals(1, containers.size()); + assertTrue(containers.contains(container)); + } + + // verify initial container attributes + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT", + container.getName()); + assertEquals("org.onap.policy.drools-pdp", container.getGroupId()); + assertEquals("drools-artifact1", container.getArtifactId()); + assertEquals("17.1.0-SNAPSHOT", container.getVersion()); + + // some container adjunct tests + { + Object bogusAdjunct = new Object(); + + // initially, no adjunct + assertSame(null, container.getAdjunct(this)); + + // set and verify adjunct + container.setAdjunct(this, bogusAdjunct); + assertSame(bogusAdjunct, container.getAdjunct(this)); + + // clear and verify adjunct + container.setAdjunct(this, null); + assertSame(null, container.getAdjunct(this)); + } + + try + { + // fetch the session, and verify that it exists + PolicySession session = container.getPolicySession("session1"); + assertTrue(session != null); + + // get all sessions, and verify that this one is the only one + { + Collection<PolicySession> sessions = container.getPolicySessions(); + assertEquals(1, sessions.size()); + assertTrue(sessions.contains(session)); + } + + // verify session attributes + assertEquals(container, session.getPolicyContainer()); + assertEquals("session1", session.getName()); + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1", + session.getFullName()); + + // some session adjunct tests + { + Object bogusAdjunct = new Object(); + + // initially, no adjunct + assertSame(null, session.getAdjunct(this)); + + // set and verify adjunct + session.setAdjunct(this, bogusAdjunct); + assertSame(bogusAdjunct, session.getAdjunct(this)); + + // clear and verify adjunct + session.setAdjunct(this, null); + assertSame(null, session.getAdjunct(this)); + } + + // insert a new fact (using 'insertAll') + int[] a = new int[]{0, 7, 3, 4}; + container.insertAll(a); + + // the Drools rules should add 7 + 3 + 4, and store 14 in a[0] + assertTrue(waitForChange(a) == 14); + + // exercise some more API methods + assertEquals(container.getClassLoader(), + container.getKieContainer().getClassLoader()); + } + finally + { + // should be equivalent to 'shutdown' without persistence + container.destroy(); + assertFalse(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("destroyKieSession-exception"), + TestPolicySessionFeatureAPI.getLog()); + + // clear exception trigger + TestPolicySessionFeatureAPI.setExceptionTrigger(false); + } + + // final conditions -- there should be no containers + assertEquals(0, PolicyContainer.getPolicyContainers().size()); + } + + /** + * This method is tied to the expected behavior of the drools sessions. + * Initially, the value of 'array[0]' should be 0. The Drools rules + * will either add or multiply 'array[1]' through 'array[n-1]', depending + * upon the version. It waits up to 30 seconds for a non-zero value + * to appear. + */ + private int waitForChange(int[] array) throws InterruptedException + { + int rval = -1; + + // the value is tested every 1/100 of a second, and it waits up to + // 3000 iterations (= 30 seconds) for a non-zero value + for (int i = 0 ; i < 3000 ; i += 1) + { + // wait for 10 milliseconds = 1/100 of a second + Thread.sleep(10); + if ((rval = array[0]) != 0) + { + // a non-zero value has been stored + break; + } + } + return(rval); + } + + /** + * @param args an array of string arguments + * @return an ArrayList constructed from the provided arguments + */ + private ArrayList<String> buildArrayList(String... args) + { + ArrayList<String> rval = new ArrayList<>(); + for (String arg : args) + { + rval.add(arg); + } + return(rval); + } +} diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/TestPolicySessionFeatureAPI.java b/policy-core/src/test/java/org/onap/policy/drools/core/TestPolicySessionFeatureAPI.java new file mode 100644 index 00000000..f456d814 --- /dev/null +++ b/policy-core/src/test/java/org/onap/policy/drools/core/TestPolicySessionFeatureAPI.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * policy-core + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.core; + +import java.util.ArrayList; +import org.kie.api.runtime.KieSession; + +/** + * This class supports 'DroolsContainerTest' by implementing + * 'PolicySessionFeatureAPI', and providing a means to indicate + * which hooks have been invoked. + */ +public class TestPolicySessionFeatureAPI implements PolicySessionFeatureAPI +{ + // contains the log entries since the most recent 'getLog()' call + static private ArrayList<String> log = new ArrayList<>(); + + // if 'true', trigger an exception right after doing the log, + // to verify that exceptions are handled + static private boolean exceptionTrigger = false; + + /** + * @return the current contents of the log, and clear the log + */ + static public ArrayList<String> getLog() + { + synchronized(log) + { + ArrayList<String> rval = new ArrayList<>(log); + log.clear(); + return(rval); + } + } + + /** + * This method controls whether these hooks trigger an exception after + * being invoked. + * + * @param indicator if 'true', subsequent hook method calls will trigger + * an exception; if 'false', no exception is triggered + */ + static public void setExceptionTrigger(boolean indicator) + { + exceptionTrigger = indicator; + } + + /** + * This method adds an entry to the log, and possibly triggers an exception + * + * @param arg value to add to the log + */ + static private void addLog(String arg) + { + if (exceptionTrigger) + { + // the log entry will include a '-exception' appended to the end + synchronized(log) + { + log.add(arg + "-exception"); + } + System.out.println("*** " + arg + "-exception invoked ***"); + + // throw an exception -- it is up to the invoking code to catch it + throw(new IllegalStateException("Triggered from " + arg)); + } + else + { + // create a log entry, and display to standard output + synchronized(log) + { + log.add(arg); + } + System.out.println("*** " + arg + " invoked ***"); + } + } + + /***************************************/ + /* 'PolicySessionFeatureAPI' interface */ + /***************************************/ + + /** + * {@inheritDoc} + */ + public int getSequenceNumber() + { + return(1); + } + + /** + * {@inheritDoc} + */ + public void globalInit(String args[], String configDir) + { + addLog("globalInit"); + } + + /** + * {@inheritDoc} + */ + public KieSession activatePolicySession + (PolicyContainer policyContainer, String name, String kieBaseName) + { + addLog("activatePolicySession"); + return(null); + } + + /** + * {@inheritDoc} + */ + public void newPolicySession(PolicySession policySession) + { + addLog("newPolicySession"); + } + + /** + * {@inheritDoc} + */ + public PolicySession.ThreadModel selectThreadModel(PolicySession session) + { + addLog("selectThreadModel"); + return(null); + } + + /** + * {@inheritDoc} + */ + public void disposeKieSession(PolicySession policySession) + { + addLog("disposeKieSession"); + } + + /** + * {@inheritDoc} + */ + public void destroyKieSession(PolicySession policySession) + { + addLog("destroyKieSession"); + } +} diff --git a/policy-core/src/test/resources/META-INF/services/org.onap.policy.drools.core.PolicySessionFeatureAPI b/policy-core/src/test/resources/META-INF/services/org.onap.policy.drools.core.PolicySessionFeatureAPI new file mode 100644 index 00000000..d6b088c3 --- /dev/null +++ b/policy-core/src/test/resources/META-INF/services/org.onap.policy.drools.core.PolicySessionFeatureAPI @@ -0,0 +1 @@ +org.onap.policy.drools.core.TestPolicySessionFeatureAPI |