2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
19 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
22 package org.openecomp.sdc.be.components.csar;
24 import static org.openecomp.sdc.common.api.Constants.DEFAULT_MODEL_NAME;
26 import fj.data.Either;
28 import java.util.Optional;
29 import org.apache.commons.lang3.tuple.ImmutablePair;
30 import org.openecomp.sdc.be.components.impl.BaseBusinessLogic;
31 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
32 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
33 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
34 import org.openecomp.sdc.be.config.BeEcompErrorManager;
35 import org.openecomp.sdc.be.dao.api.ActionStatus;
36 import org.openecomp.sdc.be.model.Component;
37 import org.openecomp.sdc.be.model.NodeTypeInfo;
38 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
39 import org.openecomp.sdc.be.model.Resource;
40 import org.openecomp.sdc.be.model.Service;
41 import org.openecomp.sdc.be.model.User;
42 import org.openecomp.sdc.be.model.VendorSoftwareProduct;
43 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
44 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
45 import org.openecomp.sdc.be.model.operations.StorageException;
46 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
47 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
48 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
49 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
50 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
51 import org.openecomp.sdc.be.model.operations.impl.CsarOperation;
52 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
53 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
54 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
55 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
56 import org.openecomp.sdc.common.log.wrappers.Logger;
57 import org.openecomp.sdc.exception.ResponseFormat;
58 import org.springframework.beans.factory.annotation.Autowired;
60 @org.springframework.stereotype.Component("csarBusinessLogic")
61 public class CsarBusinessLogic extends BaseBusinessLogic {
63 private static final Logger log = Logger.getLogger(CsarBusinessLogic.class);
64 private static final String CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID = "Creating resource from CSAR: fetching CSAR with id ";
65 private static final String FAILED = " failed";
66 private final YamlTemplateParsingHandler yamlHandler;
67 private CsarOperation csarOperation;
68 private ModelOperation modelOperation;
71 public CsarBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
72 IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
73 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, YamlTemplateParsingHandler yamlHandler,
74 ArtifactsOperations artifactToscaOperation, ModelOperation modelOperation) {
75 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
76 artifactToscaOperation);
77 this.yamlHandler = yamlHandler;
78 this.modelOperation = modelOperation;
82 public void setCsarOperation(CsarOperation csarOperation) {
83 this.csarOperation = csarOperation;
86 public void validateCsarBeforeCreate(Resource resource, AuditingActionEnum auditingAction, User user, String csarUUID) {
87 // check if VF with the same Csar UUID or with he same name already
90 StorageOperationStatus status = toscaOperationFacade.validateCsarUuidUniqueness(csarUUID);
91 if (status == StorageOperationStatus.ENTITY_ALREADY_EXISTS) {
92 log.debug("Failed to create resource {}, csarUUID {} already exist for a different VF ", resource.getSystemName(), csarUUID);
93 auditAndThrowException(resource, user, auditingAction, ActionStatus.VSP_ALREADY_EXISTS, csarUUID);
94 } else if (status != StorageOperationStatus.OK) {
95 log.debug("Failed to validate uniqueness of CsarUUID {} for resource", csarUUID, resource.getSystemName());
96 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
100 public void validateCsarBeforeCreate(Service resource, String csarUUID) {
101 // check if VF with the same Csar UUID or with he same name already exists
102 StorageOperationStatus status = toscaOperationFacade.validateCsarUuidUniqueness(csarUUID);
103 log.debug("enter validateCsarBeforeCreate,get status:{}", status);
104 if (status == StorageOperationStatus.ENTITY_ALREADY_EXISTS) {
105 log.debug("Failed to create resource {}, csarUUID {} already exist for a different VF ", resource.getSystemName(), csarUUID);
106 } else if (status != StorageOperationStatus.OK) {
107 log.debug("Failed to validate uniqueness of CsarUUID '{}' for resource '{}'", csarUUID, resource.getSystemName());
108 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
112 public OnboardedCsarInfo getCsarInfo(Resource resource, Resource oldResource, User user, Map<String, byte[]> payload, String csarUUID, AuditingActionEnum auditingAction) {
113 Map<String, byte[]> csar = payload;
115 final var vendorSoftwareProduct = getCsar(resource, user);
116 validateModel(resource, vendorSoftwareProduct);
118 csar = vendorSoftwareProduct.getFileMap();
120 ImmutablePair<String, String> toscaYamlCsarStatus = validateAndParseCsar(resource, user, csar, csarUUID, auditingAction).left()
121 .on(this::throwComponentException);
122 String checksum = CsarValidationUtils.getToscaYamlChecksum(csar, csarUUID, componentsUtils).left()
123 .on(r -> logAndThrowComponentException(r, "Failed to calculate checksum for casrUUID {} error {} ", csarUUID));
124 if (oldResource != null && !checksum
125 .equals(oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum())) {
127 "The checksum of main template yaml of csar with csarUUID {} is not equal to the previous one, existing checksum is {}, new one is {}.",
128 csarUUID, oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum(), checksum);
129 oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().setImportedToscaChecksum(checksum);
131 return new OnboardedCsarInfo(user, csarUUID, resource.getCsarVersionId(), csar, resource.getName(), toscaYamlCsarStatus.getKey(),
132 toscaYamlCsarStatus.getValue(), true);
135 private void validateModel(final Resource resource, final VendorSoftwareProduct vendorSoftwareProduct) {
136 if (resource.getModel() == null) {
137 if (!vendorSoftwareProduct.getModelList().isEmpty()) {
138 var modelStringList = String.join(", ", vendorSoftwareProduct.getModelList());
139 throw new ByActionStatusComponentException(ActionStatus.VSP_MODEL_NOT_ALLOWED, DEFAULT_MODEL_NAME, modelStringList);
143 if (!vendorSoftwareProduct.getModelList().contains(resource.getModel())) {
144 var modelStringList =
145 vendorSoftwareProduct.getModelList().isEmpty() ? DEFAULT_MODEL_NAME : String.join(", ", vendorSoftwareProduct.getModelList());
146 throw new ByActionStatusComponentException(ActionStatus.VSP_MODEL_NOT_ALLOWED, resource.getModel(), modelStringList);
150 public ServiceCsarInfo getCsarInfo(Service service, Service oldResource, User user, Map<String, byte[]> payload, String csarUUID, AuditingActionEnum auditingAction) {
151 Map<String, byte[]> csar = getCsar(service, user, payload, csarUUID);
152 ImmutablePair<String, String> toscaYamlCsarStatus = validateAndParseCsar(service, user, csar, csarUUID, auditingAction).left()
153 .on(this::throwComponentException);
154 String checksum = CsarValidationUtils.getToscaYamlChecksum(csar, csarUUID, componentsUtils).left()
155 .on(r -> logAndThrowComponentException(r, "Failed to calculate checksum for casrUUID {} error {} ", csarUUID));
156 if (oldResource != null && !checksum
157 .equals(oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum())) {
159 "The checksum of main template yaml of csar with csarUUID {} is not equal to the previous one, existing checksum is {}, new one is {}.",
160 csarUUID, oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum(), checksum);
161 oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().setImportedToscaChecksum(checksum);
163 return new ServiceCsarInfo(user, csarUUID, csar, service.getName(), service.getModel(), toscaYamlCsarStatus.getKey(),
164 toscaYamlCsarStatus.getValue(), true, modelOperation);
167 public ParsedToscaYamlInfo getParsedToscaYamlInfo(String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo,
168 CsarInfo csarInfo, String nodeName, Component component) {
170 .parseResourceInfoFromYAML(yamlName, topologyTemplateYaml, csarInfo.getCreatedNodesToscaResourceNames(), nodeTypesInfo, nodeName,
171 component, getInterfaceTemplateYaml(csarInfo).orElse(""));
174 private Optional<String> getInterfaceTemplateYaml(CsarInfo csarInfo) {
176 String interfaceTemplateYaml = "";
177 if (csarInfo.getMainTemplateName().contains(".yml")) {
178 yamlFile = csarInfo.getMainTemplateName().split(".yml");
179 interfaceTemplateYaml = yamlFile[0] + "-interface.yml";
180 } else if (csarInfo.getMainTemplateName().contains(".yaml")) {
181 yamlFile = csarInfo.getMainTemplateName().split(".yaml");
182 interfaceTemplateYaml = yamlFile[0] + "-interface.yaml";
184 if (csarInfo.getCsar().containsKey(interfaceTemplateYaml)) {
185 return Optional.of(new String(csarInfo.getCsar().get(interfaceTemplateYaml)));
187 return Optional.empty();
190 private String logAndThrowComponentException(ResponseFormat responseFormat, String logMessage, String... params) {
191 log.debug(logMessage, params, responseFormat);
192 throw new ByResponseFormatComponentException(responseFormat);
195 private ImmutablePair<String, String> throwComponentException(ResponseFormat responseFormat) {
196 throw new ByResponseFormatComponentException(responseFormat);
199 private Either<ImmutablePair<String, String>, ResponseFormat> validateAndParseCsar(Component component, User user, Map<String, byte[]> csar,
200 String csarUUID, AuditingActionEnum auditingAction) {
201 Either<Boolean, ResponseFormat> validateCsarStatus = CsarValidationUtils.validateCsar(csar, csarUUID, componentsUtils);
202 if (validateCsarStatus.isRight()) {
203 ResponseFormat responseFormat = validateCsarStatus.right().value();
204 log.debug("Error when validate csar with ID {}, error: {}", csarUUID, responseFormat);
205 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
206 if (component instanceof Resource) {
207 componentsUtils.auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.CREATE_RESOURCE);
209 return Either.right(responseFormat);
211 Either<ImmutablePair<String, String>, ResponseFormat> toscaYamlCsarStatus = CsarValidationUtils.getToscaYaml(csar, csarUUID, componentsUtils, auditingAction);
212 if (toscaYamlCsarStatus.isRight()) {
213 ResponseFormat responseFormat = toscaYamlCsarStatus.right().value();
214 log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
215 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
216 if (component instanceof Resource) {
217 componentsUtils.auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.CREATE_RESOURCE);
219 return Either.right(responseFormat);
221 return toscaYamlCsarStatus;
224 private Map<String, byte[]> getCsar(Component component, User user, Map<String, byte[]> payload, String csarUUID) {
225 if (payload != null) {
228 Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.findVspLatestPackage(csarUUID, user);
229 if (csar.isRight()) {
230 StorageOperationStatus value = csar.right().value();
231 log.debug("#getCsar - failed to fetch csar with ID {}, error: {}", csarUUID, value);
232 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
233 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(value), csarUUID);
234 if (component instanceof Resource) {
235 Resource newResource = (Resource) component;
236 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.CREATE_RESOURCE);
238 throw new StorageException(csar.right().value());
240 return csar.left().value();
243 private VendorSoftwareProduct getCsar(final Resource resource, final User user) {
244 final Optional<VendorSoftwareProduct> vendorSoftwareProductOpt;
246 if (resource.getCsarVersionId() == null) {
247 vendorSoftwareProductOpt = csarOperation.findLatestVsp(resource.getCsarUUID(), user);
249 vendorSoftwareProductOpt = csarOperation.findVsp(resource.getCsarUUID(), resource.getCsarVersionId(), user);
251 } catch (final Exception exception) {
252 log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, CsarBusinessLogic.class.getName(), exception.getMessage());
253 auditGetCsarError(resource, user, resource.getCsarUUID(), StorageOperationStatus.GENERAL_ERROR);
254 throw new ByActionStatusComponentException(ActionStatus.VSP_FIND_ERROR, resource.getCsarUUID(), resource.getCsarVersionId());
256 if (vendorSoftwareProductOpt.isEmpty()) {
257 auditGetCsarError(resource, user, resource.getCsarUUID(), StorageOperationStatus.CSAR_NOT_FOUND);
258 throw new ByActionStatusComponentException(ActionStatus.VSP_NOT_FOUND, resource.getCsarUUID(), resource.getCsarVersionId());
260 return vendorSoftwareProductOpt.get();
263 private void auditGetCsarError(Component component, User user, String csarUUID, StorageOperationStatus storageOperationStatus) {
264 log.debug("#getCsar - failed to fetch csar with ID {}, error: {}", csarUUID, storageOperationStatus);
265 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
266 var responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageOperationStatus), csarUUID);
267 if (component instanceof Resource) {
268 componentsUtils.auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.CREATE_RESOURCE);
272 private void auditAndThrowException(Resource resource, User user, AuditingActionEnum auditingAction, ActionStatus status, String... params) {
273 ResponseFormat errorResponse = componentsUtils.getResponseFormat(status, params);
274 componentsUtils.auditResource(errorResponse, user, resource, auditingAction);
275 throw new ByResponseFormatComponentException(errorResponse, params);
278 private Either<ImmutablePair<String, String>, ResponseFormat> validateAndParseCsar(Service service, User user, Map<String, byte[]> payload,
279 String csarUUID, AuditingActionEnum auditingAction) {
280 Map<String, byte[]> csar = getCsar(service, user, payload, csarUUID);
281 Either<Boolean, ResponseFormat> validateCsarStatus = CsarValidationUtils.validateCsar(csar, csarUUID, componentsUtils);
282 if (validateCsarStatus.isRight()) {
283 ResponseFormat responseFormat = validateCsarStatus.right().value();
284 log.debug("Error when validate csar with ID {}, error: {}", csarUUID, responseFormat);
285 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
286 return Either.right(responseFormat);
288 Either<ImmutablePair<String, String>, ResponseFormat> toscaYamlCsarStatus = CsarValidationUtils.getToscaYaml(csar, csarUUID, componentsUtils, auditingAction);
289 if (toscaYamlCsarStatus.isRight()) {
290 ResponseFormat responseFormat = toscaYamlCsarStatus.right().value();
291 log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
292 BeEcompErrorManager.getInstance().logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
293 return Either.right(responseFormat);
295 return toscaYamlCsarStatus;