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