Add CCVPN Bandwidth on demand policy 45/83945/5
authorVidyashree Rama <vidyashree.rama@huawei.com>
Tue, 2 Apr 2019 09:10:35 +0000 (14:40 +0530)
committerVidyashree Rama <vidyashree.rama@huawei.com>
Fri, 5 Apr 2019 06:32:38 +0000 (12:02 +0530)
CCVPN Bandwidth on demand policy

Issue-ID: POLICY-1405
Change-Id: I67bceb35e5a849933b3e46772c9cbbbaab1e9a75
Signed-off-by: Vidyashree Rama <vidyashree.rama@huawei.com>
21 files changed:
controlloop/common/actors/actor.sdnc/src/main/java/org/onap/policy/controlloop/actor/sdnc/SdncActorServiceProvider.java
controlloop/common/actors/actor.sdnc/src/test/java/org/onap/policy/controlloop/actor/sdnc/SdncActorServiceProviderTest.java
controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java
controlloop/common/feature-controlloop-management/src/main/feature/bin/create-cl-usecases
controlloop/common/feature-controlloop-management/src/main/feature/bin/push-policies-usecases
controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealRequest.java
controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleParameter.java [new file with mode: 0644]
controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleParametersInfo.java [new file with mode: 0644]
controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleRequestInput.java [new file with mode: 0644]
controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVnfInfo.java [new file with mode: 0644]
controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncManager.java
controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncRequest.java
controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SdncSimulatorJaxRs.java
controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/CCVPNBW.yaml [new file with mode: 0644]
controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.bw.onset.json [new file with mode: 0644]
controlloop/templates/archetype-cl-usecases/src/main/resources/META-INF/maven/archetype-metadata.xml
controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/CCVPNBW.yaml [new file with mode: 0644]
controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/ccvpnbw.brmsgw.params.json [new file with mode: 0644]
controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.bw.onset.json [new file with mode: 0644]
controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/CcvpnBwControlLoopTest.java [new file with mode: 0644]
controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_CCVPN_BW.yaml [new file with mode: 0644]

index b9eaf7e..ab6a778 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * SdncActorServiceProvider
  * ================================================================================
- * Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
+ * Copyright (C) 2018-2019 Huawei Technologies Co., Ltd. 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.
@@ -37,6 +37,11 @@ import org.onap.policy.sdnc.SdncHealRequest;
 import org.onap.policy.sdnc.SdncHealRequestHeaderInfo;
 import org.onap.policy.sdnc.SdncHealRequestInfo;
 import org.onap.policy.sdnc.SdncHealServiceInfo;
+import org.onap.policy.sdnc.SdncHealVfModuleParameter;
+import org.onap.policy.sdnc.SdncHealVfModuleParametersInfo;
+import org.onap.policy.sdnc.SdncHealVfModuleRequestInput;
+import org.onap.policy.sdnc.SdncHealVnfInfo;
+
 import org.onap.policy.sdnc.SdncRequest;
 
 import org.slf4j.Logger;
