diff options
author | Denes Nemeth <denes.nemeth@nokia.com> | 2018-03-08 21:44:02 +0100 |
---|---|---|
committer | Denes Nemeth <denes.nemeth@nokia.com> | 2018-03-08 21:44:02 +0100 |
commit | f6228e56abb06a36212216bc5674e69e6c0d9610 (patch) | |
tree | e4f212d8c47c2484343989794fa93f6bd5566392 | |
parent | 270744e18b624e750e3a5f4fac59780068196147 (diff) |
Adding missing tests
Change-Id: I2b0de4c101535259f133436d6997ae393ba6c8ef
Signed-off-by: Denes Nemeth <denes.nemeth@nokia.com>
Issue-ID: VFC-728
19 files changed, 679 insertions, 242 deletions
diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/api/INotificationSender.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/api/INotificationSender.java index c601f5ac..55e9cca2 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/api/INotificationSender.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/api/INotificationSender.java @@ -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); } diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java index f283672e..1d9ef8dc 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java @@ -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); } diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java index 32c3f909..50f6221b 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java @@ -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; } } diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/OnapVnfdBuilder.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/OnapVnfdBuilder.java index 03c27a83..e628458d 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/OnapVnfdBuilder.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/OnapVnfdBuilder.java @@ -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); } } diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/ConverterApi.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/ConverterApi.java index 8eb2007b..790ac054 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/ConverterApi.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/ConverterApi.java @@ -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()); diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/util/SystemFunctions.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/util/SystemFunctions.java index b8c50b1a..0bb63039 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/util/SystemFunctions.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/util/SystemFunctions.java @@ -161,4 +161,5 @@ public class SystemFunctions { public CloseableHttpClient getHttpClient() { return HttpClients.createDefault(); } -} + +}
\ No newline at end of file diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/JobManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/JobManager.java index 2aba46b3..94cb404c 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/JobManager.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/JobManager.java @@ -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); } } diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/LifecycleManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/LifecycleManager.java index cbf5341d..b78c13a0 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/LifecycleManager.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/LifecycleManager.java @@ -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()); diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/LifecycleChangeNotificationManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/LifecycleChangeNotificationManager.java index 9ee8cbda..6a31e833 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/LifecycleChangeNotificationManager.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/LifecycleChangeNotificationManager.java @@ -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); } } } diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestGenericExternalSystemInfoProvider.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestGenericExternalSystemInfoProvider.java index 17cf8258..a0d4ea4d 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestGenericExternalSystemInfoProvider.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestGenericExternalSystemInfoProvider.java @@ -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; + } + } } diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcGrantManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcGrantManager.java index a2bf0305..4bbf0764 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcGrantManager.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcGrantManager.java @@ -159,6 +159,32 @@ public class TestVfcGrantManager extends TestBase { } /** + * 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 */ @Test @@ -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 { @@ -259,6 +285,54 @@ public class TestVfcGrantManager extends TestBase { } /** + * 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 */ @Test diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcNotificationSender.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcNotificationSender.java index 008d8272..d28e224f 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcNotificationSender.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/TestVfcNotificationSender.java @@ -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) { diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/TestOnapVnfdBuilder.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/TestOnapVnfdBuilder.java index fd93dce2..5001eedf 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/TestOnapVnfdBuilder.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/packagetransformer/TestOnapVnfdBuilder.java @@ -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"); + } /** diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestConverterApi.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestConverterApi.java index 95bdc5f4..218c478e 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestConverterApi.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestConverterApi.java @@ -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()); + } + } } diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestLifecycleManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestLifecycleManager.java index 3ff53643..c601f7ee 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestLifecycleManager.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestLifecycleManager.java @@ -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()); } /** diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java index 18567f4c..7121bea6 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/notification/TestLifecycleChangeNotificationManager.java @@ -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(); @@ -240,6 +238,19 @@ public class TestLifecycleChangeNotificationManager extends TestBase { } /** + * 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 */ @Test @@ -345,6 +356,38 @@ public class TestLifecycleChangeNotificationManager extends TestBase { } /** + * 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 */ @Test @@ -361,11 +404,50 @@ 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,12 +466,58 @@ 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")); diff --git a/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.cbam.yaml b/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.cbam.yaml index a5e18eec..4f8415e6 100644 --- a/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.cbam.yaml +++ b/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.cbam.yaml @@ -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 diff --git a/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.onap.yaml b/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.onap.yaml index ddb96bf0..51842a87 100644 --- a/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.onap.yaml +++ b/nokiav2/driver/src/test/resources/unittests/packageconverter/nodes.vnfd.onap.yaml @@ -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 diff --git a/nokiav2/driver/src/test/resources/unittests/vnfd.scale.yaml b/nokiav2/driver/src/test/resources/unittests/vnfd.scale.yaml index 478fedaf..87493f58 100644 --- a/nokiav2/driver/src/test/resources/unittests/vnfd.scale.yaml +++ b/nokiav2/driver/src/test/resources/unittests/vnfd.scale.yaml @@ -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 |