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 Util {
61 private static final String OPSHISTPUPROP = "OperationsHistoryPU";
62 private static final Logger logger = LoggerFactory.getLogger(Util.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);