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