@@ -55,6 +60,9 @@ public class SdncActorServiceProvider implements Actor {
     // Strings for recipes
     private static final String RECIPE_REROUTE = "Reroute";
 
+    // Strings for recipes
+    private static final String RECIPE_BW_ON_DEMAND = "BandwidthOnDemand";
+
     private static final ImmutableList<String> recipes = ImmutableList.of(RECIPE_REROUTE);
     private static final ImmutableMap<String, List<String>> targets =
             new ImmutableMap.Builder<String, List<String>>().put(RECIPE_REROUTE, ImmutableList.of(TARGET_VM)).build();
@@ -81,34 +89,92 @@ public class SdncActorServiceProvider implements Actor {
 
     /**
      * Construct a request.
-     * 
+     *
      * @param onset the onset event
      * @param operation the control loop operation
      * @param policy the policy
      * @return the constructed request
      */
-    public static SdncRequest constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation,
+    public SdncRequest constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation,
             Policy policy) {
+        switch (policy.getRecipe()) {
+            case RECIPE_REROUTE:
+                return constructReOptimizeRequest(onset);
+            case RECIPE_BW_ON_DEMAND:
+                logger.info("Construct request for receipe {}" , RECIPE_BW_ON_DEMAND);
+                return constructBwOnDemandRequest(onset);
+            default:
+                logger.info("Unsupported recipe {} " + policy.getRecipe());
+                return null;
+        }
+    }
 
-        if (!policy.getRecipe().equalsIgnoreCase(RECIPE_REROUTE)) {
+    private SdncRequest constructBwOnDemandRequest(VirtualControlLoopEvent onset) {
+        // Construct an Sdnc request
+        String serviceInstance = onset.getAai().get("service-instance.service-instance-id");
+        if (serviceInstance == null || serviceInstance.isEmpty()) {
+            // This indicates that AAI Enrichment needs to be done by event producer.
             return null;
         }
+        SdncHealVfModuleParameter bandwidth = new SdncHealVfModuleParameter();
+        bandwidth.setName("bandwidth");
+        bandwidth.setValue(onset.getAai().get("bandwidth"));
+
+        SdncHealVfModuleParameter timeStamp = new SdncHealVfModuleParameter();
+        timeStamp.setName("bandwidth-change-time");
+        timeStamp.setValue(onset.getAai().get("bandwidth-change-time"));
+
+        SdncHealVfModuleParametersInfo vfParametersInfo = new SdncHealVfModuleParametersInfo();
+        vfParametersInfo.addParameters(bandwidth);
+        vfParametersInfo.addParameters(timeStamp);
+
+        SdncHealVfModuleRequestInput vfRequestInfo = new SdncHealVfModuleRequestInput();
+        vfRequestInfo.setVfModuleParametersInfo(vfParametersInfo);
+
+        SdncHealServiceInfo serviceInfo = new SdncHealServiceInfo();
+        serviceInfo.setServiceInstanceId(serviceInstance);
+
+        SdncHealRequestInfo requestInfo = new SdncHealRequestInfo();
+        requestInfo.setRequestAction("SdwanBWPolicyChange");
+
+        SdncHealRequestHeaderInfo headerInfo = new SdncHealRequestHeaderInfo();
+        headerInfo.setSvcAction("update");
+        headerInfo.setSvcRequestId(UUID.randomUUID().toString());
 
+        SdncRequest request = new SdncRequest();
+        request.setNsInstanceId(serviceInstance);
+        request.setRequestId(onset.getRequestId());
+        request.setUrl("/GENERIC-RESOURCE-API:vnf-topology-operation");
+
+        SdncHealVnfInfo vnfInfo = new SdncHealVnfInfo();
+        vnfInfo.setVnfId(onset.getAai().get("vnfId"));
+
+        SdncHealRequest healRequest = new SdncHealRequest();
+        healRequest.setVnfInfo(vnfInfo);
+        healRequest.setRequestHeaderInfo(headerInfo);
+        healRequest.setVfModuleRequestInput(vfRequestInfo);
+        healRequest.setRequestInfo(requestInfo);
+        healRequest.setServiceInfo(serviceInfo);
+        request.setHealRequest(healRequest);
+        return request;
+    }
+
+    private SdncRequest constructReOptimizeRequest(VirtualControlLoopEvent onset) {
         // Construct an Sdnc request
         String serviceInstance = onset.getAai().get("service-instance.service-instance-id");
         if (serviceInstance == null || serviceInstance.isEmpty()) {
-            // This indicates that AAI Enrichment needs to be done by event producer. 
+            // This indicates that AAI Enrichment needs to be done by event producer.
             return null;
         }
         SdncHealServiceInfo serviceInfo = new SdncHealServiceInfo();
         serviceInfo.setServiceInstanceId(serviceInstance);
-        
+
         String networkId = onset.getAai().get("network-information.network-id");
         if (networkId == null || networkId.isEmpty()) {
-            // This indicates that AAI Enrichment needs to be done by event producer. 
+            // This indicates that AAI Enrichment needs to be done by event producer.
             return null;
         }
-        SdncHealNetworkInfo networkInfo = new SdncHealNetworkInfo();        
+        SdncHealNetworkInfo networkInfo = new SdncHealNetworkInfo();
         networkInfo.setNetworkId(networkId);
 
         SdncHealRequestInfo requestInfo = new SdncHealRequestInfo();
@@ -121,6 +187,7 @@ public class SdncActorServiceProvider implements Actor {
         SdncRequest request = new SdncRequest();
         request.setNsInstanceId(serviceInstance);
         request.setRequestId(onset.getRequestId());
+        request.setUrl("/GENERIC-RESOURCE-API:network-topology-operation");
 
         SdncHealRequest healRequest = new SdncHealRequest();
         healRequest.setRequestHeaderInfo(headerInfo);
@@ -128,7 +195,6 @@ public class SdncActorServiceProvider implements Actor {
         healRequest.setRequestInfo(requestInfo);
         healRequest.setServiceInfo(serviceInfo);
         request.setHealRequest(healRequest);
-
         return request;
     }
 }
\ No newline at end of file
index 633234f..f968f86 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * TestSdncActorServiceProvider
  * ================================================================================
- * Copyright (C) 2018 Huawei. All rights reserved.
+ * Copyright (C) 2018-2019 Huawei Technologies Co., Ltd. All rights reserved.
  * Modifications Copyright (C) 2018 AT&T Corp. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -68,31 +68,32 @@ public class SdncActorServiceProviderTest {
         Policy policy = new Policy();
         policy.setRecipe("Reroute");
 
-        assertNull(SdncActorServiceProvider.constructRequest(onset, operation, policy));
+        SdncActorServiceProvider provider = new SdncActorServiceProvider();
+        assertNull(provider.constructRequest(onset, operation, policy));
 
         onset.getAai().put("network-information.network-id", "network-5555");
-        assertNull(SdncActorServiceProvider.constructRequest(onset, operation, policy));
+        assertNull(provider.constructRequest(onset, operation, policy));
 
         PolicyEngine.manager.setEnvironmentProperty("aai.url", "http://localhost:6666");
         PolicyEngine.manager.setEnvironmentProperty("aai.username", "AAI");
         PolicyEngine.manager.setEnvironmentProperty("aai.password", "AAI");
-        assertNull(SdncActorServiceProvider.constructRequest(onset, operation, policy));
+        assertNull(provider.constructRequest(onset, operation, policy));
 
         UUID requestId = UUID.randomUUID();
         onset.setRequestId(requestId);
-        assertNull(SdncActorServiceProvider.constructRequest(onset, operation, policy));
+        assertNull(provider.constructRequest(onset, operation, policy));
 
         PolicyEngine.manager.setEnvironmentProperty("aai.password", "AAI");
-        assertNull(SdncActorServiceProvider.constructRequest(onset, operation, policy));
+        assertNull(provider.constructRequest(onset, operation, policy));
 
         onset.getAai().put("service-instance.service-instance-id", "service-instance-01");
-        assertNotNull(SdncActorServiceProvider.constructRequest(onset, operation, policy));
+        assertNotNull(provider.constructRequest(onset, operation, policy));
 
         policy.setRecipe("Reroute");
-        assertNotNull(SdncActorServiceProvider.constructRequest(onset, operation, policy));
+        assertNotNull(provider.constructRequest(onset, operation, policy));
 
         SdncRequest request =
-                SdncActorServiceProvider.constructRequest(onset, operation, policy);
+                provider.constructRequest(onset, operation, policy);
 
         assertEquals(requestId, Objects.requireNonNull(request).getRequestId());
         assertEquals("reoptimize", request.getHealRequest().getRequestHeaderInfo().getSvcAction());
index 2ea1c48..9d60e2d 100644 (file)
@@ -3,6 +3,7 @@
  * controlloop operation manager
  * ================================================================================
  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.
@@ -309,13 +310,14 @@ public class ControlLoopOperationManager implements Serializable {
 
                 return operationRequest;
             case "SDNC":
-                this.operationRequest = SdncActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
+                SdncActorServiceProvider provider = new SdncActorServiceProvider();
+                this.operationRequest = provider.constructRequest((VirtualControlLoopEvent) onset,
                         operation.clOperation, this.policy);
                 this.currentOperation = operation;
                 if (this.operationRequest == null) {
                     this.policyResult = PolicyResult.FAILURE;
                 }
-                return operationRequest;                
+                return operationRequest;
             default:
                 throw new ControlLoopException("invalid actor " + policy.getActor() + " on policy");
         }
index 5662e7c..99843aa 100644 (file)
@@ -5,6 +5,7 @@
 # ONAP
 # ================================================================================
 # Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved.
+# Modifications Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.
@@ -67,6 +68,11 @@ imeout%3A+3600%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+
 pe%3A+Reroute%0D%0A++++target%3A%0D%0A++++++type%3A+VM%0D%0A++++retry%3A+3%0D%0A++++timeout%3A+1200%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_fail
 ure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard"
 
+# CCVPN Bandwidth On Demand Policy Parameters
+CCVPN_BW_CONTROL_LOOP_NAME="ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b"
+CCVPN_BW_POLICY_NAME="CCVPNBandwidthOnDemand"
+CCVPN_BW_CONTROL_LOOP_YAML="controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b%0D%0A++trigger_policy%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++++name%3A+CCVPNBandwidthOnDemand%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++recipe%3A+BandwidthOnDemand%0D%0A++++target%3A%0D%0A++++++type%3A+VM%0D%0A++++retry%3A+3%0D%0A++++timeout%3A+1200%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard"
+
 # Generic Scope and Version
 POLICY_SCOPE="usecases"
 POLICY_VERSION="v0.0.1"
@@ -107,6 +113,10 @@ read -e -i "${CCVPN_CONTROL_LOOP_NAME}" -p "CCVPN Control Loop Name> " CCVPN_CON
 read -e -i "${CCVPN_POLICY_NAME}" -p "CCVPN Policy Name> " CCVPN_POLICY_NAME
 read -e -i "${CCVPN_CONTROL_LOOP_YAML}" -p "CCVPN Control Loop Yaml> " CCVPN_CONTROL_LOOP_YAML
 
+read -e -i "${CCVPN_BW_CONTROL_LOOP_NAME}" -p "CCVPN BW Control Loop Name> " CCVPN_BW_CONTROL_LOOP_NAME
+read -e -i "${CCVPN_BW_POLICY_NAME}" -p "CCVPN BW Policy Name> " CCVPN_BW_POLICY_NAME
+read -e -i "${CCVPN_BW_CONTROL_LOOP_YAML}" -p "CCVPN BW Control Loop Yaml> " CCVPN_BW_CONTROL_LOOP_YAML
+
 read -e -i "${POLICY_SCOPE}" -p "Generic Policy Scope> " POLICY_SCOPE
 read -e -i "${POLICY_VERSION}" -p "Generic Policy Version> " POLICY_VERSION
 
@@ -149,6 +159,10 @@ if [ -z "${CCVPN_CONTROL_LOOP_NAME}" ]; then echo "Aborting: CCVPN Control Loop
 if [ -z "${CCVPN_POLICY_NAME}" ]; then echo "Aborting: CCVPN Policy Name not provided"; exit 1; fi
 if [ -z "${CCVPN_CONTROL_LOOP_YAML}" ]; then echo "Aborting: CCVPN Control Loop Yaml not provided"; exit 1; fi
 
+if [ -z "${CCVPN_BW_CONTROL_LOOP_NAME}" ]; then echo "Aborting: CCVPN BW Control Loop Name not provided"; exit 1; fi
+if [ -z "${CCVPN_BW_POLICY_NAME}" ]; then echo "Aborting: CCVPN BW Policy Name not provided"; exit 1; fi
+if [ -z "${CCVPN_BW_CONTROL_LOOP_YAML}" ]; then echo "Aborting: CCVPN BW Control Loop Yaml not provided"; exit 1; fi
+
 if [ -z "${POLICY_SCOPE}" ]; then echo "Aborting: Template Policy Scope not provided"; exit 1; fi
 if [ -z "${POLICY_VERSION}" ]; then echo "Aborting: Template Policy Version not provided"; exit 1; fi
 
@@ -199,6 +213,10 @@ echo "CCVPN Drools Fact Generation: CCVPN Control Loop Control Name: ${CCVPN_CON
 echo "CCVPN Drools Fact Generation: CCVPN Control Loop Policy Name: ${CCVPN_POLICY_NAME}"
 echo "CCVPN Drools Fact Generation: CCVPN Control Loop Yaml: ${CCVPN_CONTROL_LOOP_YAML}"
 echo
+echo "CCVPN BW Drools Fact Generation: CCVPN BW Control Loop Control Name: ${CCVPN_BW_CONTROL_LOOP_NAME}"
+echo "CCVPN BW Drools Fact Generation: CCVPN BW Control Loop Policy Name: ${CCVPN_BW_POLICY_NAME}"
+echo "CCVPN BW Drools Fact Generation: CCVPN BW Control Loop Yaml: ${CCVPN_BW_CONTROL_LOOP_YAML}"
+echo
 echo "Generic Drools Fact: Control Loop Policy Scope: ${POLICY_SCOPE}"
 echo "Generic: Control Loop Policy Version: ${POLICY_VERSION}"
 echo
@@ -295,6 +313,9 @@ mvn archetype:generate \
     -DccvpnClosedLoopControlName="${CCVPN_CONTROL_LOOP_NAME}" \
     -DccvpnPolicyName="${CCVPN_POLICY_NAME}" \
     -DccvpnControlLoopYaml="${CCVPN_CONTROL_LOOP_YAML}" \
+    -DccvpnBwClosedLoopControlName="${CCVPN_BW_CONTROL_LOOP_NAME}" \
+    -DccvpnBwPolicyName="${CCVPN_BW_POLICY_NAME}" \
+    -DccvpnBwControlLoopYaml="${CCVPN_BW_CONTROL_LOOP_YAML}" \
     -DpolicyScope="${POLICY_SCOPE}" \
     -DpolicyVersion="${POLICY_VERSION}" \
     -DbrmsgwTopic="${BRMSGW_TOPIC}" \
index dc64c3e..307d782 100644 (file)
@@ -5,6 +5,7 @@
 # ONAP
 # ================================================================================
 # Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved.
+# Modifications Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.
@@ -137,6 +138,18 @@ curl -k --silent --user @1b3rt:31nst31n -X PUT --header 'Content-Type: text/plai
 
 sleep 2
 
+echo
+echo "Inserting CCVPN Bandwidth On Demand Policy..."
+curl -k --silent --user @1b3rt:31nst31n -X PUT --header 'Content-Type: text/plain' -d '{
+        "closedLoopControlName": "ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b",
+        "controlLoopYaml": "controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b%0D%0A++trigger_policy%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++++name%3A+CCVPNBandwidthOnDemand%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++recipe%3A+BandwidthOnDemand%0D%0A++++target%3A%0D%0A++++++type%3A+VM%0D%0A++++retry%3A+3%0D%0A++++timeout%3A+1200%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard",
+        "policyName": "ccvpnBandwidthOnDemand",
+        "policyScope": "DCAE",
+        "policyVersion": "1.2.0"
+}' "https://localhost:9696/policy/pdp/engine/topics/sources/ueb/${BRMSGW_TOPIC}/events" | python -m json.tool
+
+sleep 2
+
 echo
 echo "Policy insertions completed."
 echo
index 74122b8..9830848 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2018 Huawei. All rights reserved.
+ * Copyright (C) 2018-2019 Huawei Technologies Co., Ltd. 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.
@@ -38,6 +38,12 @@ public class SdncHealRequest implements Serializable {
     @SerializedName("network-information")
     private SdncHealNetworkInfo networkInfo;
 
+    @SerializedName("vnf-information")
+    private SdncHealVnfInfo vnfInfo;
+
+    @SerializedName("vf-module-request-input")
+    private SdncHealVfModuleRequestInput vfModuleRequestInput;
+
     public SdncHealRequest() {
         // Default constructor for SdncHealRequest
     }
@@ -74,4 +80,19 @@ public class SdncHealRequest implements Serializable {
         this.networkInfo = networkInfo;
     }
 
+    public SdncHealVnfInfo getVnfInfo() {
+        return vnfInfo;
+    }
+
+    public void setVnfInfo(SdncHealVnfInfo vnfInfo) {
+        this.vnfInfo = vnfInfo;
+    }
+
+    public SdncHealVfModuleRequestInput getVfModuleRequestInput() {
+        return vfModuleRequestInput;
+    }
+
+    public void setVfModuleRequestInput(SdncHealVfModuleRequestInput input) {
+        this.vfModuleRequestInput = input;
+    }
 }
diff --git a/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleParameter.java b/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleParameter.java
new file mode 100644 (file)
index 0000000..0ad7723
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.sdnc;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+public class SdncHealVfModuleParameter implements Serializable {
+
+    private static final long serialVersionUID = 3208673205100673119L;
+
+    @SerializedName("name")
+    private String name;
+
+    @SerializedName("value")
+    private String value;
+
+    public SdncHealVfModuleParameter() {
+        // Default constructor for SdncHealVfModuleParameter
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}
diff --git a/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleParametersInfo.java b/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleParametersInfo.java
new file mode 100644 (file)
index 0000000..0463c6a
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.sdnc;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SdncHealVfModuleParametersInfo implements Serializable {
+
+    private static final long serialVersionUID = 3208673205100673119L;
+
+    @SerializedName("param")
+    private List<SdncHealVfModuleParameter> parameters;
+
+    public SdncHealVfModuleParametersInfo() {
+        // Default constructor for SdncHealVfModuleParametersInfo
+        parameters = new LinkedList<>();
+    }
+
+    public List<SdncHealVfModuleParameter> getParameters() {
+        return parameters;
+    }
+
+    public void setParameters(List<SdncHealVfModuleParameter> parameters) {
+        this.parameters = parameters;
+    }
+
+    public void addParameters(SdncHealVfModuleParameter parameter) {
+        parameters.add(parameter);
+    }
+}
diff --git a/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleRequestInput.java b/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVfModuleRequestInput.java
new file mode 100644 (file)
index 0000000..98cfc7e
--- /dev/null
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.sdnc;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+public class SdncHealVfModuleRequestInput implements Serializable {
+
+    private static final long serialVersionUID = 3208673205100673119L;
+
+    @SerializedName("vf-module-input-parameters")
+    private SdncHealVfModuleParametersInfo vfModuleParametersInfo;
+
+    public SdncHealVfModuleRequestInput() {
+        // Default constructor for SdncHealVfModuleRequestInput
+    }
+
+    public SdncHealVfModuleParametersInfo getVfModuleParametersInfo() {
+        return vfModuleParametersInfo;
+    }
+
+    public void setVfModuleParametersInfo(SdncHealVfModuleParametersInfo info) {
+        this.vfModuleParametersInfo = info;
+    }
+}
diff --git a/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVnfInfo.java b/controlloop/common/model-impl/sdnc/src/main/java/org/onap/policy/sdnc/SdncHealVnfInfo.java
new file mode 100644 (file)
index 0000000..16a6203
--- /dev/null
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.sdnc;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+public class SdncHealVnfInfo implements Serializable {
+
+    private static final long serialVersionUID = 3208673205100673119L;
+
+    @SerializedName("vnf-id")
+    private String vnfId;
+
+    public SdncHealVnfInfo() {
+        // Default constructor for SdncHealVnfInfo
+    }
+
+    public String getVnfId() {
+        return vnfId;
+    }
+
+    public void setVnfId(String vnfId) {
+        this.vnfId = vnfId;
+    }
+}
index 9d8c979..c5ce6b2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ============LICENSE_START=======================================================
- * Copyright (C) 2018 Huawei. All rights reserved.
+ * Copyright (C) 2018-2019 Huawei Technologies Co., Ltd. All rights reserved.
  * ================================================================================
  * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd.
@@ -96,7 +96,7 @@ public final class SdncManager implements Runnable {
         responseError.setResponseOutput(responseOutput);
 
         headers.put("Accept", "application/json");
-        String sdncUrl = sdncUrlBase + "/GENERIC-RESOURCE-API:network-topology-operation";
+        String sdncUrl = sdncUrlBase + sdncRequest.getUrl();
 
         try {
             String sdncRequestJson = Serialization.gsonPretty.toJson(sdncRequest);
index ad824f6..7590c0d 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2018 Huawei. All rights reserved.
+ * Copyright (C) 2018-2019 Huawei Technologies Co., Ltd. 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.
@@ -29,6 +29,7 @@ public class SdncRequest implements Serializable {
     // These fields are not serialized and not part of JSON
     private transient String nsInstanceId;
     private transient UUID requestId;
+    private transient String url;
 
     @SerializedName("input")
     private SdncHealRequest healRequest;
@@ -60,4 +61,12 @@ public class SdncRequest implements Serializable {
     public void setHealRequest(SdncHealRequest healRequest) {
         this.healRequest = healRequest;
     }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
 }
index 47bdf01..4b22fa3 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * simulators
  * ================================================================================
- * Copyright (C) 2018 Huawei. All rights reserved.
+ * Copyright (C) 2018-2019 Huawei Technologies Co., Ltd. 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.
@@ -55,4 +55,24 @@ public class SdncSimulatorJaxRs {
         response.setResponseOutput(responseOutput);
         return Serialization.gsonPretty.toJson(response);
     }
+
+    /**
+     * SDNC vnf topology operation.
+     *
+     * @return the response
+     */
+    @POST
+    @Path("/GENERIC-RESOURCE-API:vnf-topology-operation")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces("application/json")
+    public String sdncVnfTopologyOperation() {
+        final SdncResponse response = new SdncResponse();
+        response.setRequestId(UUID.randomUUID().toString());
+        SdncResponseOutput responseOutput = new SdncResponseOutput();
+        responseOutput.setResponseCode("200");
+        responseOutput.setAckFinalIndicator("Y");
+        responseOutput.setSvcRequestId(UUID.randomUUID().toString());
+        response.setResponseOutput(responseOutput);
+        return Serialization.gsonPretty.toJson(response);
+    }
 }
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/CCVPNBW.yaml b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/CCVPNBW.yaml
new file mode 100644 (file)
index 0000000..7b296ce
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.
+controlLoop:
+  version: 2.0.0
+  controlLoopName: ${ccvpnBwClosedLoopControlName}
+  trigger_policy: unique-policy-id-16-Reroute
+  timeout: 3600
+  abatement: false
+
+policies:
+  - id: unique-policy-id-16-BandwidthOnDemand
+    name: CCVPNBandwidthOnDemand
+    description:
+    actor: SDNC
+    recipe: BandwidthOnDemand
+    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
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.bw.onset.json b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.bw.onset.json
new file mode 100644 (file)
index 0000000..b2dbb7b
--- /dev/null
@@ -0,0 +1,25 @@
+{
+  "closedLoopEventClient": "DCAE.HolmesInstance",
+  "policyVersion": "2.0.0",
+  "policyName": "CCVPNBandwidthOnDemand",
+  "policyScope": "service=SITEService,type=SampleType,closedLoopControlName=CL-CCVPN-d925ed73-8231-4d02-9545-db4e101f88f8",
+  "target_type": "VM",
+  "AAI": {
+    "vserver.vserver-name" : "TBD",
+    "globalSubscriberId" : "e151059a-d924-4629-845f-264db19e50b4",
+    "serviceType" : "service-ccvpn",
+    "service-instance.service-instance-id" : "298dad9933BBBasa",
+    "vserver.is-closed-loop-disabled" : "false",
+    "vserver.prov-status":"ACTIVE",
+    "bandwidth" : "500",
+    "bandwidth-change-time":"20190321-10:59:32:321",
+    "vnfId": "2fbf0f93-c46e-42ed-9a9b-68aaa09ea11d"
+  },
+  "closedLoopAlarmStart": "1484677482204798",
+  "closedLoopEventStatus": "ONSET",
+  "closedLoopControlName": "${ccvpnBwClosedLoopControlName}",
+  "version": "1.0.2",
+  "target": "vserver.vserver-name",
+  "requestID": "97964e10-686e-4790-8c45-bdfa61df880f",
+  "from": "DCAE"
+}
\ No newline at end of file
index 18151b5..e27e3e4 100644 (file)
@@ -4,6 +4,7 @@
   archetype-closed-loop-demo-rules
   ================================================================================
   Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+  Modifications Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.
      <requiredProperty key="ccvpnControlLoopYaml">
          <defaultValue>controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b%0D%0A++trigger_policy%3A+unique-policy-id-16-Reroute%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-Reroute%0D%0A++++name%3A+Connectivity Reroute%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++recipe%3A+Reroute%0D%0A++++target%3A%0D%0A++++++type%3A+VM%0D%0A++++retry%3A+3%0D%0A++++timeout%3A+1200%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard</defaultValue>
      </requiredProperty>
+     <requiredProperty key="ccvpnBwClosedLoopControlName">
+     <defaultValue>ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b</defaultValue>
+     </requiredProperty>
+     <requiredProperty key="ccvpnBwPolicyName">
+         <defaultValue>CCVPNBandwidthOnDemand</defaultValue>
+     </requiredProperty>
+     <requiredProperty key="ccvpnBwControlLoopYaml">
+         <defaultValue>controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b%0D%0A++trigger_policy%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++++name%3A+CCVPNBandwidthOnDemand%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++recipe%3A+BandwidthOnDemand%0D%0A++++target%3A%0D%0A++++++type%3A+VM%0D%0A++++retry%3A+3%0D%0A++++timeout%3A+1200%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard</defaultValue>
+     </requiredProperty>
      <requiredProperty key="policyScope">
        <defaultValue>DCAE</defaultValue>
      </requiredProperty>     
diff --git a/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/CCVPNBW.yaml b/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/CCVPNBW.yaml
new file mode 100644 (file)
index 0000000..7b296ce
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.
+controlLoop:
+  version: 2.0.0
+  controlLoopName: ${ccvpnBwClosedLoopControlName}
+  trigger_policy: unique-policy-id-16-Reroute
+  timeout: 3600
+  abatement: false
+
+policies:
+  - id: unique-policy-id-16-BandwidthOnDemand
+    name: CCVPNBandwidthOnDemand
+    description:
+    actor: SDNC
+    recipe: BandwidthOnDemand
+    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
diff --git a/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/ccvpnbw.brmsgw.params.json b/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/ccvpnbw.brmsgw.params.json
new file mode 100644 (file)
index 0000000..6425b40
--- /dev/null
@@ -0,0 +1,7 @@
+{
+       "closedLoopControlName": "${ccvpnBwClosedLoopControlName}",
+       "controlLoopYaml": "${ccvpnBwControlLoopYaml}",
+       "policyName": "${ccvpnBwPolicyName}",
+       "policyScope": "${policyScope}",
+       "policyVersion": "${policyVersion}"
+}
\ No newline at end of file
diff --git a/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.bw.onset.json b/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.bw.onset.json
new file mode 100644 (file)
index 0000000..b2dbb7b
--- /dev/null
@@ -0,0 +1,25 @@
+{
+  "closedLoopEventClient": "DCAE.HolmesInstance",
+  "policyVersion": "2.0.0",
+  "policyName": "CCVPNBandwidthOnDemand",
+  "policyScope": "service=SITEService,type=SampleType,closedLoopControlName=CL-CCVPN-d925ed73-8231-4d02-9545-db4e101f88f8",
+  "target_type": "VM",
+  "AAI": {
+    "vserver.vserver-name" : "TBD",
+    "globalSubscriberId" : "e151059a-d924-4629-845f-264db19e50b4",
+    "serviceType" : "service-ccvpn",
+    "service-instance.service-instance-id" : "298dad9933BBBasa",
+    "vserver.is-closed-loop-disabled" : "false",
+    "vserver.prov-status":"ACTIVE",
+    "bandwidth" : "500",
+    "bandwidth-change-time":"20190321-10:59:32:321",
+    "vnfId": "2fbf0f93-c46e-42ed-9a9b-68aaa09ea11d"
+  },
+  "closedLoopAlarmStart": "1484677482204798",
+  "closedLoopEventStatus": "ONSET",
+  "closedLoopControlName": "${ccvpnBwClosedLoopControlName}",
+  "version": "1.0.2",
+  "target": "vserver.vserver-name",
+  "requestID": "97964e10-686e-4790-8c45-bdfa61df880f",
+  "from": "DCAE"
+}
\ No newline at end of file
diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/CcvpnBwControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/CcvpnBwControlLoopTest.java
new file mode 100644 (file)
index 0000000..395ecc2
--- /dev/null
@@ -0,0 +1,373 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2019 AT&T Intellectual Property.
+ * ================================================================================
+ * 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.charset.StandardCharsets;
+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.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.EventProtocolParams;
+import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
+import org.onap.policy.drools.system.PolicyController;
+import org.onap.policy.drools.system.PolicyEngine;
+import org.onap.policy.drools.utils.logging.LoggerUtil;
+import org.onap.policy.sdnc.SdncRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CcvpnBwControlLoopTest implements TopicListener {
+
+    private static final Logger logger = LoggerFactory.getLogger(CcvpnBwControlLoopTest.class);
+
+    private static List<? extends TopicSink> noopTopics;
+
+    private static KieSession kieSession;
+    private static SupportUtil.Pair<ControlLoopPolicy, String> pair;
+
+    static {
+        /* Set environment properties */
+        SupportUtil.setAaiProps();
+        SupportUtil.setSdncProps();
+        LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "INFO");
+    }
+
+    /**
+     * Setup the 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, "POLICY-CL-MGT");
+        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(EventProtocolParams.builder()
+                .groupId("junit.groupId")
+                .artifactId("junit.artifactId")
+                .topic("POLICY-CL-MGT")
+                .eventClass("org.onap.policy.controlloop.VirtualControlLoopNotification")
+                .protocolFilter(new JsonProtocolFilter())
+                .modelClassLoaderHash(1111));
+
+        try {
+            SupportUtil.buildAaiSim();
+            SupportUtil.buildSdncSim();
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        /*
+         *
+         * Start the kie session
+         */
+        try {
+            kieSession = startSession(
+                    "../archetype-cl-amsterdam/src/main/resources/archetype-resources/"
+                    + "src/main/resources/__closedLoopControlName__.drl",
+                    "src/test/resources/yaml/policy_ControlLoop_CCVPN_BW.yaml", "type=operational",
+                    "BandwidthOnDemand", "2.0.0");
+        } catch (IOException e) {
+            e.printStackTrace();
+            logger.debug("Could not create kieSession");
+            fail("Could not create kieSession");
+        }
+    }
+
+    /**
+     * Tear down the simulator.
+     */
+    @AfterClass
+    public static void tearDownSimulator() {
+
+        /*
+         * Gracefully shut down the kie session
+         */
+        kieSession.dispose();
+
+        PolicyEngine.manager.stop();
+        HttpServletServer.factory.destroy();
+        PolicyController.factory.shutdown();
+        TopicEndpoint.manager.shutdown();
+    }
+
+    @Test
+    public void successTest() throws IOException {
+
+        /*
+         * 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);
+        }
+
+        /*
+         * Simulate an onset event the policy engine will receive from DCAE to kick off processing
+         * through the rules
+         */
+        sendEvent(pair.first);
+
+        kieSession.fireUntilHalt();
+
+        // allow object clean-up
+        kieSession.fireAllRules();
+
+        /*
+         * The only fact in memory should be Params
+         */
+        assertEquals(1, kieSession.getFactCount());
+
+        /*
+         * Print what's left in memory
+         */
+        dumpFacts(kieSession);
+    }
+
+    @Test
+    public void nullRequestTest() throws IOException {
+
+        /*
+         * 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);
+        }
+
+        /*
+         * Simulate an onset event the policy engine will receive from DCAE to kick off processing
+         * through the rules
+         */
+
+        VirtualControlLoopEvent event = new VirtualControlLoopEvent();
+        event.setClosedLoopControlName(pair.first.getControlLoop().getControlLoopName());
+        event.setRequestId(UUID.randomUUID());
+        event.setClosedLoopEventClient("DCAE.HolmesInstance");
+        event.setTargetType(ControlLoopTargetType.VM);
+        event.setTarget("vserver.vserver-name");
+        event.setFrom("DCAE");
+        event.setClosedLoopAlarmStart(Instant.now());
+        event.setAai(new HashMap<String, String>());
+        event.getAai().put("vserver.vserver-name", "nullRequest");
+        event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
+        kieSession.insert(event);
+
+        kieSession.fireUntilHalt();
+
+        // allow object clean-up
+        kieSession.fireAllRules();
+
+        /*
+         * The only fact in memory should be Params
+         */
+        assertEquals(1, kieSession.getFactCount());
+
+        /*
+         * Print what's left in memory
+         */
+        dumpFacts(kieSession);
+    }
+
+    /**
+     * 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 IO Exception
+     */
+    private static KieSession startSession(String droolsTemplate, String yamlFile, String policyScope,
+            String policyName, String policyVersion) throws IOException {
+
+        /*
+         * Load policies from yaml
+         */
+        pair = SupportUtil.loadYaml(yamlFile);
+        assertNotNull(pair);
+        assertNotNull(pair.first);
+        assertNotNull(pair.first.getControlLoop());
+        assertNotNull(pair.first.getControlLoop().getControlLoopName());
+        assertTrue(pair.first.getControlLoop().getControlLoopName().length() > 0);
+
+        /*
+         * Construct a kie session
+         */
+        final KieSession kieSession = SupportUtil.buildContainer(droolsTemplate,
+                pair.first.getControlLoop().getControlLoopName(),
+                policyScope, policyName, policyVersion, URLEncoder.encode(pair.second,
+                                                                          StandardCharsets.UTF_8.name()));
+
+        /*
+         * Retrieve the Policy Engine
+         */
+
+        logger.debug("============");
+        logger.debug(URLEncoder.encode(pair.second, StandardCharsets.UTF_8.name()));
+        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,
+                    VirtualControlLoopNotification.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());
+                assertTrue(notification.getMessage().toLowerCase().endsWith("permit"));
+            } else if (policyName.endsWith("GUARD_PERMITTED")) {
+                logger.debug("Rule Fired: " + notification.getPolicyName());
+                assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.getNotification()));
+                assertNotNull(notification.getMessage());
+                assertTrue(notification.getMessage().startsWith("actor=SDNC"));
+            } else if (policyName.endsWith("OPERATION.TIMEOUT")) {
+                logger.debug("Rule Fired: " + notification.getPolicyName());
+                kieSession.halt();
+                logger.debug("The operation timed out");
+                fail("Operation Timed Out");
+            } else if (policyName.endsWith("SDNC.RESPONSE")) {
+                logger.debug("Rule Fired: " + notification.getPolicyName());
+                assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.getNotification()));
+                assertNotNull(notification.getMessage());
+                assertTrue(notification.getMessage().startsWith("actor=SDNC"));
+            } else if (policyName.endsWith("EVENT.MANAGER")) {
+                logger.debug("Rule Fired: " + notification.getPolicyName());
+                if ("nullRequest".equals(notification.getAai().get("vserver.vserver-name"))) {
+                    assertEquals(ControlLoopNotificationType.FINAL_FAILURE, notification.getNotification());
+                } else {
+                    assertEquals(ControlLoopNotificationType.FINAL_SUCCESS, notification.getNotification());
+                }
+                kieSession.halt();
+            } else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) {
+                logger.debug("Rule Fired: " + notification.getPolicyName());
+                kieSession.halt();
+                logger.debug("The control loop timed out");
+                fail("Control Loop Timed Out");
+            }
+        } else if (obj instanceof SdncRequest) {
+            logger.debug("\n============ SDNC received the request!!! ===========\n");
+        }
+    }
+
+    /**
+     * 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 policy the controlLoopName comes from the policy
+     */
+    protected void sendEvent(ControlLoopPolicy policy) {
+        VirtualControlLoopEvent event = new VirtualControlLoopEvent();
+        event.setClosedLoopControlName(policy.getControlLoop().getControlLoopName());
+        event.setRequestId(UUID.randomUUID());
+        event.setClosedLoopEventClient("DCAE.HolmesInstance");
+        event.setTargetType(ControlLoopTargetType.VM);
+        event.setTarget("vserver.vserver-name");
+        event.setFrom("DCAE");
+        event.setClosedLoopAlarmStart(Instant.now());
+        event.setAai(new HashMap<String, String>());
+        event.getAai().put("vserver.vserver-name", "TBD");
+        event.getAai().put("globalSubscriberId", "e151059a-d924-4629-845f-264db19e50b4");
+        event.getAai().put("serviceType", "siteService");
+        event.getAai().put("service-instance.service-instance-id", "service-instance-id-example-1");
+        event.getAai().put("vserver.is-closed-loop-disabled", "false");
+        event.getAai().put("vserver.prov-status", "ACTIVE");
+        event.getAai().put("bandwidth", "500");
+        event.getAai().put("bandwidth-change-time", "20190326-05:20:38:668");
+        event.getAai().put("vnfId", "vnf-id");
+        event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET);
+        kieSession.insert(event);
+    }
+
+    /**
+     * Dumps the kie session facts.
+     *
+     * @param kieSession input session
+     */
+    public static void dumpFacts(KieSession kieSession) {
+        logger.debug("Fact Count: " + kieSession.getFactCount());
+        for (FactHandle handle : kieSession.getFactHandles()) {
+            logger.debug("FACT: " + handle);
+        }
+    }
+}
\ No newline at end of file
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_CCVPN_BW.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_CCVPN_BW.yaml
new file mode 100644 (file)
index 0000000..f994d41
--- /dev/null
@@ -0,0 +1,37 @@
+# Copyright (C) 2019 Huawei Technologies Co., Ltd. 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.
+controlLoop:
+  version: 2.0.0
+  controlLoopName: ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b
+  trigger_policy: unique-policy-id-16-BandwidthOnDemand
+  timeout: 3600
+  abatement: false
+
+policies:
+  - id: unique-policy-id-16-BandwidthOnDemand
+    name: CCVPNBandwidthOnDemand
+    description:
+    actor: SDNC
+    recipe: BandwidthOnDemand
+    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
+