diff options
67 files changed, 4405 insertions, 435 deletions
diff --git a/nokiav2/deployment/pom.xml b/nokiav2/deployment/pom.xml index c58bc0ea..ff9bc505 100644 --- a/nokiav2/deployment/pom.xml +++ b/nokiav2/deployment/pom.xml @@ -26,72 +26,20 @@ <artifactId>vfc-nfvo-driver-vnfm-svnfm-nokiav2</artifactId> <version>1.1.0-SNAPSHOT</version> </parent> - <repositories> - <repository> - <id>project.local</id> - <name>project</name> - <url>file:${project.basedir}/src/repo</url> - </repository> - </repositories> <build> <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-dependency-plugin</artifactId> - <version>3.0.2</version> - <executions> - <execution> - <id>copy</id> - <phase>install</phase> - <goals> - <goal>copy</goal> - </goals> - </execution> - </executions> - <configuration> - <excludeTypes>pom</excludeTypes> - <artifactItems> - <artifactItem> - <artifactId>driverwar</artifactId> - <version>1.1.0-SNAPSHOT</version> - <groupId>org.onap.vfc.nfvo.driver.vnfm.svnfm.nokiav2</groupId> - <type>war</type> - <overWrite>true</overWrite> - <outputDirectory>${project.basedir}/src/main/resources</outputDirectory> - <destFileName>driver.war</destFileName> - </artifactItem> - </artifactItems> - </configuration> - </plugin> - <plugin> - <artifactId>maven-assembly-plugin</artifactId> - <version>3.1.0</version> - <configuration> - <descriptors> - <descriptor>src/assembly/assembly.xml</descriptor> - </descriptors> - </configuration> - <executions> - <execution> - <id>create-archive</id> - <phase>package</phase> - <goals> - <goal>single</goal> - </goals> - </execution> - </executions> - </plugin> + <!-- fail the bulid if xmlstarlet is not present in Jenkins env --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <configuration> - <executable>${project.basedir}/src/main/resources/build_image.sh</executable> + <executable>${project.basedir}/src/main/resources/test_xmlstarlet.sh</executable> <workingDirectory>${project.build.directory}</workingDirectory> </configuration> <executions> <execution> - <phase>package</phase> + <phase>compile</phase> <goals> <goal>exec</goal> </goals> diff --git a/nokiav2/deployment/src/main/resources/Dockerfile b/nokiav2/deployment/src/main/resources/Dockerfile index e42f7b94..2ad7209c 100755 --- a/nokiav2/deployment/src/main/resources/Dockerfile +++ b/nokiav2/deployment/src/main/resources/Dockerfile @@ -1,17 +1,16 @@ FROM centos:7 WORKDIR /service +ARG VERSION COPY docker-entrypoint.sh . COPY LICENSE ./ONAP_LICENSE COPY application.properties . -COPY driver.war . - RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf RUN sed -i 's|#baseurl=http://mirror.centos.org/centos|baseurl=http://mirrors.ocf.berkeley.edu/centos|' /etc/yum.repos.d/*.repo RUN yum -y update -RUN yum -y install java-1.8.0-openjdk-headless +RUN yum -y install java-1.8.0-openjdk-headless wget # Debugging tools withing the container -RUN yum -y install mc vim tcpdump wget net-tools nc strace telnet unzip -#RUN sed -i 's|#networkaddress.cache.ttl=-1|networkaddress.cache.ttl=10|' /usr/lib/jvm/jre/lib/security/java.security +RUN yum -y install mc vim tcpdump net-tools nc strace telnet unzip xmlstarlet +RUN wget -q -O driver.war "https://nexus.onap.org/service/local/artifact/maven/redirect?r=staging&g=org.onap.vfc.nfvo.driver.vnfm.svnfm.nokiav2&a=driverwar&v=${VERSION}&e=war" ENV JAVA_HOME /usr/lib/jvm/jre RUN yum clean all EXPOSE 8089 diff --git a/nokiav2/deployment/src/main/resources/build_image.sh b/nokiav2/deployment/src/main/resources/build_image.sh index 24706f86..384c213a 100755 --- a/nokiav2/deployment/src/main/resources/build_image.sh +++ b/nokiav2/deployment/src/main/resources/build_image.sh @@ -17,34 +17,46 @@ if [ "a$1" != "abuildDocker" ] ; then echo "Skipping building Docker image" + echo "If you would like to build the docker image by script execute $0 buildDocker" + echo "If you would like to build and push the docker image by script execute $0 buildDocker pushImage" echo "If you would like to build the docker image by maven execute mvn package -Dexec.args=\"buildDocker\"" + echo "If you would like to push the docker image by maven execute mvn package -Dexec.args=\"buildDocker pushImage\"" exit fi DIRNAME=`dirname $0` DOCKER_BUILD_DIR=`cd $DIRNAME/; pwd` -echo "DOCKER_BUILD_DIR=${DOCKER_BUILD_DIR}" +echo "----- Build directory ${DOCKER_BUILD_DIR}" cd ${DOCKER_BUILD_DIR} -BUILD_ARGS="--no-cache --squash" -ORG="onap" -VERSION="1.1.0" +VERSION=`xmlstarlet sel -t -v "/_:project/_:version" ../../../pom.xml | sed 's/-SNAPSHOT//g'` +echo "------ Detected version: $VERSION" + PROJECT="vfc" IMAGE="nfvo/svnfm/nokiav2" DOCKER_REPOSITORY="nexus3.onap.org:10003" +ORG="onap" +BUILD_ARGS="--no-cache" +# it looks like that ONAP jenkins does not support squash +#BUILD_ARGS="--no-cache --squash" + IMAGE_NAME="${DOCKER_REPOSITORY}/${ORG}/${PROJECT}/${IMAGE}" TIMESTAMP=$(date +"%Y%m%dT%H%M%S") if [ $HTTP_PROXY ]; then + echo "----- Using HTTP proxy ${HTTP_PROXY}" BUILD_ARGS+=" --build-arg HTTP_PROXY=${HTTP_PROXY}" fi + if [ $HTTPS_PROXY ]; then + echo "----- Using HTTPS proxy ${HTTPS_PROXY}" BUILD_ARGS+=" --build-arg HTTPS_PROXY=${HTTPS_PROXY}" fi function build_image { echo "Start build docker image: ${IMAGE_NAME}" - docker build ${BUILD_ARGS} -t ${IMAGE_NAME}:latest . + echo "docker build --build-arg VERSION=${VERSION} ${BUILD_ARGS} -t ${IMAGE_NAME}:latest ." + docker build --build-arg VERSION=${VERSION} ${BUILD_ARGS} -t ${IMAGE_NAME}:latest . } function push_image_tag { diff --git a/nokiav2/deployment/src/main/resources/test_xmlstarlet.sh b/nokiav2/deployment/src/main/resources/test_xmlstarlet.sh new file mode 100755 index 00000000..f5ee03d3 --- /dev/null +++ b/nokiav2/deployment/src/main/resources/test_xmlstarlet.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +DIRNAME=`dirname $0` +BUILD_DIR=`cd $DIRNAME/; pwd` + +#If xmlstarlet is not present build will fail +xmlstarlet ed ${BUILD_DIR}/../../../pom.xml diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml deleted file mode 100644 index d0c75b95..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<metadata modelVersion="1.1.0"> - <groupId>org.onap.vfc.nfvo.driver.vnfm.svnfm</groupId> - <artifactId>vfc-nfvo-driver-vnfm-svnfm</artifactId> - <version>1.1.0-SNAPSHOT</version> - <versioning> - <snapshot> - <timestamp>20180308.094402</timestamp> - <buildNumber>1</buildNumber> - </snapshot> - <lastUpdated>20180308094402</lastUpdated> - <snapshotVersions> - <snapshotVersion> - <extension>pom</extension> - <value>1.1.0-20180308.094402-1</value> - <updated>20180308094402</updated> - </snapshotVersion> - </snapshotVersions> - </versioning> -</metadata> diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml.md5 b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml.md5 deleted file mode 100644 index 472b3e80..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml.md5 +++ /dev/null @@ -1 +0,0 @@ -60b7495445e0beefa15d6d99e1a6e414
\ No newline at end of file diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml.sha1 b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml.sha1 deleted file mode 100644 index ed4fb1f0..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/maven-metadata.xml.sha1 +++ /dev/null @@ -1 +0,0 @@ -a459cd0bb4960a3484035c0d3c8f877f467be5a5
\ No newline at end of file diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom deleted file mode 100644 index ffe5bc6a..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0"?> -<!-- - Copyright 2017 ZTE Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <parent> - <groupId>org.onap.oparent</groupId> - <artifactId>oparent</artifactId> - <version>0.1.1</version> - </parent> - <modelVersion>4.0.0</modelVersion> - <groupId>org.onap.vfc.nfvo.driver.vnfm.svnfm</groupId> - <artifactId>vfc-nfvo-driver-vnfm-svnfm</artifactId> - <version>1.1.0-SNAPSHOT</version> - <packaging>pom</packaging> - <name>vfc-nfvo-driver-vnfm-svnfm</name> - <description>vfc-nfvo-driver-vnfm-svnfm</description> - <modules> - <module>zte</module> - <module>huawei</module> - <module>nokia</module> - <module>nokiav2</module> - </modules> -</project> diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom.md5 b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom.md5 deleted file mode 100644 index 48473a22..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom.md5 +++ /dev/null @@ -1 +0,0 @@ -e8f2e2ef2633830bbe80a3b78391e1b2
\ No newline at end of file diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom.sha1 b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom.sha1 deleted file mode 100644 index f4fe3764..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/1.1.0-SNAPSHOT/vfc-nfvo-driver-vnfm-svnfm-1.1.0-20180308.094402-1.pom.sha1 +++ /dev/null @@ -1 +0,0 @@ -8f3224dcebfb83ec7dfd637f013728d55e701f5c
\ No newline at end of file diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml deleted file mode 100644 index 5bd2a7c0..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<metadata> - <groupId>org.onap.vfc.nfvo.driver.vnfm.svnfm</groupId> - <artifactId>vfc-nfvo-driver-vnfm-svnfm</artifactId> - <versioning> - <versions> - <version>1.1.0-SNAPSHOT</version> - </versions> - <lastUpdated>20180308094402</lastUpdated> - </versioning> -</metadata> diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml.md5 b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml.md5 deleted file mode 100644 index 6fe29e47..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml.md5 +++ /dev/null @@ -1 +0,0 @@ -33379de33c0323f40765da74d9c89c23
\ No newline at end of file diff --git a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml.sha1 b/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml.sha1 deleted file mode 100644 index 6a3c1f7b..00000000 --- a/nokiav2/deployment/src/repo/org/onap/vfc/nfvo/driver/vnfm/svnfm/vfc-nfvo-driver-vnfm-svnfm/maven-metadata.xml.sha1 +++ /dev/null @@ -1 +0,0 @@ -170dc16b9adbbbac54cc418990ae9ac03ee7ce9e
\ No newline at end of file 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/core/MsbApiProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/MsbApiProvider.java index ec98e966..64a418de 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/MsbApiProvider.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/MsbApiProvider.java @@ -60,9 +60,7 @@ public class MsbApiProvider extends IpMappingProvider { public String getMicroServiceUrl(String name, String version) { MicroServiceFullInfo microServiceFullInfo = getMicroServiceInfo(name, version); String ipAnPort = getNodeIpAnPort(microServiceFullInfo); - //FIXME the enable_ssl field should be used, but it is not available in SDK - //depends on https://jira.onap.org/browse/MSB-151 - String protocol = (ipAnPort.endsWith(":8443") || ipAnPort.endsWith(":443")) ? "https://" : "http://"; + String protocol = microServiceFullInfo.isEnable_ssl() ? "https://" : "http://"; //the field name in A&AI is misleading the URL is relative path postfixed to http(s)://ip:port return protocol + ipAnPort + microServiceFullInfo.getUrl(); } diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/SelfRegistrationManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/SelfRegistrationManager.java index 3fda6192..a9e11653 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/SelfRegistrationManager.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/SelfRegistrationManager.java @@ -140,8 +140,7 @@ public class SelfRegistrationManager { microServiceInfo.setVisualRange(INTERNAL_SERVICE); microServiceInfo.setServiceName(SERVICE_NAME); microServiceInfo.setVersion(DRIVER_VERSION); - //FIXME set enable_ssl to false after the field has been added to MSB SDK https://jira.onap.org/browse/MSB-151 - //currently defaults to false, which is good + microServiceInfo.setEnable_ssl(true); Node node = new Node(); microServiceInfo.setNodes(new HashSet<>()); microServiceInfo.getNodes().add(node); diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/AAIExternalSystemInfoProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/AAIExternalSystemInfoProvider.java new file mode 100644 index 00000000..f5656f75 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/AAIExternalSystemInfoProvider.java @@ -0,0 +1,120 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import org.onap.aai.domain.yang.v11.EsrSystemInfo; +import org.onap.aai.domain.yang.v11.EsrSystemInfoList; +import org.onap.aai.domain.yang.v11.EsrVnfm; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.GenericExternalSystemInfoProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vnfmdriver.model.VimInfo; +import org.onap.vnfmdriver.model.VnfmInfo; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import static java.lang.String.format; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.CLOUD; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.ESR; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getCloudOwner; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getRegionName; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for providing information related to the VNFM from VF-C source + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +public class AAIExternalSystemInfoProvider extends GenericExternalSystemInfoProvider { + private static final String VNFM_URL = "/esr-vnfm-list/esr-vnfm/%s?depth=all"; + private static final String VIM_URL = "/cloud-regions/cloud-region/%s/%s/esr-system-info-list"; + private static Logger logger = getLogger(AAIExternalSystemInfoProvider.class); + private final AAIRestApiProvider aaiRestApiProvider; + + @Autowired + AAIExternalSystemInfoProvider(Environment environment, AAIRestApiProvider aaiRestApiProvider) { + super(environment); + this.aaiRestApiProvider = aaiRestApiProvider; + } + + @Override + public VnfmInfo queryVnfmInfoFromSource(String vnfmId) { + try { + return convertEsrToVnfmInfo(aaiRestApiProvider.get(logger, ESR, format(VNFM_URL, vnfmId), EsrVnfm.class)); + } catch (RuntimeException e) { + throw buildFatalFailure(logger, "Unable to query VNFM with " + vnfmId + " identifier from AAI", e); + } + } + + @Override + public VimInfo getVimInfo(String vimId) { + try { + return convertEsrToVim(getEsrSystemInfo(vimId), vimId); + } catch (RuntimeException e) { + throw buildFatalFailure(logger, "Unable to query VIM with " + vimId + " identifier from AAI", e); + } + } + + /** + * @param vimId the identifier of the VIM + * @return the VIM details + */ + public EsrSystemInfo getEsrSystemInfo(String vimId) { + String url = format(VIM_URL, getCloudOwner(vimId), getRegionName(vimId)); + return aaiRestApiProvider.get(logger, CLOUD, url, EsrSystemInfoList.class).getEsrSystemInfo().get(0); + } + + private VimInfo convertEsrToVim(EsrSystemInfo esrSystemInfo, String vimId) { + VimInfo vimInfo = new VimInfo(); + vimInfo.setDescription(esrSystemInfo.getSystemName()); + vimInfo.setName(esrSystemInfo.getSystemName()); + vimInfo.setPassword(esrSystemInfo.getPassword()); + vimInfo.setStatus(esrSystemInfo.getSystemStatus()); + vimInfo.setType(esrSystemInfo.getType()); + vimInfo.setUrl(esrSystemInfo.getServiceUrl()); + vimInfo.setVersion(esrSystemInfo.getVersion()); + if (esrSystemInfo.getSslCacert() == null) { + vimInfo.setSslInsecure("true"); + } else { + vimInfo.setSslInsecure("false"); + vimInfo.setSslCacert(esrSystemInfo.getSslCacert()); + } + vimInfo.setUserName(esrSystemInfo.getUserName()); + vimInfo.setVendor(esrSystemInfo.getVendor()); + vimInfo.setVimId(vimId); + return vimInfo; + } + + + private VnfmInfo convertEsrToVnfmInfo(EsrVnfm vnfmInAai) { + EsrSystemInfo esrSystemInfo = vnfmInAai.getEsrSystemInfoList().getEsrSystemInfo().get(0); + VnfmInfo vnfmInfo = new VnfmInfo(); + vnfmInfo.setPassword(esrSystemInfo.getPassword()); + vnfmInfo.setDescription(esrSystemInfo.getEsrSystemInfoId()); + vnfmInfo.setName(esrSystemInfo.getSystemName()); + vnfmInfo.setType(esrSystemInfo.getType()); + vnfmInfo.setUrl(esrSystemInfo.getServiceUrl()); + vnfmInfo.setVersion(esrSystemInfo.getVersion()); + vnfmInfo.setVimId(vnfmInAai.getVimId()); + vnfmInfo.setVendor(esrSystemInfo.getVendor()); + vnfmInfo.setUserName(esrSystemInfo.getUserName()); + vnfmInfo.setVnfmId(vnfmInAai.getVnfmId()); + return vnfmInfo; + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/AAIRestApiProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/AAIRestApiProvider.java new file mode 100644 index 00000000..141ba847 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/AAIRestApiProvider.java @@ -0,0 +1,183 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import com.google.common.annotations.VisibleForTesting; +import org.onap.aai.restclient.client.Headers; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; +import org.onap.aai.restclient.enums.RestAuthenticationMode; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.MsbApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Conditional; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; + +import javax.xml.bind.JAXBContext; +import java.io.ByteArrayOutputStream; +import java.io.StringReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import static com.google.common.collect.Lists.newArrayList; +import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.SelfRegistrationManager.SERVICE_NAME; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for providing access to AAI APIs. + * Handles authentication and mandatory parameters. + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +public class AAIRestApiProvider { + private static final String AAI_VERSION = "v11"; + private static Logger logger = getLogger(AAIRestApiProvider.class); + private final MsbApiProvider msbApiProvider; + @Value("${aaiUsername}") + private String aaiUsername; + @Value("${aaiPassword}") + private String aaiPassword; + + @Autowired + AAIRestApiProvider(MsbApiProvider msbApiProvider) { + this.msbApiProvider = msbApiProvider; + } + + /** + * @param logger the logger of the class that requests unmarshalling + * @param service the AAI service of the request + * @param url the URL of the request after the base URL (ex. /cloud-infrastructure/...) + * @param clazz the class of the result + * @param <T> the type of the result + * @return the result of the GET request + */ + public <T> T get(Logger logger, AAIService service, String url, Class<T> clazz) { + return expectSuccess(logger, buildClient().get(getBaseUrl(service.getServiceName()) + url, buildCommonHeaders(), APPLICATION_XML_TYPE), clazz, url); + } + + /** + * @param logger the logger of the class that requests unmarshalling + * @param service the AAI service of the request + * @param url the URL of the request after the base URL (ex. /cloud-infrastructure/...) + * @param payload the payload of the request (non serialized) + * @param clazz the class of the result + * @param <T> the type of the result + * @return the result of the PUT request + */ + public <T, S> T put(Logger logger, AAIService service, String url, S payload, Class<T> clazz) { + String marshalledContent = marshall(payload); + OperationResult result = buildClient().put(getBaseUrl(service.getServiceName()) + url, marshalledContent, buildCommonHeaders(), APPLICATION_XML_TYPE, APPLICATION_XML_TYPE); + return expectSuccess(logger, result, clazz, url); + } + + /** + * Execute a delete request on the given URL + * + * @param logger the logger of the class that requests unmarshalling + * @param service the AAI service of the request + * @param url the URL of the request after the base URL (ex. /cloud-infrastructure/...) + */ + public void delete(Logger logger, AAIService service, String url) { + buildClient().delete(getBaseUrl(service.getServiceName()) + url, buildCommonHeaders(), APPLICATION_XML_TYPE); + } + + /** + * @param serviceName the name of the AAI service on MSB + * @return the base URL of the service + */ + private String getBaseUrl(String serviceName) { + return msbApiProvider.getMicroServiceUrl(serviceName, AAI_VERSION); + } + + private <T> T expectSuccess(Logger logger, OperationResult result, Class<T> clazz, String url) { + if (!result.wasSuccessful()) { + if (result.getResultCode() == 404) { + logger.debug("The resource at " + url + " does not exists"); + throw new NoSuchElementException("The resource at " + url + " does not exists"); + } + throw buildFatalFailure(logger, "Bad response. Code: " + result.getResultCode() + " cause: " + result.getFailureCause()); + } + if (clazz.isAssignableFrom(Void.class)) { + return null; + } + return unmarshal(result.getResult(), clazz); + } + + private <T> T unmarshal(String content, Class<T> clazz) { + try { + return (T) JAXBContext.newInstance(clazz).createUnmarshaller().unmarshal(new StringReader(content)); + } catch (Exception e) { + throw buildFatalFailure(logger, "Unable to unmarshal content", e); + } + } + + private String marshall(Object object) { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + JAXBContext.newInstance(object.getClass()).createMarshaller().marshal(object, bos); + return bos.toString(); + } catch (Exception e) { + throw buildFatalFailure(logger, "Unable to marshal content", e); + } + } + + /** + * @return the common mandatory headers for AAI requests + */ + private Map<String, List<String>> buildCommonHeaders() { + Map<String, List<String>> headers = new HashMap<>(); + headers.put(Headers.ACCEPT, newArrayList(MediaType.APPLICATION_XML_VALUE)); + headers.put(Headers.FROM_APP_ID, newArrayList(SERVICE_NAME)); + return headers; + } + + + private RestClient buildClient() { + return buildRawClient().basicAuthUsername(aaiUsername).basicAuthPassword(aaiPassword).authenticationMode(RestAuthenticationMode.SSL_BASIC); + } + + @VisibleForTesting + RestClient buildRawClient() { + return new RestClient(); + } + + public enum AAIService { + NETWORK { + String getServiceName() { + return "aai-network"; + } + }, + ESR { + String getServiceName() { + return "aai-externalSystem"; + } + }, + CLOUD { + String getServiceName() { + return "aai-cloudInfrastructure"; + } + }; + + abstract String getServiceName(); + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/GrantlessGrantManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/GrantlessGrantManager.java new file mode 100644 index 00000000..a113405a --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/GrantlessGrantManager.java @@ -0,0 +1,65 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import com.nokia.cbam.lcm.v32.model.VnfInfo; +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.vnfmdriver.model.GrantVNFResponseVim; +import org.onap.vnfmdriver.model.VnfHealRequest; +import org.onap.vnfmdriver.model.VnfScaleRequest; +import org.slf4j.Logger; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for handling granting before the execution of a VNF operation in case of direct integration + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +public class GrantlessGrantManager implements IGrantManager { + private static Logger logger = getLogger(GrantlessGrantManager.class); + + @Override + public void requestGrantForHeal(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfHealRequest request, String jobId) { + noGrantRequested(); + } + + @Override + public void requestGrantForScale(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfScaleRequest request, String jobId) { + noGrantRequested(); + } + + @Override + public void requestGrantForTerminate(String vnfmId, String vnfId, String vimId, String onapVnfdId, VnfInfo vnf, String jobId) { + noGrantRequested(); + } + + @Override + public GrantVNFResponseVim requestGrantForInstantiate(String vnfmId, String vnfId, String vimId, String onapVnfdId, String instantiationLevelId, String cbamVnfdContent, String jobId) { + noGrantRequested(); + GrantVNFResponseVim grantResponse = new GrantVNFResponseVim(); + grantResponse.setVimId(vimId); + return grantResponse; + } + + private void noGrantRequested() { + logger.info("No grant is requested in direct mode"); + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/SdcPackageProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/SdcPackageProvider.java new file mode 100644 index 00000000..8a165478 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/SdcPackageProvider.java @@ -0,0 +1,105 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IPackageProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.MsbApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; +import org.yaml.snakeyaml.Yaml; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import static com.google.common.io.ByteStreams.toByteArray; +import static java.lang.String.format; +import static org.apache.http.HttpHeaders.ACCEPT; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.SelfRegistrationManager.SERVICE_NAME; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.*; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions.systemFunctions; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CatalogManager.getFileInZip; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CatalogManager.getVnfdLocation; +import static org.slf4j.LoggerFactory.getLogger; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; + +/** + * Responsible for providing access to AAI APIs. + * Handles authentication and mandatory parameters. + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +public class SdcPackageProvider implements IPackageProvider { + private static final String SDC_MSB_NAME = "sdc"; + private static final String SDC_MSB_VERSION = "v1"; + private static final String GET_PACKAGE_URL = "%s/sdc/v1/catalog/resources/%s/toscaModel"; + private static Logger logger = getLogger(SdcPackageProvider.class); + private final MsbApiProvider msbApiProvider; + private final DriverProperties driverProperties; + @Value("${sdcUsername}") + private String sdcUsername; + @Value("${sdcPassword}") + private String sdcPassword; + + @Autowired + SdcPackageProvider(MsbApiProvider msbApiProvider, DriverProperties driverProperties) { + this.msbApiProvider = msbApiProvider; + this.driverProperties = driverProperties; + } + + @Override + public byte[] getPackage(String csarId) { + String baseUrl = msbApiProvider.getMicroServiceUrl(SDC_MSB_NAME, SDC_MSB_VERSION); + try { + CloseableHttpClient client = systemFunctions().getHttpClient(); + HttpGet httpget = new HttpGet(format(GET_PACKAGE_URL, baseUrl, csarId)); + httpget.setHeader(ACCEPT, APPLICATION_OCTET_STREAM_VALUE); + httpget.setHeader("X-ECOMP-InstanceID", driverProperties.getVnfmId()); + httpget.setHeader("X-FromAppId", SERVICE_NAME); + CloseableHttpResponse response = client.execute(httpget); + HttpEntity entity = response.getEntity(); + InputStream is = entity.getContent(); + byte[] bytes = toByteArray(is); + client.close(); + return bytes; + } catch (Exception e) { + throw buildFatalFailure(logger, "Unable to download " + csarId + " package from SDC", e); + } + } + + @Override + public String getCbamVnfdId(String csarId) { + byte[] onapPackage = getPackage(csarId); + try { + String vnfdLocation = getVnfdLocation(new ByteArrayInputStream(onapPackage)); + String onapVnfdContent = getFileInZip(new ByteArrayInputStream(onapPackage), vnfdLocation).toString(); + JsonObject root = new Gson().toJsonTree(new Yaml().load(onapVnfdContent)).getAsJsonObject(); + return childElement(child(root, "metadata"), "resourceVendorModelNumber").getAsString(); + } catch (Exception e) { + throw buildFatalFailure(logger, "Unable to extract CBAM VNFD id from ONAP package", e); + } + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/AAINotificationProcessor.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/AAINotificationProcessor.java new file mode 100644 index 00000000..ff2bde8a --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/AAINotificationProcessor.java @@ -0,0 +1,146 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.nokia.cbam.lcm.v32.model.AffectedVirtualLink; +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.api.INotificationSender; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +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.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.tryFind; +import static com.nokia.cbam.lcm.v32.model.ChangeType.*; +import static com.nokia.cbam.lcm.v32.model.OperationStatus.STARTED; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.LInterfaceManager.buildUrl; +import static org.slf4j.LoggerFactory.getLogger; +import static org.springframework.util.StringUtils.isEmpty; + +/** + * Responsible for providing information related to the VNFM from VF-C source + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +public class AAINotificationProcessor implements INotificationSender { + private static Logger logger = getLogger(AAINotificationProcessor.class); + private final GenericVnfManager genericVnfManager; + private final L3NetworkManager l3NetworkManager; + private final LInterfaceManager lInterfaceManager; + private final VnfcManager vnfcManager; + private final VserverManager vserverManager; + + @Autowired + AAINotificationProcessor(GenericVnfManager genericVnfManager, L3NetworkManager l3NetworkManager, LInterfaceManager lInterfaceManager, VnfcManager vnfcManager, VserverManager vserverManager) { + this.genericVnfManager = genericVnfManager; + this.l3NetworkManager = l3NetworkManager; + this.lInterfaceManager = lInterfaceManager; + this.vnfcManager = vnfcManager; + this.vserverManager = vserverManager; + } + + @Override + public void processNotification(VnfLifecycleChangeNotification receivedNotification, OperationExecution operationExecution, Optional<ReportedAffectedConnectionPoints> affectedConnectionPoints, String vimId) { + boolean inMaintenance = STARTED.equals(receivedNotification.getStatus()); + genericVnfManager.createOrUpdate(receivedNotification.getVnfInstanceId(), inMaintenance); + addOrUpdateVls(receivedNotification, vimId); + addOrUpdateVnfcs(receivedNotification, vimId, inMaintenance); + processCps(receivedNotification, affectedConnectionPoints, vimId, inMaintenance); + removeVnfcs(receivedNotification, vimId); + removeVls(receivedNotification); + logger.info("Notification processed successfully"); + } + + private void removeVls(VnfLifecycleChangeNotification receivedNotification) { + for (AffectedVirtualLink removedVl : filter(receivedNotification.getAffectedVirtualLinks(), affectedVirtualLink -> affectedVirtualLink.getChangeType().equals(REMOVED))) { + l3NetworkManager.delete(receivedNotification.getVnfInstanceId(), removedVl); + } + } + + private void removeVnfcs(VnfLifecycleChangeNotification receivedNotification, String vimId) { + for (com.nokia.cbam.lcm.v32.model.AffectedVnfc removedVnfc : filter(receivedNotification.getAffectedVnfcs(), vnfc -> REMOVED.equals(vnfc.getChangeType()))) { + vnfcManager.delete(receivedNotification.getVnfInstanceId(), removedVnfc); + vserverManager.delete(vimId, removedVnfc); + } + } + + private void processCps(VnfLifecycleChangeNotification receivedNotification, Optional<ReportedAffectedConnectionPoints> affectedConnectionPoints, String vimId, boolean inMaintenance) { + if (affectedConnectionPoints.isPresent()) { + for (ReportedAffectedCp removedCp : collectCpsToBeDeleted(vimId, affectedConnectionPoints.get())) { + lInterfaceManager.delete(vimId, removedCp); + } + //these can only be added or modified because if something is in the post CPS it can not be removed + //since it is present after the operation + for (ReportedAffectedCp affectedCp : affectedConnectionPoints.get().getPost()) { + if (!isEmpty(affectedCp.getServerProviderId())) { + lInterfaceManager.update(receivedNotification.getVnfInstanceId(), vimId, affectedCp, inMaintenance); + } + else{ + logger.warn("The changed {} connection point is not linked to any server", affectedCp.getCpId()); + } + } + } + else{ + logger.warn("The changed connection points are not present in VNF with {} identifier", receivedNotification.getVnfInstanceId()); + } + } + + private void addOrUpdateVnfcs(VnfLifecycleChangeNotification receivedNotification, String vimId, boolean inMaintenance) { + for (com.nokia.cbam.lcm.v32.model.AffectedVnfc affectedVnfc : receivedNotification.getAffectedVnfcs()) { + if (affectedVnfc.getChangeType() == MODIFIED || affectedVnfc.getChangeType() == ADDED) { + vserverManager.update(vimId, receivedNotification.getVnfInstanceId(), affectedVnfc, receivedNotification.getAffectedVirtualStorages(), inMaintenance); + vnfcManager.update(vimId, VserverManager.getTenantId(affectedVnfc), receivedNotification.getVnfInstanceId(), affectedVnfc, inMaintenance); + } + } + } + + private void addOrUpdateVls(VnfLifecycleChangeNotification receivedNotification, String vimId) { + for (AffectedVirtualLink affectedVirtualLink : receivedNotification.getAffectedVirtualLinks()) { + if ((affectedVirtualLink.getChangeType() == MODIFIED) || (affectedVirtualLink.getChangeType() == ADDED)) { + l3NetworkManager.update(vimId, receivedNotification.getVnfInstanceId(), affectedVirtualLink); + } + } + } + + /** + * The ports that are present in the pre, but not present in the post are + * removed regardless of the "removed" flag being present in the pre, because + * that only signals the remove intention, but does not actually mean that + * the resource have been removed + */ + private Collection<ReportedAffectedCp> collectCpsToBeDeleted(String vimId, ReportedAffectedConnectionPoints cps) { + Set<ReportedAffectedCp> cpsToRemove = new HashSet<>(); + for (ReportedAffectedCp cpBeforeOperation : cps.getPre()) { + if (!isEmpty(cpBeforeOperation.getServerProviderId())) { + String originalResource = buildUrl(vimId, cpBeforeOperation); + if (!tryFind(cps.getPost(), cpAfterOperation -> originalResource.equals(buildUrl(vimId, cpAfterOperation))).isPresent()) { + cpsToRemove.add(cpBeforeOperation); + } + } + } + return cpsToRemove; + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/AbstractManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/AbstractManager.java new file mode 100644 index 00000000..c8008f38 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/AbstractManager.java @@ -0,0 +1,143 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.google.gson.Gson; +import org.onap.aai.domain.yang.v11.ObjectFactory; +import org.onap.aai.domain.yang.v11.Relationship; +import org.onap.aai.domain.yang.v11.RelationshipData; +import org.onap.aai.domain.yang.v11.RelationshipList; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.slf4j.Logger; + +import java.util.HashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; + +import static com.google.common.collect.Iterables.find; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.SEPARATOR; + +/** + * Handles the common management of changing entities in AAI + */ +abstract class AbstractManager { + protected static final ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + protected final AAIRestApiProvider aaiRestApiProvider; + protected final CbamRestApiProvider cbamRestApiProvider; + protected final DriverProperties driverProperties; + + AbstractManager(AAIRestApiProvider aaiRestApiProvider, CbamRestApiProvider cbamRestApiProvider, DriverProperties driverProperties) { + this.aaiRestApiProvider = aaiRestApiProvider; + this.cbamRestApiProvider = cbamRestApiProvider; + this.driverProperties = driverProperties; + } + + /** + * @param key the key of the relationship + * @param value the value of the relationship + * @return the relationship + */ + protected static RelationshipData buildRelationshipData(String key, String value) { + RelationshipData data = new RelationshipData(); + data.setRelationshipKey(key); + data.setRelationshipValue(value); + return data; + } + + /** + * Extract mandatory value from the additional data on LCN resources + * + * @param additionalData the additional data + * @param key the key of the additional data + * @return the value of the additional data + */ + protected static String extractMandatoryValue(Object additionalData, String key) { + return new Gson().toJsonTree(additionalData).getAsJsonObject().get(key).getAsString(); + } + + /** + * Create or update the singleton relationship. Singleton means that relationships can only have a + * single {@link Relationship} with the given {@link Relationship#getRelatedTo} value + * + * @param relationships the list of relationships + * @param relationship the expected relationship + */ + protected static void addSingletonRelation(RelationshipList relationships, Relationship relationship) { + boolean found = false; + for (Relationship currentRelationShip : relationships.getRelationship()) { + if (relationship.getRelatedTo().equals(currentRelationShip.getRelatedTo())) { + found = true; + } + } + if (!found) { + relationships.getRelationship().add(relationship); + } else { + Relationship existingRelationShip = find(relationships.getRelationship(), currentRelationShip -> currentRelationShip.getRelatedTo().equals(relationship.getRelatedTo())); + existingRelationShip.getRelationshipData().clear(); + existingRelationShip.getRelationshipData().addAll(relationship.getRelationshipData()); + } + } + + /** + * Add the given relationship if it is already not part of the relationships + * + * @param relationships the relationships + * @param relationship the relationship to be added + */ + protected static void addMissingRelation(RelationshipList relationships, Relationship relationship) { + for (Relationship currentRelationShip : relationships.getRelationship()) { + if (currentRelationShip.getRelatedTo().equals(relationship.getRelatedTo()) + && compositeKeys(currentRelationShip.getRelationshipData()).equals(compositeKeys(relationship.getRelationshipData()))) { + return; + } + } + relationships.getRelationship().add(relationship); + } + + private static Set<String> compositeKeys(List<RelationshipData> data) { + Set<String> keys = new HashSet<>(); + for (RelationshipData relationshipData : data) { + keys.add(relationshipData.getRelationshipKey() + SEPARATOR + relationshipData.getRelationshipValue()); + } + return keys; + } + + /** + * @return the concrete logger to be used + */ + protected abstract Logger getLogger(); + + /** + * Creates or returns a REST resource instance + * + * @param service the type of the service + * @param url the URL of the resource without the service prefix + * @param newInstance the empty instance if the resource does not exists + * @param <T> the type of the resource + * @return the created or queried resource + */ + protected <T> T createOrGet(AAIRestApiProvider.AAIService service, String url, T newInstance) { + try { + return (T) aaiRestApiProvider.get(getLogger(), service, url, newInstance.getClass()); + } catch (NoSuchElementException e) { + getLogger().debug("The resource on " + url + " URL was not found in AAI", e); + return newInstance; + } + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/GenericVnfManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/GenericVnfManager.java new file mode 100644 index 00000000..959177c1 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/GenericVnfManager.java @@ -0,0 +1,114 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.nokia.cbam.lcm.v32.ApiException; +import com.nokia.cbam.lcm.v32.model.VnfInfo; +import org.onap.aai.domain.yang.v11.GenericVnf; +import org.onap.aai.domain.yang.v11.Relationship; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import java.util.NoSuchElementException; + +import static java.lang.String.format; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.NETWORK; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions.systemFunctions; + +/** + * Responsible for managing the {@link GenericVnf} in AAI + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +class GenericVnfManager extends AbstractManager { + private static final String VNF_URL = "/generic-vnfs/generic-vnf/%s"; + private static final long MAX_MS_TO_WAIT_FOR_VNF_TO_APPEAR = 30 * 1000L; + private static Logger logger = org.slf4j.LoggerFactory.getLogger(GenericVnfManager.class); + + @Autowired + GenericVnfManager(AAIRestApiProvider aaiRestApiProvider, CbamRestApiProvider cbamRestApiProvider, DriverProperties driverProperties) { + super(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + } + + static Relationship linkTo(String vnfId) { + Relationship relationship = new Relationship(); + relationship.setRelatedTo("generic-vnf"); + relationship.getRelationshipData().add(buildRelationshipData("generic-vnf.vnf-id", vnfId)); + return relationship; + } + + @Override + protected Logger getLogger() { + return logger; + } + + void createOrUpdate(String vnfId, boolean inMaintenance) { + try { + GenericVnf vnf = waitForVnfToAppearInAai(vnfId); + updateFields(vnf, vnfId, inMaintenance); + } catch (NoSuchElementException e) { + try { + logger.warn("The VNF with " + vnfId + " identifier did not appear in time", e); + updateFields(OBJECT_FACTORY.createGenericVnf(), vnfId, inMaintenance); + } catch (Exception e2) { + logger.warn("The VNF with " + vnfId + " identifier has been created since after the maximal wait for VNF to appear timeout", e2); + //the VNF might have been created since the last poll + updateFields(getExistingVnf(vnfId), vnfId, inMaintenance); + } + } + } + + GenericVnf getExistingVnf(String vnfId) { + return aaiRestApiProvider.get(logger, NETWORK, format(VNF_URL, vnfId), GenericVnf.class); + } + + private void updateFields(GenericVnf vnf, String vnfId, boolean inMaintenance) { + try { + VnfInfo vnfInfo = cbamRestApiProvider.getCbamLcmApi(driverProperties.getVnfmId()).vnfsVnfInstanceIdGet(vnfId, CbamRestApiProvider.NOKIA_LCM_API_VERSION); + vnf.setVnfName(vnfInfo.getName()); + } catch (ApiException e) { + throw buildFatalFailure(logger, "Unable to query VNF with " + vnfId + " identifier from CBAM", e); + } + vnf.setVnfId(vnfId); + vnf.setInMaint(inMaintenance); + vnf.setVnfInstanceId(vnfId); + //FIXME whould be good to know if this parameter is relevant or not? (mandatory) + vnf.setVnfType("NokiaVNF"); + vnf.setIsClosedLoopDisabled(inMaintenance); + aaiRestApiProvider.put(logger, NETWORK, format(VNF_URL, vnf.getVnfId()), vnf, Void.class); + } + + private GenericVnf waitForVnfToAppearInAai(String vnfId) { + long timeoutInMs = systemFunctions().currentTimeMillis() + MAX_MS_TO_WAIT_FOR_VNF_TO_APPEAR; + while (timeoutInMs - systemFunctions().currentTimeMillis() > 0) { + try { + return aaiRestApiProvider.get(logger, NETWORK, format(VNF_URL, vnfId), GenericVnf.class); + } catch (NoSuchElementException e) { + logger.debug("Unable to get VNF with " + vnfId + " identifier", e); + } + systemFunctions().sleep(3 * 1000L); + } + throw new NoSuchElementException(); + } + +}
\ No newline at end of file diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/L3NetworkManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/L3NetworkManager.java new file mode 100644 index 00000000..6d2b42bc --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/L3NetworkManager.java @@ -0,0 +1,104 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.nokia.cbam.lcm.v32.model.AffectedVirtualLink; +import org.onap.aai.domain.yang.v11.L3Network; +import org.onap.aai.domain.yang.v11.Relationship; +import org.onap.aai.domain.yang.v11.RelationshipList; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import static java.lang.String.format; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.NETWORK; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.SEPARATOR; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getCloudOwner; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getRegionName; + +/** + * Responsible for managing the {@link L3Network} in AAI + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +class L3NetworkManager extends AbstractManager { + private static final String NETWORK_URL = "/l3-networks/l3-network/%s"; + private static Logger logger = org.slf4j.LoggerFactory.getLogger(L3NetworkManager.class); + + @Autowired + L3NetworkManager(AAIRestApiProvider aaiRestApiProvider, CbamRestApiProvider cbamRestApiProvider, DriverProperties driverProperties) { + super(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + } + + @Override + protected Logger getLogger() { + return logger; + } + + void update(String vimId, String vnfId, AffectedVirtualLink affectedVirtualLink) { + L3Network l3Network = createOrGet(NETWORK, format(NETWORK_URL, buildNetworkId(vnfId, affectedVirtualLink)), OBJECT_FACTORY.createL3Network()); + updateNetworkFields(vimId, vnfId, affectedVirtualLink, l3Network); + } + + void delete(String vnfId, AffectedVirtualLink removedVl) { + aaiRestApiProvider.delete(logger, NETWORK, format(NETWORK_URL, buildNetworkId(vnfId, removedVl))); + } + + private void updateNetworkFields(String vimId, String vnfId, AffectedVirtualLink affectedVirtualLink, L3Network network) { + network.setNetworkId(buildNetworkId(vnfId, affectedVirtualLink)); + network.setNetworkName(extractMandatoryValue(affectedVirtualLink.getResource().getAdditionalData(), "name")); + network.setNeutronNetworkId(affectedVirtualLink.getResource().getResourceId()); + network.setIsBoundToVpn(false); + network.setIsExternalNetwork(false); + network.setIsProviderNetwork(false); + network.setIsSharedNetwork(false); + network.setOperationalStatus("active"); + network.setOrchestrationStatus("active"); + if (network.getRelationshipList() == null) { + network.setRelationshipList(new RelationshipList()); + } + addMissingRelation(network.getRelationshipList(), GenericVnfManager.linkTo(vnfId)); + addSingletonRelation(network.getRelationshipList(), getRegionLink(vimId)); + addSingletonRelation(network.getRelationshipList(), getTenantLink(vimId, extractMandatoryValue(affectedVirtualLink.getResource().getAdditionalData(), "tenantId"))); + aaiRestApiProvider.put(logger, NETWORK, format(NETWORK_URL, network.getNetworkId()), network, Void.class); + } + + private String buildNetworkId(String vnfId, AffectedVirtualLink affectedVirtualLink) { + return vnfId + SEPARATOR + affectedVirtualLink.getId(); + } + + private Relationship getRegionLink(String vimId) { + Relationship relationship = new Relationship(); + relationship.setRelatedTo("cloud-region"); + relationship.getRelationshipData().add(buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(vimId))); + relationship.getRelationshipData().add(buildRelationshipData("cloud-region.cloud-region-id", getRegionName(vimId))); + return relationship; + } + + private Relationship getTenantLink(String vimId, String tenantId) { + Relationship relationship = new Relationship(); + relationship.setRelatedTo("tenant"); + relationship.getRelationshipData().add(buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(vimId))); + relationship.getRelationshipData().add(buildRelationshipData("cloud-region.cloud-region-id", getRegionName(vimId))); + relationship.getRelationshipData().add(buildRelationshipData("tenant.tenant-id", tenantId)); + return relationship; + } +}
\ No newline at end of file diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/LInterfaceManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/LInterfaceManager.java new file mode 100644 index 00000000..229fe679 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/LInterfaceManager.java @@ -0,0 +1,101 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import org.onap.aai.domain.yang.v11.L3InterfaceIpv4AddressList; +import org.onap.aai.domain.yang.v11.L3InterfaceIpv6AddressList; +import org.onap.aai.domain.yang.v11.LInterface; +import org.onap.aai.domain.yang.v11.RelationshipList; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.ReportedAffectedCp; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import static java.lang.String.format; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.CLOUD; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getCloudOwner; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getRegionName; + +/** + * Responsible for managing the {@link LInterface} in AAI + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +class LInterfaceManager extends AbstractManager { + private static Logger logger = org.slf4j.LoggerFactory.getLogger(LInterfaceManager.class); + + @Autowired + LInterfaceManager(AAIRestApiProvider aaiRestApiProvider, CbamRestApiProvider cbamRestApiProvider, DriverProperties driverProperties) { + super(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + } + + static String buildUrl(String vimId, ReportedAffectedCp affectedCp) { + String cloudOwner = getCloudOwner(vimId); + String regionName = getRegionName(vimId); + String tenantId = affectedCp.getTenantId(); + String vServerId = affectedCp.getServerProviderId(); + String cpId = affectedCp.getCpId(); + return format("/cloud-regions/cloud-region/%s/%s/tenants/tenant/%s/vservers/vserver/%s/l-interfaces/l-interface/%s", cloudOwner, regionName, tenantId, vServerId, cpId); + } + + @Override + protected Logger getLogger() { + return logger; + } + + void update(String vnfId, String vimId, ReportedAffectedCp affectedCp, boolean inMaintenance) { + LInterface lInterface = createOrGet(CLOUD, buildUrl(vimId, affectedCp), OBJECT_FACTORY.createLInterface()); + updateFields(lInterface, affectedCp, vnfId, buildUrl(vimId, affectedCp), inMaintenance); + } + + void delete(String vimId, ReportedAffectedCp removedCp) { + aaiRestApiProvider.delete(logger, AAIRestApiProvider.AAIService.CLOUD, buildUrl(vimId, removedCp)); + } + + private void updateFields(LInterface logicalInterface, ReportedAffectedCp affectedCp, String vnfId, String url, boolean inMaintenance) { + logicalInterface.setInMaint(inMaintenance); + logicalInterface.setIsIpUnnumbered(false); + logicalInterface.setIsPortMirrored(false); + logicalInterface.setInterfaceName(affectedCp.getName()); + logicalInterface.setInterfaceId(affectedCp.getCpId()); + logicalInterface.setInterfaceRole(affectedCp.getCpdId()); + logicalInterface.setMacaddr(affectedCp.getMacAddress()); + logicalInterface.setProvStatus("active"); + if (affectedCp.getIpAddress() != null) { + if (affectedCp.getIpAddress().contains(":")) { + L3InterfaceIpv6AddressList ipv6Address = OBJECT_FACTORY.createL3InterfaceIpv6AddressList(); + ipv6Address.setL3InterfaceIpv6Address(affectedCp.getIpAddress()); + ipv6Address.setNeutronNetworkId(affectedCp.getNetworkProviderId()); + logicalInterface.getL3InterfaceIpv6AddressList().add(ipv6Address); + } else { + L3InterfaceIpv4AddressList ipv4Address = OBJECT_FACTORY.createL3InterfaceIpv4AddressList(); + ipv4Address.setL3InterfaceIpv4Address(affectedCp.getIpAddress()); + ipv4Address.setNeutronNetworkId(affectedCp.getNetworkProviderId()); + logicalInterface.getL3InterfaceIpv4AddressList().add(ipv4Address); + } + } + if (logicalInterface.getRelationshipList() == null) { + logicalInterface.setRelationshipList(new RelationshipList()); + } + addSingletonRelation(logicalInterface.getRelationshipList(), GenericVnfManager.linkTo(vnfId)); + aaiRestApiProvider.put(logger, CLOUD, url, logicalInterface, Void.class); + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/VnfcManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/VnfcManager.java new file mode 100644 index 00000000..976e283d --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/VnfcManager.java @@ -0,0 +1,90 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.google.common.base.Splitter; +import com.nokia.cbam.lcm.v32.model.AffectedVnfc; +import org.onap.aai.domain.yang.v11.RelationshipList; +import org.onap.aai.domain.yang.v11.Vnfc; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +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.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import static java.lang.String.format; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.NETWORK; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.SEPARATOR; + +/** + * Responsible for managing {@link Vnfc} in AAI + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +public class VnfcManager extends AbstractManager { + private static Logger logger = org.slf4j.LoggerFactory.getLogger(VnfcManager.class); + + @Autowired + VnfcManager(AAIRestApiProvider aaiRestApiProvider, CbamRestApiProvider cbamRestApiProvider, DriverProperties driverProperties) { + super(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + } + + public static String buildUrl(String vnfId, String cbamVnfcId) { + return format("/vnfcs/vnfc/%s", buildId(vnfId, cbamVnfcId)); + } + + public static String getCbamVnfcId(String vnfcId){ + String vnfId = Splitter.on(CbamUtils.SEPARATOR).split(vnfcId).iterator().next(); + return vnfcId.replaceFirst(vnfId + SEPARATOR, ""); + } + + private static String buildId(String vnfId, String cbamVnfcId) { + return vnfId + SEPARATOR + cbamVnfcId; + } + + @Override + protected Logger getLogger() { + return logger; + } + + void delete(String vnfId, com.nokia.cbam.lcm.v32.model.AffectedVnfc cbamVnfc) { + aaiRestApiProvider.delete(logger, NETWORK, buildUrl(vnfId, cbamVnfc.getId())); + } + + void update(String vimId, String tenantId, String vnfId, com.nokia.cbam.lcm.v32.model.AffectedVnfc cbamVnfc, boolean inMaintenance) { + String url = buildUrl(vnfId, cbamVnfc.getId()); + Vnfc vnfc = createOrGet(NETWORK, url, OBJECT_FACTORY.createVnfc()); + updateFields(vimId, tenantId, vnfc, cbamVnfc, vnfId, url, inMaintenance); + } + + private void updateFields(String vimId, String tenantId, Vnfc aaiVnfc, com.nokia.cbam.lcm.v32.model.AffectedVnfc cbamVnfc, String vnfId, String url, boolean inMaintenance) { + aaiVnfc.setInMaint(inMaintenance); + aaiVnfc.setIsClosedLoopDisabled(inMaintenance); + //FIXME would be good to know what is this mandatory parameter + aaiVnfc.setNfcFunction(cbamVnfc.getId()); + //FIXME would be good to know what is this mandatory parameter + aaiVnfc.setNfcNamingCode(cbamVnfc.getId()); + aaiVnfc.setVnfcName(buildId(vnfId, cbamVnfc.getId())); + aaiVnfc.setRelationshipList(new RelationshipList()); + addSingletonRelation(aaiVnfc.getRelationshipList(), VserverManager.linkTo(vimId, tenantId, cbamVnfc.getComputeResource().getResourceId())); + addSingletonRelation(aaiVnfc.getRelationshipList(), GenericVnfManager.linkTo(vnfId)); + aaiRestApiProvider.put(logger, NETWORK, url, aaiVnfc, Void.class); + } +}
\ No newline at end of file diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/VserverManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/VserverManager.java new file mode 100644 index 00000000..cec779a4 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/VserverManager.java @@ -0,0 +1,132 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.nokia.cbam.lcm.v32.model.AffectedVirtualStorage; +import com.nokia.cbam.lcm.v32.model.AffectedVnfc; +import org.onap.aai.domain.yang.v11.*; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import java.util.List; + +import static com.google.common.collect.Iterables.find; +import static java.lang.String.format; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.CLOUD; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.childElement; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getCloudOwner; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getRegionName; + +/** + * Responsible for managing {@link Vserver} in AAI + */ +@Component +@Conditional(value = Conditions.UseForDirect.class) +class VserverManager extends AbstractManager { + private static Logger logger = org.slf4j.LoggerFactory.getLogger(VserverManager.class); + + @Autowired + VserverManager(AAIRestApiProvider aaiRestApiProvider, CbamRestApiProvider cbamRestApiProvider, DriverProperties driverProperties) { + super(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + } + + static Relationship linkTo(String vimId, String tenantId, String serverProviderId) { + Relationship relationship = new Relationship(); + relationship.setRelatedTo("vserver"); + relationship.getRelationshipData().add(buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(vimId))); + relationship.getRelationshipData().add(buildRelationshipData("cloud-region.cloud-region-id", getRegionName(vimId))); + relationship.getRelationshipData().add(buildRelationshipData("tenant.tenant-id", tenantId)); + relationship.getRelationshipData().add(buildRelationshipData("vserver.vserver-id", serverProviderId)); + return relationship; + } + + static String getTenantId(AffectedVnfc cbamVnfc) { + return extractMandatoryValue(cbamVnfc.getComputeResource().getAdditionalData(), "tenantId"); + } + + @Override + protected Logger getLogger() { + return logger; + } + + void update(String vimId, String vnfId, AffectedVnfc cbamVnfc, List<AffectedVirtualStorage> affectedVirtualStorages, boolean inMaintenance) { + String url = buildUrl(vimId, cbamVnfc); + Vserver vserver = createOrGet(CLOUD, url, OBJECT_FACTORY.createVserver()); + updateFields(vserver, cbamVnfc, vnfId, affectedVirtualStorages, url, inMaintenance); + } + + void delete(String vimId, com.nokia.cbam.lcm.v32.model.AffectedVnfc deletedVnfc) { + aaiRestApiProvider.delete(logger, CLOUD, buildUrl(vimId, deletedVnfc)); + } + + private String buildUrl(String vimId, AffectedVnfc cbamVnfc) { + String tenantId = getTenantId(cbamVnfc); + String cloudOwner = getCloudOwner(vimId); + String regionName = getRegionName(vimId); + return format("/cloud-regions/cloud-region/%s/%s/tenants/tenant/%s/vservers/vserver/%s", cloudOwner, regionName, tenantId, cbamVnfc.getComputeResource().getResourceId()); + } + + private void updateFields(Vserver server, AffectedVnfc cbamVnfc, String vnfId, List<AffectedVirtualStorage> affectedVirtualStorages, String url, boolean inMaintenance) { + server.setInMaint(inMaintenance); + server.setIsClosedLoopDisabled(inMaintenance); + JsonElement additionalData = new Gson().toJsonTree(cbamVnfc.getComputeResource().getAdditionalData()); + server.setVserverName(additionalData.getAsJsonObject().get("name").getAsString()); + server.setVserverId(cbamVnfc.getComputeResource().getResourceId()); + server.setProvStatus("active"); + server.setRelationshipList(new RelationshipList()); + server.setVserverId(cbamVnfc.getComputeResource().getResourceId()); + server.setVserverSelflink(extractSelfLink(cbamVnfc.getComputeResource().getAdditionalData())); + addSingletonRelation(server.getRelationshipList(), GenericVnfManager.linkTo(vnfId)); + if (server.getVolumes() == null) { + server.setVolumes(new Volumes()); + } + if (cbamVnfc.getStorageResourceIds() != null) { + for (String virtualStorageId : cbamVnfc.getStorageResourceIds()) { + Volume volume = new Volume(); + AffectedVirtualStorage affectedStorage = find(affectedVirtualStorages, storage -> virtualStorageId.equals(storage.getId())); + volume.setVolumeId(affectedStorage.getResource().getResourceId()); + server.getVolumes().getVolume().add(volume); + } + } else { + server.setVolumes(OBJECT_FACTORY.createVolumes()); + } + aaiRestApiProvider.put(logger, CLOUD, url, server, Void.class); + } + + private String extractSelfLink(Object additionalData) { + try { + JsonObject root = new Gson().toJsonTree(additionalData).getAsJsonObject(); + for (JsonElement link : childElement(root, "links").getAsJsonArray()) { + if (link.getAsJsonObject().has("rel") && "self".equals(link.getAsJsonObject().get("rel").getAsString())) { + return link.getAsJsonObject().get("href").getAsString(); + } + } + return "unknown"; + } catch (Exception e) { + logger.debug("Missing links in the server", e); + return "unknown"; + } + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/package-info.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/package-info.java new file mode 100644 index 00000000..7b1cca56 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Handles notification processing in case of direct SO integration + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/package-info.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/package-info.java new file mode 100644 index 00000000..39fc82d5 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Handles information exchange with ONAP components directly instead of routing request through VF-C + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; 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..8d658310 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) { @@ -80,7 +81,7 @@ public class OnapVnfdBuilder { body.append(buildEcp(node.getKey(), node.getValue(), nodeTemplates)); break; default: - // + logger.warn("The {} type is not converted", type); } } return buildHeader(topologyTemplate) + body.toString(); @@ -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/restapi/LcmApi.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/LcmApi.java index 74ac6ea2..7f63a1a4 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/LcmApi.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/LcmApi.java @@ -28,6 +28,9 @@ import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; +import java.util.Optional; + +import static java.util.Optional.empty; import static org.apache.http.HttpStatus.SC_CREATED; import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties.BASE_URL; import static org.slf4j.LoggerFactory.getLogger; @@ -146,6 +149,6 @@ public class LcmApi { @ResponseBody public JobInfo healVnf(@RequestBody VnfHealRequest request, @PathVariable("vnfmId") String vnfmId, @PathVariable("vnfId") String vnfInstanceId, HttpServletResponse httpResponse) { logger.info("REST: Heal VNF"); - return lifecycleManager.healVnf(vnfmId, vnfInstanceId, request, httpResponse); + return lifecycleManager.healVnf(vnfmId, vnfInstanceId, request, empty(), httpResponse); } } 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/AdditionalParameters.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/AdditionalParameters.java index 70cf11ca..dfb7adaf 100644 --- a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/AdditionalParameters.java +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/AdditionalParameters.java @@ -35,7 +35,7 @@ public class AdditionalParameters { private List<ExtVirtualLinkData> extVirtualLinks = new ArrayList<>(); private Object additionalParams; - AdditionalParameters() { + public AdditionalParameters() { //only used through reflection (gson) } 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..79e9487d 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; @@ -131,12 +131,10 @@ public class LifecycleManager { * @param csarId the identifier of the VNF package * @param vnfName the name of the VNF * @param description the description of the VNF - * @param addtionalParams additional parameters for the VNF instantiation request * @return the VNF creation result */ - public VnfCreationResult create(String vnfmId, String csarId, String vnfName, String description, AdditionalParameters addtionalParams) { - logOperationInput("not yet specified", "create", addtionalParams); - validateVimType(addtionalParams.getVimType()); + public VnfCreationResult create(String vnfmId, String csarId, String vnfName, String description) { + logOperationInput("not yet specified", "creation", csarId); try { CatalogAdapterVnfpackage cbamPackage = catalogManager.preparePackageInCbam(vnfmId, csarId); CreateVnfRequest vnfCreateRequest = new CreateVnfRequest(); @@ -151,8 +149,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 +167,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); @@ -206,7 +204,8 @@ public class LifecycleManager { */ public VnfInstantiateResponse createAndInstantiate(String vnfmId, VnfInstantiateRequest request, HttpServletResponse httpResponse) { AdditionalParameters additionalParameters = convertInstantiationAdditionalParams(request.getVnfPackageId(), request.getAdditionalParam()); - VnfCreationResult creationResult = create(vnfmId, request.getVnfDescriptorId(), request.getVnfInstanceName(), request.getVnfInstanceDescription(), additionalParameters); + validateVimType(additionalParameters.getVimType()); + VnfCreationResult creationResult = create(vnfmId, request.getVnfDescriptorId(), request.getVnfInstanceName(), request.getVnfInstanceDescription()); return instantiate(vnfmId, request, httpResponse, additionalParameters, creationResult.vnfInfo.getId(), creationResult.vnfdId); } @@ -219,7 +218,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 +230,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 +256,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 +518,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 +528,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()); @@ -555,9 +556,10 @@ public class LifecycleManager { * @param vnfId the identifier of the VNF * @param request the heal request * @param httpResponse the HTTP response + * @param vnfcId the identifer of thr VNFC to be healed * @return the job for tracking the heal */ - public JobInfo healVnf(String vnfmId, String vnfId, VnfHealRequest request, HttpServletResponse httpResponse) { + public JobInfo healVnf(String vnfmId, String vnfId, VnfHealRequest request, Optional<String> vnfcId, HttpServletResponse httpResponse) { logOperationInput(vnfId, "heal", request); return scheduleExecution(vnfId, httpResponse, "heal", job -> { HealVnfRequest cbamHealRequest = new HealVnfRequest(); @@ -565,6 +567,7 @@ public class LifecycleManager { additionalParams.put("vmName", request.getAffectedvm().getVmname()); additionalParams.put("action", request.getAction()); additionalParams.put("jobId", job.getJobId()); + additionalParams.put("vnfcId", vnfcId.orElse("unknown")); cbamHealRequest.setAdditionalParams(additionalParams); com.nokia.cbam.lcm.v32.model.VnfInfo vnf = cbamRestApiProvider.getCbamLcmApi(vnfmId).vnfsVnfInstanceIdGet(vnfId, NOKIA_LCM_API_VERSION); String vimId = getVimIdFromInstantiationRequest(vnfmId, vnf); @@ -619,15 +622,19 @@ public class LifecycleManager { @FunctionalInterface private interface AsynchronousExecution { void execute(JobInfo job) throws ApiException; - } - - private static class VnfCreationResult { - private com.nokia.cbam.lcm.v32.model.VnfInfo vnfInfo; - private String vnfdId; + } + public static class VnfCreationResult { + private final com.nokia.cbam.lcm.v32.model.VnfInfo vnfInfo; + private final String vnfdId; VnfCreationResult(com.nokia.cbam.lcm.v32.model.VnfInfo vnfInfo, String vnfdId) { this.vnfInfo = vnfInfo; this.vnfdId = vnfdId; } + + public com.nokia.cbam.lcm.v32.model.VnfInfo getVnfInfo() { + return vnfInfo; + } + } } 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/TestNokiaSvnfmApplication.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/TestNokiaSvnfmApplication.java index 47e441ff..249e16c9 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/TestNokiaSvnfmApplication.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/TestNokiaSvnfmApplication.java @@ -21,6 +21,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.*; import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.SelfRegistrationManager; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.TestUtil; import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.JobManager; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.ContextClosedEvent; @@ -138,6 +139,16 @@ public class TestNokiaSvnfmApplication { } /** + * Spring will instantiate using reflection + */ + @Test + public void testUseStaticWay() throws Exception { + //verify + //the constructor is public even if has no private fields + new NokiaSvnfmApplication(); + } + + /** * static entry point calling an other static entry point can not be tested */ @Test diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/ct/CTDirectReal.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/ct/CTDirectReal.java new file mode 100644 index 00000000..a428ee90 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/ct/CTDirectReal.java @@ -0,0 +1,100 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.ct; + +import com.google.gson.JsonObject; +import com.nokia.cbam.lcm.v32.model.*; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.NokiaSvnfmApplication; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIExternalSystemInfoProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.AAINotificationProcessor; +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.VimInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.ArrayList; + +import static java.util.Optional.of; + +@RunWith(value = SpringRunner.class) +@SpringBootTest(classes = NokiaSvnfmApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@ActiveProfiles("direct") +public class CTDirectReal { + @Autowired + private AAIExternalSystemInfoProvider externalSystemInfoProvider; + @Autowired + private AAINotificationProcessor notificationProcessor; + + /** + * The following is not a real test, but only start the driver locally. + * It takes parameters from application-real.properties + */ + @Test + public void testBasicWorkflow() throws Exception { + VimInfo nokia_regionOne = externalSystemInfoProvider.getVimInfo("Nokia_RegionOne"); + + VnfLifecycleChangeNotification recievedNot = new VnfLifecycleChangeNotification(); + recievedNot.setVnfInstanceId("CBAM-d8deb02a7a51449dba576ac9eabb55b8"); + ReportedAffectedConnectionPoints affectedConnectionPoints = new ReportedAffectedConnectionPoints(); + recievedNot.setAffectedVirtualLinks(new ArrayList<>()); + AffectedVirtualLink link = new AffectedVirtualLink(); + recievedNot.getAffectedVirtualLinks().add(link); + link.setId("vlid1"); + link.setChangeType(ChangeType.REMOVED); + link.setVirtualLinkDescId("vldId1"); + link.setResource(new ResourceHandle()); + link.getResource().setResourceId("netProviderId1"); + link.getResource().setAdditionalData(additionalData("name", "networkName")); + recievedNot.setAffectedVnfcs(new ArrayList<>()); + AffectedVnfc vnfc = new AffectedVnfc(); + vnfc.setId("myVnfcId1"); + vnfc.setChangeType(ChangeType.ADDED); + vnfc.setVduId("myVduId"); + vnfc.setStorageResourceIds(new ArrayList<>()); + vnfc.setComputeResource(new ResourceHandle()); + vnfc.getComputeResource().setResourceId("serverProvId1"); + JsonObject additionalData = additionalData("name", "serverName"); + additionalData.addProperty("tenantId", "de8fd0d1d5874503a47b920c10f4322a"); + vnfc.getComputeResource().setAdditionalData(additionalData); + recievedNot.getAffectedVnfcs().add(vnfc); + ReportedAffectedCp addedCp = new ReportedAffectedCp(); + addedCp.setCpId("cpId"); + addedCp.setIpAddress("1.2.3.4"); + addedCp.setMacAddress("a:b:c:d:e:f"); + addedCp.setNetworkProviderId("netProviderId1"); + addedCp.setServerProviderId("serverProvId1"); + addedCp.setProviderId("portId"); + addedCp.setTenantId("de8fd0d1d5874503a47b920c10f4322a"); + addedCp.setCpdId("cpdId"); + affectedConnectionPoints.getPost().add(addedCp); + notificationProcessor.processNotification(recievedNot, null, of(affectedConnectionPoints), "Nokia_RegionOne"); + Thread.sleep(10000000 * 1000L); + } + + JsonObject additionalData(String key, String value) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty(key, value); + return jsonObject; + } + + +} 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/core/TestMsbApiProvider.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestMsbApiProvider.java index aefe63a2..eb3674c3 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestMsbApiProvider.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/TestMsbApiProvider.java @@ -121,16 +121,17 @@ public class TestMsbApiProvider extends TestBase { /** - * use HTTPS for known ports (443) should be removed if https://jira.onap.org/browse/MSB-151 is solved + * use HTTPS for known ports */ @Test - public void testMsb151IssueHack() throws Exception { + public void testMsbServiceOverssl() throws Exception { NodeInfo nonDocker = new NodeInfo(); nonDocker.setIp("173.1.2.3"); - nonDocker.setPort("443"); + nonDocker.setPort("123"); microServiceInfo.setServiceName("serviceName"); microServiceInfo.setVersion("v1"); microServiceInfo.setUrl("/lead/nslcm/v1"); + microServiceInfo.setEnable_ssl(true); when(environment.getProperty(IpMappingProvider.IP_MAP, String.class, "")).thenReturn("173.1.2.3->1.2.3.4"); nodes.add(nonDocker); msbApiProvider = new MsbApiProvider(environment) { @@ -142,32 +143,7 @@ public class TestMsbApiProvider extends TestBase { when(msbClient.queryMicroServiceInfo("serviceName", "v1")).thenReturn(microServiceInfo); msbApiProvider.afterPropertiesSet(); //when - assertEquals("https://1.2.3.4:443/lead/nslcm/v1", msbApiProvider.getMicroServiceUrl("serviceName", "v1")); - } - - /** - * use HTTPS for known ports (443) should be removed if https://jira.onap.org/browse/MSB-151 is solved - */ - @Test - public void testMsb151IssueHack2() throws Exception { - NodeInfo nonDocker = new NodeInfo(); - nonDocker.setIp("173.1.2.3"); - nonDocker.setPort("8443"); - microServiceInfo.setServiceName("serviceName"); - microServiceInfo.setVersion("v1"); - microServiceInfo.setUrl("/lead/nslcm/v1"); - when(environment.getProperty(IpMappingProvider.IP_MAP, String.class, "")).thenReturn("173.1.2.3->1.2.3.4"); - nodes.add(nonDocker); - msbApiProvider = new MsbApiProvider(environment) { - @Override - public MSBServiceClient getMsbClient() { - return msbClient; - } - }; - when(msbClient.queryMicroServiceInfo("serviceName", "v1")).thenReturn(microServiceInfo); - msbApiProvider.afterPropertiesSet(); - //when - assertEquals("https://1.2.3.4:8443/lead/nslcm/v1", msbApiProvider.getMicroServiceUrl("serviceName", "v1")); + assertEquals("https://1.2.3.4:123/lead/nslcm/v1", msbApiProvider.getMicroServiceUrl("serviceName", "v1")); } /** diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestAAIExternalSystemInfoProvider.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestAAIExternalSystemInfoProvider.java new file mode 100644 index 00000000..c1da617e --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestAAIExternalSystemInfoProvider.java @@ -0,0 +1,189 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.onap.aai.domain.yang.v11.EsrSystemInfo; +import org.onap.aai.domain.yang.v11.EsrSystemInfoList; +import org.onap.aai.domain.yang.v11.EsrVnfm; +import org.onap.aai.domain.yang.v11.ObjectFactory; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; +import org.onap.vnfmdriver.model.VimInfo; +import org.onap.vnfmdriver.model.VnfmInfo; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.fail; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestAAIExternalSystemInfoProvider extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + private AAIExternalSystemInfoProvider aaiExternalSystemInfoProvider; + @Mock + private AAIRestApiProvider aaiRestApiProvider; + + @Before + public void init() { + aaiExternalSystemInfoProvider = new AAIExternalSystemInfoProvider(environment, aaiRestApiProvider); + setField(AAIExternalSystemInfoProvider.class, "logger", logger); + } + + /** + * test query VIM success scenario + */ + @Test + public void testVim() throws Exception { + EsrSystemInfoList vims = OBJECT_FACTORY.createEsrSystemInfoList(); + EsrSystemInfo vim = OBJECT_FACTORY.createEsrSystemInfo(); + vims.getEsrSystemInfo().add(vim); + vim.setPassword("myPassword"); + vim.setUserName("myUsername"); + vim.setServiceUrl("http://1.2.3.4:1234/a"); + vim.setVersion("v123"); + vim.setSystemStatus("active"); + vim.setSystemName("name"); + vim.setType("type"); + vim.setSslInsecure(true); + vim.setVendor("vendor"); + when(aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/esr-system-info-list", EsrSystemInfoList.class)).thenReturn(vims); + //when + VimInfo vimInfo = aaiExternalSystemInfoProvider.getVimInfo(VIM_ID); + assertEquals("myPassword", vimInfo.getPassword()); + assertEquals("true", vimInfo.getSslInsecure()); + assertEquals(null, vimInfo.getSslCacert()); + assertEquals("myUsername", vimInfo.getUserName()); + assertEquals("name", vimInfo.getDescription()); + assertEquals("name", vimInfo.getName()); + assertEquals("http://1.2.3.4:1234/a", vimInfo.getUrl()); + assertEquals("active", vimInfo.getStatus()); + assertEquals("type", vimInfo.getType()); + assertEquals("v123", vimInfo.getVersion()); + assertEquals(VIM_ID, vimInfo.getVimId()); + assertEquals(null, vimInfo.getCreateTime()); + + } + + /** + * test query VIM success scenario for SSL + */ + @Test + public void testVimSsl() throws Exception { + EsrSystemInfoList vims = OBJECT_FACTORY.createEsrSystemInfoList(); + EsrSystemInfo vim = OBJECT_FACTORY.createEsrSystemInfo(); + vims.getEsrSystemInfo().add(vim); + vim.setPassword("myPassword"); + vim.setUserName("myUsername"); + vim.setServiceUrl("https://1.2.3.4:1234/a"); + vim.setVersion("v123"); + vim.setSystemStatus("active"); + vim.setSystemName("name"); + vim.setType("type"); + vim.setSslInsecure(false); + vim.setSslCacert("cert"); + vim.setVendor("vendor"); + when(aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/esr-system-info-list", EsrSystemInfoList.class)).thenReturn(vims); + //when + VimInfo vimInfo = aaiExternalSystemInfoProvider.getVimInfo(VIM_ID); + assertEquals("myPassword", vimInfo.getPassword()); + assertEquals("false", vimInfo.getSslInsecure()); + assertEquals("cert", vimInfo.getSslCacert()); + assertEquals("myUsername", vimInfo.getUserName()); + assertEquals("name", vimInfo.getDescription()); + assertEquals("name", vimInfo.getName()); + assertEquals("https://1.2.3.4:1234/a", vimInfo.getUrl()); + assertEquals("active", vimInfo.getStatus()); + assertEquals("type", vimInfo.getType()); + assertEquals("v123", vimInfo.getVersion()); + assertEquals(VIM_ID, vimInfo.getVimId()); + assertEquals(null, vimInfo.getCreateTime()); + } + + /** + * unable to query VIM from AAI results in error + */ + @Test + public void testVimUnableToQuery() throws Exception { + RuntimeException expectedException = new RuntimeException(); + when(aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/esr-system-info-list", EsrSystemInfoList.class)).thenThrow(expectedException); + //when + try { + aaiExternalSystemInfoProvider.getVimInfo(VIM_ID); + fail(); + } catch (Exception e) { + verify(logger).error("Unable to query VIM with myCloudOwnerId_myRegionName identifier from AAI", expectedException); + assertEquals(expectedException, e.getCause()); + } + } + + /** + * test VNFM query success scenario + */ + @Test + public void testVnfmQuery() throws Exception { + EsrVnfm vnfm = OBJECT_FACTORY.createEsrVnfm(); + vnfm.setVimId(VIM_ID); + vnfm.setEsrSystemInfoList(OBJECT_FACTORY.createEsrSystemInfoList()); + EsrSystemInfo esrInfo = OBJECT_FACTORY.createEsrSystemInfo(); + vnfm.getEsrSystemInfoList().getEsrSystemInfo().add(esrInfo); + esrInfo.setPassword("myPassword"); + esrInfo.setUserName("myUsername"); + esrInfo.setServiceUrl("https://1.2.3.4:1234/a"); + esrInfo.setVersion("v123"); + esrInfo.setSystemStatus("active"); + esrInfo.setSystemName("name"); + esrInfo.setType("type"); + esrInfo.setSslInsecure(false); + esrInfo.setSslCacert("cert"); + esrInfo.setVendor("vendor"); + vnfm.setVnfmId(VNFM_ID); + when(aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.ESR, "/esr-vnfm-list/esr-vnfm/" + VNFM_ID + "?depth=all", EsrVnfm.class)).thenReturn(vnfm); + + //when + VnfmInfo actualVnfmInfo = aaiExternalSystemInfoProvider.queryVnfmInfoFromSource(VNFM_ID); + //verify + assertEquals("myPassword", actualVnfmInfo.getPassword()); + assertEquals("https://1.2.3.4:1234/a", actualVnfmInfo.getUrl()); + assertEquals("myUsername", actualVnfmInfo.getUserName()); + assertEquals(null, actualVnfmInfo.getCreateTime()); + assertEquals(null, actualVnfmInfo.getDescription()); + assertEquals("name", actualVnfmInfo.getName()); + assertEquals("type", actualVnfmInfo.getType()); + assertEquals("vendor", actualVnfmInfo.getVendor()); + assertEquals("v123", actualVnfmInfo.getVersion()); + assertEquals(VIM_ID, actualVnfmInfo.getVimId()); + assertEquals(VNFM_ID, actualVnfmInfo.getVnfmId()); + } + + /** + * unable to query VNFM from AAI results in error + */ + @Test + public void testVnfmUnableToQuery() throws Exception { + RuntimeException expectedException = new RuntimeException(); + when(aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.ESR, "/esr-vnfm-list/esr-vnfm/" + VNFM_ID + "?depth=all", EsrVnfm.class)).thenThrow(expectedException); + //when + try { + aaiExternalSystemInfoProvider.queryVnfmInfoFromSource(VNFM_ID); + fail(); + } catch (Exception e) { + verify(logger).error("Unable to query VNFM with " + VNFM_ID + " identifier from AAI", expectedException); + assertEquals(expectedException, e.getCause()); + } + } +}
\ No newline at end of file diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestAAIRestApiProvider.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestAAIRestApiProvider.java new file mode 100644 index 00000000..953f7da0 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestAAIRestApiProvider.java @@ -0,0 +1,238 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.aai.domain.yang.v11.GenericVnf; +import org.onap.aai.domain.yang.v11.L3Network; +import org.onap.aai.domain.yang.v11.ObjectFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; +import org.onap.aai.restclient.enums.RestAuthenticationMode; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; + +import javax.xml.bind.JAXBContext; +import java.io.ByteArrayOutputStream; +import java.io.StringReader; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import static com.google.common.collect.Lists.newArrayList; +import static java.util.Base64.getEncoder; +import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE; +import static junit.framework.TestCase.*; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestAAIRestApiProvider extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + @Mock + private RestClient restClient; + private AAIRestApiProvider aaiRestApiProvider; + private ArgumentCaptor<Map> headers = ArgumentCaptor.forClass(Map.class); + private ArgumentCaptor<String> payload = ArgumentCaptor.forClass(String.class); + + private OperationResult result = new OperationResult(); + + public static String marshall(Object object) throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + JAXBContext.newInstance(object.getClass()).createMarshaller().marshal(object, bos); + return bos.toString(); + } + + public static <T> T unmarshal(String content, Class<T> clazz) { + try { + return (T) JAXBContext.newInstance(clazz).createUnmarshaller().unmarshal(new StringReader(content)); + } catch (Exception e) { + throw new RuntimeException(); + } + } + + @Before + public void init() { + //MockitoAnnotations.initMocks(this); + AAIRestApiProvider real = new AAIRestApiProvider(msbApiProvider); + setField(AAIRestApiProvider.class, "logger", logger); + setFieldWithPropertyAnnotation(real, "${aaiUsername}", "aaiUsername"); + setFieldWithPropertyAnnotation(real, "${aaiPassword}", "aaiPassword"); + aaiRestApiProvider = Mockito.spy(real); + when(aaiRestApiProvider.buildRawClient()).thenReturn(restClient); + when(restClient.basicAuthPassword("aaiPassword")).thenReturn(restClient); + when(restClient.basicAuthUsername("aaiUsername")).thenReturn(restClient); + when(restClient.authenticationMode(RestAuthenticationMode.SSL_BASIC)).thenReturn(restClient); + when(msbApiProvider.getMicroServiceUrl(AAIRestApiProvider.AAIService.CLOUD.getServiceName(), "v11")).thenReturn("x://1.2.3.4:4/a"); + result.setResultCode(201); + } + + /** + * test HTTP GET success scenario + */ + @Test + public void testGetSuccess() throws Exception { + GenericVnf vnf = OBJECT_FACTORY.createGenericVnf(); + vnf.setVnfId("myVnfId"); + when(restClient.get(eq("x://1.2.3.4:4/a/myurl"), headers.capture(), eq(APPLICATION_XML_TYPE))).thenReturn(result); + result.setResult(marshall(vnf)); + //when + GenericVnf actualVnf = aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl", GenericVnf.class); + //verify + assertEquals(vnf.getVnfId(), actualVnf.getVnfId()); + assertHeaders(); + } + + /** + * HTTP GET on non existing resource results in {@link java.util.NoSuchElementException} + */ + @Test + public void testGetMissingResource() throws Exception { + when(restClient.get(eq("x://1.2.3.4:4/a/myurl"), headers.capture(), eq(APPLICATION_XML_TYPE))).thenReturn(result); + result.setResultCode(404); + //when + try { + aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl", GenericVnf.class); + fail(); + } catch (NoSuchElementException e) { + verify(logger).debug("The resource at /myurl does not exists"); + assertEquals("The resource at /myurl does not exists", e.getMessage()); + } + } + + /** + * Non known HTTP response code is propagated + */ + @Test + public void testUnknownErroCode() throws Exception { + when(restClient.get(eq("x://1.2.3.4:4/a/myurl"), headers.capture(), eq(APPLICATION_XML_TYPE))).thenReturn(result); + result.setResultCode(502); + result.setFailureCause("myFail"); + //when + try { + aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl", GenericVnf.class); + fail(); + } catch (RuntimeException e) { + verify(logger).error("Bad response. Code: 502 cause: myFail"); + assertEquals("Bad response. Code: 502 cause: myFail", e.getMessage()); + } + } + + /** + * response content is not used when not requesting result + */ + @Test + public void testNoResult() throws Exception { + when(restClient.get(eq("x://1.2.3.4:4/a/myurl"), headers.capture(), eq(APPLICATION_XML_TYPE))).thenReturn(result); + result.setResultCode(202); + //when + Void result = aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl", Void.class); + //verify + assertNull(result); + } + + /** + * test HTTP PUT success scenario + */ + @Test + public void putSuccess() throws Exception { + when(restClient.put(eq("x://1.2.3.4:4/a/myurl"), payload.capture(), headers.capture(), eq(APPLICATION_XML_TYPE), eq(APPLICATION_XML_TYPE))).thenReturn(result); + GenericVnf request = OBJECT_FACTORY.createGenericVnf(); + request.setVnfId("myVnfId"); + L3Network response = OBJECT_FACTORY.createL3Network(); + response.setNetworkId("myNetworkId"); + result.setResult(marshall(response)); + //when + L3Network actualResponse = aaiRestApiProvider.put(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl", request, L3Network.class); + //verify + GenericVnf actualValue = unmarshal(payload.getValue(), GenericVnf.class); + assertEquals("myVnfId", actualValue.getVnfId()); + assertEquals("myNetworkId", actualResponse.getNetworkId()); + assertHeaders(); + } + + /** + * test HTTP delete success scenario + */ + @Test + public void deleteSuccess() throws Exception { + when(restClient.delete(eq("x://1.2.3.4:4/a/myurl"), headers.capture(), eq(APPLICATION_XML_TYPE))).thenReturn(result); + //when + aaiRestApiProvider.delete(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl"); + //verify + assertHeaders(); + //the when above is the verify + } + + /** + * invalid request content results in error + */ + @Test + public void testInvalidInput() throws Exception { + when(restClient.put(eq("x://1.2.3.4:4/a/myurl"), payload.capture(), headers.capture(), eq(APPLICATION_XML_TYPE), eq(APPLICATION_XML_TYPE))).thenReturn(result); + //when + try { + aaiRestApiProvider.put(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl", "Invalid content", L3Network.class); + //verify + fail(); + } catch (Exception e) { + assertEquals("Unable to marshal content", e.getMessage()); + verify(logger).error("Unable to marshal content", e.getCause()); + } + } + + /** + * invalid response content results in error + */ + @Test + public void testInvalidResponse() throws Exception { + when(restClient.put(eq("x://1.2.3.4:4/a/myurl"), payload.capture(), headers.capture(), eq(APPLICATION_XML_TYPE), eq(APPLICATION_XML_TYPE))).thenReturn(result); + GenericVnf request = OBJECT_FACTORY.createGenericVnf(); + request.setVnfId("myVnfId"); + result.setResult("invalid"); + //when + try { + aaiRestApiProvider.put(logger, AAIRestApiProvider.AAIService.CLOUD, "/myurl", request, L3Network.class); + //verify + fail(); + } catch (Exception e) { + assertEquals("Unable to unmarshal content", e.getMessage()); + verify(logger).error("Unable to unmarshal content", e.getCause()); + } + } + + /** + * test AAI service names in AAI + */ + @Test + public void testServiceNames() { + //the names have been base64-ed to prevent "smart" IDEs (idea) to refactor the tests too for the otherwise known fix constants in external systems + assertEquals("YWFpLWNsb3VkSW5mcmFzdHJ1Y3R1cmU=", getEncoder().encodeToString(AAIRestApiProvider.AAIService.CLOUD.getServiceName().getBytes())); + assertEquals("YWFpLW5ldHdvcms=", getEncoder().encodeToString(AAIRestApiProvider.AAIService.NETWORK.getServiceName().getBytes())); + assertEquals("YWFpLWV4dGVybmFsU3lzdGVt", getEncoder().encodeToString(AAIRestApiProvider.AAIService.ESR.getServiceName().getBytes())); + } + + private void assertHeaders() { + Map<String, List<String>> actualHeaders = headers.getValue(); + assertEquals(2, actualHeaders.size()); + assertEquals(newArrayList("NokiaSVNFM"), actualHeaders.get("X-FromAppId")); + assertEquals(newArrayList("application/xml"), actualHeaders.get("Accept")); + } +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestGrantlessGrantManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestGrantlessGrantManager.java new file mode 100644 index 00000000..ad9b7fc8 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestGrantlessGrantManager.java @@ -0,0 +1,80 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import org.junit.Before; +import org.junit.Test; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; +import org.onap.vnfmdriver.model.GrantVNFResponseVim; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.Mockito.verify; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestGrantlessGrantManager extends TestBase { + private GrantlessGrantManager grantlessGrantManager; + + @Before + public void init() { + grantlessGrantManager = new GrantlessGrantManager(); + setField(GrantlessGrantManager.class, "logger", logger); + } + + /** + * grant is only logged for healing + */ + @Test + public void testGrantForHeal() throws Exception { + //when + grantlessGrantManager.requestGrantForHeal(null, null, null, null, null, null); + //verify + verify(logger).info("No grant is requested in direct mode"); + } + + /** + * grant is only logged for instantiation + */ + @Test + public void testGrantForInstantiate() throws Exception { + //when + GrantVNFResponseVim grant = grantlessGrantManager.requestGrantForInstantiate(null, null, VIM_ID, null, null, null, null); + //verify + verify(logger).info("No grant is requested in direct mode"); + assertEquals(VIM_ID, grant.getVimId()); + } + + /** + * grant is only logged for scaling + */ + @Test + public void testGrantForScaling() throws Exception { + //when + grantlessGrantManager.requestGrantForScale(null, null, null, null, null, null); + //verify + verify(logger).info("No grant is requested in direct mode"); + } + + /** + * grant is only logged for termination + */ + @Test + public void testGrantForTerminate() throws Exception { + //when + grantlessGrantManager.requestGrantForTerminate(null, null, null, null, null, null); + //verify + verify(logger).info("No grant is requested in direct mode"); + } +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestSdcPackageProvider.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestSdcPackageProvider.java new file mode 100644 index 00000000..199f7255 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/TestSdcPackageProvider.java @@ -0,0 +1,130 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct; + +import org.apache.http.client.methods.HttpGet; +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; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.NoSuchElementException; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.fail; +import static org.apache.http.HttpHeaders.ACCEPT; +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.onap.core.SelfRegistrationManager.SERVICE_NAME; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestSdcPackageProvider extends TestBase { + private SdcPackageProvider sdcPackageProvider; + + @Before + public void init() { + sdcPackageProvider = new SdcPackageProvider(msbApiProvider, driverProperties); + setField(SdcPackageProvider.class, "logger", logger); + setFieldWithPropertyAnnotation(sdcPackageProvider, "${sdcUsername}", "sdcUsername"); + setFieldWithPropertyAnnotation(sdcPackageProvider, "${sdcPassword}", "sdcPassword"); + when(msbApiProvider.getMicroServiceUrl("sdc", "v1")).thenReturn("https://1.2.3.4:456/g"); + } + + /** + * test package download from SDC + */ + @Test + public void testPackageDownload() throws Exception { + when(entity.getContent()).thenReturn(new ByteArrayInputStream("test".getBytes())); + //when + byte[] result = sdcPackageProvider.getPackage("csarId"); + //verify + assertEquals("test", new String("test")); + HttpGet httpGet = (HttpGet) request.getValue(); + assertEquals(VNFM_ID, httpGet.getFirstHeader("X-ECOMP-InstanceID").getValue()); + assertEquals(SERVICE_NAME, httpGet.getFirstHeader("X-FromAppId").getValue()); + assertEquals(APPLICATION_OCTET_STREAM_VALUE, httpGet.getFirstHeader(ACCEPT).getValue()); + assertEquals("https://1.2.3.4:456/g/sdc/v1/catalog/resources/csarId/toscaModel", httpGet.getURI().toASCIIString()); + } + + /** + * failure to download package from SDC is propagated + */ + @Test + public void testFailedPackageDownload() throws Exception { + IOException expectedException = new IOException(); + when(httpClient.execute(any())).thenThrow(expectedException); + try { + sdcPackageProvider.getPackage("csarId"); + fail(); + } catch (Exception e) { + assertEquals("Unable to download csarId package from SDC", e.getMessage()); + assertEquals(expectedException, e.getCause()); + verify(logger).error("Unable to download csarId package from SDC", expectedException); + } + } + + /** + * get VNFD from ONAP package + */ + @Test + public void testGetVnfd() throws Exception { + byte[] onapPackageContent = TestUtil.loadFile("unittests/TestCbamCatalogManager.sample.csar"); + when(entity.getContent()).thenReturn(new ByteArrayInputStream(onapPackageContent)); + //when + String cbamVnfdId = sdcPackageProvider.getCbamVnfdId("csarId"); + //verify + assertEquals("Nokia~SimpleDual_scalable~1.0~1.0", cbamVnfdId); + } + + /** + * unable to download package from SDC during get CBAM VNFD id + */ + @Test + public void testUnableToDownloadPackageDuringVnfdIdGet() throws Exception { + IOException expectedException = new IOException(); + when(httpClient.execute(any())).thenThrow(expectedException); + try { + sdcPackageProvider.getCbamVnfdId("csarId"); + fail(); + } catch (Exception e) { + assertEquals("Unable to download csarId package from SDC", e.getMessage()); + assertEquals(expectedException, e.getCause()); + verify(logger).error("Unable to download csarId package from SDC", expectedException); + } + } + + /** + * invalid VNF package results in error + */ + @Test + public void testInvalidVNFDContent() throws Exception { + byte[] onapPackageContent = "invalidZip".getBytes(); + when(entity.getContent()).thenReturn(new ByteArrayInputStream(onapPackageContent)); + try { + sdcPackageProvider.getCbamVnfdId("csarId"); + fail(); + } catch (Exception e) { + assertEquals("Unable to extract CBAM VNFD id from ONAP package", e.getMessage()); + verify(logger).error(eq("Unable to extract CBAM VNFD id from ONAP package"), any(NoSuchElementException.class)); + } + } +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestAAINotificationProcessor.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestAAINotificationProcessor.java new file mode 100644 index 00000000..bc8f7835 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestAAINotificationProcessor.java @@ -0,0 +1,253 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.google.gson.JsonObject; +import com.nokia.cbam.lcm.v32.model.*; +import org.jetbrains.annotations.NotNull; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; +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 java.util.ArrayList; +import java.util.UUID; + +import static com.nokia.cbam.lcm.v32.model.ChangeType.*; +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestAAINotificationProcessor extends TestBase { + @Mock + private GenericVnfManager genericVnfManager; + @Mock + private L3NetworkManager l3NetworkManager; + @Mock + private LInterfaceManager lInterfaceManager; + @Mock + private VnfcManager vnfcManager; + @Mock + private VserverManager vserverManager; + private AAINotificationProcessor aaiNotificationProcessor; + + @Before + public void init() { + aaiNotificationProcessor = new AAINotificationProcessor(genericVnfManager, l3NetworkManager, lInterfaceManager, vnfcManager, vserverManager); + setField(AAINotificationProcessor.class, "logger", logger); + } + + /** + * test objects are manipulated in correct order in AAA + * (other is dependency between the objects though relations) + */ + @Test + public void testObjectManipulationOrder() throws Exception { + VnfLifecycleChangeNotification recievenNotification = new VnfLifecycleChangeNotification(); + recievenNotification.setAffectedVnfcs(new ArrayList<>()); + recievenNotification.setAffectedVirtualLinks(new ArrayList<>()); + ArrayList<AffectedVirtualStorage> affectedVirtualStorages = new ArrayList<>(); + recievenNotification.setAffectedVirtualStorages(affectedVirtualStorages); + recievenNotification.setVnfInstanceId(VNF_ID); + recievenNotification.setStatus(OperationStatus.STARTED); + AffectedVirtualLink addedLink = buildVl(recievenNotification, ADDED); + AffectedVirtualLink removedLink = buildVl(recievenNotification, REMOVED); + AffectedVirtualLink modifiedLink = buildVl(recievenNotification, MODIFIED); + AffectedVnfc addedVnfc = buildVnfc(recievenNotification, ADDED, "tenantId1"); + AffectedVnfc removedVnfc = buildVnfc(recievenNotification, REMOVED, "tenantId2"); + AffectedVnfc modifedVnfc = buildVnfc(recievenNotification, MODIFIED, "tenantId3"); + boolean inMaintenance = true; + ReportedAffectedConnectionPoints affectedConnectionPoints = new ReportedAffectedConnectionPoints(); + + ReportedAffectedCp removedCp = buildCp(); + removedCp.setServerProviderId("serverId"); + affectedConnectionPoints.getPre().add(removedCp); + + ReportedAffectedCp removedCpWithoutServer = buildCp(); + removedCpWithoutServer.setServerProviderId(null); + affectedConnectionPoints.getPre().add(removedCpWithoutServer); + + ReportedAffectedCp addedCp = buildCp(); + addedCp.setServerProviderId("serverId"); + affectedConnectionPoints.getPost().add(addedCp); + //when + aaiNotificationProcessor.processNotification(recievenNotification, null, of(affectedConnectionPoints), VIM_ID); + //verify + InOrder inOrder = Mockito.inOrder(genericVnfManager, l3NetworkManager, lInterfaceManager, vnfcManager, vserverManager); + inOrder.verify(l3NetworkManager).update(VIM_ID, VNF_ID, addedLink); + inOrder.verify(l3NetworkManager).update(VIM_ID, VNF_ID, modifiedLink); + inOrder.verify(vserverManager).update(VIM_ID, VNF_ID, addedVnfc, affectedVirtualStorages, inMaintenance); + inOrder.verify(vnfcManager).update(VIM_ID, "tenantId1", VNF_ID, addedVnfc, inMaintenance); + inOrder.verify(vserverManager).update(VIM_ID, VNF_ID, modifedVnfc, affectedVirtualStorages, inMaintenance); + inOrder.verify(vnfcManager).update(VIM_ID, "tenantId3", VNF_ID, modifedVnfc, inMaintenance); + inOrder.verify(lInterfaceManager).delete(VIM_ID, removedCp); + inOrder.verify(lInterfaceManager).update(VNF_ID, VIM_ID, addedCp, inMaintenance); + inOrder.verify(vnfcManager).delete(VNF_ID, removedVnfc); + inOrder.verify(vserverManager).delete(VIM_ID, removedVnfc); + inOrder.verify(l3NetworkManager).delete(VNF_ID, removedLink); + verify(lInterfaceManager, never()).update(VNF_ID, VIM_ID, removedCpWithoutServer, inMaintenance); + verify(lInterfaceManager, never()).delete(VIM_ID, removedCpWithoutServer); + } + + /** + * - unchanged CP is updated + * - changed CP is updated + */ + @Test + public void testCps() throws Exception { + VnfLifecycleChangeNotification recievenNotification = new VnfLifecycleChangeNotification(); + recievenNotification.setAffectedVnfcs(new ArrayList<>()); + recievenNotification.setAffectedVirtualLinks(new ArrayList<>()); + recievenNotification.setVnfInstanceId(VNF_ID); + recievenNotification.setStatus(OperationStatus.STARTED); + ArrayList<AffectedVirtualStorage> affectedVirtualStorages = new ArrayList<>(); + recievenNotification.setAffectedVirtualStorages(affectedVirtualStorages); + boolean inMaintenance = true; + ReportedAffectedConnectionPoints affectedConnectionPoints = new ReportedAffectedConnectionPoints(); + + ReportedAffectedCp unchangedCp = buildCp(); + unchangedCp.setCpId("unchanged"); + affectedConnectionPoints.getPre().add(unchangedCp); + affectedConnectionPoints.getPost().add(unchangedCp); + + ReportedAffectedCp changedCpBefore = buildCp(); + changedCpBefore.setCpId("changedBefore"); + ReportedAffectedCp changedCpAfter = buildCp(); + changedCpAfter.setCpId("changedAfter"); + changedCpAfter.setCpId(changedCpBefore.getCpId()); + affectedConnectionPoints.getPre().add(changedCpBefore); + affectedConnectionPoints.getPost().add(changedCpAfter); + + //when + aaiNotificationProcessor.processNotification(recievenNotification, null, of(affectedConnectionPoints), VIM_ID); + //verify + verify(lInterfaceManager).update(VNF_ID, VIM_ID, unchangedCp, inMaintenance); + verify(lInterfaceManager, never()).update(VNF_ID, VIM_ID, changedCpBefore, inMaintenance); + verify(lInterfaceManager).update(VNF_ID, VIM_ID, changedCpAfter, inMaintenance); + } + + /** + * the end notification calls resource managers with not in maintenance state + */ + @Test + public void testEndNotification() throws Exception { + VnfLifecycleChangeNotification recievenNotification = new VnfLifecycleChangeNotification(); + recievenNotification.setAffectedVnfcs(new ArrayList<>()); + recievenNotification.setAffectedVirtualLinks(new ArrayList<>()); + ArrayList<AffectedVirtualStorage> affectedVirtualStorages = new ArrayList<>(); + recievenNotification.setAffectedVirtualStorages(affectedVirtualStorages); + recievenNotification.setVnfInstanceId(VNF_ID); + recievenNotification.setStatus(OperationStatus.FINISHED); + AffectedVirtualLink addedLink = buildVl(recievenNotification, ADDED); + AffectedVirtualLink removedLink = buildVl(recievenNotification, REMOVED); + AffectedVirtualLink modifiedLink = buildVl(recievenNotification, MODIFIED); + AffectedVnfc addedVnfc = buildVnfc(recievenNotification, ADDED, "tenantId1"); + AffectedVnfc removedVnfc = buildVnfc(recievenNotification, REMOVED, "tenantId2"); + AffectedVnfc modifedVnfc = buildVnfc(recievenNotification, MODIFIED, "tenantId3"); + boolean inMaintenance = false; + ReportedAffectedConnectionPoints affectedConnectionPoints = new ReportedAffectedConnectionPoints(); + + ReportedAffectedCp removedCp = buildCp(); + removedCp.setServerProviderId("serverId"); + affectedConnectionPoints.getPre().add(removedCp); + + ReportedAffectedCp removedCpWithoutServer = buildCp(); + removedCpWithoutServer.setServerProviderId(null); + affectedConnectionPoints.getPre().add(removedCpWithoutServer); + + ReportedAffectedCp addedCp = buildCp(); + addedCp.setServerProviderId("serverId"); + affectedConnectionPoints.getPost().add(addedCp); + + ReportedAffectedCp cpWithoutServer = buildCp(); + cpWithoutServer.setServerProviderId(null); + affectedConnectionPoints.getPost().add(cpWithoutServer); + + //when + aaiNotificationProcessor.processNotification(recievenNotification, null, of(affectedConnectionPoints), VIM_ID); + //verify + InOrder inOrder = Mockito.inOrder(genericVnfManager, l3NetworkManager, lInterfaceManager, vnfcManager, vserverManager); + inOrder.verify(l3NetworkManager).update(VIM_ID, VNF_ID, addedLink); + inOrder.verify(l3NetworkManager).update(VIM_ID, VNF_ID, modifiedLink); + inOrder.verify(vserverManager).update(VIM_ID, VNF_ID, addedVnfc, affectedVirtualStorages, inMaintenance); + inOrder.verify(vnfcManager).update(VIM_ID, "tenantId1", VNF_ID, addedVnfc, inMaintenance); + inOrder.verify(vserverManager).update(VIM_ID, VNF_ID, modifedVnfc, affectedVirtualStorages, inMaintenance); + inOrder.verify(vnfcManager).update(VIM_ID, "tenantId3", VNF_ID, modifedVnfc, inMaintenance); + inOrder.verify(lInterfaceManager).delete(VIM_ID, removedCp); + inOrder.verify(lInterfaceManager).update(VNF_ID, VIM_ID, addedCp, inMaintenance); + inOrder.verify(vnfcManager).delete(VNF_ID, removedVnfc); + inOrder.verify(vserverManager).delete(VIM_ID, removedVnfc); + inOrder.verify(l3NetworkManager).delete(VNF_ID, removedLink); + verify(lInterfaceManager, never()).update(VNF_ID, VIM_ID, removedCpWithoutServer, inMaintenance); + verify(lInterfaceManager, never()).delete(VIM_ID, removedCpWithoutServer); + verify(logger).warn("The changed {} connection point is not linked to any server", cpWithoutServer.getCpId()); + } + + + + /** + * if changes connection points are not present a warning is logged + */ + @Test + public void testMissingChangedConnectionPoints() throws Exception { + VnfLifecycleChangeNotification recievenNotification = new VnfLifecycleChangeNotification(); + recievenNotification.setAffectedVnfcs(new ArrayList<>()); + recievenNotification.setAffectedVirtualLinks(new ArrayList<>()); + recievenNotification.setVnfInstanceId(VNF_ID); + //when + aaiNotificationProcessor.processNotification(recievenNotification, null, empty(), VIM_ID); + //verify + verify(logger).warn("The changed connection points are not present in VNF with {} identifier", VNF_ID); + } + + @NotNull + private ReportedAffectedCp buildCp() { + ReportedAffectedCp cp = new ReportedAffectedCp(); + cp.setServerProviderId(UUID.randomUUID().toString()); + cp.setName(UUID.randomUUID().toString()); + cp.setEcpdId(UUID.randomUUID().toString()); + cp.setMacAddress(UUID.randomUUID().toString()); + cp.setNetworkProviderId(UUID.randomUUID().toString()); + cp.setCpdId(UUID.randomUUID().toString()); + cp.setCpId(UUID.randomUUID().toString()); + cp.setTenantId(UUID.randomUUID().toString()); + return cp; + } + + private AffectedVirtualLink buildVl(VnfLifecycleChangeNotification recievenNotification, ChangeType changeType) { + AffectedVirtualLink affectedVirtualLink = new AffectedVirtualLink(); + affectedVirtualLink.setChangeType(changeType); + recievenNotification.getAffectedVirtualLinks().add(affectedVirtualLink); + return affectedVirtualLink; + } + + private AffectedVnfc buildVnfc(VnfLifecycleChangeNotification recievenNotification, ChangeType changeType, String tenantId) { + AffectedVnfc addedVnfc = new AffectedVnfc(); + addedVnfc.setChangeType(changeType); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("tenantId", tenantId); + addedVnfc.setComputeResource(new ResourceHandle()); + addedVnfc.getComputeResource().setAdditionalData(additionalData); + recievenNotification.getAffectedVnfcs().add(addedVnfc); + return addedVnfc; + } +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestAbstractManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestAbstractManager.java new file mode 100644 index 00000000..2495daf1 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestAbstractManager.java @@ -0,0 +1,230 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.google.gson.JsonObject; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.onap.aai.domain.yang.v11.*; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; +import org.slf4j.Logger; + +import java.util.NoSuchElementException; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.Mockito.when; + +public class TestAbstractManager extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + @Mock + private AAIRestApiProvider aaiRestApiProvider; + private DummyManager dummyManager; + + @Before + public void init() { + dummyManager = new DummyManager(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + } + + /** + * if the REST resource does not exists the provided instance is used + */ + @Test + public void testIfResourceDoesNotExists() throws Exception { + GenericVnf newInstance = OBJECT_FACTORY.createGenericVnf(); + when(aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "url", GenericVnf.class)).thenThrow(new NoSuchElementException()); + //when + GenericVnf actualInstance = dummyManager.createOrGet(AAIRestApiProvider.AAIService.CLOUD, "url", newInstance); + //verify + assertEquals(newInstance, actualInstance); + } + + /** + * if the REST resource exists it is not recreated + */ + @Test + public void testIfResourceExists() throws Exception { + GenericVnf newInstance = OBJECT_FACTORY.createGenericVnf(); + GenericVnf existingInstance = OBJECT_FACTORY.createGenericVnf(); + existingInstance.setVnfId("id"); + when(aaiRestApiProvider.get(logger, AAIRestApiProvider.AAIService.CLOUD, "url", GenericVnf.class)).thenReturn(existingInstance); + //when + GenericVnf actualInstance = dummyManager.createOrGet(AAIRestApiProvider.AAIService.CLOUD, "url", newInstance); + //verify + assertEquals(existingInstance, actualInstance); + } + + @Test + public void testBuildRelationshipData() { + RelationshipData relationshipData = AbstractManager.buildRelationshipData("key", "value"); + assertEquals("key", relationshipData.getRelationshipKey()); + assertEquals("value", relationshipData.getRelationshipValue()); + } + + @Test + public void testExtractMandatoryValue() { + JsonObject object = new JsonObject(); + object.addProperty("key", "value"); + assertEquals("value", AbstractManager.extractMandatoryValue(object, "key")); + } + + /** + * the same relation is replaced + */ + @Test + public void testAddSingletonRelationForExisting() { + RelationshipList relations = OBJECT_FACTORY.createRelationshipList(); + Relationship relation = OBJECT_FACTORY.createRelationship(); + relation.setRelatedTo("unknownRelation"); + relations.getRelationship().add(relation); + Relationship sameRelation = OBJECT_FACTORY.createRelationship(); + sameRelation.setRelatedTo("relatedTo"); + relations.getRelationship().add(sameRelation); + RelationshipData data = OBJECT_FACTORY.createRelationshipData(); + data.setRelationshipValue("v"); + data.setRelationshipKey("k"); + sameRelation.getRelationshipData().add(data); + + Relationship newRelation = OBJECT_FACTORY.createRelationship(); + newRelation.setRelatedTo("relatedTo"); + RelationshipData data2 = OBJECT_FACTORY.createRelationshipData(); + data2.setRelationshipValue("v2"); + data2.setRelationshipKey("k2"); + newRelation.getRelationshipData().add(data2); + + //when + AbstractManager.addSingletonRelation(relations, newRelation); + //verify + + assertEquals(2, relations.getRelationship().size()); + assertEquals(1, relations.getRelationship().get(1).getRelationshipData().size()); + assertEquals("k2", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipKey()); + assertEquals("v2", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipValue()); + } + + /** + * the missing relation is created + */ + @Test + public void testAddSingletonRelation() { + RelationshipList relations = OBJECT_FACTORY.createRelationshipList(); + Relationship relation = OBJECT_FACTORY.createRelationship(); + relation.setRelatedTo("unknownRelation"); + relations.getRelationship().add(relation); + + Relationship newRelation = OBJECT_FACTORY.createRelationship(); + newRelation.setRelatedTo("relatedTo"); + RelationshipData data2 = OBJECT_FACTORY.createRelationshipData(); + data2.setRelationshipValue("v2"); + data2.setRelationshipKey("k2"); + newRelation.getRelationshipData().add(data2); + + //when + AbstractManager.addSingletonRelation(relations, newRelation); + //verify + assertEquals(2, relations.getRelationship().size()); + assertEquals(1, relations.getRelationship().get(1).getRelationshipData().size()); + assertEquals("k2", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipKey()); + assertEquals("v2", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipValue()); + } + + /** + * the same relation is replaced + */ + @Test + public void testAddMissingRelationForExisting() { + RelationshipList relations = OBJECT_FACTORY.createRelationshipList(); + Relationship relation = OBJECT_FACTORY.createRelationship(); + relation.setRelatedTo("unknownRelation"); + relations.getRelationship().add(relation); + Relationship sameRelation = OBJECT_FACTORY.createRelationship(); + sameRelation.setRelatedTo("relatedTo"); + relations.getRelationship().add(sameRelation); + RelationshipData data = OBJECT_FACTORY.createRelationshipData(); + data.setRelationshipValue("v"); + data.setRelationshipKey("k"); + sameRelation.getRelationshipData().add(data); + + Relationship newRelation = OBJECT_FACTORY.createRelationship(); + newRelation.setRelatedTo("relatedTo"); + RelationshipData data2 = OBJECT_FACTORY.createRelationshipData(); + data2.setRelationshipValue("v2"); + data2.setRelationshipKey("k2"); + newRelation.getRelationshipData().add(data2); + + //when + AbstractManager.addMissingRelation(relations, newRelation); + //verify + + assertEquals(3, relations.getRelationship().size()); + assertEquals(1, relations.getRelationship().get(1).getRelationshipData().size()); + assertEquals("k", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipKey()); + assertEquals("v", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipValue()); + assertEquals("k2", relations.getRelationship().get(2).getRelationshipData().get(0).getRelationshipKey()); + assertEquals("v2", relations.getRelationship().get(2).getRelationshipData().get(0).getRelationshipValue()); + } + + /** + * adding the same relation is not duplicated + */ + @Test + public void testAddMissingRelation() { + RelationshipList relations = OBJECT_FACTORY.createRelationshipList(); + Relationship relation = OBJECT_FACTORY.createRelationship(); + relation.setRelatedTo("unknownRelation"); + relations.getRelationship().add(relation); + + Relationship sameRelation = OBJECT_FACTORY.createRelationship(); + sameRelation.setRelatedTo("relatedTo"); + relations.getRelationship().add(sameRelation); + RelationshipData data = OBJECT_FACTORY.createRelationshipData(); + data.setRelationshipValue("v"); + data.setRelationshipKey("k"); + sameRelation.getRelationshipData().add(data); + + Relationship newRelation = OBJECT_FACTORY.createRelationship(); + newRelation.setRelatedTo("relatedTo"); + RelationshipData data2 = OBJECT_FACTORY.createRelationshipData(); + data2.setRelationshipValue("v"); + data2.setRelationshipKey("k"); + newRelation.getRelationshipData().add(data2); + + //when + AbstractManager.addMissingRelation(relations, newRelation); + //verify + assertEquals(2, relations.getRelationship().size()); + assertEquals(1, relations.getRelationship().get(1).getRelationshipData().size()); + assertEquals("k", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipKey()); + assertEquals("v", relations.getRelationship().get(1).getRelationshipData().get(0).getRelationshipValue()); + } + + class DummyManager extends AbstractManager { + + DummyManager(AAIRestApiProvider aaiRestApiProvider, CbamRestApiProvider cbamRestApiProvider, DriverProperties driverProperties) { + super(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + } + + @Override + protected Logger getLogger() { + return logger; + } + } + + +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestGenericVnfManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestGenericVnfManager.java new file mode 100644 index 00000000..861966f3 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestGenericVnfManager.java @@ -0,0 +1,250 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.nokia.cbam.lcm.v32.ApiException; +import com.nokia.cbam.lcm.v32.model.VnfInfo; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.aai.domain.yang.v11.*; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; + +import java.util.HashSet; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.fail; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.NETWORK; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestGenericVnfManager extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + private ArgumentCaptor<GenericVnf> payload = ArgumentCaptor.forClass(GenericVnf.class); + + @Mock + private AAIRestApiProvider aaiRestApiProvider; + private GenericVnfManager genericVnfManager; + private VnfInfo vnfInfo = new VnfInfo(); + + static void assertRelation(RelationshipList relationShips, String relatedTo, RelationshipData... data) { + for (Relationship relationship : relationShips.getRelationship()) { + if (relationship.getRelatedTo().equals(relatedTo)) { + assertEquals(data.length, relationship.getRelationshipData().size()); + int i = 0; + for (RelationshipData c : data) { + assertEquals(c.getRelationshipKey(), relationship.getRelationshipData().get(i).getRelationshipKey()); + assertEquals(c.getRelationshipValue(), relationship.getRelationshipData().get(i).getRelationshipValue()); + i++; + } + return; + } + } + fail(); + } + + @Before + public void init() { + genericVnfManager = new GenericVnfManager(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + setField(GenericVnfManager.class, "logger", logger); + AtomicLong currentTime = new AtomicLong(0L); + when(systemFunctions.currentTimeMillis()).thenAnswer(new Answer<Long>() { + @Override + public Long answer(InvocationOnMock invocation) throws Throwable { + return currentTime.get(); + } + }); + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + currentTime.addAndGet((Long) invocation.getArguments()[0] + 1); + return null; + } + }).when(systemFunctions).sleep(anyLong()); + } + + /** + * retrieving an existing VNF + */ + @Test + public void testGetExistingVnf() throws Exception { + GenericVnf aaiVnf = OBJECT_FACTORY.createGenericVnf(); + when(aaiRestApiProvider.get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class)).thenReturn(aaiVnf); + //when + GenericVnf vnf = genericVnfManager.getExistingVnf(VNF_ID); + //verify + assertEquals(aaiVnf, vnf); + } + + /** + * if the VNF does not exist it is created + */ + @Test + public void createNonExistingVnf() throws Exception { + GenericVnf vnfInAaai = OBJECT_FACTORY.createGenericVnf(); + Set<GenericVnf> vnfs = new HashSet<>(); + when(aaiRestApiProvider.get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class)).thenAnswer((Answer<GenericVnf>) invocation -> { + if (vnfs.size() == 0) { + throw new NoSuchElementException(); + } + return vnfs.iterator().next(); + }); + when(cbamRestApiProvider.getCbamLcmApi(VNFM_ID).vnfsVnfInstanceIdGet(VNF_ID, CbamRestApiProvider.NOKIA_LCM_API_VERSION)).thenReturn(vnfInfo); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/generic-vnfs/generic-vnf/" + VNF_ID), payload.capture(), eq(Void.class))).thenAnswer(invocation -> { + vnfs.add(vnfInAaai); + return null; + }); + vnfInfo.setName("vnfName"); + //when + genericVnfManager.createOrUpdate(VNF_ID, true); + //verify + GenericVnf vnfSentToAai = payload.getValue(); + assertEquals(VNF_ID, vnfSentToAai.getVnfId()); + assertEquals(VNF_ID, vnfSentToAai.getVnfInstanceId()); + assertEquals("NokiaVNF", vnfSentToAai.getVnfType()); + assertEquals(true, vnfSentToAai.isInMaint()); + assertEquals(true, vnfSentToAai.isIsClosedLoopDisabled()); + assertEquals("vnfName", vnfSentToAai.getVnfName()); + verify(systemFunctions, times(10)).sleep(3000); + verify(aaiRestApiProvider, times(10)).get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class); + } + + /** + * if the VNF exist it is updated + */ + @Test + public void testUpdateExistingVnf() throws Exception { + GenericVnf vnfInAaai = OBJECT_FACTORY.createGenericVnf(); + vnfInAaai.setResourceVersion("v1"); + when(aaiRestApiProvider.get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class)).thenReturn(vnfInAaai); + when(cbamRestApiProvider.getCbamLcmApi(VNFM_ID).vnfsVnfInstanceIdGet(VNF_ID, CbamRestApiProvider.NOKIA_LCM_API_VERSION)).thenReturn(vnfInfo); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/generic-vnfs/generic-vnf/" + VNF_ID), payload.capture(), eq(Void.class))).thenReturn(null); + vnfInfo.setName("vnfName"); + //when + genericVnfManager.createOrUpdate(VNF_ID, true); + //verify + GenericVnf vnfSentToAai = payload.getValue(); + assertEquals(VNF_ID, vnfSentToAai.getVnfId()); + assertEquals(VNF_ID, vnfSentToAai.getVnfInstanceId()); + assertEquals("NokiaVNF", vnfSentToAai.getVnfType()); + assertEquals(true, vnfSentToAai.isInMaint()); + assertEquals(true, vnfSentToAai.isIsClosedLoopDisabled()); + assertEquals("vnfName", vnfSentToAai.getVnfName()); + verify(systemFunctions, never()).sleep(anyLong()); + verify(aaiRestApiProvider, times(1)).get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class); + } + + /** + * error is propagated if unable to query VNF from CBAM + */ + @Test + public void testUnableToQueryVnfFromCBAM() throws Exception { + GenericVnf vnfInAaai = OBJECT_FACTORY.createGenericVnf(); + vnfInAaai.setResourceVersion("v1"); + when(aaiRestApiProvider.get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class)).thenReturn(vnfInAaai); + ApiException expectedException = new ApiException(); + when(cbamRestApiProvider.getCbamLcmApi(VNFM_ID).vnfsVnfInstanceIdGet(VNF_ID, CbamRestApiProvider.NOKIA_LCM_API_VERSION)).thenThrow(expectedException); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/generic-vnfs/generic-vnf/" + VNF_ID), payload.capture(), eq(Void.class))).thenAnswer(invocation -> { + vnfInAaai.setResourceVersion("v2"); + return null; + }); + vnfInfo.setName("vnfName"); + //when + try { + genericVnfManager.createOrUpdate(VNF_ID, true); + } catch (Exception e) { + verify(logger).error("Unable to query VNF with myVnfId identifier from CBAM", expectedException); + assertEquals("Unable to query VNF with myVnfId identifier from CBAM", e.getMessage()); + } + } + + /** + * if the VNF is created after the last attempt to query VNF, but before the + * the driver creates the VNF it is not created but updated + */ + @Test + public void testConcurency1() throws Exception { + GenericVnf vnfInAaai = OBJECT_FACTORY.createGenericVnf(); + vnfInAaai.setResourceVersion("v3"); + Set<Integer> queryCount = new HashSet<>(); + when(aaiRestApiProvider.get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class)).thenAnswer((Answer<GenericVnf>) invocation -> { + queryCount.add(queryCount.size()); + if (queryCount.size() >= 11) { + return vnfInAaai; + } + throw new NoSuchElementException(); + }); + when(cbamRestApiProvider.getCbamLcmApi(VNFM_ID).vnfsVnfInstanceIdGet(VNF_ID, CbamRestApiProvider.NOKIA_LCM_API_VERSION)).thenReturn(vnfInfo); + RuntimeException runtimeException = new RuntimeException(); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/generic-vnfs/generic-vnf/" + VNF_ID), payload.capture(), eq(Void.class))).thenAnswer(invocation -> { + GenericVnf vnfSentToAAi = (GenericVnf) invocation.getArguments()[3]; + if (vnfSentToAAi.getResourceVersion() == null) { + throw runtimeException; + } + return null; + }); + vnfInfo.setName("vnfName"); + //when + genericVnfManager.createOrUpdate(VNF_ID, true); + //verify + GenericVnf vnfSentToAai = payload.getValue(); + assertEquals(VNF_ID, vnfSentToAai.getVnfId()); + assertEquals(VNF_ID, vnfSentToAai.getVnfInstanceId()); + assertEquals("NokiaVNF", vnfSentToAai.getVnfType()); + assertEquals(true, vnfSentToAai.isInMaint()); + assertEquals(true, vnfSentToAai.isIsClosedLoopDisabled()); + assertEquals("vnfName", vnfSentToAai.getVnfName()); + assertEquals("v3", vnfSentToAai.getResourceVersion()); + verify(systemFunctions, times(10)).sleep(3000); + verify(aaiRestApiProvider, times(11)).get(logger, NETWORK, "/generic-vnfs/generic-vnf/" + VNF_ID, GenericVnf.class); + verify(aaiRestApiProvider, times(2)).put(eq(logger), eq(NETWORK), eq("/generic-vnfs/generic-vnf/" + VNF_ID), anyString(), eq(Void.class)); + verify(logger).warn(eq("The VNF with myVnfId identifier did not appear in time"), any(NoSuchElementException.class)); + verify(logger).warn("The VNF with myVnfId identifier has been created since after the maximal wait for VNF to appear timeout", runtimeException); + } + + /** + * test how entities can refer to a VNF + */ + @Test + public void testRelations() { + //when + Relationship relationship = GenericVnfManager.linkTo(VNF_ID); + //verify + assertEquals("generic-vnf", relationship.getRelatedTo()); + assertEquals(1, relationship.getRelationshipData().size()); + assertEquals("generic-vnf.vnf-id", relationship.getRelationshipData().get(0).getRelationshipKey()); + assertEquals(VNF_ID, relationship.getRelationshipData().get(0).getRelationshipValue()); + } + + /** + * test inheritence + */ + @Test + public void testInheritence() { + assertEquals(logger, genericVnfManager.getLogger()); + } +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestL3NetworkManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestL3NetworkManager.java new file mode 100644 index 00000000..159d6e63 --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestL3NetworkManager.java @@ -0,0 +1,143 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.google.gson.JsonObject; +import com.nokia.cbam.lcm.v32.model.AffectedVirtualLink; +import com.nokia.cbam.lcm.v32.model.ResourceHandle; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.onap.aai.domain.yang.v11.L3Network; +import org.onap.aai.domain.yang.v11.ObjectFactory; +import org.onap.aai.domain.yang.v11.RelationshipList; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; + +import java.util.NoSuchElementException; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +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.onap.direct.AAIRestApiProvider.AAIService.NETWORK; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.AbstractManager.buildRelationshipData; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.TestGenericVnfManager.assertRelation; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getCloudOwner; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getRegionName; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestL3NetworkManager extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + private ArgumentCaptor<L3Network> payload = ArgumentCaptor.forClass(L3Network.class); + private AffectedVirtualLink affectedVirtualLink = new AffectedVirtualLink(); + @Mock + private AAIRestApiProvider aaiRestApiProvider; + private L3NetworkManager l3NetworkManager; + + @Before + public void init() { + l3NetworkManager = new L3NetworkManager(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + setField(L3NetworkManager.class, "logger", logger); + } + + /** + * test L3 network creation + */ + @Test + public void testUpdate() throws Exception { + affectedVirtualLink.setId("vlId"); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("name", "netName"); + additionalData.addProperty("tenantId", "myTenantId"); + affectedVirtualLink.setResource(new ResourceHandle()); + affectedVirtualLink.getResource().setAdditionalData(additionalData); + affectedVirtualLink.getResource().setResourceId("netProviderId"); + when(aaiRestApiProvider.get(logger, NETWORK, "/l3-networks/l3-network/myVnfId_vlId", L3Network.class)).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/l3-networks/l3-network/myVnfId_vlId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + l3NetworkManager.update(VIM_ID, VNF_ID, affectedVirtualLink); + //verify + assertEquals("myVnfId_vlId", payload.getValue().getNetworkId()); + assertEquals("netName", payload.getValue().getNetworkName()); + assertEquals("netProviderId", payload.getValue().getNeutronNetworkId()); + assertFalse(payload.getValue().isIsBoundToVpn()); + assertFalse(payload.getValue().isIsProviderNetwork()); + assertFalse(payload.getValue().isIsSharedNetwork()); + assertFalse(payload.getValue().isIsExternalNetwork()); + assertEquals("active", payload.getValue().getOperationalStatus()); + assertRelation(payload.getValue().getRelationshipList(), "cloud-region", buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(VIM_ID)), buildRelationshipData("cloud-region.cloud-region-id", getRegionName(VIM_ID))); + assertRelation(payload.getValue().getRelationshipList(), "tenant", buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(VIM_ID)), buildRelationshipData("cloud-region.cloud-region-id", getRegionName(VIM_ID)), buildRelationshipData("tenant.tenant-id", "myTenantId")); + assertRelation(payload.getValue().getRelationshipList(), "generic-vnf", buildRelationshipData("generic-vnf.vnf-id", VNF_ID)); + } + + /** + * Test existing resource update + */ + @Test + public void testExistingUpdate() throws Exception { + affectedVirtualLink.setId("vlId"); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("name", "netName"); + additionalData.addProperty("tenantId", "myTenantId"); + affectedVirtualLink.setResource(new ResourceHandle()); + affectedVirtualLink.getResource().setAdditionalData(additionalData); + affectedVirtualLink.getResource().setResourceId("netProviderId"); + L3Network l3Network = OBJECT_FACTORY.createL3Network(); + l3Network.setResourceVersion("v3"); + l3Network.setRelationshipList(new RelationshipList()); + when(aaiRestApiProvider.get(logger, NETWORK, "/l3-networks/l3-network/myVnfId_vlId", L3Network.class)).thenReturn(l3Network); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/l3-networks/l3-network/myVnfId_vlId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + l3NetworkManager.update(VIM_ID, VNF_ID, affectedVirtualLink); + //verify + assertEquals("myVnfId_vlId", payload.getValue().getNetworkId()); + assertEquals("netName", payload.getValue().getNetworkName()); + assertEquals("netProviderId", payload.getValue().getNeutronNetworkId()); + assertFalse(payload.getValue().isIsBoundToVpn()); + assertFalse(payload.getValue().isIsProviderNetwork()); + assertFalse(payload.getValue().isIsSharedNetwork()); + assertFalse(payload.getValue().isIsExternalNetwork()); + assertEquals("active", payload.getValue().getOperationalStatus()); + assertEquals("v3", payload.getValue().getResourceVersion()); + assertRelation(payload.getValue().getRelationshipList(), "cloud-region", buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(VIM_ID)), buildRelationshipData("cloud-region.cloud-region-id", getRegionName(VIM_ID))); + assertRelation(payload.getValue().getRelationshipList(), "tenant", buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(VIM_ID)), buildRelationshipData("cloud-region.cloud-region-id", getRegionName(VIM_ID)), buildRelationshipData("tenant.tenant-id", "myTenantId")); + assertRelation(payload.getValue().getRelationshipList(), "generic-vnf", buildRelationshipData("generic-vnf.vnf-id", VNF_ID)); + } + /** + * test L3 network deletion + */ + @Test + public void testDelete() throws Exception { + affectedVirtualLink.setId("vlId"); + //when + l3NetworkManager.delete(VNF_ID, affectedVirtualLink); + //verify + verify(aaiRestApiProvider).delete(logger, NETWORK, "/l3-networks/l3-network/myVnfId_vlId"); + } + + /** + * test inheritence + */ + @Test + public void testInheritence() { + assertEquals(logger, l3NetworkManager.getLogger()); + } + + +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestLInterfaceManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestLInterfaceManager.java new file mode 100644 index 00000000..ef9f569e --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestLInterfaceManager.java @@ -0,0 +1,230 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.onap.aai.domain.yang.v11.LInterface; +import org.onap.aai.domain.yang.v11.ObjectFactory; +import org.onap.aai.domain.yang.v11.RelationshipList; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.ReportedAffectedCp; + +import java.util.NoSuchElementException; + +import static junit.framework.TestCase.assertEquals; +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.onap.direct.AAIRestApiProvider.AAIService.CLOUD; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.AbstractManager.buildRelationshipData; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.TestGenericVnfManager.assertRelation; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestLInterfaceManager extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + private ArgumentCaptor<LInterface> payload = ArgumentCaptor.forClass(LInterface.class); + + @Mock + private AAIRestApiProvider aaiRestApiProvider; + private LInterfaceManager lInterfaceManager; + + @Before + public void init() { + lInterfaceManager = new LInterfaceManager(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + setField(LInterfaceManager.class, "logger", logger); + } + + /** + * test update success scenario + */ + @Test + public void testUpdate() throws Exception { + ReportedAffectedCp affectedCp = new ReportedAffectedCp(); + affectedCp.setCpdId("cpdId"); + affectedCp.setTenantId("myTenantId"); + affectedCp.setProviderId("portProviderId"); + affectedCp.setServerProviderId("serverProviderId"); + affectedCp.setNetworkProviderId("networkProviderId"); + affectedCp.setMacAddress("mac"); + affectedCp.setIpAddress("1.2.3.4"); + affectedCp.setEcpdId("ecpdId"); + affectedCp.setName("name"); + affectedCp.setCpId("cpId"); + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), eq(LInterface.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + lInterfaceManager.update(VNF_ID, VIM_ID, affectedCp, true); + //verify + LInterface actualInterface = payload.getValue(); + assertEquals(true, actualInterface.isInMaint()); + assertEquals(false, actualInterface.isIsIpUnnumbered()); + assertEquals(false, actualInterface.isIsPortMirrored()); + assertEquals("name", actualInterface.getInterfaceName()); + assertEquals("cpId", actualInterface.getInterfaceId()); + assertEquals("cpdId", actualInterface.getInterfaceRole()); + assertEquals("mac", actualInterface.getMacaddr()); + assertEquals("active", actualInterface.getProvStatus()); + assertEquals(1, actualInterface.getL3InterfaceIpv4AddressList().size()); + assertEquals(0, actualInterface.getL3InterfaceIpv6AddressList().size()); + assertEquals("networkProviderId", actualInterface.getL3InterfaceIpv4AddressList().get(0).getNeutronNetworkId()); + assertEquals("1.2.3.4", actualInterface.getL3InterfaceIpv4AddressList().get(0).getL3InterfaceIpv4Address()); + assertRelation(actualInterface.getRelationshipList(), "generic-vnf", buildRelationshipData("generic-vnf.vnf-id", VNF_ID)); + } + + /** + * test update success scenario without IP + */ + @Test + public void testUpdateWithoutIp() throws Exception { + ReportedAffectedCp affectedCp = new ReportedAffectedCp(); + affectedCp.setCpdId("cpdId"); + affectedCp.setTenantId("myTenantId"); + affectedCp.setProviderId("portProviderId"); + affectedCp.setServerProviderId("serverProviderId"); + affectedCp.setNetworkProviderId("networkProviderId"); + affectedCp.setMacAddress("mac"); + affectedCp.setEcpdId("ecpdId"); + affectedCp.setName("name"); + affectedCp.setCpId("cpId"); + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), eq(LInterface.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + lInterfaceManager.update(VNF_ID, VIM_ID, affectedCp, true); + //verify + LInterface actualInterface = payload.getValue(); + assertEquals(true, actualInterface.isInMaint()); + assertEquals(false, actualInterface.isIsIpUnnumbered()); + assertEquals(false, actualInterface.isIsPortMirrored()); + assertEquals("name", actualInterface.getInterfaceName()); + assertEquals("cpId", actualInterface.getInterfaceId()); + assertEquals("cpdId", actualInterface.getInterfaceRole()); + assertEquals("mac", actualInterface.getMacaddr()); + assertEquals("active", actualInterface.getProvStatus()); + assertEquals(0, actualInterface.getL3InterfaceIpv6AddressList().size()); + assertEquals(0, actualInterface.getL3InterfaceIpv4AddressList().size()); + assertRelation(actualInterface.getRelationshipList(), "generic-vnf", buildRelationshipData("generic-vnf.vnf-id", VNF_ID)); + } + + /** + * test update success scenario + */ + @Test + public void testExistingUpdate() throws Exception { + ReportedAffectedCp affectedCp = new ReportedAffectedCp(); + affectedCp.setCpdId("cpdId"); + affectedCp.setTenantId("myTenantId"); + affectedCp.setProviderId("portProviderId"); + affectedCp.setServerProviderId("serverProviderId"); + affectedCp.setNetworkProviderId("networkProviderId"); + affectedCp.setMacAddress("mac"); + affectedCp.setIpAddress("1.2.3.4"); + affectedCp.setEcpdId("ecpdId"); + affectedCp.setName("name"); + affectedCp.setCpId("cpId"); + LInterface lInterface = OBJECT_FACTORY.createLInterface(); + lInterface.setResourceVersion("v3"); + lInterface.setRelationshipList(new RelationshipList()); + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), eq(LInterface.class))).thenReturn(lInterface); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + lInterfaceManager.update(VNF_ID, VIM_ID, affectedCp, true); + //verify + LInterface actualInterface = payload.getValue(); + assertEquals(true, actualInterface.isInMaint()); + assertEquals(false, actualInterface.isIsIpUnnumbered()); + assertEquals(false, actualInterface.isIsPortMirrored()); + assertEquals("name", actualInterface.getInterfaceName()); + assertEquals("cpId", actualInterface.getInterfaceId()); + assertEquals("cpdId", actualInterface.getInterfaceRole()); + assertEquals("mac", actualInterface.getMacaddr()); + assertEquals("active", actualInterface.getProvStatus()); + assertEquals(1, actualInterface.getL3InterfaceIpv4AddressList().size()); + assertEquals(0, actualInterface.getL3InterfaceIpv6AddressList().size()); + assertEquals("networkProviderId", actualInterface.getL3InterfaceIpv4AddressList().get(0).getNeutronNetworkId()); + assertEquals("1.2.3.4", actualInterface.getL3InterfaceIpv4AddressList().get(0).getL3InterfaceIpv4Address()); + assertEquals("v3", lInterface.getResourceVersion()); + assertRelation(actualInterface.getRelationshipList(), "generic-vnf", buildRelationshipData("generic-vnf.vnf-id", VNF_ID)); + } + + /** + * test update success scenario for IPv6 address + */ + @Test + public void testUpdateForIpv6() throws Exception { + ReportedAffectedCp affectedCp = new ReportedAffectedCp(); + affectedCp.setCpdId("cpdId"); + affectedCp.setTenantId("myTenantId"); + affectedCp.setProviderId("portProviderId"); + affectedCp.setServerProviderId("serverProviderId"); + affectedCp.setNetworkProviderId("networkProviderId"); + affectedCp.setMacAddress("mac"); + affectedCp.setIpAddress("::"); + affectedCp.setEcpdId("ecpdId"); + affectedCp.setName("name"); + affectedCp.setCpId("cpId"); + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), eq(LInterface.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq("/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + lInterfaceManager.update(VNF_ID, VIM_ID, affectedCp, false); + //verify + LInterface actualInterface = payload.getValue(); + assertEquals(false, actualInterface.isInMaint()); + assertEquals(false, actualInterface.isIsIpUnnumbered()); + assertEquals(false, actualInterface.isIsPortMirrored()); + assertEquals("name", actualInterface.getInterfaceName()); + assertEquals("cpId", actualInterface.getInterfaceId()); + assertEquals("cpdId", actualInterface.getInterfaceRole()); + assertEquals("mac", actualInterface.getMacaddr()); + assertEquals("active", actualInterface.getProvStatus()); + assertEquals(0, actualInterface.getL3InterfaceIpv4AddressList().size()); + assertEquals(1, actualInterface.getL3InterfaceIpv6AddressList().size()); + assertEquals("networkProviderId", actualInterface.getL3InterfaceIpv6AddressList().get(0).getNeutronNetworkId()); + assertEquals("::", actualInterface.getL3InterfaceIpv6AddressList().get(0).getL3InterfaceIpv6Address()); + assertRelation(actualInterface.getRelationshipList(), "generic-vnf", buildRelationshipData("generic-vnf.vnf-id", VNF_ID)); + } + + /** + * test L3 network deletion + */ + @Test + public void testDelete() throws Exception { + ReportedAffectedCp affectedCp = new ReportedAffectedCp(); + affectedCp.setCpId("cpId"); + affectedCp.setCpdId("cpdId"); + affectedCp.setTenantId("myTenantId"); + affectedCp.setProviderId("portProviderId"); + affectedCp.setServerProviderId("serverProviderId"); + affectedCp.setNetworkProviderId("networkProviderId"); + //when + lInterfaceManager.delete(VIM_ID, affectedCp); + //verify + verify(aaiRestApiProvider).delete(logger, CLOUD, "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId/l-interfaces/l-interface/cpId"); + } + + /** + * test inheritence + */ + @Test + public void testInheritence() { + assertEquals(logger, lInterfaceManager.getLogger()); + } + + +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestVnfcManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestVnfcManager.java new file mode 100644 index 00000000..87a1149b --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestVnfcManager.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.nokia.cbam.lcm.v32.model.AffectedVnfc; +import com.nokia.cbam.lcm.v32.model.ResourceHandle; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.onap.aai.domain.yang.v11.ObjectFactory; +import org.onap.aai.domain.yang.v11.Vnfc; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; + +import java.util.NoSuchElementException; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.NETWORK; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.AbstractManager.buildRelationshipData; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.TestGenericVnfManager.assertRelation; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getCloudOwner; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getRegionName; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestVnfcManager extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + private ArgumentCaptor<Vnfc> payload = ArgumentCaptor.forClass(Vnfc.class); + + @Mock + private AAIRestApiProvider aaiRestApiProvider; + private VnfcManager vnfcManager; + + @Before + public void init() { + vnfcManager = new VnfcManager(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + setField(VnfcManager.class, "logger", logger); + } + + /** + * test update + */ + @Test + public void testUpdate() throws Exception { + AffectedVnfc affectedVnfc = new AffectedVnfc(); + affectedVnfc.setComputeResource(new ResourceHandle()); + affectedVnfc.getComputeResource().setResourceId("serverProviderId"); + affectedVnfc.setId("vnfcId"); + when(aaiRestApiProvider.get(eq(logger), eq(NETWORK), eq("/vnfcs/vnfc/myVnfId_vnfcId"), eq(Vnfc.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/vnfcs/vnfc/myVnfId_vnfcId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + vnfcManager.update(VIM_ID, "myTenantPrivderId", VNF_ID, affectedVnfc, true); + //verify + Vnfc vnfc = payload.getValue(); + assertEquals("myVnfId_vnfcId", vnfc.getVnfcName()); + assertEquals("vnfcId", vnfc.getNfcFunction()); + assertEquals("vnfcId", vnfc.getNfcNamingCode()); + assertRelation(payload.getValue().getRelationshipList(), "generic-vnf", buildRelationshipData("generic-vnf.vnf-id", VNF_ID)); + + assertRelation(vnfc.getRelationshipList(), "vserver", + buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(VIM_ID)), + buildRelationshipData("cloud-region.cloud-region-id", getRegionName(VIM_ID)), + buildRelationshipData("tenant.tenant-id", "myTenantPrivderId"), + buildRelationshipData("vserver.vserver-id", "serverProviderId")); + } + + /** + * test delete + */ + @Test + public void testDelete() throws Exception { + AffectedVnfc affectedVnfc = new AffectedVnfc(); + affectedVnfc.setComputeResource(new ResourceHandle()); + affectedVnfc.getComputeResource().setResourceId("serverProviderId"); + affectedVnfc.setId("vnfcId"); + when(aaiRestApiProvider.get(eq(logger), eq(NETWORK), eq("/vnfcs/vnfc/myVnfId_vnfcId"), eq(Vnfc.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(NETWORK), eq("/vnfcs/vnfc/myVnfId_vnfcId"), payload.capture(), eq(Void.class))).thenReturn(null); + //when + vnfcManager.delete(VNF_ID, affectedVnfc); + //verify + aaiRestApiProvider.delete(logger, NETWORK, "/vnfcs/vnfc/myVnfId_vnfcId"); + } + + /** + * test inheritence + */ + @Test + public void testInheritence() { + assertEquals(logger, vnfcManager.getLogger()); + } + + +} diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestVserverManager.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestVserverManager.java new file mode 100644 index 00000000..bb5d1d3d --- /dev/null +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/direct/notification/TestVserverManager.java @@ -0,0 +1,253 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.nokia.cbam.lcm.v32.model.AffectedVirtualStorage; +import com.nokia.cbam.lcm.v32.model.AffectedVnfc; +import com.nokia.cbam.lcm.v32.model.ResourceHandle; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.onap.aai.domain.yang.v11.*; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.TestBase; + +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.AAIRestApiProvider.AAIService.CLOUD; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.AbstractManager.buildRelationshipData; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.direct.notification.TestGenericVnfManager.assertRelation; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getCloudOwner; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.getRegionName; +import static org.springframework.test.util.ReflectionTestUtils.setField; + +public class TestVserverManager extends TestBase { + private ObjectFactory OBJECT_FACTORY = new ObjectFactory(); + private ArgumentCaptor<Vserver> payload = ArgumentCaptor.forClass(Vserver.class); + + @Mock + private AAIRestApiProvider aaiRestApiProvider; + private VserverManager vserverManager; + + @Before + public void init() { + vserverManager = new VserverManager(aaiRestApiProvider, cbamRestApiProvider, driverProperties); + setField(VserverManager.class, "logger", logger); + } + + /** + * test update + */ + @Test + public void testUpdate() throws Exception { + AffectedVnfc affectedVnfc = new AffectedVnfc(); + affectedVnfc.setComputeResource(new ResourceHandle()); + affectedVnfc.getComputeResource().setResourceId("serverProviderId"); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("name", "serverName"); + additionalData.addProperty("tenantId", "myTenantId"); + JsonArray links = new JsonArray(); + links.add(new JsonObject()); + JsonObject nonRelSelfink = new JsonObject(); + nonRelSelfink.addProperty("rel", "self2"); + nonRelSelfink.addProperty("href", "url"); + links.add(nonRelSelfink); + + JsonObject link = new JsonObject(); + link.addProperty("rel", "self"); + link.addProperty("href", "url"); + links.add(link); + additionalData.add("links", links); + affectedVnfc.getComputeResource().setAdditionalData(additionalData); + affectedVnfc.setId("vnfcId"); + List<AffectedVirtualStorage> affectedStorages = new ArrayList<>(); + affectedStorages.add(new AffectedVirtualStorage()); + affectedStorages.get(0).setId("sId"); + affectedStorages.get(0).setResource(new ResourceHandle()); + affectedStorages.get(0).getResource().setResourceId("storageProviderId"); + affectedVnfc.setStorageResourceIds(new ArrayList<>()); + affectedVnfc.getStorageResourceIds().add("sId"); + + String url = "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId"; + + Vserver existingVserver = OBJECT_FACTORY.createVserver(); + existingVserver.setVolumes(new Volumes()); + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq(url), eq(Vserver.class))).thenReturn(existingVserver); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq(url), payload.capture(), eq(Void.class))).thenReturn(null); + //when + vserverManager.update(VIM_ID, VNF_ID, affectedVnfc, affectedStorages, true); + //verify + Vserver vserver = payload.getValue(); + assertEquals("serverProviderId", vserver.getVserverId()); + assertEquals("active", vserver.getProvStatus()); + assertEquals("serverName", vserver.getVserverName()); + assertEquals("url", vserver.getVserverSelflink()); + assertEquals(1, vserver.getVolumes().getVolume().size()); + assertEquals("storageProviderId", vserver.getVolumes().getVolume().get(0).getVolumeId()); + } + + /** + * test missing links + */ + @Test + public void testUpdateEmptyLinks() throws Exception { + AffectedVnfc affectedVnfc = new AffectedVnfc(); + affectedVnfc.setComputeResource(new ResourceHandle()); + affectedVnfc.getComputeResource().setResourceId("serverProviderId"); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("name", "serverName"); + additionalData.addProperty("tenantId", "myTenantId"); + JsonArray links = new JsonArray(); + additionalData.add("links", links); + affectedVnfc.getComputeResource().setAdditionalData(additionalData); + affectedVnfc.setId("vnfcId"); + List<AffectedVirtualStorage> affectedStorages = new ArrayList<>(); + affectedStorages.add(new AffectedVirtualStorage()); + affectedStorages.get(0).setId("sId"); + affectedStorages.get(0).setResource(new ResourceHandle()); + affectedStorages.get(0).getResource().setResourceId("storageProviderId"); + affectedVnfc.setStorageResourceIds(new ArrayList<>()); + affectedVnfc.getStorageResourceIds().add("sId"); + + String url = "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId"; + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq(url), eq(Vserver.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq(url), payload.capture(), eq(Void.class))).thenReturn(null); + //when + vserverManager.update(VIM_ID, VNF_ID, affectedVnfc, affectedStorages, true); + //verify + Vserver vserver = payload.getValue(); + assertEquals("serverProviderId", vserver.getVserverId()); + assertEquals("active", vserver.getProvStatus()); + assertEquals("serverName", vserver.getVserverName()); + assertEquals("unknown", vserver.getVserverSelflink()); + assertEquals(1, vserver.getVolumes().getVolume().size()); + assertEquals("storageProviderId", vserver.getVolumes().getVolume().get(0).getVolumeId()); + } + + /** + * test update when links is not present on vServer + */ + @Test + public void testUpdateWithNoLinks() throws Exception { + AffectedVnfc affectedVnfc = new AffectedVnfc(); + affectedVnfc.setComputeResource(new ResourceHandle()); + affectedVnfc.getComputeResource().setResourceId("serverProviderId"); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("name", "serverName"); + additionalData.addProperty("tenantId", "myTenantId"); + affectedVnfc.getComputeResource().setAdditionalData(additionalData); + affectedVnfc.setId("vnfcId"); + List<AffectedVirtualStorage> affectedStorages = new ArrayList<>(); + affectedStorages.add(new AffectedVirtualStorage()); + affectedStorages.get(0).setId("sId"); + affectedStorages.get(0).setResource(new ResourceHandle()); + affectedStorages.get(0).getResource().setResourceId("storageProviderId"); + affectedVnfc.setStorageResourceIds(new ArrayList<>()); + affectedVnfc.getStorageResourceIds().add("sId"); + + String url = "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId"; + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq(url), eq(Vserver.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq(url), payload.capture(), eq(Void.class))).thenReturn(null); + //when + vserverManager.update(VIM_ID, VNF_ID, affectedVnfc, affectedStorages, true); + //verify + Vserver vserver = payload.getValue(); + assertEquals("serverProviderId", vserver.getVserverId()); + assertEquals("active", vserver.getProvStatus()); + assertEquals("serverName", vserver.getVserverName()); + assertEquals("unknown", vserver.getVserverSelflink()); + assertEquals(1, vserver.getVolumes().getVolume().size()); + assertEquals("storageProviderId", vserver.getVolumes().getVolume().get(0).getVolumeId()); + } + + /** + * test update when removing volumes + */ + @Test + public void testUpdateWithRemovingVolumes() throws Exception { + AffectedVnfc affectedVnfc = new AffectedVnfc(); + affectedVnfc.setComputeResource(new ResourceHandle()); + affectedVnfc.getComputeResource().setResourceId("serverProviderId"); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("name", "serverName"); + additionalData.addProperty("tenantId", "myTenantId"); + affectedVnfc.getComputeResource().setAdditionalData(additionalData); + affectedVnfc.setId("vnfcId"); + List<AffectedVirtualStorage> affectedStorages = new ArrayList<>(); + String url = "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId"; + when(aaiRestApiProvider.get(eq(logger), eq(CLOUD), eq(url), eq(Vserver.class))).thenThrow(new NoSuchElementException()); + when(aaiRestApiProvider.put(eq(logger), eq(CLOUD), eq(url), payload.capture(), eq(Void.class))).thenReturn(null); + //when + vserverManager.update(VIM_ID, VNF_ID, affectedVnfc, affectedStorages, true); + //verify + Vserver vserver = payload.getValue(); + assertEquals("serverProviderId", vserver.getVserverId()); + assertEquals("active", vserver.getProvStatus()); + assertEquals("serverName", vserver.getVserverName()); + assertEquals("unknown", vserver.getVserverSelflink()); + assertEquals(0, vserver.getVolumes().getVolume().size()); + } + + /** + * test delete + */ + @Test + public void testDelete() throws Exception { + AffectedVnfc affectedVnfc = new AffectedVnfc(); + affectedVnfc.setComputeResource(new ResourceHandle()); + affectedVnfc.getComputeResource().setResourceId("serverProviderId"); + JsonObject additionalData = new JsonObject(); + additionalData.addProperty("name", "serverName"); + additionalData.addProperty("tenantId", "myTenantId"); + affectedVnfc.getComputeResource().setAdditionalData(additionalData); + affectedVnfc.setId("vnfcId"); + //when + vserverManager.delete(VIM_ID, affectedVnfc); + //verify + String url = "/cloud-regions/cloud-region/myCloudOwnerId/myRegionName/tenants/tenant/myTenantId/vservers/vserver/serverProviderId"; + aaiRestApiProvider.delete(logger, CLOUD, url); + } + + @Test + public void testLinks() { + Relationship relationship = VserverManager.linkTo(VIM_ID, "myTenantPrivderId", "serverProviderId"); + RelationshipList relationships = new RelationshipList(); + relationships.getRelationship().add(relationship); + assertRelation(relationships, "vserver", + buildRelationshipData("cloud-region.cloud-owner", getCloudOwner(VIM_ID)), + buildRelationshipData("cloud-region.cloud-region-id", getRegionName(VIM_ID)), + buildRelationshipData("tenant.tenant-id", "myTenantPrivderId"), + buildRelationshipData("vserver.vserver-id", "serverProviderId")); + } + + /** + * test inheritence + */ + @Test + public void testInheritence() { + assertEquals(logger, vserverManager.getLogger()); + } + + +} 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..2cd0aa1e 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,14 @@ 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"); + verify(logger).warn("The {} type is not converted", "tosca.nodes.nfv.Unknown"); } /** 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/restapi/TestLcmApi.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestLcmApi.java index 4d10fd52..6b04d69d 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestLcmApi.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/restapi/TestLcmApi.java @@ -28,6 +28,7 @@ import org.onap.vnfmdriver.model.VnfInstantiateRequest; import org.onap.vnfmdriver.model.VnfScaleRequest; import org.onap.vnfmdriver.model.VnfTerminateRequest; +import static java.util.Optional.empty; import static org.apache.http.HttpStatus.SC_CREATED; import static org.mockito.Mockito.verify; import static org.springframework.test.util.ReflectionTestUtils.setField; @@ -70,7 +71,7 @@ public class TestLcmApi extends TestBase { //when lcmApi.healVnf(req, VNFM_ID, VNF_ID, httpResponse); //verify - verify(lifecycleManager).healVnf(VNFM_ID, VNF_ID, req, httpResponse); + verify(lifecycleManager).healVnf(VNFM_ID, VNF_ID, req, empty(), httpResponse); verify(logger).info("REST: Heal VNF"); } diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/spring/TestConditions.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/spring/TestConditions.java index f716cad6..7a525b37 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/spring/TestConditions.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/spring/TestConditions.java @@ -21,6 +21,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.TestUtil; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; @@ -63,4 +64,12 @@ public class TestConditions { TestCase.assertTrue(new Conditions.UseForDirect().matches(conditionContext, null)); } + /** + * use class in a static way + */ + @Test + public void useStaticway(){ + TestUtil.coveragePrivateConstructorForClassesWithStaticMethodsOnly(Conditions.class); + } + } diff --git a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestCbamTokenProvider.java b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestCbamTokenProvider.java index 44ba0e52..4b35f2ff 100644 --- a/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestCbamTokenProvider.java +++ b/nokiav2/driver/src/test/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/TestCbamTokenProvider.java @@ -45,6 +45,10 @@ import java.security.KeyStoreException; import java.util.ArrayList; import java.util.Base64; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import static junit.framework.TestCase.*; import static org.mockito.Matchers.eq; @@ -54,10 +58,10 @@ import static org.springframework.test.util.ReflectionTestUtils.setField; class HttpTestServer { Server _server; - List<String> requests = new ArrayList<>(); - List<Integer> codes = new ArrayList<>(); - List<String> respones = new ArrayList<>(); - + volatile List<String> requests = new ArrayList<>(); + volatile List<Integer> codes = new ArrayList<>(); + volatile List<String> respones = new ArrayList<>(); + ExecutorService executorService = Executors.newCachedThreadPool(); public void start() throws Exception { configureServer(); startServer(); @@ -67,6 +71,18 @@ class HttpTestServer { requests.clear(); codes.clear(); _server.start(); + Future<?> serverStarted = executorService.submit(() -> { + while(true){ + try { + Thread.sleep(10); + if(_server.isStarted()){ + return; + } + } catch (InterruptedException e) { + } + } + }); + serverStarted.get(30, TimeUnit.SECONDS); } protected void configureServer() throws Exception { @@ -119,6 +135,8 @@ public class TestCbamTokenProvider extends TestBase { testServer.start(); URI uri = testServer._server.getURI(); setField(cbamTokenProvider, "cbamKeyCloakBaseUrl", uri.toString()); + + } private void addGoodTokenResponse() { 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..c6e76ef6 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 @@ -49,9 +49,11 @@ import java.util.*; import static java.lang.Boolean.parseBoolean; import static java.nio.file.Files.readAllBytes; +import static java.util.Optional.empty; 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 +253,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 +265,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 +275,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 +299,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 +311,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 +759,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 +1165,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()); + } /** @@ -1309,7 +1318,7 @@ public class TestLifecycleManager extends TestBase { String instantiationParams = "{ \"vims\" : [ { \"id\" : \"" + VIM_ID + "\" } ] }"; when(operationExecutionApi.operationExecutionsOperationExecutionIdOperationParamsGet(instantiationOperationExecution.getId(), NOKIA_LCM_API_VERSION)).thenReturn(new JsonParser().parse(instantiationParams)); //when - JobInfo job = lifecycleManager.healVnf(VNFM_ID, VNF_ID, healRequest, restResponse); + JobInfo job = lifecycleManager.healVnf(VNFM_ID, VNF_ID, healRequest, empty(), restResponse); //verify waitForJobToFinishInJobManager(finished); assertEquals(1, actualHealRequest.getAllValues().size()); @@ -1322,6 +1331,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()); } /** @@ -1357,7 +1367,7 @@ public class TestLifecycleManager extends TestBase { } }); //when - JobInfo job = lifecycleManager.healVnf(VNFM_ID, VNF_ID, healRequest, restResponse); + JobInfo job = lifecycleManager.healVnf(VNFM_ID, VNF_ID, healRequest, empty(), restResponse); //verify waitForJobToFinishInJobManager(finished); assertEquals(100, expectedExceptions.size()); @@ -1380,7 +1390,7 @@ public class TestLifecycleManager extends TestBase { healRequest.setAffectedvm(affectedVm); when(vnfApi.vnfsVnfInstanceIdGet(VNF_ID, NOKIA_LCM_API_VERSION)).thenThrow(expectedException); //when - JobInfo job = lifecycleManager.healVnf(VNFM_ID, VNF_ID, healRequest, restResponse); + JobInfo job = lifecycleManager.healVnf(VNFM_ID, VNF_ID, healRequest, empty(), restResponse); //verify waitForJobToFinishInJobManager(finished); verify(logger).error("Unable to heal VNF with myVnfId identifier", expectedException); 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/application-direct.properties b/nokiav2/driver/src/test/resources/application-direct.properties new file mode 100644 index 00000000..f933db94 --- /dev/null +++ b/nokiav2/driver/src/test/resources/application-direct.properties @@ -0,0 +1,73 @@ +############################################################################### +# Copyright 2016, Nokia Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +############################################################################### +server.error.whitelabel.enabled=false +############################################################################### +# Beginning of mandatory properties # +############################################################################### +# The TCP port of the server +server.port=8089 +# the base path of the server +server.context-path= +# the IP address to which the server binds to +server.address=127.0.0.1 +# the IP address of the server reported to the micro service bus +driverMsbExternalIp=10.41.63.151 +# the IP address of the server reported to the VNFM +driverVnfmExternalIp=10.41.63.151 +# the IP address of the message bus +messageBusIp=msb.api.simpledemo.onap.org +# the TCP port of the message bus +messageBusPort=80 +# the URL of the CBAM catalog service +cbamCatalogUrl=https://10.41.63.149:443/api/catalog/adapter +# the URL of the CBAM LCN service +cbamLcnUrl=https://10.41.63.149:443/vnfm/lcn/v3 +# the URL of the CBAM authentication service +cbamKeyCloakBaseUrl=https://10.41.63.149:443/auth +# skip hostname verification during SSL on CBAM LCN, LCM and authorization interface +skipHostnameVerification=true +# skip certificate verification during SSL on CBAM LCN, LCM and authorization interface +skipCertificateVerification=true +# the collection of trusted certificates for SSL on CBAM LCN, LCM and authorization interface +# in PEM format encoded in BASE64 to a single line +trustedCertificates= +# the username to be used for requesting a token on CBAM authorization interface +cbamUsername=onap +# the password to be used for requesting a token on CBAM authorization interface +cbamPassword=Admin@123 +# the identifier of the VNFM in A&AI core system registry +vnfmId=7c267318-2a6a-4d47-b039-a7cce5fea38b +aaiUsername=AAI +aaiPassword=AAI +sdcUsername=SDC +sdcPassword=SDC + +############################################################################### +# End of mandatory properties for driver # +############################################################################### +ipMap=10.0.14.1->msb.api.simpledemo.onap.org,172.17.0.15->msb.api.simpledemo.onap.org,10.0.1.1->aai.api.simpledemo.onap.org +vnfmInfoCacheEvictionInMs=600000 + +## for logging begin ## +com.fasterxml.jackson.core=jackson-databind +#logging.file=${catalina.base}/logs/vfcadaptor.log +logging.level.org.springframework=INFO +logging.level.org.hibernate=OFF +logging.level.org.springframework.web=DEBUG +## for logging end ## + +spring.http.multipart.max-file-size=50000KB +spring.http.multipart.max-request-size=50000KB 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..985ab276 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,7 +18,10 @@ topology_template: - virtual_compute: myCompute - virtual_storage: myStorage1 - virtual_storage: myStorage2 + - unhandled_type: unknown + unknownType: + type: tosca.nodes.nfv.Unknown myCompute: type: tosca.nodes.nfv.VirtualCompute @@ -64,6 +67,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 +98,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 |