2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 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;
 
  23 import static org.junit.Assert.*;
 
  25 import java.io.IOException;
 
  26 import java.net.URLEncoder;
 
  27 import java.time.Instant;
 
  28 import java.util.HashMap;
 
  29 import java.util.UUID;
 
  31 import org.junit.AfterClass;
 
  32 import org.junit.BeforeClass;
 
  33 import org.junit.Test;
 
  34 import org.kie.api.runtime.KieSession;
 
  35 import org.kie.api.runtime.rule.FactHandle;
 
  36 import org.onap.policy.appclcm.LCMRequest;
 
  37 import org.onap.policy.appclcm.LCMRequestWrapper;
 
  38 import org.onap.policy.appclcm.LCMResponse;
 
  39 import org.onap.policy.appclcm.LCMResponseWrapper;
 
  40 import org.onap.policy.controlloop.ControlLoopEventStatus;
 
  41 import org.onap.policy.controlloop.ControlLoopNotificationType;
 
  42 import org.onap.policy.controlloop.VirtualControlLoopEvent;
 
  43 import org.onap.policy.controlloop.VirtualControlLoopNotification;
 
  44 import org.onap.policy.controlloop.policy.ControlLoopPolicy;
 
  45 import org.onap.policy.drools.PolicyEngineListener;
 
  46 import org.onap.policy.drools.http.server.HttpServletServer;
 
  47 import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
 
  48 import org.slf4j.Logger;
 
  49 import org.slf4j.LoggerFactory;
 
  51 public class VCPEControlLoopTest implements PolicyEngineListener {
 
  53     private static final Logger logger = LoggerFactory.getLogger(VCPEControlLoopTest.class);
 
  55     private KieSession kieSession;
 
  56     private Util.Pair<ControlLoopPolicy, String> pair;
 
  57     private PolicyEngineJUnitImpl engine; 
 
  58     private UUID requestID;
 
  61         /* Set environment properties */
 
  68     public static void setUpSimulator() {
 
  72         } catch (Exception e) {
 
  78     public static void tearDownSimulator() {
 
  79         HttpServletServer.factory.destroy();
 
  83     public void successTest() {
 
  85          * Start the kie session
 
  88             kieSession = startSession("src/main/resources/ControlLoop_Template_xacml_guard.drl", 
 
  89                         "src/test/resources/yaml/policy_ControlLoop_vCPE.yaml",
 
  90                         "service=ServiceDemo;resource=Res1Demo;type=operational", 
 
  92                         "org.onap.closed_loop.ServiceDemo:VNFS:1.0.0");
 
  93         } catch (IOException e) {
 
  95             logger.debug("Could not create kieSession");
 
  96             fail("Could not create kieSession");
 
 100          * Allows the PolicyEngine to callback to this object to
 
 101          * notify that there is an event ready to be pulled 
 
 104         engine.addListener(this);
 
 107          * Create a unique requestId
 
 109         requestID = UUID.randomUUID();
 
 112          * Simulate an onset event the policy engine will 
 
 113          * receive from DCAE to kick off processing through
 
 116         sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET);
 
 118         kieSession.fireUntilHalt();
 
 121          * The only fact in memory should be Params
 
 123         assertEquals(1, kieSession.getFactCount());
 
 126          * Print what's left in memory
 
 128         dumpFacts(kieSession);
 
 131          * Gracefully shut down the kie session
 
 133         kieSession.dispose();
 
 137      * This method will start a kie session and instantiate 
 
 140      * @param droolsTemplate
 
 143      *          the yaml file containing the policies
 
 148      * @param policyVersion
 
 149      *          version of the policy          
 
 150      * @return the kieSession to be used to insert facts 
 
 151      * @throws IOException
 
 153     private KieSession startSession(String droolsTemplate, 
 
 157             String policyVersion) throws IOException {
 
 160          * Load policies from yaml
 
 162         pair = Util.loadYaml(yamlFile);
 
 164         assertNotNull(pair.a);
 
 165         assertNotNull(pair.a.getControlLoop());
 
 166         assertNotNull(pair.a.getControlLoop().getControlLoopName());
 
 167         assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
 
 170          * Construct a kie session
 
 172         final KieSession kieSession = Util.buildContainer(droolsTemplate, 
 
 173                 pair.a.getControlLoop().getControlLoopName(), 
 
 177                 URLEncoder.encode(pair.b, "UTF-8"));
 
 180          * Retrieve the Policy Engine
 
 182         engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
 
 184         logger.debug("============");
 
 185         logger.debug(URLEncoder.encode(pair.b, "UTF-8"));
 
 186         logger.debug("============");
 
 193      * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String)
 
 195     public void newEventNotification(String topic) {
 
 197          * Pull the object that was sent out to DMAAP and make
 
 198          * sure it is a ControlLoopNoticiation of type active
 
 200         Object obj = engine.subscribe("UEB", topic);
 
 202         if (obj instanceof VirtualControlLoopNotification) {
 
 203             VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj;
 
 204             String policyName = notification.policyName;
 
 205             if (policyName.endsWith("EVENT")) {
 
 206                 logger.debug("Rule Fired: " + notification.policyName);
 
 207                 assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.notification));
 
 209             else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) {
 
 210                 logger.debug("Rule Fired: " + notification.policyName);
 
 211                 assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification));
 
 212                 assertNotNull(notification.message);
 
 213                 assertTrue(notification.message.startsWith("Sending guard query"));
 
 215             else if (policyName.endsWith("GUARD.RESPONSE")) {
 
 216                 logger.debug("Rule Fired: " + notification.policyName);
 
 217                 assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification));
 
 218                 assertNotNull(notification.message);
 
 219                 assertTrue(notification.message.endsWith("PERMIT"));
 
 221             else if (policyName.endsWith("GUARD_PERMITTED")) {
 
 222                 logger.debug("Rule Fired: " + notification.policyName);
 
 223                 assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification));
 
 224                 assertNotNull(notification.message);
 
 225                 assertTrue(notification.message.startsWith("actor=APPC"));
 
 227             else if (policyName.endsWith("OPERATION.TIMEOUT")) {
 
 228                 logger.debug("Rule Fired: " + notification.policyName);
 
 230                 logger.debug("The operation timed out");
 
 231                 fail("Operation Timed Out");
 
 233             else if (policyName.endsWith("APPC.LCM.RESPONSE")) {
 
 234                 logger.debug("Rule Fired: " + notification.policyName);
 
 235                 assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.notification));
 
 236                 assertNotNull(notification.message);
 
 237                 assertTrue(notification.message.startsWith("actor=APPC"));
 
 238                 sendEvent(pair.a, requestID, ControlLoopEventStatus.ABATED);
 
 240             else if (policyName.endsWith("EVENT.MANAGER")) {
 
 241                 logger.debug("Rule Fired: " + notification.policyName);
 
 242                 assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification));
 
 245             else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) {
 
 246                 logger.debug("Rule Fired: " + notification.policyName);
 
 248                 logger.debug("The control loop timed out");
 
 249                 fail("Control Loop Timed Out");
 
 252         else if (obj instanceof LCMRequestWrapper) {
 
 254              * The request should be of type LCMRequestWrapper
 
 255              * and the subrequestid should be 1
 
 257             LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj;
 
 258             LCMRequest appcRequest = dmaapRequest.getBody();
 
 259             assertTrue(appcRequest.getCommonHeader().getSubRequestId().equals("1"));
 
 261             logger.debug("\n============ APPC received the request!!! ===========\n");
 
 264              * Simulate a success response from APPC and insert
 
 265              * the response into the working memory
 
 267             LCMResponseWrapper dmaapResponse = new LCMResponseWrapper();
 
 268             LCMResponse appcResponse = new LCMResponse(appcRequest);
 
 269             appcResponse.getStatus().setCode(400);
 
 270             appcResponse.getStatus().setMessage("AppC success");
 
 271             dmaapResponse.setBody(appcResponse);
 
 272             kieSession.insert(dmaapResponse);
 
 277      * This method is used to simulate event messages from DCAE
 
 278      * that start the control loop (onset message) or end the
 
 279      * control loop (abatement message).
 
 281      * @param policy the controlLoopName comes from the policy 
 
 282      * @param requestID the requestId for this event
 
 283      * @param status could be onset or abated
 
 285     protected void sendEvent(ControlLoopPolicy policy, UUID requestID, ControlLoopEventStatus status) {
 
 286         VirtualControlLoopEvent event = new VirtualControlLoopEvent();
 
 287         event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
 
 288         event.requestID = requestID;
 
 289         event.target = "generic-vnf.vnf-id";
 
 290         event.closedLoopAlarmStart = Instant.now();
 
 291         event.AAI = new HashMap<>();
 
 292         event.AAI.put("generic-vnf.vnf-id", "testGenericVnfID");
 
 293         event.closedLoopEventStatus = status;
 
 294         kieSession.insert(event);
 
 298      * This method will dump all the facts in the working memory.
 
 300      * @param kieSession the session containing the facts
 
 302     public void dumpFacts(KieSession kieSession) {
 
 303         logger.debug("Fact Count: {}", kieSession.getFactCount());
 
 304         for (FactHandle handle : kieSession.getFactHandles()) {
 
 305             logger.debug("FACT: {}", handle);