Adding missing tests 43/34843/1
authorDenes Nemeth <denes.nemeth@nokia.com>
Thu, 8 Mar 2018 20:44:02 +0000 (21:44 +0100)
committerDenes Nemeth <denes.nemeth@nokia.com>
Thu, 8 Mar 2018 20:44:02 +0000 (21:44 +0100)
Change-Id: I2b0de4c101535259f133436d6997ae393ba6c8ef
Signed-off-by: Denes Nemeth <denes.nemeth@nokia.com>
Issue-ID: VFC-728

19 files changed:
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/api/INotificationSender.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/OnapVnfdBuilder.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/ConverterApi.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/util/SystemFunctions.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/JobManager.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/LifecycleManager.java
nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/LifecycleChangeNotificationManager.java
nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestGenericExternalSystemInfoProvider.java
nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcGrantManager.java
nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcNotificationSender.java
nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/TestOnapVnfdBuilder.java
nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestConverterApi.java
nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestLifecycleManager.java
nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java
nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.cbam.yaml
nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.onap.yaml
nokiav2/driver/src/test/resources/unittests/vnfd.scale.yaml

index c601f5a..55e9cca 100644 (file)
@@ -19,6 +19,8 @@ import com.nokia.cbam.lcm.v32.model.OperationExecution;
 import com.nokia.cbam.lcm.v32.model.VnfLifecycleChangeNotification;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.ReportedAffectedConnectionPoints;
 
+import java.util.Optional;
+
 /**
  * Responsible for processing the preprocessed notification from CBAM and making the changes
  * based on the notification in various ONAP sub systems.
@@ -33,5 +35,5 @@ public interface INotificationSender {
      * @param affectedConnectionPoints the affected connection points during the operation
      * @param vimId                    the identifier of the VIM in ONAP
      */
-    void processNotification(VnfLifecycleChangeNotification receivedNotification, OperationExecution operationExecution, ReportedAffectedConnectionPoints affectedConnectionPoints, String vimId);
+    void processNotification(VnfLifecycleChangeNotification receivedNotification, OperationExecution operationExecution, Optional<ReportedAffectedConnectionPoints> affectedConnectionPoints, String vimId);
 }
index f283672..1d9ef8d 100644 (file)
@@ -26,7 +26,6 @@ import com.nokia.cbam.lcm.v32.model.VnfInfo;
 import com.nokia.cbam.lcm.v32.model.VnfcResourceInfo;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IGrantManager;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions;
-import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CatalogManager;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider;
 import org.onap.vnfmdriver.model.*;
@@ -40,6 +39,7 @@ import java.util.*;
 
 import static com.nokia.cbam.lcm.v32.model.InstantiationState.INSTANTIATED;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
+import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.child;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION;
 import static org.onap.vnfmdriver.model.OperationType.TERMINAL;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -103,7 +103,7 @@ public class VfcGrantManager implements IGrantManager {
             try {
                 grantRequest = buildGrantRequest(vnfmId, vimId, onapVnfdId, jobId, TERMINAL);
                 grantRequest.setVnfInstanceId(vnfId);
-                addVnfsToGrant(vnf, grantRequest);
+                addVnfcsToGrant(vnf, grantRequest);
             } catch (Exception e) {
                 throw buildFatalFailure(logger, "Unable to prepare grant request for termination", e);
             }
@@ -111,7 +111,8 @@ public class VfcGrantManager implements IGrantManager {
         }
     }
 
