vDNS tosca compliant policies support 75/102275/2
authorjhh <jorge.hernandez-herrero@att.com>
Tue, 25 Feb 2020 00:14:04 +0000 (18:14 -0600)
committerjhh <jorge.hernandez-herrero@att.com>
Tue, 25 Feb 2020 00:22:33 +0000 (18:22 -0600)
Issue-ID: POLICY-2383
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
Change-Id: I5d5d864b2853f6e7e0c7e1096cb17746500f2495
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/UsecasesBase.java
controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/VcpeTest.java
controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/VfwTest.java
controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/VlbTest.java
controlloop/common/controller-usecases/src/test/resources/vlb/tosca-compliant-vlb.json [new file with mode: 0644]
controlloop/common/eventmanager/pom.xml
controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/processor/ControlLoopProcessorTest.java
controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vcpe.json [deleted file]
controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vfw.json [deleted file]
controlloop/common/eventmanager/src/test/resources/tosca-policy-legacy-vdns.json [new file with mode: 0644]

index 618963a..66ad324 100644 (file)
@@ -36,6 +36,7 @@ import java.util.Queue;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
 import org.kie.api.event.rule.AfterMatchFiredEvent;
 import org.kie.api.event.rule.BeforeMatchFiredEvent;
 import org.kie.api.event.rule.DefaultAgendaEventListener;
@@ -54,6 +55,7 @@ import org.onap.policy.common.endpoints.event.comm.TopicListener;
 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
 import org.onap.policy.controlloop.drl.legacy.ControlLoopParams;
 import org.onap.policy.drools.persistence.SystemPersistence;
 import org.onap.policy.drools.persistence.SystemPersistenceConstants;
@@ -66,6 +68,7 @@ import org.onap.policy.drools.util.KieUtils;
 import org.onap.policy.drools.utils.PropertyUtil;
 import org.onap.policy.drools.utils.logging.LoggerUtil;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.onap.policy.simulators.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -76,6 +79,7 @@ import org.slf4j.LoggerFactory;
 public abstract class UsecasesBase {
 
     private static final Logger logger = LoggerFactory.getLogger(UsecasesBase.class);
+    private static final StandardCoder coder = new StandardCoder();
 
     /**
      * PDP-D Engine.
@@ -151,14 +155,33 @@ public abstract class UsecasesBase {
             .get();
     }
 
+    protected ToscaPolicy getPolicyFromResource(String resourcePath, String policyName) throws CoderException {
+        String policyJson = ResourceUtils.getResourceAsString(resourcePath);
+        ToscaServiceTemplate serviceTemplate = coder.decode(policyJson, ToscaServiceTemplate.class);
+        ToscaPolicy policy = serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName);
+        assertNotNull(policy);
+
+        /*
+         * name and version are used within a drl.  api component and drools core will ensure that these
+         * are populated.
+         */
+        if (StringUtils.isBlank(policy.getName())) {
+            policy.setName(policyName);
+        }
 
-    /**
-     * Installs a given policy.
-     */
-    protected ToscaPolicy setupPolicy(String policyPath) throws IOException, CoderException, InterruptedException {
+        if (StringUtils.isBlank(policy.getVersion())) {
+            policy.setVersion(policy.getTypeVersion());
+        }
+
+        return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName);
+    }
+
+    protected ToscaPolicy getPolicyFromFile(String policyPath) throws IOException, CoderException {
         String rawPolicy = new String(Files.readAllBytes(Paths.get(policyPath)));
-        ToscaPolicy policy = new StandardCoder().decode(rawPolicy, ToscaPolicy.class);
+        return coder.decode(rawPolicy, ToscaPolicy.class);
+    }
 
