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