2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.policy.template.demo.clc;
 
  23 import static org.junit.Assert.fail;
 
  26 import java.io.FileInputStream;
 
  27 import java.io.IOException;
 
  28 import java.io.InputStream;
 
  29 import java.nio.charset.StandardCharsets;
 
  30 import java.nio.file.Files;
 
  31 import java.nio.file.Path;
 
  32 import java.nio.file.Paths;
 
  33 import java.util.List;
 
  34 import java.util.regex.Matcher;
 
  35 import java.util.regex.Pattern;
 
  36 import javax.persistence.EntityManager;
 
  37 import javax.persistence.EntityManagerFactory;
 
  38 import javax.persistence.Persistence;
 
  39 import javax.persistence.Query;
 
  40 import org.apache.commons.io.IOUtils;
 
  41 import org.kie.api.KieServices;
 
  42 import org.kie.api.builder.KieBuilder;
 
  43 import org.kie.api.builder.KieFileSystem;
 
  44 import org.kie.api.builder.Message;
 
  45 import org.kie.api.builder.ReleaseId;
 
  46 import org.kie.api.builder.Results;
 
  47 import org.kie.api.runtime.KieContainer;
 
  48 import org.kie.api.runtime.KieSession;
 
  49 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
 
  50 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
 
  51 import org.onap.policy.controlloop.policy.guard.ControlLoopGuard;
 
  52 import org.onap.policy.drools.system.PolicyEngine;
 
  53 import org.slf4j.Logger;
 
  54 import org.slf4j.LoggerFactory;
 
  55 import org.yaml.snakeyaml.Yaml;
 
  56 import org.yaml.snakeyaml.constructor.Constructor;
 
  59 public final class SupportUtil {
 
  61     private static final String OPSHISTPUPROP = "OperationsHistoryPU";
 
  62     private static final Logger logger = LoggerFactory.getLogger(SupportUtil.class);
 
  64     // values from the last call to buildContainer()
 
  66     private static KieServices kieServices;
 
  67     private static KieContainer keyContainer;
 
  69     public static class Pair<A, B> {
 
  71         public final B second;
 
  73         public Pair(A first, B second) {
 
  82      * @param testFile test file to load
 
  83      * @return the Pair of a policy and the yaml contents
 
  85     public static Pair<ControlLoopPolicy, String> loadYaml(String testFile) {
 
  86         try (InputStream is = new FileInputStream(new File(testFile))) {
 
  87             String contents = IOUtils.toString(is, StandardCharsets.UTF_8);
 
  89             // Read the yaml into our Java Object
 
  91             Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
 
  92             Object obj = yaml.load(contents);
 
  94             logger.debug(contents);
 
  96             return new Pair<ControlLoopPolicy, String>((ControlLoopPolicy) obj, contents);
 
  97         } catch (IOException e) {
 
  98             fail(e.getLocalizedMessage());
 
 104      * Load the YAML guard policy.
 
 106      * @param testFile the test file to load
 
 107      * @return return the guard object
 
 109     public static ControlLoopGuard loadYamlGuard(String testFile) {
 
 110         try (InputStream is = new FileInputStream(new File(testFile))) {
 
 111             String contents = IOUtils.toString(is, StandardCharsets.UTF_8);
 
 113             // Read the yaml into our Java Object
 
 115             Yaml yaml = new Yaml(new Constructor(ControlLoopGuard.class));
 
 116             Object obj = yaml.load(contents);
 
 117             return (ControlLoopGuard) obj;
 
 118         } catch (IOException e) {
 
 119             fail(e.getLocalizedMessage());
 
 124     public static HttpServletServer buildAaiSim() throws InterruptedException, IOException {
 
 125         return org.onap.policy.simulators.Util.buildAaiSim();
 
 129      * Build a container containing a single set of rules.
 
 131      * @param droolsTemplate template
 
 132      * @param closedLoopControlName control loop id
 
 133      * @param policyScope policy scope
 
 134      * @param policyName policy name
 
 135      * @param policyVersion policy version
 
 136      * @param yamlSpecification incoming yaml specification
 
 137      * @return the Kie session
 
 138      * @throws IOException if the container cannot be built
 
 140     public static KieSession buildContainer(String droolsTemplate, String closedLoopControlName, String policyScope,
 
 141                     String policyName, String policyVersion, String yamlSpecification) throws IOException {
 
 143         RuleSpec spec = new RuleSpec(droolsTemplate, closedLoopControlName, policyScope, policyName, policyVersion,
 
 146         return buildContainer(policyVersion, new RuleSpec[] {spec});
 
 150      * Build a container containing all of the specified rules.
 
 152      * @param policyVersion policy version
 
 153      * @param specifications rule specifications
 
 154      * @return the Kie session
 
 155      * @throws IOException if the container cannot be built
 
 157     public static KieSession buildContainer(String policyVersion, RuleSpec[] specifications) throws IOException {
 
 159         // Get our Drools Kie factory
 
 161         kieServices = KieServices.Factory.get();
 
 163         ReleaseId releaseId = buildPolicy(policyVersion, specifications);
 
 164         logger.debug(releaseId.toString());
 
 167         // Create our kie Session and container
 
 169         keyContainer = kieServices.newKieContainer(releaseId);
 
 171         return keyContainer.newKieSession();
 
 175      * Update the container with new rules.
 
 177      * @param policyVersion new policy version
 
 178      * @param specifications new rule specifications
 
 179      * @throws IOException if the container cannot be built
 
 181     public static void updateContainer(String policyVersion, RuleSpec[] specifications) throws IOException {
 
 182         ReleaseId releaseId = buildPolicy(policyVersion, specifications);
 
 183         logger.debug(releaseId.toString());
 
 185         keyContainer.updateToVersion(releaseId);
 
 189      * Build the Policy so it can be loaded into a KIE container.
 
 191      * @param policyVersion policy version
 
 192      * @param specifications rule specifications
 
 193      * @return the release
 
 194      * @throws IOException if the container cannot be built
 
 196     private static ReleaseId buildPolicy(String policyVersion, RuleSpec[] specifications) throws IOException {
 
 198         // Generate our drools rule from our template
 
 200         KieFileSystem kfs = kieServices.newKieFileSystem();
 
 201         ReleaseId releaseId = kieServices.getRepository().getDefaultReleaseId();
 
 202         releaseId = kieServices.newReleaseId(releaseId.getGroupId(), releaseId.getArtifactId(), policyVersion);
 
 204         kfs.generateAndWritePomXML(releaseId);
 
 206         for (RuleSpec spec : specifications) {
 
 207             String drlContents = spec.generateRules();
 
 208             kfs.write("src/main/resources/" + spec.policyName + ".drl",
 
 209                             kieServices.getResources().newByteArrayResource(drlContents.getBytes()));
 
 215         KieBuilder builder = kieServices.newKieBuilder(kfs).buildAll();
 
 216         Results results = builder.getResults();
 
 217         if (results.hasMessages(Message.Level.ERROR)) {
 
 218             for (Message msg : results.getMessages()) {
 
 219                 logger.error(msg.toString());
 
 221             throw new RuntimeException("Drools Rule has Errors");
 
 223         for (Message msg : results.getMessages()) {
 
 224             logger.debug(msg.toString());
 
 231      *  Set the A&AI properties.
 
 233     public static void setAaiProps() {
 
 234         PolicyEngine.manager.setEnvironmentProperty("aai.url", "http://localhost:6666");
 
 235         PolicyEngine.manager.setEnvironmentProperty("aai.username", "AAI");
 
 236         PolicyEngine.manager.setEnvironmentProperty("aai.password", "AAI");
 
 240      *  Set the Guard properties to use embedded XACML PDPEngine.
 
 242     public static void setGuardPropsEmbedded() {
 
 244          * Guard PDP-x connection Properties. No URL specified -> use embedded PDPEngine.
 
 246         PolicyEngine.manager.setEnvironmentProperty("prop.guard.propfile",
 
 247                                                     "src/test/resources/xacml/xacml_guard_clc.properties");
 
 248         PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_USER,        "python");
 
 249         PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_PASS,        "test");
 
 250         PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_CLIENT_USER, "python");
 
 251         PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_CLIENT_PASS, "test");
 
 252         PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_ENV,         "TEST");
 
 253         PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_DISABLED,    "false");
 
 257      *  Set the operation history properties.
 
 259     public static void setPuProp() {
 
 260         System.setProperty(OPSHISTPUPROP, "TestOperationsHistoryPU");
 
 264      * Dump the contents of the History database.
 
 266      * @return a list of the database entries
 
 268     public static List<?> dumpDb() {
 
 270         // Connect to in-mem db
 
 272         EntityManagerFactory emf = Persistence.createEntityManagerFactory("TestOperationsHistoryPU");
 
 273         EntityManager em = emf.createEntityManager();
 
 277         String sql = "select * from operationshistory10";
 
 278         Query nq = em.createNativeQuery(sql);
 
 279         List<?> results = null;
 
 284             results = nq.getResultList();
 
 285         } catch (Exception ex) {
 
 286             logger.error("getStatusFromDB threw: ", ex);
 
 288             // Clean up and return null
 
 295         // Clean up and return results
 
 303      * Rule specification.
 
 305     public static class RuleSpec {
 
 306         private String droolsTemplate;
 
 307         private String closedLoopControlName;
 
 308         private String policyScope;
 
 309         private String policyName;
 
 310         private String policyVersion;
 
 311         private String yamlSpecification;
 
 314          * Constructs the object.
 
 316          * @param droolsTemplate template
 
 317          * @param closedLoopControlName control loop id
 
 318          * @param policyScope policy scope
 
 319          * @param policyName policy name
 
 320          * @param policyVersion policy version
 
 321          * @param yamlSpecification incoming yaml specification
 
 323         public RuleSpec(String droolsTemplate, String closedLoopControlName, String policyScope, String policyName,
 
 324                         String policyVersion, String yamlSpecification) {
 
 326             this.droolsTemplate = droolsTemplate;
 
 327             this.closedLoopControlName = closedLoopControlName;
 
 328             this.policyScope = policyScope;
 
 329             this.policyName = policyName;
 
 330             this.policyVersion = policyVersion;
 
 331             this.yamlSpecification = yamlSpecification;
 
 335          * Generates the rules by reading the template and making variable substitutions.
 
 338          * @throws IOException if an error occurs
 
 340         private String generateRules() throws IOException {
 
 341             Path rule = Paths.get(droolsTemplate);
 
 342             String ruleTemplate = new String(Files.readAllBytes(rule));
 
 344             Pattern pattern = Pattern.compile("\\$\\{closedLoopControlName\\}");
 
 345             Matcher matcher = pattern.matcher(ruleTemplate);
 
 346             ruleTemplate = matcher.replaceAll(closedLoopControlName);
 
 348             pattern = Pattern.compile("\\$\\{policyScope\\}");
 
 349             matcher = pattern.matcher(ruleTemplate);
 
 350             ruleTemplate = matcher.replaceAll(policyScope);
 
 352             pattern = Pattern.compile("\\$\\{policyName\\}");
 
 353             matcher = pattern.matcher(ruleTemplate);
 
 354             ruleTemplate = matcher.replaceAll(policyName);
 
 356             pattern = Pattern.compile("\\$\\{policyVersion\\}");
 
 357             matcher = pattern.matcher(ruleTemplate);
 
 358             ruleTemplate = matcher.replaceAll(policyVersion);
 
 360             pattern = Pattern.compile("\\$\\{controlLoopYaml\\}");
 
 361             matcher = pattern.matcher(ruleTemplate);
 
 362             ruleTemplate = matcher.replaceAll(yamlSpecification);