85af369f496db4af7fc8d85f689fcf4766fcab65
[so/adapters/so-cnf-adapter.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2023 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.cnfm.lcm.bpmn.flows.tasks;
21
22 import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.AS_INSTANCE_ID_PARAM_NAME;
23 import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME;
24 import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_AS_REQUEST_PARAM_NAME;
25 import static org.onap.so.cnfm.lcm.bpmn.flows.CamundaVariableNameConstants.CREATE_AS_RESPONSE_PARAM_NAME;
26 import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.APPLICATION_NAME_PARAM_NAME;
27 import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.APPLICATION_VERSION_PARAM_NAME;
28 import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DEPLOYMENT_ITEMS_PARAM_NAME;
29 import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DESCRIPTOR_ID_PARAM_NAME;
30 import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.DESCRIPTOR_INVARIANT_ID_PARAM_NAME;
31 import static org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPropertiesConstants.PROVIDER_PARAM_NAME;
32 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.CLOUD_OWNER_PARAM_KEY;
33 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.CLOUD_REGION_PARAM_KEY;
34 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.RESOURCE_ID_KEY;
35 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.SERVICE_INSTANCE_ID_PARAM_KEY;
36 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.SERVICE_INSTANCE_NAME_PARAM_KEY;
37 import static org.onap.so.cnfm.lcm.model.utils.AdditionalParamsConstants.TENANT_ID_PARAM_KEY;
38 import java.util.Arrays;
39 import java.util.ArrayList;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Optional;
43 import java.util.UUID;
44 import java.time.LocalDateTime;
45
46 import org.camunda.bpm.engine.delegate.DelegateExecution;
47 import org.onap.aai.domain.yang.GenericVnf;
48 import org.onap.so.cnfm.lcm.bpmn.flows.extclients.aai.AaiServiceProvider;
49 import org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.DeploymentItem;
50 import org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcCsarPackageParser;
51 import org.onap.so.cnfm.lcm.bpmn.flows.extclients.sdc.SdcPackageProvider;
52 import org.onap.so.cnfm.lcm.database.beans.AsDeploymentItem;
53 import org.onap.so.cnfm.lcm.database.beans.AsInst;
54 import org.onap.so.cnfm.lcm.database.beans.JobStatusEnum;
55 import org.onap.so.cnfm.lcm.database.beans.State;
56 import org.onap.so.cnfm.lcm.database.beans.AsLifecycleParam;
57 import org.onap.so.cnfm.lcm.database.service.DatabaseServiceProvider;
58 import org.onap.so.cnfm.lcm.model.AsInstance;
59 import org.onap.so.cnfm.lcm.model.AsInstance.InstantiationStateEnum;
60 import org.onap.so.cnfm.lcm.model.CreateAsRequest;
61 import org.onap.so.cnfm.lcm.model.ErrorDetails;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64 import org.springframework.beans.factory.annotation.Autowired;
65 import org.springframework.stereotype.Component;
66
67 /**
68  * @author Waqas Ikram (waqas.ikram@est.tech)
69  *
70  */
71 @Component
72 public class CreateAsTask extends AbstractServiceTask {
73     private static final String ASD_PROPERTIES_PARAM_NAME = "asdProperties";
74     private static final String DOES_AS_PACKAGE_EXISTS_PARAM_NAME = "doesAsPackageExists";
75     private static final String DOES_AS_INSTANCE_EXISTS_PARAM_NAME = "doesAsInstanceExists";
76     private static final Logger logger = LoggerFactory.getLogger(CreateAsTask.class);
77
78     private final AaiServiceProvider aaiServiceProvider;
79     private final SdcPackageProvider sdcPackageProvider;
80     private final SdcCsarPackageParser sdcParser;
81
82
83     @Autowired
84     public CreateAsTask(final DatabaseServiceProvider databaseServiceProvider,
85             final AaiServiceProvider aaiServiceProvider, final SdcPackageProvider sdcPackageProvider,
86             final SdcCsarPackageParser sdcParser) {
87         super(databaseServiceProvider);
88         this.aaiServiceProvider = aaiServiceProvider;
89         this.sdcPackageProvider = sdcPackageProvider;
90         this.sdcParser = sdcParser;
91     }
92
93     public void setJobStatusToStarted(final DelegateExecution execution) {
94         setJobStatus(execution, JobStatusEnum.STARTED, "Create AS workflow process started");
95     }
96
97     public void setJobStatusToFinished(final DelegateExecution execution) {
98         setJobStatus(execution, JobStatusEnum.FINISHED, "Create AS workflow process finished");
99     }
100
101     public void setJobStatusToError(final DelegateExecution execution) {
102         setJobStatusToError(execution, "Create AS workflow process failed");
103     }
104
105     public void getAsPackage(final DelegateExecution execution) {
106         logger.info("Retrieving AS package from SDC ...");
107         setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Retrieving AS package from SDC");
108
109         final CreateAsRequest createAsRequest = (CreateAsRequest) execution.getVariable(CREATE_AS_REQUEST_PARAM_NAME);
110
111         logger.info("Retrieving AS package from SDC using asdId: {}", createAsRequest.getAsdId());
112
113         try {
114
115             final Optional<byte[]> optional = sdcPackageProvider.getSdcResourcePackage(createAsRequest.getAsdId());
116
117             if (optional.isPresent()) {
118                 logger.info("ASD Package exists for asdId {}", createAsRequest.getAsdId());
119
120                 final Map<String, Object> asdProperties = sdcParser.getAsdProperties(optional.get());
121                 logger.info("ASD Package properties fields {}", asdProperties);
122
123                 execution.setVariable(ASD_PROPERTIES_PARAM_NAME, asdProperties);
124                 execution.setVariable(DOES_AS_PACKAGE_EXISTS_PARAM_NAME, true);
125             } else {
126
127                 final String message = "Unable to find ASD package using asdId: " + createAsRequest.getAsdId();
128                 logger.error(message);
129                 execution.setVariable(DOES_AS_PACKAGE_EXISTS_PARAM_NAME, false);
130                 abortOperation(execution, message);
131             }
132         } catch (final Exception failureException) {
133             final String message =
134                     "Unexpected exception occured while getting asd package using asdId: " + createAsRequest.getAsdId();
135             logger.error(message, failureException);
136
137             execution.setVariable(DOES_AS_PACKAGE_EXISTS_PARAM_NAME, false);
138             execution.setVariable(AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
139                     new ErrorDetails().title(message).detail(message));
140         }
141
142     }
143
144     public void doesAsInstanceExistsInDb(final DelegateExecution execution) {
145         logger.info("Executing doesAsInstanceExistsInDb  ...");
146
147         setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Checking if AS Instance exists in database");
148
149         final CreateAsRequest createAsRequest =
150                 (CreateAsRequest) execution.getVariables().get(CREATE_AS_REQUEST_PARAM_NAME);
151
152         final boolean exists = databaseServiceProvider.isAsInstExists(createAsRequest.getAsInstanceName());
153         logger.info("As Instance entry {} exists in database", exists ? "does" : "doesn't");
154         execution.setVariable(DOES_AS_INSTANCE_EXISTS_PARAM_NAME, exists);
155
156         if (exists) {
157             final Optional<AsInst> optional =
158                     databaseServiceProvider.getAsInstByName(createAsRequest.getAsInstanceName());
159             final AsInst asInst = optional.get();
160             execution.setVariable(AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
161                     new ErrorDetails().detail("As Instance already exists in database : " + asInst.toString()));
162         }
163
164         logger.info("Finished executing doesAsInstanceExistsInDb  ...");
165
166     }
167
168     public void createAsInstanceInDb(final DelegateExecution execution) {
169         try {
170             logger.info("Executing createAsInstanceInDb  ...");
171
172             setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Creating AS Instance entry in database");
173
174             final CreateAsRequest createAsRequest =
175                     (CreateAsRequest) execution.getVariable(CREATE_AS_REQUEST_PARAM_NAME);
176
177             final Map<String, Object> additionalParams = createAsRequest.getAdditionalParams();
178
179             if (additionalParams == null) {
180                 abortOperation(execution, "Missing 'additionalParams' mandatory field");
181             }
182
183             final String cloudOwner = getMandatoryValue(additionalParams, CLOUD_OWNER_PARAM_KEY, execution);
184             final String cloudRegion = getMandatoryValue(additionalParams, CLOUD_REGION_PARAM_KEY, execution);
185             final String tenantId = getMandatoryValue(additionalParams, TENANT_ID_PARAM_KEY, execution);
186             final String resourceId = (String) additionalParams.get(RESOURCE_ID_KEY);
187
188             final String serviceInstanceName =
189                     getMandatoryValue(additionalParams, SERVICE_INSTANCE_NAME_PARAM_KEY, execution);
190             final String serviceInstanceId =
191                     getMandatoryValue(additionalParams, SERVICE_INSTANCE_ID_PARAM_KEY, execution);
192
193             final String asInstId = getAsInstId(resourceId);
194             execution.setVariable(AS_INSTANCE_ID_PARAM_NAME, asInstId);
195
196             @SuppressWarnings("unchecked")
197             final Map<String, Object> asdProperties =
198                     (Map<String, Object>) execution.getVariable(ASD_PROPERTIES_PARAM_NAME);
199
200             final AsInst asInst = new AsInst().asInstId(asInstId).name(createAsRequest.getAsInstanceName())
201                     .asdId(createAsRequest.getAsdId())
202                     .asPackageId(getParamValue(asdProperties, DESCRIPTOR_ID_PARAM_NAME))
203                     .asdInvariantId(getParamValue(asdProperties, DESCRIPTOR_INVARIANT_ID_PARAM_NAME))
204                     .asProvider(getParamValue(asdProperties, PROVIDER_PARAM_NAME))
205                     .asApplicationName(getParamValue(asdProperties, APPLICATION_NAME_PARAM_NAME))
206                     .asApplicationVersion(getParamValue(asdProperties, APPLICATION_VERSION_PARAM_NAME))
207                     .description(createAsRequest.getAsInstanceDescription()).serviceInstanceId(serviceInstanceId)
208                     .serviceInstanceName(serviceInstanceName).cloudOwner(cloudOwner).cloudRegion(cloudRegion)
209                     .tenantId(tenantId).status(State.NOT_INSTANTIATED).statusUpdatedTime(LocalDateTime.now());
210
211             @SuppressWarnings("unchecked")
212             final List<DeploymentItem> deploymentItems =
213                     (List<DeploymentItem>) asdProperties.get(DEPLOYMENT_ITEMS_PARAM_NAME);
214
215             if (deploymentItems != null) {
216                 deploymentItems.forEach(item -> {
217                     final AsDeploymentItem asDeploymentItem =
218                             new AsDeploymentItem().itemId(item.getItemId()).name(item.getName())
219                                     .deploymentOrder(item.getDeploymentOrder() != null
220                                             ? Integer.parseInt(item.getDeploymentOrder())
221                                             : null)
222                                     .artifactFilePath(item.getFile()).status(State.NOT_INSTANTIATED)
223                                     .createTime(LocalDateTime.now()).lastUpdateTime(LocalDateTime.now())
224                                     .releaseName(generateReleaseName(asInst, item));
225                     final List<AsLifecycleParam> lifecycleParams = getLifeCycleParams(asDeploymentItem, item);
226                     asDeploymentItem.setAsLifecycleParams(lifecycleParams);
227                     asInst.asdeploymentItems(asDeploymentItem);
228                 });
229             }
230
231             databaseServiceProvider.saveAsInst(asInst);
232             logger.info("Finished executing createAsInstanceInDb  ...");
233         } catch (final Exception exception) {
234             logger.error("Unable to create AsInst object in database", exception);
235             throw exception;
236         }
237
238     }
239
240     private List<AsLifecycleParam> getLifeCycleParams(final AsDeploymentItem asDeploymentItem,
241             final DeploymentItem deploymentItem) {
242         final List<AsLifecycleParam> asLifecycleParams = new ArrayList<>();
243         if (deploymentItem.getLifecycleParameters() != null) {
244             for (final String lifecycleParam : deploymentItem.getLifecycleParameters()) {
245                 asLifecycleParams.add(
246                         new AsLifecycleParam().asDeploymentItemInst(asDeploymentItem).asLifecycleParam(lifecycleParam));
247             }
248
249
250         }
251         return asLifecycleParams;
252     }
253
254     private String generateReleaseName(final AsInst asInst, final DeploymentItem item) {
255         return String.join("-", Arrays.asList(asInst.getName(), item.getName(), item.getItemId())).toLowerCase()
256                 .replaceAll("[\\s\\_]", "-");
257     }
258
259     public void createGenericVnfInstanceInAai(final DelegateExecution execution) {
260         logger.info("Executing createAsInstanceInAai  ...");
261         try {
262             setJobStatus(execution, JobStatusEnum.IN_PROGRESS, "Creating Generic Vnf Instance in AAI");
263
264             final String asInstId = (String) execution.getVariable(AS_INSTANCE_ID_PARAM_NAME);
265             final AsInst asInst = getAsInst(execution, asInstId);
266
267             final GenericVnf genericVnf = new GenericVnf();
268             genericVnf.setVnfId(asInstId);
269             genericVnf.setVnfName(asInst.getName());
270             genericVnf.setVnfType(asInst.getServiceInstanceName() + "/" + asInst.getName());
271             genericVnf.setServiceId(asInst.getServiceInstanceId());
272             genericVnf.setOperationalStatus("Created");
273             genericVnf.setOrchestrationStatus("Created");
274             genericVnf.setIsClosedLoopDisabled(false);
275             aaiServiceProvider.createGenericVnfAndConnectServiceInstance(asInst.getServiceInstanceId(), asInstId,
276                     genericVnf);
277
278             aaiServiceProvider.connectGenericVnfToTenant(asInstId, asInst.getCloudOwner(), asInst.getCloudRegion(),
279                     asInst.getTenantId());
280
281         } catch (final Exception exception) {
282             final String message = "Unable to Create Generic Vnf Instance in AAI";
283             logger.error(message, exception);
284             abortOperation(execution, message);
285         }
286         logger.info("Finished executing createNsInstanceInAai  ...");
287
288     }
289
290     public void setCreateAsResponse(final DelegateExecution execution) {
291         logger.info("Executing setCreateAsResponse  ...");
292         final String asInstId = (String) execution.getVariable(AS_INSTANCE_ID_PARAM_NAME);
293         final Optional<AsInst> optional = databaseServiceProvider.getAsInst(asInstId);
294
295         if (optional.isPresent()) {
296             final AsInst asInst = optional.get();
297             final AsInstance response =
298                     new AsInstance().asInstanceid(asInst.getAsInstId()).asInstanceName(asInst.getName())
299                             .asdId(asInst.getAsdId()).asInstanceDescription(asInst.getDescription())
300                             .instantiationState(InstantiationStateEnum.fromValue(asInst.getStatus().toString()))
301                             .asProvider(asInst.getAsProvider()).asApplicationName(asInst.getAsApplicationName())
302                             .asApplicationVersion(asInst.getAsApplicationVersion());
303             logger.info("Saving CreateNsResponse: {} in Execution ...", response);
304             execution.setVariable(CREATE_AS_RESPONSE_PARAM_NAME, response);
305         } else {
306             final String message = "Unable to find AS Instance in datababse using id: " + asInstId;
307             logger.error(message);
308             abortOperation(execution, message);
309         }
310
311         logger.info("Finished executing setCreateNsResponse  ...");
312
313     }
314
315     private String getMandatoryValue(final Map<String, Object> additionalParams, final String key,
316             final DelegateExecution execution) {
317         final Object value = additionalParams.get(key);
318         if (value == null) {
319             abortOperation(execution, "Missing '" + key + "' mandatory field");
320         }
321         return value.toString();
322     }
323
324     private String getAsInstId(final String resourceId) {
325         if ((resourceId != null) && !(resourceId.isBlank())) {
326             logger.debug("Will use resourceId as asInstId: {}", resourceId);
327             return resourceId;
328         }
329         final String asInstId = UUID.randomUUID().toString();
330         logger.debug("Creating random UUID for asInstId: {}", asInstId);
331         return asInstId;
332     }
333
334     private String getParamValue(final Map<String, Object> properties, final String key) {
335         final Object object = properties.get(key);
336         if (object != null) {
337             return object.toString();
338         }
339         logger.warn("Unable to final property value for key {}", key);
340         return null;
341     }
342 }