Support for Test Topology Auto Design- Service Import
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / AbstractValidationsServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  * Modifications copyright (c) 2019 Nokia
20  * ================================================================================
21  */
22
23 package org.openecomp.sdc.be.servlets;
24
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import com.google.gson.Gson;
27 import com.google.gson.JsonSyntaxException;
28 import fj.data.Either;
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.FileNotFoundException;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.lang.reflect.Type;
35 import java.nio.charset.StandardCharsets;
36 import java.util.Arrays;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Optional;
41 import java.util.function.Supplier;
42 import javax.servlet.ServletContext;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.ws.rs.core.Response;
45 import org.apache.commons.codec.binary.Base64;
46 import org.apache.commons.collections4.MapUtils;
47 import org.apache.commons.io.IOUtils;
48 import org.apache.commons.lang3.StringUtils;
49 import org.apache.commons.lang3.tuple.ImmutablePair;
50 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
52 import org.openecomp.sdc.be.components.impl.ImportUtils;
53 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
54 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
55 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
56 import org.openecomp.sdc.be.components.impl.ServiceImportManager;
57 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
58 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
59 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
60 import org.openecomp.sdc.be.config.BeEcompErrorManager;
61 import org.openecomp.sdc.be.config.ConfigurationManager;
62 import org.openecomp.sdc.be.dao.api.ActionStatus;
63 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
64 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
65 import org.openecomp.sdc.be.impl.ComponentsUtils;
66 import org.openecomp.sdc.be.impl.ServletUtils;
67 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
68 import org.openecomp.sdc.be.model.ArtifactDefinition;
69 import org.openecomp.sdc.be.model.Component;
70 import org.openecomp.sdc.be.model.Resource;
71 import org.openecomp.sdc.be.model.Service;
72 import org.openecomp.sdc.be.model.UploadResourceInfo;
73 import org.openecomp.sdc.be.model.UploadServiceInfo;
74 import org.openecomp.sdc.be.model.User;
75 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
76 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
77 import org.openecomp.sdc.be.servlets.ServiceUploadServlet.ServiceAuthorityTypeEnum;
78 import org.openecomp.sdc.be.user.Role;
79 import org.openecomp.sdc.be.user.UserBusinessLogic;
80 import org.openecomp.sdc.be.utils.TypeUtils;
81 import org.openecomp.sdc.common.api.Constants;
82 import org.openecomp.sdc.common.api.UploadArtifactInfo;
83 import org.openecomp.sdc.common.datastructure.Wrapper;
84 import org.openecomp.sdc.common.log.wrappers.Logger;
85 import org.openecomp.sdc.common.util.GeneralUtility;
86 import org.openecomp.sdc.common.util.YamlToObjectConverter;
87 import org.openecomp.sdc.common.zip.ZipUtils;
88 import org.openecomp.sdc.common.zip.exception.ZipException;
89 import org.openecomp.sdc.exception.ResponseFormat;
90 import org.springframework.web.context.WebApplicationContext;
91 import org.yaml.snakeyaml.Yaml;
92
93 public abstract class AbstractValidationsServlet extends BeGenericServlet {
94
95     private static final Logger log = Logger.getLogger(AbstractValidationsServlet.class);
96     private static final String TOSCA_SIMPLE_YAML_PREFIX = "tosca_simple_yaml_";
97     private static final List<String> TOSCA_DEFINITION_VERSIONS = Arrays.asList(
98         TOSCA_SIMPLE_YAML_PREFIX + "1_0_0",
99         TOSCA_SIMPLE_YAML_PREFIX + "1_1_0",
100         "tosca_simple_profile_for_nfv_1_0_0",
101         TOSCA_SIMPLE_YAML_PREFIX + "1_0",
102         TOSCA_SIMPLE_YAML_PREFIX + "1_1",
103         TOSCA_SIMPLE_YAML_PREFIX + "1_2",
104         TOSCA_SIMPLE_YAML_PREFIX + "1_3");
105     private static final List<String> TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(".yml", ".yaml", ".csar", ".meta");
106
107     protected ServletUtils servletUtils;
108     protected ResourceImportManager resourceImportManager;
109     protected final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
110
111     protected ServiceImportManager serviceImportManager;
112
113     public AbstractValidationsServlet(UserBusinessLogic userBusinessLogic,
114         ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils,
115         ServletUtils servletUtils, ResourceImportManager resourceImportManager) {
116         super(userBusinessLogic, componentsUtils);
117         this.servletUtils = servletUtils;
118         this.resourceImportManager = resourceImportManager;
119         this.componentInstanceBusinessLogic = componentInstanceBL;
120     }
121
122     protected void init() {
123     }
124
125     protected synchronized void initSpringFromContext() {
126         if (serviceImportManager == null) {
127             ServletContext context = servletRequest.getSession().getServletContext();
128             WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
129                     .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
130             WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
131             serviceImportManager = webApplicationContext.getBean(ServiceImportManager.class);
132         }
133     }
134
135     protected void validateResourceDoesNotExist(Wrapper<Response> responseWrapper, User user, String resourceName) {
136         if (resourceImportManager.isResourceExist(resourceName)) {
137             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
138             Response errorResponse = buildErrorResponse(responseFormat);
139             getComponentsUtils().auditResource(responseFormat, user, resourceName, AuditingActionEnum.IMPORT_RESOURCE);
140             responseWrapper.setInnerElement(errorResponse);
141         }
142     }
143
144     protected void validateUserExist(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, String userUserId) {
145         log.debug("get user {} from DB", userUserId);
146         // get user details
147         if (userUserId == null) {
148             log.info("user userId is null");
149             Response response = returnMissingInformation(new User());
150             responseWrapper.setInnerElement(response);
151         }
152
153         else {
154             UserBusinessLogic userAdmin = getServletUtils().getUserAdmin();
155             try {
156                 User user = userAdmin.getUser(userUserId);
157                 userWrapper.setInnerElement(user);
158             } catch (ComponentException ce) {
159                 log.info("user is not listed. userId={}", userUserId);
160                 User user = new User();
161                 user.setUserId(userUserId);
162                 Response response = returnMissingInformation(user);
163                 responseWrapper.setInnerElement(response);
164             }
165         }
166     }
167
168     protected Response returnMissingInformation(User user) {
169         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION);
170         getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
171         return buildErrorResponse(responseFormat);
172     }
173
174     protected void validateDataNotNull(Wrapper<Response> responseWrapper, Object... dataParams) {
175         for (Object dataElement : dataParams) {
176             if (dataElement == null) {
177                 log.info("Invalid body was received.");
178                 Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
179                 responseWrapper.setInnerElement(response);
180                 break;
181             }
182         }
183
184     }
185
186     protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user) {
187         log.debug("validate user role");
188         if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) {
189             log.info("user is not in appropriate role to perform action");
190             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
191             log.debug("audit before sending response");
192             getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
193
194             Response response = buildErrorResponse(responseFormat);
195             errorResponseWrapper.setInnerElement(response);
196         }
197
198     }
199
200     protected void validateZip(final Wrapper<Response> responseWrapper, final File zipFile, final String payloadName) {
201         if (StringUtils.isEmpty(payloadName)) {
202             log.info("Invalid JSON was received. Payload name is empty");
203             final Response errorResponse =
204                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
205             responseWrapper.setInnerElement(errorResponse);
206             return;
207         }
208         final Map<String, byte[]> unzippedFolder;
209         try {
210             unzippedFolder = ZipUtils.readZip(zipFile, false);
211         } catch (final ZipException e) {
212             log.error("Could not read ZIP file '{}' for validation", zipFile.getName(), e);
213             final Response errorResponse =
214                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
215             responseWrapper.setInnerElement(errorResponse);
216             return;
217         }
218         if (!unzippedFolder.containsKey(payloadName)) {
219             log.info("Could no find payload '{}' in ZIP file '{}'", payloadName, zipFile.getName());
220             final Response errorResponse =
221                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
222             responseWrapper.setInnerElement(errorResponse);
223         }
224
225
226     }
227
228     protected void validateCsar(final Wrapper<Response> responseWrapper, final File csarFile, final String payloadName) {
229         if (StringUtils.isEmpty(payloadName)) {
230             log.info("Invalid JSON was received. Payload name is empty");
231             Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
232             responseWrapper.setInnerElement(errorResponse);
233             return;
234         }
235         final Map<String, byte[]> unzippedFolder;
236         try {
237             unzippedFolder = ZipUtils.readZip(csarFile, false);
238         } catch (final ZipException e) {
239             log.error("Could not read CSAR file '{}' for validation", csarFile.getName(), e);
240             final Response errorResponse =
241                 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
242             responseWrapper.setInnerElement(errorResponse);
243             return;
244         }
245         if (unzippedFolder.isEmpty()) {
246             log.info("The CSAR file is empty");
247             Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
248             responseWrapper.setInnerElement(errorResponse);
249         }
250
251     }
252
253     protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
254         extractZipContents(yamlStringWrapper, file);
255     }
256
257     public static void extractZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
258         final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
259         String ymlName = unzippedFolder.keySet().iterator().next();
260         fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file);
261     }
262
263     private static void fillToscaTemplateFromZip(final Wrapper<String> yamlStringWrapper, final String payloadName,
264                                                  final File file) throws ZipException {
265         final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
266         final byte[] yamlFileInBytes = unzippedFolder.get(payloadName);
267         final String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8);
268         log.debug("received yaml: {}", yamlAsString);
269         yamlStringWrapper.setInnerElement(yamlAsString);
270     }
271
272     protected void fillPayloadDataFromFile(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfoWrapper, File file)  {
273         try(InputStream fileInputStream = new FileInputStream(file)){
274
275             byte [] data = new byte[(int)file.length()];
276             if( fileInputStream.read(data) == -1){
277                 log.info("Invalid json was received.");
278                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
279
280                 Response errorResp = buildErrorResponse(responseFormat);
281                 responseWrapper.setInnerElement(errorResp);
282             }
283             String payloadData =  Base64.encodeBase64String(data);
284             uploadResourceInfoWrapper.setPayloadData(payloadData);
285
286
287
288         } catch (IOException e) {
289             log.info("Invalid json was received or Error while closing input Stream.");
290             log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
291             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
292
293             Response errorResp = buildErrorResponse(responseFormat);
294             responseWrapper.setInnerElement(errorResp);
295
296         }
297     }
298
299     protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) {
300         log.debug("validate user role");
301         if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
302             if (!user.getRole().equals(Role.ADMIN.name())) {
303                 log.info("user is not in appropriate role to perform action");
304                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
305                 log.debug("audit before sending response");
306                 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
307
308                 Response response = buildErrorResponse(responseFormat);
309                 errorResponseWrapper.setInnerElement(response);
310             }
311         } else {
312             validateUserRole(errorResponseWrapper, user);
313         }
314
315     }
316
317     protected void validateAndFillResourceJson(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, User user, ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) {
318         boolean isValid;
319         try {
320             log.debug("The received json is {}", resourceInfo);
321             UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class);
322             if (resourceInfoObject == null) {
323                 isValid = false;
324             } else {
325                 if (!resourceAuthorityEnum.isBackEndImport()) {
326                     isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty();
327                     //only resource name is checked
328                 } else {
329                     isValid = true;
330                 }
331                 uploadResourceInfoWrapper.setInnerElement(resourceInfoObject);
332             }
333
334         } catch (JsonSyntaxException e) {
335             log.debug("Invalid json was received. {}", e.getMessage(), e);
336             isValid = false;
337
338         }
339         if (!isValid) {
340             log.info("Invalid json was received.");
341             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
342             getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
343             Response errorResp = buildErrorResponse(responseFormat);
344             responseWrapper.setInnerElement(errorResp);
345         }
346     }
347
348     protected void validateAuthorityType(Wrapper<Response> responseWrapper, String authorityType) {
349         log.debug("The received authority type is {}", authorityType);
350         ResourceAuthorityTypeEnum authorityTypeEnum = ResourceAuthorityTypeEnum.findByUrlPath(authorityType);
351         if (authorityTypeEnum == null) {
352             log.info("Invalid authority type was received.");
353             Response errorResp = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
354             responseWrapper.setInnerElement(errorResp);
355         }
356     }
357
358     public ServletUtils getServletUtils() {
359         return servletUtils;
360     }
361
362     public Gson getGson() {
363         return getServletUtils().getGson();
364     }
365
366     public ComponentsUtils getComponentsUtils() {
367         return getServletUtils().getComponentsUtils();
368     }
369
370     protected void validatePayloadIsTosca(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
371         log.debug("checking payload is valid tosca");
372         boolean isValid;
373         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
374         Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
375
376         if (findFirstToscaStringElement.isRight()) {
377             isValid = false;
378         } else {
379             String defenitionVersionFound = findFirstToscaStringElement.left().value();
380             if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
381                 isValid = false;
382             } else {
383                 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
384             }
385         }
386
387         if (!isValid) {
388             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
389             Response errorResponse = buildErrorResponse(responseFormat);
390             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
391             responseWrapper.setInnerElement(errorResponse);
392         }
393
394     }
395
396     protected void validatePayloadIsYml(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaTamplatePayload) {
397         log.debug("checking tosca template is valid yml");
398         YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
399         boolean isYamlValid = yamlConvertor.isValidYaml(toscaTamplatePayload.getBytes());
400         if (!isYamlValid) {
401             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
402             Response errorResponse = buildErrorResponse(responseFormat);
403             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
404             responseWrapper.setInnerElement(errorResponse);
405         }
406     }
407
408     /**
409      * Gets the Resource type from the given node type name.
410      *
411      * @param nodeTypeFullName - Node type Name
412      * @return Resource Type name
413      */
414     private String getResourceType(final String nodeTypeFullName) {
415
416         final Optional<String> nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
417         if (nodeTypeNamePrefix.isPresent()) {
418             final String nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.get().length());
419             final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
420             if (findTypes.length > 0) {
421                 final ResourceTypeEnum resourceType = ResourceTypeEnum.getType(findTypes[0].toUpperCase());
422                 if (resourceType != null) {
423                     return resourceType.name();
424                 }
425             }
426         }
427         return ResourceTypeEnum.VFC.name();
428     }
429
430     /**
431      * Extracts the Node Type Name prefix from the given Node Type Name.
432      * @param nodeName - Node Type Name
433      * @return Node Type Name prefix
434      */
435     private Optional<String> getNodeTypeNamePrefix(final String nodeName) {
436         final List<String> definedNodeTypeNamespaceList = ConfigurationManager.getConfigurationManager()
437             .getConfiguration().getDefinedResourceNamespace();
438         for (final String validNamespace : definedNodeTypeNamespaceList) {
439             if (nodeName.startsWith(validNamespace)) {
440                 return Optional.of(validNamespace);
441             }
442         }
443         return Optional.empty();
444     }
445
446     protected void validatePayloadNameSpace(final Wrapper<Response> responseWrapper,
447                                             final UploadResourceInfo resourceInfo,
448                                             final User user, final String toscaPayload) {
449         boolean isValid;
450         String namespace = "";
451         final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
452         final Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
453         if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
454             isValid = false;
455         } else {
456             namespace = toscaElement.left().value().keySet().iterator().next();
457             isValid = getNodeTypeNamePrefix(namespace).isPresent();
458         }
459         if (!isValid) {
460             final ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE);
461             final Response errorResponse = buildErrorResponse(responseFormat);
462             getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
463             responseWrapper.setInnerElement(errorResponse);
464         } else {
465             resourceInfo.setResourceType(getResourceType(namespace));
466         }
467     }
468
469     private void validatePayloadIsSingleResource(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
470         log.debug("checking payload contains single resource");
471         boolean isValid;
472         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
473         Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
474         if (toscaElement.isRight()) {
475             isValid = false;
476         } else {
477             isValid = toscaElement.left().value().size() == 1;
478         }
479
480         if (!isValid) {
481             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_SINGLE_RESOURCE);
482             Response errorResponse = buildErrorResponse(responseFormat);
483             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
484             responseWrapper.setInnerElement(errorResponse);
485         }
486
487     }
488
489     private void validatePayloadIsNotService(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaPayload) {
490         log.debug("checking payload is not a tosca service");
491         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
492         Either<Object, ResultStatusEnum> toscaElement = ImportUtils.findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL);
493
494         if (toscaElement.isLeft()) {
495             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE);
496             Response errorResponse = buildErrorResponse(responseFormat);
497             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
498             responseWrapper.setInnerElement(errorResponse);
499         }
500
501     }
502
503     private void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
504         String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName();
505         boolean isValidSuffix = isToscaTemplatePayloadNameValid(responseWrapper, toscaTemplatePayloadName);
506         if (!isValidSuffix) {
507             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
508             Response errorResponse = buildErrorResponse(responseFormat);
509             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
510             responseWrapper.setInnerElement(errorResponse);
511         }
512     }
513
514     private boolean isToscaTemplatePayloadNameValid(Wrapper<Response> responseWrapper, String toscaTemplatePayloadName) {
515         boolean isValidSuffix = false;
516         if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) {
517             for (String validSuffix : TOSCA_YML_CSAR_VALID_SUFFIX) {
518                 isValidSuffix = isValidSuffix || toscaTemplatePayloadName.toLowerCase().endsWith(validSuffix);
519             }
520         }
521         return isValidSuffix;
522     }
523
524     private void validateMD5(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request, String resourceInfoJsonString) {
525         boolean isValid;
526         String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
527         if (recievedMD5 == null) {
528             isValid = false;
529         } else {
530             String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(resourceInfoJsonString);
531             isValid = calculateMD5.equals(recievedMD5);
532         }
533         if (!isValid) {
534             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM);
535             Response errorResponse = buildErrorResponse(responseFormat);
536             getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
537             responseWrapper.setInnerElement(errorResponse);
538         }
539     }
540
541     ComponentTypeEnum validateComponentType(String componentType) {
542         if (componentType == null) {
543             throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR);
544         }
545         if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) {
546             return ComponentTypeEnum.RESOURCE;
547         }
548         if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) {
549             return ComponentTypeEnum.SERVICE;
550         }
551         log.debug("Invalid componentType:{}", componentType);
552         throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR, componentType);
553     }
554
555
556     ComponentTypeEnum convertToComponentType(String componentType) {
557         return validateComponentType(componentType);
558     }
559
560     private void fillToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo resourceInfo) {
561         if (resourceInfo.getPayloadData() == null || resourceInfo.getPayloadData().isEmpty()) {
562             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
563             Response errorResponse = buildErrorResponse(responseFormat);
564             getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
565             responseWrapper.setInnerElement(errorResponse);
566         } else {
567             String toscaPayload = resourceInfo.getPayloadData();
568             String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
569             yamlStringWrapper.setInnerElement(decodedPayload);
570         }
571
572     }
573
574     void fillPayload(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, String resourceInfoJsonString, ResourceAuthorityTypeEnum resourceAuthorityEnum,
575             File file) throws ZipException {
576
577         if (responseWrapper.isEmpty()) {
578             if (resourceAuthorityEnum.isBackEndImport()) {
579                 // PrePayload Validations
580                 if (responseWrapper.isEmpty()) {
581                     validateDataNotNull(responseWrapper, file, resourceInfoJsonString);
582                 }
583                 if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){
584                     if (responseWrapper.isEmpty()) {
585                         validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
586                     }
587
588                     // Fill PayLoad From File
589                     if (responseWrapper.isEmpty()) {
590                         fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file);
591                     }
592                 }else{
593
594                     if (responseWrapper.isEmpty()) {
595                         validateCsar(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
596                     }
597
598                     // Fill PayLoad From File
599                     if (responseWrapper.isEmpty()) {
600                         fillPayloadDataFromFile(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), file);
601                     }
602
603                 }
604
605             } else {
606                 // Fill PayLoad From JSON
607                 if (responseWrapper.isEmpty()) {
608                     fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement());
609                 }
610             }
611
612         }
613
614     }
615
616     protected void specificResourceAuthorityValidations(final Wrapper<Response> responseWrapper,
617                                                         final Wrapper<UploadResourceInfo> uploadResourceInfoWrapper,
618                                                         final Wrapper<String> yamlStringWrapper, final User user,
619                                                         final HttpServletRequest request, final String resourceInfoJsonString,
620                                                         final ResourceAuthorityTypeEnum resourceAuthorityEnum) {
621
622         if (responseWrapper.isEmpty()) {
623             // UI Only Validation
624             if (!resourceAuthorityEnum.isBackEndImport()) {
625                 importUIValidations(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, request, resourceInfoJsonString);
626             }
627
628             // User Defined Type Resources
629             if (resourceAuthorityEnum.isUserTypeResource()
630                     && !CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())
631                     && responseWrapper.isEmpty()) {
632                             validatePayloadNameSpace(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement());
633             }
634         }
635     }
636
637     void commonGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, ResourceAuthorityTypeEnum resourceAuthorityEnum, String userId,
638                                   String resourceInfoJsonString) {
639
640         if (responseWrapper.isEmpty()) {
641             validateUserExist(responseWrapper, userWrapper, userId);
642         }
643
644         if (responseWrapper.isEmpty()) {
645             validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum);
646         }
647
648         if (responseWrapper.isEmpty()) {
649             validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum, resourceInfoJsonString);
650         }
651
652         if (responseWrapper.isEmpty()) {
653             validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
654         }
655         if (responseWrapper.isEmpty()) {
656             validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
657         }
658
659     }
660
661     private void validateResourceType(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
662         String resourceType = uploadResourceInfo.getResourceType();
663         if (resourceType == null || !ResourceTypeEnum.containsName(resourceType)) {
664             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
665             Response errorResponse = buildErrorResponse(responseFormat);
666             getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
667             responseWrapper.setInnerElement(errorResponse);
668         }
669     }
670
671     private void importUIValidations(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, HttpServletRequest request, String resourceInfoJsonString) {
672         if (responseWrapper.isEmpty()) {
673             validateMD5(responseWrapper, user, resourceInfo, request, resourceInfoJsonString);
674         }
675         if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
676             validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName());
677         }
678     }
679
680     void commonPayloadValidations(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) {
681
682         if (responseWrapper.isEmpty()) {
683             validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
684         }
685         if (responseWrapper.isEmpty()) {
686             validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
687         }
688         if (responseWrapper.isEmpty()) {
689             validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
690         }
691         if (responseWrapper.isEmpty()) {
692             validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
693         }
694     }
695
696
697     void handleImport(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfoObject, String yamlAsString, ResourceAuthorityTypeEnum authority, boolean createNewVersion, String resourceUniqueId) {
698         ImmutablePair<Resource, ActionStatus> createOrUpdateResponse = null;
699         Response response = null;
700         Object representation = null;
701         ImmutablePair<Resource, ActionStatus> importedResourceStatus = null;
702         if (CsarValidationUtils.isCsarPayloadName(resourceInfoObject.getPayloadName())) {
703             log.debug("import resource from csar");
704             importedResourceStatus = importResourceFromUICsar(resourceInfoObject, user, resourceUniqueId);
705         } else if (!authority.isUserTypeResource()) {
706             log.debug("import normative type resource");
707             createOrUpdateResponse = resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, user, createNewVersion, true);
708         } else {
709             log.debug("import user resource (not normative type)");
710             createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user,  false);
711         }
712         if (createOrUpdateResponse!= null){
713             importedResourceStatus = createOrUpdateResponse;
714         }
715         if(importedResourceStatus != null){
716             try {
717                 representation = RepresentationUtils.toRepresentation(importedResourceStatus.left);
718             } catch (IOException e) {
719                 log.debug("Error while building resource representation : {}", e.getMessage(), e);
720             }
721             response = buildOkResponse(getComponentsUtils().getResponseFormat(importedResourceStatus.right), representation);
722         }
723         responseWrapper.setInnerElement(response);
724     }
725
726     private ImmutablePair<Resource, ActionStatus> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user, String resourceUniqueId) {
727
728         Resource newResource;
729         ActionStatus actionStatus;
730         Resource resource = new Resource();
731         String payloadName = resourceInfoObject.getPayloadName();
732         fillResourceFromResourceInfoObject(resource, resourceInfoObject);
733
734         Map<String, byte[]> csarUIPayload = getCsarFromPayload(resourceInfoObject);
735         getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName);
736
737         if (resourceUniqueId == null || resourceUniqueId.isEmpty()) {
738             newResource = resourceImportManager.getResourceBusinessLogic().createResource(resource, AuditingActionEnum.CREATE_RESOURCE, user, csarUIPayload, payloadName);
739             actionStatus = ActionStatus.CREATED;
740         } else {
741             newResource = resourceImportManager.getResourceBusinessLogic().validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId);
742             actionStatus = ActionStatus.OK;
743         }
744         return new ImmutablePair<>(newResource, actionStatus);
745     }
746
747     protected Resource throwComponentException(ResponseFormat responseFormat) {
748         throw new ByResponseFormatComponentException(responseFormat);
749     }
750
751     private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Resource resource, User user, String csarUUID) {
752         getAndValidateComponentCsarYaml(csarUIPayload, resource, user, csarUUID);
753     }
754
755     private void getAndValidateComponentCsarYaml(Map<String, byte[]> csarUIPayload, Component component, User user, String csarUUID) {
756
757         Either<ImmutablePair<String, String>, ResponseFormat> getToscaYamlRes = CsarValidationUtils.getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils());
758
759         if (getToscaYamlRes.isRight()) {
760             ResponseFormat responseFormat = getToscaYamlRes.right().value();
761             log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
762             if (component instanceof Resource) {
763                 BeEcompErrorManager.getInstance()
764                     .logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
765                 getComponentsUtils().auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.CREATE_RESOURCE);
766             }else {
767                 BeEcompErrorManager.getInstance()
768                     .logBeDaoSystemError("Creating service from CSAR: fetching CSAR with id " + csarUUID + " failed");
769             }
770             throwComponentException(responseFormat);
771         }
772         String toscaYaml = getToscaYamlRes.left().value().getValue();
773
774         log.debug("checking tosca template is valid yml");
775         YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
776         boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes());
777         if (!isValid) {
778             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
779             if (component instanceof Resource) {
780                 getComponentsUtils().auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.IMPORT_RESOURCE);
781             }
782             throwComponentException(responseFormat);
783         }
784
785         log.debug("checking payload is valid tosca");
786         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaYaml);
787         Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
788
789         if (findFirstToscaStringElement.isRight()) {
790             isValid = false;
791         } else {
792             String defenitionVersionFound = findFirstToscaStringElement.left().value();
793             if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
794                 isValid = false;
795             } else {
796                 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
797             }
798         }
799
800         if (!isValid) {
801             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
802             if (component instanceof Resource) {
803                 log.debug("enter getAndValidateComponentCsarYaml,component instanceof Resource");
804                 getComponentsUtils().auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.IMPORT_RESOURCE);
805             }
806             throwComponentException(responseFormat);
807         }
808     }
809
810     private void fillResourceFromResourceInfoObject(Resource resource, UploadResourceInfo resourceInfoObject) {
811         resourceImportManager.populateResourceMetadata(resourceInfoObject, resource);
812         fillArtifacts(resource, resourceInfoObject);
813
814     }
815
816     private void fillArtifacts(Resource resource, UploadResourceInfo resourceInfoObject) {
817         if (resource != null && resourceInfoObject != null) {
818             List<UploadArtifactInfo> artifactList = resourceInfoObject.getArtifactList();
819             if (artifactList != null) {
820                 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
821                 buildArtifactsHM(artifactList, artifactsHM);
822                 resource.setArtifacts(artifactsHM);
823             }
824         }
825     }
826
827     private void buildArtifactsHM(List<UploadArtifactInfo> artifactList, Map<String, ArtifactDefinition> artifactsHM){
828         for (UploadArtifactInfo artifact : artifactList) {
829             ArtifactDefinition artifactDef = new ArtifactDefinition();
830             artifactDef.setArtifactName(artifact.getArtifactName());
831             artifactDef.setArtifactType(artifact.getArtifactType().getType());
832             artifactDef.setDescription(artifact.getArtifactDescription());
833             artifactDef.setPayloadData(artifact.getArtifactData());
834             artifactDef.setArtifactRef(artifact.getArtifactPath());
835             artifactsHM.put(artifactDef.getArtifactName(), artifactDef);
836         }
837     }
838
839     private Map<String, byte[]> getCsarFromPayload(UploadResourceInfo innerElement) {
840         String csarUUID = innerElement.getPayloadName();
841         String payloadData = innerElement.getPayloadData();
842
843         return getComponentCsarFromPayload(csarUUID, payloadData);
844     }
845
846     private Map<String, byte[]> getComponentCsarFromPayload(String csarUUID, String payloadData){
847         if (payloadData == null) {
848             log.info("Failed to decode received csar {}", csarUUID);
849             throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
850         }
851
852         byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8));
853         if (decodedPayload == null) {
854             log.info("Failed to decode received csar {}", csarUUID);
855             throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
856         }
857
858         Map<String, byte[]> csar = null;
859         try {
860             csar = ZipUtils.readZip(decodedPayload, false);
861         } catch (final ZipException e) {
862             log.info("Failed to unzip received csar {}", csarUUID, e);
863         }
864         return csar;
865     }
866
867     void validateInputStream(final HttpServletRequest request, Wrapper<String> dataWrapper, Wrapper<ResponseFormat> errorWrapper) throws IOException {
868         InputStream inputStream = request.getInputStream();
869         byte[] bytes = IOUtils.toByteArray(inputStream);
870         if (bytes == null || bytes.length == 0) {
871             log.info("Empty body was sent.");
872             errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
873         } else {
874             dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8));
875         }
876
877     }
878
879     <T> void validateClassParse(String data, Wrapper<T> parsedClassWrapper, Supplier<Class<T>> classGen, Wrapper<ResponseFormat> errorWrapper) {
880         try {
881             T parsedClass = gson.fromJson(data, classGen.get());
882             if (parsedClass == null) {
883                 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
884             } else {
885                 parsedClassWrapper.setInnerElement(parsedClass);
886             }
887         } catch (JsonSyntaxException e) {
888             log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e);
889             errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
890         }
891     }
892
893     void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType, Wrapper<ComponentInstanceBusinessLogic> blWrapper, Wrapper<ResponseFormat> errorWrapper) {
894         ServletContext context = request.getSession().getServletContext();
895         ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context);
896         if (componentInstanceLogic == null) {
897             log.debug("Unsupported component type {}", containerComponentType);
898             errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
899         } else {
900             blWrapper.setInnerElement(componentInstanceLogic);
901         }
902     }
903
904     <T> Response buildResponseFromElement(Wrapper<ResponseFormat> errorWrapper, Wrapper<T> attributeWrapper) throws IOException {
905         Response response;
906         if (errorWrapper.isEmpty()) {
907             ObjectMapper mapper = new ObjectMapper();
908             String result = mapper.writeValueAsString(attributeWrapper.getInnerElement());
909             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
910         } else {
911             response = buildErrorResponse(errorWrapper.getInnerElement());
912         }
913         return response;
914     }
915
916     protected void validateXECOMPInstanceIDHeader(String instanceIdHeader, Wrapper<ResponseFormat> responseWrapper) {
917         ResponseFormat responseFormat;
918         if(StringUtils.isEmpty(instanceIdHeader) ){
919             log.debug("Missing X-ECOMP-InstanceID header");
920             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
921             responseWrapper.setInnerElement(responseFormat);
922         }
923     }
924
925     protected void validateHttpCspUserIdHeader(String header, Wrapper<ResponseFormat> responseWrapper) {
926         ResponseFormat responseFormat;
927         if( StringUtils.isEmpty(header)){
928             log.debug("MissingUSER_ID");
929             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
930             responseWrapper.setInnerElement(responseFormat);
931         }
932     }
933
934     <T> Either<T, ResponseFormat> parseToObject(String json, Supplier<Class<T>> classSupplier) {
935
936         try {
937             T object = RepresentationUtils.fromRepresentation(json, classSupplier.get());
938             return Either.left(object);
939         } catch (Exception e) {
940             log.debug("Failed to parse json to {} object", classSupplier.get().getName(), e);
941             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
942             return Either.right(responseFormat);
943         }
944     }
945
946     public <T> Either<List<T>, ResponseFormat> parseListOfObjects(String json, Type type) {
947         try {
948             List<T> listOfObjects = gson.fromJson(json, type);
949             return Either.left(listOfObjects);
950         } catch (Exception e) {
951             log.debug("Failed to parse json to {} object", type.getClass().getName(), e);
952             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
953             return Either.right(responseFormat);
954         }
955     }
956     protected void validateNotEmptyBody(String data) {
957         if (StringUtils.isEmpty(data)) {
958             throw new ByActionStatusComponentException(ActionStatus.MISSING_BODY);
959         }
960     }
961
962     protected void commonServiceGeneralValidations(
963         Wrapper<Response> responseWrapper, Wrapper<User> userWrapper,
964         Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, ServiceAuthorityTypeEnum serviceAuthorityEnum,
965         String userUserId,
966         String serviceInfoJsonString) {
967
968         if (responseWrapper.isEmpty()) {
969             validateUserExist(responseWrapper, userWrapper, userUserId);
970         }
971
972         if (responseWrapper.isEmpty()) {
973             validateUserRole(responseWrapper, userWrapper.getInnerElement(), serviceAuthorityEnum);
974         }
975
976         if (responseWrapper.isEmpty()) {
977             validateAndFillServiceJson(responseWrapper, uploadServiceInfoWrapper, userWrapper.getInnerElement(),
978                 serviceAuthorityEnum, serviceInfoJsonString);
979         }
980
981         if (responseWrapper.isEmpty()) {
982             validateToscaTemplatePayloadName(responseWrapper, uploadServiceInfoWrapper.getInnerElement(),
983                 userWrapper.getInnerElement());
984         }
985
986     }
987
988     protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user,
989         ServiceAuthorityTypeEnum serviceAuthority) {
990         log.debug("validate user role");
991         if (serviceAuthority == ServiceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
992             if (!user.getRole().equals(Role.ADMIN.name())) {
993                 log.info("user is not in appropriate role to perform action");
994                 ResponseFormat responseFormat =
995                     getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
996                 log.debug("audit before sending response");
997                 Response response = buildErrorResponse(responseFormat);
998                 errorResponseWrapper.setInnerElement(response);
999             }
1000         } else {
1001             validateUserRole(errorResponseWrapper, user);
1002         }
1003
1004     }
1005
1006     protected void validateAndFillServiceJson(Wrapper<Response> responseWrapper,
1007         Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, User user,
1008         ServiceAuthorityTypeEnum serviceAuthorityEnum, String serviceInfo) {
1009         boolean isValid;
1010         try {
1011             log.debug("The received json is {}", serviceInfo);
1012             UploadServiceInfo serviceInfoObject = gson.fromJson(serviceInfo, UploadServiceInfo.class);
1013             if (serviceInfoObject == null) {
1014                 isValid = false;
1015             } else {
1016                 if (!serviceAuthorityEnum.isBackEndImport()) {
1017                     isValid =
1018                         serviceInfoObject.getPayloadName() != null && !serviceInfoObject.getPayloadName().isEmpty();
1019                     //only service name is checked
1020                 } else {
1021                     isValid = true;
1022                 }
1023                 uploadServiceInfoWrapper.setInnerElement(serviceInfoObject);
1024                 log.debug("get isValid:{},serviceInfoObject get name:{},get tags:{},getContactId:{}," +
1025                                 " getPayloadName:{}",isValid,
1026                         uploadServiceInfoWrapper.getInnerElement().getName(),
1027                         uploadServiceInfoWrapper.getInnerElement().getTags(),
1028                         uploadServiceInfoWrapper.getInnerElement().getContactId(),
1029                         uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1030             }
1031
1032         } catch (JsonSyntaxException e) {
1033             log.debug("enter validateAndFillServiceJson,Invalid json was received. {}", e.getMessage(), e);
1034             isValid = false;
1035
1036         }
1037         if (!isValid) {
1038             log.info("Invalid json was received.");
1039             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1040             Response errorResp = buildErrorResponse(responseFormat);
1041             responseWrapper.setInnerElement(errorResp);
1042         }
1043     }
1044
1045     protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper,
1046         UploadServiceInfo uploadServiceInfo, User user) {
1047         String toscaTemplatePayloadName = uploadServiceInfo.getPayloadName();
1048         boolean isValidSuffix = isToscaTemplatePayloadNameValid(responseWrapper, toscaTemplatePayloadName);
1049         if (!isValidSuffix) {
1050             ResponseFormat responseFormat =
1051                 getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
1052             Response errorResponse = buildErrorResponse(responseFormat);
1053             responseWrapper.setInnerElement(errorResponse);
1054         }
1055
1056     }
1057
1058
1059     protected void specificServiceAuthorityValidations(Wrapper<Response> responseWrapper,
1060         Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, Wrapper<String> yamlStringWrapper, User user,
1061         HttpServletRequest request, String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum)
1062         throws FileNotFoundException {
1063
1064         if (responseWrapper.isEmpty()) {
1065             // UI Only Validation
1066             if (!serviceAuthorityEnum.isBackEndImport()) {
1067                 importUIValidations(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user, request,
1068                     serviceInfoJsonString);
1069             }
1070
1071             // User Defined Type Services
1072             if (serviceAuthorityEnum.isUserTypeService() && !CsarValidationUtils.isCsarPayloadName(
1073                 uploadServiceInfoWrapper.getInnerElement().getPayloadName())) {
1074                 if (responseWrapper.isEmpty()) {
1075                     validatePayloadNameSpace(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user,
1076                         yamlStringWrapper.getInnerElement());
1077                 }
1078
1079             }
1080         }
1081     }
1082
1083     protected void importUIValidations(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user,
1084         HttpServletRequest request, String serviceInfoJsonString) {
1085         if (responseWrapper.isEmpty()) {
1086             validateMD5(responseWrapper, user, serviceInfo, request, serviceInfoJsonString);
1087         }
1088         if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod()
1089             .equals("POST")) {
1090             validateServiceDoesNotExist(responseWrapper, user, serviceInfo.getName());
1091         }
1092     }
1093
1094     protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user,
1095         String toscaPayload) {
1096         boolean isValid;
1097         String nameSpace = "";
1098         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
1099         Either<Map<String, Object>, ResultStatusEnum> toscaElement =
1100             ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
1101         if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
1102             isValid = false;
1103         } else {
1104             nameSpace = toscaElement.left().value().keySet().iterator().next();
1105             isValid = nameSpace.startsWith(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX);
1106             log.debug("enter validatePayloadNameSpace,get nameSpace:{},get Valid is:{}",nameSpace,isValid);
1107         }
1108         if (!isValid) {
1109             ResponseFormat responseFormat =
1110                 getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_NAMESPACE);
1111             Response errorResponse = buildErrorResponse(responseFormat);
1112             responseWrapper.setInnerElement(errorResponse);
1113         } else {
1114             String str1 = nameSpace.substring(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX.length());
1115             String[] findTypes = str1.split("\\.");
1116             if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) {
1117                 String type = findTypes[0].toUpperCase();
1118                 serviceInfo.setServiceType(type);
1119             } else {
1120                 serviceInfo.setServiceType(ResourceTypeEnum.SERVICE.name());
1121             }
1122         }
1123
1124     }
1125
1126     protected void validateMD5(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfo,
1127         HttpServletRequest request, String serviceInfoJsonString) {
1128         boolean isValid;
1129         String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
1130         if (recievedMD5 == null) {
1131             isValid = false;
1132         } else {
1133             String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(serviceInfoJsonString);
1134             isValid = calculateMD5.equals(recievedMD5);
1135         }
1136         if (!isValid) {
1137             ResponseFormat responseFormat =
1138                 getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_CHECKSUM);
1139             Response errorResponse = buildErrorResponse(responseFormat);
1140             responseWrapper.setInnerElement(errorResponse);
1141         }
1142     }
1143
1144
1145     protected void validateServiceDoesNotExist(Wrapper<Response> responseWrapper, User user, String serviceName) {
1146         if (serviceImportManager.isServiceExist(serviceName)) {
1147             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.SERVICE_ALREADY_EXISTS);
1148             Response errorResponse = buildErrorResponse(responseFormat);
1149             responseWrapper.setInnerElement(errorResponse);
1150         }
1151     }
1152
1153     protected void handleImportService(Wrapper<Response> responseWrapper, User user,
1154         UploadServiceInfo serviceInfoObject, String yamlAsString, ServiceAuthorityTypeEnum authority,
1155         boolean createNewVersion, String serviceUniqueId) throws ZipException {
1156
1157         Response response = null;
1158         Object representation = null;
1159         ImmutablePair<Service, ActionStatus> importedServiceStatus = null;
1160         if (CsarValidationUtils.isCsarPayloadName(serviceInfoObject.getPayloadName())) {
1161             log.debug("import service from csar");
1162             importedServiceStatus = importServiceFromUICsar(serviceInfoObject, user, serviceUniqueId);
1163         }
1164
1165         if (importedServiceStatus != null) {
1166             try {
1167                 representation = RepresentationUtils.toRepresentation(importedServiceStatus.left);
1168             } catch (IOException e) {
1169                 log.debug("Error while building service representation : {}", e.getMessage(), e);
1170             }
1171             response = buildOkResponse(getComponentsUtils().getResponseFormat(importedServiceStatus.right),
1172                 representation);
1173         }
1174         responseWrapper.setInnerElement(response);
1175     }
1176
1177     private ImmutablePair<Service, ActionStatus> importServiceFromUICsar(UploadServiceInfo serviceInfoObject, User user,
1178         String serviceUniqueId) throws ZipException {
1179
1180         Service newService;
1181         ImmutablePair<Service, ActionStatus> result = null;
1182         ActionStatus actionStatus;
1183         Service service = new Service();
1184         String payloadName = serviceInfoObject.getPayloadName();
1185         fillServiceFromServiceInfoObject(service, serviceInfoObject);
1186
1187         Map<String, byte[]> csarUIPayloadRes = getCsarFromPayload(serviceInfoObject);
1188
1189         getAndValidateCsarYaml(csarUIPayloadRes, service, user, payloadName);
1190
1191         newService = serviceImportManager.getServiceImportBusinessLogic()
1192             .createService(service, AuditingActionEnum.CREATE_SERVICE, user, csarUIPayloadRes,
1193                 payloadName);
1194         actionStatus = ActionStatus.CREATED;
1195
1196         return new ImmutablePair<>(newService, actionStatus);
1197     }
1198
1199
1200     private void fillServiceFromServiceInfoObject(Service service, UploadServiceInfo serviceInfoObject) {
1201         serviceImportManager.populateServiceMetadata(serviceInfoObject, service);
1202         fillArtifacts(service, serviceInfoObject);
1203
1204     }
1205
1206     private Map<String, byte[]> getCsarFromPayload(UploadServiceInfo innerElement)
1207         throws ZipException {
1208         String csarUUID = innerElement.getPayloadName();
1209         String payloadData = innerElement.getPayloadData();
1210         return getComponentCsarFromPayload(csarUUID, payloadData);
1211     }
1212
1213     private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Service service, User user,
1214         String csarUUID) {
1215         getAndValidateComponentCsarYaml(csarUIPayload, service, user, csarUUID);
1216     }
1217
1218     private void fillArtifacts(Service service, UploadServiceInfo serviceInfoObject) {
1219         if (service != null && serviceInfoObject != null) {
1220             List<UploadArtifactInfo> artifactList = serviceInfoObject.getArtifactList();
1221             if (artifactList != null) {
1222                 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
1223                 buildArtifactsHM(artifactList, artifactsHM);
1224                 service.setArtifacts(artifactsHM);
1225             }
1226         }
1227     }
1228     /**
1229      * import service payload to postman
1230      * @param responseWrapper
1231      * @param uploadServiceInfoWrapper
1232      * @param yamlStringWrapper
1233      * @param user
1234      * @param serviceInfoJsonString
1235      * @param serviceAuthorityEnum
1236      * @param file
1237      * @throws ZipException
1238      */
1239     protected void fillServicePayload(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum,
1240                                       File file) throws ZipException {
1241         log.debug("enter fillServicePayload");
1242         if (responseWrapper.isEmpty()) {
1243             log.debug("enter fillServicePayload,get responseWrapper is empty");
1244             if (serviceAuthorityEnum.isBackEndImport()) {
1245                 // PrePayload Validations
1246                 if (responseWrapper.isEmpty()) {
1247                     validateDataNotNull(responseWrapper, file, serviceInfoJsonString);
1248                 }
1249                 if (responseWrapper.isEmpty()){
1250                     log.debug("enter fillServicePayload,responseWrapper is empty");
1251                 }
1252                 if(!serviceAuthorityEnum.equals(ServiceAuthorityTypeEnum.CSAR_TYPE_BE)){
1253                     if (responseWrapper.isEmpty()) {
1254                         validateZip(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1255                     }
1256
1257                     // Fill PayLoad From File
1258                     if (responseWrapper.isEmpty()) {
1259                         fillToscaTemplateFromZip(yamlStringWrapper, uploadServiceInfoWrapper.getInnerElement().getPayloadName(), file);
1260                     }
1261                 }else{
1262
1263                     log.debug("enter fillServicePayload,ServiceAuthorityTypeEnum is CSAR_TYPE_BE");
1264                     if (responseWrapper.isEmpty()) {
1265                         validateCsar(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1266                     }
1267                     if (!responseWrapper.isEmpty()) {
1268                         log.debug("enter fillServicePayload,get responseWrapper:{}", responseWrapper);
1269                     }
1270                     // Fill PayLoad From File
1271                     if (responseWrapper.isEmpty()) {
1272                         fillServicePayloadDataFromFile(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), file);
1273                     }
1274
1275                 }
1276
1277             } else {
1278                 // Fill PayLoad From JSON
1279                 if (responseWrapper.isEmpty()) {
1280                     fillServiceToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadServiceInfoWrapper.getInnerElement());
1281                 }
1282             }
1283
1284         }
1285
1286     }
1287
1288     protected void fillServicePayloadDataFromFile(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfoWrapper, File file)  {
1289         try(InputStream fileInputStream = new FileInputStream(file)){
1290
1291             log.debug("enter fillServicePayloadDataFromFile");
1292             byte [] data = new byte[(int)file.length()];
1293             if( fileInputStream.read(data) == -1){
1294                 log.info("Invalid json was received.");
1295                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1296
1297                 Response errorResp = buildErrorResponse(responseFormat);
1298                 responseWrapper.setInnerElement(errorResp);
1299             }
1300             String payloadData =  Base64.encodeBase64String(data);
1301             uploadServiceInfoWrapper.setPayloadData(payloadData);
1302             log.debug("enter fillServicePayloadDataFromFile,get payloadData:{}",
1303                     uploadServiceInfoWrapper.getPayloadData());
1304
1305             log.debug("enter fillServicePayloadDataFromFile,get uploadService:{}",uploadServiceInfoWrapper);
1306
1307         } catch (IOException e) {
1308             log.info("Invalid json was received or Error while closing input Stream.");
1309             log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
1310             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1311
1312             Response errorResp = buildErrorResponse(responseFormat);
1313             responseWrapper.setInnerElement(errorResp);
1314         }
1315     }
1316
1317     private void fillServiceToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadServiceInfo serviceInfo) {
1318         if (serviceInfo.getPayloadData() == null || serviceInfo.getPayloadData().isEmpty()) {
1319             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
1320             Response errorResponse = buildErrorResponse(responseFormat);
1321             getComponentsUtils().auditResource(responseFormat, user, serviceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
1322             responseWrapper.setInnerElement(errorResponse);
1323         } else {
1324             String toscaPayload = serviceInfo.getPayloadData();
1325             String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
1326             yamlStringWrapper.setInnerElement(decodedPayload);
1327         }
1328     }
1329
1330 }