From bf5eeb23a769a2e2b75f432b74f10fdbcfd2f161 Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Fri, 27 Sep 2019 13:27:11 +0100 Subject: Fix zip slip security flaw Apply zip slip checking in zip operations throughout the system. Centralizes most of the zip logic in one class. Create tests to zip functionalities and zip slip problem. Change-Id: I721f3d44b34fe6d242c9537f5a515ce1bb534c9a Issue-ID: SDC-1401 Signed-off-by: andre.schmid --- .../be/servlets/AbstractValidationsServlet.java | 84 +- .../sdc/be/servlets/ResourceUploadServlet.java | 373 ++++--- .../sdc/be/servlets/ResourcesServlet.java | 1146 ++++++++++---------- .../sdc/be/servlets/TypesUploadEndpoint.java | 279 ++--- .../java/org/openecomp/sdc/be/tosca/CsarUtils.java | 25 +- .../src/test/java/org/openecomp/sdc/ZipUtil.java | 143 --- .../be/components/csar/CsarBusinessLogicTest.java | 13 +- .../sdc/be/components/csar/CsarInfoTest.java | 14 +- .../impl/utils/YamlTemplateParsingHandlerTest.java | 30 +- 9 files changed, 1007 insertions(+), 1100 deletions(-) delete mode 100644 catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java (limited to 'catalog-be') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java index e00889646a..514576fcd8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java @@ -42,12 +42,12 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.collections4.MapUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.CsarValidationUtils; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; import org.openecomp.sdc.be.components.impl.ImportUtils; import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; @@ -75,7 +75,8 @@ import org.openecomp.sdc.common.datastructure.Wrapper; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.GeneralUtility; import org.openecomp.sdc.common.util.YamlToObjectConverter; -import org.openecomp.sdc.common.util.ZipUtil; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.exception.ResponseFormat; import org.yaml.snakeyaml.Yaml; @@ -168,37 +169,76 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } - protected void validateZip(Wrapper responseWrapper, File file, String payloadName) { - Map unzippedFolder = ZipUtil.readZip(file); - if (payloadName == null || payloadName.isEmpty() || !unzippedFolder.containsKey(payloadName)) { - log.info("Invalid json was received. payloadName should be yml file name"); - Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + protected void validateZip(final Wrapper responseWrapper, final File zipFile, final String payloadName) { + if (StringUtils.isEmpty(payloadName)) { + log.info("Invalid JSON was received. Payload name is empty"); + final Response errorResponse = + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); responseWrapper.setInnerElement(errorResponse); + return; } + final Map unzippedFolder; + try { + unzippedFolder = ZipUtils.readZip(zipFile, false); + } catch (final ZipException e) { + log.error("Could not read ZIP file '{}' for validation", zipFile.getName(), e); + final Response errorResponse = + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + responseWrapper.setInnerElement(errorResponse); + return; + } + if (!unzippedFolder.containsKey(payloadName)) { + log.info("Could no find payload '{}' in ZIP file '{}'", payloadName, zipFile.getName()); + final Response errorResponse = + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + responseWrapper.setInnerElement(errorResponse); + } + } - protected void validateCsar(Wrapper responseWrapper, File file, String payloadName) { - Map unzippedFolder = ZipUtil.readZip(file); - if (payloadName == null || payloadName.isEmpty() || unzippedFolder.isEmpty()) { - log.info("Invalid json was received. payloadName should be yml file name"); + + protected void validateCsar(final Wrapper responseWrapper, final File csarFile, final String payloadName) { + if (StringUtils.isEmpty(payloadName)) { + log.info("Invalid JSON was received. Payload name is empty"); + Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + responseWrapper.setInnerElement(errorResponse); + return; + } + final Map unzippedFolder; + try { + unzippedFolder = ZipUtils.readZip(csarFile, false); + } catch (final ZipException e) { + log.error("Could not read CSAR file '{}' for validation", csarFile.getName(), e); + final Response errorResponse = + buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + responseWrapper.setInnerElement(errorResponse); + return; + } + if (unzippedFolder.isEmpty()) { + log.info("The CSAR file is empty"); Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); responseWrapper.setInnerElement(errorResponse); } } - protected void fillZipContents(Wrapper yamlStringWrapper, File file) { + protected void fillZipContents(Wrapper yamlStringWrapper, File file) throws ZipException { extractZipContents(yamlStringWrapper, file); } - public static void extractZipContents(Wrapper yamlStringWrapper, File file) { - Map unzippedFolder = ZipUtil.readZip(file); + public static void extractZipContents(Wrapper yamlStringWrapper, File file) throws ZipException { + final Map unzippedFolder = ZipUtils.readZip(file, false); String ymlName = unzippedFolder.keySet().iterator().next(); fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file); } private static void fillToscaTemplateFromZip(Wrapper yamlStringWrapper, String payloadName, File file) { - Map unzippedFolder = ZipUtil.readZip(file); + Map unzippedFolder = null; + try { + unzippedFolder = ZipUtils.readZip(file, false); + } catch (final ZipException e) { + log.info("Failed to unzip file", e); + } byte[] yamlFileInBytes = unzippedFolder.get(payloadName); String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8); log.debug("received yaml: {}", yamlAsString); @@ -738,19 +778,23 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { String csarUUID = innerElement.getPayloadName(); String payloadData = innerElement.getPayloadData(); if (payloadData == null) { - log.info("Failed to decode received csar", csarUUID); + log.info("Failed to decode received csar {}", csarUUID); return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID)); } byte[] decodedPayload = Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8)); if (decodedPayload == null) { - log.info("Failed to decode received csar", csarUUID); + log.info("Failed to decode received csar {}", csarUUID); return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID)); } - Map csar = ZipUtil.readZip(decodedPayload); - if (csar == null) { - log.info("Failed to unzip received csar", csarUUID); + Map csar = null; + try { + csar = ZipUtils.readZip(decodedPayload, false); + } catch (final ZipException e) { + log.info("Failed to unzip received csar {}", csarUUID, e); + } + if (MapUtils.isEmpty(csar)) { return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID)); } return Either.left(csar); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java index 3d7471ebc3..bfd7ce720a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java @@ -1,187 +1,186 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.servlets; - -import java.io.File; -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.UploadResourceInfo; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.openecomp.sdc.common.log.wrappers.Logger; -import com.jcabi.aspects.Loggable; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.info.Info; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -/** - * Root resource (exposed at "/" path) - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/upload") -@OpenAPIDefinition(info = @Info(title = "Resources Catalog Upload", description = "Upload resource yaml")) -@Singleton -public class ResourceUploadServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(ResourceUploadServlet.class); - public static final String NORMATIVE_TYPE_RESOURCE = "multipart"; - public static final String CSAR_TYPE_RESOURCE = "csar"; - public static final String USER_TYPE_RESOURCE = "user-resource"; - public static final String USER_TYPE_RESOURCE_UI_IMPORT = "user-resource-ui-import"; - - @Inject - public ResourceUploadServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - } - - public enum ResourceAuthorityTypeEnum { - NORMATIVE_TYPE_BE(NORMATIVE_TYPE_RESOURCE, true, false), USER_TYPE_BE(USER_TYPE_RESOURCE, true, - true), USER_TYPE_UI(USER_TYPE_RESOURCE_UI_IMPORT, false, - true), CSAR_TYPE_BE(CSAR_TYPE_RESOURCE, true, true); - - private String urlPath; - private boolean isBackEndImport, isUserTypeResource; - - public static ResourceAuthorityTypeEnum findByUrlPath(String urlPath) { - ResourceAuthorityTypeEnum found = null; - for (ResourceAuthorityTypeEnum curr : ResourceAuthorityTypeEnum.values()) { - if (curr.getUrlPath().equals(urlPath)) { - found = curr; - break; - } - } - return found; - } - - private ResourceAuthorityTypeEnum(String urlPath, boolean isBackEndImport, boolean isUserTypeResource) { - this.urlPath = urlPath; - this.isBackEndImport = isBackEndImport; - this.isUserTypeResource = isUserTypeResource; - } - - public String getUrlPath() { - return urlPath; - } - - public boolean isBackEndImport() { - return isBackEndImport; - } - - public boolean isUserTypeResource() { - return isUserTypeResource; - } - } - - @POST - @Path("/{resourceAuthority}") - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "Create Resource from yaml", method = "POST", summary = "Returns created resource", - responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "409", description = "Resource already exist")}) - public Response uploadMultipart( - @Parameter(description = "validValues: normative-resource / user-resource", - schema = @Schema(allowableValues = {NORMATIVE_TYPE_RESOURCE , - USER_TYPE_RESOURCE,USER_TYPE_RESOURCE_UI_IMPORT})) @PathParam( - value = "resourceAuthority") final String resourceAuthority, - @Parameter(description = "FileInputStream") @FormDataParam("resourceZip") File file, - @Parameter(description = "ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader, - @Parameter(description = "resourceMetadata") @FormDataParam("resourceMetadata") String resourceInfoJsonString, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - // updateResourse Query Parameter if false checks if already exist - @DefaultValue("true") @QueryParam("createNewVersion") boolean createNewVersion) { - - try { - - Wrapper responseWrapper = new Wrapper<>(); - Wrapper userWrapper = new Wrapper<>(); - Wrapper uploadResourceInfoWrapper = new Wrapper<>(); - Wrapper yamlStringWrapper = new Wrapper<>(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // When we get an errorResponse it will be filled into the - // responseWrapper - validateAuthorityType(responseWrapper, resourceAuthority); - - ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.findByUrlPath(resourceAuthority); - - commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, resourceInfoJsonString); - - fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), resourceInfoJsonString, resourceAuthorityEnum, file); - - // PayLoad Validations - if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){ - commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); - - specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, resourceAuthorityEnum); - } - - if (responseWrapper.isEmpty()) { - handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, createNewVersion, null); - } - - return responseWrapper.getInnerElement(); - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Upload Resource"); - log.debug("upload resource failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - /********************************************************************************************************************/ -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.servlets; + +import java.io.File; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; +import com.jcabi.aspects.Loggable; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/upload") +@OpenAPIDefinition(info = @Info(title = "Resources Catalog Upload", description = "Upload resource yaml")) +@Singleton +public class ResourceUploadServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(ResourceUploadServlet.class); + public static final String NORMATIVE_TYPE_RESOURCE = "multipart"; + public static final String CSAR_TYPE_RESOURCE = "csar"; + public static final String USER_TYPE_RESOURCE = "user-resource"; + public static final String USER_TYPE_RESOURCE_UI_IMPORT = "user-resource-ui-import"; + + @Inject + public ResourceUploadServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + } + + public enum ResourceAuthorityTypeEnum { + NORMATIVE_TYPE_BE(NORMATIVE_TYPE_RESOURCE, true, false), USER_TYPE_BE(USER_TYPE_RESOURCE, true, + true), USER_TYPE_UI(USER_TYPE_RESOURCE_UI_IMPORT, false, + true), CSAR_TYPE_BE(CSAR_TYPE_RESOURCE, true, true); + + private String urlPath; + private boolean isBackEndImport, isUserTypeResource; + + public static ResourceAuthorityTypeEnum findByUrlPath(String urlPath) { + ResourceAuthorityTypeEnum found = null; + for (ResourceAuthorityTypeEnum curr : ResourceAuthorityTypeEnum.values()) { + if (curr.getUrlPath().equals(urlPath)) { + found = curr; + break; + } + } + return found; + } + + private ResourceAuthorityTypeEnum(String urlPath, boolean isBackEndImport, boolean isUserTypeResource) { + this.urlPath = urlPath; + this.isBackEndImport = isBackEndImport; + this.isUserTypeResource = isUserTypeResource; + } + + public String getUrlPath() { + return urlPath; + } + + public boolean isBackEndImport() { + return isBackEndImport; + } + + public boolean isUserTypeResource() { + return isUserTypeResource; + } + } + + @POST + @Path("/{resourceAuthority}") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource from yaml", method = "POST", summary = "Returns created resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource already exist")}) + public Response uploadMultipart( + @Parameter(description = "validValues: normative-resource / user-resource", + schema = @Schema(allowableValues = {NORMATIVE_TYPE_RESOURCE , + USER_TYPE_RESOURCE,USER_TYPE_RESOURCE_UI_IMPORT})) @PathParam( + value = "resourceAuthority") final String resourceAuthority, + @Parameter(description = "FileInputStream") @FormDataParam("resourceZip") File file, + @Parameter(description = "ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader, + @Parameter(description = "resourceMetadata") @FormDataParam("resourceMetadata") String resourceInfoJsonString, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + // updateResourse Query Parameter if false checks if already exist + @DefaultValue("true") @QueryParam("createNewVersion") boolean createNewVersion) { + + try { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + Wrapper uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper yamlStringWrapper = new Wrapper<>(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // When we get an errorResponse it will be filled into the + // responseWrapper + validateAuthorityType(responseWrapper, resourceAuthority); + + ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.findByUrlPath(resourceAuthority); + + commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, resourceInfoJsonString); + + fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), resourceInfoJsonString, resourceAuthorityEnum, file); + + // PayLoad Validations + if(!resourceAuthorityEnum.equals(ResourceAuthorityTypeEnum.CSAR_TYPE_BE)){ + commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); + + specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, resourceAuthorityEnum); + } + + if (responseWrapper.isEmpty()) { + handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, createNewVersion, null); + } + + return responseWrapper.getInnerElement(); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Upload Resource"); + log.debug("upload resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java index 415fdcf562..03bed4762f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java @@ -1,574 +1,572 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.servlets; - -import com.jcabi.aspects.Loggable; -import fj.data.Either; -import javax.inject.Inject; -import org.apache.http.HttpStatus; -import org.json.JSONException; -import org.json.JSONObject; -import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; -import org.openecomp.sdc.be.components.impl.CsarValidationUtils; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; -import org.openecomp.sdc.be.components.impl.ImportUtils; -import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceImportManager; -import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.Product; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.UploadResourceInfo; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum; -import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.exception.ResponseFormat; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.info.Info; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import javax.inject.Singleton; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.*; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog") -@OpenAPIDefinition(info = @Info(title = "Resources Catalog", description = "Resources Servlet")) -@Singleton -public class ResourcesServlet extends AbstractValidationsServlet { - - private static final Logger log = Logger.getLogger(ResourcesServlet.class); - private final ResourceBusinessLogic resourceBusinessLogic; - - @Inject - public ResourcesServlet(UserBusinessLogic userBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBL, - ResourceBusinessLogic resourceBusinessLogic, - ComponentsUtils componentsUtils, ServletUtils servletUtils, - ResourceImportManager resourceImportManager) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); - this.resourceBusinessLogic = resourceBusinessLogic; - } - - @POST - @Path("/resources") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", - responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "409", description = "Resource already exist")}) - public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); - init(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - - Response response; - try { - - Wrapper responseWrapper = new Wrapper<>(); - // UI Import - if (isUIImport(data)) { - performUIImport(responseWrapper, data, request, userId, null); - } - // UI Create - else { - - Either convertResponse = parseToResource(data, modifier); - if (convertResponse.isRight()) { - log.debug("failed to parse resource"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - - Resource resource = convertResponse.left().value(); - Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null); - Object representation = RepresentationUtils.toRepresentation(createdResource); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation); - responseWrapper.setInnerElement(response); - } - return responseWrapper.getInnerElement(); - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource"); - log.debug("create resource failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } - - private boolean isUIImport(String data) { - boolean isUIImport; - try { - JSONObject json = new JSONObject(data); - String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME); - isUIImport = payloadName != null && !payloadName.isEmpty(); - } catch (JSONException e) { - log.debug("failed to parse json sent from client, json:{}", data, e); - isUIImport = false; - } - return isUIImport; - } - - private void performUIImport(Wrapper responseWrapper, String data, final HttpServletRequest request, String userId, String resourceUniqueId) throws FileNotFoundException { - - Wrapper userWrapper = new Wrapper<>(); - Wrapper uploadResourceInfoWrapper = new Wrapper<>(); - Wrapper yamlStringWrapper = new Wrapper<>(); - - ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI; - - commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data); - - if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) { - fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum, null); - - // PayLoad Validations - commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); - } - specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, data, resourceAuthorityEnum); - - if (responseWrapper.isEmpty()) { - handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId); - } - } - - private Either parseToResource(String resourceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); - } - - private Either parseToLightResource(String resourceJson, User user) { - Either ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); - if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow) - ret.left().value().setRequirements(null); - ret.left().value().setCapabilities(null); - } - return ret; - } - - @DELETE - @Path("/resources/{resourceId}") - public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - - Response response; - - try { - String resourceIdLower = resourceId.toLowerCase(); - ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier); - - if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { - log.debug("failed to delete resource"); - response = buildErrorResponse(actionResponse); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - return response; - - } catch (JSONException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); - log.debug("delete resource failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @DELETE - @Path("/resources/{resourceName}/{version}") - public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - String userId = request.getHeader(Constants.USER_ID_HEADER); - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - - Response response; - ResponseFormat actionResponse = resourceBusinessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier); - - if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { - log.debug("failed to delete resource"); - response = buildErrorResponse(actionResponse); - return response; - } - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); - return response; - } - - @GET - @Path("/resources/{resourceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", - responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "404", description = "Resource not found")}) - public Response getResourceById(@PathParam("resourceId") final String resourceId, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - - Response response; - - try { - String resourceIdLower = resourceId.toLowerCase(); - log.trace("get resource with id {}", resourceId); - Either actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier); - - if (actionResponse.isRight()) { - log.debug("failed to get resource"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource"); - log.debug("get resource failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @GET - @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "Retrieve Resource by name and version", method = "GET", - summary = "Returns resource according to resourceId", responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "404", description = "Resource not found")}) - public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, - @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - ServletContext context = request.getSession().getServletContext(); - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - Response response; - try { - Either actionResponse = resourceBusinessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId); - if (actionResponse.isRight()) { - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version"); - log.debug("get resource failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } - } - - @GET - @Path("/resources/validate-name/{resourceName}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "validate resource name", method = "GET", - summary = "checks if the chosen resource name is available ", responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), - @ApiResponse(responseCode = "403", description = "Restricted operation")}) - public Response validateResourceName(@PathParam("resourceName") final String resourceName, - @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}" , userId); - Response response; - - if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) { - log.debug("invalid resource type received"); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - return response; - - } - ResourceTypeEnum typeEnum = null; - if (resourceType != null) { - typeEnum = ResourceTypeEnum.valueOf(resourceType); - } - Either, ResponseFormat> actionResponse = resourceBusinessLogic.validateResourceNameExists(resourceName, typeEnum, userId); - - if (actionResponse.isRight()) { - log.debug("failed to validate resource name"); - response = buildErrorResponse(actionResponse.right().value()); - return response; - } - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); - } - - @GET - @Path("/resources/certified/abstract") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}" , url); - try { - List resources = resourceBusinessLogic - .getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources)); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources"); - log.debug("getCertifiedAbstractResources failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - } - - @GET - @Path("/resources/certified/notabstract") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}" , url); - try { - List resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces)); - - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources"); - log.debug("getCertifiedNotAbstractResources failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - @PUT - @Path("/resources/{resourceId}/metadata") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata", - responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource metadata updated"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content")}) - public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId, - @Parameter(description = "Resource metadata to be updated", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}" , url); - - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Response response; - try { - String resourceIdLower = resourceId.toLowerCase(); - Either updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); - if (updateInfoResource.isRight()) { - log.debug("failed to parse resource metadata"); - response = buildErrorResponse(updateInfoResource.right().value()); - return response; - } - Resource updatedResource = resourceBusinessLogic.updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false); - Object resource = RepresentationUtils.toRepresentation(updatedResource); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata"); - log.debug("Update Resource Metadata failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @PUT - @Path("/resources/{resourceId}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", - responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource updated"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "409", description = "Resource already exist")}) - public Response updateResource( - @Parameter(description = "Resource object to be updated", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @PathParam(value = "resourceId") String resourceId) { - - userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); - init(); - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - // get modifier id - User modifier = new User(); - modifier.setUserId(userId); - log.debug("modifier id is {}", userId); - Response response; - try { - Wrapper responseWrapper = new Wrapper<>(); - // UI Import - if (isUIImport(data)) { - performUIImport(responseWrapper, data, request, userId, resourceId); - } else { - Either convertResponse = parseToLightResource(data, modifier); - if (convertResponse.isRight()) { - log.debug("failed to parse resource"); - response = buildErrorResponse(convertResponse.right().value()); - return response; - } - Resource updatedResource = resourceBusinessLogic.validateAndUpdateResourceFromCsar( - convertResponse.left().value(), modifier, null, null, resourceId); - Object representation = RepresentationUtils.toRepresentation(updatedResource); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); - responseWrapper.setInnerElement(response); - } - return responseWrapper.getInnerElement(); - } catch (IOException e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource"); - log.debug("update resource failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - - } - } - - @GET - @Path("/resources/csar/{csaruuid}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid", - responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource retrieced"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) - public Response getResourceFromCsar(@Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @PathParam(value = "csaruuid") String csarUUID) { - - init(); - - String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("Start handle request of {}", url); - - // retrieve user details - userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); - User user = new User(); - user.setUserId(userId); - - log.debug("user id is {}", userId); - - Response response; - - try { - - Either eitherResource = - resourceBusinessLogic.getLatestResourceFromCsarUuid(csarUUID, user); - - // validate response - if (eitherResource.isRight()) { - log.debug("failed to get resource from csarUuid : {}", csarUUID); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), - eitherResource.right().value()); - } else { - Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value()); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); - } - - return response; - - } catch (IOException e) { - log.debug("get resource by csar failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; - } - } -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.servlets; + +import com.jcabi.aspects.Loggable; +import fj.data.Either; +import javax.inject.Inject; +import org.apache.http.HttpStatus; +import org.json.JSONException; +import org.json.JSONObject; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.CsarValidationUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@OpenAPIDefinition(info = @Info(title = "Resources Catalog", description = "Resources Servlet")) +@Singleton +public class ResourcesServlet extends AbstractValidationsServlet { + + private static final Logger log = Logger.getLogger(ResourcesServlet.class); + private final ResourceBusinessLogic resourceBusinessLogic; + + @Inject + public ResourcesServlet(UserBusinessLogic userBusinessLogic, + ComponentInstanceBusinessLogic componentInstanceBL, + ResourceBusinessLogic resourceBusinessLogic, + ComponentsUtils componentsUtils, ServletUtils servletUtils, + ResourceImportManager resourceImportManager) { + super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + this.resourceBusinessLogic = resourceBusinessLogic; + } + + @POST + @Path("/resources") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource already exist")}) + public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + init(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response; + try { + + Wrapper responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, null); + } + // UI Create + else { + + Either convertResponse = parseToResource(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse resource"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + + Resource resource = convertResponse.left().value(); + Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null); + Object representation = RepresentationUtils.toRepresentation(createdResource); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation); + responseWrapper.setInnerElement(response); + } + return responseWrapper.getInnerElement(); + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource"); + log.debug("create resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + private boolean isUIImport(String data) { + boolean isUIImport; + try { + JSONObject json = new JSONObject(data); + String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME); + isUIImport = payloadName != null && !payloadName.isEmpty(); + } catch (JSONException e) { + log.debug("failed to parse json sent from client, json:{}", data, e); + isUIImport = false; + } + return isUIImport; + } + + private void performUIImport(Wrapper responseWrapper, String data, final HttpServletRequest request, String userId, String resourceUniqueId) throws FileNotFoundException { + + Wrapper userWrapper = new Wrapper<>(); + Wrapper uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper yamlStringWrapper = new Wrapper<>(); + + ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI; + + commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data); + + if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) { + fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum, null); + + // PayLoad Validations + commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); + } + specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, data, resourceAuthorityEnum); + + if (responseWrapper.isEmpty()) { + handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId); + } + } + + private Either parseToResource(String resourceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); + } + + private Either parseToLightResource(String resourceJson, User user) { + Either ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); + if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow) + ret.left().value().setRequirements(null); + ret.left().value().setCapabilities(null); + } + return ret; + } + + @DELETE + @Path("/resources/{resourceId}") + public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + + Response response; + + try { + String resourceIdLower = resourceId.toLowerCase(); + ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete resource"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (JSONException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); + log.debug("delete resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @DELETE + @Path("/resources/{resourceName}/{version}") + public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + + Response response; + ResponseFormat actionResponse = resourceBusinessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete resource"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + } + + @GET + @Path("/resources/{resourceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response getResourceById(@PathParam("resourceId") final String resourceId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + + Response response; + + try { + String resourceIdLower = resourceId.toLowerCase(); + log.trace("get resource with id {}", resourceId); + Either actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get resource"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource"); + log.debug("get resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Retrieve Resource by name and version", method = "GET", + summary = "Returns resource according to resourceId", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Resource not found")}) + public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, + @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + Response response; + try { + Either actionResponse = resourceBusinessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId); + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version"); + log.debug("get resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/resources/validate-name/{resourceName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "validate resource name", method = "GET", + summary = "checks if the chosen resource name is available ", responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource found"), + @ApiResponse(responseCode = "403", description = "Restricted operation")}) + public Response validateResourceName(@PathParam("resourceName") final String resourceName, + @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}" , userId); + Response response; + + if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) { + log.debug("invalid resource type received"); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + return response; + + } + ResourceTypeEnum typeEnum = null; + if (resourceType != null) { + typeEnum = ResourceTypeEnum.valueOf(resourceType); + } + Either, ResponseFormat> actionResponse = resourceBusinessLogic.validateResourceNameExists(resourceName, typeEnum, userId); + + if (actionResponse.isRight()) { + log.debug("failed to validate resource name"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } + + @GET + @Path("/resources/certified/abstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}" , url); + try { + List resources = resourceBusinessLogic + .getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources)); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources"); + log.debug("getCertifiedAbstractResources failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/resources/certified/notabstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}" , url); + try { + List resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces)); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources"); + log.debug("getCertifiedNotAbstractResources failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @PUT + @Path("/resources/{resourceId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource metadata updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content")}) + public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId, + @Parameter(description = "Resource metadata to be updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}" , url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response; + try { + String resourceIdLower = resourceId.toLowerCase(); + Either updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); + if (updateInfoResource.isRight()) { + log.debug("failed to parse resource metadata"); + response = buildErrorResponse(updateInfoResource.right().value()); + return response; + } + Resource updatedResource = resourceBusinessLogic.updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false); + Object resource = RepresentationUtils.toRepresentation(updatedResource); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata"); + log.debug("Update Resource Metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Path("/resources/{resourceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Resource updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Resource already exist")}) + public Response updateResource( + @Parameter(description = "Resource object to be updated", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @PathParam(value = "resourceId") String resourceId) { + + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + init(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response; + try { + Wrapper responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, resourceId); + } else { + Either convertResponse = parseToLightResource(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse resource"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + Resource updatedResource = resourceBusinessLogic.validateAndUpdateResourceFromCsar( + convertResponse.left().value(), modifier, null, null, resourceId); + Object representation = RepresentationUtils.toRepresentation(updatedResource); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); + responseWrapper.setInnerElement(response); + } + return responseWrapper.getInnerElement(); + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource"); + log.debug("update resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/resources/csar/{csaruuid}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid", + responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Resource retrieced"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + public Response getResourceFromCsar(@Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @PathParam(value = "csaruuid") String csarUUID) { + + init(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // retrieve user details + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + User user = new User(); + user.setUserId(userId); + + log.debug("user id is {}", userId); + + Response response; + + try { + + Either eitherResource = + resourceBusinessLogic.getLatestResourceFromCsarUuid(csarUUID, user); + + // validate response + if (eitherResource.isRight()) { + log.debug("failed to get resource from csarUuid : {}", csarUUID); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + eitherResource.right().value()); + } else { + Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); + } + + return response; + + } catch (IOException e) { + log.debug("get resource by csar failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java index 5847a06e2b..5a148ef39e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadEndpoint.java @@ -1,136 +1,143 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.servlets; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import javax.ws.rs.Consumes; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.openecomp.sdc.be.components.impl.CommonImportManager; -import org.openecomp.sdc.be.components.validation.AccessValidations; -import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; -import org.openecomp.sdc.be.model.AnnotationTypeDefinition; -import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations; -import org.openecomp.sdc.be.utils.TypeUtils; -import org.openecomp.sdc.common.datastructure.Wrapper; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; -import com.google.common.annotations.VisibleForTesting; -import com.jcabi.aspects.Loggable; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.info.Info; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -/** - * Here new APIs for types upload written in an attempt to gradually servlet responseCode - */ -@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/uploadType") -@Consumes(MediaType.MULTIPART_FORM_DATA) -@Produces(MediaType.APPLICATION_JSON) -@OpenAPIDefinition(info = @Info(title = "Catalog Types Upload")) -@Controller -public class TypesUploadEndpoint { - - private final CommonImportManager commonImportManager; - private final AnnotationTypeOperations annotationTypeOperations; - private final AccessValidations accessValidations; - - public TypesUploadEndpoint(CommonImportManager commonImportManager, AnnotationTypeOperations annotationTypeOperations, AccessValidations accessValidations) { - this.commonImportManager = commonImportManager; - this.annotationTypeOperations = annotationTypeOperations; - this.accessValidations = accessValidations; - } - - @POST - @Path("/annotationtypes") - @Operation(description = "Create AnnotationTypes from yaml", method = "POST", - summary = "Returns created annotation types",responses = @ApiResponse( - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) - @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "annotation types created"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "409", description = "annotation types already exist")}) - - public Response uploadAnnotationTypes(@Parameter(description = "FileInputStream") @FormDataParam("annotationTypesZip") File file, - @HeaderParam("USER_ID") String userId) throws IOException { - accessValidations.validateUserExists(userId, "Annotation Types Creation"); - Wrapper yamlStringWrapper = new Wrapper<>(); - AbstractValidationsServlet.extractZipContents(yamlStringWrapper, file); - List> typesResults = - commonImportManager.createElementTypes(yamlStringWrapper.getInnerElement(), - TypesUploadEndpoint::buildAnnotationFromFieldMap, annotationTypeOperations); - HttpStatus status = getHttpStatus(typesResults); - return Response.status(status.value()).entity(typesResults).build(); - } - - @VisibleForTesting - static HttpStatus getHttpStatus(List> typesResults) { - boolean typeActionFailed = false; - boolean typeExists = false; - boolean typeActionSucceeded = false; - for (ImmutablePair typeResult : typesResults) { - Boolean result = typeResult.getRight(); - if (result==null) { - typeExists = true; - } else if (result) { - typeActionSucceeded = true; - } else { - typeActionFailed = true; - } - } - HttpStatus status = HttpStatus.OK; - if (typeActionFailed) { - status = HttpStatus.BAD_REQUEST; - } else if (typeActionSucceeded) { - status = HttpStatus.CREATED; - } else if (typeExists) { - status = HttpStatus.CONFLICT; - } - return status; - } - - private static T buildAnnotationFromFieldMap(String typeName, Map toscaJson) { - AnnotationTypeDefinition annotationType = new AnnotationTypeDefinition(); - annotationType.setVersion(TypeUtils.getFirstCertifiedVersionVersion()); - annotationType.setHighestVersion(true); - annotationType.setType(typeName); - TypeUtils.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, annotationType::setDescription); - CommonImportManager.setProperties(toscaJson, annotationType::setProperties); - return (T) annotationType; - } - - -} +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.servlets; + +import java.io.File; +import java.util.List; +import java.util.Map; +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.openecomp.sdc.be.components.impl.CommonImportManager; +import org.openecomp.sdc.be.components.validation.AccessValidations; +import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; +import org.openecomp.sdc.be.model.AnnotationTypeDefinition; +import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations; +import org.openecomp.sdc.be.utils.TypeUtils; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.zip.exception.ZipException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import com.google.common.annotations.VisibleForTesting; +import com.jcabi.aspects.Loggable; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +/** + * Here new APIs for types upload written in an attempt to gradually servlet responseCode + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/uploadType") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@OpenAPIDefinition(info = @Info(title = "Catalog Types Upload")) +@Controller +public class TypesUploadEndpoint { + private static final Logger LOGGER = LoggerFactory.getLogger(TypesUploadEndpoint.class); + + private final CommonImportManager commonImportManager; + private final AnnotationTypeOperations annotationTypeOperations; + private final AccessValidations accessValidations; + + public TypesUploadEndpoint(CommonImportManager commonImportManager, AnnotationTypeOperations annotationTypeOperations, AccessValidations accessValidations) { + this.commonImportManager = commonImportManager; + this.annotationTypeOperations = annotationTypeOperations; + this.accessValidations = accessValidations; + } + + @POST + @Path("/annotationtypes") + @Operation(description = "Create AnnotationTypes from yaml", method = "POST", + summary = "Returns created annotation types",responses = @ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class))))) + @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "annotation types created"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "annotation types already exist")}) + + public Response uploadAnnotationTypes(@Parameter(description = "FileInputStream") @FormDataParam("annotationTypesZip") File file, + @HeaderParam("USER_ID") String userId) { + accessValidations.validateUserExists(userId, "Annotation Types Creation"); + final Wrapper yamlStringWrapper = new Wrapper<>(); + try { + AbstractValidationsServlet.extractZipContents(yamlStringWrapper, file); + } catch (final ZipException e) { + LOGGER.error("Could not extract zip contents", e); + } + List> typesResults = + commonImportManager.createElementTypes(yamlStringWrapper.getInnerElement(), + TypesUploadEndpoint::buildAnnotationFromFieldMap, annotationTypeOperations); + HttpStatus status = getHttpStatus(typesResults); + return Response.status(status.value()).entity(typesResults).build(); + } + + @VisibleForTesting + static HttpStatus getHttpStatus(List> typesResults) { + boolean typeActionFailed = false; + boolean typeExists = false; + boolean typeActionSucceeded = false; + for (ImmutablePair typeResult : typesResults) { + Boolean result = typeResult.getRight(); + if (result==null) { + typeExists = true; + } else if (result) { + typeActionSucceeded = true; + } else { + typeActionFailed = true; + } + } + HttpStatus status = HttpStatus.OK; + if (typeActionFailed) { + status = HttpStatus.BAD_REQUEST; + } else if (typeActionSucceeded) { + status = HttpStatus.CREATED; + } else if (typeExists) { + status = HttpStatus.CONFLICT; + } + return status; + } + + private static T buildAnnotationFromFieldMap(String typeName, Map toscaJson) { + AnnotationTypeDefinition annotationType = new AnnotationTypeDefinition(); + annotationType.setVersion(TypeUtils.getFirstCertifiedVersionVersion()); + annotationType.setHighestVersion(true); + annotationType.setType(typeName); + TypeUtils.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, annotationType::setDescription); + CommonImportManager.setProperties(toscaJson, annotationType::setProperties); + return (T) annotationType; + } + + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java index 2f1357ea13..836565c1fe 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java @@ -55,6 +55,7 @@ import org.openecomp.sdc.common.impl.ExternalConfiguration; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.GeneralUtility; import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.common.zip.ZipUtils; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.beans.factory.annotation.Autowired; @@ -339,23 +340,20 @@ public class CsarUtils { isInCertificationRequest); } - private Either addSchemaFilesFromCassandra(ZipOutputStream zip, - byte[] schemaFileZip) { - + private Either addSchemaFilesFromCassandra(final ZipOutputStream zip, + final byte[] schemaFileZip) { final int initSize = 2048; - log.debug("Starting copy from Schema file zip to CSAR zip"); - - try (ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - BufferedOutputStream bos = new BufferedOutputStream(out, initSize)) { + try (final ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip)); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final BufferedOutputStream bos = new BufferedOutputStream(out, initSize)) { ZipEntry entry; while ((entry = zipStream.getNextEntry()) != null) { - - String entryName = entry.getName(); + ZipUtils.checkForZipSlipInRead(entry); + final String entryName = entry.getName(); int readSize = initSize; - byte[] entryData = new byte[initSize]; + final byte[] entryData = new byte[initSize]; while ((readSize = zipStream.read(entryData, 0, readSize)) != -1) { bos.write(entryData, 0, readSize); @@ -368,13 +366,12 @@ public class CsarUtils { zip.flush(); out.reset(); } - } catch (IOException | NullPointerException e) { - log.error("Error while writing the SDC schema file to the CSAR {}", e); + } catch (final Exception e) { + log.error("Error while writing the SDC schema file to the CSAR", e); return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); } log.debug("Finished coppy from Schema file zip to CSAR zip"); - return Either.left(zip); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java b/catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java deleted file mode 100644 index 87e351be8a..0000000000 --- a/catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java +++ /dev/null @@ -1,143 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Modifications Copyright (c) 2019 Samsung - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.output.ByteArrayOutputStream; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -public class ZipUtil { - - public static void main(String[] args) { - - String zipFileName = "/src/test/resources/config/config.zip"; - - zipFileName = "C:\\Git_work\\D2-SDnC\\catalog-be\\src\\test\\resources\\config\\config.zip"; - zipFileName = "src/test/resources/config/config.zip"; - - Path path = Paths.get(zipFileName); - - try { - byte[] zipAsBytes = Files.readAllBytes(path); - // encode to base - - byte[] decodedMd5 = Base64.encodeBase64(zipAsBytes); - String decodedStr = new String(decodedMd5); - - zipAsBytes = Base64.decodeBase64(decodedStr.getBytes()); - - // String str = new String(zipAsBytes); - - // readZip(str.getBytes()); - readZip(zipAsBytes); - - } catch (IOException e) { - e.printStackTrace(); - } - - } - - private static Map readZip(byte[] zipAsBytes) { - - Map fileNameToByteArray = new HashMap<>(); - - byte[] buffer = new byte[1024]; - ZipInputStream zis = null; - try { - - zis = new ZipInputStream(new ByteArrayInputStream(zipAsBytes)); - // get the zipped file list entry - ZipEntry ze = zis.getNextEntry(); - - while (ze != null) { - - String fileName = ze.getName(); - - if (!ze.isDirectory()) { - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - try { - int len; - while ((len = zis.read(buffer)) > 0) { - os.write(buffer, 0, len); - } - - // aClass.outputStreamMethod(os); - String aString = new String(os.toByteArray(), "UTF-8"); - - fileNameToByteArray.put(fileName, os.toByteArray()); - - } finally { - if (os != null) { - os.close(); - } - } - } - ze = zis.getNextEntry(); - - } - - zis.closeEntry(); - zis.close(); - - } catch (IOException ex) { - ex.printStackTrace(); - return null; - } finally { - if (zis != null) { - try { - zis.closeEntry(); - zis.close(); - } catch (IOException e) { - // TODO: add log - } - - } - } - - return fileNameToByteArray; - - } - - private static byte[] loadResource(String resourceDir) throws IOException, URISyntaxException { - - Path path = Paths.get(ZipUtil.class.getResource(resourceDir).toURI()); - return Files.readAllBytes(path); - } - - public static Map readData(String resourceDir) throws IOException, URISyntaxException { - - byte[] data = loadResource(resourceDir); - return readZip(data); - } -} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java index 2f7f5aab17..9bad9f4fa8 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogicTest.java @@ -50,11 +50,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; import org.openecomp.sdc.be.components.impl.BaseBusinessLogicMock; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; @@ -66,7 +62,8 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.CsarOperation; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; -import org.openecomp.sdc.common.util.ZipUtil; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.exception.ResponseFormat; public class CsarBusinessLogicTest extends BaseBusinessLogicMock { @@ -125,7 +122,7 @@ public class CsarBusinessLogicTest extends BaseBusinessLogicMock { } @Test() - public void testGetCsarInfoWithPayload() throws IOException, URISyntaxException { + public void testGetCsarInfoWithPayload() throws IOException, URISyntaxException, ZipException { // given Resource resource = new Resource(); resource.setName(RESOURCE_NAME); @@ -185,11 +182,11 @@ public class CsarBusinessLogicTest extends BaseBusinessLogicMock { test.validateCsarBeforeCreate(resource, AuditingActionEnum.ARTIFACT_DOWNLOAD, user, "csarUUID"); } - public Map loadPayload(String payloadName) throws IOException, URISyntaxException { + public Map loadPayload(String payloadName) throws IOException, URISyntaxException, ZipException { Path path = Paths.get(getClass().getResource("/" + payloadName).toURI()); byte[] data = Files.readAllBytes(path); - return ZipUtil.readZip(data); + return ZipUtils.readZip(data, false); } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java index 3ae65c818a..69f9f5704d 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java @@ -25,7 +25,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.IOException; +import java.io.File; import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; @@ -41,7 +41,8 @@ import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentEx import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.model.NodeTypeInfo; import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.ZipUtil; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; @RunWith(MockitoJUnitRunner.class) public class CsarInfoTest { @@ -52,19 +53,18 @@ public class CsarInfoTest { private User user; private static final String CSAR_UUID = "csarUUID"; - private static final String PAYLOAD_NAME = "/mock_service.csar"; + private static final String PAYLOAD_NAME = "mock_service.csar"; private static final String RESOURCE_NAME = "resourceName"; private static final String MAIN_TEMPLATE_NAME = "Definitions/tosca_mock_vf.yaml"; - private static final String NEW_NODE_NAME = "new_db"; private static final String NODE_TYPE = "tosca.nodes.Compute"; private static final String DELIVER_FOR = "tosca.nodes.Root"; @Before - public void setup() throws IOException, URISyntaxException { - + public void setup() throws ZipException, URISyntaxException { // given - Map payload = ZipUtil.readData(PAYLOAD_NAME); + final File csarFile = new File(CsarInfoTest.class.getClassLoader().getResource(PAYLOAD_NAME).toURI()); + final Map payload = ZipUtils.readZip(csarFile, false); String mainTemplateContent = new String(payload.get(MAIN_TEMPLATE_NAME)); csarInfo = new CsarInfo(user, CSAR_UUID, payload, RESOURCE_NAME, diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java index 19d1a17e84..8ae02c4f1b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java @@ -27,11 +27,14 @@ import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import java.io.IOException; +import java.io.File; import java.net.URISyntaxException; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; - import org.assertj.core.util.Lists; import org.junit.Assert; import org.junit.Before; @@ -41,8 +44,6 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - -import org.openecomp.sdc.ZipUtil; import org.openecomp.sdc.be.components.csar.CsarInfo; import org.openecomp.sdc.be.components.csar.YamlTemplateParsingHandler; import org.openecomp.sdc.be.components.impl.AnnotationBusinessLogic; @@ -50,8 +51,15 @@ import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic; import org.openecomp.sdc.be.components.validation.AnnotationValidator; import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.ParsedToscaYamlInfo; +import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import java.io.File; import java.io.IOException; @@ -88,10 +96,8 @@ public class YamlTemplateParsingHandlerTest { private final static GroupTypeDefinition rootGroupType = buildRootGroupType(); private final static String CAPABILITY_TYPE = "org.openecomp.capabilities.VLANAssignment"; private final static String CAPABILITY_NAME = "vlan_assignment"; - private static final String CSAR_FILE_PATH = "/csars/with_groups.csar"; - + private static final String CSAR_FILE_PATH = "csars/with_groups.csar"; private static final String FILE_NAME = "MainServiceTemplate.yaml"; - private static final String CSAR_UUID = "csarUUID"; private static final String RESOURCE_NAME = "resourceName"; private static final String MAIN_TEMPLATE_NAME = "Definitions/MainServiceTemplate.yaml"; @@ -103,8 +109,10 @@ public class YamlTemplateParsingHandlerTest { YamlTemplateParsingHandler testSubject; @BeforeClass() - public static void prepareData() throws IOException, URISyntaxException { - csar = ZipUtil.readData(CSAR_FILE_PATH); + public static void prepareData() throws URISyntaxException, ZipException { + final File csarFile = new File( + YamlTemplateParsingHandlerTest.class.getClassLoader().getResource(CSAR_FILE_PATH).toURI()); + csar = ZipUtils.readZip(csarFile, false); Optional keyOp = csar.keySet().stream().filter(k -> k.endsWith(FILE_NAME)).findAny(); byte[] mainTemplateService = keyOp.map(csar::get).orElse(null); -- cgit 1.2.3-korg