Improve test coverage
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / csar / CsarBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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  * ================================================================================
21  */
22 package org.openecomp.sdc.be.components.csar;
23
24 import fj.data.Either;
25 import org.apache.commons.lang3.tuple.ImmutablePair;
26 import org.openecomp.sdc.be.components.impl.BaseBusinessLogic;
27 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
28 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
29 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
30 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
31 import org.openecomp.sdc.be.config.BeEcompErrorManager;
32 import org.openecomp.sdc.be.dao.api.ActionStatus;
33 import org.openecomp.sdc.be.model.Component;
34 import org.openecomp.sdc.be.model.NodeTypeInfo;
35 import org.openecomp.sdc.be.model.ParsedToscaYamlInfo;
36 import org.openecomp.sdc.be.model.Resource;
37 import org.openecomp.sdc.be.model.Service;
38 import org.openecomp.sdc.be.model.User;
39 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
41 import org.openecomp.sdc.be.model.operations.StorageException;
42 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
43 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
44 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
45 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
46 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
47 import org.openecomp.sdc.be.model.operations.impl.CsarOperation;
48 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
49 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
50 import org.openecomp.sdc.common.log.wrappers.Logger;
51 import org.openecomp.sdc.exception.ResponseFormat;
52 import org.springframework.beans.factory.annotation.Autowired;
53
54 import java.util.Map;
55
56 @org.springframework.stereotype.Component("csarBusinessLogic")
57 public class CsarBusinessLogic extends BaseBusinessLogic {
58
59     private static final Logger log = Logger.getLogger(CsarBusinessLogic.class);
60
61     private static final String CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID = "Creating resource from CSAR: fetching CSAR with id ";
62     private static final String FAILED = " failed";
63
64     private final YamlTemplateParsingHandler yamlHandler;
65     private CsarOperation csarOperation;
66
67     @Autowired
68     public CsarBusinessLogic(IElementOperation elementDao,
69         IGroupOperation groupOperation,
70         IGroupInstanceOperation groupInstanceOperation,
71         IGroupTypeOperation groupTypeOperation,
72         GroupBusinessLogic groupBusinessLogic,
73         InterfaceOperation interfaceOperation,
74         InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
75         YamlTemplateParsingHandler yamlHandler,
76         ArtifactsOperations artifactToscaOperation) {
77         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
78             interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
79         this.yamlHandler = yamlHandler;
80     }
81
82     @Autowired
83     public void setCsarOperation(CsarOperation csarOperation) {
84         this.csarOperation = csarOperation;
85     }
86
87     public void validateCsarBeforeCreate(Resource resource, AuditingActionEnum auditingAction, User user, String csarUUID) {
88         // check if VF with the same Csar UUID or with he same name already
89         // exists
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 ",
93                     resource.getSystemName(), csarUUID);
94             auditAndThrowException(resource, user, auditingAction, ActionStatus.VSP_ALREADY_EXISTS,
95                     csarUUID);
96         } else if (status != StorageOperationStatus.OK) {
97             log.debug("Failed to validate uniqueness of CsarUUID {} for resource", csarUUID,
98                     resource.getSystemName());
99             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
100         }
101     }
102
103     public void validateCsarBeforeCreate(Service resource, String csarUUID) {
104         // check if VF with the same Csar UUID or with he same name already
105         // exists
106         StorageOperationStatus status = toscaOperationFacade.validateCsarUuidUniqueness(csarUUID);
107         log.debug("enter validateCsarBeforeCreate,get status:{}", status);
108         if (status == StorageOperationStatus.ENTITY_ALREADY_EXISTS) {
109             log.debug("Failed to create resource {}, csarUUID {} already exist for a different VF ",
110                     resource.getSystemName(), csarUUID);
111         } else if (status != StorageOperationStatus.OK) {
112             log.debug("Failed to validate uniqueness of CsarUUID {} for resource", csarUUID,
113                     resource.getSystemName());
114             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
115         }
116     }
117
118     public CsarInfo getCsarInfo(Resource resource, Resource oldResource,User user, Map<String, byte[]> payload, String csarUUID){
119         Map<String, byte[]> csar = getCsar(resource, user, payload, csarUUID);
120         ImmutablePair<String, String> toscaYamlCsarStatus = validateAndParseCsar(resource,
121                 user, csar, csarUUID)
122                 .left().on(this::throwComponentException);
123
124         String checksum = CsarValidationUtils.getToscaYamlChecksum(csar,
125                 csarUUID, componentsUtils).left().on(r->logAndThrowComponentException(r, "Failed to calculate checksum for casrUUID {} error {} ", csarUUID));
126         if (oldResource!=null && !checksum.equals(
127                 oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum())) {
128             log.debug("The checksum of main template yaml of csar with csarUUID {} is not equal to the previous one, existing checksum is {}, new one is {}.", csarUUID,
129                     oldResource.getComponentMetadataDefinition().getMetadataDataDefinition()
130                             .getImportedToscaChecksum(),
131                     checksum);
132             oldResource.getComponentMetadataDefinition().getMetadataDataDefinition()
133                     .setImportedToscaChecksum(checksum);
134         }
135
136         return new CsarInfo(user, csarUUID, csar, resource.getName(),
137                 toscaYamlCsarStatus.getKey(), toscaYamlCsarStatus.getValue(), true);
138     }
139
140     public CsarInfo getCsarInfo(Service service, Service oldResource,User user, Map<String, byte[]> payload, String csarUUID){
141         Map<String, byte[]> csar = getCsar(service, user, payload, csarUUID);
142         ImmutablePair<String, String> toscaYamlCsarStatus = validateAndParseCsar(service,
143                 user, csar, csarUUID)
144                                                                     .left().on(this::throwComponentException);
145
146         String checksum = CsarValidationUtils.getToscaYamlChecksum(csar,
147                 csarUUID, componentsUtils).left().on(r->logAndThrowComponentException(r, "Failed to calculate checksum for casrUUID {} error {} ", csarUUID));
148         if (oldResource!=null && !checksum.equals(
149                 oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum())) {
150             log.debug("The checksum of main template yaml of csar with csarUUID {} is not equal to the previous one, existing checksum is {}, new one is {}.", csarUUID,
151                     oldResource.getComponentMetadataDefinition().getMetadataDataDefinition()
152                             .getImportedToscaChecksum(),
153                     checksum);
154             oldResource.getComponentMetadataDefinition().getMetadataDataDefinition()
155                     .setImportedToscaChecksum(checksum);
156         }
157
158         return new CsarInfo(user, csarUUID, csar, service.getName(),
159                 toscaYamlCsarStatus.getKey(), toscaYamlCsarStatus.getValue(), true);
160     }
161         
162     public ParsedToscaYamlInfo getParsedToscaYamlInfo(String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo, String nodeName, Component component) {
163         return yamlHandler.parseResourceInfoFromYAML(
164                 yamlName, topologyTemplateYaml, csarInfo.getCreatedNodesToscaResourceNames(), nodeTypesInfo,
165                 nodeName, component);
166     }
167
168     private String logAndThrowComponentException(ResponseFormat responseFormat, String logMessage, String ...params) {
169         log.debug(logMessage, params, responseFormat);
170         throw new ByResponseFormatComponentException(responseFormat);
171     }
172
173     private ImmutablePair<String,String> throwComponentException(ResponseFormat responseFormat) {
174         throw new ByResponseFormatComponentException(responseFormat);
175     }
176
177     private Either<ImmutablePair<String, String>, ResponseFormat> validateAndParseCsar(Component component, User user,
178                                                                                       Map<String, byte[]> payload, String csarUUID) {
179         Map<String, byte[]> csar = getCsar(component, user, payload, csarUUID);
180         Either<Boolean, ResponseFormat> validateCsarStatus = CsarValidationUtils.validateCsar(csar,
181                 csarUUID, componentsUtils);
182         if (validateCsarStatus.isRight()) {
183             ResponseFormat responseFormat = validateCsarStatus.right().value();
184             log.debug("Error when validate csar with ID {}, error: {}", csarUUID, responseFormat);
185             BeEcompErrorManager.getInstance()
186                     .logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
187             if(component instanceof Resource){
188                 componentsUtils.auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.CREATE_RESOURCE);
189             }
190
191             return Either.right(responseFormat);
192         }
193
194         Either<ImmutablePair<String, String>, ResponseFormat> toscaYamlCsarStatus = CsarValidationUtils
195                 .getToscaYaml(csar, csarUUID, componentsUtils);
196
197         if (toscaYamlCsarStatus.isRight()) {
198             ResponseFormat responseFormat = toscaYamlCsarStatus.right().value();
199             log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
200             BeEcompErrorManager.getInstance()
201                     .logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
202             if(component instanceof Resource) {
203                 componentsUtils.auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.CREATE_RESOURCE);
204             }
205             return Either.right(responseFormat);
206         }
207         return toscaYamlCsarStatus;
208     }
209
210     private Map<String, byte[]> getCsar(Component component, User user, Map<String, byte[]> payload, String csarUUID) {
211         if (payload != null) {
212             return payload;
213         }
214         Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.getCsar(csarUUID, user);
215         if (csar.isRight()) {
216             StorageOperationStatus value = csar.right().value();
217             log.debug("#getCsar - failed to fetch csar with ID {}, error: {}", csarUUID, value);
218             BeEcompErrorManager.getInstance()
219                     .logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
220             ResponseFormat responseFormat = componentsUtils
221                     .getResponseFormat(componentsUtils.convertFromStorageResponse(value), csarUUID);
222             if(component instanceof Resource){
223                 Resource newResource = (Resource) component;
224                 componentsUtils.auditResource(responseFormat, user, newResource, AuditingActionEnum.CREATE_RESOURCE);
225             }
226
227             throw new StorageException(csar.right().value());
228         }
229         return csar.left().value();
230     }
231
232     private void auditAndThrowException(Resource resource, User user, AuditingActionEnum auditingAction, ActionStatus status, String... params){
233         ResponseFormat errorResponse = componentsUtils.getResponseFormat(status, params);
234         componentsUtils.auditResource(errorResponse, user, resource, auditingAction);
235         throw new ByResponseFormatComponentException(errorResponse, params);
236     }
237
238     private Either<ImmutablePair<String, String>, ResponseFormat> validateAndParseCsar(Service service, User user,
239         Map<String, byte[]> payload, String csarUUID) {
240         Map<String, byte[]> csar = getCsar(service, user, payload, csarUUID);
241         Either<Boolean, ResponseFormat> validateCsarStatus = CsarValidationUtils.validateCsar(csar,
242             csarUUID, componentsUtils);
243         if (validateCsarStatus.isRight()) {
244             ResponseFormat responseFormat = validateCsarStatus.right().value();
245             log.debug("Error when validate csar with ID {}, error: {}", csarUUID, responseFormat);
246             BeEcompErrorManager.getInstance()
247                 .logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
248
249             return Either.right(responseFormat);
250         }
251
252         Either<ImmutablePair<String, String>, ResponseFormat> toscaYamlCsarStatus = CsarValidationUtils
253             .getToscaYaml(csar, csarUUID, componentsUtils);
254
255         if (toscaYamlCsarStatus.isRight()) {
256             ResponseFormat responseFormat = toscaYamlCsarStatus.right().value();
257             log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
258             BeEcompErrorManager.getInstance()
259                 .logBeDaoSystemError(CREATING_RESOURCE_FROM_CSAR_FETCHING_CSAR_WITH_ID + csarUUID + FAILED);
260             return Either.right(responseFormat);
261         }
262         return toscaYamlCsarStatus;
263     }
264 }