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;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.lang.reflect.Type;
29 import java.nio.charset.StandardCharsets;
30 import java.util.EnumMap;
31 import java.util.HashMap;
32 import java.util.List;
34 import java.util.function.Supplier;
35 import java.util.zip.ZipInputStream;
37 import javax.annotation.Resource;
38 import javax.servlet.ServletContext;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.ws.rs.core.Response;
42 import org.apache.commons.codec.binary.Base64;
43 import org.apache.commons.io.IOUtils;
44 import org.apache.commons.lang3.StringUtils;
45 import org.apache.commons.lang3.tuple.ImmutablePair;
46 import org.codehaus.jackson.map.ObjectMapper;
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.ImportUtils.ToscaTagNamesEnum;
53 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
54 import org.openecomp.sdc.be.config.BeEcompErrorManager;
55 import org.openecomp.sdc.be.dao.api.ActionStatus;
56 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
57 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
58 import org.openecomp.sdc.be.impl.ComponentsUtils;
59 import org.openecomp.sdc.be.impl.ServletUtils;
60 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
61 import org.openecomp.sdc.be.model.ArtifactDefinition;
62 import org.openecomp.sdc.be.model.UploadResourceInfo;
63 import org.openecomp.sdc.be.model.User;
64 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
65 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
66 import org.openecomp.sdc.be.user.IUserBusinessLogic;
67 import org.openecomp.sdc.be.user.Role;
68 import org.openecomp.sdc.common.api.Constants;
69 import org.openecomp.sdc.common.api.UploadArtifactInfo;
70 import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum;
71 import org.openecomp.sdc.common.datastructure.Wrapper;
72 import org.openecomp.sdc.common.util.GeneralUtility;
73 import org.openecomp.sdc.common.util.YamlToObjectConverter;
74 import org.openecomp.sdc.common.util.ZipUtil;
75 import org.openecomp.sdc.exception.ResponseFormat;
76 import org.slf4j.Logger;
77 import org.springframework.beans.factory.annotation.Autowired;
78 import org.springframework.web.context.WebApplicationContext;
79 import org.yaml.snakeyaml.Yaml;
81 import com.google.gson.Gson;
82 import com.google.gson.JsonSyntaxException;
84 import fj.data.Either;
86 public abstract class AbstractValidationsServlet extends BeGenericServlet {
89 private ServletUtils servletUtils;
92 private ResourceImportManager resourceImportManager;
95 protected ComponentsUtils componentsUtils;
97 private Logger log = null;
99 protected void init(Logger log) {
101 initSpringFromContext();
105 protected synchronized void initLog(Logger log) {
106 if (this.log == null) {
111 private synchronized void initSpringFromContext() {
112 if (servletUtils == null) {
113 ServletContext context = servletRequest.getSession().getServletContext();
114 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
115 .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
116 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
117 servletUtils = webApplicationContext.getBean(ServletUtils.class);
118 resourceImportManager = webApplicationContext.getBean(ResourceImportManager.class);
122 protected void validateResourceDoesNotExist(Wrapper<Response> responseWrapper, User user, String resourceName) {
123 if (resourceImportManager.isResourceExist(resourceName)) {
124 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS);
125 Response errorResponse = buildErrorResponse(responseFormat);
126 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
127 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceName);
128 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
129 responseWrapper.setInnerElement(errorResponse);
133 protected void validateUserExist(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, String userUserId) {
134 log.debug("get user {} from DB", userUserId);
136 if (userUserId == null) {
137 log.info("user userId is null");
138 Response response = returnMissingInformation(new User());
139 responseWrapper.setInnerElement(response);
143 IUserBusinessLogic userAdmin = getServletUtils().getUserAdmin();
144 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(userUserId, false);
145 if (eitherCreator.isRight()) {
146 log.info("user is not listed. userId={}", userUserId);
147 User user = new User();
148 user.setUserId(userUserId);
149 Response response = returnMissingInformation(user);
150 responseWrapper.setInnerElement(response);
152 userWrapper.setInnerElement(eitherCreator.left().value());
157 protected Response returnMissingInformation(User user) {
158 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION);
159 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null);
160 return buildErrorResponse(responseFormat);
163 protected void validateDataNotNull(Wrapper<Response> responseWrapper, Object... dataParams) {
164 for (Object dataElement : dataParams) {
165 if (dataElement == null) {
166 log.info("Invalid body was received.");
167 Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
168 responseWrapper.setInnerElement(response);
175 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user) {
176 log.debug("validate user role");
177 if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) {
178 log.info("user is not in appropriate role to perform action");
179 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
180 log.debug("audit before sending response");
181 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null);
183 Response response = buildErrorResponse(responseFormat);
184 errorResponseWrapper.setInnerElement(response);
189 protected void validateZip(Wrapper<Response> responseWrapper, File file, String payloadName) throws FileNotFoundException {
190 InputStream fileInputStream = new FileInputStream(file);
191 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
192 if (payloadName == null || payloadName.isEmpty() || !unzippedFolder.containsKey(payloadName)) {
193 log.info("Invalid json was received. payloadName should be yml file name");
194 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
195 responseWrapper.setInnerElement(errorResponse);
199 protected void validateCsar(Wrapper<Response> responseWrapper, File file, String payloadName) throws FileNotFoundException {
200 InputStream fileInputStream = new FileInputStream(file);
201 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
202 if (payloadName == null || payloadName.isEmpty() || unzippedFolder.isEmpty()) {
203 log.info("Invalid json was received. payloadName should be yml file name");
204 Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
205 responseWrapper.setInnerElement(errorResponse);
210 protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws FileNotFoundException {
211 InputStream fileInputStream = new FileInputStream(file);
212 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
213 String ymlName = unzippedFolder.keySet().iterator().next();
214 fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file);
217 protected void fillToscaTemplateFromZip(Wrapper<String> yamlStringWrapper, String payloadName, File file) throws FileNotFoundException {
218 InputStream fileInputStream = new FileInputStream(file);
219 Map<String, byte[]> unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream));
220 byte[] yamlFileInBytes = unzippedFolder.get(payloadName);
221 String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8);
222 log.debug("received yaml: {}", yamlAsString);
223 yamlStringWrapper.setInnerElement(yamlAsString);
226 protected void fillPayloadDataFromFile(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfoWrapper, File file) {
227 try(InputStream fileInputStream = new FileInputStream(file);){
229 byte [] data = new byte[(int)file.length()];
230 if( fileInputStream.read(data) == -1){
231 log.info("Invalid json was received.");
232 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
234 Response errorResp = buildErrorResponse(responseFormat);
235 responseWrapper.setInnerElement(errorResp);
237 String payloadData = Base64.encodeBase64String(data);
238 uploadResourceInfoWrapper.setPayloadData(payloadData);
242 } catch (IOException e) {
243 log.info("Invalid json was received or Error while closing input Stream.");
244 log.debug("Invalid json was received or Error while closing input Stream. {}", e.getMessage(), e);
245 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
247 Response errorResp = buildErrorResponse(responseFormat);
248 responseWrapper.setInnerElement(errorResp);
253 protected void validateUserRole(Wrapper<Response> errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) {
254 log.debug("validate user role");
255 if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) {
256 if (!user.getRole().equals(Role.ADMIN.name())) {
257 log.info("user is not in appropriate role to perform action");
258 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
259 log.debug("audit before sending response");
260 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null);
262 Response response = buildErrorResponse(responseFormat);
263 errorResponseWrapper.setInnerElement(response);
266 validateUserRole(errorResponseWrapper, user);
271 protected void validateAndFillResourceJson(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, User user, ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) {
274 log.debug("The received json is {}", resourceInfo);
275 UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class);
276 if (resourceInfoObject == null) {
279 if (!resourceAuthorityEnum.isBackEndImport()) {
280 isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty();
281 //only resource name is checked
285 uploadResourceInfoWrapper.setInnerElement(resourceInfoObject);
288 } catch (JsonSyntaxException e) {
289 log.debug("Invalid json was received. {}", e.getMessage(), e);
294 log.info("Invalid json was received.");
295 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
296 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null);
297 Response errorResp = buildErrorResponse(responseFormat);
298 responseWrapper.setInnerElement(errorResp);
302 protected void validateAuthorityType(Wrapper<Response> responseWrapper, String authorityType) {
303 log.debug("The received authority type is {}", authorityType);
304 ResourceAuthorityTypeEnum authorityTypeEnum = ResourceAuthorityTypeEnum.findByUrlPath(authorityType);
305 if (authorityTypeEnum == null) {
306 log.info("Invalid authority type was received.");
307 Response errorResp = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
308 responseWrapper.setInnerElement(errorResp);
312 public ServletUtils getServletUtils() {
313 initSpringFromContext();
317 public Gson getGson() {
318 return getServletUtils().getGson();
321 public ComponentsUtils getComponentsUtils() {
322 return getServletUtils().getComponentsUtils();
325 protected void validatePayloadIsTosca(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
326 log.debug("checking payload is valid tosca");
328 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
329 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION);
331 if (findFirstToscaStringElement.isRight()) {
334 String defenitionVersionFound = findFirstToscaStringElement.left().value();
335 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
338 isValid = ImportUtils.Constants.TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
343 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
344 Response errorResponse = buildErrorResponse(responseFormat);
345 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
346 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName());
347 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
348 responseWrapper.setInnerElement(errorResponse);
353 protected void validatePayloadIsYml(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaTamplatePayload) {
354 log.debug("checking tosca template is valid yml");
355 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
356 boolean isYamlValid = yamlConvertor.isValidYaml(toscaTamplatePayload.getBytes());
358 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
359 Response errorResponse = buildErrorResponse(responseFormat);
360 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
361 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName());
362 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
363 responseWrapper.setInnerElement(errorResponse);
367 protected void validatePayloadNameSpace(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, String toscaPayload) {
369 String nameSpace = "";
370 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
371 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.NODE_TYPES);
372 if (toscaElement.isRight() || toscaElement.left().value().size() != 1) {
375 nameSpace = toscaElement.left().value().keySet().iterator().next();
376 isValid = nameSpace.startsWith(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX);
379 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE);
380 Response errorResponse = buildErrorResponse(responseFormat);
381 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
382 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInfo.getName());
383 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
384 responseWrapper.setInnerElement(errorResponse);
386 String str1 = nameSpace.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length());
387 String[] findTypes = str1.split("\\.");
388 if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) {
389 String type = findTypes[0].toUpperCase();
390 resourceInfo.setResourceType(type);
392 resourceInfo.setResourceType(ResourceTypeEnum.VFC.name());
398 protected void validatePayloadIsSingleResource(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) {
399 log.debug("checking payload contains single resource");
401 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
402 Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.NODE_TYPES);
403 if (toscaElement.isRight()) {
406 isValid = toscaElement.left().value().size() == 1;
410 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_SINGLE_RESOURCE);
411 Response errorResponse = buildErrorResponse(responseFormat);
412 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
413 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName());
414 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
415 responseWrapper.setInnerElement(errorResponse);
420 protected void validatePayloadIsNotService(Wrapper<Response> responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaPayload) {
421 log.debug("checking payload is not a tosca service");
422 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(toscaPayload);
423 Either<Object, ResultStatusEnum> toscaElement = ImportUtils.findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL);
425 if (toscaElement.isLeft()) {
426 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE);
427 Response errorResponse = buildErrorResponse(responseFormat);
428 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
429 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName());
430 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
431 responseWrapper.setInnerElement(errorResponse);
436 protected void validateToscaTemplatePayloadName(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user) {
437 String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName();
438 boolean isValidSuffix = false;
439 if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) {
440 for (String validSuffix : ImportUtils.Constants.TOSCA_YML_CSAR_VALID_SUFFIX) {
441 isValidSuffix = isValidSuffix || toscaTemplatePayloadName.toLowerCase().endsWith(validSuffix);
444 if (!isValidSuffix) {
445 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
446 Response errorResponse = buildErrorResponse(responseFormat);
447 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
448 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName());
449 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
450 responseWrapper.setInnerElement(errorResponse);
455 protected void validateMD5(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request, String resourceInfoJsonString) {
457 String recievedMD5 = request.getHeader(Constants.MD5_HEADER);
458 if (recievedMD5 == null) {
461 String calculateMD5 = GeneralUtility.calculateMD5Base64EncodedByString(resourceInfoJsonString);
462 isValid = calculateMD5.equals(recievedMD5);
465 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM);
466 Response errorResponse = buildErrorResponse(responseFormat);
467 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
468 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInfo.getName());
469 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
470 responseWrapper.setInnerElement(errorResponse);
474 protected void validateComponentType(Wrapper<Response> responseWrapper, Wrapper<ComponentTypeEnum> componentWrapper, String componentType) {
476 if (componentType == null) {
479 if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) {
481 componentWrapper.setInnerElement(ComponentTypeEnum.RESOURCE);
482 } else if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) {
484 componentWrapper.setInnerElement(ComponentTypeEnum.SERVICE);
490 log.debug("Invalid componentType:{}", componentType);
491 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
492 Response errorResp = buildErrorResponse(responseFormat);
493 responseWrapper.setInnerElement(errorResp);
497 protected void fillToscaTemplateFromJson(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo resourceInfo) {
498 if (resourceInfo.getPayloadData() == null || resourceInfo.getPayloadData().isEmpty()) {
499 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD);
500 Response errorResponse = buildErrorResponse(responseFormat);
501 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
502 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInfo.getName());
503 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
504 responseWrapper.setInnerElement(errorResponse);
506 String toscaPayload = resourceInfo.getPayloadData();
507 String decodedPayload = new String(Base64.decodeBase64(toscaPayload));
508 yamlStringWrapper.setInnerElement(decodedPayload);
513 protected void fillPayload(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, String resourceInfoJsonString, ResourceAuthorityTypeEnum resourceAuthorityEnum,
514 File file) throws FileNotFoundException {
516 if (responseWrapper.isEmpty()) {
517 if (resourceAuthorityEnum.isBackEndImport()) {
518 // PrePayload Validations
519 if (responseWrapper.isEmpty()) {
520 validateDataNotNull(responseWrapper, file, resourceInfoJsonString);
522 if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){
523 if (responseWrapper.isEmpty()) {
524 validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
527 // Fill PayLoad From File
528 if (responseWrapper.isEmpty()) {
529 fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file);
533 if (responseWrapper.isEmpty()) {
534 validateCsar(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName());
537 // Fill PayLoad From File
538 if (responseWrapper.isEmpty()) {
539 fillPayloadDataFromFile(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), file);
545 // Fill PayLoad From JSON
546 if (responseWrapper.isEmpty()) {
547 fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement());
555 protected void specificResourceAuthorityValidations(Wrapper<Response> responseWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, Wrapper<String> yamlStringWrapper, User user, HttpServletRequest request, String resourceInfoJsonString,
556 ResourceAuthorityTypeEnum resourceAuthorityEnum) throws FileNotFoundException {
558 if (responseWrapper.isEmpty()) {
559 // UI Only Validation
560 if (!resourceAuthorityEnum.isBackEndImport()) {
561 importUIValidations(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, request, resourceInfoJsonString);
564 // User Defined Type Resources
565 if (resourceAuthorityEnum.isUserTypeResource() && !CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
566 if (responseWrapper.isEmpty()) {
567 validatePayloadNameSpace(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement());
574 protected void commonGeneralValidations(Wrapper<Response> responseWrapper, Wrapper<User> userWrapper, Wrapper<UploadResourceInfo> uploadResourceInfoWrapper, ResourceAuthorityTypeEnum resourceAuthorityEnum, String userUserId,
575 String resourceInfoJsonString) {
577 if (responseWrapper.isEmpty()) {
578 validateUserExist(responseWrapper, userWrapper, userUserId);
581 if (responseWrapper.isEmpty()) {
582 validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum);
585 if (responseWrapper.isEmpty()) {
586 validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum, resourceInfoJsonString);
589 if (responseWrapper.isEmpty()) {
590 validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement());
592 if (responseWrapper.isEmpty()) {
593 validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement(), resourceAuthorityEnum);
598 private void validateResourceType(Wrapper<Response> responseWrapper, UploadResourceInfo uploadResourceInfo, User user, ResourceAuthorityTypeEnum resourceAuthorityEnum) {
599 String resourceType = uploadResourceInfo.getResourceType();
600 if (resourceType == null || !ResourceTypeEnum.containsName(resourceType)) {
601 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
602 Response errorResponse = buildErrorResponse(responseFormat);
603 EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class);
604 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName());
605 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
606 responseWrapper.setInnerElement(errorResponse);
608 if (resourceType.equals(ResourceTypeEnum.getTypeByName("VF").getValue()) && resourceAuthorityEnum == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE){
609 log.debug("Import of VF resource type is forbidden - VF resource import can be done using onboarding flow only");
610 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_TYPE);
611 Response errorResponse = buildErrorResponse(responseFormat);
612 EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class);
613 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName());
614 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
615 responseWrapper.setInnerElement(errorResponse);
619 protected void importUIValidations(Wrapper<Response> responseWrapper, UploadResourceInfo resourceInfo, User user, HttpServletRequest request, String resourceInfoJsonString) {
620 if (responseWrapper.isEmpty()) {
621 validateMD5(responseWrapper, user, resourceInfo, request, resourceInfoJsonString);
623 if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) {
624 validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName());
628 protected void commonPayloadValidations(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) {
630 if (responseWrapper.isEmpty()) {
631 validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
633 if (responseWrapper.isEmpty()) {
634 validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
636 if (responseWrapper.isEmpty()) {
637 validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
639 if (responseWrapper.isEmpty()) {
640 validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
644 /*protected void topologyTemplatePayloadValidations(Wrapper<Response> responseWrapper, Wrapper<String> yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) {
646 if (responseWrapper.isEmpty()) {
647 validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
649 if (responseWrapper.isEmpty()) {
650 validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement());
652 if (responseWrapper.isEmpty()) {
653 validatePayloadIsTopologyTemplate(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement());
658 protected void handleImport(Wrapper<Response> responseWrapper, User user, UploadResourceInfo resourceInfoObject, String yamlAsString, ResourceAuthorityTypeEnum authority, boolean createNewVersion, String resourceUniqueId) {
659 Either<ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus>, ResponseFormat> createOrUpdateResponse;
661 Object representation = null;
663 if (CsarValidationUtils.isCsarPayloadName(resourceInfoObject.getPayloadName())) {
664 log.debug("import resource from csar");
666 createOrUpdateResponse = importResourceFromUICsar(resourceInfoObject, user, resourceUniqueId);
667 //if (createOrUpdateResponse.isLeft()){
668 // LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction();
669 // lifecycleChangeInfo.setUserRemarks("certification on import");
670 // Function<Resource, Either<Boolean, ResponseFormat>> validator = (resource) -> resourceImportManager.getResourceBusinessLogic().validatePropertiesDefaultValues(createOrUpdateResponse.left().value().left);
673 } else if (!authority.isUserTypeResource()) {
674 log.debug("import normative type resource");
675 createOrUpdateResponse = resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, user, createNewVersion, true);
677 log.debug("import user resource (not normative type)");
678 createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user, false, false);
680 if (createOrUpdateResponse.isRight()) {
681 response = buildErrorResponse(createOrUpdateResponse.right().value());
684 representation = RepresentationUtils.toRepresentation(createOrUpdateResponse.left().value().getLeft());
685 } catch (IOException e) {
686 log.debug("Error while building resource representation : {}", e.getMessage(), e);
688 ActionStatus successStatus = createOrUpdateResponse.left().value().right;
689 response = buildOkResponse(getComponentsUtils().getResponseFormat(successStatus), representation);
691 responseWrapper.setInnerElement(response);
694 private Either<ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus>, ResponseFormat> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user, String resourceUniqueId) {
696 Either<org.openecomp.sdc.be.model.Resource, ResponseFormat> createOrUpdateResourceRes;
697 ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus> result = null;
698 ActionStatus actionStatus;
699 org.openecomp.sdc.be.model.Resource resource = new org.openecomp.sdc.be.model.Resource();
700 String payloadName = resourceInfoObject.getPayloadName();
701 fillResourceFromResourceInfoObject(resource, resourceInfoObject);
703 Either<Map<String, byte[]>, ResponseFormat> csarUIPayloadRes = getScarFromPayload(resourceInfoObject);
704 if (csarUIPayloadRes.isRight()) {
705 return Either.right(csarUIPayloadRes.right().value());
707 Map<String, byte[]> csarUIPayload = csarUIPayloadRes.left().value();
709 createOrUpdateResourceRes = getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName);
710 if (createOrUpdateResourceRes.isRight()) {
711 return Either.right(createOrUpdateResourceRes.right().value());
713 if (resourceUniqueId == null || resourceUniqueId.isEmpty()) {
714 createOrUpdateResourceRes = resourceImportManager.getResourceBusinessLogic().createResource(resource, AuditingActionEnum.CREATE_RESOURCE, user, csarUIPayload, payloadName);
715 if (createOrUpdateResourceRes.isRight()) {
716 return Either.right(createOrUpdateResourceRes.right().value());
718 actionStatus = ActionStatus.CREATED;
720 createOrUpdateResourceRes = resourceImportManager.getResourceBusinessLogic().validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId);
721 if (createOrUpdateResourceRes.isRight()) {
722 return Either.right(createOrUpdateResourceRes.right().value());
724 actionStatus = ActionStatus.OK;
726 result = new ImmutablePair<org.openecomp.sdc.be.model.Resource, ActionStatus>(createOrUpdateResourceRes.left().value(), actionStatus);
727 return Either.left(result);
730 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) {
732 Either<ImmutablePair<String, String>, ResponseFormat> getToscaYamlRes = CsarValidationUtils.getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils());
734 if (getToscaYamlRes.isRight()) {
735 ResponseFormat responseFormat = getToscaYamlRes.right().value();
736 log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat);
737 BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
738 getComponentsUtils().auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.CREATE_RESOURCE, null);
739 return Either.right(responseFormat);
741 String toscaYaml = getToscaYamlRes.left().value().getValue();
743 log.debug("checking tosca template is valid yml");
744 YamlToObjectConverter yamlConvertor = new YamlToObjectConverter();
745 boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes());
747 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE);
748 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
749 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resource.getName());
750 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
751 return Either.right(responseFormat);
754 log.debug("checking payload is valid tosca");
755 String heatDecodedPayload = toscaYaml;
756 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
757 Either<String, ResultStatusEnum> findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION);
759 if (findFirstToscaStringElement.isRight()) {
762 String defenitionVersionFound = findFirstToscaStringElement.left().value();
763 if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) {
766 isValid = ImportUtils.Constants.TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound);
771 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE);
772 EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class);
773 additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resource.getName());
774 getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam);
775 return Either.right(responseFormat);
777 return Either.left(resource);
780 private void fillResourceFromResourceInfoObject(org.openecomp.sdc.be.model.Resource resource, UploadResourceInfo resourceInfoObject) {
781 if (resource != null && resourceInfoObject != null) {
782 resource.setDescription(resourceInfoObject.getDescription());
783 resource.setTags(resourceInfoObject.getTags());
784 resource.setCategories(resourceInfoObject.getCategories());
785 resource.setContactId(resourceInfoObject.getContactId());
786 resource.setName(resourceInfoObject.getName());
787 resource.setIcon(resourceInfoObject.getResourceIconPath());
788 resource.setVendorName(resourceInfoObject.getVendorName());
789 resource.setVendorRelease(resourceInfoObject.getVendorRelease());
790 resource.setResourceType(ResourceTypeEnum.valueOf(resourceInfoObject.getResourceType()));
791 List<UploadArtifactInfo> artifactList = resourceInfoObject.getArtifactList();
792 if (artifactList != null) {
793 Map<String, ArtifactDefinition> artifactsHM = new HashMap<String, ArtifactDefinition>();
794 for (UploadArtifactInfo artifact : artifactList) {
795 ArtifactDefinition artifactDef = new ArtifactDefinition();
796 artifactDef.setArtifactName(artifact.getArtifactName());
797 artifactDef.setArtifactType(artifact.getArtifactType().getType());
798 artifactDef.setDescription(artifact.getArtifactDescription());
799 artifactDef.setPayloadData(artifact.getArtifactData());
800 artifactDef.setArtifactRef(artifact.getArtifactPath());
801 artifactsHM.put(artifactDef.getArtifactName(), artifactDef);
803 resource.setArtifacts(artifactsHM);
809 private Either<Map<String, byte[]>, ResponseFormat> getScarFromPayload(UploadResourceInfo innerElement) {
810 String csarUUID = innerElement.getPayloadName();
811 String payloadData = innerElement.getPayloadData();
812 if (payloadData == null) {
813 log.info("Failed to decode received csar", csarUUID);
814 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID));
817 byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8));
818 if (decodedPayload == null) {
819 log.info("Failed to decode received csar", csarUUID);
820 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID));
823 Map<String, byte[]> csar = ZipUtil.readZip(decodedPayload);
825 log.info("Failed to unzip received csar", csarUUID);
826 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID));
828 return Either.left(csar);
831 protected void validateInputStream(final HttpServletRequest request, Wrapper<String> dataWrapper, Wrapper<ResponseFormat> errorWrapper) throws IOException {
832 InputStream inputStream = request.getInputStream();
833 byte[] bytes = IOUtils.toByteArray(inputStream);
834 if (bytes == null || bytes.length == 0) {
835 log.info("Empty body was sent.");
836 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
838 dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8));
843 protected <T> void validateClassParse(String data, Wrapper<T> parsedClassWrapper, Supplier<Class<T>> classGen, Wrapper<ResponseFormat> errorWrapper) {
845 T parsedClass = gson.fromJson(data, classGen.get());
846 if (parsedClass == null) {
847 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
849 parsedClassWrapper.setInnerElement(parsedClass);
851 } catch (JsonSyntaxException e) {
852 log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e);
853 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
857 protected void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType, Wrapper<ComponentInstanceBusinessLogic> blWrapper, Wrapper<ResponseFormat> errorWrapper) {
858 ServletContext context = request.getSession().getServletContext();
860 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
861 ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum);
862 if (componentInstanceLogic == null) {
863 log.debug("Unsupported component type {}", containerComponentType);
864 errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
866 blWrapper.setInnerElement(componentInstanceLogic);
870 protected <T> Response buildResponseFromElement(Wrapper<ResponseFormat> errorWrapper, Wrapper<T> attributeWrapper) throws IOException {
872 if (errorWrapper.isEmpty()) {
873 ObjectMapper mapper = new ObjectMapper();
874 String result = mapper.writeValueAsString(attributeWrapper.getInnerElement());
875 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
877 response = buildErrorResponse(errorWrapper.getInnerElement());
882 protected void validateXECOMPInstanceIDHeader(String instanceIdHeader, Wrapper<ResponseFormat> responseWrapper) {
883 ResponseFormat responseFormat;
884 if(StringUtils.isEmpty(instanceIdHeader) ){
885 log.debug("Missing X-ECOMP-InstanceID header");
886 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
887 responseWrapper.setInnerElement(responseFormat);
891 protected void validateHttpCspUserIdHeader(String header, Wrapper<ResponseFormat> responseWrapper) {
892 ResponseFormat responseFormat;
893 if( StringUtils.isEmpty(header)){
894 log.debug("MissingUSER_ID");
895 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
896 responseWrapper.setInnerElement(responseFormat);
901 * Convert json to Object object
903 * @param classSupplier
907 public <T> Either<T, ResponseFormat> parseToObject(String json, Supplier<Class<T>> classSupplier) {
910 T object = RepresentationUtils.fromRepresentation(json, classSupplier.get());
911 return Either.left(object);
912 } catch (Exception e) {
913 log.debug("Failed to parse json to {} object", classSupplier.get().getName(), e);
914 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
915 return Either.right(responseFormat);
920 * Convert json to Object object
926 public <T> Either<List<T>, ResponseFormat> parseListOfObjects(String json, Type type) {
928 List<T> listOfObjects = gson.fromJson(json, type);
929 return Either.left(listOfObjects);
930 } catch (Exception e) {
931 log.debug("Failed to parse json to {} object", type.getClass().getName(), e);
932 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
933 return Either.right(responseFormat);