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 * ================================================================================
23 package org.openecomp.sdc.be.servlets;
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import com.google.gson.Gson;
27 import com.google.gson.JsonSyntaxException;
28 import fj.data.Either;
30 import java.io.FileInputStream;
31 import java.io.FileNotFoundException;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.lang.reflect.Type;
35 import java.nio.charset.StandardCharsets;
36 import java.util.Arrays;
37 import java.util.HashMap;
38 import java.util.List;
40 import java.util.Optional;
41 import java.util.function.Supplier;
42 import javax.servlet.ServletContext;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.ws.rs.core.Response;
45 import org.apache.commons.codec.binary.Base64;
46 import org.apache.commons.collections4.MapUtils;
47 import org.apache.commons.io.IOUtils;
48 import org.apache.commons.lang3.StringUtils;
49 import org.apache.commons.lang3.tuple.ImmutablePair;
50 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
52 import org.openecomp.sdc.be.components.impl.ImportUtils;
53 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
54 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
55 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
56 import org.openecomp.sdc.be.components.impl.ServiceImportManager;
57 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
58 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
59 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
60 import org.openecomp.sdc.be.config.BeEcompErrorManager;
61 import org.openecomp.sdc.be.config.ConfigurationManager;
62 import org.openecomp.sdc.be.dao.api.ActionStatus;
63 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
64 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
65 import org.openecomp.sdc.be.impl.ComponentsUtils;
66 import org.openecomp.sdc.be.impl.ServletUtils;
67 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
68 import org.openecomp.sdc.be.model.ArtifactDefinition;
69 import org.openecomp.sdc.be.model.Component;
70 import org.openecomp.sdc.be.model.Resource;
71 import org.openecomp.sdc.be.model.Service;
72 import org.openecomp.sdc.be.model.UploadResourceInfo;
73 import org.openecomp.sdc.be.model.UploadServiceInfo;
74 import org.openecomp.sdc.be.model.User;
75 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
76 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
77 import org.openecomp.sdc.be.servlets.ServiceUploadServlet.ServiceAuthorityTypeEnum;
78 import org.openecomp.sdc.be.user.Role;
79 import org.openecomp.sdc.be.user.UserBusinessLogic;
80 import org.openecomp.sdc.be.utils.TypeUtils;
81 import org.openecomp.sdc.common.api.Constants;
82 import org.openecomp.sdc.common.api.UploadArtifactInfo;
83 import org.openecomp.sdc.common.datastructure.Wrapper;
84 import org.openecomp.sdc.common.log.wrappers.Logger;
85 import org.openecomp.sdc.common.util.GeneralUtility;
86 import org.openecomp.sdc.common.util.YamlToObjectConverter;
87 import org.openecomp.sdc.common.zip.ZipUtils;
88 import org.openecomp.sdc.common.zip.exception.ZipException;
89 import org.openecomp.sdc.exception.ResponseFormat;
90 import org.springframework.web.context.WebApplicationContext;
91 import org.yaml.snakeyaml.Yaml;
93 public abstract class AbstractValidationsServlet extends BeGenericServlet {
95 private static final Logger log = Logger.getLogger(AbstractValidationsServlet.class);
96 private static final String TOSCA_SIMPLE_YAML_PREFIX = "tosca_simple_yaml_";
97 private static final List<String> TOSCA_DEFINITION_VERSIONS = Arrays.asList(
98 TOSCA_SIMPLE_YAML_PREFIX + "1_0_0",
99 TOSCA_SIMPLE_YAML_PREFIX + "1_1_0",
100 "tosca_simple_profile_for_nfv_1_0_0",
101 TOSCA_SIMPLE_YAML_PREFIX + "1_0",
102 TOSCA_SIMPLE_YAML_PREFIX + "1_1",
103 TOSCA_SIMPLE_YAML_PREFIX + "1_2",
104 TOSCA_SIMPLE_YAML_PREFIX + "1_3");
105 private static final List<String> TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(".yml", ".yaml", ".csar", ".meta");
107 protected ServletUtils servletUtils;
108 protected ResourceImportManager resourceImportManager;
109 protected final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
111 protected ServiceImportManager serviceImportManager;
113 public AbstractValidationsServlet(UserBusinessLogic userBusinessLogic,
114 ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils,
115 ServletUtils servletUtils, ResourceImportManager resourceImportManager) {
116 super(userBusinessLogic, componentsUtils);
117 this.servletUtils = servletUtils;
118 this.resourceImportManager = resourceImportManager;
119 this.componentInstanceBusinessLogic = componentInstanceBL;
122 protected void init() {
125 protected synchronized void initSpringFromContext() {
126 if (serviceImportManager == null) {
127 ServletContext context = servletRequest.getSession().getServletContext();
128 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
129 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
130 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
131 serviceImportManager = webApplicationContext.getBean(ServiceImportManager.class);
135 protected void validateResourceDoesNotExist(Wrapper<Response> responseWrapper, User user, String resourceName) {
136 if (resourceImportManager.isResourceExist(resourceName)) {
137 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
138 Response errorResponse = buildErrorResponse(responseFormat);
139 getComponentsUtils().auditResource(responseFormat, user, resourceName, AuditingActionEnum.IMPORT_RESOURCE);
140 responseWrapper.setInnerElement(errorResponse);
144 protected void validateUserExist(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, String userUserId) {
145 log.debug("get user {} from DB", userUserId);
147 if (userUserId == null) {
148 log.info("user userId is null");
149 Response response = returnMissingInformation(new User());
150 responseWrapper.setInnerElement(response);
154 UserBusinessLogic userAdmin = getServletUtils().getUserAdmin();
156 User user = userAdmin.getUser(userUserId);
157 userWrapper.setInnerElement(user);
158 } catch (ComponentException ce) {
159 log.info("user is not listed. userId={}", userUserId);
160 User user = new User();
161 user.setUserId(userUserId);
162 Response response = returnMissingInformation(user);
163 responseWrapper.setInnerElement(response);
168 protected Response returnMissingInformation(User user) {
169 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION);
170 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
171 return buildErrorResponse(responseFormat);
174 protected void validateDataNotNull(Wrapper<Response> responseWrapper, Object... dataParams) {
175 for (Object dataElement : dataParams) {
176 if (dataElement == null) {
177 log.info("Invalid body was received.");
178 Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
179 responseWrapper.setInnerElement(response);
186 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user) {
187 log.debug("validate user role");
188 if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) {
189 log.info("user is not in appropriate role to perform action");
190 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
191 log.debug("audit before sending response");
192 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
194 Response response = buildErrorResponse(responseFormat);
195 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 =
204 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
205 responseWrapper.setInnerElement(errorResponse);
208 final Map<String, byte[]> unzippedFolder;
210 unzippedFolder = ZipUtils.readZip(zipFile, false);
211 } catch (final ZipException e) {
212 log.error("Could not read ZIP file '{}' for validation", zipFile.getName(), e);
213 final Response errorResponse =
214 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
215 responseWrapper.setInnerElement(errorResponse);
218 if (!unzippedFolder.containsKey(payloadName)) {
219 log.info("Could no find payload '{}' in ZIP file '{}'", payloadName, zipFile.getName());
220 final Response errorResponse =
221 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
222 responseWrapper.setInnerElement(errorResponse);
228 protected void validateCsar(final Wrapper<Response> responseWrapper, final File csarFile, final String payloadName) {
229 if (StringUtils.isEmpty(payloadName)) {
230 log.info("Invalid JSON was received. Payload name is empty");
231 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
232 responseWrapper.setInnerElement(errorResponse);
235 final Map<String, byte[]> unzippedFolder;
237 unzippedFolder = ZipUtils.readZip(csarFile, false);
238 } catch (final ZipException e) {
239 log.error("Could not read CSAR file '{}' for validation", csarFile.getName(), e);
240 final Response errorResponse =
241 buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
242 responseWrapper.setInnerElement(errorResponse);
245 if (unzippedFolder.isEmpty()) {
246 log.info("The CSAR file is empty");
247 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
248 responseWrapper.setInnerElement(errorResponse);
253 protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
254 extractZipContents(yamlStringWrapper, file);
257 public static void extractZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
258 final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
259 String ymlName = unzippedFolder.keySet().iterator().next();
260 fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file);
263 private static void fillToscaTemplateFromZip(final Wrapper<String> yamlStringWrapper, final String payloadName,
264 final File file) throws ZipException {
265 final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
266 final byte[] yamlFileInBytes = unzippedFolder.get(payloadName);
267 final String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8);
268 log.debug("received yaml: {}", yamlAsString);
269 yamlStringWrapper.setInnerElement(yamlAsString);
272 protected void fillPayloadDataFromFile(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfoWrapper, File file) {
273 try(InputStream fileInputStream = new FileInputStream(file)){
275 byte [] data = new byte[(int)file.length()];
276 if( fileInputStream.read(data) == -1){
277 log.info("Invalid json was received.");
278 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
280 Response errorResp = buildErrorResponse(responseFormat);
281 responseWrapper.setInnerElement(errorResp);
283 String payloadData = Base64.encodeBase64String(data);
284 uploadResourceInfoWrapper.setPayloadData(payloadData);
288 } catch (IOException e) {
289 log.info("Invalid json was received or Error while closing input Stream.");
290 log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
291 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
293 Response errorResp = buildErrorResponse(responseFormat);
294 responseWrapper.setInnerElement(errorResp);
299 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) {
300 log.debug("validate user role");
301 if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
302 if (!user.getRole().equals(Role.ADMIN.name())) {
303 log.info("user is not in appropriate role to perform action");
304 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
305 log.debug("audit before sending response");
306 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
308 Response response = buildErrorResponse(responseFormat);
309 errorResponseWrapper.setInnerElement(response);
312 validateUserRole(errorResponseWrapper, user);
317 protected void validateAndFillResourceJson(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, User user, ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) {
320 log.debug("The received json is {}", resourceInfo);
321 UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class);
322 if (resourceInfoObject == null) {
325 if (!resourceAuthorityEnum.isBackEndImport()) {
326 isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty();
327 //only resource name is checked
331 uploadResourceInfoWrapper.setInnerElement(resourceInfoObject);
334 } catch (JsonSyntaxException e) {
335 log.debug("Invalid json was received. {}", e.getMessage(), e);
340 log.info("Invalid json was received.");
341 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
342 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
343 Response errorResp = buildErrorResponse(responseFormat);
344 responseWrapper.setInnerElement(errorResp);
348 protected void validateAuthorityType(Wrapper<Response> responseWrapper, String authorityType) {
349 log.debug("The received authority type is {}", authorityType);
350 ResourceAuthorityTypeEnum authorityTypeEnum = ResourceAuthorityTypeEnum.findByUrlPath(authorityType);
351 if (authorityTypeEnum == null) {
352 log.info("Invalid authority type was received.");
353 Response errorResp = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
354 responseWrapper.setInnerElement(errorResp);
358 public ServletUtils getServletUtils() {
362 public Gson getGson() {
363 return getServletUtils().getGson();
366 public ComponentsUtils getComponentsUtils() {
367 return getServletUtils().getComponentsUtils();
370 protected void validatePayloadIsTosca(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
371 log.debug("checking payload is valid tosca");
373 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
374 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
376 if (findFirstToscaStringElement.isRight()) {
379 String defenitionVersionFound = findFirstToscaStringElement.left().value();
380 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
383 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
388 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
389 Response errorResponse = buildErrorResponse(responseFormat);
390 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
391 responseWrapper.setInnerElement(errorResponse);
396 protected void validatePayloadIsYml(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaTamplatePayload) {
397 log.debug("checking tosca template is valid yml");
398 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
399 boolean isYamlValid = yamlConvertor.isValidYaml(toscaTamplatePayload.getBytes());
401 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
402 Response errorResponse = buildErrorResponse(responseFormat);
403 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
404 responseWrapper.setInnerElement(errorResponse);
409 * Gets the Resource type from the given node type name.
411 * @param nodeTypeFullName - Node type Name
412 * @return Resource Type name
414 private String getResourceType(final String nodeTypeFullName) {
416 final Optional<String> nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
417 if (nodeTypeNamePrefix.isPresent()) {
418 final String nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.get().length());
419 final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
420 if (findTypes.length > 0) {
421 final ResourceTypeEnum resourceType = ResourceTypeEnum.getType(findTypes[0].toUpperCase());
422 if (resourceType != null) {
423 return resourceType.name();
427 return ResourceTypeEnum.VFC.name();
431 * Extracts the Node Type Name prefix from the given Node Type Name.
432 * @param nodeName - Node Type Name
433 * @return Node Type Name prefix
435 private Optional<String> getNodeTypeNamePrefix(final String nodeName) {
436 final List<String> definedNodeTypeNamespaceList = ConfigurationManager.getConfigurationManager()
437 .getConfiguration().getDefinedResourceNamespace();
438 for (final String validNamespace : definedNodeTypeNamespaceList) {
439 if (nodeName.startsWith(validNamespace)) {
440 return Optional.of(validNamespace);
443 return Optional.empty();
446 protected void validatePayloadNameSpace(final Wrapper<Response> responseWrapper,
447 final UploadResourceInfo resourceInfo,
448 final User user, final String toscaPayload) {
450 String namespace = "";
451 final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
452 final Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
453 if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
456 namespace = toscaElement.left().value().keySet().iterator().next();
457 isValid = getNodeTypeNamePrefix(namespace).isPresent();
460 final ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE);
461 final Response errorResponse = buildErrorResponse(responseFormat);
462 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
463 responseWrapper.setInnerElement(errorResponse);
465 resourceInfo.setResourceType(getResourceType(namespace));
469 private void validatePayloadIsSingleResource(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
470 log.debug("checking payload contains single resource");
472 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
473 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
474 if (toscaElement.isRight()) {
477 isValid = toscaElement.left().value().size() == 1;
481 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_SINGLE_RESOURCE);
482 Response errorResponse = buildErrorResponse(responseFormat);
483 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
484 responseWrapper.setInnerElement(errorResponse);
489 private void validatePayloadIsNotService(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaPayload) {
490 log.debug("checking payload is not a tosca service");
491 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
492 Either<Object, ResultStatusEnum> toscaElement = ImportUtils.findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL);
494 if (toscaElement.isLeft()) {
495 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE);
496 Response errorResponse = buildErrorResponse(responseFormat);
497 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
498 responseWrapper.setInnerElement(errorResponse);
503 private void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
504 String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName();
505 boolean isValidSuffix = isToscaTemplatePayloadNameValid(responseWrapper, toscaTemplatePayloadName);
506 if (!isValidSuffix) {
507 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
508 Response errorResponse = buildErrorResponse(responseFormat);
509 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
510 responseWrapper.setInnerElement(errorResponse);
514 private boolean isToscaTemplatePayloadNameValid(Wrapper<Response> responseWrapper, String toscaTemplatePayloadName) {
515 boolean isValidSuffix = false;
516 if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) {
517 for (String validSuffix : TOSCA_YML_CSAR_VALID_SUFFIX) {
518 isValidSuffix = isValidSuffix || toscaTemplatePayloadName.toLowerCase().endsWith(validSuffix);
521 return isValidSuffix;
524 private void validateMD5(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request, String resourceInfoJsonString) {
526 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
527 if (recievedMD5 == null) {
530 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(resourceInfoJsonString);
531 isValid = calculateMD5.equals(recievedMD5);
534 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM);
535 Response errorResponse = buildErrorResponse(responseFormat);
536 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
537 responseWrapper.setInnerElement(errorResponse);
541 ComponentTypeEnum validateComponentType(String componentType) {
542 if (componentType == null) {
543 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR);
545 if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) {
546 return ComponentTypeEnum.RESOURCE;
548 if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) {
549 return ComponentTypeEnum.SERVICE;
551 log.debug("Invalid componentType:{}", componentType);
552 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR, componentType);
556 ComponentTypeEnum convertToComponentType(String componentType) {
557 return validateComponentType(componentType);
560 private void fillToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo resourceInfo) {
561 if (resourceInfo.getPayloadData() == null || resourceInfo.getPayloadData().isEmpty()) {
562 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
563 Response errorResponse = buildErrorResponse(responseFormat);
564 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
565 responseWrapper.setInnerElement(errorResponse);
567 String toscaPayload = resourceInfo.getPayloadData();
568 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
569 yamlStringWrapper.setInnerElement(decodedPayload);
574 void fillPayload(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, String resourceInfoJsonString, ResourceAuthorityTypeEnum resourceAuthorityEnum,
575 File file) throws ZipException {
577 if (responseWrapper.isEmpty()) {
578 if (resourceAuthorityEnum.isBackEndImport()) {
579 // PrePayload Validations
580 if (responseWrapper.isEmpty()) {
581 validateDataNotNull(responseWrapper, file, resourceInfoJsonString);
583 if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){
584 if (responseWrapper.isEmpty()) {
585 validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
588 // Fill PayLoad From File
589 if (responseWrapper.isEmpty()) {
590 fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file);
594 if (responseWrapper.isEmpty()) {
595 validateCsar(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
598 // Fill PayLoad From File
599 if (responseWrapper.isEmpty()) {
600 fillPayloadDataFromFile(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), file);
606 // Fill PayLoad From JSON
607 if (responseWrapper.isEmpty()) {
608 fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement());
616 protected void specificResourceAuthorityValidations(final Wrapper<Response> responseWrapper,
617 final Wrapper<UploadResourceInfo> uploadResourceInfoWrapper,
618 final Wrapper<String> yamlStringWrapper, final User user,
619 final HttpServletRequest request, final String resourceInfoJsonString,
620 final ResourceAuthorityTypeEnum resourceAuthorityEnum) {
622 if (responseWrapper.isEmpty()) {
623 // UI Only Validation
624 if (!resourceAuthorityEnum.isBackEndImport()) {
625 importUIValidations(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, request, resourceInfoJsonString);
628 // User Defined Type Resources
629 if (resourceAuthorityEnum.isUserTypeResource()
630 && !CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())
631 && responseWrapper.isEmpty()) {
632 validatePayloadNameSpace(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement());
637 void commonGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, ResourceAuthorityTypeEnum resourceAuthorityEnum, String userId,
638 String resourceInfoJsonString) {
640 if (responseWrapper.isEmpty()) {
641 validateUserExist(responseWrapper, userWrapper, userId);
644 if (responseWrapper.isEmpty()) {
645 validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum);
648 if (responseWrapper.isEmpty()) {
649 validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum, resourceInfoJsonString);
652 if (responseWrapper.isEmpty()) {
653 validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
655 if (responseWrapper.isEmpty()) {
656 validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
661 private void validateResourceType(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
662 String resourceType = uploadResourceInfo.getResourceType();
663 if (resourceType == null || !ResourceTypeEnum.containsName(resourceType)) {
664 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
665 Response errorResponse = buildErrorResponse(responseFormat);
666 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
667 responseWrapper.setInnerElement(errorResponse);
671 private void importUIValidations(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, HttpServletRequest request, String resourceInfoJsonString) {
672 if (responseWrapper.isEmpty()) {
673 validateMD5(responseWrapper, user, resourceInfo, request, resourceInfoJsonString);
675 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
676 validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName());
680 void commonPayloadValidations(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) {
682 if (responseWrapper.isEmpty()) {
683 validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
685 if (responseWrapper.isEmpty()) {
686 validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
688 if (responseWrapper.isEmpty()) {
689 validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
691 if (responseWrapper.isEmpty()) {
692 validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
697 void handleImport(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfoObject, String yamlAsString, ResourceAuthorityTypeEnum authority, boolean createNewVersion, String resourceUniqueId) {
698 ImmutablePair<Resource, ActionStatus> createOrUpdateResponse = null;
699 Response response = null;
700 Object representation = null;
701 ImmutablePair<Resource, ActionStatus> importedResourceStatus = null;
702 if (CsarValidationUtils.isCsarPayloadName(resourceInfoObject.getPayloadName())) {
703 log.debug("import resource from csar");
704 importedResourceStatus = importResourceFromUICsar(resourceInfoObject, user, resourceUniqueId);
705 } else if (!authority.isUserTypeResource()) {
706 log.debug("import normative type resource");
707 createOrUpdateResponse = resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, user, createNewVersion, true);
709 log.debug("import user resource (not normative type)");
710 createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user, false);
712 if (createOrUpdateResponse!= null){
713 importedResourceStatus = createOrUpdateResponse;
715 if(importedResourceStatus != null){
717 representation = RepresentationUtils.toRepresentation(importedResourceStatus.left);
718 } catch (IOException e) {
719 log.debug("Error while building resource representation : {}", e.getMessage(), e);
721 response = buildOkResponse(getComponentsUtils().getResponseFormat(importedResourceStatus.right), representation);
723 responseWrapper.setInnerElement(response);
726 private ImmutablePair<Resource, ActionStatus> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user, String resourceUniqueId) {
728 Resource newResource;
729 ActionStatus actionStatus;
730 Resource resource = new Resource();
731 String payloadName = resourceInfoObject.getPayloadName();
732 fillResourceFromResourceInfoObject(resource, resourceInfoObject);
734 Map<String, byte[]> csarUIPayload = getCsarFromPayload(resourceInfoObject);
735 getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName);
737 if (resourceUniqueId == null || resourceUniqueId.isEmpty()) {
738 newResource = resourceImportManager.getResourceBusinessLogic().createResource(resource, AuditingActionEnum.CREATE_RESOURCE, user, csarUIPayload, payloadName);
739 actionStatus = ActionStatus.CREATED;
741 newResource = resourceImportManager.getResourceBusinessLogic().validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId);
742 actionStatus = ActionStatus.OK;
744 return new ImmutablePair<>(newResource, actionStatus);
747 protected Resource throwComponentException(ResponseFormat responseFormat) {
748 throw new ByResponseFormatComponentException(responseFormat);
751 private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Resource resource, User user, String csarUUID) {
752 getAndValidateComponentCsarYaml(csarUIPayload, resource, user, csarUUID);
755 private void getAndValidateComponentCsarYaml(Map<String, byte[]> csarUIPayload, Component component, User user, String csarUUID) {
757 Either<ImmutablePair<String, String>, ResponseFormat> getToscaYamlRes = CsarValidationUtils.getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils());
759 if (getToscaYamlRes.isRight()) {
760 ResponseFormat responseFormat = getToscaYamlRes.right().value();
761 log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
762 if (component instanceof Resource) {
763 BeEcompErrorManager.getInstance()
764 .logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
765 getComponentsUtils().auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.CREATE_RESOURCE);
767 BeEcompErrorManager.getInstance()
768 .logBeDaoSystemError("Creating service from CSAR: fetching CSAR with id " + csarUUID + " failed");
770 throwComponentException(responseFormat);
772 String toscaYaml = getToscaYamlRes.left().value().getValue();
774 log.debug("checking tosca template is valid yml");
775 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
776 boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes());
778 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
779 if (component instanceof Resource) {
780 getComponentsUtils().auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.IMPORT_RESOURCE);
782 throwComponentException(responseFormat);
785 log.debug("checking payload is valid tosca");
786 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaYaml);
787 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
789 if (findFirstToscaStringElement.isRight()) {
792 String defenitionVersionFound = findFirstToscaStringElement.left().value();
793 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
796 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
801 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
802 if (component instanceof Resource) {
803 log.debug("enter getAndValidateComponentCsarYaml,component instanceof Resource");
804 getComponentsUtils().auditResource(responseFormat, user, (Resource)component, AuditingActionEnum.IMPORT_RESOURCE);
806 throwComponentException(responseFormat);
810 private void fillResourceFromResourceInfoObject(Resource resource, UploadResourceInfo resourceInfoObject) {
811 resourceImportManager.populateResourceMetadata(resourceInfoObject, resource);
812 fillArtifacts(resource, resourceInfoObject);
816 private void fillArtifacts(Resource resource, UploadResourceInfo resourceInfoObject) {
817 if (resource != null && resourceInfoObject != null) {
818 List<UploadArtifactInfo> artifactList = resourceInfoObject.getArtifactList();
819 if (artifactList != null) {
820 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
821 buildArtifactsHM(artifactList, artifactsHM);
822 resource.setArtifacts(artifactsHM);
827 private void buildArtifactsHM(List<UploadArtifactInfo> artifactList, Map<String, ArtifactDefinition> artifactsHM){
828 for (UploadArtifactInfo artifact : artifactList) {
829 ArtifactDefinition artifactDef = new ArtifactDefinition();
830 artifactDef.setArtifactName(artifact.getArtifactName());
831 artifactDef.setArtifactType(artifact.getArtifactType().getType());
832 artifactDef.setDescription(artifact.getArtifactDescription());
833 artifactDef.setPayloadData(artifact.getArtifactData());
834 artifactDef.setArtifactRef(artifact.getArtifactPath());
835 artifactsHM.put(artifactDef.getArtifactName(), artifactDef);
839 private Map<String, byte[]> getCsarFromPayload(UploadResourceInfo innerElement) {
840 String csarUUID = innerElement.getPayloadName();
841 String payloadData = innerElement.getPayloadData();
843 return getComponentCsarFromPayload(csarUUID, payloadData);
846 private Map<String, byte[]> getComponentCsarFromPayload(String csarUUID, String payloadData){
847 if (payloadData == null) {
848 log.info("Failed to decode received csar {}", csarUUID);
849 throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
852 byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8));
853 if (decodedPayload == null) {
854 log.info("Failed to decode received csar {}", csarUUID);
855 throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
858 Map<String, byte[]> csar = null;
860 csar = ZipUtils.readZip(decodedPayload, false);
861 } catch (final ZipException e) {
862 log.info("Failed to unzip received csar {}", csarUUID, e);
867 void validateInputStream(final HttpServletRequest request, Wrapper<String> dataWrapper, Wrapper<ResponseFormat> errorWrapper) throws IOException {
868 InputStream inputStream = request.getInputStream();
869 byte[] bytes = IOUtils.toByteArray(inputStream);
870 if (bytes == null || bytes.length == 0) {
871 log.info("Empty body was sent.");
872 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
874 dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8));
879 <T> void validateClassParse(String data, Wrapper<T> parsedClassWrapper, Supplier<Class<T>> classGen, Wrapper<ResponseFormat> errorWrapper) {
881 T parsedClass = gson.fromJson(data, classGen.get());
882 if (parsedClass == null) {
883 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
885 parsedClassWrapper.setInnerElement(parsedClass);
887 } catch (JsonSyntaxException e) {
888 log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e);
889 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
893 void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType, Wrapper<ComponentInstanceBusinessLogic> blWrapper, Wrapper<ResponseFormat> errorWrapper) {
894 ServletContext context = request.getSession().getServletContext();
895 ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context);
896 if (componentInstanceLogic == null) {
897 log.debug("Unsupported component type {}", containerComponentType);
898 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
900 blWrapper.setInnerElement(componentInstanceLogic);
904 <T> Response buildResponseFromElement(Wrapper<ResponseFormat> errorWrapper, Wrapper<T> attributeWrapper) throws IOException {
906 if (errorWrapper.isEmpty()) {
907 ObjectMapper mapper = new ObjectMapper();
908 String result = mapper.writeValueAsString(attributeWrapper.getInnerElement());
909 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
911 response = buildErrorResponse(errorWrapper.getInnerElement());
916 protected void validateXECOMPInstanceIDHeader(String instanceIdHeader, Wrapper<ResponseFormat> responseWrapper) {
917 ResponseFormat responseFormat;
918 if(StringUtils.isEmpty(instanceIdHeader) ){
919 log.debug("Missing X-ECOMP-InstanceID header");
920 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
921 responseWrapper.setInnerElement(responseFormat);
925 protected void validateHttpCspUserIdHeader(String header, Wrapper<ResponseFormat> responseWrapper) {
926 ResponseFormat responseFormat;
927 if( StringUtils.isEmpty(header)){
928 log.debug("MissingUSER_ID");
929 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
930 responseWrapper.setInnerElement(responseFormat);
934 <T> Either<T, ResponseFormat> parseToObject(String json, Supplier<Class<T>> classSupplier) {
937 T object = RepresentationUtils.fromRepresentation(json, classSupplier.get());
938 return Either.left(object);
939 } catch (Exception e) {
940 log.debug("Failed to parse json to {} object", classSupplier.get().getName(), e);
941 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
942 return Either.right(responseFormat);
946 public <T> Either<List<T>, ResponseFormat> parseListOfObjects(String json, Type type) {
948 List<T> listOfObjects = gson.fromJson(json, type);
949 return Either.left(listOfObjects);
950 } catch (Exception e) {
951 log.debug("Failed to parse json to {} object", type.getClass().getName(), e);
952 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
953 return Either.right(responseFormat);
956 protected void validateNotEmptyBody(String data) {
957 if (StringUtils.isEmpty(data)) {
958 throw new ByActionStatusComponentException(ActionStatus.MISSING_BODY);
962 protected void commonServiceGeneralValidations(
963 Wrapper<Response> responseWrapper, Wrapper<User> userWrapper,
964 Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, ServiceAuthorityTypeEnum serviceAuthorityEnum,
966 String serviceInfoJsonString) {
968 if (responseWrapper.isEmpty()) {
969 validateUserExist(responseWrapper, userWrapper, userUserId);
972 if (responseWrapper.isEmpty()) {
973 validateUserRole(responseWrapper, userWrapper.getInnerElement(), serviceAuthorityEnum);
976 if (responseWrapper.isEmpty()) {
977 validateAndFillServiceJson(responseWrapper, uploadServiceInfoWrapper, userWrapper.getInnerElement(),
978 serviceAuthorityEnum, serviceInfoJsonString);
981 if (responseWrapper.isEmpty()) {
982 validateToscaTemplatePayloadName(responseWrapper, uploadServiceInfoWrapper.getInnerElement(),
983 userWrapper.getInnerElement());
988 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user,
989 ServiceAuthorityTypeEnum serviceAuthority) {
990 log.debug("validate user role");
991 if (serviceAuthority == ServiceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
992 if (!user.getRole().equals(Role.ADMIN.name())) {
993 log.info("user is not in appropriate role to perform action");
994 ResponseFormat responseFormat =
995 getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
996 log.debug("audit before sending response");
997 Response response = buildErrorResponse(responseFormat);
998 errorResponseWrapper.setInnerElement(response);
1001 validateUserRole(errorResponseWrapper, user);
1006 protected void validateAndFillServiceJson(Wrapper<Response> responseWrapper,
1007 Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, User user,
1008 ServiceAuthorityTypeEnum serviceAuthorityEnum, String serviceInfo) {
1011 log.debug("The received json is {}", serviceInfo);
1012 UploadServiceInfo serviceInfoObject = gson.fromJson(serviceInfo, UploadServiceInfo.class);
1013 if (serviceInfoObject == null) {
1016 if (!serviceAuthorityEnum.isBackEndImport()) {
1018 serviceInfoObject.getPayloadName() != null && !serviceInfoObject.getPayloadName().isEmpty();
1019 //only service name is checked
1023 uploadServiceInfoWrapper.setInnerElement(serviceInfoObject);
1024 log.debug("get isValid:{},serviceInfoObject get name:{},get tags:{},getContactId:{}," +
1025 " getPayloadName:{}",isValid,
1026 uploadServiceInfoWrapper.getInnerElement().getName(),
1027 uploadServiceInfoWrapper.getInnerElement().getTags(),
1028 uploadServiceInfoWrapper.getInnerElement().getContactId(),
1029 uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1032 } catch (JsonSyntaxException e) {
1033 log.debug("enter validateAndFillServiceJson,Invalid json was received. {}", e.getMessage(), e);
1038 log.info("Invalid json was received.");
1039 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1040 Response errorResp = buildErrorResponse(responseFormat);
1041 responseWrapper.setInnerElement(errorResp);
1045 protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper,
1046 UploadServiceInfo uploadServiceInfo, User user) {
1047 String toscaTemplatePayloadName = uploadServiceInfo.getPayloadName();
1048 boolean isValidSuffix = isToscaTemplatePayloadNameValid(responseWrapper, toscaTemplatePayloadName);
1049 if (!isValidSuffix) {
1050 ResponseFormat responseFormat =
1051 getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
1052 Response errorResponse = buildErrorResponse(responseFormat);
1053 responseWrapper.setInnerElement(errorResponse);
1059 protected void specificServiceAuthorityValidations(Wrapper<Response> responseWrapper,
1060 Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, Wrapper<String> yamlStringWrapper, User user,
1061 HttpServletRequest request, String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum)
1062 throws FileNotFoundException {
1064 if (responseWrapper.isEmpty()) {
1065 // UI Only Validation
1066 if (!serviceAuthorityEnum.isBackEndImport()) {
1067 importUIValidations(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user, request,
1068 serviceInfoJsonString);
1071 // User Defined Type Services
1072 if (serviceAuthorityEnum.isUserTypeService() && !CsarValidationUtils.isCsarPayloadName(
1073 uploadServiceInfoWrapper.getInnerElement().getPayloadName())) {
1074 if (responseWrapper.isEmpty()) {
1075 validatePayloadNameSpace(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), user,
1076 yamlStringWrapper.getInnerElement());
1083 protected void importUIValidations(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user,
1084 HttpServletRequest request, String serviceInfoJsonString) {
1085 if (responseWrapper.isEmpty()) {
1086 validateMD5(responseWrapper, user, serviceInfo, request, serviceInfoJsonString);
1088 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod()
1090 validateServiceDoesNotExist(responseWrapper, user, serviceInfo.getName());
1094 protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, User user,
1095 String toscaPayload) {
1097 String nameSpace = "";
1098 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
1099 Either<Map<String, Object>, ResultStatusEnum> toscaElement =
1100 ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
1101 if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
1104 nameSpace = toscaElement.left().value().keySet().iterator().next();
1105 isValid = nameSpace.startsWith(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX);
1106 log.debug("enter validatePayloadNameSpace,get nameSpace:{},get Valid is:{}",nameSpace,isValid);
1109 ResponseFormat responseFormat =
1110 getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_NAMESPACE);
1111 Response errorResponse = buildErrorResponse(responseFormat);
1112 responseWrapper.setInnerElement(errorResponse);
1114 String str1 = nameSpace.substring(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX.length());
1115 String[] findTypes = str1.split("\\.");
1116 if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) {
1117 String type = findTypes[0].toUpperCase();
1118 serviceInfo.setServiceType(type);
1120 serviceInfo.setServiceType(ResourceTypeEnum.SERVICE.name());
1126 protected void validateMD5(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfo,
1127 HttpServletRequest request, String serviceInfoJsonString) {
1129 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
1130 if (recievedMD5 == null) {
1133 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(serviceInfoJsonString);
1134 isValid = calculateMD5.equals(recievedMD5);
1137 ResponseFormat responseFormat =
1138 getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_CHECKSUM);
1139 Response errorResponse = buildErrorResponse(responseFormat);
1140 responseWrapper.setInnerElement(errorResponse);
1145 protected void validateServiceDoesNotExist(Wrapper<Response> responseWrapper, User user, String serviceName) {
1146 if (serviceImportManager.isServiceExist(serviceName)) {
1147 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.SERVICE_ALREADY_EXISTS);
1148 Response errorResponse = buildErrorResponse(responseFormat);
1149 responseWrapper.setInnerElement(errorResponse);
1153 protected void handleImportService(Wrapper<Response> responseWrapper, User user,
1154 UploadServiceInfo serviceInfoObject, String yamlAsString, ServiceAuthorityTypeEnum authority,
1155 boolean createNewVersion, String serviceUniqueId) throws ZipException {
1157 Response response = null;
1158 Object representation = null;
1159 ImmutablePair<Service, ActionStatus> importedServiceStatus = null;
1160 if (CsarValidationUtils.isCsarPayloadName(serviceInfoObject.getPayloadName())) {
1161 log.debug("import service from csar");
1162 importedServiceStatus = importServiceFromUICsar(serviceInfoObject, user, serviceUniqueId);
1165 if (importedServiceStatus != null) {
1167 representation = RepresentationUtils.toRepresentation(importedServiceStatus.left);
1168 } catch (IOException e) {
1169 log.debug("Error while building service representation : {}", e.getMessage(), e);
1171 response = buildOkResponse(getComponentsUtils().getResponseFormat(importedServiceStatus.right),
1174 responseWrapper.setInnerElement(response);
1177 private ImmutablePair<Service, ActionStatus> importServiceFromUICsar(UploadServiceInfo serviceInfoObject, User user,
1178 String serviceUniqueId) throws ZipException {
1181 ImmutablePair<Service, ActionStatus> result = null;
1182 ActionStatus actionStatus;
1183 Service service = new Service();
1184 String payloadName = serviceInfoObject.getPayloadName();
1185 fillServiceFromServiceInfoObject(service, serviceInfoObject);
1187 Map<String, byte[]> csarUIPayloadRes = getCsarFromPayload(serviceInfoObject);
1189 getAndValidateCsarYaml(csarUIPayloadRes, service, user, payloadName);
1191 newService = serviceImportManager.getServiceImportBusinessLogic()
1192 .createService(service, AuditingActionEnum.CREATE_SERVICE, user, csarUIPayloadRes,
1194 actionStatus = ActionStatus.CREATED;
1196 return new ImmutablePair<>(newService, actionStatus);
1200 private void fillServiceFromServiceInfoObject(Service service, UploadServiceInfo serviceInfoObject) {
1201 serviceImportManager.populateServiceMetadata(serviceInfoObject, service);
1202 fillArtifacts(service, serviceInfoObject);
1206 private Map<String, byte[]> getCsarFromPayload(UploadServiceInfo innerElement)
1207 throws ZipException {
1208 String csarUUID = innerElement.getPayloadName();
1209 String payloadData = innerElement.getPayloadData();
1210 return getComponentCsarFromPayload(csarUUID, payloadData);
1213 private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Service service, User user,
1215 getAndValidateComponentCsarYaml(csarUIPayload, service, user, csarUUID);
1218 private void fillArtifacts(Service service, UploadServiceInfo serviceInfoObject) {
1219 if (service != null && serviceInfoObject != null) {
1220 List<UploadArtifactInfo> artifactList = serviceInfoObject.getArtifactList();
1221 if (artifactList != null) {
1222 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
1223 buildArtifactsHM(artifactList, artifactsHM);
1224 service.setArtifacts(artifactsHM);
1229 * import service payload to postman
1230 * @param responseWrapper
1231 * @param uploadServiceInfoWrapper
1232 * @param yamlStringWrapper
1234 * @param serviceInfoJsonString
1235 * @param serviceAuthorityEnum
1237 * @throws ZipException
1239 protected void fillServicePayload(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum,
1240 File file) throws ZipException {
1241 log.debug("enter fillServicePayload");
1242 if (responseWrapper.isEmpty()) {
1243 log.debug("enter fillServicePayload,get responseWrapper is empty");
1244 if (serviceAuthorityEnum.isBackEndImport()) {
1245 // PrePayload Validations
1246 if (responseWrapper.isEmpty()) {
1247 validateDataNotNull(responseWrapper, file, serviceInfoJsonString);
1249 if (responseWrapper.isEmpty()){
1250 log.debug("enter fillServicePayload,responseWrapper is empty");
1252 if(!serviceAuthorityEnum.equals(ServiceAuthorityTypeEnum.CSAR_TYPE_BE)){
1253 if (responseWrapper.isEmpty()) {
1254 validateZip(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1257 // Fill PayLoad From File
1258 if (responseWrapper.isEmpty()) {
1259 fillToscaTemplateFromZip(yamlStringWrapper, uploadServiceInfoWrapper.getInnerElement().getPayloadName(), file);
1263 log.debug("enter fillServicePayload,ServiceAuthorityTypeEnum is CSAR_TYPE_BE");
1264 if (responseWrapper.isEmpty()) {
1265 validateCsar(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1267 if (!responseWrapper.isEmpty()) {
1268 log.debug("enter fillServicePayload,get responseWrapper:{}", responseWrapper);
1270 // Fill PayLoad From File
1271 if (responseWrapper.isEmpty()) {
1272 fillServicePayloadDataFromFile(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), file);
1278 // Fill PayLoad From JSON
1279 if (responseWrapper.isEmpty()) {
1280 fillServiceToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadServiceInfoWrapper.getInnerElement());
1288 protected void fillServicePayloadDataFromFile(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfoWrapper, File file) {
1289 try(InputStream fileInputStream = new FileInputStream(file)){
1291 log.debug("enter fillServicePayloadDataFromFile");
1292 byte [] data = new byte[(int)file.length()];
1293 if( fileInputStream.read(data) == -1){
1294 log.info("Invalid json was received.");
1295 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1297 Response errorResp = buildErrorResponse(responseFormat);
1298 responseWrapper.setInnerElement(errorResp);
1300 String payloadData = Base64.encodeBase64String(data);
1301 uploadServiceInfoWrapper.setPayloadData(payloadData);
1302 log.debug("enter fillServicePayloadDataFromFile,get payloadData:{}",
1303 uploadServiceInfoWrapper.getPayloadData());
1305 log.debug("enter fillServicePayloadDataFromFile,get uploadService:{}",uploadServiceInfoWrapper);
1307 } catch (IOException e) {
1308 log.info("Invalid json was received or Error while closing input Stream.");
1309 log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
1310 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1312 Response errorResp = buildErrorResponse(responseFormat);
1313 responseWrapper.setInnerElement(errorResp);
1317 private void fillServiceToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadServiceInfo serviceInfo) {
1318 if (serviceInfo.getPayloadData() == null || serviceInfo.getPayloadData().isEmpty()) {
1319 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
1320 Response errorResponse = buildErrorResponse(responseFormat);
1321 getComponentsUtils().auditResource(responseFormat, user, serviceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
1322 responseWrapper.setInnerElement(errorResponse);
1324 String toscaPayload = serviceInfo.getPayloadData();
1325 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
1326 yamlStringWrapper.setInnerElement(decodedPayload);