diff options
Diffstat (limited to 'controlloop/templates/template.demo.clc/src/test/java/org')
2 files changed, 367 insertions, 63 deletions
diff --git a/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/ControlLoopParamsCleanupTest.java b/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/ControlLoopParamsCleanupTest.java new file mode 100644 index 000000000..257aeb350 --- /dev/null +++ b/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/ControlLoopParamsCleanupTest.java @@ -0,0 +1,231 @@ +/*- + * ============LICENSE_START======================================================= + * demo + * ================================================================================ + * Copyright (C) 2018 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.template.demo.clc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.kie.api.runtime.KieSession; +import org.onap.policy.controlloop.policy.ControlLoopPolicy; +import org.onap.policy.drools.utils.logging.LoggerUtil; +import org.onap.policy.template.demo.clc.Util.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Verifies that Params objects are cleaned up when rules are updated. This loads + * <b>two</b> copies of the rule set into a single policy to ensure that the two copies + * interact appropriately with each other's Params objects. + */ +public class ControlLoopParamsCleanupTest { + private static final Logger logger = LoggerFactory.getLogger(ControlLoopParamsCleanupTest.class); + + private static final String YAML = "src/test/resources/yaml/policy_ControlLoop_ParamsCleanup-test.yaml"; + + /** + * YAML to be used when the first rule set is updated. + */ + private static final String YAML2 = "src/test/resources/yaml/policy_ControlLoop_ParamsCleanup-test2.yaml"; + + private static final String POLICY_VERSION = "v2.0"; + + private static final String POLICY_NAME = "CL_CleanupTest"; + + private static final String POLICY_SCOPE = "type=operational"; + + private static final String CONTROL_LOOP_NAME = "ControlLoop-Params-Cleanup-Test"; + + private static final String DROOLS_TEMPLATE = "src/main/resources/__closedLoopControlName__.drl"; + + // values specific to the second copy of the rules + + private static final String YAML_B = "src/test/resources/yaml/policy_ControlLoop_ParamsCleanup-test-B.yaml"; + private static final String POLICY_NAME_B = "CL_CleanupTest_B"; + private static final String CONTROL_LOOP_NAME_B = "ControlLoop-Params-Cleanup-Test-B"; + + private static KieSession kieSession; + private static Util.RuleSpec[] specifications; + + /** + * Setup the simulator. + */ + @BeforeClass + public static void setUpSimulator() { + LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "INFO"); + + try { + specifications = new Util.RuleSpec[2]; + + specifications[0] = new Util.RuleSpec(DROOLS_TEMPLATE, CONTROL_LOOP_NAME, POLICY_SCOPE, POLICY_NAME, + POLICY_VERSION, loadYaml(YAML)); + + specifications[1] = new Util.RuleSpec(DROOLS_TEMPLATE, CONTROL_LOOP_NAME_B, POLICY_SCOPE, POLICY_NAME_B, + POLICY_VERSION, loadYaml(YAML_B)); + + kieSession = Util.buildContainer(POLICY_VERSION, specifications); + + } catch (IOException e) { + logger.error("Could not create kieSession", e); + fail("Could not create kieSession"); + } + } + + /** + * Tear down. + */ + @AfterClass + public static void tearDown() { + kieSession.dispose(); + } + + @Test + public void test() throws IOException { + + /* + * Let rules create Params objects. There should be one object for each set of + * rules. + */ + kieSession.fireAllRules(); + List<Object> facts = getSessionObjects(); + assertEquals(specifications.length, facts.size()); + Iterator<Object> iter = facts.iterator(); + + final Object fact1 = iter.next(); + assertTrue(fact1.toString().contains(loadYaml(YAML))); + + final Object fact1b = iter.next(); + assertTrue(fact1b.toString().contains(loadYaml(YAML_B))); + + logger.info("UPDATING VERSION TO v3.0"); + updatePolicy(YAML2, "v3.0"); + + /* + * Let rules update Params objects. The Params for the first set of rules should + * now be deleted and replaced with a new one, while the Params for the second set + * should be unchanged. + */ + kieSession.fireAllRules(); + facts = getSessionObjects(); + assertEquals(specifications.length, facts.size()); + iter = facts.iterator(); + + final Object fact2 = iter.next(); + assertTrue(fact2 != fact1); + assertTrue(fact2 != fact1b); + assertTrue(fact2.toString().contains(loadYaml(YAML2))); + + assertTrue(iter.next() == fact1b); + + logger.info("UPDATING VERSION TO v4.0"); + updatePolicy(YAML, "v4.0"); + + /* + * Let rules update Params objects. The Params for the first set of rules should + * now be deleted and replaced with a new one, while the Params for the second set + * should be unchanged. + */ + kieSession.fireAllRules(); + facts = getSessionObjects(); + assertEquals(specifications.length, facts.size()); + iter = facts.iterator(); + + final Object fact3 = iter.next(); + assertTrue(fact3.toString().contains(loadYaml(YAML))); + assertTrue(fact3 != fact2); + assertTrue(fact3 != fact1b); + + assertTrue(iter.next() == fact1b); + + logger.info("UPDATING VERSION TO v4.0 (i.e., unchanged)"); + updatePolicy(YAML, "v4.0"); + + /* + * Let rules update Params objects. As the version (and YAML) are unchanged for + * either rule set, both Params objects should be unchanged. + */ + kieSession.fireAllRules(); + facts = getSessionObjects(); + assertEquals(specifications.length, facts.size()); + iter = facts.iterator(); + assertTrue(iter.next() == fact3); + assertTrue(iter.next() == fact1b); + } + + /** + * Updates the policy, changing the YAML associated with the first rule set. + * + * @param yamlFile name of the YAML file + * @param policyVersion policy version + * @throws IOException if an error occurs + */ + private static void updatePolicy(String yamlFile, String policyVersion) throws IOException { + + specifications[0] = new Util.RuleSpec(DROOLS_TEMPLATE, CONTROL_LOOP_NAME, POLICY_SCOPE, POLICY_NAME, + policyVersion, loadYaml(yamlFile)); + + /* + * Update the policy within the container. + */ + Util.updateContainer(policyVersion, specifications); + } + + /** + * Loads a YAML file and URL-encodes it. + * + * @param yamlFile name of the YAML file + * @return the contents of the specified file, URL-encoded + * @throws UnsupportedEncodingException if an error occurs + */ + private static String loadYaml(String yamlFile) throws UnsupportedEncodingException { + Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yamlFile); + assertNotNull(pair); + assertNotNull(pair.first); + assertNotNull(pair.first.getControlLoop()); + assertNotNull(pair.first.getControlLoop().getControlLoopName()); + assertTrue(pair.first.getControlLoop().getControlLoopName().length() > 0); + + return URLEncoder.encode(pair.second, "UTF-8"); + } + + /** + * Gets the session objects. + * + * @return the session objects + */ + private static List<Object> getSessionObjects() { + // sort the objects so we know the order + LinkedList<Object> lst = new LinkedList<>(kieSession.getObjects()); + lst.sort((left, right) -> left.toString().compareTo(right.toString())); + + return lst; + } +} diff --git a/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/Util.java b/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/Util.java index 6001331de..1d105911c 100644 --- a/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/Util.java +++ b/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/Util.java @@ -33,12 +33,10 @@ import java.nio.file.Paths; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; - import org.apache.commons.io.IOUtils; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; @@ -46,7 +44,6 @@ import org.kie.api.builder.KieFileSystem; import org.kie.api.builder.Message; import org.kie.api.builder.ReleaseId; import org.kie.api.builder.Results; -import org.kie.api.builder.model.KieModuleModel; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.onap.policy.common.endpoints.http.server.HttpServletServer; @@ -64,6 +61,11 @@ public final class Util { private static final String OPSHISTPUPROP = "OperationsHistoryPU"; private static final Logger logger = LoggerFactory.getLogger(Util.class); + // values from the last call to buildContainer() + + private static KieServices kieServices; + private static KieContainer keyContainer; + public static class Pair<A, B> { public final A first; public final B second; @@ -123,39 +125,9 @@ public final class Util { return org.onap.policy.simulators.Util.buildAaiSim(); } - private static String generatePolicy(String ruleContents, - String closedLoopControlName, - String policyScope, - String policyName, - String policyVersion, - String controlLoopYaml) { - - Pattern pattern = Pattern.compile("\\$\\{closedLoopControlName\\}"); - Matcher matcher = pattern.matcher(ruleContents); - ruleContents = matcher.replaceAll(closedLoopControlName); - - pattern = Pattern.compile("\\$\\{policyScope\\}"); - matcher = pattern.matcher(ruleContents); - ruleContents = matcher.replaceAll(policyScope); - - pattern = Pattern.compile("\\$\\{policyName\\}"); - matcher = pattern.matcher(ruleContents); - ruleContents = matcher.replaceAll(policyName); - - pattern = Pattern.compile("\\$\\{policyVersion\\}"); - matcher = pattern.matcher(ruleContents); - ruleContents = matcher.replaceAll(policyVersion); - - pattern = Pattern.compile("\\$\\{controlLoopYaml\\}"); - matcher = pattern.matcher(ruleContents); - ruleContents = matcher.replaceAll(controlLoopYaml); - - return ruleContents; - } - /** - * Build the container. - * + * Build a container containing a single set of rules. + * * @param droolsTemplate template * @param closedLoopControlName control loop id * @param policyScope policy scope @@ -165,41 +137,82 @@ public final class Util { * @return the Kie session * @throws IOException if the container cannot be built */ - public static KieSession buildContainer(String droolsTemplate, String closedLoopControlName, - String policyScope, String policyName, String policyVersion, - String yamlSpecification) throws IOException { + public static KieSession buildContainer(String droolsTemplate, String closedLoopControlName, String policyScope, + String policyName, String policyVersion, String yamlSpecification) throws IOException { + + RuleSpec spec = new RuleSpec(droolsTemplate, closedLoopControlName, policyScope, policyName, policyVersion, + yamlSpecification); + + return buildContainer(policyVersion, new RuleSpec[] {spec}); + } + + /** + * Build a container containing all of the specified rules. + * + * @param policyVersion policy version + * @param specifications rule specifications + * @return the Kie session + * @throws IOException if the container cannot be built + */ + public static KieSession buildContainer(String policyVersion, RuleSpec[] specifications) throws IOException { // // Get our Drools Kie factory // - KieServices ks = KieServices.Factory.get(); + kieServices = KieServices.Factory.get(); + + ReleaseId releaseId = buildPolicy(policyVersion, specifications); + logger.debug(releaseId.toString()); - KieModuleModel kieModule = ks.newKieModuleModel(); + // + // Create our kie Session and container + // + keyContainer = kieServices.newKieContainer(releaseId); + + return keyContainer.newKieSession(); + } + + /** + * Update the container with new rules. + * + * @param policyVersion new policy version + * @param specifications new rule specifications + * @throws IOException if the container cannot be built + */ + public static void updateContainer(String policyVersion, RuleSpec[] specifications) throws IOException { + ReleaseId releaseId = buildPolicy(policyVersion, specifications); + logger.debug(releaseId.toString()); - logger.debug("KMODULE:" + System.lineSeparator() + kieModule.toXML()); + keyContainer.updateToVersion(releaseId); + } + /** + * Build the Policy so it can be loaded into a KIE container. + * + * @param policyVersion policy version + * @param specifications rule specifications + * @return the release + * @throws IOException if the container cannot be built + */ + private static ReleaseId buildPolicy(String policyVersion, RuleSpec[] specifications) throws IOException { // // Generate our drools rule from our template // - KieFileSystem kfs = ks.newKieFileSystem(); + KieFileSystem kfs = kieServices.newKieFileSystem(); + ReleaseId releaseId = kieServices.getRepository().getDefaultReleaseId(); + releaseId = kieServices.newReleaseId(releaseId.getGroupId(), releaseId.getArtifactId(), policyVersion); - kfs.writeKModuleXML(kieModule.toXML()); - { - Path rule = Paths.get(droolsTemplate); - String ruleTemplate = new String(Files.readAllBytes(rule)); - String drlContents = generatePolicy(ruleTemplate, - closedLoopControlName, - policyScope, - policyName, - policyVersion, - yamlSpecification); - - kfs.write("src/main/resources/" + policyName + ".drl", - ks.getResources().newByteArrayResource(drlContents.getBytes())); + kfs.generateAndWritePomXML(releaseId); + + for (RuleSpec spec : specifications) { + String drlContents = spec.generateRules(); + kfs.write("src/main/resources/" + spec.policyName + ".drl", + kieServices.getResources().newByteArrayResource(drlContents.getBytes())); } + // // Compile the rule // - KieBuilder builder = ks.newKieBuilder(kfs).buildAll(); + KieBuilder builder = kieServices.newKieBuilder(kfs).buildAll(); Results results = builder.getResults(); if (results.hasMessages(Message.Level.ERROR)) { for (Message msg : results.getMessages()) { @@ -210,14 +223,8 @@ public final class Util { for (Message msg : results.getMessages()) { logger.debug(msg.toString()); } - // - // Create our kie Session and container - // - ReleaseId releaseId = ks.getRepository().getDefaultReleaseId(); - logger.debug(releaseId.toString()); - KieContainer keyContainer = ks.newKieContainer(releaseId); - return keyContainer.newKieSession(); + return releaseId; } /** @@ -291,4 +298,70 @@ public final class Util { emf.close(); return results; } + + /** + * Rule specification. + */ + public static class RuleSpec { + private String droolsTemplate; + private String closedLoopControlName; + private String policyScope; + private String policyName; + private String policyVersion; + private String yamlSpecification; + + /** + * Constructs the object. + * + * @param droolsTemplate template + * @param closedLoopControlName control loop id + * @param policyScope policy scope + * @param policyName policy name + * @param policyVersion policy version + * @param yamlSpecification incoming yaml specification + */ + public RuleSpec(String droolsTemplate, String closedLoopControlName, String policyScope, String policyName, + String policyVersion, String yamlSpecification) { + + this.droolsTemplate = droolsTemplate; + this.closedLoopControlName = closedLoopControlName; + this.policyScope = policyScope; + this.policyName = policyName; + this.policyVersion = policyVersion; + this.yamlSpecification = yamlSpecification; + } + + /** + * Generates the rules by reading the template and making variable substitutions. + * + * @return the rules + * @throws IOException if an error occurs + */ + private String generateRules() throws IOException { + Path rule = Paths.get(droolsTemplate); + String ruleTemplate = new String(Files.readAllBytes(rule)); + + Pattern pattern = Pattern.compile("\\$\\{closedLoopControlName\\}"); + Matcher matcher = pattern.matcher(ruleTemplate); + ruleTemplate = matcher.replaceAll(closedLoopControlName); + + pattern = Pattern.compile("\\$\\{policyScope\\}"); + matcher = pattern.matcher(ruleTemplate); + ruleTemplate = matcher.replaceAll(policyScope); + + pattern = Pattern.compile("\\$\\{policyName\\}"); + matcher = pattern.matcher(ruleTemplate); + ruleTemplate = matcher.replaceAll(policyName); + + pattern = Pattern.compile("\\$\\{policyVersion\\}"); + matcher = pattern.matcher(ruleTemplate); + ruleTemplate = matcher.replaceAll(policyVersion); + + pattern = Pattern.compile("\\$\\{controlLoopYaml\\}"); + matcher = pattern.matcher(ruleTemplate); + ruleTemplate = matcher.replaceAll(yamlSpecification); + + return ruleTemplate; + } + } } |