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