-    private void addVnfsToGrant(VnfInfo vnf, GrantVNFRequest grantRequest) {
+    private void addVnfcsToGrant(VnfInfo vnf, GrantVNFRequest grantRequest) {
+        //VNF is instantiated but has no VNFC
         if (vnf.getInstantiatedVnfInfo().getVnfcResourceInfo() != null) {
             for (VnfcResourceInfo vnfc : vnf.getInstantiatedVnfInfo().getVnfcResourceInfo()) {
                 ResourceChange resourceChange = new ResourceChange();
@@ -164,11 +165,11 @@ public class VfcGrantManager implements IGrantManager {
 
     private Set<ResourceChange> calculateResourceChangeDuringInstantiate(String vnfdContent, String instantiationLevelId) {
         JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject();
-        JsonObject capabilities = CbamUtils.child(CbamUtils.child(CbamUtils.child(root, "topology_template"), "substitution_mappings"), "capabilities");
-        JsonObject deploymentFlavorProperties = CbamUtils.child(CbamUtils.child(capabilities, "deployment_flavour"), "properties");
-        JsonObject instantiationLevels = CbamUtils.child(deploymentFlavorProperties, "instantiation_levels");
+        JsonObject capabilities = child(child(child(root, "topology_template"), "substitution_mappings"), "capabilities");
+        JsonObject deploymentFlavorProperties = child(child(capabilities, "deployment_flavour"), "properties");
+        JsonObject instantiationLevels = child(deploymentFlavorProperties, "instantiation_levels");
         Set<ResourceChange> resourceChanges = new HashSet<>();
-        for (Map.Entry<String, JsonElement> vdu_level : CbamUtils.child(CbamUtils.child(instantiationLevels, instantiationLevelId), ("vdu_levels")).entrySet()) {
+        for (Map.Entry<String, JsonElement> vdu_level : child(child(instantiationLevels, instantiationLevelId), ("vdu_levels")).entrySet()) {
             JsonElement numberOfInstances = vdu_level.getValue().getAsJsonObject().get("number_of_instances");
             for (int i = 0; i < numberOfInstances.getAsLong(); i++) {
                 ResourceChange resourceChange = new ResourceChange();
@@ -184,11 +185,11 @@ public class VfcGrantManager implements IGrantManager {
     private Set<ResourceChange> calculateResourceChangeDuringScaling(String vnfdContent, String aspectId, int steps) {
         JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject();
         Set<ResourceChange> resourceChanges = new HashSet<>();
-        JsonArray policies = CbamUtils.child(root, "topology_template").getAsJsonObject().get("policies").getAsJsonArray();
+        JsonArray policies = child(root, "topology_template").getAsJsonObject().get("policies").getAsJsonArray();
         for (JsonElement policy : policies) {
             if ("heat_mapping".equals(policy.getAsJsonObject().entrySet().iterator().next().getKey())) {
                 JsonObject aspects = policy.getAsJsonObject().entrySet().iterator().next().getValue().getAsJsonObject().get("properties").getAsJsonObject().get("aspects").getAsJsonObject();
-                JsonObject aspect = aspects.get(aspectId).getAsJsonObject();
+                JsonObject aspect = child(aspects, aspectId);
                 if (aspect.has("vdus")) {
                     addChangesForAspect(steps, resourceChanges, aspect);
                 }
index 32c3f90..50f6221 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc;
 
-import com.google.common.base.Optional;
 import com.google.gson.Gson;
 import com.nokia.cbam.lcm.v32.model.OperationExecution;
 import com.nokia.cbam.lcm.v32.model.ScaleVnfRequest;
@@ -23,6 +22,7 @@ import com.nokia.cbam.lcm.v32.model.VnfLifecycleChangeNotification;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.INotificationSender;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties;
+import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.LifecycleChangeNotificationManager;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.ReportedAffectedConnectionPoints;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.ReportedAffectedCp;
 import org.onap.vnfmdriver.model.*;
@@ -32,10 +32,11 @@ import org.springframework.context.annotation.Conditional;
 import org.springframework.stereotype.Component;
 
 import java.util.ArrayList;
+import java.util.Optional;
 
-import static com.google.common.base.Optional.of;
 import static com.google.common.collect.Iterables.tryFind;
 import static com.nokia.cbam.lcm.v32.model.ScaleDirection.IN;
+import static java.util.Optional.of;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.SEPARATOR;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.JobManager.extractOnapJobId;
@@ -58,22 +59,18 @@ public class VfcNotificationSender implements INotificationSender {
     }
 
     @Override
-    public void processNotification(VnfLifecycleChangeNotification recievedNotification, OperationExecution operationExecution, ReportedAffectedConnectionPoints affectedCps, String vimId) {
+    public void processNotification(VnfLifecycleChangeNotification recievedNotification, OperationExecution operationExecution, Optional<ReportedAffectedConnectionPoints> affectedCps, String vimId) {
         VNFLCMNotification notificationToSend = new VNFLCMNotification();
         notificationToSend.setJobId(extractOnapJobId(operationExecution.getOperationParams()));
         notificationToSend.setOperation(getOperation(operationExecution, recievedNotification.getOperation()));
         notificationToSend.setVnfInstanceId(recievedNotification.getVnfInstanceId());
-        switch (recievedNotification.getStatus()) {
-            case FINISHED:
-            case FAILED:
-                notificationToSend.setStatus(VnfLcmNotificationStatus.RESULT);
-                addAffectedVirtualLinks(recievedNotification, notificationToSend);
-                addAffectedVnfcs(vimId, recievedNotification.getVnfInstanceId(), notificationToSend, recievedNotification);
-                addAffectedCps(vimId, notificationToSend, affectedCps);
-                break;
-            default:
-                notificationToSend.setStatus(VnfLcmNotificationStatus.START);
-                break;
+        if (LifecycleChangeNotificationManager.isTerminal(recievedNotification.getStatus())) {
+            notificationToSend.setStatus(VnfLcmNotificationStatus.RESULT);
+            addAffectedVirtualLinks(recievedNotification, notificationToSend);
+            addAffectedVnfcs(vimId, recievedNotification.getVnfInstanceId(), notificationToSend, recievedNotification);
+            addAffectedCps(vimId, notificationToSend, affectedCps);
+        } else {
+            notificationToSend.setStatus(VnfLcmNotificationStatus.START);
         }
         sendNotification(notificationToSend);
     }
@@ -81,7 +78,7 @@ public class VfcNotificationSender implements INotificationSender {
     private void sendNotification(VNFLCMNotification notification) {
         try {
             if (logger.isInfoEnabled()) {
-                logger.info("Sending LCN: " + new Gson().toJson(notification));
+                logger.info("Sending LCN: {}", new Gson().toJson(notification));
             }
             vfcRestApiProvider.getNsLcmApi().vNFLCMNotification(driverProperties.getVnfmId(), notification.getVnfInstanceId(), notification);
         } catch (Exception e) {
@@ -143,28 +140,31 @@ public class VfcNotificationSender implements INotificationSender {
     }
 
     private Optional<VnfCpNotificationType> getChangeType(ReportedAffectedConnectionPoints affectedCps, ReportedAffectedCp affectedCp) {
-        Optional<ReportedAffectedCp> cpBeforeOperation = tryFind(affectedCps.getPre(), pre -> affectedCp.getCpId().equals(pre.getCpId()));
-        Optional<ReportedAffectedCp> cpAfterOperation = tryFind(affectedCps.getPost(), post -> affectedCp.getCpId().equals(post.getCpId()));
+        com.google.common.base.Optional<ReportedAffectedCp> cpBeforeOperation = tryFind(affectedCps.getPre(), pre -> affectedCp.getCpId().equals(pre.getCpId()));
+        com.google.common.base.Optional<ReportedAffectedCp> cpAfterOperation = tryFind(affectedCps.getPost(), post -> affectedCp.getCpId().equals(post.getCpId()));
         if (cpBeforeOperation.isPresent() && cpAfterOperation.isPresent()) {
-            return cpAfterOperation.get().equals(cpBeforeOperation.get()) ? Optional.absent() : of(VnfCpNotificationType.CHANGED);
+            return cpAfterOperation.get().equals(cpBeforeOperation.get()) ? Optional.empty() : of(VnfCpNotificationType.CHANGED);
         } else {
             //the affected CP must be present in the pre or post
             return of((cpAfterOperation.isPresent() ? VnfCpNotificationType.ADDED : VnfCpNotificationType.REMOVED));
         }
     }
 
-    private void addAffectedCps(String vimId, VNFLCMNotification notificationToSend, ReportedAffectedConnectionPoints affectedCps) {
-        if (affectedCps != null) {
+    private void addAffectedCps(String vimId, VNFLCMNotification notificationToSend, Optional<ReportedAffectedConnectionPoints> affectedCps) {
+        if (affectedCps.isPresent()) {
             notificationToSend.setAffectedCp(new ArrayList<>());
-            for (ReportedAffectedCp pre : affectedCps.getPre()) {
-                Optional<VnfCpNotificationType> changeType = getChangeType(affectedCps, pre);
+            for (ReportedAffectedCp pre : affectedCps.get().getPre()) {
+                Optional<VnfCpNotificationType> changeType = getChangeType(affectedCps.get(), pre);
                 if (of(VnfCpNotificationType.REMOVED).equals(changeType)) {
                     addModifiedCp(vimId, notificationToSend, pre, changeType);
                 }
             }
-            for (ReportedAffectedCp post : affectedCps.getPost()) {
-                Optional<VnfCpNotificationType> changeType = getChangeType(affectedCps, post);
-                if (of(VnfCpNotificationType.ADDED).equals(changeType) || of(VnfCpNotificationType.CHANGED).equals(changeType)) {
+            for (ReportedAffectedCp post : affectedCps.get().getPost()) {
+                Optional<VnfCpNotificationType> changeType = getChangeType(affectedCps.get(), post);
+                if (of(VnfCpNotificationType.ADDED).equals(changeType)) {
+                    addModifiedCp(vimId, notificationToSend, post, changeType);
+                }
+                if (of(VnfCpNotificationType.CHANGED).equals(changeType)) {
                     addModifiedCp(vimId, notificationToSend, post, changeType);
                 }
             }
@@ -185,19 +185,18 @@ public class VfcNotificationSender implements INotificationSender {
     }
 
     private org.onap.vnfmdriver.model.OperationType getOperation(OperationExecution operationExecution, com.nokia.cbam.lcm.v32.model.OperationType type) {
-        switch (type) {
-            case TERMINATE:
-                return org.onap.vnfmdriver.model.OperationType.TERMINAL;
-            case INSTANTIATE:
-                return org.onap.vnfmdriver.model.OperationType.INSTANTIATE;
-            case SCALE:
-                if (IN == new Gson().fromJson(new Gson().toJson(operationExecution.getOperationParams()), ScaleVnfRequest.class).getType()) {
-                    return OperationType.SCALEIN;
-                } else {
-                    return OperationType.SCALEOUT;
-                }
-            default:
-                return org.onap.vnfmdriver.model.OperationType.HEAL;
+        if (type == com.nokia.cbam.lcm.v32.model.OperationType.TERMINATE) {
+            return OperationType.TERMINAL;
+        } else if (type == com.nokia.cbam.lcm.v32.model.OperationType.INSTANTIATE) {
+            return OperationType.INSTANTIATE;
+        } else if (type == com.nokia.cbam.lcm.v32.model.OperationType.SCALE) {
+            if (IN == new Gson().fromJson(new Gson().toJson(operationExecution.getOperationParams()), ScaleVnfRequest.class).getType()) {
+                return OperationType.SCALEIN;
+            } else {
+                return OperationType.SCALEOUT;
+            }
+        } else {
+            return OperationType.HEAL;
         }
     }
 
@@ -206,13 +205,12 @@ public class VfcNotificationSender implements INotificationSender {
     }
 
     private org.onap.vnfmdriver.model.VnfNotificationType getChangeType(com.nokia.cbam.lcm.v32.model.ChangeType changeType) {
-        switch (changeType) {
-            case ADDED:
-                return org.onap.vnfmdriver.model.VnfNotificationType.ADDED;
-            case REMOVED:
-                return org.onap.vnfmdriver.model.VnfNotificationType.REMOVED;
-            default: //case MODIFIED:
-                return org.onap.vnfmdriver.model.VnfNotificationType.MODIFIED;
+        if (changeType == com.nokia.cbam.lcm.v32.model.ChangeType.ADDED) {
+            return VnfNotificationType.ADDED;
+        } else if (changeType == com.nokia.cbam.lcm.v32.model.ChangeType.REMOVED) {
+            return VnfNotificationType.REMOVED;
+        } else {
+            return VnfNotificationType.MODIFIED;
         }
     }
 
index 03c27a8..e628458 100644 (file)
@@ -21,7 +21,7 @@ import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
-import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
 import org.yaml.snakeyaml.Yaml;
 
 import java.util.Map;
@@ -31,15 +31,16 @@ import java.util.regex.Pattern;
 
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.child;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.childElement;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Transforms a CBAM package into an ONAP package
  */
 public class OnapVnfdBuilder {
-
     public static final String DESCRIPTION = "description";
     public static final String PROPERTIES = "properties";
     public static final String REQUIREMENTS = "requirements";
+    private static Logger logger = getLogger(OnapVnfdBuilder.class);
 
     @VisibleForTesting
     static String indent(String content, int prefixSize) {
@@ -157,28 +158,36 @@ public class OnapVnfdBuilder {
         if (ecp.getAsJsonObject().has(REQUIREMENTS)) {
             String icpName = getIcpName(ecp.getAsJsonObject().get(REQUIREMENTS).getAsJsonArray());
             if (icpName != null) {
-                return buildIcp(name, icpName, nodes);
+                return buildEcpInternal(name, icpName, nodes);
+            } else {
+                logger.warn("The {} ecp does not have an internal connection point", name);
             }
+        } else {
+            logger.warn("The {} ecp does not have an requirements section", name);
         }
         return "";
     }
 
-    private String buildIcp(String name, String icpName, Set<Map.Entry<String, JsonElement>> nodes) {
+    private String buildEcpInternal(String ecpName, String icpName, Set<Map.Entry<String, JsonElement>> nodes) {
         JsonObject icpNode = get(icpName, nodes).getAsJsonObject();
         if (icpNode.has(REQUIREMENTS)) {
-            String vdu = getVdu(icpNode.getAsJsonObject().get(REQUIREMENTS).getAsJsonArray());
+            String vdu = getVduOfIcp(icpNode.getAsJsonObject().get(REQUIREMENTS).getAsJsonArray());
+            //internal connection point is bound to VDU
             if (vdu != null) {
-                return buildVduCpd(name, vdu, child(icpNode, PROPERTIES));
+                return buildVduCpd(ecpName, vdu, child(icpNode, PROPERTIES));
+            } else {
+                logger.warn("The {} internal connection point of the {} ecp does not have a VDU", icpName, ecpName);
             }
+        } else {
+            logger.warn("The {} internal connection point of the {} ecp does not have a requirements section", icpName, ecpName);
         }
         return "";
     }
 
-    @Nullable
-    private String getVdu(JsonArray requirements) {
+    private String getVduOfIcp(JsonArray icpRequirements) {
         String vdu = null;
-        for (int i = 0; i < requirements.size(); i++) {
-            JsonElement requirement = requirements.get(i);
+        for (int i = 0; i < icpRequirements.size(); i++) {
+            JsonElement requirement = icpRequirements.get(i);
             Map.Entry<String, JsonElement> next = requirement.getAsJsonObject().entrySet().iterator().next();
             String s = next.getKey();
             if ("virtual_binding".equals(s)) {
@@ -188,7 +197,6 @@ public class OnapVnfdBuilder {
         return vdu;
     }
 
-    @Nullable
     private String getIcpName(JsonArray requirements) {
         String icpName = null;
         for (int i = 0; i < requirements.size(); i++) {
@@ -202,18 +210,6 @@ public class OnapVnfdBuilder {
         return icpName;
     }
 
-    private String buildVduCpd(String name, String vdu, JsonObject properties) {
-        return indent(name + ":\n" +
-                "  type: tosca.nodes.nfv.VduCpd\n" +
-                "  " + PROPERTIES + ":\n" +
-                "    layer_protocol: " + childElement(properties, "layer_protocol").getAsString() + "\n" +
-                "    role: leaf\n" +
-                (properties.has(DESCRIPTION) ?
-                        "    description: " + childElement(properties, DESCRIPTION).getAsString() + "\n" : "") +
-                "  requirements:\n" +
-                "    - virtual_binding: " + vdu + "\n", 2);
-    }
-
     private String buildIcp(String name, JsonObject icp) {
         if (icp.has(REQUIREMENTS)) {
             JsonArray requirements = icp.get(REQUIREMENTS).getAsJsonArray();
@@ -225,42 +221,59 @@ public class OnapVnfdBuilder {
                 String s = next.getKey();
                 if ("virtual_binding".equals(s)) {
                     vdu = next.getValue().getAsString();
-
                 } else if ("virtual_link".equals(s)) {
                     vl = next.getValue().getAsString();
                 }
             }
-            if (vdu != null && vl != null) {
+            if (vdu == null) {
+                logger.warn("The {} internal connection point does not have a VDU", name);
+            } else if (vl == null) {
+                logger.warn("The {} internal connection point does not have a VL", name);
+            } else {
                 JsonObject properties = child(icp, PROPERTIES);
-                return "    " + name + ":\n" +
-                        "      type: tosca.nodes.nfv.VduCpd\n" +
-                        "      " + PROPERTIES + ":\n" +
-                        "        layer_protocol: " + childElement(properties, "layer_protocol").getAsString() + "\n" +
-                        "        role: leaf\n" + (properties.has(DESCRIPTION) ?
-                        "        description: " + childElement(properties, DESCRIPTION).getAsString() + "\n" : "") +
-                        "      requirements:\n" +
-                        "        - virtual_binding: " + vdu + "\n" +
-                        "        - virtual_link: " + vl + "\n";
+                return indent(name + ":\n" +
+                        "  type: tosca.nodes.nfv.VduCpd\n" +
+                        "  " + PROPERTIES + ":\n" +
+                        "    layer_protocol: " + childElement(properties, "layer_protocol").getAsString() + "\n" +
+                        "    role: leaf\n" + (properties.has(DESCRIPTION) ?
+                        "    description: " + childElement(properties, DESCRIPTION).getAsString() + "\n" : "") +
+                        "  requirements:\n" +
+                        "    - virtual_binding: " + vdu + "\n" +
+                        "    - virtual_link: " + vl + "\n", 2);
             }
+        } else {
+            logger.warn("The {} internal connection point does not have a requirements section", name);
         }
         return "";
     }
 
+    private String buildVduCpd(String name, String vdu, JsonObject properties) {
+        return indent(name + ":\n" +
+                "  type: tosca.nodes.nfv.VduCpd\n" +
+                "  " + PROPERTIES + ":\n" +
+                "    layer_protocol: " + childElement(properties, "layer_protocol").getAsString() + "\n" +
+                "    role: leaf\n" +
+                (properties.has(DESCRIPTION) ?
+                        "    description: " + childElement(properties, DESCRIPTION).getAsString() + "\n" : "") +
+                "  requirements:\n" +
+                "    - virtual_binding: " + vdu + "\n", 2);
+    }
+
     private String buildVolume(String nodeName, JsonObject volume) {
-        return "    " + nodeName + ":\n" +
-                "      type: tosca.nodes.nfv.VDU.VirtualStorage\n" +
-                "      properties:\n" +
-                "        id: " + nodeName + "\n" +
-                "        type_of_storage: volume\n" +
-                "        size_of_storage: " + childElement(child(volume, PROPERTIES), "size_of_storage").getAsString() + "\n";
+        return indent(nodeName + ":\n" +
+                "  type: tosca.nodes.nfv.VDU.VirtualStorage\n" +
+                "  properties:\n" +
+                "    id: " + nodeName + "\n" +
+                "    type_of_storage: volume\n" +
+                "    size_of_storage: " + childElement(child(volume, PROPERTIES), "size_of_storage").getAsString() + "\n", 2);
     }
 
     private String buildVl(String name) {
-        return "    " + name + ":\n" +
-                "      type: tosca.nodes.nfv.VnfVirtualLinkDesc\n" +
-                "      properties:\n" +
-                "        vl_flavours:\n" +
-                "          flavours:\n" +
-                "            flavourId: notUsed\n";
+        return indent(name + ":\n" +
+                "  type: tosca.nodes.nfv.VnfVirtualLinkDesc\n" +
+                "  properties:\n" +
+                "    vl_flavours:\n" +
+                "      flavours:\n" +
+                "        flavourId: notUsed\n", 2);
     }
 }
index 8eb2007..790ac05 100644 (file)
@@ -68,7 +68,7 @@ public class ConverterApi {
         byte[] convertedPackage;
         try {
             convertedPackage = vnfPackageConverter.covert(new ByteArrayInputStream(content));
-        } catch (IOException e) {
+        } catch (Exception e) {
             throw buildFatalFailure(logger, "Unable to convert VNF package", e);
         }
         httpResponse.addHeader(CONTENT_TYPE, APPLICATION_OCTET_STREAM.getMimeType());
index 2aba46b..94cb404 100644 (file)
@@ -41,6 +41,8 @@ import static com.google.common.base.Splitter.on;
 import static com.google.common.collect.Iterables.find;
 import static com.google.common.collect.Iterables.tryFind;
 import static com.google.common.collect.Lists.newArrayList;
+import static com.nokia.cbam.lcm.v32.model.OperationStatus.FAILED;
+import static com.nokia.cbam.lcm.v32.model.OperationStatus.STARTED;
 import static java.util.Optional.empty;
 import static java.util.Optional.of;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.SEPARATOR;
@@ -201,15 +203,12 @@ public class JobManager {
     }
 
     private JobDetailInfo getJobDetailInfo(String vnfmId, String jobId, String vnfId, OperationExecution operation) {
-        switch (operation.getStatus()) {
-            case STARTED:
-                return reportOngoing(jobId);
-            case FINISHED:
-            case OTHER:
-                return getJobForTerminalOperationState(vnfmId, jobId, vnfId, operation);
-            case FAILED:
-            default: //all cases handled
-                return reportFailed(jobId, operation.getError().getTitle() + ": " + operation.getError().getDetail());
+        if (operation.getStatus() == STARTED) {
+            return reportOngoing(jobId);
+        } else if (operation.getStatus() == FAILED) {
+            return reportFailed(jobId, operation.getError().getTitle() + ": " + operation.getError().getDetail());
+        } else {
+            return getJobForTerminalOperationState(vnfmId, jobId, vnfId, operation);
         }
     }
 
index cbf5341..b78c13a 100644 (file)
@@ -43,7 +43,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 import static com.google.common.base.Splitter.on;
-import static com.google.common.base.Strings.isNullOrEmpty;
 import static com.google.common.collect.Iterables.find;
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Sets.newHashSet;
@@ -71,6 +70,7 @@ public class LifecycleManager {
      * The key of the CBAM VNF extension for the identifier of the VNFM in ONAP
      */
     public static final String EXTERNAL_VNFM_ID = "externalVnfmId";
+    public static final String SCALE_OPERATION_NAME = "scale";
     private static Logger logger = getLogger(LifecycleManager.class);
     private final CatalogManager catalogManager;
     private final IGrantManager grantManager;
@@ -135,7 +135,7 @@ public class LifecycleManager {
      * @return the VNF creation result
      */
     public VnfCreationResult create(String vnfmId, String csarId, String vnfName, String description, AdditionalParameters addtionalParams) {
-        logOperationInput("not yet specified", "create", addtionalParams);
+        logOperationInput("not yet specified", "creation", addtionalParams);
         validateVimType(addtionalParams.getVimType());
         try {
             CatalogAdapterVnfpackage cbamPackage = catalogManager.preparePackageInCbam(vnfmId, csarId);
@@ -151,8 +151,8 @@ public class LifecycleManager {
         }
     }
 
-    private void logOperationInput(String vnfId, String operationName, Object payload){
-        if(logger.isInfoEnabled()){
+    private void logOperationInput(String vnfId, String operationName, Object payload) {
+        if (logger.isInfoEnabled()) {
             logger.info("Starting {} operation on VNF with {} identifier with {} parameter", operationName, vnfId, new Gson().toJson(payload));
         }
     }
@@ -169,7 +169,7 @@ public class LifecycleManager {
      * @return the instantiation response
      */
     public VnfInstantiateResponse instantiate(String vnfmId, VnfInstantiateRequest request, HttpServletResponse httpResponse, AdditionalParameters additionalParameters, String vnfId, String vnfdId) {
-        logOperationInput(vnfId, "instantiate", request);
+        logOperationInput(vnfId, "instantiation", request);
         validateVimType(additionalParameters.getVimType());
         VnfInstantiateResponse response = new VnfInstantiateResponse();
         response.setVnfInstanceId(vnfId);
@@ -219,7 +219,7 @@ public class LifecycleManager {
         VimInfo vimInfo = vimInfoProvider.getVimInfo(vim.getVimId());
         InstantiateVnfRequest instantiationRequest = new InstantiateVnfRequest();
         addExternalLinksToRequest(request.getExtVirtualLink(), additionalParameters, instantiationRequest, vimId);
-        instantiationRequest.getVims().add(addVim(additionalParameters, vimId, vim, vimInfo, instantiationRequest));
+        instantiationRequest.getVims().add(addVim(additionalParameters, vimId, vim, vimInfo));
         instantiationRequest.setFlavourId(getFlavorId(vnfdContent));
         instantiationRequest.setComputeResourceFlavours(additionalParameters.getComputeResourceFlavours());
         instantiationRequest.setGrantlessMode(true);
@@ -231,17 +231,19 @@ public class LifecycleManager {
             instantiationRequest.addExtVirtualLinksItem(extVirtualLinkData);
         }
         JsonObject root = new Gson().toJsonTree(jobInfo).getAsJsonObject();
-        if (additionalParameters.getAdditionalParams() != null && !isNullOrEmpty(additionalParameters.getAdditionalParams().toString())) {
+        if (additionalParameters.getAdditionalParams() != null) {
             for (Map.Entry<String, JsonElement> item : new Gson().toJsonTree(additionalParameters.getAdditionalParams()).getAsJsonObject().entrySet()) {
                 root.add(item.getKey(), item.getValue());
             }
+        } else {
+            logger.warn("No additional parameters were specified for the operation");
         }
         instantiationRequest.setAdditionalParams(root);
         OperationExecution operationExecution = cbamRestApiProvider.getCbamLcmApi(vnfmId).vnfsVnfInstanceIdInstantiatePost(vnfId, instantiationRequest, NOKIA_LCM_API_VERSION);
         waitForOperationToFinish(vnfmId, vnfId, operationExecution.getId());
     }
 
-    private com.nokia.cbam.lcm.v32.model.VimInfo addVim(AdditionalParameters additionalParameters, String vimId, GrantVNFResponseVim vim, VimInfo vimInfo, InstantiateVnfRequest instantiationRequest) {
+    private com.nokia.cbam.lcm.v32.model.VimInfo addVim(AdditionalParameters additionalParameters, String vimId, GrantVNFResponseVim vim, VimInfo vimInfo) {
         if (additionalParameters.getVimType() == OPENSTACK_V2_INFO) {
             return buildOpenStackV2INFO(vimId, vim, vimInfo);
 
@@ -255,7 +257,7 @@ public class LifecycleManager {
     }
 
     private void validateVimType(com.nokia.cbam.lcm.v32.model.VimInfo.VimInfoTypeEnum vimType) {
-        if(com.nokia.cbam.lcm.v32.model.VimInfo.VimInfoTypeEnum.OTHER_VIM_INFO.equals(vimType)){
+        if (com.nokia.cbam.lcm.v32.model.VimInfo.VimInfoTypeEnum.OTHER_VIM_INFO.equals(vimType)) {
             throw buildFatalFailure(logger, "Only " + OPENSTACK_V2_INFO + ", " + OPENSTACK_V3_INFO + " and " + VMWARE_VCLOUD_INFO + " is the supported VIM types");
         }
     }
@@ -517,8 +519,8 @@ public class LifecycleManager {
      * @return the job for tracking the scale
      */
     public JobInfo scaleVnf(String vnfmId, String vnfId, VnfScaleRequest request, HttpServletResponse httpResponse) {
-        logOperationInput(vnfId, "scale", request);
-        return scheduleExecution(vnfId, httpResponse, "scale", jobInfo -> {
+        logOperationInput(vnfId, SCALE_OPERATION_NAME, request);
+        return scheduleExecution(vnfId, httpResponse, SCALE_OPERATION_NAME, jobInfo -> {
             ScaleVnfRequest cbamRequest = new ScaleVnfRequest();
             cbamRequest.setAspectId(request.getAspectId());
             cbamRequest.setNumberOfSteps(Integer.valueOf(request.getNumberOfSteps()));
@@ -527,7 +529,7 @@ public class LifecycleManager {
             JsonObject root = new Gson().toJsonTree(jobInfo).getAsJsonObject();
             com.nokia.cbam.lcm.v32.model.VnfInfo cbamVnfInfo = cbamRestApiProvider.getCbamLcmApi(vnfmId).vnfsVnfInstanceIdGet(vnfId, NOKIA_LCM_API_VERSION);
             String vnfdContent = catalogManager.getCbamVnfdContent(vnfmId, cbamVnfInfo.getVnfdId());
-            Set<String> acceptableOperationParameters = getAcceptableOperationParameters(vnfdContent, "Basic", "scale");
+            Set<String> acceptableOperationParameters = getAcceptableOperationParameters(vnfdContent, "Basic", SCALE_OPERATION_NAME);
             buildAdditionalParameters(request, root, acceptableOperationParameters);
             cbamRequest.setAdditionalParams(root);
             grantManager.requestGrantForScale(vnfmId, vnfId, getVimIdFromInstantiationRequest(vnfmId, vnf), getVnfdIdFromModifyableAttributes(vnf), request, jobInfo.getJobId());
index 9ee8cbd..6a31e83 100644 (file)
@@ -16,9 +16,7 @@
 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
 import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
@@ -37,13 +35,16 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
-import java.util.NoSuchElementException;
+import java.util.Optional;
 import java.util.Set;
 
-import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.find;
 import static com.google.common.collect.Iterables.tryFind;
 import static com.google.common.collect.Sets.newConcurrentHashSet;
+import static com.google.common.collect.Sets.newHashSet;
 import static com.nokia.cbam.lcm.v32.model.OperationType.INSTANTIATE;
+import static java.util.Optional.empty;
+import static java.util.Optional.of;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.childElement;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION;
@@ -80,7 +81,7 @@ public class LifecycleChangeNotificationManager implements ILifecycleChangeNotif
     /**
      * < Separates the VNF id and the resource id within a VNF
      */
-    private static final Set<OperationStatus> terminalStatus = Sets.newHashSet(OperationStatus.FINISHED, OperationStatus.FAILED);
+    private static final Set<OperationStatus> terminalStatus = newHashSet(OperationStatus.FINISHED, OperationStatus.FAILED);
     private static Logger logger = getLogger(LifecycleChangeNotificationManager.class);
 
     private final CbamRestApiProvider restApiProvider;
@@ -95,35 +96,37 @@ public class LifecycleChangeNotificationManager implements ILifecycleChangeNotif
         this.restApiProvider = restApiProvider;
     }
 
+    /**
+     * @param status the status of the operation
+     * @return has the operation finished
+     */
+    public static boolean isTerminal(OperationStatus status) {
+        return terminalStatus.contains(status);
+    }
+
     @VisibleForTesting
     static OperationExecution findLastInstantiationBefore(List<OperationExecution> operationExecutions, OperationExecution currentOperation) {
-        for (OperationExecution opExs : filter(NEWEST_OPERATIONS_FIRST.sortedCopy(operationExecutions), (OperationExecution opex2) -> !opex2.getStartTime().isAfter(currentOperation.getStartTime()))) {
-            if (INSTANTIATE.equals(opExs.getOperationType()) &&
-                    (opExs.getStartTime().toLocalDate().isBefore(currentOperation.getStartTime().toLocalDate()) ||
-                            opExs.getStartTime().toLocalDate().isEqual(currentOperation.getStartTime().toLocalDate())
-                    )) {
-                return opExs;
-            }
-        }
-        throw new NoSuchElementException();
+        return find(NEWEST_OPERATIONS_FIRST.sortedCopy(operationExecutions), (OperationExecution opex2) ->
+                !opex2.getStartTime().isAfter(currentOperation.getStartTime())
+                        && INSTANTIATE.equals(opex2.getOperationType()));
     }
 
     @Override
-    public void handleLcn(VnfLifecycleChangeNotification recievedNotification) {
+    public void handleLcn(VnfLifecycleChangeNotification receivedNotification) {
         if (logger.isInfoEnabled()) {
-            logger.info("Received LCN: " + new Gson().toJson(recievedNotification));
+            logger.info("Received LCN: {}", new Gson().toJson(receivedNotification));
         }
         VnfsApi cbamLcmApi = restApiProvider.getCbamLcmApi(driverProperties.getVnfmId());
         try {
             List<VnfInfo> vnfs = cbamLcmApi.vnfsGet(NOKIA_LCM_API_VERSION);
-            com.google.common.base.Optional<VnfInfo> currentVnf = tryFind(vnfs, vnf -> vnf.getId().equals(recievedNotification.getVnfInstanceId()));
-            String vnfHeader = "The VNF with " + recievedNotification.getVnfInstanceId() + " identifier";
+            com.google.common.base.Optional<VnfInfo> currentVnf = tryFind(vnfs, vnf -> vnf.getId().equals(receivedNotification.getVnfInstanceId()));
+            String vnfHeader = "The VNF with " + receivedNotification.getVnfInstanceId() + " identifier";
             if (!currentVnf.isPresent()) {
                 logger.warn(vnfHeader + " disappeared before being able to process the LCN");
                 //swallow LCN
                 return;
             } else {
-                VnfInfo vnf = cbamLcmApi.vnfsVnfInstanceIdGet(recievedNotification.getVnfInstanceId(), NOKIA_LCN_API_VERSION);
+                VnfInfo vnf = cbamLcmApi.vnfsVnfInstanceIdGet(receivedNotification.getVnfInstanceId(), NOKIA_LCN_API_VERSION);
                 com.google.common.base.Optional<VnfProperty> externalVnfmId = tryFind(vnf.getExtensions(), prop -> prop.getName().equals(LifecycleManager.EXTERNAL_VNFM_ID));
                 if (!externalVnfmId.isPresent()) {
                     logger.warn(vnfHeader + " is not a managed VNF");
@@ -139,19 +142,24 @@ public class LifecycleChangeNotificationManager implements ILifecycleChangeNotif
         }
         OperationExecutionsApi cbamOperationExecutionApi = restApiProvider.getCbamOperationExecutionApi(driverProperties.getVnfmId());
         try {
-            List<OperationExecution> operationExecutions = cbamLcmApi.vnfsVnfInstanceIdOperationExecutionsGet(recievedNotification.getVnfInstanceId(), NOKIA_LCM_API_VERSION);
-            OperationExecution operationExecution = cbamOperationExecutionApi.operationExecutionsOperationExecutionIdGet(recievedNotification.getLifecycleOperationOccurrenceId(), NOKIA_LCM_API_VERSION);
+            List<OperationExecution> operationExecutions = cbamLcmApi.vnfsVnfInstanceIdOperationExecutionsGet(receivedNotification.getVnfInstanceId(), NOKIA_LCM_API_VERSION);
+            OperationExecution operationExecution = cbamOperationExecutionApi.operationExecutionsOperationExecutionIdGet(receivedNotification.getLifecycleOperationOccurrenceId(), NOKIA_LCM_API_VERSION);
             OperationExecution closestInstantiationToOperation = findLastInstantiationBefore(operationExecutions, operationExecution);
             String vimId = getVimId(cbamOperationExecutionApi, closestInstantiationToOperation);
-            notificationSender.processNotification(recievedNotification, operationExecution, buildAffectedCps(operationExecution), vimId);
-            if (OperationType.TERMINATE.equals(recievedNotification.getOperation()) && terminalStatus.contains(recievedNotification.getStatus())) {
-                processedNotifications.add(new ProcessedNotification(recievedNotification.getLifecycleOperationOccurrenceId(), recievedNotification.getStatus()));
+            notificationSender.processNotification(receivedNotification, operationExecution, buildAffectedCps(operationExecution), vimId);
+            if (isTerminationFinished(receivedNotification)) {
+                //signal LifecycleManager to continue the deletion of the VNF
+                processedNotifications.add(new ProcessedNotification(receivedNotification.getLifecycleOperationOccurrenceId(), receivedNotification.getStatus()));
             }
         } catch (ApiException e) {
-            throw buildFatalFailure(logger, "Unable to retrieve the current VNF " + recievedNotification.getVnfInstanceId(), e);
+            throw buildFatalFailure(logger, "Unable to retrieve the current VNF " + receivedNotification.getVnfInstanceId(), e);
         }
     }
 
+    private boolean isTerminationFinished(VnfLifecycleChangeNotification receivedNotification) {
+        return OperationType.TERMINATE.equals(receivedNotification.getOperation()) && terminalStatus.contains(receivedNotification.getStatus());
+    }
+
     private String getVimId(OperationExecutionsApi cbamOperationExecutionApi, OperationExecution closestInstantiationToOperation) {
         try {
             Object operationParams = cbamOperationExecutionApi.operationExecutionsOperationExecutionIdOperationParamsGet(closestInstantiationToOperation.getId(), NOKIA_LCM_API_VERSION);
@@ -164,7 +172,7 @@ public class LifecycleChangeNotificationManager implements ILifecycleChangeNotif
     @Override
     public void waitForTerminationToBeProcessed(String operationExecutionId) {
         while (true) {
-            com.google.common.base.Optional<ProcessedNotification> notification = Iterables.tryFind(processedNotifications, processedNotification -> processedNotification.getOperationExecutionId().equals(operationExecutionId));
+            com.google.common.base.Optional<ProcessedNotification> notification = tryFind(processedNotifications, processedNotification -> processedNotification.getOperationExecutionId().equals(operationExecutionId));
             if (notification.isPresent()) {
                 processedNotifications.remove(notification.get());
                 return;
@@ -178,47 +186,47 @@ public class LifecycleChangeNotificationManager implements ILifecycleChangeNotif
         return request.getVims().get(0).getId();
     }
 
-    private ReportedAffectedConnectionPoints buildAffectedCps(OperationExecution operationExecution) {
+    private Optional<ReportedAffectedConnectionPoints> buildAffectedCps(OperationExecution operationExecution) {
         if (operationExecution.getOperationType() == OperationType.TERMINATE) {
             String terminationType = childElement(new Gson().toJsonTree(operationExecution.getOperationParams()).getAsJsonObject(), "terminationType").getAsString();
             if (TerminationType.FORCEFUL.name().equals(terminationType)) {
                 //in case of force full termination the Ansible is not executed, so the connection points can not be
                 //calculated from operation execution result
                 logger.warn("Unable to send information related to affected connection points during forceful termination");
-                return null;
+                return empty();
             }
         }
         try {
             JsonElement root = new Gson().toJsonTree(operationExecution.getAdditionalData());
             if (root.getAsJsonObject().has("operationResult")) {
                 JsonObject operationResult = root.getAsJsonObject().get("operationResult").getAsJsonObject();
-                if (!isPresent(operationResult, "cbam_pre") || !isPresent(operationResult, "cbam_post")) {
-                    handleFailure(operationExecution, null);
+                if (isAbsent(operationResult, "cbam_pre") ||
+                        isAbsent(operationResult, "cbam_post")) {
+                    return handleFailure(operationExecution, null);
+                } else {
+                    return of(new Gson().fromJson(operationResult, ReportedAffectedConnectionPoints.class));
                 }
-                return new Gson().fromJson(operationResult, ReportedAffectedConnectionPoints.class);
+            } else {
+                return handleFailure(operationExecution, null);
             }
         } catch (Exception e) {
-            handleFailure(operationExecution, e);
+            return handleFailure(operationExecution, e);
         }
-        return new ReportedAffectedConnectionPoints();
     }
 
-    private boolean isPresent(JsonObject operationResult, String key) {
-        return operationResult.has(key) && operationResult.get(key).isJsonArray();
+    private boolean isAbsent(JsonObject operationResult, String key) {
+        return !operationResult.has(key) || !operationResult.get(key).isJsonArray();
     }
 
-    private void handleFailure(OperationExecution operationExecution, Exception e) {
-        switch (operationExecution.getStatus()) {
-            case FAILED:
-            case OTHER:
-                logger.warn("The operation failed and the affected connection points were not reported");
-                break;
-            case STARTED: //can not happen (the changed resources are only executed for terminal state
-            case FINISHED:
-                if (e != null) {
-                    throw buildFatalFailure(logger, PROBLEM, e);
-                }
-                throw buildFatalFailure(logger, PROBLEM);
+    private Optional<ReportedAffectedConnectionPoints> handleFailure(OperationExecution operationExecution, Exception e) {
+        if (operationExecution.getStatus() == OperationStatus.FAILED) {
+            logger.warn("The operation failed and the affected connection points were not reported");
+            return empty();
+        } else {
+            if (e != null) {
+                throw buildFatalFailure(logger, PROBLEM, e);
+            }
+            throw buildFatalFailure(logger, PROBLEM);
         }
     }
 }
index 17cf825..a0d4ea4 100644 (file)
@@ -87,29 +87,11 @@ public class TestGenericExternalSystemInfoProvider extends TestBase {
         verify(genericExternalSystemInfoProvider, Mockito.times(2)).queryVnfmInfoFromSource(VNFM_ID);
     }
 
-    class TestClass extends GenericExternalSystemInfoProvider {
-
-        TestClass(Environment environment) {
-            super(environment);
-        }
-
-        @Override
-        public VnfmInfo queryVnfmInfoFromSource(String vnfmId) {
-            return null;
-        }
-
-        @Override
-        public VimInfo getVimInfo(String vimId) {
-            return null;
-        }
-    }
-
-
     /**
      * Unable to query VNFM results is propagated
      */
     @Test
-    public void testUnableToQueryVnfmInfoProvider() throws Exception{
+    public void testUnableToQueryVnfmInfoProvider() throws Exception {
         class TestClass extends GenericExternalSystemInfoProvider {
 
             TestClass(Environment environment) {
@@ -129,10 +111,26 @@ public class TestGenericExternalSystemInfoProvider extends TestBase {
         try {
             new TestClass(null).getVnfmInfo(VNFM_ID);
             fail();
-        }
-        catch (Exception e){
+        } catch (Exception e) {
             assertEquals("Unable to query VNFM info for myVnfmId", e.getMessage());
             verify(logger).error(eq("Unable to query VNFM info for myVnfmId"), any(RuntimeException.class));
         }
     }
+
+    class TestClass extends GenericExternalSystemInfoProvider {
+
+        TestClass(Environment environment) {
+            super(environment);
+        }
+
+        @Override
+        public VnfmInfo queryVnfmInfoFromSource(String vnfmId) {
+            return null;
+        }
+
+        @Override
+        public VimInfo getVimInfo(String vimId) {
+            return null;
+        }
+    }
 }
index a2bf030..4bbf076 100644 (file)
@@ -158,6 +158,32 @@ public class TestVfcGrantManager extends TestBase {
         assertBasicGrantAttributes(request, org.onap.vnfmdriver.model.OperationType.TERMINAL);
     }
 
+    /**
+     * grant is requested for termination if the the VNF is instantiated even if has no VNFCs
+     */
+    @Test
+    public void testGrantIsRequestedIfInstantiatedWithNoVnfcs() {
+        VnfInfo vnf = new VnfInfo();
+        vnf.setId(VNF_ID);
+        vnf.setInstantiationState(InstantiationState.INSTANTIATED);
+        InstantiatedVnfInfo instantiatedVnfInfo = new InstantiatedVnfInfo();
+        vnf.setInstantiatedVnfInfo(instantiatedVnfInfo);
+        VnfProperty prop = new VnfProperty();
+        prop.setName(LifecycleManager.ONAP_CSAR_ID);
+        prop.setValue(ONAP_CSAR_ID);
+        vnf.setVnfConfigurableProperties(new ArrayList<>());
+        vnf.getVnfConfigurableProperties().add(prop);
+        //when
+        vfcGrantManager.requestGrantForTerminate(VNFM_ID, VNF_ID, VIM_ID, ONAP_CSAR_ID, vnf, JOB_ID);
+        //verify
+        assertEquals(1, grantRequest.getAllValues().size());
+        GrantVNFRequest request = grantRequest.getValue();
+        assertVduInGrant(request.getRemoveResource(), "vdu1", 0);
+        assertVduInGrant(request.getRemoveResource(), "vdu2", 0);
+        assertEquals(0, request.getAddResource().size());
+        assertBasicGrantAttributes(request, org.onap.vnfmdriver.model.OperationType.TERMINAL);
+    }
+
     /**
      * test failure logging & propagation during grant request for instantiation
      */
@@ -179,7 +205,7 @@ public class TestVfcGrantManager extends TestBase {
     }
 
     /**
-     * failuire is to request grant is logged
+     * failure is to request grant is logged
      */
     @Test
     public void testFailureToRequestGrantIsLogged() throws Exception {
@@ -211,7 +237,7 @@ public class TestVfcGrantManager extends TestBase {
     }
 
     /**
-     * failuire is to request grant is logged
+     * failure is to request grant is logged
      */
     @Test
     public void testFailureToRequestGrantForScaleIsLogged() throws Exception {
@@ -258,6 +284,54 @@ public class TestVfcGrantManager extends TestBase {
         assertBasicGrantAttributes(request, org.onap.vnfmdriver.model.OperationType.SCALEOUT);
     }
 
+    /**
+     * test grant request for scale out without VDUs
+     */
+    @Test
+    public void testGrantDuringScaleOutWithoutVdus() throws Exception {
+        String cbamVnfdContent = new String(readAllBytes(Paths.get(TestVfcGrantManager.class.getResource("/unittests/vnfd.scale.yaml").toURI())));
+        VnfScaleRequest scaleRequest = new VnfScaleRequest();
+        scaleRequest.setType(ScaleDirection.OUT);
+        scaleRequest.setAspectId("aspectWithOutVdu");
+        scaleRequest.setNumberOfSteps("2");
+        VnfInfo vnf = new VnfInfo();
+        when(vnfApi.vnfsVnfInstanceIdGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenReturn(vnf);
+        vnf.setVnfdId(CBAM_VNFD_ID);
+        when(cbamCatalogManager.getCbamVnfdContent(VNFM_ID, CBAM_VNFD_ID)).thenReturn(cbamVnfdContent);
+        //when
+        vfcGrantManager.requestGrantForScale(VNFM_ID, VNF_ID, VIM_ID, ONAP_CSAR_ID, scaleRequest, JOB_ID);
+        //verify
+        assertEquals(1, grantRequest.getAllValues().size());
+        GrantVNFRequest request = grantRequest.getValue();
+        assertVduInGrant(request.getAddResource(), "vdu1", 0);
+        assertVduInGrant(request.getAddResource(), "vdu2", 0);
+        assertEquals(0, request.getRemoveResource().size());
+        assertBasicGrantAttributes(request, org.onap.vnfmdriver.model.OperationType.SCALEOUT);
+    }
+
+    /**
+     * test grant request for scale out without resources
+     */
+    @Test
+    public void testGrantDuringScaleOutForEmptyAspect() throws Exception {
+        String cbamVnfdContent = new String(readAllBytes(Paths.get(TestVfcGrantManager.class.getResource("/unittests/vnfd.scale.yaml").toURI())));
+        VnfScaleRequest scaleRequest = new VnfScaleRequest();
+        scaleRequest.setType(ScaleDirection.OUT);
+        scaleRequest.setAspectId("emptyAspect");
+        scaleRequest.setNumberOfSteps("2");
+        VnfInfo vnf = new VnfInfo();
+        when(vnfApi.vnfsVnfInstanceIdGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenReturn(vnf);
+        vnf.setVnfdId(CBAM_VNFD_ID);
+        when(cbamCatalogManager.getCbamVnfdContent(VNFM_ID, CBAM_VNFD_ID)).thenReturn(cbamVnfdContent);
+        //when
+        try {
+            vfcGrantManager.requestGrantForScale(VNFM_ID, VNF_ID, VIM_ID, ONAP_CSAR_ID, scaleRequest, JOB_ID);
+            fail();
+        } catch (Exception e) {
+            assertEquals("Missing child emptyAspect", e.getMessage());
+        }
+    }
+
     /**
      * test grant request for scale in
      */
index 008d827..d28e224 100644 (file)
@@ -41,6 +41,8 @@ import org.threeten.bp.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.List;
 
+import static java.util.Optional.empty;
+import static java.util.Optional.of;
 import static junit.framework.TestCase.*;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
@@ -114,7 +116,7 @@ public class TestVfcNotificationSender extends TestBase {
         recievedLcn.setStatus(OperationStatus.STARTED);
         recievedLcn.setOperation(OperationType.INSTANTIATE);
         //when
-        vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, affectedCp, VIM_ID);
+        vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, empty(), VIM_ID);
         //verify
         assertEquals(1, sentLcnToVfc.getAllValues().size());
         assertNull(sentLcnToVfc.getValue().getAffectedVl());
@@ -188,7 +190,7 @@ public class TestVfcNotificationSender extends TestBase {
         JsonElement additionalData = new Gson().toJsonTree(operationResult);
         instantiationOperation.setAdditionalData(additionalData);
         //when
-        vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, affectedConnectionPoints, VIM_ID);
+        vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, of(affectedConnectionPoints), VIM_ID);
         //verify
         assertEquals(1, sentLcnToVfc.getAllValues().size());
 
@@ -271,7 +273,7 @@ public class TestVfcNotificationSender extends TestBase {
         JsonElement additionalData = new Gson().toJsonTree(operationResult);
         instantiationOperation.setAdditionalData(additionalData);
         //when
-        vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, affectedConnectionPoints, VIM_ID);
+        vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, of(affectedConnectionPoints), VIM_ID);
         //verify
         assertEquals(1, sentLcnToVfc.getAllValues().size());
 
@@ -352,7 +354,7 @@ public class TestVfcNotificationSender extends TestBase {
         JsonElement additionalData = new Gson().toJsonTree(operationResult);
         instantiationOperation.setAdditionalData(additionalData);
         //when
-        vfcNotificationSender.processNotification(recievedLcn, terminationOperation, affectedConnectionPoints, VIM_ID);
+        vfcNotificationSender.processNotification(recievedLcn, terminationOperation, of(affectedConnectionPoints), VIM_ID);
         //verify
         assertEquals(1, sentLcnToVfc.getAllValues().size());
 
@@ -473,7 +475,7 @@ public class TestVfcNotificationSender extends TestBase {
         JsonElement additionalData = new Gson().toJsonTree(operationResult);
         instantiationOperation.setAdditionalData(additionalData);
         //when
-        vfcNotificationSender.processNotification(recievedLcn, healOperation, affectedConnectionPoints, VIM_ID);
+        vfcNotificationSender.processNotification(recievedLcn, healOperation, of(affectedConnectionPoints), VIM_ID);
         //verify
         assertEquals(1, sentLcnToVfc.getAllValues().size());
 
@@ -585,7 +587,7 @@ public class TestVfcNotificationSender extends TestBase {
         JsonElement additionalData = new Gson().toJsonTree(operationResult);
         scaleOperation.setAdditionalData(additionalData);
         //when
-        vfcNotificationSender.processNotification(recievedLcn, scaleOperation, affectedConnectionPoints, VIM_ID);
+        vfcNotificationSender.processNotification(recievedLcn, scaleOperation, of(affectedConnectionPoints), VIM_ID);
         //verify
         assertEquals(1, sentLcnToVfc.getAllValues().size());
 
@@ -698,7 +700,7 @@ public class TestVfcNotificationSender extends TestBase {
         scaleOperation.setAdditionalData(additionalData);
         scaleOperation.setOperationType(OperationType.SCALE);
         //when
-        vfcNotificationSender.processNotification(recievedLcn, scaleOperation, affectedConnectionPoints, VIM_ID);
+        vfcNotificationSender.processNotification(recievedLcn, scaleOperation, of(affectedConnectionPoints), VIM_ID);
         //verify
         assertEquals(1, sentLcnToVfc.getAllValues().size());
 
@@ -742,6 +744,99 @@ public class TestVfcNotificationSender extends TestBase {
         assertEquals(VNF_ID, sentLcnToVfc.getValue().getVnfInstanceId());
     }
 
+
+    /**
+     * en empty LCN is sent even if nothing has changed
+     */
+    @Test
+    public void testNothingChanged() {
+        //given
+        recievedLcn.setOperation(OperationType.SCALE);
+        recievedLcn.setStatus(OperationStatus.FINISHED);
+        recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
+        ScaleVnfRequest request = new ScaleVnfRequest();
+        request.setAdditionalParams(new JsonParser().parse("{ \"jobId\" : \"" + JOB_ID + "\" }"));
+        request.setType(ScaleDirection.IN);
+        scaleOperation.setOperationParams(request);
+        OperationResult operationResult = new OperationResult();
+        JsonElement additionalData = new Gson().toJsonTree(operationResult);
+        scaleOperation.setAdditionalData(additionalData);
+        scaleOperation.setOperationType(OperationType.SCALE);
+        when(logger.isInfoEnabled()).thenReturn(false);
+        //when
+        vfcNotificationSender.processNotification(recievedLcn, scaleOperation, empty(), VIM_ID);
+        //verify
+        assertEquals(1, sentLcnToVfc.getAllValues().size());
+
+        assertNull(sentLcnToVfc.getValue().getAffectedVl());
+        assertNull(sentLcnToVfc.getValue().getAffectedVnfc());
+        assertNull(sentLcnToVfc.getValue().getAffectedCp());
+        assertNull(sentLcnToVfc.getValue().getAffectedVirtualStorage());
+        assertEquals(JOB_ID, sentLcnToVfc.getValue().getJobId());
+        assertEquals(org.onap.vnfmdriver.model.OperationType.SCALEIN, sentLcnToVfc.getValue().getOperation());
+        assertEquals(VnfLcmNotificationStatus.RESULT, sentLcnToVfc.getValue().getStatus());
+        assertEquals(VNF_ID, sentLcnToVfc.getValue().getVnfInstanceId());
+        verify(logger, never()).info(eq("Sending LCN: {}"), anyString());
+    }
+
+    /**
+     * If a connection point is not modified it is not contained in the LCN
+     */
+    @Test
+    public void testNonModifiedCP() {
+        //given
+        recievedLcn.setOperation(OperationType.HEAL);
+        recievedLcn.setStatus(OperationStatus.FINISHED);
+
+        ReportedAffectedConnectionPoints affectedConnectionPoints = new ReportedAffectedConnectionPoints();
+        ReportedAffectedCp affectedCp = new ReportedAffectedCp();
+        affectedCp.setCpdId("cpVnfdId");
+        affectedCp.setIpAddress("1.2.3.4");
+        affectedCp.setMacAddress("myMac");
+        affectedCp.setName("myPortName");
+        affectedCp.setCpId("cpId");
+
+        // affectedCp.setEcpdId("ecpdId");
+        affectedCp.setNetworkProviderId("networkProviderId");
+        affectedCp.setProviderId("portProviderId");
+        affectedCp.setServerProviderId("serverProviderId");
+        affectedCp.setTenantId("tenantId");
+        affectedConnectionPoints.getPre().add(affectedCp);
+
+        ReportedAffectedCp after = new ReportedAffectedCp();
+        after.setCpdId("cpVnfdId");
+        after.setIpAddress("1.2.3.4");
+        after.setMacAddress("myMac");
+        after.setName("myPortName");
+        after.setCpId("cpId");
+
+        // affectedCp.setEcpdId("ecpdId");
+        after.setNetworkProviderId("networkProviderId");
+        after.setProviderId("portProviderId");
+        after.setServerProviderId("serverProviderId");
+        after.setTenantId("tenantId");
+        affectedConnectionPoints.getPost().add(after);
+
+
+        OperationResult operationResult = new OperationResult();
+        operationResult.operationResult = affectedConnectionPoints;
+        JsonElement additionalData = new Gson().toJsonTree(operationResult);
+        instantiationOperation.setAdditionalData(additionalData);
+        //when
+        vfcNotificationSender.processNotification(recievedLcn, healOperation, of(affectedConnectionPoints), VIM_ID);
+        //verify
+        assertEquals(1, sentLcnToVfc.getAllValues().size());
+
+        assertNull(sentLcnToVfc.getValue().getAffectedVl());
+        assertNull(sentLcnToVfc.getValue().getAffectedVnfc());
+        assertEquals(0, sentLcnToVfc.getValue().getAffectedCp().size());
+        assertNull(sentLcnToVfc.getValue().getAffectedVirtualStorage());
+        assertEquals(JOB_ID, sentLcnToVfc.getValue().getJobId());
+        assertEquals(org.onap.vnfmdriver.model.OperationType.HEAL, sentLcnToVfc.getValue().getOperation());
+        assertEquals(VnfLcmNotificationStatus.RESULT, sentLcnToVfc.getValue().getStatus());
+        assertEquals(VNF_ID, sentLcnToVfc.getValue().getVnfInstanceId());
+    }
+
     /**
      * Unable to send notification to VF-C results in error
      */
@@ -753,7 +848,7 @@ public class TestVfcNotificationSender extends TestBase {
         recievedLcn.setOperation(OperationType.INSTANTIATE);
         //when
         try {
-            vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, affectedCp, VIM_ID);
+            vfcNotificationSender.processNotification(recievedLcn, instantiationOperation, empty(), VIM_ID);
             //verify
             fail();
         } catch (Exception e) {
index fd93dce..5001eed 100644 (file)
@@ -15,6 +15,7 @@
  */
 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.packagetransformer;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.TestUtil;
 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase;
@@ -23,11 +24,19 @@ import java.util.NoSuchElementException;
 
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.fail;
+import static org.mockito.Mockito.verify;
+import static org.springframework.test.util.ReflectionTestUtils.setField;
 
 
 public class TestOnapVnfdBuilder extends TestBase {
     private OnapVnfdBuilder packageTransformer = new OnapVnfdBuilder();
 
+
+    @Before
+    public void init() {
+        setField(OnapVnfdBuilder.class, "logger", logger);
+    }
+
     @Test
     public void indent() {
         assertEquals("    x", packageTransformer.indent("x", 2));
@@ -51,6 +60,17 @@ public class TestOnapVnfdBuilder extends TestBase {
     @Test
     public void testNodes() {
         assertEquals(new String(TestUtil.loadFile("unittests/packageconverter/nodes.vnfd.onap.yaml")), packageTransformer.toOnapVnfd(new String(TestUtil.loadFile("unittests/packageconverter/nodes.vnfd.cbam.yaml"))));
+        verify(logger).warn("The {} ecp does not have an internal connection point", "myEcpWithoutIcp");
+        verify(logger).warn("The {} ecp does not have an requirements section", "ecpWithIcpWithOutRequirements");
+        verify(logger).warn("The {} internal connection point of the {} ecp does not have a VDU", "icpWithoutVdu", "myEcpWithoutIcpWithoutVdu");
+
+        verify(logger).warn("The {} internal connection point of the {} ecp does not have a requirements section", "icpWithOutRequiements", "myEcpWithoutIcpWithoutIcpReq");
+
+
+        verify(logger).warn("The {} internal connection point does not have a VDU", "icpWithOutVdu");
+        verify(logger).warn("The {} internal connection point does not have a requirements section", "icpWithOutRequiements");
+        verify(logger).warn("The {} internal connection point does not have a VL", "icpWithOutVl");
+
     }
 
     /**
index 95bdc5f..218c478 100644 (file)
@@ -17,7 +17,6 @@
 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.restapi;
 
 import com.google.common.collect.Lists;
-import junit.framework.TestCase;
 import org.apache.http.entity.ContentType;
 import org.junit.Before;
 import org.junit.Test;
@@ -41,9 +40,9 @@ import java.io.IOException;
 import java.io.PrintStream;
 import java.util.Arrays;
 
-import static junit.framework.TestCase.assertEquals;
-import static junit.framework.TestCase.assertTrue;
-import static junit.framework.TestCase.fail;
+import static junit.framework.TestCase.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CatalogManager.getFileInZip;
@@ -121,17 +120,33 @@ public class TestConverterApi extends TestBase {
      * error is propagated if unable to extract package from HTTP request
      */
     @Test
-    public void testUnableToExtractPackageToBeConverted() throws Exception{
+    public void testUnableToExtractPackageToBeConverted() throws Exception {
         IOException expectedException = new IOException();
         when(httpRequest.getParts()).thenThrow(expectedException);
         try {
             converterApi.convert(httpResponse, httpRequest);
             fail();
-        }
-        catch (Exception e){
+        } catch (Exception e) {
             verify(logger).error("Unable to extract package from REST parameters", expectedException);
             assertEquals("Unable to extract package from REST parameters", e.getMessage());
             assertEquals(expectedException, e.getCause());
         }
     }
+
+    /**
+     * error is propagated if unable to extract package from HTTP request
+     */
+    @Test
+    public void testUnableToConvertPackage() throws Exception {
+        Part part = Mockito.mock(Part.class);
+        when(part.getInputStream()).thenReturn(new ByteArrayInputStream(TestUtil.loadFile("unittests/packageconverter/cbam.package.zip")));
+        when(httpRequest.getParts()).thenReturn(Lists.newArrayList(part));
+        try {
+            converterApi.convert(httpResponse, httpRequest);
+            fail();
+        } catch (Exception e) {
+            verify(logger).error(eq("Unable to convert VNF package"), any(RuntimeException.class));
+            assertEquals("Unable to convert VNF package", e.getMessage());
+        }
+    }
 }
index 3ff5364..c601f7e 100644 (file)
@@ -52,6 +52,7 @@ import static java.nio.file.Files.readAllBytes;
 import static junit.framework.TestCase.*;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.*;
+import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.child;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions.systemFunctions;
 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION;
 import static org.springframework.test.util.ReflectionTestUtils.setField;
@@ -251,8 +252,8 @@ public class TestLifecycleManager extends TestBase {
         //the 3.2 API does not accept empty array
         assertNull(actualVnfModifyRequest.getValue().getVnfConfigurableProperties());
         verify(jobManager).spawnJob(VNF_ID, restResponse);
-        //verify(logger).info(eq("Additional parameters for instantiation: {}"), anyString());
-        //FIXME
+        verify(logger).info(eq("Starting {} operation on VNF with {} identifier with {} parameter"), eq("creation"), eq("not yet specified"), anyString());
+        verify(logger).info(eq("Starting {} operation on VNF with {} identifier with {} parameter"), eq("instantiation"), eq(VNF_ID), anyString());
     }
 
     /**
@@ -263,7 +264,7 @@ public class TestLifecycleManager extends TestBase {
         //given
         VnfInstantiateRequest instantiationRequest = prepareInstantiationRequest(VimInfo.VimInfoTypeEnum.OTHER_VIM_INFO);
         when(vnfApi.vnfsPost(createRequest.capture(), eq(NOKIA_LCM_API_VERSION))).thenReturn(vnfInfo);
-        when(logger.isDebugEnabled()).thenReturn(false);
+        when(logger.isInfoEnabled()).thenReturn(false);
         //when
         try {
             lifecycleManager.createAndInstantiate(VNFM_ID, instantiationRequest, restResponse);
@@ -273,7 +274,8 @@ public class TestLifecycleManager extends TestBase {
             assertEquals("Only OPENSTACK_V2_INFO, OPENSTACK_V3_INFO and VMWARE_VCLOUD_INFO is the supported VIM types", e.getMessage());
         }
         verify(vnfApi, never()).vnfsPost(Mockito.any(), Mockito.any());
-        verify(logger, never()).debug(eq("Additional parameters for instantiation: {}"), anyString());
+        verify(logger, never()).info(eq("Starting {} operation on VNF with {} identifier with {} parameter"), eq("creation"), eq("not yet specified"), anyString());
+        verify(logger, never()).info(eq("Starting {} operation on VNF with {} identifier with {} parameter"), eq("instantiation"), eq(VNF_ID), anyString());
         verify(logger).error("Only OPENSTACK_V2_INFO, OPENSTACK_V3_INFO and VMWARE_VCLOUD_INFO is the supported VIM types");
     }
 
@@ -296,6 +298,9 @@ public class TestLifecycleManager extends TestBase {
         grantResponse.setAccessInfo(accessInfo);
         ArgumentCaptor<InstantiateVnfRequest> actualInstantiationRequest = ArgumentCaptor.forClass(InstantiateVnfRequest.class);
         when(vnfApi.vnfsVnfInstanceIdInstantiatePost(eq(VNF_ID), actualInstantiationRequest.capture(), eq(NOKIA_LCM_API_VERSION))).thenReturn(instantiationOperationExecution);
+        JsonObject inputs = child((JsonObject) instantiationRequest.getAdditionalParam(), "inputs");
+        JsonObject vnfs = child(child(inputs, "vnfs"), ONAP_CSAR_ID);
+        vnfs.remove("additionalParams");
         //when
         VnfInstantiateResponse response = lifecycleManager.createAndInstantiate(VNFM_ID, instantiationRequest, restResponse);
         waitForJobToFinishInJobManager(finished);
@@ -305,9 +310,9 @@ public class TestLifecycleManager extends TestBase {
         assertEquals(StoreLoader.getCertifacates(caCert).iterator().next(), new String(actualVim.getInterfaceInfo().getTrustedCertificates().get(0)));
         assertTrue(!actualVim.getInterfaceInfo().isSkipCertificateVerification());
         assertTrue(!actualVim.getInterfaceInfo().isSkipCertificateHostnameCheck());
+        verify(logger).warn("No additional parameters were specified for the operation");
     }
 
-
     /**
      * non specified SSL verification means not verified
      */
@@ -753,6 +758,7 @@ public class TestLifecycleManager extends TestBase {
         notificationIsProcessedBeforeDeletingTheVnf.verify(notificationManager).waitForTerminationToBeProcessed("terminationId");
         notificationIsProcessedBeforeDeletingTheVnf.verify(vnfApi).vnfsVnfInstanceIdDelete(VNF_ID, NOKIA_LCM_API_VERSION);
         verify(jobManager).spawnJob(VNF_ID, restResponse);
+        verify(logger).info(eq("Starting {} operation on VNF with {} identifier with {} parameter"), eq("termination"), eq(VNF_ID), anyString());
     }
 
     /**
@@ -1158,6 +1164,8 @@ public class TestLifecycleManager extends TestBase {
         assertEquals(Integer.valueOf(2), sRequest.getNumberOfSteps());
         assertTrue("{\"jobId\":\"myJobId\",\"a\":\"b\"}".equals(new Gson().toJson(sRequest.getAdditionalParams())) || "{\"a\":\"b\",\"jobId\":\"myJobId\"}".equals(new Gson().toJson(sRequest.getAdditionalParams())));
         verify(jobManager).spawnJob(VNF_ID, restResponse);
+        verify(logger).info(eq("Starting {} operation on VNF with {} identifier with {} parameter"), eq("scale"), eq(VNF_ID), anyString());
+
     }
 
     /**
@@ -1322,6 +1330,7 @@ public class TestLifecycleManager extends TestBase {
         assertEquals("vmName", root.get("vmName").getAsString());
         assertEquals(JOB_ID, root.get("jobId").getAsString());
         verify(jobManager).spawnJob(VNF_ID, restResponse);
+        verify(logger).info(eq("Starting {} operation on VNF with {} identifier with {} parameter"), eq("heal"), eq(VNF_ID), anyString());
     }
 
     /**
index 18567f4..7121bea 100644 (file)
@@ -31,10 +31,8 @@ import org.threeten.bp.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.NoSuchElementException;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+import java.util.Optional;
+import java.util.concurrent.*;
 
 import static com.nokia.cbam.lcm.v32.model.OperationType.*;
 import static junit.framework.TestCase.*;
@@ -56,7 +54,7 @@ public class TestLifecycleChangeNotificationManager extends TestBase {
     private OperationExecution terminationOperation = new OperationExecution();
 
     private ArgumentCaptor<OperationExecution> currentOperationExecution = ArgumentCaptor.forClass(OperationExecution.class);
-    private ArgumentCaptor<ReportedAffectedConnectionPoints> affectedConnectionPoints = ArgumentCaptor.forClass(ReportedAffectedConnectionPoints.class);
+    private ArgumentCaptor<Optional> affectedConnectionPoints = ArgumentCaptor.forClass(Optional.class);
 
     private List<VnfInfo> vnfs = new ArrayList<>();
     private VnfInfo vnf = new VnfInfo();
@@ -239,6 +237,19 @@ public class TestLifecycleChangeNotificationManager extends TestBase {
         verify(logger).warn("The VNF with " + VNF_ID + " identifier is not a managed VNF");
     }
 
+    /**
+     * LCN is not logged in case of non info log level
+     */
+    @Test
+    public void testNoLogging() throws Exception {
+        vnf.getExtensions().clear();
+        when(logger.isInfoEnabled()).thenReturn(false);
+        //when
+        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+        //verify
+        verify(logger, never()).info(eq("Received LCN: {}"), anyString());
+    }
+
     /**
      * if the VNF is not managed by this VNFM the LCN is dropped
      */
@@ -344,6 +355,38 @@ public class TestLifecycleChangeNotificationManager extends TestBase {
         assertTrue(waitExitedWithSuccess.get());
     }
 
+    /**
+     * the processing of the start notification does not trigger the deletion of the VNF
+     */
+    @Test
+    public void testStartLcnForTerminate() throws Exception {
+        recievedLcn.setOperation(OperationType.TERMINATE);
+        recievedLcn.setStatus(OperationStatus.STARTED);
+        recievedLcn.setLifecycleOperationOccurrenceId(terminationOperation.getId());
+        ExecutorService executorService = Executors.newCachedThreadPool();
+        Future<Boolean> waitExitedWithSuccess = executorService.submit(() -> {
+            try {
+                lifecycleChangeNotificationManager.waitForTerminationToBeProcessed(terminationOperation.getId());
+                return true;
+            } catch (Exception e) {
+                return false;
+            }
+        });
+        //processing the start notification
+        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+        //verify
+        try {
+            waitExitedWithSuccess.get(10, TimeUnit.MILLISECONDS);
+            fail();
+        } catch (Exception e) {
+        }
+        recievedLcn.setStatus(OperationStatus.FINISHED);
+        //when
+        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+        //verify
+        assertTrue(waitExitedWithSuccess.get());
+    }
+
     /**
      * Forceful termination results in an empty affected connection points
      */
@@ -361,10 +404,49 @@ public class TestLifecycleChangeNotificationManager extends TestBase {
         terminationOperation.setOperationType(OperationType.TERMINATE);
         //when
         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
-        assertNull(affectedConnectionPoints.getValue());
+        assertFalse(affectedConnectionPoints.getValue().isPresent());
         verify(logger).warn("Unable to send information related to affected connection points during forceful termination");
     }
 
+    /**
+     * Failures in affected connection point processing are tolerated for failed operation
+     * (because the POST script was not able to run)
+     */
+    @Test
+    public void testFailedOperations() throws Exception {
+        //given
+        recievedLcn.setOperation(OperationType.INSTANTIATE);
+        recievedLcn.setStatus(OperationStatus.FAILED);
+        recievedLcn.setLifecycleOperationOccurrenceId(instantiationOperation.getId());
+        instantiationOperation.setAdditionalData(null);
+        instantiationOperation.setStatus(OperationStatus.FAILED);
+        //when
+        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+        //verify
+        assertFalse(affectedConnectionPoints.getValue().isPresent());
+        verify(logger).warn("The operation failed and the affected connection points were not reported");
+    }
+
+    /**
+     * Failures in affected connection point processing are tolerated for failed operation
+     * (because the POST script was not able to run)
+     */
+    @Test
+    public void testMissingOperationResult() throws Exception {
+        //given
+        recievedLcn.setOperation(OperationType.INSTANTIATE);
+        recievedLcn.setStatus(OperationStatus.FAILED);
+        recievedLcn.setLifecycleOperationOccurrenceId(instantiationOperation.getId());
+        instantiationOperation.setStatus(OperationStatus.FAILED);
+        JsonObject additionalData = (JsonObject) instantiationOperation.getAdditionalData();
+        additionalData.remove("operationResult");
+        //when
+        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+        //verify
+        assertFalse(affectedConnectionPoints.getValue().isPresent());
+        verify(logger).warn("The operation failed and the affected connection points were not reported");
+    }
+
     /**
      * test end notification scenario for failed scale-out
      * - LCN is sent to VF-C, but the
@@ -384,11 +466,57 @@ public class TestLifecycleChangeNotificationManager extends TestBase {
         scaleOperation.setOperationType(OperationType.SCALE);
         //when
         lifecycleChangeNotificationManager.handleLcn(recievedLcn);
-        assertEquals(0, affectedConnectionPoints.getValue().getPost().size());
-        assertEquals(0, affectedConnectionPoints.getValue().getPre().size());
+        assertFalse(affectedConnectionPoints.getValue().isPresent());
+        verify(logger).warn("The operation failed and the affected connection points were not reported");
+    }
+
+    /**
+     * if the cbam_post is missing error handling should be applied
+     */
+    @Test
+    public void testMissingPostResultForFailedOperation() {
+        //given
+        recievedLcn.setOperation(OperationType.SCALE);
+        recievedLcn.setStatus(OperationStatus.FAILED);
+        recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
+        ScaleVnfRequest request = new ScaleVnfRequest();
+        request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
+        request.setType(ScaleDirection.OUT);
+        scaleOperation.setOperationParams(request);
+        scaleOperation.setStatus(OperationStatus.FAILED);
+        ((JsonObject) scaleOperation.getAdditionalData()).get("operationResult").getAsJsonObject().remove("cbam_post");
+        scaleOperation.setOperationType(OperationType.SCALE);
+        //when
+        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+        assertFalse(affectedConnectionPoints.getValue().isPresent());
         verify(logger).warn("The operation failed and the affected connection points were not reported");
     }
 
+    /**
+     * if invalid type is specified for cbam_post error handling should be applied
+     */
+    @Test
+    public void testInvalidPost() {
+        //given
+        recievedLcn.setOperation(OperationType.SCALE);
+        recievedLcn.setStatus(OperationStatus.FAILED);
+        recievedLcn.setLifecycleOperationOccurrenceId(scaleOperation.getId());
+        ScaleVnfRequest request = new ScaleVnfRequest();
+        request.setAdditionalParams(new JsonParser().parse("{ \"type\" : \"IN\", \"jobId\" : \"" + JOB_ID + "\" }"));
+        request.setType(ScaleDirection.OUT);
+        scaleOperation.setOperationParams(request);
+        scaleOperation.setStatus(OperationStatus.FAILED);
+        JsonObject operationResult = ((JsonObject) scaleOperation.getAdditionalData()).get("operationResult").getAsJsonObject();
+        operationResult.remove("cbam_post");
+        operationResult.addProperty("cbam_post", "");
+        scaleOperation.setOperationType(OperationType.SCALE);
+        //when
+        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
+        assertFalse(affectedConnectionPoints.getValue().isPresent());
+        verify(logger).warn("The operation failed and the affected connection points were not reported");
+    }
+
+
     /**
      * test end notification success scenario for scale-out
      * - LCN is sent to VF-C
@@ -419,24 +547,6 @@ public class TestLifecycleChangeNotificationManager extends TestBase {
         }
     }
 
-    /**
-     * missing connection points are tolerated in case of failed operations
-     */
-    @Test
-    public void testMissingConnectionPoints() {
-        //given
-        recievedLcn.setOperation(OperationType.INSTANTIATE);
-        recievedLcn.setStatus(OperationStatus.FAILED);
-        recievedLcn.setLifecycleOperationOccurrenceId(instantiationOperation.getId());
-        instantiationOperation.setAdditionalData(null);
-        instantiationOperation.setStatus(OperationStatus.FAILED);
-        //when
-        lifecycleChangeNotificationManager.handleLcn(recievedLcn);
-        assertEquals(0, affectedConnectionPoints.getValue().getPost().size());
-        assertEquals(0, affectedConnectionPoints.getValue().getPre().size());
-        verify(logger).warn("The operation failed and the affected connection points were not reported");
-    }
-
     private JsonObject buildTerminationParams() {
         JsonObject root = new JsonObject();
         root.add("terminationType", new JsonPrimitive("GRACEFULL"));
index a5e18ee..4f8415e 100644 (file)
@@ -18,6 +18,7 @@ topology_template:
         - virtual_compute: myCompute
         - virtual_storage: myStorage1
         - virtual_storage: myStorage2
+        - unhandled_type: unknown
 
 
     myCompute:
@@ -64,6 +65,30 @@ topology_template:
         - virtual_binding: vduNode
         - virtual_link: myNetwork1
 
+    icpWithOutDescription:
+      type: tosca.nodes.nfv.ICP
+      properties:
+        layer_protocol: ipv4
+      requirements:
+        - virtual_binding: vduNode
+        - virtual_link: myNetwork1
+
+    icpWithoutVdu:
+      type: tosca.nodes.nfv.ICP
+      properties:
+        layer_protocol: ipv4
+        description: myDescription
+      requirements:
+        - virtual_link: myNetwork1
+
+    icpWithOutVl:
+      type: tosca.nodes.nfv.ICP
+      properties:
+        layer_protocol: ipv4
+        description: myDescription
+      requirements:
+        - virtual_binding: vduNode
+
     myEcp:
       type: tosca.nodes.nfv.ECP
       properties:
@@ -71,15 +96,56 @@ topology_template:
       requirements:
         - internal_connection_point: icpWithEcp
 
+    myEcpWithDescription:
+      type: tosca.nodes.nfv.ECP
+      properties:
+        layer_protocol: ipv4
+      requirements:
+        - internal_connection_point: icpWithOutDescription
+
+    myEcpWithoutIcpWithoutVdu:
+      type: tosca.nodes.nfv.ECP
+      properties:
+        layer_protocol: ipv4
+      requirements:
+        - internal_connection_point: icpWithoutVdu
+
+    myEcpWithoutIcpWithoutIcpReq:
+      type: tosca.nodes.nfv.ECP
+      properties:
+        layer_protocol: ipv4
+      requirements:
+        - internal_connection_point: icpWithOutRequiements
+
+    myEcpWithoutIcp:
+      type: tosca.nodes.nfv.ECP
+      properties:
+        layer_protocol: ipv4
+      requirements:
+        - not_valid: d
+
     icpWithOutVdu:
       type: tosca.nodes.nfv.ICP
       properties:
         layer_protocol: ipv4
         description: myDescription
+      requirements:
+        - not_valid: a
+
+    icpWithOutRequiements:
+      type: tosca.nodes.nfv.ICP
+      properties:
+        layer_protocol: ipv4
+        description: myDescription
 
     ecpWithIcpWithOutVdu:
       type: tosca.nodes.nfv.ECP
       properties:
         layer_protocol: ipv4
       requirements:
-        - internal_connection_point: icpWithOutVdu
\ No newline at end of file
+        - internal_connection_point: icpWithOutVdu
+
+    ecpWithIcpWithOutRequirements:
+      type: tosca.nodes.nfv.ECP
+      properties:
+        layer_protocol: ipv4
\ No newline at end of file
index ddb96bf..51842a8 100644 (file)
@@ -70,6 +70,14 @@ topology_template:
       requirements:
         - virtual_binding: vduNode
         - virtual_link: myNetwork1
+    icpWithOutDescription:
+      type: tosca.nodes.nfv.VduCpd
+      properties:
+        layer_protocol: ipv4
+        role: leaf
+      requirements:
+        - virtual_binding: vduNode
+        - virtual_link: myNetwork1
     myEcp:
       type: tosca.nodes.nfv.VduCpd
       properties:
@@ -78,3 +86,10 @@ topology_template:
         description: myDescription
       requirements:
         - virtual_binding: vduNode
+    myEcpWithDescription:
+      type: tosca.nodes.nfv.VduCpd
+      properties:
+        layer_protocol: ipv4
+        role: leaf
+      requirements:
+        - virtual_binding: vduNode
index 478feda..87493f5 100644 (file)
@@ -1,5 +1,13 @@
 topology_template:
   policies:
+    - unkown_policy:
+        properties:
+          aspects:
+            aspect1:
+              vdus:
+                vdu1:
+                  - heatResource: wrapper_rg.0.server
+                  - heatResource: wrapper_rg.1.server
     - heat_mapping:
         properties:
           aspects:
@@ -9,4 +17,7 @@ topology_template:
                   - heatResource: wrapper_rg.0.server
                   - heatResource: wrapper_rg.1.server
                 vdu2:
-                  - heatResource: wrapper_rg2.0.server
\ No newline at end of file
+                  - heatResource: wrapper_rg2.0.server
+            emptyAspect: # does not make sense
+            aspectWithOutVdu: # does not make sense
+              network:
\ No newline at end of file