Add VFC Response in Working Memory & JUNIT 55/11855/10
authorRitu Sood <ritu.sood@intel.com>
Mon, 11 Sep 2017 21:20:13 +0000 (14:20 -0700)
committerRitu Sood <ritu.sood@intel.com>
Thu, 21 Sep 2017 10:35:01 +0000 (03:35 -0700)
Adding code to insert VFC reponse in working
memory and handling that response. Also adding
JUNIT and yaml file for VoLTE usecase.

Issue-Id: POLICY-212
Change-Id: I74a13272ccd931478d27d80715d8c3ac756fb5c7
Signed-off-by: Ritu Sood <ritu.sood@intel.com>
controlloop/common/actors/actor.vfc/src/main/java/org/onap/policy/controlloop/actor/vfc/VFCActorServiceProvider.java
controlloop/common/eventmanager/pom.xml
controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java
controlloop/common/model-impl/vfc/pom.xml
controlloop/common/model-impl/vfc/src/main/java/org/onap/policy/vfc/VFCManager.java
controlloop/common/model-impl/vfc/src/main/java/org/onap/policy/vfc/VFCRequest.java
controlloop/common/model-impl/vfc/src/main/java/org/onap/policy/vfc/VFCResponse.java
controlloop/common/model-impl/vfc/src/main/java/org/onap/policy/vfc/VFCResponseDescriptor.java
controlloop/templates/template.demo/src/main/resources/ControlLoop_Template_xacml_guard.drl
controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFCControlLoopTest.java [new file with mode: 0644]
controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_VFC.yaml [new file with mode: 0644]

index 49b93e8..1ea65fa 100644 (file)
 package org.onap.policy.controlloop.actor.vfc;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-
+import java.util.UUID;
 import org.onap.policy.controlloop.VirtualControlLoopEvent;
 import org.onap.policy.vfc.VFCRequest;
 import org.onap.policy.vfc.VFCHealRequest;
@@ -30,15 +28,12 @@ import org.onap.policy.vfc.VFCHealAdditionalParams;
 import org.onap.policy.vfc.VFCHealActionVmInfo;
 import org.onap.policy.controlloop.ControlLoopOperation;
 import org.onap.policy.controlloop.policy.Policy;
-
 import org.onap.policy.controlloop.actorServiceProvider.spi.Actor;
+
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import org.onap.policy.aai.AAIManager;
 import org.onap.policy.aai.AAIGETVnfResponse;