+    private ToscaPolicy setupPolicy(ToscaPolicy policy) throws InterruptedException {
         final KieObjectExpectedCallback policyTracker = new KieObjectInsertedExpectedCallback<>(policy);
         final KieObjectExpectedCallback paramsTracker = new KieClassInsertedExpectedCallback<>(ControlLoopParams.class);
 
@@ -167,23 +190,31 @@ public abstract class UsecasesBase {
         assertTrue(policyTracker.isNotified());
         assertTrue(paramsTracker.isNotified());
 
-        assertEquals(1,
-            usecases
-                .getDrools()
-                .facts(USECASES, ToscaPolicy.class).stream()
-                .filter((anotherPolicy) -> anotherPolicy == policy)
-                .count());
-
-        assertEquals(1,
-            usecases
-                .getDrools()
-                .facts(USECASES, ControlLoopParams.class).stream()
-                .filter((params) -> params.getToscaPolicy() == policy)
-                .count());
+        assertEquals(1, usecases.getDrools().facts(USECASES, ToscaPolicy.class).stream()
+                                .filter((anotherPolicy) -> anotherPolicy == policy).count());
 
+        assertEquals(1, usecases.getDrools().facts(USECASES, ControlLoopParams.class).stream()
+                                .filter((params) -> params.getToscaPolicy() == policy).count());
         return policy;
     }
 
+    /**
+     * Installs a policy from policy/models (examples) repo.
+     */
+    protected ToscaPolicy setupPolicyFromResource(String resourcePath, String policyName)
+            throws CoderException, InterruptedException {
+        return setupPolicy(getPolicyFromResource(resourcePath, policyName));
+    }
+
+
+    /**
+     * Installs a given policy.
+     */
+    protected ToscaPolicy setupPolicyFromFile(String policyPath)
+            throws IOException, CoderException, InterruptedException {
+        return setupPolicy(getPolicyFromFile(policyPath));
+    }
+
     /**
      * Deletes a policy.
      */
index 1d9d0dd..ec3b502 100644 (file)
@@ -127,7 +127,7 @@ public class VcpeTest extends UsecasesBase {
     @Test
     public void sunnyDayLegacy() throws InterruptedException, CoderException, IOException {
         assertEquals(0, usecases.getDrools().factCount(USECASES));
-        policy = setupPolicy(TOSCA_LEGACY_POLICY_VCPE);
+        policy = setupPolicyFromFile(TOSCA_LEGACY_POLICY_VCPE);
         assertEquals(2, usecases.getDrools().factCount(USECASES));
 
         sunnyDay();
@@ -139,7 +139,7 @@ public class VcpeTest extends UsecasesBase {
     @Test
     public void sunnyDayCompliant() throws InterruptedException, CoderException, IOException {
         assertEquals(0, usecases.getDrools().factCount(USECASES));
-        policy = setupPolicy(TOSCA_COMPLIANT_POLICY_VCPE);
+        policy = setupPolicyFromFile(TOSCA_COMPLIANT_POLICY_VCPE);
         assertEquals(2, usecases.getDrools().factCount(USECASES));
 
         sunnyDay();
@@ -153,7 +153,7 @@ public class VcpeTest extends UsecasesBase {
     @Test
     public void onsetFloodPrevention() throws IOException, InterruptedException, CoderException {
         assertEquals(0, usecases.getDrools().factCount(USECASES));
-        policy = setupPolicy(TOSCA_LEGACY_POLICY_VCPE);
+        policy = setupPolicyFromFile(TOSCA_LEGACY_POLICY_VCPE);
         assertEquals(2, usecases.getDrools().factCount(USECASES));
 
         injectOnTopic(DCAE_TOPIC, Paths.get(ONSET_1));
index 3796f0b..8386b30 100644 (file)
@@ -68,7 +68,7 @@ public class VfwTest extends UsecasesBase {
      * Prepare PDP-D Framework for testing.
      */
     @BeforeClass
-    public static void prepareResouces() throws InterruptedException, CoderException, IOException {
+    public static void prepareResouces() throws InterruptedException, IOException {
         setupLogging();
         preparePdpD();
         setupSimulators();
@@ -124,7 +124,7 @@ public class VfwTest extends UsecasesBase {
     @Test
     public void sunnyDayLegacy() throws InterruptedException, CoderException, IOException {
         assertEquals(0, usecases.getDrools().factCount(USECASES));
-        policy = setupPolicy(TOSCA_LEGACY_POLICY_VFW);
+        policy = setupPolicyFromFile(TOSCA_LEGACY_POLICY_VFW);
         assertEquals(2, usecases.getDrools().factCount(USECASES));
 
         sunnyDay();
@@ -136,7 +136,7 @@ public class VfwTest extends UsecasesBase {
     @Test
     public void sunnyDayCompliant() throws InterruptedException, CoderException, IOException {
         assertEquals(0, usecases.getDrools().factCount(USECASES));
-        policy = setupPolicy(TOSCA_COMPLIANT_POLICY_VFW);
+        policy = setupPolicyFromFile(TOSCA_COMPLIANT_POLICY_VFW);
         assertEquals(2, usecases.getDrools().factCount(USECASES));
 
         sunnyDay();
index e577fab..73eeae8 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2020 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.
@@ -41,7 +41,8 @@ public class VlbTest extends UsecasesBase {
     /**
      * VLB Tosca Policy File.
      */
-    private static final String TOSCA_POLICY_VLB = "src/test/resources/vlb/tosca-vlb.json";
+    private static final String TOSCA_LEGACY_POLICY_VLB = "src/test/resources/vlb/tosca-vlb.json";
+    private static final String TOSCA_COMPLIANT_POLICY_VLB = "src/test/resources/vlb/tosca-compliant-vlb.json";
 
     /*
      * VLB Use case Messages.
@@ -62,7 +63,7 @@ public class VlbTest extends UsecasesBase {
      * Prepare PDP-D Framework for testing.
      */
     @BeforeClass
-    public static void prepareResouces() throws InterruptedException, CoderException, IOException {
+    public static void prepareResouces() throws InterruptedException, IOException {
         setupLogging();
         preparePdpD();
         setupSimulators();
@@ -80,8 +81,7 @@ public class VlbTest extends UsecasesBase {
     /**
      * Sunny day scenario for the VCPE use case.
      */
-    @Test
-    public void sunnyDay() throws IOException {
+    private void sunnyDay() throws IOException {
 
         /* Inject an ONSET event over the DCAE topic */
         injectOnTopic(DCAE_TOPIC, Paths.get(ONSET));
@@ -100,6 +100,30 @@ public class VlbTest extends UsecasesBase {
         waitForFinalSuccess(policy, policyClMgt);
     }
 
+    /**
+     * Sunny Day with Legacy Tosca Policy.
+     */
+    @Test
+    public void sunnyDayLegacy() throws InterruptedException, CoderException, IOException {
+        assertEquals(0, usecases.getDrools().factCount(USECASES));
+        policy = setupPolicyFromFile(TOSCA_LEGACY_POLICY_VLB);
+        assertEquals(2, usecases.getDrools().factCount(USECASES));
+
+        sunnyDay();
+    }
+
+    /**
+     * Sunny Day with Tosca Compliant Policy.
+     */
+    @Test
+    public void sunnyDayCompliant() throws InterruptedException, CoderException, IOException {
+        assertEquals(0, usecases.getDrools().factCount(USECASES));
+        policy = setupPolicyFromFile(TOSCA_COMPLIANT_POLICY_VLB);
+        assertEquals(2, usecases.getDrools().factCount(USECASES));
+
+        sunnyDay();
+    }
+
     /**
      * Observe Topics.
      */
@@ -118,16 +142,6 @@ public class VlbTest extends UsecasesBase {
         }
     }
 
-    /**
-     * Install Policy.
-     */
-    @Before
-    public void installPolicy() throws IOException, CoderException, InterruptedException {
-        assertEquals(0, usecases.getDrools().factCount(USECASES));
-        policy = setupPolicy(TOSCA_POLICY_VLB);
-        assertEquals(2, usecases.getDrools().factCount(USECASES));
-    }
-
     /**
      * Uninstall Policy.
      */
diff --git a/controlloop/common/controller-usecases/src/test/resources/vlb/tosca-compliant-vlb.json b/controlloop/common/controller-usecases/src/test/resources/vlb/tosca-compliant-vlb.json
new file mode 100644 (file)
index 0000000..0ddd630
--- /dev/null
@@ -0,0 +1,48 @@
+{
+    "type": "onap.policies.controlloop.operational.common.Drools",
+    "type_version": "1.0.0",
+    "name": "operational.scaleout",
+    "version": "1.0.0",
+    "metadata": {
+        "policy-id": "operational.scaleout"
+    },
+    "properties": {
+        "id": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3",
+        "timeout": 1200,
+        "abatement": false,
+        "trigger": "unique-policy-id-1-scale-up",
+        "operations": [
+            {
+                "id": "unique-policy-id-1-scale-up",
+                "description": "Create a new VF Module",
+                "operation": {
+                    "actor": "SO",
+                    "operation": "VF Module Create",
+                    "target": {
+                        "targetType": "VFMODULE",
+                        "entityIds": {
+                            "modelInvariantId": "e6130d03-56f1-4b0a-9a1d-e1b2ebc30e0e",
+                            "modelVersionId": "94b18b1d-cc91-4f43-911a-e6348665f292",
+                            "modelName": "VfwclVfwsnkBbefb8ce2bde..base_vfw..module-0",
+                            "modelVersion": 1,
+                            "modelCustomizationId": "47958575-138f-452a-8c8d-d89b595f8164"
+                        }
+                    },
+                    "payload": {
+                        "requestParameters": "{\"usePreload\":true,\"userParams\":[]}",
+                        "configurationParameters": "[{\"ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[9]\",\"oam-ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[16]\",\"enabled\":\"$.vf-module-topology.vf-module-parameters.param[23]\"}]"
+                    }
+                },
+                "timeout": 1200,
+                "retries": 0,
+                "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"
+            }
+        ],
+        "controllerName": "usecases"
+    }
+}
index 4f9bfb7..8848170 100644 (file)
             <version>${policy.models.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.onap.policy.models</groupId>
+            <artifactId>policy-models-examples</artifactId>
+            <version>${policy.models.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
index a309147..ae6af6c 100644 (file)
@@ -32,14 +32,17 @@ import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.junit.Test;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
 import org.onap.policy.controlloop.ControlLoopException;
 import org.onap.policy.controlloop.policy.FinalResult;
 import org.onap.policy.controlloop.policy.Policy;
 import org.onap.policy.controlloop.policy.PolicyResult;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,32 +58,67 @@ public class ControlLoopProcessorTest {
         this.testFailure(yamlString);
     }
 
+    private ToscaPolicy getPolicyFromResource(String resourcePath, String policyName) throws CoderException {
+        String policyJson = ResourceUtils.getResourceAsString(resourcePath);
+        ToscaServiceTemplate serviceTemplate = coder.decode(policyJson, ToscaServiceTemplate.class);
+        ToscaPolicy policy = serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName);
+        assertNotNull(policy);
+
+        /*
+         * name and version are used within a drl.  api component and drools core will ensure that these
+         * are populated.
+         */
+        if (StringUtils.isBlank(policy.getName())) {
+            policy.setName(policyName);
+        }
+
+        if (StringUtils.isBlank(policy.getVersion())) {
+            policy.setVersion(policy.getTypeVersion());
+        }
+
+        return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName);
+    }
+
     @Test
     public void testControlLoopFromToscaLegacy() throws IOException, CoderException, ControlLoopException {
         String policy =
                 new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-legacy-vcpe.json")));
         assertNotNull(
                 new ControlLoopProcessor(coder.decode(policy, ToscaPolicy.class)).getCurrentPolicy());
+
+        policy =
+                new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-legacy-vdns.json")));
+        assertNotNull(
+                new ControlLoopProcessor(coder.decode(policy, ToscaPolicy.class)).getCurrentPolicy());
     }
 
     @Test
-    public void testControlLoopFromToscaCompliant() throws IOException, CoderException, ControlLoopException {
-        String policy =
-                  new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-compliant-vcpe.json")));
+    public void testControlLoopFromToscaCompliant()
+            throws CoderException, ControlLoopException {
         assertNotNull(
-                  new ControlLoopProcessor(coder.decode(policy, ToscaPolicy.class)).getCurrentPolicy());
+                new ControlLoopProcessor(
+                        getPolicyFromResource(
+                                "policies/vCPE.policy.operational.input.tosca.json", "operational.restart")
+                ).getCurrentPolicy());
+
 
-        policy =
-                new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-compliant-vfw.json")));
         assertNotNull(
-                new ControlLoopProcessor(coder.decode(policy, ToscaPolicy.class)).getCurrentPolicy());
+                new ControlLoopProcessor(
+                        getPolicyFromResource(
+                                "policies/vFirewall.policy.operational.input.tosca.json", "operational.modifyconfig")
+                ).getCurrentPolicy());
+
+        assertNotNull(
+                new ControlLoopProcessor(
+                        getPolicyFromResource(
+                                "policies/vDNS.policy.operational.input.tosca.json", "operational.scaleout")
+                ).getCurrentPolicy());
     }
 
     @Test
-    public void testControlLoopFromToscaCompliantBad() throws IOException, CoderException, ControlLoopException {
-        String policy =
-                new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-compliant-vcpe.json")));
-        ToscaPolicy toscaPolicy = coder.decode(policy, ToscaPolicy.class);
+    public void testControlLoopFromToscaCompliantBad() throws CoderException {
+        ToscaPolicy toscaPolicy = getPolicyFromResource(
+                "policies/vCPE.policy.operational.input.tosca.json", "operational.restart");
         toscaPolicy.setType("onap.policies.controlloop.Operational");
         assertThatThrownBy(() -> new ControlLoopProcessor(toscaPolicy)).hasCauseInstanceOf(CoderException.class);
     }
@@ -147,7 +185,7 @@ public class ControlLoopProcessorTest {
     }
 
     /**
-     * Test policies in the given yaml following the successfull path.
+     * Test policies in the given yaml following the successful path.
      *
      * @param yaml yaml containing the policies to test
      * @throws ControlLoopException if an error occurs
diff --git a/controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vcpe.json b/controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vcpe.json
deleted file mode 100644 (file)
index 61fb8a6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-    "type": "onap.policies.controlloop.operational.common.Drools",
-    "type_version": "1.0.0",
-    "version": "1.0.0",
-    "name": "operational.restart",
-    "metadata": {
-        "policy-id": "operational.restart"
-    },
-    "properties": {
-        "id": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e",
-        "timeout": 3600,
-        "abatement": false,
-        "trigger": "unique-policy-id-1-restart",
-        "operations": [
-            {
-                "id": "unique-policy-id-1-restart",
-                "description": "Restart the VM",
-                "operation": {
-                    "actor": "APPC",
-                    "operation": "Restart",
-                    "target": {
-                        "targetType": "VM"
-                    }
-                },
-                "timeout": 1200,
-                "retries": 3,
-                "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"
-            }
-        ],
-        "controllerName": "usecases"
-    }
-}
\ No newline at end of file
diff --git a/controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vfw.json b/controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vfw.json
deleted file mode 100644 (file)
index c96b49c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-    "type": "onap.policies.controlloop.operational.common.Drools",
-    "type_version": "1.0.0",
-    "name": "operational.modifyconfig",
-    "version": "1.0.0",
-    "metadata": {
-        "policy-id": "operational.modifyconfig"
-    },
-    "properties": {
-        "id": "ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a",
-        "timeout": 60,
-        "abatement": false,
-        "trigger": "unique-policy-id-1-modifyConfig",
-        "operations": [
-            {
-                "id": "unique-policy-id-1-modifyConfig",
-                "description": "Modify the packet generator",
-                "operation": {
-                    "actor": "APPC",
-                    "operation": "ModifyConfig",
-                    "target": {
-                        "targetType": "VNF",
-                        "entityIds": {
-                            "resourceID": "bbb3cefd-01c8-413c-9bdd-2b92f9ca3d38"
-                        }
-                    }
-                },
-                "timeout": 300,
-                "retries": 0,
-                "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"
-            }
-        ],
-        "controllerName": "usecases"
-    }
-}
diff --git a/controlloop/common/eventmanager/src/test/resources/tosca-policy-legacy-vdns.json b/controlloop/common/eventmanager/src/test/resources/tosca-policy-legacy-vdns.json
new file mode 100644 (file)
index 0000000..5147d99
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "type": "onap.policies.controlloop.Operational",
+  "type_version": "1.0.0",
+  "properties": {
+    "content": "controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20controlLoopName%3A%20ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3%0A%20%20services%3A%0A%20%20%20%20-%20serviceName%3A%20d4738992-6497-4dca-9db9%0A%20%20%20%20%20%20serviceInvariantUUID%3A%20dc112d6e-7e73-4777-9c6f-1a7fb5fd1b6f%0A%20%20%20%20%20%20serviceUUID%3A%202eea06c6-e1d3-4c3a-b9c4-478c506eeedf%0A%20%20trigger_policy%3A%20unique-policy-id-1-scale-up%0A%20%20timeout%3A%2060%0A%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-scale-up%0A%20%20%20%20name%3A%20Create%20a%20new%20VF%20Module%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20SO%0A%20%20%20%20recipe%3A%20VF%20Module%20Create%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20type%3A%20VFMODULE%0A%20%20%20%20%20%20modelInvariantId%3A%20e6130d03-56f1-4b0a-9a1d-e1b2ebc30e0e%0A%20%20%20%20%20%20modelVersionId%3A%2094b18b1d-cc91-4f43-911a-e6348665f292%0A%20%20%20%20%20%20modelName%3A%20VfwclVfwsnkBbefb8ce2bde..base_vfw..module-0%0A%20%20%20%20%20%20modelVersion%3A%201%0A%20%20%20%20%20%20modelCustomizationId%3A%2047958575-138f-452a-8c8d-d89b595f8164%0A%20%20%20%20payload%3A%0A%20%20%20%20%20%20requestParameters%3A%20%27%7B%22usePreload%22%3Atrue%2C%22userParams%22%3A%5B%5D%7D%27%0A%20%20%20%20%20%20configurationParameters%3A%20%27%5B%7B%22ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B9%5D%22%2C%22oam-ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B16%5D%22%2C%22enabled%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B23%5D%22%7D%5D%27%0A%20%20%20%20retry%3A%200%0A%20%20%20%20timeout%3A%2030%0A%20%20%20%20success%3A%20final_success%0A%20%20%20%20failure%3A%20final_failure%0A%20%20%20%20failure_timeout%3A%20final_failure_timeout%0A%20%20%20%20failure_retries%3A%20final_failure_retries%0A%20%20%20%20failure_exception%3A%20final_failure_exception%0A%20%20%20%20failure_guard%3A%20final_failure_guard%0A"
+  },
+  "name": "vlb",
+  "version": "1.0.0"
+}
\ No newline at end of file