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=========================================================
21 package org.openecomp.sdc.be.servlets;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.google.gson.Gson;
25 import com.google.gson.JsonSyntaxException;
26 import fj.data.Either;
27 import org.apache.commons.codec.binary.Base64;
28 import org.apache.commons.io.IOUtils;
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.commons.lang3.tuple.ImmutablePair;
31 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
32 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
33 import org.openecomp.sdc.be.components.impl.ImportUtils;
34 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
35 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
36 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum;
37 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
38 import org.openecomp.sdc.be.config.BeEcompErrorManager;
39 import org.openecomp.sdc.be.dao.api.ActionStatus;
40 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
41 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
42 import org.openecomp.sdc.be.impl.ComponentsUtils;
43 import org.openecomp.sdc.be.impl.ServletUtils;
44 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
45 import org.openecomp.sdc.be.model.ArtifactDefinition;
46 import org.openecomp.sdc.be.model.UploadResourceInfo;
47 import org.openecomp.sdc.be.model.User;
48 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
49 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
50 import org.openecomp.sdc.be.user.IUserBusinessLogic;
51 import org.openecomp.sdc.be.user.Role;
52 import org.openecomp.sdc.common.api.Constants;
53 import org.openecomp.sdc.common.api.UploadArtifactInfo;
54 import org.openecomp.sdc.common.datastructure.Wrapper;
55 import org.openecomp.sdc.common.util.GeneralUtility;
56 import org.openecomp.sdc.common.util.YamlToObjectConverter;
57 import org.openecomp.sdc.common.util.ZipUtil;
58 import org.openecomp.sdc.exception.ResponseFormat;
59 import org.slf4j.Logger;
60 import org.springframework.web.context.WebApplicationContext;
61 import org.yaml.snakeyaml.Yaml;
63 import javax.servlet.ServletContext;
64 import javax.servlet.http.HttpServletRequest;
65 import javax.ws.rs.core.Response;
67 import java.io.FileInputStream;
68 import java.io.FileNotFoundException;
69 import java.io.IOException;
70 import java.io.InputStream;
71 import java.lang.reflect.Type;
72 import java.nio.charset.StandardCharsets;
73 import java.util.Arrays;
74 import java.util.HashMap;
75 import java.util.List;
77 import java.util.function.Supplier;
78 import java.util.zip.ZipInputStream;
80 public abstract class AbstractValidationsServlet extends BeGenericServlet {
82 private static final String TOSCA_SIMPLE_YAML_PREFIX = "tosca_simple_yaml_";
83 private static final List<String> TOSCA_DEFINITION_VERSIONS = Arrays.asList(TOSCA_SIMPLE_YAML_PREFIX + "1_0_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1_0", "tosca_simple_profile_for_nfv_1_0_0", TOSCA_SIMPLE_YAML_PREFIX + "1_0", TOSCA_SIMPLE_YAML_PREFIX + "1_1");
84 private static final List<String> TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(".yml", ".yaml", ".csar");
86 protected ServletUtils servletUtils;
88 protected ResourceImportManager resourceImportManager;
90 protected ComponentsUtils componentsUtils;
92 private Logger log = null;
94 protected void init(Logger log) {
96 initSpringFromContext();
100 protected synchronized void initLog(Logger log) {
101 if (this.log == null) {
106 private synchronized void initSpringFromContext() {
107 if (servletUtils == null) {
108 ServletContext context = servletRequest.getSession().getServletContext();
109 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
110 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
111 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
112 servletUtils = webApplicationContext.getBean(ServletUtils.class);
113 resourceImportManager = webApplicationContext.getBean(ResourceImportManager.class);
117 protected void validateResourceDoesNotExist(Wrapper<Response> responseWrapper, User user, String resourceName) {
118 if (resourceImportManager.isResourceExist(resourceName)) {
119 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
120 Response errorResponse = buildErrorResponse(responseFormat);
121 getComponentsUtils().auditResource(responseFormat, user, resourceName, AuditingActionEnum.IMPORT_RESOURCE);
122 responseWrapper.setInnerElement(errorResponse);
126 protected void validateUserExist(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, String userUserId) {
127 log.debug("get user {} from DB", userUserId);
129 if (userUserId == null) {
130 log.info("user userId is null");
131 Response response = returnMissingInformation(new User());
132 responseWrapper.setInnerElement(response);
136 IUserBusinessLogic userAdmin = getServletUtils().getUserAdmin();
137 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(userUserId, false);
138 if (eitherCreator.isRight()) {
139 log.info("user is not listed. userId={}", userUserId);
140 User user = new User();
141 user.setUserId(userUserId);
142 Response response = returnMissingInformation(user);
143 responseWrapper.setInnerElement(response);
145 userWrapper.setInnerElement(eitherCreator.left().value());
150 protected Response returnMissingInformation(User user) {
151 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION);
152 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
153 return buildErrorResponse(responseFormat);
156 protected void validateDataNotNull(Wrapper<Response> responseWrapper, Object... dataParams) {
157 for (Object dataElement : dataParams) {
158 if (dataElement == null) {
159 log.info("Invalid body was received.");
160 Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
161 responseWrapper.setInnerElement(response);
168 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user) {
169 log.debug("validate user role");
170 if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) {
171 log.info("user is not in appropriate role to perform action");
172 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
173 log.debug("audit before sending response");
174 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
176 Response response = buildErrorResponse(responseFormat);
177 errorResponseWrapper.setInnerElement(response);
182 protected void validateZip(Wrapper<Response> responseWrapper, File file, String payloadName) throws FileNotFoundException {
183 InputStream fileInputStream = new FileInputStream(file);
184 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
185 if (payloadName == null || payloadName.isEmpty() || !unzippedFolder.containsKey(payloadName)) {
186 log.info("Invalid json was received. payloadName should be yml file name");
187 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
188 responseWrapper.setInnerElement(errorResponse);
192 protected void validateCsar(Wrapper<Response> responseWrapper, File file, String payloadName) throws FileNotFoundException {
193 InputStream fileInputStream = new FileInputStream(file);
194 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
195 if (payloadName == null || payloadName.isEmpty() || unzippedFolder.isEmpty()) {
196 log.info("Invalid json was received. payloadName should be yml file name");
197 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
198 responseWrapper.setInnerElement(errorResponse);
203 protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws FileNotFoundException {
204 InputStream fileInputStream = new FileInputStream(file);
205 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
206 String ymlName = unzippedFolder.keySet().iterator().next();
207 fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file);
210 protected void fillToscaTemplateFromZip(Wrapper<String> yamlStringWrapper, String payloadName, File file) throws FileNotFoundException {
211 InputStream fileInputStream = new FileInputStream(file);
212 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
213 byte[] yamlFileInBytes = unzippedFolder.get(payloadName);
214 String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8);
215 log.debug("received yaml: {}", yamlAsString);
216 yamlStringWrapper.setInnerElement(yamlAsString);
219 protected void fillPayloadDataFromFile(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfoWrapper, File file) {
220 try(InputStream fileInputStream = new FileInputStream(file)){
222 byte [] data = new byte[(int)file.length()];
223 if( fileInputStream.read(data) == -1){
224 log.info("Invalid json was received.");
225 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
227 Response errorResp = buildErrorResponse(responseFormat);
228 responseWrapper.setInnerElement(errorResp);
230 String payloadData = Base64.encodeBase64String(data);
231 uploadResourceInfoWrapper.setPayloadData(payloadData);
235 } catch (IOException e) {
236 log.info("Invalid json was received or Error while closing input Stream.");
237 log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
238 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
240 Response errorResp = buildErrorResponse(responseFormat);
241 responseWrapper.setInnerElement(errorResp);
246 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) {
247 log.debug("validate user role");
248 if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
249 if (!user.getRole().equals(Role.ADMIN.name())) {
250 log.info("user is not in appropriate role to perform action");
251 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
252 log.debug("audit before sending response");
253 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
255 Response response = buildErrorResponse(responseFormat);
256 errorResponseWrapper.setInnerElement(response);
259 validateUserRole(errorResponseWrapper, user);
264 protected void validateAndFillResourceJson(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, User user, ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) {
267 log.debug("The received json is {}", resourceInfo);
268 UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class);
269 if (resourceInfoObject == null) {
272 if (!resourceAuthorityEnum.isBackEndImport()) {
273 isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty();
274 //only resource name is checked
278 uploadResourceInfoWrapper.setInnerElement(resourceInfoObject);
281 } catch (JsonSyntaxException e) {
282 log.debug("Invalid json was received. {}", e.getMessage(), e);
287 log.info("Invalid json was received.");
288 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
289 getComponentsUtils().auditResource(responseFormat, user, "", AuditingActionEnum.IMPORT_RESOURCE);
290 Response errorResp = buildErrorResponse(responseFormat);
291 responseWrapper.setInnerElement(errorResp);
295 protected void validateAuthorityType(Wrapper<Response> responseWrapper, String authorityType) {
296 log.debug("The received authority type is {}", authorityType);
297 ResourceAuthorityTypeEnum authorityTypeEnum = ResourceAuthorityTypeEnum.findByUrlPath(authorityType);
298 if (authorityTypeEnum == null) {
299 log.info("Invalid authority type was received.");
300 Response errorResp = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
301 responseWrapper.setInnerElement(errorResp);
305 public ServletUtils getServletUtils() {
306 initSpringFromContext();
310 public Gson getGson() {
311 return getServletUtils().getGson();
314 public ComponentsUtils getComponentsUtils() {
315 return getServletUtils().getComponentsUtils();
318 protected void validatePayloadIsTosca(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
319 log.debug("checking payload is valid tosca");
321 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
322 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION);
324 if (findFirstToscaStringElement.isRight()) {
327 String defenitionVersionFound = findFirstToscaStringElement.left().value();
328 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
331 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
336 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
337 Response errorResponse = buildErrorResponse(responseFormat);
338 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
339 responseWrapper.setInnerElement(errorResponse);
344 protected void validatePayloadIsYml(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaTamplatePayload) {
345 log.debug("checking tosca template is valid yml");
346 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
347 boolean isYamlValid = yamlConvertor.isValidYaml(toscaTamplatePayload.getBytes());
349 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
350 Response errorResponse = buildErrorResponse(responseFormat);
351 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
352 responseWrapper.setInnerElement(errorResponse);
356 protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, String toscaPayload) {
358 String nameSpace = "";
359 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
360 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.NODE_TYPES);
361 if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
364 nameSpace = toscaElement.left().value().keySet().iterator().next();
365 isValid = nameSpace.startsWith(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX);
368 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE);
369 Response errorResponse = buildErrorResponse(responseFormat);
370 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
371 responseWrapper.setInnerElement(errorResponse);
373 String str1 = nameSpace.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length());
374 String[] findTypes = str1.split("\\.");
375 if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) {
376 String type = findTypes[0].toUpperCase();
377 resourceInfo.setResourceType(type);
379 resourceInfo.setResourceType(ResourceTypeEnum.VFC.name());
385 protected void validatePayloadIsSingleResource(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
386 log.debug("checking payload contains single resource");
388 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
389 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.NODE_TYPES);
390 if (toscaElement.isRight()) {
393 isValid = toscaElement.left().value().size() == 1;
397 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_SINGLE_RESOURCE);
398 Response errorResponse = buildErrorResponse(responseFormat);
399 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
400 responseWrapper.setInnerElement(errorResponse);
405 protected void validatePayloadIsNotService(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaPayload) {
406 log.debug("checking payload is not a tosca service");
407 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
408 Either<Object, ResultStatusEnum> toscaElement = ImportUtils.findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL);
410 if (toscaElement.isLeft()) {
411 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE);
412 Response errorResponse = buildErrorResponse(responseFormat);
413 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
414 responseWrapper.setInnerElement(errorResponse);
419 protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
420 String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName();
421 boolean isValidSuffix = false;
422 if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) {
423 for (String validSuffix : TOSCA_YML_CSAR_VALID_SUFFIX) {
424 isValidSuffix = isValidSuffix || toscaTemplatePayloadName.toLowerCase().endsWith(validSuffix);
427 if (!isValidSuffix) {
428 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
429 Response errorResponse = buildErrorResponse(responseFormat);
430 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
431 responseWrapper.setInnerElement(errorResponse);
436 protected void validateMD5(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request, String resourceInfoJsonString) {
438 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
439 if (recievedMD5 == null) {
442 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(resourceInfoJsonString);
443 isValid = calculateMD5.equals(recievedMD5);
446 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM);
447 Response errorResponse = buildErrorResponse(responseFormat);
448 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
449 responseWrapper.setInnerElement(errorResponse);
453 protected void validateComponentType(Wrapper<Response> responseWrapper, Wrapper<ComponentTypeEnum> componentTypeWrapper, String componentType) {
455 if (componentType == null) {
458 if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) {
460 componentTypeWrapper.setInnerElement(ComponentTypeEnum.RESOURCE);
461 } else if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) {
463 componentTypeWrapper.setInnerElement(ComponentTypeEnum.SERVICE);
469 log.debug("Invalid componentType:{}", componentType);
470 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType)));
474 protected Either<ComponentTypeEnum, ResponseFormat> convertToComponentType(String componentType) {
475 Wrapper<Response> errorWrapper = new Wrapper<>();
476 Wrapper<ComponentTypeEnum> componentWrapper = new Wrapper<>();
477 validateComponentType(errorWrapper, componentWrapper, componentType);
478 return errorWrapper.isEmpty() ? Either.left(componentWrapper.getInnerElement()) : Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
481 protected void fillToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo resourceInfo) {
482 if (resourceInfo.getPayloadData() == null || resourceInfo.getPayloadData().isEmpty()) {
483 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
484 Response errorResponse = buildErrorResponse(responseFormat);
485 getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
486 responseWrapper.setInnerElement(errorResponse);
488 String toscaPayload = resourceInfo.getPayloadData();
489 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
490 yamlStringWrapper.setInnerElement(decodedPayload);
495 protected void fillPayload(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, String resourceInfoJsonString, ResourceAuthorityTypeEnum resourceAuthorityEnum,
496 File file) throws FileNotFoundException {
498 if (responseWrapper.isEmpty()) {
499 if (resourceAuthorityEnum.isBackEndImport()) {
500 // PrePayload Validations
501 if (responseWrapper.isEmpty()) {
502 validateDataNotNull(responseWrapper, file, resourceInfoJsonString);
504 if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){
505 if (responseWrapper.isEmpty()) {
506 validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
509 // Fill PayLoad From File
510 if (responseWrapper.isEmpty()) {
511 fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file);
515 if (responseWrapper.isEmpty()) {
516 validateCsar(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
519 // Fill PayLoad From File
520 if (responseWrapper.isEmpty()) {
521 fillPayloadDataFromFile(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), file);
527 // Fill PayLoad From JSON
528 if (responseWrapper.isEmpty()) {
529 fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement());
537 protected void specificResourceAuthorityValidations(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, HttpServletRequest request, String resourceInfoJsonString,
538 ResourceAuthorityTypeEnum resourceAuthorityEnum) throws FileNotFoundException {
540 if (responseWrapper.isEmpty()) {
541 // UI Only Validation
542 if (!resourceAuthorityEnum.isBackEndImport()) {
543 importUIValidations(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, request, resourceInfoJsonString);
546 // User Defined Type Resources
547 if (resourceAuthorityEnum.isUserTypeResource() && !CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
548 if (responseWrapper.isEmpty()) {
549 validatePayloadNameSpace(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement());
556 protected void commonGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, ResourceAuthorityTypeEnum resourceAuthorityEnum, String userUserId,
557 String resourceInfoJsonString) {
559 if (responseWrapper.isEmpty()) {
560 validateUserExist(responseWrapper, userWrapper, userUserId);
563 if (responseWrapper.isEmpty()) {
564 validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum);
567 if (responseWrapper.isEmpty()) {
568 validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum, resourceInfoJsonString);
571 if (responseWrapper.isEmpty()) {
572 validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
574 if (responseWrapper.isEmpty()) {
575 validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
580 private void validateResourceType(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
581 String resourceType = uploadResourceInfo.getResourceType();
582 if (resourceType == null || !ResourceTypeEnum.containsName(resourceType)) {
583 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
584 Response errorResponse = buildErrorResponse(responseFormat);
585 getComponentsUtils().auditResource(responseFormat, user, uploadResourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE);
586 responseWrapper.setInnerElement(errorResponse);
590 protected void importUIValidations(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, HttpServletRequest request, String resourceInfoJsonString) {
591 if (responseWrapper.isEmpty()) {
592 validateMD5(responseWrapper, user, resourceInfo, request, resourceInfoJsonString);
594 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
595 validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName());
599 protected void commonPayloadValidations(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) {
601 if (responseWrapper.isEmpty()) {
602 validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
604 if (responseWrapper.isEmpty()) {
605 validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
607 if (responseWrapper.isEmpty()) {
608 validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
610 if (responseWrapper.isEmpty()) {
611 validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
616 protected void handleImport(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfoObject, String yamlAsString, ResourceAuthorityTypeEnum authority, boolean createNewVersion, String resourceUniqueId) {
617 Either<ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus>, ResponseFormat> createOrUpdateResponse;
619 Object representation = null;
621 if (CsarValidationUtils.isCsarPayloadName(resourceInfoObject.getPayloadName())) {
622 log.debug("import resource from csar");
624 createOrUpdateResponse = importResourceFromUICsar(resourceInfoObject, user, resourceUniqueId);
625 } else if (!authority.isUserTypeResource()) {
626 log.debug("import normative type resource");
627 createOrUpdateResponse = resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, user, createNewVersion, true);
629 log.debug("import user resource (not normative type)");
630 createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user, false);
632 if (createOrUpdateResponse.isRight()) {
633 response = buildErrorResponse(createOrUpdateResponse.right().value());
636 representation = RepresentationUtils.toRepresentation(createOrUpdateResponse.left().value().getLeft());
637 } catch (IOException e) {
638 log.debug("Error while building resource representation : {}", e.getMessage(), e);
640 ActionStatus successStatus = createOrUpdateResponse.left().value().right;
641 response = buildOkResponse(getComponentsUtils().getResponseFormat(successStatus), representation);
643 responseWrapper.setInnerElement(response);
646 private Either<ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus>, ResponseFormat> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user, String resourceUniqueId) {
648 Either<org.openecomp.sdc.be.model.Resource, ResponseFormat> createOrUpdateResourceRes;
649 ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus> result = null;
650 ActionStatus actionStatus;
651 org.openecomp.sdc.be.model.Resource resource = new org.openecomp.sdc.be.model.Resource();
652 String payloadName = resourceInfoObject.getPayloadName();
653 fillResourceFromResourceInfoObject(resource, resourceInfoObject);
655 Either<Map<String, byte[]>, ResponseFormat> csarUIPayloadRes = getScarFromPayload(resourceInfoObject);
656 if (csarUIPayloadRes.isRight()) {
657 return Either.right(csarUIPayloadRes.right().value());
659 Map<String, byte[]> csarUIPayload = csarUIPayloadRes.left().value();
661 createOrUpdateResourceRes = getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName);
662 if (createOrUpdateResourceRes.isRight()) {
663 return Either.right(createOrUpdateResourceRes.right().value());
665 if (resourceUniqueId == null || resourceUniqueId.isEmpty()) {
666 createOrUpdateResourceRes = resourceImportManager.getResourceBusinessLogic().createResource(resource, AuditingActionEnum.CREATE_RESOURCE, user, csarUIPayload, payloadName);
667 if (createOrUpdateResourceRes.isRight()) {
668 return Either.right(createOrUpdateResourceRes.right().value());
670 actionStatus = ActionStatus.CREATED;
672 createOrUpdateResourceRes = resourceImportManager.getResourceBusinessLogic().validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId);
673 if (createOrUpdateResourceRes.isRight()) {
674 return Either.right(createOrUpdateResourceRes.right().value());
676 actionStatus = ActionStatus.OK;
678 result = new ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus>(createOrUpdateResourceRes.left().value(), actionStatus);
679 return Either.left(result);
682 private Either<org.openecomp.sdc.be.model.Resource, ResponseFormat> getAndValidateCsarYaml(Map<String, byte[]> csarUIPayload, org.openecomp.sdc.be.model.Resource resource, User user, String csarUUID) {
684 Either<ImmutablePair<String, String>, ResponseFormat> getToscaYamlRes = CsarValidationUtils.getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils());
686 if (getToscaYamlRes.isRight()) {
687 ResponseFormat responseFormat = getToscaYamlRes.right().value();
688 log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
689 BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
690 getComponentsUtils().auditResource(responseFormat, user, resource, AuditingActionEnum.CREATE_RESOURCE);
691 return Either.right(responseFormat);
693 String toscaYaml = getToscaYamlRes.left().value().getValue();
695 log.debug("checking tosca template is valid yml");
696 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
697 boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes());
699 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
700 getComponentsUtils().auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
701 return Either.right(responseFormat);
704 log.debug("checking payload is valid tosca");
705 String heatDecodedPayload = toscaYaml;
706 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
707 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION);
709 if (findFirstToscaStringElement.isRight()) {
712 String defenitionVersionFound = findFirstToscaStringElement.left().value();
713 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
716 isValid = TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
721 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
722 getComponentsUtils().auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE);
723 return Either.right(responseFormat);
725 return Either.left(resource);
728 private void fillResourceFromResourceInfoObject(org.openecomp.sdc.be.model.Resource resource, UploadResourceInfo resourceInfoObject) {
729 resourceImportManager.populateResourceMetadata(resourceInfoObject, resource);
730 fillArtifacts(resource, resourceInfoObject);
734 private void fillArtifacts(org.openecomp.sdc.be.model.Resource resource, UploadResourceInfo resourceInfoObject) {
735 if (resource != null && resourceInfoObject != null) {
736 List<UploadArtifactInfo> artifactList = resourceInfoObject.getArtifactList();
737 if (artifactList != null) {
738 Map<String, ArtifactDefinition> artifactsHM = new HashMap<String, ArtifactDefinition>();
739 for (UploadArtifactInfo artifact : artifactList) {
740 ArtifactDefinition artifactDef = new ArtifactDefinition();
741 artifactDef.setArtifactName(artifact.getArtifactName());
742 artifactDef.setArtifactType(artifact.getArtifactType().getType());
743 artifactDef.setDescription(artifact.getArtifactDescription());
744 artifactDef.setPayloadData(artifact.getArtifactData());
745 artifactDef.setArtifactRef(artifact.getArtifactPath());
746 artifactsHM.put(artifactDef.getArtifactName(), artifactDef);
748 resource.setArtifacts(artifactsHM);
753 private Either<Map<String, byte[]>, ResponseFormat> getScarFromPayload(UploadResourceInfo innerElement) {
754 String csarUUID = innerElement.getPayloadName();
755 String payloadData = innerElement.getPayloadData();
756 if (payloadData == null) {
757 log.info("Failed to decode received csar", csarUUID);
758 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID));
761 byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8));
762 if (decodedPayload == null) {
763 log.info("Failed to decode received csar", csarUUID);
764 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID));
767 Map<String, byte[]> csar = ZipUtil.readZip(decodedPayload);
769 log.info("Failed to unzip received csar", csarUUID);
770 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID));
772 return Either.left(csar);
775 protected void validateInputStream(final HttpServletRequest request, Wrapper<String> dataWrapper, Wrapper<ResponseFormat> errorWrapper) throws IOException {
776 InputStream inputStream = request.getInputStream();
777 byte[] bytes = IOUtils.toByteArray(inputStream);
778 if (bytes == null || bytes.length == 0) {
779 log.info("Empty body was sent.");
780 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
782 dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8));
787 protected <T> void validateClassParse(String data, Wrapper<T> parsedClassWrapper, Supplier<Class<T>> classGen, Wrapper<ResponseFormat> errorWrapper) {
789 T parsedClass = gson.fromJson(data, classGen.get());
790 if (parsedClass == null) {
791 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
793 parsedClassWrapper.setInnerElement(parsedClass);
795 } catch (JsonSyntaxException e) {
796 log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e);
797 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
801 protected void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType, Wrapper<ComponentInstanceBusinessLogic> blWrapper, Wrapper<ResponseFormat> errorWrapper) {
802 ServletContext context = request.getSession().getServletContext();
804 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
805 ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum);
806 if (componentInstanceLogic == null) {
807 log.debug("Unsupported component type {}", containerComponentType);
808 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
810 blWrapper.setInnerElement(componentInstanceLogic);
814 protected <T> Response buildResponseFromElement(Wrapper<ResponseFormat> errorWrapper, Wrapper<T> attributeWrapper) throws IOException {
816 if (errorWrapper.isEmpty()) {
817 ObjectMapper mapper = new ObjectMapper();
818 String result = mapper.writeValueAsString(attributeWrapper.getInnerElement());
819 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
821 response = buildErrorResponse(errorWrapper.getInnerElement());
826 protected void validateXECOMPInstanceIDHeader(String instanceIdHeader, Wrapper<ResponseFormat> responseWrapper) {
827 ResponseFormat responseFormat;
828 if(StringUtils.isEmpty(instanceIdHeader) ){
829 log.debug("Missing X-ECOMP-InstanceID header");
830 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
831 responseWrapper.setInnerElement(responseFormat);
835 protected void validateHttpCspUserIdHeader(String header, Wrapper<ResponseFormat> responseWrapper) {
836 ResponseFormat responseFormat;
837 if( StringUtils.isEmpty(header)){
838 log.debug("MissingUSER_ID");
839 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
840 responseWrapper.setInnerElement(responseFormat);
845 * Convert json to Object object
847 * @param classSupplier
851 public <T> Either<T, ResponseFormat> parseToObject(String json, Supplier<Class<T>> classSupplier) {
854 T object = RepresentationUtils.fromRepresentation(json, classSupplier.get());
855 return Either.left(object);
856 } catch (Exception e) {
857 log.debug("Failed to parse json to {} object", classSupplier.get().getName(), e);
858 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
859 return Either.right(responseFormat);
864 * Convert json to Object object
870 public <T> Either<List<T>, ResponseFormat> parseListOfObjects(String json, Type type) {
872 List<T> listOfObjects = gson.fromJson(json, type);
873 return Either.left(listOfObjects);
874 } catch (Exception e) {
875 log.debug("Failed to parse json to {} object", type.getClass().getName(), e);
876 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
877 return Either.right(responseFormat);