2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2019 Nordix Foundation.
 
   4  * ================================================================================
 
   5  * Licensed under the Apache License, Version 2.0 (the "License");
 
   6  * you may not use this file except in compliance with the License.
 
   7  * You may obtain a copy of the License at
 
   9  *      http://www.apache.org/licenses/LICENSE-2.0
 
  11  * Unless required by applicable law or agreed to in writing, software
 
  12  * distributed under the License is distributed on an "AS IS" BASIS,
 
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  * See the License for the specific language governing permissions and
 
  15  * limitations under the License.
 
  17  * SPDX-License-Identifier: Apache-2.0
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.so.adapters.vnfmadapter.lifecycle;
 
  23 import com.google.common.base.Optional;
 
  25 import org.onap.aai.domain.yang.EsrVnfm;
 
  26 import org.onap.aai.domain.yang.GenericVnf;
 
  27 import org.onap.aai.domain.yang.Relationship;
 
  28 import org.onap.so.adapters.vnfmadapter.extclients.SdcPackageProvider;
 
  29 import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiHelper;
 
  30 import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider;
 
  31 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource;
 
  32 import org.onap.so.adapters.vnfmadapter.extclients.aai.OamIpAddressSource.OamIpAddressType;
 
  33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmHelper;
 
  34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider;
 
  35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
 
  36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest;
 
  37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest;
 
  38 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest;
 
  39 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest.TerminationTypeEnum;
 
  40 import org.onap.so.adapters.vnfmadapter.jobmanagement.JobManager;
 
  41 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfNotFoundException;
 
  42 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmNotFoundException;
 
  43 import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmRequestFailureException;
 
  44 import org.onap.vnfmadapter.v1.model.CreateVnfRequest;
 
  45 import org.onap.vnfmadapter.v1.model.CreateVnfResponse;
 
  46 import org.onap.vnfmadapter.v1.model.DeleteVnfResponse;
 
  47 import org.slf4j.Logger;
 
  48 import org.slf4j.LoggerFactory;
 
  49 import org.springframework.beans.factory.annotation.Autowired;
 
  50 import org.springframework.stereotype.Component;
 
  53  * Manages lifecycle operations towards the VNFMs.
 
  56 public class LifecycleManager {
 
  57     private static final Logger logger = LoggerFactory.getLogger(LifecycleManager.class);
 
  58     private final AaiServiceProvider aaiServiceProvider;
 
  59     private final VnfmServiceProvider vnfmServiceProvider;
 
  60     private final AaiHelper aaiHelper;
 
  61     private final VnfmHelper vnfmHelper;
 
  62     private final JobManager jobManager;
 
  63     private final SdcPackageProvider packageProvider;
 
  66     LifecycleManager(final AaiServiceProvider aaiServiceProvider, final AaiHelper aaiHelper,
 
  67             final VnfmHelper vnfmHelper, final VnfmServiceProvider vnfmServiceProvider, final JobManager jobManager,
 
  68             final SdcPackageProvider packageProvider) {
 
  69         this.aaiServiceProvider = aaiServiceProvider;
 
  70         this.vnfmServiceProvider = vnfmServiceProvider;
 
  71         this.aaiHelper = aaiHelper;
 
  72         this.vnfmHelper = vnfmHelper;
 
  73         this.jobManager = jobManager;
 
  74         this.packageProvider = packageProvider;
 
  78      * Create a VNF on a VNFM.
 
  80      * @param vnfIdInAai the ID of the VNF in AAI
 
  81      * @param request the create request
 
  82      * @return the response to the request
 
  84     public CreateVnfResponse createVnf(final String vnfIdInAai, final CreateVnfRequest request) {
 
  85         GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
 
  86         EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
 
  87         checkIfVnfAlreadyExistsInVnfm(vnfm, genericVnf);
 
  90             vnfm = aaiHelper.selectVnfm(genericVnf);
 
  91             aaiServiceProvider.invokePutGenericVnfToVnfmRelationship(genericVnf, vnfm.getVnfmId());
 
  93         final InlineResponse201 vnfmResponse = sendCreateRequestToVnfm(request, genericVnf, vnfIdInAai, vnfm);
 
  95         logger.info("Create response: {}", vnfmResponse);
 
  97         genericVnf.setSelflink(getSelfLink(vnfmResponse, vnfm));
 
  99         GenericVnf genericVnfPatch = new GenericVnf();
 
 100         genericVnfPatch.setVnfId(genericVnf.getVnfId());
 
 101         genericVnfPatch.setSelflink(genericVnf.getSelflink());
 
 102         aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
 
 104         final String vnfIdInVnfm = vnfmResponse.getId();
 
 106         final OamIpAddressSource oamIpAddressSource = extractOamIpAddressSource(request);
 
 107         aaiHelper.setOamIpAddressSource(vnfIdInVnfm, oamIpAddressSource);
 
 109         createNotificationSubscription(vnfm, vnfIdInVnfm);
 
 110         final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request);
 
 112         final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false);
 
 113         final CreateVnfResponse response = new CreateVnfResponse();
 
 114         response.setJobId(jobId);
 
 118     private String getSelfLink(final InlineResponse201 vnfmResponse, final EsrVnfm vnfm) {
 
 119         if (vnfmResponse.getLinks() != null && vnfmResponse.getLinks().getSelf() != null
 
 120                 && vnfmResponse.getLinks().getSelf().getHref() != null) {
 
 121             return vnfmResponse.getLinks().getSelf().getHref();
 
 123         return vnfm.getEsrSystemInfoList().getEsrSystemInfo().iterator().next().getServiceUrl() + "/vnf_instances/"
 
 124                 + vnfmResponse.getId();
 
 127     private OamIpAddressSource extractOamIpAddressSource(final CreateVnfRequest request) {
 
 128         final Map<String, String> additionalParams = request.getAdditionalParams();
 
 130             final String sourceType = additionalParams.remove("oamIpAddressSourceType");
 
 131             final String sourceValue = additionalParams.remove("oamIpAddressSourceValue");
 
 132             final OamIpAddressType oamIpAddressType = OamIpAddressType.valueOf(sourceType.toUpperCase());
 
 133             return new OamIpAddressSource(oamIpAddressType, sourceValue);
 
 134         } catch (final NullPointerException | IllegalArgumentException exception) {
 
 135             logger.debug("Additional Params not set for OAM IP address source", exception);
 
 140     private void checkIfVnfAlreadyExistsInVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
 
 141         if (genericVnf.getSelflink() != null && !genericVnf.getSelflink().isEmpty() && vnfm != null) {
 
 142             Optional<InlineResponse201> response = Optional.absent();
 
 144                 response = vnfmServiceProvider.getVnf(vnfm, genericVnf.getSelflink());
 
 145             } catch (final Exception exception) {
 
 146                 logger.debug("Ignoring invalid self link in generic vnf", exception);
 
 148             if (response.isPresent()) {
 
 149                 throw new IllegalArgumentException("VNF " + genericVnf.getVnfId()
 
 150                         + " is already defined on the VNFM, self link: " + genericVnf.getSelflink());
 
 155     private InlineResponse201 sendCreateRequestToVnfm(final CreateVnfRequest aaiRequest, final GenericVnf genericVnf,
 
 156             final String vnfIdInAai, final EsrVnfm vnfm) {
 
 157         logger.debug("Sending a create request to SVNFM " + aaiRequest);
 
 158         final org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest vnfmRequest =
 
 159                 new org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest();
 
 161         final String vnfdId = packageProvider.getVnfdId(genericVnf.getModelVersionId());
 
 162         vnfmRequest.setVnfdId(vnfdId);
 
 163         vnfmRequest.setVnfInstanceName(aaiRequest.getName().replaceAll(" ", "_"));
 
 164         vnfmRequest.setVnfInstanceDescription(vnfIdInAai);
 
 166         final Optional<InlineResponse201> optionalResponse = vnfmServiceProvider.createVnf(vnfm, vnfmRequest);
 
 169             return optionalResponse.get();
 
 170         } catch (final Exception exception) {
 
 171             final String errorMessage = "Unable to return response from VNFM";
 
 172             logger.error(errorMessage, exception);
 
 173             throw new VnfmRequestFailureException(errorMessage, exception);
 
 177     private void createNotificationSubscription(final EsrVnfm vnfm, final String vnfId) {
 
 179             final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId);
 
 180             vnfmServiceProvider.subscribeForNotifications(vnfm, subscriptionRequest);
 
 181         } catch (final Exception exception) {
 
 182             logger.warn("Subscription for notifications to VNFM: " + vnfm.getVnfmId() + " for VNF " + vnfId
 
 183                     + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF",
 
 188     private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf,
 
 189             final CreateVnfRequest createVnfRequest) {
 
 191         final InstantiateVnfRequest instantiateVnfRequest =
 
 192                 vnfmHelper.createInstantiateRequest(createVnfRequest.getTenant(), createVnfRequest,
 
 193                         packageProvider.getFlavourId(genericVnf.getModelVersionId()));
 
 194         final String jobId = vnfmServiceProvider.instantiateVnf(vnfm, genericVnf.getSelflink(), instantiateVnfRequest);
 
 196         logger.info("Instantiate VNF request successfully sent to " + genericVnf.getSelflink());
 
 201      * Delete a VNF on a VNFM.
 
 203      * @param vnfIdInAai the ID of the VNF in AAI
 
 204      * @return the response to the request
 
 206     public DeleteVnfResponse deleteVnf(final String vnfIdInAai) {
 
 207         final GenericVnf genericVnf = getGenericVnfFromAai(vnfIdInAai);
 
 208         final EsrVnfm vnfm = getAssignedVnfm(genericVnf);
 
 210         final String operationId = sendTerminateRequestToVnfm(vnfm, genericVnf);
 
 212         if (operationId.equals(JobManager.ALREADY_COMPLETED_OPERATION_ID)) {
 
 213             sendDeleteRequestToVnfm(genericVnf);
 
 215         final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, true);
 
 217         return new DeleteVnfResponse().jobId(jobId);
 
 220     private String sendTerminateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf) {
 
 221         final TerminateVnfRequest terminateVnfRequest = new TerminateVnfRequest();
 
 222         terminateVnfRequest.setTerminationType(TerminationTypeEnum.FORCEFUL);
 
 223         return vnfmServiceProvider.terminateVnf(vnfm, genericVnf.getSelflink(), terminateVnfRequest);
 
 226     private GenericVnf getGenericVnfFromAai(final String vnfIdInAai) {
 
 227         final GenericVnf genericVnf = aaiServiceProvider.invokeGetGenericVnf(vnfIdInAai);
 
 228         if (genericVnf == null) {
 
 229             throw new VnfNotFoundException("VNF not found in AAI: " + vnfIdInAai);
 
 231         logger.debug("Retrieved generic VNF from AAI: " + genericVnf);
 
 235     private EsrVnfm getAssignedVnfm(final GenericVnf genericVnf) {
 
 236         final EsrVnfm vnfm = aaiHelper.getAssignedVnfm(genericVnf);
 
 238             throw new VnfmNotFoundException("No VNFM found in AAI for VNF " + genericVnf.getVnfId());
 
 243     private void sendDeleteRequestToVnfm(final GenericVnf genericVnf) {
 
 245         vnfmServiceProvider.deleteVnf(aaiHelper.getAssignedVnfm(genericVnf), genericVnf.getSelflink());
 
 247         final GenericVnf genericVnfPatch = new GenericVnf();
 
 248         genericVnfPatch.setVnfId(genericVnf.getVnfId());
 
 249         genericVnfPatch.setOrchestrationStatus("Assigned");
 
 250         genericVnfPatch.setSelflink("");
 
 251         aaiServiceProvider.invokePatchGenericVnf(genericVnfPatch);
 
 253         for (final Relationship relationship : genericVnf.getRelationshipList().getRelationship()) {
 
 254             if (relationship.getRelatedTo().equals("vserver")) {
 
 255                 aaiServiceProvider.invokeDeleteVserver(
 
 256                         aaiHelper.getRelationshipData(relationship, "cloud-region.cloud-owner"),
 
 257                         aaiHelper.getRelationshipData(relationship, "cloud-region.cloud-region-id"),
 
 258                         aaiHelper.getRelationshipData(relationship, "tenant.tenant-id"),
 
 259                         aaiHelper.getRelationshipData(relationship, "vserver.vserver-id"));