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