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