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