2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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 * ================================================================================
22 package org.openecomp.sdc.be.servlets;
24 import com.fasterxml.jackson.databind.ObjectMapper;
25 import com.google.gson.Gson;
26 import com.google.gson.JsonSyntaxException;
27 import fj.data.Either;
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;
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;
91 public abstract class AbstractValidationsServlet extends BeGenericServlet {
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;
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;
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);
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);
127 protected void init() {
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);
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);
149 protected void validateUserExist(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, String userUserId) {
150 log.debug("get user {} from DB", userUserId);
152 if (userUserId == null) {
153 log.info("user userId is null");
154 Response response = returnMissingInformation(new User());
155 responseWrapper.setInnerElement(response);
157 UserBusinessLogic userAdmin = getServletUtils().getUserAdmin();
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);
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);
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);
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);
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);
207 final Map<String, byte[]> unzippedFolder;
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);
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);
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);
230 final Map<String, byte[]> unzippedFolder;
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);
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);
246 protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
247 extractZipContents(yamlStringWrapper, file);
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);
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);
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);
282 validateUserRole(errorResponseWrapper, user);
286 protected void validateAndFillResourceJson(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, User user,
287 ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) {
290 log.debug("The received json is {}", resourceInfo);
291 UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class);
292 if (resourceInfoObject == null) {
295 if (!resourceAuthorityEnum.isBackEndImport()) {
296 isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty();
297 //only resource name is checked
301 uploadResourceInfoWrapper.setInnerElement(resourceInfoObject);
303 } catch (JsonSyntaxException e) {
304 log.debug("Invalid json was received. {}", e.getMessage(), e);
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);
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);
326 public ServletUtils getServletUtils() {
330 public Gson getGson() {
331 return getServletUtils().getGson();
334 public ComponentsUtils getComponentsUtils() {
335 return getServletUtils().getComponentsUtils();
338 protected void validatePayloadIsTosca(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
339 log.debug("checking payload is valid tosca");
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()) {
347 String defenitionVersionFound = findFirstToscaStringElement.left().value();
348 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
351 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
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);
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());
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);
376 * Gets the Resource type from the given node type name.
378 * @param nodeTypeFullName - Node type Name
379 * @return Resource Type name
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();
393 return ResourceTypeEnum.VFC.name();
397 * Extracts the Node Type Name prefix from the given Node Type Name.
399 * @param nodeName - Node Type Name
400 * @return Node Type Name prefix
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);
410 return Optional.empty();
413 protected void validatePayloadNameSpace(final Wrapper<Response> responseWrapper, final UploadResourceInfo resourceInfo, final User user,
414 final String toscaPayload) {
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) {
423 namespace = toscaElement.left().value().keySet().iterator().next();
424 isValid = getNodeTypeNamePrefix(namespace).isPresent();
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);
432 resourceInfo.setResourceType(getResourceType(namespace));
436 private void validatePayloadIsSingleResource(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user,
437 String toscaPayload) {
438 log.debug("checking payload contains single resource");
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()) {
446 isValid = toscaElement.left().value().size() == 1;
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);
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);
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);
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);
488 return isValidSuffix;
491 private void validateMD5(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request,
492 String resourceInfoJsonString) {
494 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
495 if (recievedMD5 == null) {
498 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(resourceInfoJsonString);
499 isValid = calculateMD5.equals(recievedMD5);
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);
509 ComponentTypeEnum validateComponentType(String componentType) {
510 if (componentType == null) {
511 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR);
513 if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) {
514 return ComponentTypeEnum.RESOURCE;
516 if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) {
517 return ComponentTypeEnum.SERVICE;
519 log.debug("Invalid componentType:{}", componentType);
520 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR, componentType);
523 ComponentTypeEnum convertToComponentType(String componentType) {
524 return validateComponentType(componentType);
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);
535 String toscaPayload = resourceInfo.getPayloadData();
536 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
537 yamlStringWrapper.setInnerElement(decodedPayload);
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);
549 if (!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)) {
550 if (responseWrapper.isEmpty()) {
551 validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
553 // Fill PayLoad From File
554 if (responseWrapper.isEmpty()) {
555 fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file);
558 if (responseWrapper.isEmpty()) {
559 validateCsar(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
561 // Fill PayLoad From File
562 if (responseWrapper.isEmpty()) {
563 fillPayloadDataFromFile(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), file);
567 // Fill PayLoad From JSON
568 if (responseWrapper.isEmpty()) {
569 fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement());
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);
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());
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);
597 if (responseWrapper.isEmpty()) {
598 validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum);
600 if (responseWrapper.isEmpty()) {
601 validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum,
602 resourceInfoJsonString);
604 if (responseWrapper.isEmpty()) {
605 validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
607 if (responseWrapper.isEmpty()) {
608 validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
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);
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);
627 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
628 validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName());
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());
637 if (responseWrapper.isEmpty()) {
638 validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
640 if (responseWrapper.isEmpty()) {
641 validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
643 if (responseWrapper.isEmpty()) {
644 validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
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 =
660 resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, user, createNewVersion, true, false);
662 log.debug("import user resource (not normative type)");
663 createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user, false);
665 if (createOrUpdateResponse != null) {
666 importedResourceStatus = createOrUpdateResponse;
668 if (importedResourceStatus != null) {
670 representation = RepresentationUtils.toRepresentation(importedResourceStatus.left);
671 } catch (IOException e) {
672 log.debug("Error while building resource representation : {}", e.getMessage(), e);
674 response = buildOkResponse(getComponentsUtils().getResponseFormat(importedResourceStatus.right), representation);
676 responseWrapper.setInnerElement(response);
679 private ImmutablePair<Resource, ActionStatus> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user,
680 String resourceUniqueId) {
681 Resource newResource;
682 ActionStatus actionStatus;
683 Resource resource = new Resource();
684 String payloadName = resourceInfoObject.getPayloadName();
685 fillResourceFromResourceInfoObject(resource, resourceInfoObject);
686 Map<String, byte[]> csarUIPayload = getCsarFromPayload(resourceInfoObject);
687 getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName);
688 if (resourceUniqueId == null || resourceUniqueId.isEmpty()) {
689 newResource = resourceImportManager.getResourceBusinessLogic()
690 .createResource(resource, AuditingActionEnum.CREATE_RESOURCE, user, csarUIPayload, payloadName);
691 actionStatus = ActionStatus.CREATED;
693 newResource = resourceImportManager.getResourceBusinessLogic()
694 .validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId);
695 actionStatus = ActionStatus.OK;
697 return new ImmutablePair<>(newResource, actionStatus);
700 protected Resource throwComponentException(ResponseFormat responseFormat) {
701 throw new ByResponseFormatComponentException(responseFormat);
704 private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Resource resource, User user, String csarUUID) {
705 getAndValidateComponentCsarYaml(csarUIPayload, resource, user, csarUUID);
708 private void getAndValidateComponentCsarYaml(Map<String, byte[]> csarUIPayload, Component component, User user, String csarUUID) {
709 Either<ImmutablePair<String, String>, ResponseFormat> getToscaYamlRes = CsarValidationUtils
710 .getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils());
711 if (getToscaYamlRes.isRight()) {
712 ResponseFormat responseFormat = getToscaYamlRes.right().value();
713 log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
714 if (component instanceof Resource) {
715 BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
716 getComponentsUtils().auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.CREATE_RESOURCE);
718 BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating service from CSAR: fetching CSAR with id " + csarUUID + " failed");
720 throwComponentException(responseFormat);
722 String toscaYaml = getToscaYamlRes.left().value().getValue();
723 log.debug("checking tosca template is valid yml");
724 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
725 boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes());
727 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
728 if (component instanceof Resource) {
729 getComponentsUtils().auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.IMPORT_RESOURCE);
731 throwComponentException(responseFormat);
733 log.debug("checking payload is valid tosca");
734 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaYaml);
735 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils
736 .findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
737 if (findFirstToscaStringElement.isRight()) {
740 String defenitionVersionFound = findFirstToscaStringElement.left().value();
741 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
744 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
748 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
749 if (component instanceof Resource) {
750 log.debug("enter getAndValidateComponentCsarYaml,component instanceof Resource");
751 getComponentsUtils().auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.IMPORT_RESOURCE);
753 throwComponentException(responseFormat);
757 private void fillResourceFromResourceInfoObject(Resource resource, UploadResourceInfo resourceInfoObject) {
758 resourceImportManager.populateResourceMetadata(resourceInfoObject, resource);
759 fillArtifacts(resource, resourceInfoObject);
762 private void fillArtifacts(Resource resource, UploadResourceInfo resourceInfoObject) {
763 if (resource != null && resourceInfoObject != null) {
764 List<UploadArtifactInfo> artifactList = resourceInfoObject.getArtifactList();
765 if (artifactList != null) {
766 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
767 buildArtifactsHM(artifactList, artifactsHM);
768 resource.setArtifacts(artifactsHM);
773 private void buildArtifactsHM(List<UploadArtifactInfo> artifactList, Map<String, ArtifactDefinition> artifactsHM) {
774 for (UploadArtifactInfo artifact : artifactList) {
775 ArtifactDefinition artifactDef = new ArtifactDefinition();
776 artifactDef.setArtifactName(artifact.getArtifactName());
777 artifactDef.setArtifactType(artifact.getArtifactType().getType());
778 artifactDef.setDescription(artifact.getArtifactDescription());
779 artifactDef.setPayloadData(artifact.getArtifactData());
780 artifactDef.setArtifactRef(artifact.getArtifactPath());
781 artifactsHM.put(artifactDef.getArtifactName(), artifactDef);
785 private Map<String, byte[]> getCsarFromPayload(UploadResourceInfo innerElement) {
786 String csarUUID = innerElement.getPayloadName();
787 String payloadData = innerElement.getPayloadData();
788 return getComponentCsarFromPayload(csarUUID, payloadData);
791 private Map<String, byte[]> getComponentCsarFromPayload(String csarUUID, String payloadData) {
792 if (payloadData == null) {
793 log.info("Failed to decode received csar {}", csarUUID);
794 throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
796 byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8));
797 if (decodedPayload == null) {
798 log.info("Failed to decode received csar {}", csarUUID);
799 throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
801 Map<String, byte[]> csar = null;
803 csar = ZipUtils.readZip(decodedPayload, false);
804 } catch (final ZipException e) {
805 log.info("Failed to unzip received csar {}", csarUUID, e);
810 void validateInputStream(final HttpServletRequest request, Wrapper<String> dataWrapper, Wrapper<ResponseFormat> errorWrapper) throws IOException {
811 InputStream inputStream = request.getInputStream();
812 byte[] bytes = IOUtils.toByteArray(inputStream);
813 if (bytes == null || bytes.length == 0) {
814 log.info("Empty body was sent.");
815 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
817 dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8));
821 <T> void validateClassParse(String data, Wrapper<T> parsedClassWrapper, Supplier<Class<T>> classGen, Wrapper<ResponseFormat> errorWrapper) {
823 T parsedClass = gson.fromJson(data, classGen.get());
824 if (parsedClass == null) {
825 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
827 parsedClassWrapper.setInnerElement(parsedClass);
829 } catch (JsonSyntaxException e) {
830 log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e);
831 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
835 void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType,
836 Wrapper<ComponentInstanceBusinessLogic> blWrapper, Wrapper<ResponseFormat> errorWrapper) {
837 ServletContext context = request.getSession().getServletContext();
838 ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context);
839 if (componentInstanceLogic == null) {
840 log.debug("Unsupported component type {}", containerComponentType);
841 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
843 blWrapper.setInnerElement(componentInstanceLogic);
847 <T> Response buildResponseFromElement(Wrapper<ResponseFormat> errorWrapper, Wrapper<T> attributeWrapper) throws IOException {
849 if (errorWrapper.isEmpty()) {
850 ObjectMapper mapper = new ObjectMapper();
851 String result = mapper.writeValueAsString(attributeWrapper.getInnerElement());
852 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
854 response = buildErrorResponse(errorWrapper.getInnerElement());
859 protected void validateXECOMPInstanceIDHeader(String instanceIdHeader, Wrapper<ResponseFormat> responseWrapper) {
860 ResponseFormat responseFormat;
861 if (StringUtils.isEmpty(instanceIdHeader)) {
862 log.debug("Missing X-ECOMP-InstanceID header");
863 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
864 responseWrapper.setInnerElement(responseFormat);
868 protected void validateHttpCspUserIdHeader(String header, Wrapper<ResponseFormat> responseWrapper) {
869 ResponseFormat responseFormat;
870 if (StringUtils.isEmpty(header)) {
871 log.debug("MissingUSER_ID");
872 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
873 responseWrapper.setInnerElement(responseFormat);
877 <T> Either<T, ResponseFormat> parseToObject(String json, Supplier<Class<T>> classSupplier) {
879 T object = RepresentationUtils.fromRepresentation(json, classSupplier.get());
880 return Either.left(object);
881 } catch (Exception e) {
882 log.debug("Failed to parse json to {} object", classSupplier.get().getName(), e);
883 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
884 return Either.right(responseFormat);
888 public <T> Either<List<T>, ResponseFormat> parseListOfObjects(String json, Type type) {
890 List<T> listOfObjects = gson.fromJson(json, type);
891 return Either.left(listOfObjects);
892 } catch (Exception e) {
893 log.debug("Failed to parse json to {} object", type.getClass().getName(), e);
894 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
895 return Either.right(responseFormat);
899 protected void validateNotEmptyBody(String data) {
900 if (StringUtils.isEmpty(data)) {
901 throw new ByActionStatusComponentException(ActionStatus.MISSING_BODY);
905 protected void commonServiceGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper,
906 Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, ServiceAuthorityTypeEnum serviceAuthorityEnum,
907 String userUserId, String serviceInfoJsonString) {
908 if (responseWrapper.isEmpty()) {
909 validateUserExist(responseWrapper, userWrapper, userUserId);
911 if (responseWrapper.isEmpty()) {
912 validateUserRole(responseWrapper, userWrapper.getInnerElement(), serviceAuthorityEnum);
914 if (responseWrapper.isEmpty()) {
915 validateAndFillServiceJson(responseWrapper, uploadServiceInfoWrapper, userWrapper.getInnerElement(), serviceAuthorityEnum,
916 serviceInfoJsonString);
918 if (responseWrapper.isEmpty()) {
919 validateToscaTemplatePayloadName(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
923 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ServiceAuthorityTypeEnum serviceAuthority) {
924 log.debug("validate user role");
925 if (serviceAuthority == ServiceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
926 if (!user.getRole().equals(Role.ADMIN.name())) {
927 log.info("user is not in appropriate role to perform action");
928 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
929 log.debug("audit before sending response");
930 Response response = buildErrorResponse(responseFormat);
931 errorResponseWrapper.setInnerElement(response);
934 validateUserRole(errorResponseWrapper, user);
938 protected void validateAndFillServiceJson(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, User user,
939 ServiceAuthorityTypeEnum serviceAuthorityEnum, String serviceInfo) {
942 log.debug("The received json is {}", serviceInfo);
943 UploadServiceInfo serviceInfoObject = gson.fromJson(serviceInfo, UploadServiceInfo.class);
944 if (serviceInfoObject == null) {
947 if (!serviceAuthorityEnum.isBackEndImport()) {
948 isValid = serviceInfoObject.getPayloadName() != null && !serviceInfoObject.getPayloadName().isEmpty();
949 //only service name is checked
953 uploadServiceInfoWrapper.setInnerElement(serviceInfoObject);
954 log.debug("get isValid:{},serviceInfoObject get name:{},get tags:{},getContactId:{}," + " getPayloadName:{}", isValid,
955 uploadServiceInfoWrapper.getInnerElement().getName(), uploadServiceInfoWrapper.getInnerElement().getTags(),
956 uploadServiceInfoWrapper.getInnerElement().getContactId(), uploadServiceInfoWrapper.getInnerElement().getPayloadName());
958 } catch (JsonSyntaxException e) {
959 log.debug("enter validateAndFillServiceJson,Invalid json was received. {}", e.getMessage(), e);
963 log.info("Invalid json was received.");
964 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
965 Response errorResp = buildErrorResponse(responseFormat);
966 responseWrapper.setInnerElement(errorResp);
970 protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfo, User user) {
971 String toscaTemplatePayloadName = uploadServiceInfo.getPayloadName();
972 boolean isValidSuffix = isToscaTemplatePayloadNameValid(responseWrapper, toscaTemplatePayloadName);
973 if (!isValidSuffix) {
974 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
975 Response errorResponse = buildErrorResponse(responseFormat);
976 responseWrapper.setInnerElement(errorResponse);
980 protected void specificServiceAuthorityValidations(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper,
981 Wrapper<String> yamlStringWrapper, User user, HttpServletRequest request,
982 String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum)
983 throws FileNotFoundException {
984 if (responseWrapper.isEmpty()) {
985 // UI Only Validation
986 if (!serviceAuthorityEnum.isBackEndImport()) {
987 importUIValidations(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user, request, serviceInfoJsonString);
989 // User Defined Type Services
990 if (serviceAuthorityEnum.isUserTypeService() && !CsarValidationUtils
991 .isCsarPayloadName(uploadServiceInfoWrapper.getInnerElement().getPayloadName())) {
992 if (responseWrapper.isEmpty()) {
993 validatePayloadNameSpace(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement());
999 protected void importUIValidations(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user, HttpServletRequest request,
1000 String serviceInfoJsonString) {
1001 if (responseWrapper.isEmpty()) {
1002 validateMD5(responseWrapper, user, serviceInfo, request, serviceInfoJsonString);
1004 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
1005 validateServiceDoesNotExist(responseWrapper, user, serviceInfo.getName());
1009 protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user, String toscaPayload) {
1011 String nameSpace = "";
1012 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
1013 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils
1014 .findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
1015 if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
1018 nameSpace = toscaElement.left().value().keySet().iterator().next();
1019 isValid = nameSpace.startsWith(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX);
1020 log.debug("enter validatePayloadNameSpace,get nameSpace:{},get Valid is:{}", nameSpace, isValid);
1023 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_NAMESPACE);
1024 Response errorResponse = buildErrorResponse(responseFormat);
1025 responseWrapper.setInnerElement(errorResponse);
1027 String str1 = nameSpace.substring(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX.length());
1028 String[] findTypes = str1.split("\\.");
1029 if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) {
1030 String type = findTypes[0].toUpperCase();
1031 serviceInfo.setServiceType(type);
1033 serviceInfo.setServiceType(ResourceTypeEnum.SERVICE.name());
1038 protected void validateMD5(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfo, HttpServletRequest request,
1039 String serviceInfoJsonString) {
1041 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
1042 if (recievedMD5 == null) {
1045 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(serviceInfoJsonString);
1046 isValid = calculateMD5.equals(recievedMD5);
1049 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_CHECKSUM);
1050 Response errorResponse = buildErrorResponse(responseFormat);
1051 responseWrapper.setInnerElement(errorResponse);
1055 protected void validateServiceDoesNotExist(Wrapper<Response> responseWrapper, User user, String serviceName) {
1056 if (serviceImportManager.isServiceExist(serviceName)) {
1057 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.SERVICE_ALREADY_EXISTS);
1058 Response errorResponse = buildErrorResponse(responseFormat);
1059 responseWrapper.setInnerElement(errorResponse);
1063 protected void handleImportService(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfoObject, String yamlAsString,
1064 ServiceAuthorityTypeEnum authority, boolean createNewVersion, String serviceUniqueId) throws ZipException {
1065 Response response = null;
1066 Object representation = null;
1067 ImmutablePair<Service, ActionStatus> importedServiceStatus = null;
1068 if (CsarValidationUtils.isCsarPayloadName(serviceInfoObject.getPayloadName())) {
1069 log.debug("import service from csar");
1070 importedServiceStatus = importServiceFromUICsar(serviceInfoObject, user, serviceUniqueId);
1072 if (importedServiceStatus != null) {
1074 representation = RepresentationUtils.toRepresentation(importedServiceStatus.left);
1075 } catch (IOException e) {
1076 log.debug("Error while building service representation : {}", e.getMessage(), e);
1078 response = buildOkResponse(getComponentsUtils().getResponseFormat(importedServiceStatus.right), representation);
1080 responseWrapper.setInnerElement(response);
1083 private ImmutablePair<Service, ActionStatus> importServiceFromUICsar(UploadServiceInfo serviceInfoObject, User user, String serviceUniqueId)
1084 throws ZipException {
1086 ImmutablePair<Service, ActionStatus> result = null;
1087 ActionStatus actionStatus;
1088 Service service = new Service();
1089 String payloadName = serviceInfoObject.getPayloadName();
1090 fillServiceFromServiceInfoObject(service, serviceInfoObject);
1091 Map<String, byte[]> csarUIPayloadRes = getCsarFromPayload(serviceInfoObject);
1092 getAndValidateCsarYaml(csarUIPayloadRes, service, user, payloadName);
1093 newService = serviceImportManager.getServiceImportBusinessLogic()
1094 .createService(service, AuditingActionEnum.CREATE_SERVICE, user, csarUIPayloadRes, payloadName);
1095 actionStatus = ActionStatus.CREATED;
1096 return new ImmutablePair<>(newService, actionStatus);
1099 private void fillServiceFromServiceInfoObject(Service service, UploadServiceInfo serviceInfoObject) {
1100 serviceImportManager.populateServiceMetadata(serviceInfoObject, service);
1101 fillArtifacts(service, serviceInfoObject);
1104 private Map<String, byte[]> getCsarFromPayload(UploadServiceInfo innerElement) throws ZipException {
1105 String csarUUID = innerElement.getPayloadName();
1106 String payloadData = innerElement.getPayloadData();
1107 return getComponentCsarFromPayload(csarUUID, payloadData);
1110 private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Service service, User user, String csarUUID) {
1111 getAndValidateComponentCsarYaml(csarUIPayload, service, user, csarUUID);
1114 private void fillArtifacts(Service service, UploadServiceInfo serviceInfoObject) {
1115 if (service != null && serviceInfoObject != null) {
1116 List<UploadArtifactInfo> artifactList = serviceInfoObject.getArtifactList();
1117 if (artifactList != null) {
1118 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
1119 buildArtifactsHM(artifactList, artifactsHM);
1120 service.setArtifacts(artifactsHM);
1126 * import service payload to postman
1128 * @param responseWrapper
1129 * @param uploadServiceInfoWrapper
1130 * @param yamlStringWrapper
1132 * @param serviceInfoJsonString
1133 * @param serviceAuthorityEnum
1135 * @throws ZipException
1137 protected void fillServicePayload(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper,
1138 Wrapper<String> yamlStringWrapper, User user, String serviceInfoJsonString,
1139 ServiceAuthorityTypeEnum serviceAuthorityEnum, File file) throws ZipException {
1140 log.debug("enter fillServicePayload");
1141 if (responseWrapper.isEmpty()) {
1142 log.debug("enter fillServicePayload,get responseWrapper is empty");
1143 if (serviceAuthorityEnum.isBackEndImport()) {
1144 // PrePayload Validations
1145 if (responseWrapper.isEmpty()) {
1146 validateDataNotNull(responseWrapper, file, serviceInfoJsonString);
1148 if (responseWrapper.isEmpty()) {
1149 log.debug("enter fillServicePayload,responseWrapper is empty");
1151 if (!serviceAuthorityEnum.equals(ServiceAuthorityTypeEnum.CSAR_TYPE_BE)) {
1152 if (responseWrapper.isEmpty()) {
1153 validateZip(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1155 // Fill PayLoad From File
1156 if (responseWrapper.isEmpty()) {
1157 fillToscaTemplateFromZip(yamlStringWrapper, uploadServiceInfoWrapper.getInnerElement().getPayloadName(), file);
1160 log.debug("enter fillServicePayload,ServiceAuthorityTypeEnum is CSAR_TYPE_BE");
1161 if (responseWrapper.isEmpty()) {
1162 validateCsar(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1164 if (!responseWrapper.isEmpty()) {
1165 log.debug("enter fillServicePayload,get responseWrapper:{}", responseWrapper);
1167 // Fill PayLoad From File
1168 if (responseWrapper.isEmpty()) {
1169 fillServicePayloadDataFromFile(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), file);
1173 // Fill PayLoad From JSON
1174 if (responseWrapper.isEmpty()) {
1175 fillServiceToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadServiceInfoWrapper.getInnerElement());
1181 protected void fillServicePayloadDataFromFile(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfoWrapper, File file) {
1182 try (InputStream fileInputStream = new FileInputStream(file)) {
1183 log.debug("enter fillServicePayloadDataFromFile");
1184 byte[] data = new byte[(int) file.length()];
1185 if (fileInputStream.read(data) == -1) {
1186 log.info("Invalid json was received.");
1187 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1188 Response errorResp = buildErrorResponse(responseFormat);
1189 responseWrapper.setInnerElement(errorResp);
1191 String payloadData = Base64.encodeBase64String(data);
1192 uploadServiceInfoWrapper.setPayloadData(payloadData);
1193 log.debug("enter fillServicePayloadDataFromFile,get payloadData:{}", uploadServiceInfoWrapper.getPayloadData());
1194 log.debug("enter fillServicePayloadDataFromFile,get uploadService:{}", uploadServiceInfoWrapper);
1195 } catch (IOException e) {
1196 log.info("Invalid json was received or Error while closing input Stream.");
1197 log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
1198 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1199 Response errorResp = buildErrorResponse(responseFormat);
1200 responseWrapper.setInnerElement(errorResp);
1204 private void fillServiceToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user,
1205 UploadServiceInfo serviceInfo) {
1206 if (serviceInfo.getPayloadData() == null || serviceInfo.getPayloadData().isEmpty()) {
1207 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
1208 Response errorResponse = buildErrorResponse(responseFormat);
1209 getComponentsUtils().auditResource(responseFormat, user, serviceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
1210 responseWrapper.setInnerElement(errorResponse);
1212 String toscaPayload = serviceInfo.getPayloadData();
1213 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
1214 yamlStringWrapper.setInnerElement(decodedPayload);