diff options
author | Denes Nemeth <denes.nemeth@nokia.com> | 2018-03-12 13:35:11 +0100 |
---|---|---|
committer | Denes Nemeth <denes.nemeth@nokia.com> | 2018-03-12 13:41:20 +0100 |
commit | 626ebae46807adeab6d0b9d5568515f457c7ece3 (patch) | |
tree | 143819aec0ae5597f60eff13499ae69d698f6cbc /nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm | |
parent | f5608b8ab40816febb064a61e80b52b572eda768 (diff) |
add direct information source
Change-Id: I3def669ecc9ea0a5df2c95f65be3d4ffc7fdf3b8
Signed-off-by: Denes Nemeth <denes.nemeth@nokia.com>
Issue-ID: VFC-728
Diffstat (limited to 'nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm')
13 files changed, 1343 insertions, 0 deletions
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; |