Fix sonarqube issues introduced by ZipSlip change
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / AbstractValidationsServlet.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
23 package org.openecomp.sdc.be.servlets;
24
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import com.google.gson.Gson;
27 import com.google.gson.JsonSyntaxException;
28 import fj.data.Either;
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.lang.reflect.Type;
34 import java.nio.charset.StandardCharsets;
35 import java.util.Arrays;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.function.Supplier;
40 import javax.servlet.ServletContext;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.ws.rs.core.Response;
43 import org.apache.commons.codec.binary.Base64;
44 import org.apache.commons.collections4.MapUtils;
45 import org.apache.commons.io.IOUtils;
46 import org.apache.commons.lang3.StringUtils;
47 import org.apache.commons.lang3.tuple.ImmutablePair;
48 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
49 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
50 import org.openecomp.sdc.be.components.impl.ImportUtils;
51 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
52 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
53 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
54 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
55 import org.openecomp.sdc.be.config.BeEcompErrorManager;
56 import org.openecomp.sdc.be.dao.api.ActionStatus;
57 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
58 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
59 import org.openecomp.sdc.be.impl.ComponentsUtils;
60 import org.openecomp.sdc.be.impl.ServletUtils;
61 import org.openecomp.sdc.be.model.ArtifactDefinition;
62 import org.openecomp.sdc.be.model.Resource;
63 import org.openecomp.sdc.be.model.UploadResourceInfo;
64 import org.openecomp.sdc.be.model.User;
65 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
66 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
67 import org.openecomp.sdc.be.user.IUserBusinessLogic;
68 import org.openecomp.sdc.be.user.Role;
69 import org.openecomp.sdc.be.user.UserBusinessLogic;
70 import org.openecomp.sdc.be.utils.TypeUtils;
71 import org.openecomp.sdc.common.api.Constants;
72 import org.openecomp.sdc.common.api.UploadArtifactInfo;
73 import org.openecomp.sdc.common.datastructure.Wrapper;
74 import org.openecomp.sdc.common.log.wrappers.Logger;
75 import org.openecomp.sdc.common.util.GeneralUtility;
76 import org.openecomp.sdc.common.util.YamlToObjectConverter;
77 import org.openecomp.sdc.common.zip.ZipUtils;
78 import org.openecomp.sdc.common.zip.exception.ZipException;
79 import org.openecomp.sdc.exception.ResponseFormat;
80 import org.yaml.snakeyaml.Yaml;
81
82 public abstract class AbstractValidationsServlet extends BeGenericServlet {
83
84     private static final Logger log = Logger.getLogger(AbstractValidationsServlet.class);
85     private static final String TOSCA_SIMPLE_YAML_PREFIX = "tosca_simple_yaml_";
86     private static final List<String> TOSCA_DEFINITION_VERSIONS = Arrays.asList(TOSCA_SIMPLE_YAML_PREFIX + "1_0_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1_0", "tosca_simple_profile_for_nfv_1_0_0", TOSCA_SIMPLE_YAML_PREFIX + "1_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1");
87     private static final List<String> TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(".yml", ".yaml", ".csar");
88
89     protected ServletUtils servletUtils;
90     protected ResourceImportManager resourceImportManager;
91     protected final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
92
93
94     public AbstractValidationsServlet(UserBusinessLogic userBusinessLogic,
95         ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils,
96         ServletUtils servletUtils, ResourceImportManager resourceImportManager) {
97         super(userBusinessLogic, componentsUtils);
98         this.servletUtils = servletUtils;
99         this.resourceImportManager = resourceImportManager;
100         this.componentInstanceBusinessLogic = componentInstanceBL;
101     }
102
103     protected void init() {
104     }
105
106     protected void validateResourceDoesNotExist(Wrapper<Response> responseWrapper, User user, String resourceName) {
107         if (resourceImportManager.isResourceExist(resourceName)) {
108             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
109             Response errorResponse = buildErrorResponse(responseFormat);
110             getComponentsUtils().auditResource(responseFormat, user, resourceName, AuditingActionEnum.IMPORT_RESOURCE);
111             responseWrapper.setInnerElement(errorResponse);
112         }
113     }
114
115     protected void validateUserExist(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, String userUserId) {
116         log.debug("get user {} from DB", userUserId);
117         // get user details
118         if (userUserId == null) {
119             log.info("user userId is null");
120             Response response = returnMissingInformation(new User());
121             responseWrapper.setInnerElement(response);
122         }
123
124         else {
125             IUserBusinessLogic userAdmin = getServletUtils().getUserAdmin();
126             Either<User, ActionStatus> eitherCreator = userAdmin.getUser(userUserId, false);
127             if (eitherCreator.isRight()) {
128                 log.info("user is not listed. userId={}", userUserId);
129                 User user = new User();
130                 user.setUserId(userUserId);
131                 Response response = returnMissingInformation(user);
132                 responseWrapper.setInnerElement(response);
133             } else {
134                 userWrapper.setInnerElement(eitherCreator.left().value());
135             }
136         }
137     }
138
139     protected Response returnMissingInformation(User user) {
140         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION);
141         getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
142         return buildErrorResponse(responseFormat);
143     }
144
145     protected void validateDataNotNull(Wrapper<Response> responseWrapper, Object... dataParams) {
146         for (Object dataElement : dataParams) {
147             if (dataElement == null) {
148                 log.info("Invalid body was received.");
149                 Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
150                 responseWrapper.setInnerElement(response);
151                 break;
152             }
153         }
154
155     }
156
157     protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user) {
158         log.debug("validate user role");
159         if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) {
160             log.info("user is not in appropriate role to perform action");
161             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
162             log.debug("audit before sending response");
163             getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
164
165             Response response = buildErrorResponse(responseFormat);
166             errorResponseWrapper.setInnerElement(response);
167         }
168
169     }
170
171     protected void validateZip(final Wrapper<Response> responseWrapper, final File zipFile, final String payloadName) {
172         if (StringUtils.isEmpty(payloadName)) {
173             log.info("Invalid JSON was received. Payload name is empty");
174             final Response errorResponse =
175                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
176             responseWrapper.setInnerElement(errorResponse);
177             return;
178         }
179         final Map<String, byte[]> unzippedFolder;
180         try {
181             unzippedFolder = ZipUtils.readZip(zipFile, false);
182         } catch (final ZipException e) {
183             log.error("Could not read ZIP file '{}' for validation", zipFile.getName(), e);
184             final Response errorResponse =
185                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
186             responseWrapper.setInnerElement(errorResponse);
187             return;
188         }
189         if (!unzippedFolder.containsKey(payloadName)) {
190             log.info("Could no find payload '{}' in ZIP file '{}'", payloadName, zipFile.getName());
191             final Response errorResponse =
192                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
193             responseWrapper.setInnerElement(errorResponse);
194         }
195
196
197     }
198
199     protected void validateCsar(final Wrapper<Response> responseWrapper, final File csarFile, final String payloadName) {
200         if (StringUtils.isEmpty(payloadName)) {
201             log.info("Invalid JSON was received. Payload name is empty");
202             Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
203             responseWrapper.setInnerElement(errorResponse);
204             return;
205         }
206         final Map<String, byte[]> unzippedFolder;
207         try {
208             unzippedFolder = ZipUtils.readZip(csarFile, false);
209         } catch (final ZipException e) {
210             log.error("Could not read CSAR file '{}' for validation", csarFile.getName(), e);
211             final Response errorResponse =
212                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
213             responseWrapper.setInnerElement(errorResponse);
214             return;
215         }
216         if (unzippedFolder.isEmpty()) {
217             log.info("The CSAR file is empty");
218             Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
219             responseWrapper.setInnerElement(errorResponse);
220         }
221
222     }
223
224     protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
225         extractZipContents(yamlStringWrapper, file);
226     }
227
228     public static void extractZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
229         final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
230         String ymlName = unzippedFolder.keySet().iterator().next();
231         fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file);
232     }
233
234     private static void fillToscaTemplateFromZip(final Wrapper<String> yamlStringWrapper, final String payloadName,
235                                                  final File file) throws ZipException {
236         final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
237         final byte[] yamlFileInBytes = unzippedFolder.get(payloadName);
238         final String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8);
239         log.debug("received yaml: {}", yamlAsString);
240         yamlStringWrapper.setInnerElement(yamlAsString);
241     }
242
243     protected void fillPayloadDataFromFile(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfoWrapper, File file)  {
244         try(InputStream fileInputStream = new FileInputStream(file)){
245
246             byte [] data = new byte[(int)file.length()];
247             if( fileInputStream.read(data) == -1){
248                 log.info("Invalid json was received.");
249                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
250
251                 Response errorResp = buildErrorResponse(responseFormat);
252                 responseWrapper.setInnerElement(errorResp);
253             }
254             String payloadData =  Base64.encodeBase64String(data);
255             uploadResourceInfoWrapper.setPayloadData(payloadData);
256
257
258
259         } catch (IOException e) {
260             log.info("Invalid json was received or Error while closing input Stream.");
261             log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
262             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
263
264             Response errorResp = buildErrorResponse(responseFormat);
265             responseWrapper.setInnerElement(errorResp);
266
267         }
268     }
269
270     protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) {
271         log.debug("validate user role");
272         if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
273             if (!user.getRole().equals(Role.ADMIN.name())) {
274                 log.info("user is not in appropriate role to perform action");
275                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
276                 log.debug("audit before sending response");
277                 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
278
279                 Response response = buildErrorResponse(responseFormat);
280                 errorResponseWrapper.setInnerElement(response);
281             }
282         } else {
283             validateUserRole(errorResponseWrapper, user);
284         }
285
286     }
287
288     protected void validateAndFillResourceJson(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, User user, ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) {
289         boolean isValid;
290         try {
291             log.debug("The received json is {}", resourceInfo);
292             UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class);
293             if (resourceInfoObject == null) {
294                 isValid = false;
295             } else {
296                 if (!resourceAuthorityEnum.isBackEndImport()) {
297                     isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty();
298                     //only resource name is checked
299                 } else {
300                     isValid = true;
301                 }
302                 uploadResourceInfoWrapper.setInnerElement(resourceInfoObject);
303             }
304
305         } catch (JsonSyntaxException e) {
306             log.debug("Invalid json was received. {}", e.getMessage(), e);
307             isValid = false;
308
309         }
310         if (!isValid) {
311             log.info("Invalid json was received.");
312             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
313             getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
314             Response errorResp = buildErrorResponse(responseFormat);
315             responseWrapper.setInnerElement(errorResp);
316         }
317     }
318
319     protected void validateAuthorityType(Wrapper<Response> responseWrapper, String authorityType) {
320         log.debug("The received authority type is {}", authorityType);
321         ResourceAuthorityTypeEnum authorityTypeEnum = ResourceAuthorityTypeEnum.findByUrlPath(authorityType);
322         if (authorityTypeEnum == null) {
323             log.info("Invalid authority type was received.");
324             Response errorResp = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
325             responseWrapper.setInnerElement(errorResp);
326         }
327     }
328
329     public ServletUtils getServletUtils() {
330         return servletUtils;
331     }
332
333     public Gson getGson() {
334         return getServletUtils().getGson();
335     }
336
337     public ComponentsUtils getComponentsUtils() {
338         return getServletUtils().getComponentsUtils();
339     }
340
341     protected void validatePayloadIsTosca(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
342         log.debug("checking payload is valid tosca");
343         boolean isValid;
344         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
345         Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
346
347         if (findFirstToscaStringElement.isRight()) {
348             isValid = false;
349         } else {
350             String defenitionVersionFound = findFirstToscaStringElement.left().value();
351             if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
352                 isValid = false;
353             } else {
354                 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
355             }
356         }
357
358         if (!isValid) {
359             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
360             Response errorResponse = buildErrorResponse(responseFormat);
361              getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
362             responseWrapper.setInnerElement(errorResponse);
363         }
364
365     }
366
367     protected void validatePayloadIsYml(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaTamplatePayload) {
368         log.debug("checking tosca template is valid yml");
369         YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
370         boolean isYamlValid = yamlConvertor.isValidYaml(toscaTamplatePayload.getBytes());
371         if (!isYamlValid) {
372             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
373             Response errorResponse = buildErrorResponse(responseFormat);
374              getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
375             responseWrapper.setInnerElement(errorResponse);
376         }
377     }
378
379     protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, String toscaPayload) {
380         boolean isValid;
381         String nameSpace = "";
382         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
383         Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
384         if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
385             isValid = false;
386         } else {
387             nameSpace = toscaElement.left().value().keySet().iterator().next();
388             isValid = nameSpace.startsWith(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX);
389         }
390         if (!isValid) {
391             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE);
392             Response errorResponse = buildErrorResponse(responseFormat);
393              getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
394             responseWrapper.setInnerElement(errorResponse);
395         } else {
396             String str1 = nameSpace.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length());
397             String[] findTypes = str1.split("\\.");
398             if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) {
399                 String type = findTypes[0].toUpperCase();
400                 resourceInfo.setResourceType(type);
401             } else {
402                 resourceInfo.setResourceType(ResourceTypeEnum.VFC.name());
403             }
404         }
405
406     }
407
408     protected void validatePayloadIsSingleResource(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
409         log.debug("checking payload contains single resource");
410         boolean isValid;
411         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
412         Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
413         if (toscaElement.isRight()) {
414             isValid = false;
415         } else {
416             isValid = toscaElement.left().value().size() == 1;
417         }
418
419         if (!isValid) {
420             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_SINGLE_RESOURCE);
421             Response errorResponse = buildErrorResponse(responseFormat);
422              getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
423             responseWrapper.setInnerElement(errorResponse);
424         }
425
426     }
427
428     protected void validatePayloadIsNotService(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaPayload) {
429         log.debug("checking payload is not a tosca service");
430         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
431         Either<Object, ResultStatusEnum> toscaElement = ImportUtils.findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL);
432
433         if (toscaElement.isLeft()) {
434             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE);
435             Response errorResponse = buildErrorResponse(responseFormat);
436             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
437             responseWrapper.setInnerElement(errorResponse);
438         }
439
440     }
441
442     protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
443         String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName();
444         boolean isValidSuffix = false;
445         if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) {
446             for (String validSuffix : TOSCA_YML_CSAR_VALID_SUFFIX) {
447                 isValidSuffix = isValidSuffix || toscaTemplatePayloadName.toLowerCase().endsWith(validSuffix);
448             }
449         }
450         if (!isValidSuffix) {
451             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
452             Response errorResponse = buildErrorResponse(responseFormat);
453             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
454             responseWrapper.setInnerElement(errorResponse);
455         }
456
457     }
458
459     protected void validateMD5(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request, String resourceInfoJsonString) {
460         boolean isValid;
461         String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
462         if (recievedMD5 == null) {
463             isValid = false;
464         } else {
465             String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(resourceInfoJsonString);
466             isValid = calculateMD5.equals(recievedMD5);
467         }
468         if (!isValid) {
469             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM);
470             Response errorResponse = buildErrorResponse(responseFormat);
471             getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
472             responseWrapper.setInnerElement(errorResponse);
473         }
474     }
475
476     protected void validateComponentType(Wrapper<Response> responseWrapper, Wrapper<ComponentTypeEnum> componentTypeWrapper, String componentType) {
477         boolean isValid;
478         if (componentType == null) {
479             isValid = false;
480         } else {
481             if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) {
482                 isValid = true;
483                 componentTypeWrapper.setInnerElement(ComponentTypeEnum.RESOURCE);
484             } else if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) {
485                 isValid = true;
486                 componentTypeWrapper.setInnerElement(ComponentTypeEnum.SERVICE);
487             } else {
488                 isValid = false;
489             }
490         }
491         if (!isValid) {
492             log.debug("Invalid componentType:{}", componentType);
493             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType)));
494         }
495     }
496
497     protected Either<ComponentTypeEnum, ResponseFormat> convertToComponentType(String componentType) {
498         Wrapper<Response> errorWrapper = new Wrapper<>();
499         Wrapper<ComponentTypeEnum> componentWrapper = new Wrapper<>();
500         validateComponentType(errorWrapper, componentWrapper, componentType);
501         return errorWrapper.isEmpty() ? Either.left(componentWrapper.getInnerElement()) : Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
502     }
503
504     protected void fillToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo resourceInfo) {
505         if (resourceInfo.getPayloadData() == null || resourceInfo.getPayloadData().isEmpty()) {
506             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
507             Response errorResponse = buildErrorResponse(responseFormat);
508             getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
509             responseWrapper.setInnerElement(errorResponse);
510         } else {
511             String toscaPayload = resourceInfo.getPayloadData();
512             String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
513             yamlStringWrapper.setInnerElement(decodedPayload);
514         }
515
516     }
517
518     protected void fillPayload(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, String resourceInfoJsonString, ResourceAuthorityTypeEnum resourceAuthorityEnum,
519             File file) throws ZipException {
520
521         if (responseWrapper.isEmpty()) {
522             if (resourceAuthorityEnum.isBackEndImport()) {
523                 // PrePayload Validations
524                 if (responseWrapper.isEmpty()) {
525                     validateDataNotNull(responseWrapper, file, resourceInfoJsonString);
526                 }
527                 if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){
528                     if (responseWrapper.isEmpty()) {
529                         validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
530                     }
531
532                     // Fill PayLoad From File
533                     if (responseWrapper.isEmpty()) {
534                         fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file);
535                     }
536                 }else{
537
538                     if (responseWrapper.isEmpty()) {
539                         validateCsar(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
540                     }
541
542                     // Fill PayLoad From File
543                     if (responseWrapper.isEmpty()) {
544                         fillPayloadDataFromFile(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), file);
545                     }
546
547                 }
548
549             } else {
550                 // Fill PayLoad From JSON
551                 if (responseWrapper.isEmpty()) {
552                     fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement());
553                 }
554             }
555
556         }
557
558     }
559
560     protected void specificResourceAuthorityValidations(final Wrapper<Response> responseWrapper,
561                                                         final Wrapper<UploadResourceInfo> uploadResourceInfoWrapper,
562                                                         final Wrapper<String> yamlStringWrapper, final User user,
563                                                         final HttpServletRequest request, final String resourceInfoJsonString,
564                                                         final ResourceAuthorityTypeEnum resourceAuthorityEnum) {
565
566         if (responseWrapper.isEmpty()) {
567             // UI Only Validation
568             if (!resourceAuthorityEnum.isBackEndImport()) {
569                 importUIValidations(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, request, resourceInfoJsonString);
570             }
571
572             // User Defined Type Resources
573             if (resourceAuthorityEnum.isUserTypeResource() && !CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
574                 if (responseWrapper.isEmpty()) {
575                     validatePayloadNameSpace(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement());
576                 }
577
578             }
579         }
580     }
581
582     protected void commonGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, ResourceAuthorityTypeEnum resourceAuthorityEnum, String userUserId,
583             String resourceInfoJsonString) {
584
585         if (responseWrapper.isEmpty()) {
586             validateUserExist(responseWrapper, userWrapper, userUserId);
587         }
588
589         if (responseWrapper.isEmpty()) {
590             validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum);
591         }
592
593         if (responseWrapper.isEmpty()) {
594             validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum, resourceInfoJsonString);
595         }
596
597         if (responseWrapper.isEmpty()) {
598             validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
599         }
600         if (responseWrapper.isEmpty()) {
601             validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
602         }
603
604     }
605
606     private void validateResourceType(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
607         String resourceType = uploadResourceInfo.getResourceType();
608         if (resourceType == null || !ResourceTypeEnum.containsName(resourceType)) {
609             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
610             Response errorResponse = buildErrorResponse(responseFormat);
611             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
612             responseWrapper.setInnerElement(errorResponse);
613         }
614     }
615
616     protected void importUIValidations(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, HttpServletRequest request, String resourceInfoJsonString) {
617         if (responseWrapper.isEmpty()) {
618             validateMD5(responseWrapper, user, resourceInfo, request, resourceInfoJsonString);
619         }
620         if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
621             validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName());
622         }
623     }
624
625     protected void commonPayloadValidations(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) {
626
627         if (responseWrapper.isEmpty()) {
628             validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
629         }
630         if (responseWrapper.isEmpty()) {
631             validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
632         }
633         if (responseWrapper.isEmpty()) {
634             validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
635         }
636         if (responseWrapper.isEmpty()) {
637             validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
638         }
639     }
640
641
642     protected void handleImport(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfoObject, String yamlAsString, ResourceAuthorityTypeEnum authority, boolean createNewVersion, String resourceUniqueId) {
643         Either<ImmutablePair<Resource, ActionStatus>, ResponseFormat> createOrUpdateResponse = null;
644         Response response = null;
645         Object representation = null;
646         ImmutablePair<Resource, ActionStatus> importedResourceStatus = null;
647         if (CsarValidationUtils.isCsarPayloadName(resourceInfoObject.getPayloadName())) {
648             log.debug("import resource from csar");
649             importedResourceStatus = importResourceFromUICsar(resourceInfoObject, user, resourceUniqueId);
650         } else if (!authority.isUserTypeResource()) {
651             log.debug("import normative type resource");
652             createOrUpdateResponse = resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, user, createNewVersion, true);
653         } else {
654             log.debug("import user resource (not normative type)");
655             createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user,  false);
656         }
657         if (createOrUpdateResponse!= null){
658             if(createOrUpdateResponse.isRight()){
659                 response = buildErrorResponse(createOrUpdateResponse.right().value());
660             }else {
661                 importedResourceStatus = createOrUpdateResponse.left().value();
662             }
663         }
664         if(importedResourceStatus != null){
665             try {
666                 representation = RepresentationUtils.toRepresentation(importedResourceStatus.left);
667             } catch (IOException e) {
668                 log.debug("Error while building resource representation : {}", e.getMessage(), e);
669             }
670             response = buildOkResponse(getComponentsUtils().getResponseFormat(importedResourceStatus.right), representation);
671         }
672         responseWrapper.setInnerElement(response);
673     }
674
675     private ImmutablePair<Resource, ActionStatus> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user, String resourceUniqueId) {
676
677         Resource newResource;
678         ImmutablePair<Resource, ActionStatus> result = null;
679         ActionStatus actionStatus;
680         Resource resource = new Resource();
681         String payloadName = resourceInfoObject.getPayloadName();
682         fillResourceFromResourceInfoObject(resource, resourceInfoObject);
683
684         Either<Map<String, byte[]>, ResponseFormat> csarUIPayloadRes = getCsarFromPayload(resourceInfoObject);
685         if (csarUIPayloadRes.isRight()) {
686             throw new ByResponseFormatComponentException(csarUIPayloadRes.right().value());
687         }
688         Map<String, byte[]> csarUIPayload = csarUIPayloadRes.left().value();
689
690         getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName);
691
692         if (resourceUniqueId == null || resourceUniqueId.isEmpty()) {
693             newResource = resourceImportManager.getResourceBusinessLogic().createResource(resource, AuditingActionEnum.CREATE_RESOURCE, user, csarUIPayload, payloadName);
694             actionStatus = ActionStatus.CREATED;
695         } else {
696             newResource = resourceImportManager.getResourceBusinessLogic().validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId);
697             actionStatus = ActionStatus.OK;
698         }
699         return new ImmutablePair<>(newResource, actionStatus);
700     }
701
702     private Resource throwComponentException(ResponseFormat responseFormat) {
703         throw new ByResponseFormatComponentException(responseFormat);
704     }
705
706     private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Resource resource, User user, String csarUUID) {
707
708         Either<ImmutablePair<String, String>, ResponseFormat> getToscaYamlRes = CsarValidationUtils.getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils());
709
710         if (getToscaYamlRes.isRight()) {
711             ResponseFormat responseFormat = getToscaYamlRes.right().value();
712             log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
713             BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
714             getComponentsUtils().auditResource(responseFormat, user, resource, AuditingActionEnum.CREATE_RESOURCE);
715             throwComponentException(responseFormat);
716         }
717         String toscaYaml = getToscaYamlRes.left().value().getValue();
718
719         log.debug("checking tosca template is valid yml");
720         YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
721         boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes());
722         if (!isValid) {
723             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
724             getComponentsUtils().auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
725             throwComponentException(responseFormat);
726         }
727
728         log.debug("checking payload is valid tosca");
729         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaYaml);
730         Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
731
732         if (findFirstToscaStringElement.isRight()) {
733             isValid = false;
734         } else {
735             String defenitionVersionFound = findFirstToscaStringElement.left().value();
736             if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
737                 isValid = false;
738             } else {
739                 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
740             }
741         }
742
743         if (!isValid) {
744             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
745             getComponentsUtils().auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
746             throwComponentException(responseFormat);
747         }
748     }
749
750     private void fillResourceFromResourceInfoObject(Resource resource, UploadResourceInfo resourceInfoObject) {
751         resourceImportManager.populateResourceMetadata(resourceInfoObject, resource);
752         fillArtifacts(resource, resourceInfoObject);
753
754     }
755
756     private void fillArtifacts(Resource resource, UploadResourceInfo resourceInfoObject) {
757         if (resource != null && resourceInfoObject != null) {
758             List<UploadArtifactInfo> artifactList = resourceInfoObject.getArtifactList();
759             if (artifactList != null) {
760                 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
761                 for (UploadArtifactInfo artifact : artifactList) {
762                     ArtifactDefinition artifactDef = new ArtifactDefinition();
763                     artifactDef.setArtifactName(artifact.getArtifactName());
764                     artifactDef.setArtifactType(artifact.getArtifactType().getType());
765                     artifactDef.setDescription(artifact.getArtifactDescription());
766                     artifactDef.setPayloadData(artifact.getArtifactData());
767                     artifactDef.setArtifactRef(artifact.getArtifactPath());
768                     artifactsHM.put(artifactDef.getArtifactName(), artifactDef);
769                 }
770                 resource.setArtifacts(artifactsHM);
771             }
772         }
773     }
774
775     private Either<Map<String, byte[]>, ResponseFormat> getCsarFromPayload(UploadResourceInfo innerElement) {
776         String csarUUID = innerElement.getPayloadName();
777         String payloadData = innerElement.getPayloadData();
778         if (payloadData == null) {
779             log.info("Failed to decode received csar {}", csarUUID);
780             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID));
781         }
782
783         byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8));
784         if (decodedPayload == null) {
785             log.info("Failed to decode received csar {}", csarUUID);
786             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID));
787         }
788
789         Map<String, byte[]> csar = null;
790         try {
791             csar = ZipUtils.readZip(decodedPayload, false);
792         } catch (final ZipException e) {
793             log.info("Failed to unzip received csar {}", csarUUID, e);
794         }
795         if (MapUtils.isEmpty(csar)) {
796             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID));
797         }
798         return Either.left(csar);
799     }
800
801     protected void validateInputStream(final HttpServletRequest request, Wrapper<String> dataWrapper, Wrapper<ResponseFormat> errorWrapper) throws IOException {
802         InputStream inputStream = request.getInputStream();
803         byte[] bytes = IOUtils.toByteArray(inputStream);
804         if (bytes == null || bytes.length == 0) {
805             log.info("Empty body was sent.");
806             errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
807         } else {
808             dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8));
809         }
810
811     }
812
813     protected <T> void validateClassParse(String data, Wrapper<T> parsedClassWrapper, Supplier<Class<T>> classGen, Wrapper<ResponseFormat> errorWrapper) {
814         try {
815             T parsedClass = gson.fromJson(data, classGen.get());
816             if (parsedClass == null) {
817                 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
818             } else {
819                 parsedClassWrapper.setInnerElement(parsedClass);
820             }
821         } catch (JsonSyntaxException e) {
822             log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e);
823             errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
824         }
825     }
826
827     protected void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType, Wrapper<ComponentInstanceBusinessLogic> blWrapper, Wrapper<ResponseFormat> errorWrapper) {
828         ServletContext context = request.getSession().getServletContext();
829         if (componentInstanceBusinessLogic == null) {
830             log.debug("Unsupported component type {}", containerComponentType);
831             errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
832         } else {
833             blWrapper.setInnerElement(componentInstanceBusinessLogic);
834         }
835     }
836
837     protected <T> Response buildResponseFromElement(Wrapper<ResponseFormat> errorWrapper, Wrapper<T> attributeWrapper) throws IOException {
838         Response response;
839         if (errorWrapper.isEmpty()) {
840             ObjectMapper mapper = new ObjectMapper();
841             String result = mapper.writeValueAsString(attributeWrapper.getInnerElement());
842             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
843         } else {
844             response = buildErrorResponse(errorWrapper.getInnerElement());
845         }
846         return response;
847     }
848
849     protected void validateXECOMPInstanceIDHeader(String instanceIdHeader, Wrapper<ResponseFormat> responseWrapper) {
850         ResponseFormat responseFormat;
851         if(StringUtils.isEmpty(instanceIdHeader) ){
852             log.debug("Missing X-ECOMP-InstanceID header");
853             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
854             responseWrapper.setInnerElement(responseFormat);
855         }
856     }
857
858     protected void validateHttpCspUserIdHeader(String header, Wrapper<ResponseFormat> responseWrapper) {
859         ResponseFormat responseFormat;
860         if( StringUtils.isEmpty(header)){
861             log.debug("MissingUSER_ID");
862             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
863             responseWrapper.setInnerElement(responseFormat);
864         }
865     }
866
867     /**
868      * Convert json to Object object
869      * @param <T>
870      * @param classSupplier
871      * @param json
872      * @return
873      */
874     public <T> Either<T, ResponseFormat> parseToObject(String json, Supplier<Class<T>> classSupplier) {
875
876         try {
877             T object = RepresentationUtils.fromRepresentation(json, classSupplier.get());
878             return Either.left(object);
879         } catch (Exception e) {
880             log.debug("Failed to parse json to {} object", classSupplier.get().getName(), e);
881             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
882             return Either.right(responseFormat);
883         }
884     }
885
886     /**
887      * Convert json to Object object
888      * @param <T>
889      * @param json
890      * @param type
891      * @return
892      */
893     public <T> Either<List<T>, ResponseFormat> parseListOfObjects(String json, Type type) {
894         try {
895             List<T> listOfObjects = gson.fromJson(json, type);
896             return Either.left(listOfObjects);
897         } catch (Exception e) {
898             log.debug("Failed to parse json to {} object", type.getClass().getName(), e);
899             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
900             return Either.right(responseFormat);
901         }
902     }
903 }