aboutsummaryrefslogtreecommitdiffstats
path: root/controlloop/templates/template.demo.clc/src/test/java
diff options
context:
space:
mode:
authorJoshua Reich <jreich@research.att.com>2018-09-14 11:38:01 -0700
committerJoshua Reich <jreich@research.att.com>2018-09-17 22:35:09 -0700
commitfaf283066f186838665ed5c38c1ba8319041bc1c (patch)
treebaecbf025374a4e120de5b9ddf405b26cb6e5d75 /controlloop/templates/template.demo.clc/src/test/java
parente3357d24078195756c8e16fc0da8aa8d1e507290 (diff)
Add demo for Control Loop Coordination.
New PipEngine and Junit test added to guard. Also bug in existing Junit test fixed. All other code added to new directory template.demo.clc Change-Id: Ida2267528bcb9404dc59ff391d45797b591814cc Issue-ID: POLICY-1109 Signed-off-by: Joshua Reich <jreich@research.att.com>
Diffstat (limited to 'controlloop/templates/template.demo.clc/src/test/java')
-rw-r--r--controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/ControlLoopCoordinationTest.java497
-rw-r--r--controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/Util.java297
2 files changed, 794 insertions, 0 deletions
diff --git a/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/ControlLoopCoordinationTest.java b/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/ControlLoopCoordinationTest.java
new file mode 100644
index 000000000..2d6279f32
--- /dev/null
+++ b/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/ControlLoopCoordinationTest.java
@@ -0,0 +1,497 @@
+/*-
+ * ============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 com.att.research.xacml.util.XACMLProperties;
+
+import com.google.gson.Gson;
+
+import java.io.IOException;
+import java.lang.StringBuilder;
+import java.net.URLEncoder;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.kie.api.runtime.KieSession;
+import org.kie.api.runtime.rule.FactHandle;
+
+import org.onap.policy.appclcm.LcmRequest;
+import org.onap.policy.appclcm.LcmRequestWrapper;
+import org.onap.policy.appclcm.LcmResponse;
+import org.onap.policy.appclcm.LcmResponseWrapper;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
+import org.onap.policy.common.endpoints.event.comm.TopicListener;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.common.endpoints.http.server.HttpServletServer;
+import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
+import org.onap.policy.controlloop.ControlLoopEventStatus;
+import org.onap.policy.controlloop.ControlLoopNotificationType;
+import org.onap.policy.controlloop.ControlLoopTargetType;
+import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.VirtualControlLoopNotification;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
+import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
+import org.onap.policy.drools.system.PolicyController;
+import org.onap.policy.drools.system.PolicyEngine;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ControlLoopCoordinationTest implements TopicListener {
+
+ private static final Logger logger = LoggerFactory.getLogger(ControlLoopCoordinationTest.class);
+
+ private static List<? extends TopicSink> noopTopics;
+
+ private static KieSession kieSession1;
+ private static KieSession kieSession2;
+ private static StringBuilder controlLoopOneName = new StringBuilder();
+ private static StringBuilder controlLoopTwoName = new StringBuilder();
+ private static String expectedDecision;
+
+ static {
+ /* Set environment properties */
+ Util.setAaiProps();
+ Util.setGuardPropsEmbedded();
+ Util.setPuProp();
+ }
+
+ /**
+ * Setup simulator.
+ */
+ @BeforeClass
+ public static void setUpSimulator() {
+ PolicyEngine.manager.configure(new Properties());
+ assertTrue(PolicyEngine.manager.start());
+ Properties noopSinkProperties = new Properties();
+ noopSinkProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, "APPC-LCM-READ,POLICY-CL-MGT");
+ noopSinkProperties.put("noop.sink.topics.APPC-LCM-READ.events", "org.onap.policy.appclcm.LcmRequestWrapper");
+ noopSinkProperties.put("noop.sink.topics.APPC-LCM-READ.events.custom.gson",
+ "org.onap.policy.appclcm.util.Serialization,gson");
+ noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events",
+ "org.onap.policy.controlloop.VirtualControlLoopNotification");
+ noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events.custom.gson",
+ "org.onap.policy.controlloop.util.Serialization,gsonPretty");
+ noopTopics = TopicEndpoint.manager.addTopicSinks(noopSinkProperties);
+
+ EventProtocolCoder.manager.addEncoder("junit.groupId", "junit.artifactId", "POLICY-CL-MGT",
+ "org.onap.policy.controlloop.VirtualControlLoopNotification", new JsonProtocolFilter(), null, null,
+ 1111);
+ EventProtocolCoder.manager.addEncoder("junit.groupId", "junit.artifactId", "APPC-LCM-READ",
+ "org.onap.policy.appclcm.LcmRequestWrapper", new JsonProtocolFilter(), null, null, 1111);
+ try {
+ Util.buildAaiSim();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+
+ /*
+ * Start the kie sessions
+ */
+ try {
+ kieSession1 = startSession(
+ controlLoopOneName,
+ "src/main/resources/__closedLoopControlName__.drl",
+ "src/test/resources/yaml/policy_ControlLoop_SyntheticOne.yaml",
+ "service=ServiceDemo;resource=Res1Demo;type=operational",
+ "SyntheticControlLoopOnePolicy",
+ "org.onap.closed_loop.ServiceDemo:VNFS:1.0.0");
+ kieSession2 = startSession(
+ controlLoopTwoName,
+ "src/main/resources/__closedLoopControlName__.drl",
+ "src/test/resources/yaml/policy_ControlLoop_SyntheticTwo.yaml",
+ "service=ServiceDemo;resource=Res1Demo;type=operational",
+ "SyntheticControlLoopTwoPolicy",
+ "org.onap.closed_loop.ServiceDemo:VNFS:1.0.0");
+ } catch (IOException e) {
+ logger.debug("Could not create kieSession, exception {}", e.getMessage());
+ fail("Could not create kieSession");
+ }
+ }
+
+ /**
+ * Tear down simulator.
+ */
+ @AfterClass
+ public static void tearDownSimulator() {
+ /*
+ * Gracefully shut down the kie session
+ */
+ kieSession1.dispose();
+ kieSession2.dispose();
+
+ PolicyEngine.manager.stop();
+ HttpServletServer.factory.destroy();
+ PolicyController.factory.shutdown();
+ TopicEndpoint.manager.shutdown();
+ }
+
+ /**
+ * Set expected decision.
+ *
+ * @param ed the expected decision ("PERMIT" or "DENY")
+ */
+ public void expectedDecisionIs(String ed) {
+ expectedDecision = ed;
+ logger.info("Expected decision is {}", ed);
+ }
+
+ /**
+ * This method is used to simulate event messages from DCAE
+ * that start the control loop (onset message) or end the
+ * control loop (abatement message).
+ *
+ * @param controlLoopName the control loop name
+ * @param requestID the requestId for this event
+ * @param status could be onset or abated
+ * @param target the target name
+ * @param kieSession the kieSession to which this event is being sent
+ */
+ protected void sendEvent(String controlLoopName,
+ UUID requestId,
+ ControlLoopEventStatus status,
+ String target,
+ KieSession kieSession) {
+ logger.debug("sendEvent controlLoopName={}", controlLoopName);
+ VirtualControlLoopEvent event = new VirtualControlLoopEvent();
+ event.setClosedLoopControlName(controlLoopName);
+ event.setRequestId(requestId);
+ event.setTarget("generic-vnf.vnf-name");
+ event.setTargetType(ControlLoopTargetType.VNF);
+ event.setClosedLoopAlarmStart(Instant.now());
+ event.setAai(new HashMap<>());
+ event.getAai().put("generic-vnf.vnf-name", target);
+ event.setClosedLoopEventStatus(status);
+
+ Gson gson = new Gson();
+ String json = gson.toJson(event);
+ logger.debug("sendEvent {}", json);
+
+ kieSession.insert(event);
+ }
+
+
+ /**
+ * Simulate an event by inserting into kieSession and firing rules as needed.
+ *
+ * @param cles the ControlLoopEventStatus
+ * @param rid the request ID
+ * @param controlLoopName the control loop name
+ * @param kieSession the kieSession to which this event is being sent
+ * @param expectedDecision the expected decision
+ */
+ protected void simulateEvent(ControlLoopEventStatus cles,
+ UUID rid,
+ String controlLoopName,
+ String target,
+ KieSession kieSession,
+ String expectedDecision) {
+ int waitMillis = 5000;
+ //
+ // if onset, set expected decision
+ //
+ if (cles == ControlLoopEventStatus.ONSET) {
+ expectedDecisionIs(expectedDecision);
+ }
+ //
+ // simulate sending event
+ //
+ sendEvent(controlLoopName, rid, cles, target, kieSession);
+ kieSession.fireUntilHalt();
+ //
+ // get dump of database entries and log
+ //
+ List entries = Util.dumpDb();
+ assertNotNull(entries);
+ logger.debug("dumpDB, {} entries", entries.size());
+ for (Object entry : entries) {
+ logger.debug("{}", entry);
+ }
+ //
+ // we are done
+ //
+ logger.info("simulateEvent: done");
+ }
+
+ /**
+ * Simulate an onset event.
+ *
+ * @param rid the request ID
+ * @param controlLoopName the control loop name
+ * @param kieSession the kieSession to which this event is being sent
+ * @param expectedDecision the expected decision
+ */
+ public void simulateOnset(UUID rid,
+ String controlLoopName,
+ String target,
+ KieSession kieSession,
+ String expectedDecision) {
+ simulateEvent(ControlLoopEventStatus.ONSET, rid, controlLoopName, target, kieSession, expectedDecision);
+ }
+
+ /**
+ * Simulate an abated event.
+ *
+ * @param rid the request ID
+ * @param controlLoopName the control loop name
+ * @param kieSession the kieSession to which this event is being sent
+ */
+ public void simulateAbatement(UUID rid,
+ String controlLoopName,
+ String target,
+ KieSession kieSession) {
+ simulateEvent(ControlLoopEventStatus.ABATED, rid, controlLoopName, target, kieSession, null);
+ }
+
+ /**
+ * This method will start a kie session and instantiate the Policy Engine.
+ *
+ * @param droolsTemplate the DRL rules file
+ * @param yamlFile the yaml file containing the policies
+ * @param policyScope scope for policy
+ * @param policyName name of the policy
+ * @param policyVersion version of the policy
+ * @return the kieSession to be used to insert facts
+ * @throws IOException throws IO exception
+ */
+ private static KieSession startSession(StringBuilder controlLoopName,
+ String droolsTemplate,
+ String yamlFile,
+ String policyScope,
+ String policyName,
+ String policyVersion) throws IOException {
+
+ /*
+ * Load policies from yaml
+ */
+ Util.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().isEmpty());
+
+ controlLoopName.append(pair.first.getControlLoop().getControlLoopName());
+ String yamlContents = pair.second;
+
+ /*
+ * Construct a kie session
+ */
+ final KieSession kieSession = Util.buildContainer(droolsTemplate,
+ controlLoopName.toString(),
+ policyScope,
+ policyName,
+ policyVersion,
+ URLEncoder.encode(yamlContents, "UTF-8"));
+
+ /*
+ * Retrieve the Policy Engine
+ */
+
+ logger.debug("============");
+ logger.debug(URLEncoder.encode(yamlContents, "UTF-8"));
+ logger.debug("============");
+
+ return kieSession;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String)
+ */
+ @Override
+ public void onTopicEvent(CommInfrastructure commType, String topic, String event) {
+ /*
+ * Pull the object that was sent out to DMAAP and make sure it is a ControlLoopNoticiation
+ * of type active
+ */
+ Object obj = null;
+ if ("POLICY-CL-MGT".equals(topic)) {
+ obj = org.onap.policy.controlloop.util.Serialization.gsonJunit.fromJson(event,
+ org.onap.policy.controlloop.VirtualControlLoopNotification.class);
+ } else if ("APPC-LCM-READ".equals(topic)) {
+ obj = org.onap.policy.appclcm.util.Serialization.gsonJunit.fromJson(event,
+ org.onap.policy.appclcm.LcmRequestWrapper.class);
+ }
+ assertNotNull(obj);
+ if (obj instanceof VirtualControlLoopNotification) {
+ VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj;
+ String policyName = notification.getPolicyName();
+ if (policyName.endsWith("EVENT")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.getNotification()));
+ } else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.getNotification()));
+ assertNotNull(notification.getMessage());
+ assertTrue(notification.getMessage().startsWith("Sending guard query"));
+ } else if (policyName.endsWith("GUARD.RESPONSE")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.getNotification()));
+ assertNotNull(notification.getMessage());
+ // THESE ARE THE MOST CRITICAL ASSERTS
+ // TEST IF GUARD.RESPONSE IS CORRECT
+ logger.debug("Testing whether decision was {} as expected", expectedDecision);
+ assertTrue(notification.getMessage().toUpperCase().endsWith(expectedDecision));
+ } else if (policyName.endsWith("GUARD_PERMITTED")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ assertEquals(ControlLoopNotificationType.OPERATION,notification.getNotification());
+ assertNotNull(notification.getMessage());
+ assertTrue(notification.getMessage().startsWith("actor=APPC"));
+ } else if (policyName.endsWith("OPERATION.TIMEOUT")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ kieSession1.halt();
+ kieSession2.halt();
+ logger.debug("The operation timed out");
+ fail("Operation Timed Out");
+ } else if (policyName.endsWith("APPC.LCM.RESPONSE")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.getNotification()));
+ assertNotNull(notification.getMessage());
+ assertTrue(notification.getMessage().startsWith("actor=APPC"));
+ } else if (policyName.endsWith("EVENT.MANAGER")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ if (notification.getMessage().endsWith("Closing the control loop.")
+ || notification.getMessage().equals("Waiting for abatement")) {
+ if (policyName.startsWith(controlLoopOneName.toString())) {
+ logger.debug("Halting kieSession1");
+ kieSession1.halt();
+ } else if (policyName.startsWith(controlLoopTwoName.toString())) {
+ logger.debug("Halting kieSession2");
+ kieSession2.halt();
+ } else {
+ fail("Unknown ControlLoop");
+ }
+ }
+ } else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) {
+ logger.debug("Rule Fired: " + notification.getPolicyName());
+ kieSession1.halt();
+ kieSession2.halt();
+ logger.debug("The control loop timed out");
+ fail("Control Loop Timed Out");
+ }
+ } else if (obj instanceof LcmRequestWrapper) {
+ /*
+ * The request should be of type LCMRequestWrapper and the subrequestid should be 1
+ */
+ LcmRequestWrapper dmaapRequest = (LcmRequestWrapper) obj;
+ LcmRequest appcRequest = dmaapRequest.getBody();
+ assertEquals(appcRequest.getCommonHeader().getSubRequestId(),"1");
+
+ logger.debug("\n============ APPC received the request!!! ===========\n");
+
+ /*
+ * Simulate a success response from APPC and insert the response into the working memory
+ */
+ LcmResponseWrapper dmaapResponse = new LcmResponseWrapper();
+ LcmResponse appcResponse = new LcmResponse(appcRequest);
+ appcResponse.getStatus().setCode(400);
+ appcResponse.getStatus().setMessage("AppC success");
+ dmaapResponse.setBody(appcResponse);
+ kieSession1.insert(dmaapResponse);
+ kieSession2.insert(dmaapResponse);
+ }
+ }
+
+ /**
+ * This method will dump all the facts in the working memory.
+ *
+ * @param kieSession the session containing the facts
+ */
+ public void dumpFacts(KieSession kieSession) {
+ logger.debug("Fact Count: {}", kieSession.getFactCount());
+ for (FactHandle handle : kieSession.getFactHandles()) {
+ logger.debug("FACT: {}", handle);
+ }
+ }
+
+ /**
+ * Test that SyntheticControlLoopOne blocks SyntheticControlLoopTwo
+ * is enforced correctly.
+ */
+ @Test
+ public void testSyntheticControlLoopOneBlocksSyntheticControlLoopTwo() throws InterruptedException {
+ logger.info("Beginning testSyntheticControlLoopOneBlocksSyntheticControlLoopTwo");
+ /*
+ * Allows the PolicyEngine to callback to this object to
+ * notify that there is an event ready to be pulled
+ * from the queue
+ */
+ for (TopicSink sink : noopTopics) {
+ assertTrue(sink.start());
+ sink.register(this);
+ }
+
+ /*
+ * Create unique requestIds
+ */
+ final UUID requestId1 = UUID.randomUUID();
+ final UUID requestId2 = UUID.randomUUID();
+ final UUID requestId3 = UUID.randomUUID();
+ final UUID requestId4 = UUID.randomUUID();
+ final UUID requestId5 = UUID.randomUUID();
+ final String cl1 = controlLoopOneName.toString();
+ final String cl2 = controlLoopTwoName.toString();
+ final String t1 = "TARGET_1";
+ final String t2 = "TARGET_2";
+
+ logger.info("@@@@@@@@@@ cl2 ONSET t1 (Success) @@@@@@@@@@");
+ simulateOnset(requestId1, cl2, t1, kieSession2,"PERMIT");
+ logger.info("@@@@@@@@@@ cl1 ONSET t1 @@@@@@@@@@");
+ simulateOnset(requestId2, cl1, t1, kieSession1,"PERMIT");
+ logger.info("@@@@@@@@@@ cl2 ABATED t1 @@@@@@@@@@");
+ simulateAbatement(requestId1, cl2, t1, kieSession2);
+ logger.info("@@@@@@@@@@ cl2 ONSET t1 (Fail) @@@@@@@@@@");
+ simulateOnset(requestId3, cl2, t1, kieSession2,"DENY");
+ logger.info("@@@@@@@@@@ cl2 ONSET t2 (Success) @@@@@@@@@@");
+ simulateOnset(requestId4, cl2, t2, kieSession2,"PERMIT");
+ logger.info("@@@@@@@@@@ cl2 ABATED t2 @@@@@@@@@@");
+ simulateAbatement(requestId4, cl2, t2, kieSession2);
+ logger.info("@@@@@@@@@@ cl1 ABATED t1 @@@@@@@@@@");
+ simulateAbatement(requestId2, cl1, t1, kieSession1);
+ logger.info("@@@@@@@@@@ cl2 ONSET t1 (Success) @@@@@@@@@@");
+ simulateOnset(requestId5, cl2, t1, kieSession2,"PERMIT");
+ logger.info("@@@@@@@@@@ cl2 ABATED t1 @@@@@@@@@@");
+ simulateAbatement(requestId5, cl2, t1, kieSession2);
+
+ /*
+ * Print what's left in memory
+ */
+ dumpFacts(kieSession1);
+ dumpFacts(kieSession2);
+ }
+}
+
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
new file mode 100644
index 000000000..5b5aa2d9c
--- /dev/null
+++ b/controlloop/templates/template.demo.clc/src/test/java/org/onap/policy/template/demo/clc/Util.java
@@ -0,0 +1,297 @@
+/*-
+ * ============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.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+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;
+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;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.controlloop.policy.guard.ControlLoopGuard;
+import org.onap.policy.drools.system.PolicyEngine;
+import org.onap.policy.guard.PolicyGuardYamlToXacml;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+
+public final class Util {
+
+ private static final String OPSHISTPUPROP = "OperationsHistoryPU";
+ private static final Logger logger = LoggerFactory.getLogger(Util.class);
+
+ public static class Pair<A, B> {
+ public final A first;
+ public final B second;
+
+ public Pair(A first, B second) {
+ this.first = first;
+ this.second = second;
+ }
+ }
+
+ /**
+ * Load YAML.
+ *
+ * @param testFile test file to load
+ * @return the Pair of a policy and the yaml contents
+ */
+ public static Pair<ControlLoopPolicy, String> loadYaml(String testFile) {
+ try (InputStream is = new FileInputStream(new File(testFile))) {
+ String contents = IOUtils.toString(is, StandardCharsets.UTF_8);
+ //
+ // Read the yaml into our Java Object
+ //
+ Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
+ Object obj = yaml.load(contents);
+
+ logger.debug(contents);
+
+ return new Pair<ControlLoopPolicy, String>((ControlLoopPolicy) obj, contents);
+ } catch (IOException e) {
+ fail(e.getLocalizedMessage());
+ }
+ return null;
+ }
+
+ /**
+ * Load the YAML guard policy.
+ *
+ * @param testFile the test file to load
+ * @return return the guard object
+ */
+ public static ControlLoopGuard loadYamlGuard(String testFile) {
+ try (InputStream is = new FileInputStream(new File(testFile))) {
+ String contents = IOUtils.toString(is, StandardCharsets.UTF_8);
+ //
+ // Read the yaml into our Java Object
+ //
+ Yaml yaml = new Yaml(new Constructor(ControlLoopGuard.class));
+ Object obj = yaml.load(contents);
+ return (ControlLoopGuard) obj;
+ } catch (IOException e) {
+ fail(e.getLocalizedMessage());
+ }
+ return null;
+ }
+
+ public static HttpServletServer buildAaiSim() throws InterruptedException, IOException {
+ 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.
+ *
+ * @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
+ * @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 {
+ //
+ // Get our Drools Kie factory
+ //
+ KieServices ks = KieServices.Factory.get();
+
+ KieModuleModel kieModule = ks.newKieModuleModel();
+
+ logger.debug("KMODULE:" + System.lineSeparator() + kieModule.toXML());
+
+ //
+ // Generate our drools rule from our template
+ //
+ KieFileSystem kfs = ks.newKieFileSystem();
+
+ 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()));
+ }
+ //
+ // Compile the rule
+ //
+ KieBuilder builder = ks.newKieBuilder(kfs).buildAll();
+ Results results = builder.getResults();
+ if (results.hasMessages(Message.Level.ERROR)) {
+ for (Message msg : results.getMessages()) {
+ logger.error(msg.toString());
+ }
+ throw new RuntimeException("Drools Rule has Errors");
+ }
+ 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();
+ }
+
+ /**
+ * Set the A&AI properties.
+ */
+ public static void setAaiProps() {
+ PolicyEngine.manager.setEnvironmentProperty("aai.url", "http://localhost:6666");
+ PolicyEngine.manager.setEnvironmentProperty("aai.username", "AAI");
+ PolicyEngine.manager.setEnvironmentProperty("aai.password", "AAI");
+ }
+
+ /**
+ * Set the Guard properties to use embedded XACML PDPEngine.
+ */
+ public static void setGuardPropsEmbedded() {
+ /*
+ * Guard PDP-x connection Properties. No URL specified -> use embedded PDPEngine.
+ */
+ PolicyEngine.manager.setEnvironmentProperty("prop.guard.propfile",
+ "src/test/resources/xacml/xacml_guard_clc.properties");
+ PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_USER, "python");
+ PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_PASS, "test");
+ PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_CLIENT_USER, "python");
+ PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_CLIENT_PASS, "test");
+ PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_ENV, "TEST");
+ PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_DISABLED, "false");
+ }
+
+ /**
+ * Set the operation history properties.
+ */
+ public static void setPuProp() {
+ System.setProperty(OPSHISTPUPROP, "TestOperationsHistoryPU");
+ }
+
+ /**
+ * Dump the contents of the History database.
+ *
+ * @return a list of the database entries
+ */
+ public static List dumpDb() {
+ //
+ // Connect to in-mem db
+ //
+ EntityManagerFactory emf = Persistence.createEntityManagerFactory("TestOperationsHistoryPU");
+ EntityManager em = emf.createEntityManager();
+ //
+ // Create query
+ //
+ String sql = "select * from operationshistory10";
+ Query nq = em.createNativeQuery(sql);
+ List results = null;
+ //
+ // Execute query
+ //
+ try {
+ results = nq.getResultList();
+ } catch (Exception ex) {
+ logger.error("getStatusFromDB threw: ", ex);
+ //
+ // Clean up and return null
+ //
+ em.close();
+ emf.close();
+ return null;
+ }
+ //
+ // Clean up and return results
+ //
+ em.close();
+ emf.close();
+ return results;
+ }
+}