Adding NS instantiation
[so.git] / so-etsi-nfvo / so-etsi-nfvo-ns-lcm / so-etsi-nfvo-ns-lcm-bpmn-flows / src / main / java / org / onap / so / etsi / nfvo / ns / lcm / bpmn / flows / tasks / InstantiateNsTask.java
1 /*-
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
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.tasks;
21
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.OCC_ID_PARAM_NAME;
26 import static org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.CamundaVariableNameConstants.VNF_CREATE_INSTANTIATE_REQUESTS;
27 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.FINISHED;
28 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.IN_PROGRESS;
29 import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.JobStatusEnum.STARTED;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Optional;
36 import org.camunda.bpm.engine.delegate.DelegateExecution;
37 import org.onap.so.adapters.etsisol003adapter.lcm.v1.model.Tenant;
38 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.NsdInfo;
39 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.model.VnfPkgInfo;
40 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.exceptions.EtsiCatalogManagerRequestFailureException;
41 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.extclients.etsicatalog.EtsiCatalogPackageManagementServiceProvider;
42 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
43 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.VirtualNetworkFunction;
44 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNfInst;
45 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NfvoNsInst;
46 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.NsLcmOpOcc;
47 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.OperationStateEnum;
48 import org.onap.so.etsi.nfvo.ns.lcm.database.beans.State;
49 import org.onap.so.etsi.nfvo.ns.lcm.database.service.DatabaseServiceProvider;
50 import org.onap.so.etsi.nfvo.ns.lcm.model.InstantiateNsRequest;
51 import org.onap.so.etsi.nfvo.ns.lcm.model.NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.springframework.beans.factory.annotation.Autowired;
55 import org.springframework.stereotype.Component;
56
57 /**
58  * @author Andrew Lamb (andrew.a.lamb@est.tech)
59  *
60  */
61 @Component
62 public class InstantiateNsTask extends AbstractNetworkServiceTask {
63
64     private static final String IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME = "isNsInstantiationSuccessful";
65     private static final String VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME = "vnfdIdToVnfPkgIdMapping";
66     private static final Logger logger = LoggerFactory.getLogger(InstantiateNsTask.class);
67     private final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider;
68
69     @Autowired
70     public InstantiateNsTask(final DatabaseServiceProvider databaseServiceProvider,
71             final EtsiCatalogPackageManagementServiceProvider etsiCatalogPackageManagementServiceProvider) {
72         super(databaseServiceProvider);
73         this.etsiCatalogPackageManagementServiceProvider = etsiCatalogPackageManagementServiceProvider;
74
75     }
76
77     public void setJobStatusToStarted(final DelegateExecution execution) {
78         setJobStatus(execution, STARTED, "Instantiate NS workflow process started");
79     }
80
81     public void setJobStatusToFinished(final DelegateExecution execution) {
82         setJobStatus(execution, FINISHED, "Instantiate NS workflow process finished");
83     }
84
85     public void updateNsInstanceStatusToInstantiating(final DelegateExecution execution) {
86         logger.info("Executing updateNsInstanceStatusToInstantiating");
87         setJobStatus(execution, IN_PROGRESS, "Updating NfvoNsInst Status to " + State.INSTANTIATING);
88         updateNsInstanceStatus(execution, State.INSTANTIATING);
89
90         logger.info("Finished executing updateNsInstanceStatusToInstantiating  ...");
91     }
92
93
94     public void checkIfVnfInstantiationWasSuccessful(final DelegateExecution execution) {
95         logger.info("Executing checkIfVnfInstantiationWasSuccessful");
96
97         @SuppressWarnings("unchecked")
98         final List<CreateInstantiateRequest> requests =
99                 (List<CreateInstantiateRequest>) execution.getVariable(VNF_CREATE_INSTANTIATE_REQUESTS);
100
101         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
102         final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
103
104         if (nfInstances == null || nfInstances.isEmpty()) {
105             final String message = "Found empty nf instances";
106             abortOperation(execution, message);
107         }
108
109         if (requests.size() != nfInstances.size()) {
110             final String message = "Missing nf Instance. Request triggered: " + requests.size()
111                     + " Nf Instace reqeust found in database " + nfInstances.size();
112             abortOperation(execution, message);
113         }
114
115         execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, true);
116
117         nfInstances.stream().forEach(instance -> {
118             if (!State.INSTANTIATED.equals(instance.getStatus())) {
119                 logger.error("VNF : {} {} instantiation failed", instance.getNfInstId(), instance.getName());
120                 execution.setVariable(IS_NS_INSTANTIATION_SUCCESSFUL_PARAM_NAME, false);
121             }
122         });
123
124         logger.info("Finished executing checkIfVnfInstantiationWasSuccessful  ...");
125     }
126
127     public void updateNsInstanceStatusToInstantiated(final DelegateExecution execution) {
128         logger.info("Executing updateNsInstanceStatusToInstantiated");
129         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
130         setJobStatus(execution, FINISHED, "Successfully " + State.INSTANTIATED + " NS: " + nsInstId);
131
132         updateNsInstanceStatus(execution, State.INSTANTIATED);
133         logger.info("Finished executing updateNsInstanceStatusToInstantiated  ...");
134     }
135
136     public void getAndParseNsdFromEtsiCatalog(final DelegateExecution execution) {
137         logger.info("Executing getAndParseNsdFromEtsiCatalog");
138         setJobStatus(execution, IN_PROGRESS, "Retrieving and parsing NSD from ETSI Catalog Manager");
139         final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution);
140         final String nsPackageId = nfvoNsInst.getNsPackageId();
141
142         try {
143             final Optional<NetworkServiceDescriptor> optional =
144                     etsiCatalogPackageManagementServiceProvider.getNetworkServiceDescriptor(nsPackageId);
145
146             if (!optional.isPresent()) {
147                 final String message = "Unable to parse NSD " + nsPackageId;
148                 logger.error(message);
149                 abortOperation(execution, message);
150             }
151
152             final NetworkServiceDescriptor networkServiceDescriptor = optional.get();
153             logger.info("Found {}", networkServiceDescriptor);
154             execution.setVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME, networkServiceDescriptor);
155
156         } catch (final EtsiCatalogManagerRequestFailureException failureException) {
157             final String message =
158                     "Unexpected exception occured while getting nsd content using nsPackageId: " + nsPackageId;
159             logger.error(message, failureException);
160
161             abortOperation(execution, message);
162         }
163
164         logger.info("Finished executing getAndParseNsdFromEtsiCatalog  ...");
165
166     }
167
168     public void prepareCreateInstantiateRequests(final DelegateExecution execution) {
169         logger.info("Executing prepareCreateInstantiateRequests ...");
170         setJobStatus(execution, IN_PROGRESS, "Preparing VNF CreateInstantiate requests");
171         final NetworkServiceDescriptor networkServiceDescriptor =
172                 (NetworkServiceDescriptor) execution.getVariable(NETWORK_SERVICE_DESCRIPTOR_PARAM_NAME);
173         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
174
175         final InstantiateNsRequest instantiateNsRequest =
176                 (InstantiateNsRequest) execution.getVariable(INSTANTIATE_NS_REQUEST_PARAM_NAME);
177
178         final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList =
179                 instantiateNsRequest.getAdditionalParamsForVnf();
180
181         @SuppressWarnings("unchecked")
182         final Map<String, String> vnfdIdToVnfPkgIdMapping =
183                 (Map<String, String>) execution.getVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME);
184
185         final List<CreateInstantiateRequest> requests = new ArrayList<>();
186
187         for (final VirtualNetworkFunction vnf : networkServiceDescriptor.getVnfs()) {
188             final List<String> vnfmInfoList = vnf.getVnfmInfoList();
189
190             final String vnfdId = vnf.getVnfdId();
191             final String vnfPkgId = vnfdIdToVnfPkgIdMapping.get(vnfdId);
192             if (vnfdId == null || vnfmInfoList.isEmpty() || vnfPkgId == null) {
193                 final String message = "Unable to find VnfdId/vnfmInfo/VnfPkgId for vnf: " + vnf;
194                 abortOperation(execution, message);
195             }
196
197             final Optional<Tenant> optional = getTenant(vnfPkgId, additionalParamsForVnfList);
198             if (!optional.isPresent()) {
199                 final String message = "Unable to find Tenant information for " + vnfdId + " in instantiateNsRequest : "
200                         + instantiateNsRequest;
201                 abortOperation(execution, message);
202             }
203
204             final Tenant tenant = optional.get();
205             final CreateInstantiateRequest createInstantiateRequest = new CreateInstantiateRequest().nsInstId(nsInstId)
206                     .vnfdId(vnfdId).vnfName(vnf.getVnfName()).vnfPkgId(vnfPkgId).nfType(vnfmInfoList.get(0))
207                     .tenant(tenant).additionalParams(getAdditionalParams(vnfPkgId, additionalParamsForVnfList));
208
209             logger.info("Adding request to list: {}", createInstantiateRequest);
210             requests.add(createInstantiateRequest);
211
212         }
213         execution.setVariable(VNF_CREATE_INSTANTIATE_REQUESTS, requests);
214
215         logger.info("Finished executing prepareCreateInstantiateRequests  ...");
216     }
217
218     public void getVnfPkgIdForEachVnfdId(final DelegateExecution execution) {
219         logger.info("Executing getVnfPkgIdForEachVnfdId ...");
220
221         setJobStatus(execution, IN_PROGRESS, "Getting VnfPkgId for each VnfdId");
222
223         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
224         final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution, nsInstId);
225
226         final String nsPackageId = nfvoNsInst.getNsPackageId();
227         final NsdInfo nsdInfo = getNsdInfo(execution, nsPackageId);
228
229         final Map<String, String> vnfdIdToVnfPkgIdMapping = new HashMap<>();
230         try {
231             for (final String vnfPkgId : nsdInfo.getVnfPkgIds()) {
232                 final Optional<VnfPkgInfo> optional =
233                         etsiCatalogPackageManagementServiceProvider.getVnfPkgInfo(vnfPkgId);
234
235                 if (!optional.isPresent()) {
236                     final String message = "Unable to find VNF package using NS vnfPkgId: " + vnfPkgId;
237                     logger.error(message);
238                     abortOperation(execution, message);
239                 }
240                 final VnfPkgInfo vnfPkgInfo = optional.get();
241                 vnfdIdToVnfPkgIdMapping.put(vnfPkgInfo.getVnfdId(), vnfPkgId);
242
243             }
244             logger.info("vnfdIdToVnfPkgIdMapping: {}", vnfdIdToVnfPkgIdMapping);
245             execution.setVariable(VNFD_ID_TO_VNF_PKG_ID_MAPPING_PARAM_NAME, vnfdIdToVnfPkgIdMapping);
246
247         } catch (final EtsiCatalogManagerRequestFailureException failureException) {
248             final String message =
249                     "Unexpected exception occured while getting VNF package using nsPackageId: " + nsPackageId;
250             logger.error(message, failureException);
251
252             abortOperation(execution, message);
253         }
254
255         logger.info("Finished executing getVnfPkgIdForEachVnfdId ...");
256
257     }
258
259     public void logTimeOut(final DelegateExecution execution) {
260         logger.error("Vnf instantiation timedOut ...");
261         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
262         final List<NfvoNfInst> nfInstances = databaseServiceProvider.getNfvoNfInstByNsInstId(nsInstId);
263         if (nfInstances != null) {
264             nfInstances.stream().forEach(instance -> {
265                 logger.info("Current status {} of vnf: {}", instance.getStatus(), instance.getName());
266             });
267         }
268     }
269
270     public void setJobStatusToError(final DelegateExecution execution) {
271         updateNsInstanceStatus(execution, State.FAILED);
272         setJobStatusToError(execution, "Instantiate NS workflow process failed");
273     }
274
275
276     public void updateNsLcmOpOccStatusToCompleted(final DelegateExecution execution) {
277         logger.info("Executing updateNsLcmOpOccStatusToCompleted ...");
278         final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
279
280         final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
281
282         if (!optional.isPresent()) {
283             final String message = "Unable to find record for NSLcmOpOcc in database using id: " + occId;
284             logger.error(message);
285             abortOperation(execution, message);
286         }
287
288         final NsLcmOpOcc nsLcmOpOcc = optional.get();
289         final OperationStateEnum operationStateCompleted = OperationStateEnum.COMPLETED;
290         logger.info("Setting operation state to {} for id: {}", operationStateCompleted, occId);
291         nsLcmOpOcc.setOperationState(operationStateCompleted);
292         databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
293
294         logger.info("Finished executing updateNsLcmOpOccStatusToCompleted ...");
295
296     }
297
298     public void updateNsLcmOpOccStatusToFailed(final DelegateExecution execution) {
299         logger.info("Executing updateNsLcmOpOccStatusToFailed ...");
300         final String occId = (String) execution.getVariable(OCC_ID_PARAM_NAME);
301
302         final Optional<NsLcmOpOcc> optional = databaseServiceProvider.getNsLcmOpOcc(occId);
303
304         if (optional.isPresent()) {
305             final NsLcmOpOcc nsLcmOpOcc = optional.get();
306             final OperationStateEnum operationStateFailed = OperationStateEnum.FAILED;
307             logger.info("Setting operation state to {} for id: {}", operationStateFailed, occId);
308             nsLcmOpOcc.setOperationState(operationStateFailed);
309
310             databaseServiceProvider.addNSLcmOpOcc(nsLcmOpOcc);
311         } else {
312             logger.error("Unable to find record for NSLcmOpOcc in database using id: {}", occId);
313         }
314
315         logger.info("Finished executing updateNsLcmOpOccStatusToFailed ...");
316
317     }
318
319     private NsdInfo getNsdInfo(final DelegateExecution execution, final String nsPackageId) {
320         try {
321             final Optional<NsdInfo> optional =
322                     etsiCatalogPackageManagementServiceProvider.getNSPackageModel(nsPackageId);
323
324             if (optional.isPresent()) {
325                 final NsdInfo packageModel = optional.get();
326                 logger.info("NS Package exists {}", packageModel);
327                 return packageModel;
328             }
329
330         } catch (final EtsiCatalogManagerRequestFailureException failureException) {
331             final String message =
332                     "Unexpected exception occured while getting ns package using nsPackageId: " + nsPackageId;
333             logger.error(message, failureException);
334
335             abortOperation(execution, message);
336         }
337
338         final String message = "Unable to find NS package using NS package id: " + nsPackageId;
339         logger.error(message);
340         abortOperation(execution, message);
341         return null;
342
343     }
344
345     private void updateNsInstanceStatus(final DelegateExecution execution, final State nsStatus) {
346         final NfvoNsInst nfvoNsInst = getNfvoNsInst(execution);
347         logger.info("Updating NfvoNsInst Status to {} and saving to DB", nsStatus);
348         nfvoNsInst.setStatus(nsStatus);
349         databaseServiceProvider.saveNfvoNsInst(nfvoNsInst);
350     }
351
352     private Optional<Tenant> getTenant(final String vnfPkgId,
353             final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) {
354
355         final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList
356                 .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst();
357
358         if (optional.isPresent()) {
359             final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get();
360             @SuppressWarnings("unchecked")
361             final Map<String, Object> additionalParams =
362                     (Map<String, Object>) additionalParamsForVnf.getAdditionalParams();
363             final String vimId = (String) additionalParams.get("vim_id");
364             if (vimId != null) {
365                 final String[] splitString = vimId.split("_");
366                 if (splitString.length == 3) {
367                     logger.info("Found Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId);
368                     return Optional.of(new Tenant().cloudOwner(splitString[0]).regionName(splitString[1])
369                             .tenantId(splitString[2]));
370                 }
371
372             }
373         }
374
375         logger.error("Unable to find Tenant in instantiateNsRequest using vnfPkgId: {}", vnfPkgId);
376         return Optional.empty();
377     }
378
379     @SuppressWarnings("unchecked")
380     private Map<String, String> getAdditionalParams(final String vnfPkgId,
381             final List<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> additionalParamsForVnfList) {
382
383         final Optional<NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf> optional = additionalParamsForVnfList
384                 .stream().filter(entry -> vnfPkgId.equals(entry.getVnfProfileId())).findFirst();
385
386         if (optional.isPresent()) {
387             final NsInstancesnsInstanceIdinstantiateAdditionalParamsForVnf additionalParamsForVnf = optional.get();
388             if (additionalParamsForVnf instanceof Map) {
389                 logger.info("Found AdditionalParams in instantiateNsRequest using vnfPkgId: {}", vnfPkgId);
390                 return (Map<String, String>) additionalParamsForVnf.getAdditionalParams();
391             }
392         }
393
394         return Collections.emptyMap();
395
396     }
397
398     private NfvoNsInst getNfvoNsInst(final DelegateExecution execution) {
399         final String nsInstId = (String) execution.getVariable(NS_INSTANCE_ID_PARAM_NAME);
400         return getNfvoNsInst(execution, nsInstId);
401     }
402
403     private NfvoNsInst getNfvoNsInst(final DelegateExecution execution, final String nsInstId) {
404         logger.info("Getting NfvoNsInst to update with nsInstId: {}", nsInstId);
405         final Optional<NfvoNsInst> optionalNfvoNsInst = databaseServiceProvider.getNfvoNsInst(nsInstId);
406
407         if (!optionalNfvoNsInst.isPresent()) {
408             final String message = "Unable to find NS Instance in database using id: " + nsInstId;
409             abortOperation(execution, message);
410         }
411
412         return optionalNfvoNsInst.get();
413     }
414
415
416 }