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