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.IOException;
31 import java.io.InputStream;
32 import java.lang.reflect.Type;
33 import java.nio.charset.StandardCharsets;
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.List;
38 import java.util.Optional;
39 import java.util.function.Supplier;
40 import javax.servlet.ServletContext;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.ws.rs.core.Response;
43 import org.apache.commons.codec.binary.Base64;
44 import org.apache.commons.io.IOUtils;
45 import org.apache.commons.lang3.StringUtils;
46 import org.apache.commons.lang3.tuple.ImmutablePair;
47 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
48 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
49 import org.openecomp.sdc.be.components.impl.ImportUtils;
50 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
51 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
52 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
53 import org.openecomp.sdc.be.components.impl.ServiceImportManager;
54 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
55 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
56 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
57 import org.openecomp.sdc.be.config.BeEcompErrorManager;
58 import org.openecomp.sdc.be.config.ConfigurationManager;
59 import org.openecomp.sdc.be.dao.api.ActionStatus;
60 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
61 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
62 import org.openecomp.sdc.be.impl.ComponentsUtils;
63 import org.openecomp.sdc.be.impl.ServletUtils;
64 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
65 import org.openecomp.sdc.be.model.ArtifactDefinition;
66 import org.openecomp.sdc.be.model.Component;
67 import org.openecomp.sdc.be.model.Resource;
68 import org.openecomp.sdc.be.model.Service;
69 import org.openecomp.sdc.be.model.UploadResourceInfo;
70 import org.openecomp.sdc.be.model.UploadServiceInfo;
71 import org.openecomp.sdc.be.model.User;
72 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
73 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
74 import org.openecomp.sdc.be.servlets.ServiceUploadServlet.ServiceAuthorityTypeEnum;
75 import org.openecomp.sdc.be.user.Role;
76 import org.openecomp.sdc.be.user.UserBusinessLogic;
77 import org.openecomp.sdc.be.utils.TypeUtils;
78 import org.openecomp.sdc.common.api.Constants;
79 import org.openecomp.sdc.common.api.UploadArtifactInfo;
80 import org.openecomp.sdc.common.datastructure.Wrapper;
81 import org.openecomp.sdc.common.log.wrappers.Logger;
82 import org.openecomp.sdc.common.util.GeneralUtility;
83 import org.openecomp.sdc.common.util.YamlToObjectConverter;
84 import org.openecomp.sdc.common.zip.ZipUtils;
85 import org.openecomp.sdc.common.zip.exception.ZipException;
86 import org.openecomp.sdc.exception.ResponseFormat;
87 import org.springframework.web.context.WebApplicationContext;
88 import org.yaml.snakeyaml.Yaml;
90 public abstract class AbstractValidationsServlet extends BeGenericServlet {
92 private static final Logger log = Logger.getLogger(AbstractValidationsServlet.class);
93 private static final String TOSCA_SIMPLE_YAML_PREFIX = "tosca_simple_yaml_";
94 private static final List<String> TOSCA_DEFINITION_VERSIONS = Arrays
95 .asList(TOSCA_SIMPLE_YAML_PREFIX + "1_0_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1_0", "tosca_simple_profile_for_nfv_1_0_0",
96 TOSCA_SIMPLE_YAML_PREFIX + "1_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1", TOSCA_SIMPLE_YAML_PREFIX + "1_2", TOSCA_SIMPLE_YAML_PREFIX + "1_3");
97 private static final List<String> TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(".yml", ".yaml", ".csar", ".meta");
98 private static final String INVALID_JSON_WAS_RECEIVED = "Invalid json was received.";
99 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
100 private static final String VALIDATE_USER_ROLE = "validate user role";
101 private static final String USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION = "user is not in appropriate role to perform action";
102 protected final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
103 protected ServletUtils servletUtils;
104 protected ResourceImportManager resourceImportManager;
105 protected ServiceImportManager serviceImportManager;
107 protected AbstractValidationsServlet(ComponentInstanceBusinessLogic componentInstanceBL,
108 ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager) {
109 super(componentsUtils);
110 this.servletUtils = servletUtils;
111 this.resourceImportManager = resourceImportManager;
112 this.componentInstanceBusinessLogic = componentInstanceBL;
115 public static void extractZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
116 final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
117 String ymlName = unzippedFolder.keySet().iterator().next();
118 fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file);
121 private static void fillToscaTemplateFromZip(final Wrapper<String> yamlStringWrapper, final String payloadName, final File file)
122 throws ZipException {
123 final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false);
124 final byte[] yamlFileInBytes = unzippedFolder.get(payloadName);
125 final String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8);
126 log.debug("received yaml: {}", yamlAsString);
127 yamlStringWrapper.setInnerElement(yamlAsString);
130 protected void init() {
133 protected synchronized void initSpringFromContext() {
134 if (serviceImportManager == null) {
135 ServletContext context = servletRequest.getSession().getServletContext();
136 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
137 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
138 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
139 serviceImportManager = webApplicationContext.getBean(ServiceImportManager.class);
143 protected void validateResourceDoesNotExist(Wrapper<Response> responseWrapper, User user, String resourceName) {
144 if (resourceImportManager.isResourceExist(resourceName)) {
145 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
146 Response errorResponse = buildErrorResponse(responseFormat);
147 getComponentsUtils().auditResource(responseFormat, user, resourceName, AuditingActionEnum.IMPORT_RESOURCE);
148 responseWrapper.setInnerElement(errorResponse);
152 protected void validateUserExist(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, String userUserId) {
153 log.debug("get user {} from DB", userUserId);
155 if (userUserId == null) {
156 log.info("user userId is null");
157 Response response = returnMissingInformation(new User());
158 responseWrapper.setInnerElement(response);
160 UserBusinessLogic userAdmin = getServletUtils().getUserAdmin();
162 User user = userAdmin.getUser(userUserId);
163 userWrapper.setInnerElement(user);
164 } catch (ComponentException ce) {
165 log.info("user is not listed. userId={}", userUserId);
166 User user = new User();
167 user.setUserId(userUserId);
168 Response response = returnMissingInformation(user);
169 responseWrapper.setInnerElement(response);
174 protected Response returnMissingInformation(User user) {
175 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION);
176 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
177 return buildErrorResponse(responseFormat);
180 protected void validateDataNotNull(Wrapper<Response> responseWrapper, Object... dataParams) {
181 for (Object dataElement : dataParams) {
182 if (dataElement == null) {
183 log.info("Invalid body was received.");
184 Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
185 responseWrapper.setInnerElement(response);
191 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user) {
192 log.debug(VALIDATE_USER_ROLE);
193 if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) {
194 log.info(USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION);
195 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
196 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
197 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
198 Response response = buildErrorResponse(responseFormat);
199 errorResponseWrapper.setInnerElement(response);
203 protected void validateZip(final Wrapper<Response> responseWrapper, final File zipFile, final String payloadName) {
204 if (StringUtils.isEmpty(payloadName)) {
205 log.info("Invalid JSON was received. Payload name is empty");
206 final Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
207 responseWrapper.setInnerElement(errorResponse);
210 final Map<String, byte[]> unzippedFolder;
212 unzippedFolder = ZipUtils.readZip(zipFile, false);
213 } catch (final ZipException e) {
214 log.error("Could not read ZIP file '{}' for validation", zipFile.getName(), e);
215 final Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
216 responseWrapper.setInnerElement(errorResponse);
219 if (!unzippedFolder.containsKey(payloadName)) {
220 log.info("Could no find payload '{}' in ZIP file '{}'", payloadName, zipFile.getName());
221 final Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
222 responseWrapper.setInnerElement(errorResponse);
226 protected void validateCsar(final Wrapper<Response> responseWrapper, final File csarFile, final String payloadName) {
227 if (StringUtils.isEmpty(payloadName)) {
228 log.info("Invalid JSON was received. Payload name is empty");
229 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
230 responseWrapper.setInnerElement(errorResponse);
233 final Map<String, byte[]> unzippedFolder;
235 unzippedFolder = ZipUtils.readZip(csarFile, false);
236 } catch (final ZipException e) {
237 log.error("Could not read CSAR file '{}' for validation", csarFile.getName(), e);
238 final Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
239 responseWrapper.setInnerElement(errorResponse);
242 if (unzippedFolder.isEmpty()) {
243 log.info("The CSAR file is empty");
244 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
245 responseWrapper.setInnerElement(errorResponse);
249 protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException {
250 extractZipContents(yamlStringWrapper, file);
253 protected void fillPayloadDataFromFile(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfoWrapper, File file) {
254 try (InputStream fileInputStream = new FileInputStream(file)) {
255 byte[] data = new byte[(int) file.length()];
256 if (fileInputStream.read(data) == -1) {
257 log.info(INVALID_JSON_WAS_RECEIVED);
258 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
259 Response errorResp = buildErrorResponse(responseFormat);
260 responseWrapper.setInnerElement(errorResp);
262 String payloadData = Base64.encodeBase64String(data);
263 uploadResourceInfoWrapper.setPayloadData(payloadData);
264 } catch (IOException e) {
265 log.info("Invalid json was received or Error while closing input Stream.");
266 log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
267 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
268 Response errorResp = buildErrorResponse(responseFormat);
269 responseWrapper.setInnerElement(errorResp);
273 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) {
274 log.debug(VALIDATE_USER_ROLE);
275 if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
276 if (!user.getRole().equals(Role.ADMIN.name())) {
277 log.info(USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION);
278 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
279 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
280 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
281 Response response = buildErrorResponse(responseFormat);
282 errorResponseWrapper.setInnerElement(response);
285 validateUserRole(errorResponseWrapper, user);
289 protected void validateAndFillResourceJson(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, User user,
290 ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) {
293 log.debug("The received json is {}", resourceInfo);
294 UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class);
295 if (resourceInfoObject == null) {
298 resourceInfoObject.setNormative(!resourceAuthorityEnum.isUserTypeResource());
299 if (!resourceAuthorityEnum.isBackEndImport()) {
300 isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty();
301 //only resource name is checked
305 uploadResourceInfoWrapper.setInnerElement(resourceInfoObject);
307 } catch (JsonSyntaxException e) {
308 log.debug("Invalid json was received. {}", e.getMessage(), e);
312 log.info(INVALID_JSON_WAS_RECEIVED);
313 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
314 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
315 Response errorResp = buildErrorResponse(responseFormat);
316 responseWrapper.setInnerElement(errorResp);
320 protected void validateAuthorityType(Wrapper<Response> responseWrapper, String authorityType) {
321 log.debug("The received authority type is {}", authorityType);
322 ResourceAuthorityTypeEnum authorityTypeEnum = ResourceAuthorityTypeEnum.findByUrlPath(authorityType);
323 if (authorityTypeEnum == null) {
324 log.info("Invalid authority type was received.");
325 Response errorResp = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
326 responseWrapper.setInnerElement(errorResp);
330 public ServletUtils getServletUtils() {
334 public Gson getGson() {
335 return getServletUtils().getGson();
339 public ComponentsUtils getComponentsUtils() {
340 return getServletUtils().getComponentsUtils();
343 protected void validatePayloadIsTosca(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
344 log.debug("checking payload is valid tosca");
346 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
347 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils
348 .findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
349 if (findFirstToscaStringElement.isRight()) {
352 String defenitionVersionFound = findFirstToscaStringElement.left().value();
353 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
356 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
360 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
361 Response errorResponse = buildErrorResponse(responseFormat);
362 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
363 responseWrapper.setInnerElement(errorResponse);
367 protected void validatePayloadIsYml(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo,
368 String toscaTamplatePayload) {
369 log.debug("checking tosca template is valid yml");
370 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
371 boolean isYamlValid = yamlConvertor.isValidYaml(toscaTamplatePayload.getBytes());
373 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
374 Response errorResponse = buildErrorResponse(responseFormat);
375 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
376 responseWrapper.setInnerElement(errorResponse);
381 * Gets the Resource type from the given node type name.
383 * @param nodeTypeFullName - Node type Name
384 * @return Resource Type name
386 private String getResourceType(final String nodeTypeFullName) {
387 final Optional<String> nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName);
388 if (nodeTypeNamePrefix.isPresent()) {
389 final String nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.get().length());
390 final String[] findTypes = nameWithouNamespacePrefix.split("\\.");
391 if (findTypes.length > 0) {
392 final ResourceTypeEnum resourceType = ResourceTypeEnum.getType(findTypes[0].toUpperCase());
393 if (resourceType != null) {
394 return resourceType.name();
398 return ResourceTypeEnum.VFC.name();
402 * Extracts the Node Type Name prefix from the given Node Type Name.
404 * @param nodeName - Node Type Name
405 * @return Node Type Name prefix
407 private Optional<String> getNodeTypeNamePrefix(final String nodeName) {
408 final List<String> definedNodeTypeNamespaceList = ConfigurationManager.getConfigurationManager().getConfiguration()
409 .getDefinedResourceNamespace();
410 for (final String validNamespace : definedNodeTypeNamespaceList) {
411 if (nodeName.startsWith(validNamespace)) {
412 return Optional.of(validNamespace);
415 return Optional.empty();
418 protected void validatePayloadNameSpace(final Wrapper<Response> responseWrapper, final UploadResourceInfo resourceInfo, final User user,
419 final String toscaPayload) {
421 String namespace = "";
422 final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
423 final Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils
424 .findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
425 if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
428 namespace = toscaElement.left().value().keySet().iterator().next();
429 isValid = getNodeTypeNamePrefix(namespace).isPresent();
432 final ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE);
433 final Response errorResponse = buildErrorResponse(responseFormat);
434 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
435 responseWrapper.setInnerElement(errorResponse);
437 resourceInfo.setResourceType(getResourceType(namespace));
441 private void validatePayloadIsSingleResource(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user,
442 String toscaPayload) {
443 log.debug("checking payload contains single resource");
445 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
446 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils
447 .findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
448 if (toscaElement.isRight()) {
451 isValid = toscaElement.left().value().size() == 1;
454 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_SINGLE_RESOURCE);
455 Response errorResponse = buildErrorResponse(responseFormat);
456 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
457 responseWrapper.setInnerElement(errorResponse);
461 private void validatePayloadIsNotService(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo,
462 String toscaPayload) {
463 log.debug("checking payload is not a tosca service");
464 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
465 Either<Object, ResultStatusEnum> toscaElement = ImportUtils
466 .findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL);
467 if (toscaElement.isLeft()) {
468 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE);
469 Response errorResponse = buildErrorResponse(responseFormat);
470 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
471 responseWrapper.setInnerElement(errorResponse);
475 private void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
476 String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName();
477 boolean isValidSuffix = isToscaTemplatePayloadNameValid(toscaTemplatePayloadName);
478 if (!isValidSuffix) {
479 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
480 Response errorResponse = buildErrorResponse(responseFormat);
481 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
482 responseWrapper.setInnerElement(errorResponse);
486 private boolean isToscaTemplatePayloadNameValid(String toscaTemplatePayloadName) {
487 boolean isValidSuffix = false;
488 if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) {
489 for (String validSuffix : TOSCA_YML_CSAR_VALID_SUFFIX) {
490 isValidSuffix = isValidSuffix || toscaTemplatePayloadName.toLowerCase().endsWith(validSuffix);
493 return isValidSuffix;
496 private void validateMD5(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request,
497 String resourceInfoJsonString) {
499 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
500 if (recievedMD5 == null) {
503 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(resourceInfoJsonString);
504 isValid = calculateMD5.equals(recievedMD5);
507 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM);
508 Response errorResponse = buildErrorResponse(responseFormat);
509 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
510 responseWrapper.setInnerElement(errorResponse);
514 ComponentTypeEnum validateComponentType(String componentType) {
515 if (componentType == null) {
516 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR);
518 if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) {
519 return ComponentTypeEnum.RESOURCE;
521 if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) {
522 return ComponentTypeEnum.SERVICE;
524 log.debug("Invalid componentType:{}", componentType);
525 throw new ByActionStatusComponentException(ActionStatus.UNSUPPORTED_ERROR, componentType);
528 ComponentTypeEnum convertToComponentType(String componentType) {
529 return validateComponentType(componentType);
532 private void fillToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user,
533 UploadResourceInfo resourceInfo) {
534 if (resourceInfo.getPayloadData() == null || resourceInfo.getPayloadData().isEmpty()) {
535 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
536 Response errorResponse = buildErrorResponse(responseFormat);
537 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
538 responseWrapper.setInnerElement(errorResponse);
540 String toscaPayload = resourceInfo.getPayloadData();
541 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
542 yamlStringWrapper.setInnerElement(decodedPayload);
546 void fillPayload(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper,
547 User user, String resourceInfoJsonString, ResourceAuthorityTypeEnum resourceAuthorityEnum, File file) throws ZipException {
548 if (responseWrapper.isEmpty()) {
549 if (resourceAuthorityEnum.isBackEndImport()) {
550 // PrePayload Validations
551 if (responseWrapper.isEmpty()) {
552 validateDataNotNull(responseWrapper, file, resourceInfoJsonString);
554 if (!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)) {
555 if (responseWrapper.isEmpty()) {
556 validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
558 // Fill PayLoad From File
559 if (responseWrapper.isEmpty()) {
560 fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file);
563 if (responseWrapper.isEmpty()) {
564 validateCsar(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
566 // Fill PayLoad From File
567 if (responseWrapper.isEmpty()) {
568 fillPayloadDataFromFile(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), file);
572 // Fill PayLoad From JSON
573 if (responseWrapper.isEmpty()) {
574 fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement());
580 protected void specificResourceAuthorityValidations(final Wrapper<Response> responseWrapper,
581 final Wrapper<UploadResourceInfo> uploadResourceInfoWrapper,
582 final Wrapper<String> yamlStringWrapper, final User user, final HttpServletRequest request,
583 final String resourceInfoJsonString, final ResourceAuthorityTypeEnum resourceAuthorityEnum) {
584 if (responseWrapper.isEmpty()) {
585 // UI Only Validation
586 if (!resourceAuthorityEnum.isBackEndImport()) {
587 importUIValidations(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, request, resourceInfoJsonString);
589 // User Defined Type Resources
590 if (resourceAuthorityEnum.isUserTypeResource() && !CsarValidationUtils
591 .isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName()) && responseWrapper.isEmpty()) {
592 validatePayloadNameSpace(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement());
597 void commonGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper,
598 ResourceAuthorityTypeEnum resourceAuthorityEnum, String userId, String resourceInfoJsonString) {
599 if (responseWrapper.isEmpty()) {
600 validateUserExist(responseWrapper, userWrapper, userId);
602 if (responseWrapper.isEmpty()) {
603 validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum);
605 if (responseWrapper.isEmpty()) {
606 validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum,
607 resourceInfoJsonString);
609 if (responseWrapper.isEmpty()) {
610 validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
612 if (responseWrapper.isEmpty()) {
613 validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
617 private void validateResourceType(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
618 String resourceType = uploadResourceInfo.getResourceType();
619 if (resourceType == null || !ResourceTypeEnum.containsName(resourceType)) {
620 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
621 Response errorResponse = buildErrorResponse(responseFormat);
622 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
623 responseWrapper.setInnerElement(errorResponse);
627 private void importUIValidations(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, HttpServletRequest request,
628 String resourceInfoJsonString) {
629 if (responseWrapper.isEmpty()) {
630 validateMD5(responseWrapper, user, resourceInfo, request, resourceInfoJsonString);
632 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
633 validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName());
637 void commonPayloadValidations(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user,
638 UploadResourceInfo uploadResourceInfo) {
639 if (responseWrapper.isEmpty()) {
640 validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
642 if (responseWrapper.isEmpty()) {
643 validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
645 if (responseWrapper.isEmpty()) {
646 validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
648 if (responseWrapper.isEmpty()) {
649 validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
653 void handleImport(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfoObject, String yamlAsString,
654 ResourceAuthorityTypeEnum authority, boolean createNewVersion, String resourceUniqueId) {
655 ImmutablePair<Resource, ActionStatus> createOrUpdateResponse = null;
656 Response response = null;
657 Object representation = null;
658 ImmutablePair<Resource, ActionStatus> importedResourceStatus = null;
659 if (CsarValidationUtils.isCsarPayloadName(resourceInfoObject.getPayloadName())) {
660 log.debug("import resource from csar");
661 importedResourceStatus = importResourceFromUICsar(resourceInfoObject, user, resourceUniqueId);
662 } else if (authority.isUserTypeResource()) {
663 log.debug("import user resource (not normative type)");
664 createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user, false);
666 log.debug("import normative type resource");
667 createOrUpdateResponse =
668 resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, null, user, createNewVersion, true, false);
670 if (createOrUpdateResponse != null) {
671 importedResourceStatus = createOrUpdateResponse;
673 if (importedResourceStatus != null) {
675 representation = RepresentationUtils.toRepresentation(importedResourceStatus.left);
676 } catch (IOException e) {
677 log.debug("Error while building resource representation : {}", e.getMessage(), e);
679 response = buildOkResponse(getComponentsUtils().getResponseFormat(importedResourceStatus.right), representation);
681 responseWrapper.setInnerElement(response);
684 private ImmutablePair<Resource, ActionStatus> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user,
685 String resourceUniqueId) {
686 Resource newResource;
687 ActionStatus actionStatus;
688 Resource resource = new Resource();
689 String payloadName = resourceInfoObject.getPayloadName();
690 fillResourceFromResourceInfoObject(resource, resourceInfoObject);
691 Map<String, byte[]> csarUIPayload = getCsarFromPayload(resourceInfoObject);
692 getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName);
693 if (resourceUniqueId == null || resourceUniqueId.isEmpty()) {
694 newResource = resourceImportManager.getResourceBusinessLogic()
695 .createResource(resource, AuditingActionEnum.CREATE_RESOURCE, user, csarUIPayload, payloadName);
696 actionStatus = ActionStatus.CREATED;
698 newResource = resourceImportManager.getResourceBusinessLogic()
699 .validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId);
700 actionStatus = ActionStatus.OK;
702 return new ImmutablePair<>(newResource, actionStatus);
705 protected Resource throwComponentException(ResponseFormat responseFormat) {
706 throw new ByResponseFormatComponentException(responseFormat);
709 private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Resource resource, User user, String csarUUID) {
710 getAndValidateComponentCsarYaml(csarUIPayload, resource, user, csarUUID);
713 private void getAndValidateComponentCsarYaml(Map<String, byte[]> csarUIPayload, Component component, User user, String csarUUID) {
714 Either<ImmutablePair<String, String>, ResponseFormat> getToscaYamlRes = CsarValidationUtils
715 .getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils(), null);
716 if (getToscaYamlRes.isRight()) {
717 ResponseFormat responseFormat = getToscaYamlRes.right().value();
718 log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
719 if (component instanceof Resource) {
720 BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
721 getComponentsUtils().auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.CREATE_RESOURCE);
723 BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating service from CSAR: fetching CSAR with id " + csarUUID + " failed");
725 throwComponentException(responseFormat);
727 String toscaYaml = getToscaYamlRes.left().value().getValue();
728 log.debug("checking tosca template is valid yml");
729 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
730 boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes());
732 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
733 if (component instanceof Resource) {
734 getComponentsUtils().auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.IMPORT_RESOURCE);
736 throwComponentException(responseFormat);
738 log.debug("checking payload is valid tosca");
739 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaYaml);
740 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils
741 .findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION);
742 if (findFirstToscaStringElement.isRight()) {
745 String defenitionVersionFound = findFirstToscaStringElement.left().value();
746 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
749 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
753 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
754 if (component instanceof Resource) {
755 log.debug("enter getAndValidateComponentCsarYaml,component instanceof Resource");
756 getComponentsUtils().auditResource(responseFormat, user, (Resource) component, AuditingActionEnum.IMPORT_RESOURCE);
758 throwComponentException(responseFormat);
762 private void fillResourceFromResourceInfoObject(Resource resource, UploadResourceInfo resourceInfoObject) {
763 resourceImportManager.populateResourceMetadata(resourceInfoObject, resource);
764 fillArtifacts(resource, resourceInfoObject);
767 private void fillArtifacts(Resource resource, UploadResourceInfo resourceInfoObject) {
768 if (resource != null && resourceInfoObject != null) {
769 List<UploadArtifactInfo> artifactList = resourceInfoObject.getArtifactList();
770 if (artifactList != null) {
771 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
772 buildArtifactsHM(artifactList, artifactsHM);
773 resource.setArtifacts(artifactsHM);
778 private void buildArtifactsHM(List<UploadArtifactInfo> artifactList, Map<String, ArtifactDefinition> artifactsHM) {
779 for (UploadArtifactInfo artifact : artifactList) {
780 ArtifactDefinition artifactDef = new ArtifactDefinition();
781 artifactDef.setArtifactName(artifact.getArtifactName());
782 artifactDef.setArtifactType(artifact.getArtifactType().getType());
783 artifactDef.setDescription(artifact.getArtifactDescription());
784 artifactDef.setPayloadData(artifact.getArtifactData());
785 artifactDef.setArtifactRef(artifact.getArtifactPath());
786 artifactsHM.put(artifactDef.getArtifactName(), artifactDef);
790 private Map<String, byte[]> getCsarFromPayload(UploadResourceInfo innerElement) {
791 String csarUUID = innerElement.getPayloadName();
792 String payloadData = innerElement.getPayloadData();
793 return getComponentCsarFromPayload(csarUUID, payloadData);
796 private Map<String, byte[]> getComponentCsarFromPayload(String csarUUID, String payloadData) {
797 if (payloadData == null) {
798 log.info("Failed to decode received csar {}", csarUUID);
799 throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
801 byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8));
802 if (decodedPayload == null) {
803 log.info("Failed to decode received csar {}", csarUUID);
804 throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND, csarUUID);
806 Map<String, byte[]> csar = null;
808 csar = ZipUtils.readZip(decodedPayload, false);
809 } catch (final ZipException e) {
810 log.info("Failed to unzip received csar {}", csarUUID, e);
815 void validateInputStream(final HttpServletRequest request, Wrapper<String> dataWrapper, Wrapper<ResponseFormat> errorWrapper) throws IOException {
816 InputStream inputStream = request.getInputStream();
817 byte[] bytes = IOUtils.toByteArray(inputStream);
818 if (bytes == null || bytes.length == 0) {
819 log.info("Empty body was sent.");
820 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
822 dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8));
826 <T> void validateClassParse(String data, Wrapper<T> parsedClassWrapper, Supplier<Class<T>> classGen, Wrapper<ResponseFormat> errorWrapper) {
828 T parsedClass = gson.fromJson(data, classGen.get());
829 if (parsedClass == null) {
830 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
832 parsedClassWrapper.setInnerElement(parsedClass);
834 } catch (JsonSyntaxException e) {
835 log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e);
836 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
840 void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType,
841 Wrapper<ComponentInstanceBusinessLogic> blWrapper, Wrapper<ResponseFormat> errorWrapper) {
842 ServletContext context = request.getSession().getServletContext();
843 ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context);
844 if (componentInstanceLogic == null) {
845 log.debug("Unsupported component type {}", containerComponentType);
846 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
848 blWrapper.setInnerElement(componentInstanceLogic);
852 <T> Response buildResponseFromElement(Wrapper<ResponseFormat> errorWrapper, Wrapper<T> attributeWrapper) throws IOException {
854 if (errorWrapper.isEmpty()) {
855 ObjectMapper mapper = new ObjectMapper();
856 String result = mapper.writeValueAsString(attributeWrapper.getInnerElement());
857 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
859 response = buildErrorResponse(errorWrapper.getInnerElement());
864 protected void validateXECOMPInstanceIDHeader(String instanceIdHeader, Wrapper<ResponseFormat> responseWrapper) {
865 ResponseFormat responseFormat;
866 if (StringUtils.isEmpty(instanceIdHeader)) {
867 log.debug("Missing X-ECOMP-InstanceID header");
868 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
869 responseWrapper.setInnerElement(responseFormat);
873 protected void validateHttpCspUserIdHeader(String header, Wrapper<ResponseFormat> responseWrapper) {
874 ResponseFormat responseFormat;
875 if (StringUtils.isEmpty(header)) {
876 log.debug("MissingUSER_ID");
877 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
878 responseWrapper.setInnerElement(responseFormat);
882 <T> Either<T, ResponseFormat> parseToObject(String json, Supplier<Class<T>> classSupplier) {
884 T object = RepresentationUtils.fromRepresentation(json, classSupplier.get());
885 return Either.left(object);
886 } catch (Exception e) {
887 log.debug("Failed to parse json to {} object", classSupplier.get().getName(), e);
888 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
889 return Either.right(responseFormat);
893 public <T> Either<List<T>, ResponseFormat> parseListOfObjects(String json, Type type) {
895 List<T> listOfObjects = gson.fromJson(json, type);
896 return Either.left(listOfObjects);
897 } catch (Exception e) {
898 log.debug("Failed to parse json to {} object", type.getClass().getName(), e);
899 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
900 return Either.right(responseFormat);
904 protected void validateNotEmptyBody(String data) {
905 if (StringUtils.isEmpty(data)) {
906 throw new ByActionStatusComponentException(ActionStatus.MISSING_BODY);
910 protected void commonServiceGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper,
911 Wrapper<UploadServiceInfo> uploadServiceInfoWrapper, ServiceAuthorityTypeEnum serviceAuthorityEnum,
912 String userUserId, String serviceInfoJsonString) {
913 if (responseWrapper.isEmpty()) {
914 validateUserExist(responseWrapper, userWrapper, userUserId);
916 if (responseWrapper.isEmpty()) {
917 validateUserRole(responseWrapper, userWrapper.getInnerElement(), serviceAuthorityEnum);
919 if (responseWrapper.isEmpty()) {
920 validateAndFillServiceJson(responseWrapper, uploadServiceInfoWrapper, serviceAuthorityEnum,
921 serviceInfoJsonString);
923 if (responseWrapper.isEmpty()) {
924 validateToscaTemplatePayloadName(responseWrapper, uploadServiceInfoWrapper.getInnerElement());
928 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ServiceAuthorityTypeEnum serviceAuthority) {
929 log.debug(VALIDATE_USER_ROLE);
930 if (serviceAuthority == ServiceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
931 if (!user.getRole().equals(Role.ADMIN.name())) {
932 log.info(USER_IS_NOT_IN_APPROPRIATE_ROLE_TO_PERFORM_ACTION);
933 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
934 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
935 Response response = buildErrorResponse(responseFormat);
936 errorResponseWrapper.setInnerElement(response);
939 validateUserRole(errorResponseWrapper, user);
943 protected void validateAndFillServiceJson(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper,
944 ServiceAuthorityTypeEnum serviceAuthorityEnum, String serviceInfo) {
947 log.debug("The received json is {}", serviceInfo);
948 UploadServiceInfo serviceInfoObject = gson.fromJson(serviceInfo, UploadServiceInfo.class);
949 if (serviceInfoObject == null) {
952 if (!serviceAuthorityEnum.isBackEndImport()) {
953 isValid = serviceInfoObject.getPayloadName() != null && !serviceInfoObject.getPayloadName().isEmpty();
954 //only service name is checked
958 uploadServiceInfoWrapper.setInnerElement(serviceInfoObject);
959 log.debug("get isValid:{},serviceInfoObject get name:{},get tags:{},getContactId:{}," + " getPayloadName:{}", isValid,
960 uploadServiceInfoWrapper.getInnerElement().getName(), uploadServiceInfoWrapper.getInnerElement().getTags(),
961 uploadServiceInfoWrapper.getInnerElement().getContactId(), uploadServiceInfoWrapper.getInnerElement().getPayloadName());
963 } catch (JsonSyntaxException e) {
964 log.debug("enter validateAndFillServiceJson,Invalid json was received. {}", e.getMessage(), e);
968 log.info(INVALID_JSON_WAS_RECEIVED);
969 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
970 Response errorResp = buildErrorResponse(responseFormat);
971 responseWrapper.setInnerElement(errorResp);
975 protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfo) {
976 String toscaTemplatePayloadName = uploadServiceInfo.getPayloadName();
977 boolean isValidSuffix = isToscaTemplatePayloadNameValid(toscaTemplatePayloadName);
978 if (!isValidSuffix) {
979 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
980 Response errorResponse = buildErrorResponse(responseFormat);
981 responseWrapper.setInnerElement(errorResponse);
985 protected void specificServiceAuthorityValidations(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper,
986 Wrapper<String> yamlStringWrapper, HttpServletRequest request,
987 String serviceInfoJsonString, ServiceAuthorityTypeEnum serviceAuthorityEnum) {
988 if (responseWrapper.isEmpty()) {
989 // UI Only Validation
990 if (!serviceAuthorityEnum.isBackEndImport()) {
991 importUIValidations(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), request, serviceInfoJsonString);
993 // User Defined Type Services
994 if (serviceAuthorityEnum.isUserTypeService()
995 && !CsarValidationUtils.isCsarPayloadName(uploadServiceInfoWrapper.getInnerElement().getPayloadName())
996 && responseWrapper.isEmpty()) {
997 validatePayloadNameSpace(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement());
1002 protected void importUIValidations(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, HttpServletRequest request,
1003 String serviceInfoJsonString) {
1004 if (responseWrapper.isEmpty()) {
1005 validateMD5(responseWrapper, request, serviceInfoJsonString);
1007 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
1008 validateServiceDoesNotExist(responseWrapper, serviceInfo.getName());
1012 protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadServiceInfo serviceInfo, String toscaPayload) {
1014 String nameSpace = "";
1015 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
1016 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils
1017 .findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
1018 if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
1021 nameSpace = toscaElement.left().value().keySet().iterator().next();
1022 isValid = nameSpace.startsWith(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX);
1023 log.debug("enter validatePayloadNameSpace,get nameSpace:{},get Valid is:{}", nameSpace, isValid);
1026 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_NAMESPACE);
1027 Response errorResponse = buildErrorResponse(responseFormat);
1028 responseWrapper.setInnerElement(errorResponse);
1030 String str1 = nameSpace.substring(Constants.USER_DEFINED_SERVICE_NAMESPACE_PREFIX.length());
1031 String[] findTypes = str1.split("\\.");
1032 if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) {
1033 String type = findTypes[0].toUpperCase();
1034 serviceInfo.setServiceType(type);
1036 serviceInfo.setServiceType(ResourceTypeEnum.SERVICE.name());
1041 protected void validateMD5(Wrapper<Response> responseWrapper, HttpServletRequest request,
1042 String serviceInfoJsonString) {
1044 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
1045 if (recievedMD5 == null) {
1048 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(serviceInfoJsonString);
1049 isValid = calculateMD5.equals(recievedMD5);
1052 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_SERVICE_CHECKSUM);
1053 Response errorResponse = buildErrorResponse(responseFormat);
1054 responseWrapper.setInnerElement(errorResponse);
1058 protected void validateServiceDoesNotExist(Wrapper<Response> responseWrapper, String serviceName) {
1059 if (serviceImportManager.isServiceExist(serviceName)) {
1060 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.SERVICE_ALREADY_EXISTS);
1061 Response errorResponse = buildErrorResponse(responseFormat);
1062 responseWrapper.setInnerElement(errorResponse);
1066 protected void handleImportService(Wrapper<Response> responseWrapper, User user, UploadServiceInfo serviceInfoObject) {
1067 Response response = null;
1068 ImmutablePair<Service, ActionStatus> importedServiceStatus = null;
1069 if (CsarValidationUtils.isCsarPayloadName(serviceInfoObject.getPayloadName())) {
1070 log.debug("import service from csar");
1071 importedServiceStatus = importServiceFromUICsar(serviceInfoObject, user);
1073 if (importedServiceStatus != null) {
1074 Object representation = null;
1076 representation = RepresentationUtils.toRepresentation(importedServiceStatus.left);
1077 } catch (IOException e) {
1078 log.debug("Error while building service representation : {}", e.getMessage(), e);
1080 response = buildOkResponse(getComponentsUtils().getResponseFormat(importedServiceStatus.right), representation);
1082 responseWrapper.setInnerElement(response);
1085 private ImmutablePair<Service, ActionStatus> importServiceFromUICsar(UploadServiceInfo serviceInfoObject, User user) {
1086 Service service = new Service();
1087 String payloadName = serviceInfoObject.getPayloadName();
1088 fillServiceFromServiceInfoObject(service, serviceInfoObject);
1089 Map<String, byte[]> csarUIPayloadRes = getCsarFromPayload(serviceInfoObject);
1090 getAndValidateCsarYaml(csarUIPayloadRes, service, user, payloadName);
1091 final Service newService = serviceImportManager.getServiceImportBusinessLogic()
1092 .createService(service, AuditingActionEnum.CREATE_SERVICE, user, csarUIPayloadRes, payloadName);
1093 return new ImmutablePair<>(newService, ActionStatus.CREATED);
1096 private void fillServiceFromServiceInfoObject(Service service, UploadServiceInfo serviceInfoObject) {
1097 serviceImportManager.populateServiceMetadata(serviceInfoObject, service);
1098 fillArtifacts(service, serviceInfoObject);
1101 private Map<String, byte[]> getCsarFromPayload(UploadServiceInfo innerElement) {
1102 String csarUUID = innerElement.getPayloadName();
1103 String payloadData = innerElement.getPayloadData();
1104 return getComponentCsarFromPayload(csarUUID, payloadData);
1107 private void getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, Service service, User user, String csarUUID) {
1108 getAndValidateComponentCsarYaml(csarUIPayload, service, user, csarUUID);
1111 private void fillArtifacts(Service service, UploadServiceInfo serviceInfoObject) {
1112 if (service != null && serviceInfoObject != null) {
1113 List<UploadArtifactInfo> artifactList = serviceInfoObject.getArtifactList();
1114 if (artifactList != null) {
1115 Map<String, ArtifactDefinition> artifactsHM = new HashMap<>();
1116 buildArtifactsHM(artifactList, artifactsHM);
1117 service.setArtifacts(artifactsHM);
1123 * import service payload to postman
1125 * @param responseWrapper
1126 * @param uploadServiceInfoWrapper
1127 * @param yamlStringWrapper
1129 * @param serviceInfoJsonString
1130 * @param serviceAuthorityEnum
1132 * @throws ZipException
1134 protected void fillServicePayload(Wrapper<Response> responseWrapper, Wrapper<UploadServiceInfo> uploadServiceInfoWrapper,
1135 Wrapper<String> yamlStringWrapper, User user, String serviceInfoJsonString,
1136 ServiceAuthorityTypeEnum serviceAuthorityEnum, File file) throws ZipException {
1137 log.debug("enter fillServicePayload");
1138 if (responseWrapper.isEmpty()) {
1139 log.debug("enter fillServicePayload,get responseWrapper is empty");
1140 if (serviceAuthorityEnum.isBackEndImport()) {
1141 // PrePayload Validations
1142 if (responseWrapper.isEmpty()) {
1143 validateDataNotNull(responseWrapper, file, serviceInfoJsonString);
1145 if (responseWrapper.isEmpty()) {
1146 log.debug("enter fillServicePayload,responseWrapper is empty");
1148 if (!serviceAuthorityEnum.equals(ServiceAuthorityTypeEnum.CSAR_TYPE_BE)) {
1149 if (responseWrapper.isEmpty()) {
1150 validateZip(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1152 // Fill PayLoad From File
1153 if (responseWrapper.isEmpty()) {
1154 fillToscaTemplateFromZip(yamlStringWrapper, uploadServiceInfoWrapper.getInnerElement().getPayloadName(), file);
1157 log.debug("enter fillServicePayload,ServiceAuthorityTypeEnum is CSAR_TYPE_BE");
1158 if (responseWrapper.isEmpty()) {
1159 validateCsar(responseWrapper, file, uploadServiceInfoWrapper.getInnerElement().getPayloadName());
1161 if (!responseWrapper.isEmpty()) {
1162 log.debug("enter fillServicePayload,get responseWrapper:{}", responseWrapper);
1164 // Fill PayLoad From File
1165 if (responseWrapper.isEmpty()) {
1166 fillServicePayloadDataFromFile(responseWrapper, uploadServiceInfoWrapper.getInnerElement(), file);
1170 // Fill PayLoad From JSON
1171 if (responseWrapper.isEmpty()) {
1172 fillServiceToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadServiceInfoWrapper.getInnerElement());
1178 protected void fillServicePayloadDataFromFile(Wrapper<Response> responseWrapper, UploadServiceInfo uploadServiceInfoWrapper, File file) {
1179 try (InputStream fileInputStream = new FileInputStream(file)) {
1180 log.debug("enter fillServicePayloadDataFromFile");
1181 byte[] data = new byte[(int) file.length()];
1182 if (fileInputStream.read(data) == -1) {
1183 log.info(INVALID_JSON_WAS_RECEIVED);
1184 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1185 Response errorResp = buildErrorResponse(responseFormat);
1186 responseWrapper.setInnerElement(errorResp);
1188 String payloadData = Base64.encodeBase64String(data);
1189 uploadServiceInfoWrapper.setPayloadData(payloadData);
1190 log.debug("enter fillServicePayloadDataFromFile,get payloadData:{}", uploadServiceInfoWrapper.getPayloadData());
1191 log.debug("enter fillServicePayloadDataFromFile,get uploadService:{}", uploadServiceInfoWrapper);
1192 } catch (IOException e) {
1193 log.info("Invalid json was received or Error while closing input Stream.");
1194 log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
1195 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
1196 Response errorResp = buildErrorResponse(responseFormat);
1197 responseWrapper.setInnerElement(errorResp);
1201 private void fillServiceToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user,
1202 UploadServiceInfo serviceInfo) {
1203 if (serviceInfo.getPayloadData() == null || serviceInfo.getPayloadData().isEmpty()) {
1204 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
1205 Response errorResponse = buildErrorResponse(responseFormat);
1206 getComponentsUtils().auditResource(responseFormat, user, serviceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
1207 responseWrapper.setInnerElement(errorResponse);
1209 String toscaPayload = serviceInfo.getPayloadData();
1210 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
1211 yamlStringWrapper.setInnerElement(decodedPayload);