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