-
-import java.util.UUID;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,7 +71,7 @@ public class VFCActorServiceProvider implements Actor {
         VFCRequest request = new VFCRequest();
         // TODO: Verify service-instance-id is part of onset event
         request.nsInstanceId = getAAIServiceInstance(onset); // onset.AAI.get("service-instance.service-instance-id");
-
+       request.requestId = onset.requestID;
         request.healRequest = new VFCHealRequest();
         request.healRequest.vnfInstanceId = onset.AAI.get("generic-vnf.vnf-id");
         request.healRequest.cause = operation.message;
@@ -110,14 +105,13 @@ public class VFCActorServiceProvider implements Actor {
         String password = "testPass";
         if (serviceInstance == null) {
             try {
-                AAIManager manager = new AAIManager();
                 if (vnfName != null) {
                     String url = urlBase + "/aai/v11/network/generic-vnfs/generic-vnf?vnf-name=";
-                    response = manager.getQueryByVnfName(url, username, password, requestID, vnfName);
+                    response = AAIManager.getQueryByVnfName(url, username, password, requestID, vnfName);
                     serviceInstance = response.serviceId;
                 } else if (vnfID != null) {
                     String url = urlBase + "/aai/v11/network/generic-vnfs/generic-vnf/";
-                    response = manager.getQueryByVnfID(url, username, password, requestID, vnfID);
+                    response = AAIManager.getQueryByVnfID(url, username, password, requestID, vnfID);
                     serviceInstance = response.serviceId;
                 } else {
                     logger.error("getAAIServiceInstance failed");
index 93ff56c..40dab74 100644 (file)
                        <version>1.1.0-SNAPSHOT</version>
                        <scope>provided</scope>
                </dependency>
+                <dependency>
+                        <groupId>org.onap.policy.drools-applications</groupId>
+                        <artifactId>vfc</artifactId>
+                        <version>1.1.0-SNAPSHOT</version>
+                        <scope>provided</scope>
+                </dependency>
+
            <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
index 8849a23..ec99c1a 100644 (file)
@@ -45,6 +45,7 @@ import org.onap.policy.controlloop.policy.Policy;
 import org.onap.policy.controlloop.policy.PolicyResult;
 import org.onap.policy.controlloop.actor.so.SOActorServiceProvider;
 import org.onap.policy.so.SOResponse;
+import org.onap.policy.vfc.VFCResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -367,8 +368,28 @@ public class ControlLoopOperationManager implements Serializable {
                                return PolicyResult.FAILURE;
                        }
 
+               } else if (response instanceof VFCResponse) {
+                       VFCResponse vfcResponse = (VFCResponse) response;
+                       if (vfcResponse.responseDescriptor.getStatus().equalsIgnoreCase("finished")) {
+                               //
+                               // Consider it as success
+                               //
+                               this.completeOperation(new Integer(1), " Success", PolicyResult.SUCCESS);
+                               if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+                                       return null;
+                               }
+                               return PolicyResult.SUCCESS;
+                       } else {
+                               //
+                               // Consider it as failure
+                               //
+                               this.completeOperation(new Integer(1), " Failed", PolicyResult.FAILURE);
+                               if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+                                       return null;
+                               }
+                               return PolicyResult.FAILURE;
+                       }
                }
-
                return null;
        }
 
index db86345..7672b1b 100644 (file)
                <artifactId>rest</artifactId>
                <version>${project.version}</version>
        </dependency>
+       <dependency>
+                       <groupId>org.drools</groupId>
+                       <artifactId>drools-core</artifactId>
+                       <version>6.5.0.Final</version>
+                       <scope>provided</scope>
+       </dependency>
   </dependencies>
 </project>
index 4797ab9..5cb6d66 100644 (file)
@@ -21,6 +21,7 @@ package org.onap.policy.vfc;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.drools.core.WorkingMemory;
 import org.onap.policy.vfc.util.Serialization;
 import org.onap.policy.rest.RESTManager;
 import org.onap.policy.rest.RESTManager.Pair;
@@ -35,9 +36,11 @@ public final class VFCManager implements Runnable {
     private String username;
     private String password;
     private VFCRequest vfcRequest;
+    WorkingMemory workingMem;
     private static final Logger logger = LoggerFactory.getLogger(VFCManager.class);
                
-    public VFCManager(VFCRequest request) {
+    public VFCManager(WorkingMemory wm, VFCRequest request) {
+        workingMem = wm;
         vfcRequest = request;
         // TODO: Get base URL, username and password from MSB?
         // TODO: Following code is a placeholder, needs to be updated
@@ -83,6 +86,7 @@ public final class VFCManager implements Runnable {
 
                     Pair<Integer, String> httpDetailsGet = RESTManager.get(urlGet, username, password, headers);
                     responseGet = Serialization.gsonPretty.fromJson(httpDetailsGet.b, VFCResponse.class);
+                   responseGet.requestId = vfcRequest.requestId.toString();
                     body = Serialization.gsonPretty.toJson(responseGet);
                     logger.debug("Response to VFC Heal get:");
                     logger.debug(body);
@@ -91,6 +95,7 @@ public final class VFCManager implements Runnable {
                         if (responseGet.responseDescriptor.status.equalsIgnoreCase("finished") ||
                                 responseGet.responseDescriptor.status.equalsIgnoreCase("error")) {
                             logger.debug("VFC Heal Status {}", responseGet.responseDescriptor.status);
+                            workingMem.insert(responseGet);
                             break;
                         }
                     }
@@ -102,6 +107,7 @@ public final class VFCManager implements Runnable {
                   && (responseGet.responseDescriptor.status != null) 
                   && (!responseGet.responseDescriptor.status.isEmpty())) {     
                         logger.debug("VFC timeout. Status: ({})", responseGet.responseDescriptor.status);
+                        workingMem.insert(responseGet);
                 }       
             } catch (JsonSyntaxException e) {
                 logger.error("Failed to deserialize into VFCResponse {}",e.getLocalizedMessage(),e);
index 9e3a77a..89c9b08 100644 (file)
 package org.onap.policy.vfc;
 
 import java.io.Serializable;
+import java.util.UUID;
 
 import com.google.gson.annotations.SerializedName;
 
 public class VFCRequest implements Serializable {
 
     private static final long serialVersionUID = 3736300970326332512L;
-    // This field is not serialized and not part of JSON
+    // These fields are not serialized and not part of JSON
     public transient String nsInstanceId;
+    public transient UUID requestId;
 
     @SerializedName("healVnfData")
     public VFCHealRequest healRequest;
index 775d78f..5d6efa0 100644 (file)
@@ -30,7 +30,9 @@ public class VFCResponse implements Serializable {
     public String jobId;
 
     @SerializedName("responseDescriptor")
-    VFCResponseDescriptor responseDescriptor;
+    public VFCResponseDescriptor responseDescriptor;
+
+    public transient String requestId;
 
     public VFCResponse() {
     }
index 9bf77c5..62c61a7 100644 (file)
@@ -27,7 +27,7 @@ public class VFCResponseDescriptor implements Serializable {
     private static final long serialVersionUID = 6827782899144150158L;
 
     @SerializedName("progress")
-    public String progress;
+    String progress;
 
     @SerializedName("status")
     String status;
@@ -47,4 +47,8 @@ public class VFCResponseDescriptor implements Serializable {
     public VFCResponseDescriptor() {
     }
 
+    public String getStatus() {
+       return status;
+    }
+
 }
index ff184b3..b506d89 100644 (file)
@@ -38,6 +38,7 @@ import org.onap.policy.appclcm.LCMRequest;
 import org.onap.policy.appclcm.LCMResponse;
 import org.onap.policy.appclcm.LCMCommonHeader;
 import org.onap.policy.vfc.VFCRequest;
+import org.onap.policy.vfc.VFCResponse;
 import org.onap.policy.vfc.VFCManager;
 import org.onap.policy.so.SOManager;
 import org.onap.policy.so.SORequest;
@@ -521,12 +522,12 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
                                        }
                                        break;
                                case "VFC":
-                                       if (request instanceof VFCRequest) {
-                                               // Start VFC thread
-                                               Thread t = new Thread(new VFCManager((VFCRequest)request));
-                                               t.start();
-                                       }                       
-                                       break;
+                                       if (request instanceof VFCRequest) {
+                                       // Start VFC thread
+                                       Thread t = new Thread(new VFCManager(drools.getWorkingMemory(), (VFCRequest)request));
+                                       t.start();
+                               }
+                               break;
                        }
                } else {
                        //
@@ -1002,6 +1003,85 @@ rule "${policyName}.SO.RESPONSE"
 
 end
 
+/*
+*
+* This rule responds to VFC Response Events
+*
+*/
+rule "${policyName}.VFC.RESPONSE"
+       when
+               $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+               $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+               $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+               $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
+               $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+        $lock : TargetLock (requestID == $event.requestID)
+               $response : VFCResponse( requestId.toString() == $event.requestID.toString() )  
+       then
+               //
+               // Logging
+               Logger.info("------------------------------------------------------------------------------------------------");
+               Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+               Logger.metrics($params);
+               Logger.metrics($event);
+               Logger.metrics($manager);
+               Logger.metrics($operation);
+               Logger.metrics($opTimer);
+               Logger.metrics($lock);
+               Logger.metrics($response);
+               // Get the result of the operation
+               //
+               PolicyResult policyResult = $operation.onResponse($response);
+               if (policyResult != null) {
+                       //
+                       // This Operation has completed, construct a notification showing our results
+                       //
+                       VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+                       notification.from = "policy";
+                       notification.policyName = drools.getRule().getName();
+                       notification.policyScope = "${policyScope}";
+                       notification.policyVersion = "${policyVersion}";
+                       notification.message = $operation.getOperationHistory();
+                       notification.history = $operation.getHistory();
+                       //
+                       // Ensure the operation is complete
+                       //
+                       if ($operation.isOperationComplete() == true) {
+                               //
+                               // It is complete, remove it from memory
+                               //
+                               retract($operation);
+                               //
+                               // We must also retract the timer object
+                               // NOTE: We could write a Rule to do this
+                               //
+                               retract($opTimer);
+                               //
+                               // Complete the operation
+                               //
+                               modify($manager) {finishOperation($operation)};
+                       } else {
+                               //
+                               // Just doing this will kick off the LOCKED rule again
+                               //
+                               modify($operation) {};
+                       }
+               } else {
+                       //
+                       // Its not finished yet (i.e. expecting more Response objects)
+                       //
+                       // Or possibly it is a leftover response that we timed the request out previously
+                       //
+               }
+               //
+               // We are going to retract these objects from memory
+               //
+               retract($response);
+
+end
+
+
+
 /*
 *
 * This is the timer that manages the timeout for an individual operation.
diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFCControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFCControlLoopTest.java
new file mode 100644 (file)
index 0000000..d5b6e44
--- /dev/null
@@ -0,0 +1,292 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * demo
+ * ================================================================================
+ * Copyright (C) 2017 Intel Corp. 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;
+
+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.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+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.kie.api.runtime.rule.FactHandle;
+import org.onap.policy.controlloop.ControlLoopEventStatus;
+import org.onap.policy.controlloop.ControlLoopLogger;
+import org.onap.policy.controlloop.ControlLoopTargetType;
+import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.impl.ControlLoopLoggerStdOutImpl;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.drools.http.server.HttpServletServer;
+import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
+import org.onap.policy.vfc.util.Serialization;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class VFCControlLoopTest {
+
+       private static final Logger log = LoggerFactory.getLogger(VFCControlLoopTest.class);
+       private KieSession kieSession;
+       private Util.Pair<ControlLoopPolicy, String> pair;
+       private PolicyEngineJUnitImpl engine;
+
+       @BeforeClass
+       public static void setUpSimulator() {
+               try {
+                       Util.buildAaiSim();
+                       Util.buildVfcSim();
+               } catch (Exception e) {
+                       fail(e.getMessage());
+               }
+       }
+
+       @AfterClass
+       public static void tearDownSimulator() {
+               HttpServletServer.factory.destroy();
+       }
+
+       @Test
+       public void testVolte() throws IOException {
+
+               final String yaml = "src/test/resources/yaml/policy_ControlLoop_VFC.yaml";
+
+               //
+               // Pull info from the yaml
+               //
+               final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yaml);
+               assertNotNull(pair);
+               assertNotNull(pair.a);
+               assertNotNull(pair.a.getControlLoop());
+               assertNotNull(pair.a.getControlLoop().getControlLoopName());
+               assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
+               final String closedLoopControlName = pair.a.getControlLoop().getControlLoopName();
+
+                /*
+         * Start the kie session
+         */
+               try {
+                       kieSession = startSession("src/main/resources/ControlLoop_Template_xacml_guard.drl",
+                                       "src/test/resources/yaml/policy_ControlLoop_VFC.yaml",
+                                       "service=ServiceTest;resource=ResourceTest;type=operational",
+                                       "CL_VFC",
+                                       "org.onap.closed_loop.ServiceTest:VNFS:1.0.0");
+               } catch (IOException e) {
+                       e.printStackTrace();
+                       log.debug("Could not create kieSession");
+                       fail("Could not create kieSession");
+               }
+
+
+               //
+               // Insert our globals
+               //
+               final ControlLoopLogger logger = new ControlLoopLoggerStdOutImpl();
+               kieSession.setGlobal("Logger", logger);
+               final PolicyEngineJUnitImpl engine = new PolicyEngineJUnitImpl();
+               kieSession.setGlobal("Engine", engine);
+
+               //
+               // Initial fire of rules
+               //
+               kieSession.fireAllRules();
+               //
+               // Kick a thread that starts testing
+               //
+               new Thread(new Runnable() {
+
+                       @Override
+                       public void run() {
+
+                               log.debug("\n************ Starting VoLTE Test *************\n");
+
+                               //
+                               // Generate an invalid DCAE Event with requestID=null
+                               //
+                               VirtualControlLoopEvent invalidEvent = new VirtualControlLoopEvent();
+                               invalidEvent.closedLoopControlName = closedLoopControlName;
+                               invalidEvent.requestID = null;
+                               invalidEvent.closedLoopEventClient = "tca.instance00009";
+                               invalidEvent.target_type = ControlLoopTargetType.VNF;
+                               invalidEvent.target = "generic-vnf.vnf-id";
+                               invalidEvent.from = "DCAE";
+                               invalidEvent.closedLoopAlarmStart = Instant.now();
+                               invalidEvent.AAI = new HashMap<String, String>();
+                               invalidEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1");
+                               invalidEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+
+                               log.debug("-------- Sending Invalid ONSET --------");
+                               log.debug(Serialization.gsonPretty.toJson(invalidEvent));
+
+                               //
+                               // Insert invalid DCAE Event into memory
+                               //
+                               kieSession.insert(invalidEvent);
+                               try {
+                                       Thread.sleep(500);
+                               } catch (InterruptedException e) {
+                               }
+                               //
+                               // Generate first DCAE ONSET Event
+                               //
+                               VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent();
+                               onsetEvent.closedLoopControlName = closedLoopControlName;
+                               onsetEvent.requestID = UUID.randomUUID();
+                               onsetEvent.closedLoopEventClient = "tca.instance00009";
+                               onsetEvent.target_type = ControlLoopTargetType.VM;
+                               onsetEvent.target = "VM_NAME";
+                               onsetEvent.from = "DCAE";
+                               onsetEvent.closedLoopAlarmStart = Instant.now();
+                               onsetEvent.AAI = new HashMap<String, String>();
+                               onsetEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1");
+                               onsetEvent.AAI.put("vserver.vserver-id", "vserver-id-16102016-aai3255-data-11-1");
+                               onsetEvent.AAI.put("generic-vnf.vnf-id", "vnf-id-16102016-aai3255-data-11-1");
+                               onsetEvent.AAI.put("service-instance.service-instance-id", "service-instance-id-16102016-aai3255-data-11-1");
+                               onsetEvent.AAI.put("vserver.is-closed-loop-disabled", "false");
+                               onsetEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+
+                               log.debug("-------- Sending Valid ONSET --------");
+                               log.debug(Serialization.gsonPretty.toJson(onsetEvent));
+
+                               //
+                               // Insert first DCAE ONSET Event into memory
+                               //
+                               kieSession.insert(onsetEvent);
+                               //
+                               // We have test for subsequent ONSET Events in testvFirewall()
+                               // So no need to test it again here
+                               //
+                               try {
+                                       Thread.sleep(30000);
+                               } catch (InterruptedException e) {
+                               }
+                               //
+                               // Test is finished, so stop the kieSession
+                               //
+                               kieSession.halt();
+                       }
+               //
+               }).start();
+               //
+               // Start firing rules
+               //
+               kieSession.fireUntilHalt();
+               //
+               // Dump working memory
+               //
+               dumpFacts(kieSession);
+
+               //
+               // See if there is anything left in memory, there SHOULD only be
+               // a params fact.
+               //
+               assertEquals("There should only be 1 Fact left in memory.", 1, kieSession.getFactCount());
+               for (FactHandle handle : kieSession.getFactHandles()) {
+                       Object fact = kieSession.getObject(handle);
+                       assertEquals("Non-Param Fact left in working memory", "org.onap.policy.controlloop.Params", fact.getClass().getName());
+               }
+
+       }
+
+       public static void dumpFacts(KieSession kieSession) {
+               log.debug("Fact Count: " + kieSession.getFactCount());
+               for (FactHandle handle : kieSession.getFactHandles()) {
+                       log.debug("FACT: " + handle);
+               }
+       }
+
+       /**
+        * 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
+        */
+       private KieSession startSession(String droolsTemplate,
+                                       String yamlFile,
+                                       String policyScope,
+                                       String policyName,
+                                       String policyVersion) throws IOException {
+
+        /*
+         * Load policies from yaml
+         */
+               pair = Util.loadYaml(yamlFile);
+               assertNotNull(pair);
+               assertNotNull(pair.a);
+               assertNotNull(pair.a.getControlLoop());
+               assertNotNull(pair.a.getControlLoop().getControlLoopName());
+               assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0);
+
+        /*
+         * Construct a kie session
+         */
+               final KieSession kieSession = Util.buildContainer(droolsTemplate,
+                               pair.a.getControlLoop().getControlLoopName(),
+                               policyScope,
+                               policyName,
+                               policyVersion,
+                               URLEncoder.encode(pair.b, "UTF-8"));
+
+        /*
+         * Retrieve the Policy Engine
+         */
+               engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
+
+               log.debug("============");
+               log.debug(URLEncoder.encode(pair.b, "UTF-8"));
+               log.debug("============");
+
+               return kieSession;
+       }
+
+}
+
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_VFC.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_VFC.yaml
new file mode 100644 (file)
index 0000000..00cced4
--- /dev/null
@@ -0,0 +1,24 @@
+controlLoop:
+  version: 2.0.0
+  controlLoopName: ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b
+
+  trigger_policy: unique-policy-id-1-restart
+  timeout: 3600
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart the VM
+    description:
+    actor: VFC
+    recipe: Restart
+    target:
+      type: VM
+    retry: 3
+    timeout: 1200
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
+    failure_guard: final_failure_guard
+