2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2020 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=========================================================
 
  20 package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
 
  22 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.INSTANTIATE_NS_REQUEST_PARAM_NAME;
 
  23 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME;
 
  24 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.NS_INSTANCE_ID_PARAM_NAME;
 
  25 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.VNF_CREATE_INSTANTIATE_REQUESTS;
 
  26 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
 
  27 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
 
  28 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED;
 
  29 import java.util.ArrayList;
 
  30 import java.util.HashMap;
 
  31 import java.util.List;
 
  33 import java.util.Optional;
 
  34 import org.apache.commons.lang.StringUtils;
 
  35 import org.camunda.bpm.engine.delegate.DelegateExecution;
 
  36 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant;
 
  37 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
 
  38 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
 
  39 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException;
 
  40 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider;
 
  41 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
 
  42 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.VirtualNetworkFunction;
 
  43 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
 
  44 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
 
  45 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
 
  46 import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
 
  47 import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
 
  48 import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf;
 
  49 import org.slf4j.Logger;
 
  50 import org.slf4j.LoggerFactory;
 
  51 import org.springframework.beans.factory.annotation.Autowired;
 
  52 import org.springframework.stereotype.Component;
 
  55  * @author Waqas Ikram (waqas.ikram@est.tech)
 
  56  * @author Andrew Lamb (andrew.a.lamb@est.tech)
 
  60 public class InstantiateNsTask extends AbstractNetworkServiceTask {
 
  62     private static final String IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME = "isNsInstantiationSuccessful";
 
  63     private static final String VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME = "vnfdIdToVnfPkgIdMapping";
 
  64     private static final Logger logger = LoggerFactory.getLogger(InstantiateNsTask.class);
 
  65     private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider;
 
  68     public InstantiateNsTask(final DatabaseServiceProvider databaseServiceProvider,
 
  69             final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) {
 
  70         super(databaseServiceProvider);
 
  71         this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider;
 
  75     public void setJobStatusToStarted(final DelegateExecution execution) {
 
  76         setJobStatus(execution, STARTED, "Instantiate NS workflow process started");
 
  79     public void setJobStatusToFinished(final DelegateExecution execution) {
 
  80         setJobStatus(execution, FINISHED, "Instantiate NS workflow process finished");
 
  83     public void updateNsInstanceStatusToInstantiating(final DelegateExecution execution) {
 
  84         logger.info("Executing updateNsInstanceStatusToInstantiating");
 
  85         setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.INSTANTIATING);
 
  86         updateNsInstanceStatus(execution, State.INSTANTIATING);
 
  88         logger.info("Finished executing updateNsInstanceStatusToInstantiating  ...");
 
  92     public void checkIfVnfInstantiationWasSuccessful(final DelegateExecution execution) {
 
  93         logger.info("Executing checkIfVnfInstantiationWasSuccessful");
 
  95         @SuppressWarnings("unchecked")
 
  96         final List<CreateInstantiateRequest> requests =
 
  97                 (List<CreateInstantiateRequest>) execution.getVariable(VNF_CREATE_INSTANTIATE_REQUESTS);
 
  99         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
 
 100         final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
 
 102         if (nfInstances == null || nfInstances.isEmpty()) {
 
 103             final String message = "Found empty nf instances";
 
 104             abortOperation(execution, message);
 
 107         if (requests.size() != nfInstances.size()) {
 
 108             final String message = "Missing nf Instance. Request triggered: " + requests.size()
 
 109                     + " Nf Instace reqeust found in database " + nfInstances.size();
 
 110             abortOperation(execution, message);
 
 113         execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, true);
 
 115         nfInstances.stream().forEach(instance -> {
 
 116             if (!State.INSTANTIATED.equals(instance.getStatus())) {
 
 117                 logger.error("VNF : {} {} instantiation failed", instance.getNfInstId(), instance.getName());
 
 118                 execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, false);
 
 122         logger.info("Finished executing checkIfVnfInstantiationWasSuccessful  ...");
 
 125     public void updateNsInstanceStatusToInstantiated(final DelegateExecution execution) {
 
 126         logger.info("Executing updateNsInstanceStatusToInstantiated");
 
 127         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
 
 128         setJobStatus(execution, FINISHED, "Successfully " + State.INSTANTIATED + " NS: " + nsInstId);
 
 130         updateNsInstanceStatus(execution, State.INSTANTIATED);
 
 131         logger.info("Finished executing updateNsInstanceStatusToInstantiated  ...");
 
 134     public void getAndParseNsdFromEtsiCatalog(final DelegateExecution execution) {
 
 135         logger.info("Executing getAndParseNsdFromEtsiCatalog");
 
 136         setJobStatus(execution, IN_PROGRESS, "Retrieving and parsing NSD from ETSI Catalog Manager");
 
 137         final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution);
 
 138         final String nsPackageId = nfvoNsInst.getNsPackageId();
 
 141             final Optional<NetworkServiceDescriptor> optional =
 
 142                     etsiCatalogPackageManagementServiceProvider.getNetworkServiceDescriptor(nsPackageId);
 
 144             if (optional.isEmpty()) {
 
 145                 final String message = "Unable to parse NSD " + nsPackageId;
 
 146                 logger.error(message);
 
 147                 abortOperation(execution, message);
 
 150             final NetworkServiceDescriptor networkServiceDescriptor = optional.get();
 
 151             logger.info("Found {}", networkServiceDescriptor);
 
 152             execution.setVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME, networkServiceDescriptor);
 
 154         } catch (final EtsiCatalogManagerRequestFailureException failureException) {
 
 155             final String message =
 
 156                     "Unexpected exception occured while getting nsd content using nsPackageId: " + nsPackageId;
 
 157             logger.error(message, failureException);
 
 159             abortOperation(execution, message);
 
 162         logger.info("Finished executing getAndParseNsdFromEtsiCatalog  ...");
 
 166     public void prepareCreateInstantiateRequests(final DelegateExecution execution) {
 
 167         logger.info("Executing prepareCreateInstantiateRequests ...");
 
 168         setJobStatus(execution, IN_PROGRESS, "Preparing VNF CreateInstantiate requests");
 
 169         final NetworkServiceDescriptor networkServiceDescriptor =
 
 170                 (NetworkServiceDescriptor) execution.getVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME);
 
 171         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
 
 172         final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
 
 174         final InstantiateNsRequest instantiateNsRequest =
 
 175                 (InstantiateNsRequest) execution.getVariable(INSTANTIATE_NS_REQUEST_PARAM_NAME);
 
 177         final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList =
 
 178                 instantiateNsRequest.getAdditionalParamsForVnf();
 
 180         @SuppressWarnings("unchecked")
 
 181         final Map<String, String> vnfdIdToVnfPkgIdMapping =
 
 182                 (Map<String, String>) execution.getVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME);
 
 184         final List<CreateInstantiateRequest> requests = new ArrayList<>();
 
 186         for (final VirtualNetworkFunction vnf : networkServiceDescriptor.getVnfs()) {
 
 187             final List<String> vnfmInfoList = vnf.getVnfmInfoList();
 
 189             final String vnfdId = vnf.getVnfdId();
 
 190             final String vnfPkgId = vnfdIdToVnfPkgIdMapping.get(vnfdId);
 
 191             if (vnfdId == null || vnfmInfoList.isEmpty() || vnfPkgId == null) {
 
 192                 final String message = "Unable to find VnfdId/vnfmInfo/VnfPkgId for vnf: " + vnf;
 
 193                 abortOperation(execution, message);
 
 196             final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfOptional =
 
 197                     getAdditionalParamsForVnf(vnfdId, additionalParamsForVnfList);
 
 199             if (additionalParamsForVnfOptional.isEmpty()) {
 
 200                 final String message = "Unable to find AdditionalParamsForVnf for " + vnfdId
 
 201                         + " in instantiateNsRequest : " + instantiateNsRequest;
 
 202                 abortOperation(execution, message);
 
 205             final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf =
 
 206                     additionalParamsForVnfOptional.get();
 
 208             @SuppressWarnings("unchecked")
 
 209             final Map<String, String> additionalParams =
 
 210                     (Map<String, String>) additionalParamsForVnf.getAdditionalParams();
 
 212             final Optional<Tenant> optional = getTenant(additionalParams);
 
 213             if (optional.isEmpty()) {
 
 214                 final String message = "Unable to find Tenant information for " + vnfdId + " in instantiateNsRequest : "
 
 215                         + instantiateNsRequest;
 
 216                 abortOperation(execution, message);
 
 219             final String vnfInstanceName = additionalParamsForVnf.getVnfInstanceName();
 
 220             final String vnfName = StringUtils.isNotBlank(vnfInstanceName) ? vnfInstanceName
 
 221                     : nfvoNsInst.getName() + "." + vnf.getVnfName();
 
 223             final CreateInstantiateRequest createInstantiateRequest =
 
 224                     new CreateInstantiateRequest().nsInstId(nsInstId).vnfdId(vnfdId).vnfName(vnfName).vnfPkgId(vnfPkgId)
 
 225                             .nfType(vnfmInfoList.get(0)).tenant(optional.get()).additionalParams(additionalParams);
 
 227             logger.info("Adding request to list: {}", createInstantiateRequest);
 
 228             requests.add(createInstantiateRequest);
 
 231         execution.setVariable(VNF_CREATE_INSTANTIATE_REQUESTS, requests);
 
 233         logger.info("Finished executing prepareCreateInstantiateRequests  ...");
 
 236     public void getVnfPkgIdForEachVnfdId(final DelegateExecution execution) {
 
 237         logger.info("Executing getVnfPkgIdForEachVnfdId ...");
 
 239         setJobStatus(execution, IN_PROGRESS, "Getting VnfPkgId for each VnfdId");
 
 241         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
 
 242         final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
 
 244         final String nsPackageId = nfvoNsInst.getNsPackageId();
 
 245         final NsdInfo nsdInfo = getNsdInfo(execution, nsPackageId);
 
 247         final Map<String, String> vnfdIdToVnfPkgIdMapping = new HashMap<>();
 
 249             for (final String vnfPkgId : nsdInfo.getVnfPkgIds()) {
 
 250                 final Optional<VnfPkgInfo> optional =
 
 251                         etsiCatalogPackageManagementServiceProvider.getVnfPkgInfo(vnfPkgId);
 
 253                 if (optional.isEmpty()) {
 
 254                     final String message = "Unable to find VNF package using NS vnfPkgId: " + vnfPkgId;
 
 255                     logger.error(message);
 
 256                     abortOperation(execution, message);
 
 258                 final VnfPkgInfo vnfPkgInfo = optional.get();
 
 259                 vnfdIdToVnfPkgIdMapping.put(vnfPkgInfo.getVnfdId(), vnfPkgId);
 
 262             logger.info("vnfdIdToVnfPkgIdMapping: {}", vnfdIdToVnfPkgIdMapping);
 
 263             execution.setVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME, vnfdIdToVnfPkgIdMapping);
 
 265         } catch (final EtsiCatalogManagerRequestFailureException failureException) {
 
 266             final String message =
 
 267                     "Unexpected exception occured while getting VNF package using nsPackageId: " + nsPackageId;
 
 268             logger.error(message, failureException);
 
 270             abortOperation(execution, message);
 
 273         logger.info("Finished executing getVnfPkgIdForEachVnfdId ...");
 
 277     public void logTimeOut(final DelegateExecution execution) {
 
 278         logger.error("Vnf instantiation timedOut ...");
 
 279         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
 
 280         final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
 
 281         if (nfInstances != null) {
 
 282             nfInstances.stream().forEach(instance -> {
 
 283                 logger.info("Current status {} of vnf: {}", instance.getStatus(), instance.getName());
 
 288     public void setJobStatusToError(final DelegateExecution execution) {
 
 289         updateNsInstanceStatus(execution, State.FAILED);
 
 290         setJobStatusToError(execution, "Instantiate NS workflow process failed");
 
 293     private NsdInfo getNsdInfo(final DelegateExecution execution, final String nsPackageId) {
 
 295             final Optional<NsdInfo> optional =
 
 296                     etsiCatalogPackageManagementServiceProvider.getNSPackageModel(nsPackageId);
 
 298             if (optional.isPresent()) {
 
 299                 final NsdInfo packageModel = optional.get();
 
 300                 logger.info("NS Package exists {}", packageModel);
 
 304         } catch (final EtsiCatalogManagerRequestFailureException failureException) {
 
 305             final String message =
 
 306                     "Unexpected exception occured while getting ns package using nsPackageId: " + nsPackageId;
 
 307             logger.error(message, failureException);
 
 309             abortOperation(execution, message);
 
 312         final String message = "Unable to find NS package using NS package id: " + nsPackageId;
 
 313         logger.error(message);
 
 314         abortOperation(execution, message);
 
 319     private void updateNsInstanceStatus(final DelegateExecution execution, final State nsStatus) {
 
 320         final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution);
 
 321         logger.info("Updating NfvoNsInst Status to {} and saving to DB", nsStatus);
 
 322         nfvoNsInst.setStatus(nsStatus);
 
 323         databaseServiceProvider.saveNfvoNsInst(nfvoNsInst);
 
 326     private Optional<Tenant> getTenant(final Map<String, String> additionalParams) {
 
 327         final String vimId = (String) additionalParams.get("vim_id");
 
 329             final String[] splitString = vimId.split("_");
 
 330             if (splitString.length == 3) {
 
 331                 logger.info("Found Tenant in additionalParams: {}", additionalParams);
 
 333                         new Tenant().cloudOwner(splitString[0]).regionName(splitString[1]).tenantId(splitString[2]));
 
 337         logger.error("Unable to find Tenant in additionalParams: {}", additionalParams);
 
 338         return Optional.empty();
 
 341     private Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> getAdditionalParamsForVnf(
 
 343             final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) {
 
 344         final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional =
 
 345                 additionalParamsForVnfList.stream().filter(entry -> vnfdId.equals(entry.getVnfProfileId())).findFirst();
 
 346         if (optional.isPresent()) {
 
 347             logger.info("Found AdditionalParamsForVnf in instantiateNsRequest using vnfdId: {}", vnfdId);