diff options
Diffstat (limited to 'catalog-be/src/main/java/org/openecomp')
5 files changed, 976 insertions, 931 deletions
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<Response> responseWrapper, File file, String payloadName) { - Map<String, byte[]> 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<Response> 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<String, byte[]> 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<Response> responseWrapper, File file, String payloadName) { - Map<String, byte[]> 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<Response> 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<String, byte[]> 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<String> yamlStringWrapper, File file) { + protected void fillZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException { extractZipContents(yamlStringWrapper, file); } - public static void extractZipContents(Wrapper<String> yamlStringWrapper, File file) { - Map<String, byte[]> unzippedFolder = ZipUtil.readZip(file); + public static void extractZipContents(Wrapper<String> yamlStringWrapper, File file) throws ZipException { + final Map<String, byte[]> unzippedFolder = ZipUtils.readZip(file, false); String ymlName = unzippedFolder.keySet().iterator().next(); fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file); } private static void fillToscaTemplateFromZip(Wrapper<String> yamlStringWrapper, String payloadName, File file) { - Map<String, byte[]> unzippedFolder = ZipUtil.readZip(file); + Map<String, byte[]> 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<String, byte[]> csar = ZipUtil.readZip(decodedPayload); - if (csar == null) { - log.info("Failed to unzip received csar", csarUUID); + Map<String, byte[]> 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<Response> responseWrapper = new Wrapper<>();
- Wrapper<User> userWrapper = new Wrapper<>();
- Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
- Wrapper<String> 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<Response> responseWrapper = new Wrapper<>(); + Wrapper<User> userWrapper = new Wrapper<>(); + Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper<String> 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<Response> responseWrapper = new Wrapper<>();
- // UI Import
- if (isUIImport(data)) {
- performUIImport(responseWrapper, data, request, userId, null);
- }
- // UI Create
- else {
-
- Either<Resource, ResponseFormat> 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<Response> responseWrapper, String data, final HttpServletRequest request, String userId, String resourceUniqueId) throws FileNotFoundException {
-
- Wrapper<User> userWrapper = new Wrapper<>();
- Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
- Wrapper<String> 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<Resource, ResponseFormat> parseToResource(String resourceJson, User user) {
- return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
- }
-
- private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) {
- Either<Resource, ResponseFormat> 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<Resource, ResponseFormat> 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<Resource, ResponseFormat> 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<Map<String, Boolean>, 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<Resource> 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<Resource> 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<Resource, ResponseFormat> 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<Response> responseWrapper = new Wrapper<>();
- // UI Import
- if (isUIImport(data)) {
- performUIImport(responseWrapper, data, request, userId, resourceId);
- } else {
- Either<Resource, ResponseFormat> 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<Resource, ResponseFormat> 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<Response> responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, null); + } + // UI Create + else { + + Either<Resource, ResponseFormat> 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<Response> responseWrapper, String data, final HttpServletRequest request, String userId, String resourceUniqueId) throws FileNotFoundException { + + Wrapper<User> userWrapper = new Wrapper<>(); + Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper<String> 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<Resource, ResponseFormat> parseToResource(String resourceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); + } + + private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) { + Either<Resource, ResponseFormat> 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<Resource, ResponseFormat> 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<Resource, ResponseFormat> 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<Map<String, Boolean>, 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<Resource> 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<Resource> 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<Resource, ResponseFormat> 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<Response> responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, resourceId); + } else { + Either<Resource, ResponseFormat> 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<Resource, ResponseFormat> 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<String> yamlStringWrapper = new Wrapper<>();
- AbstractValidationsServlet.extractZipContents(yamlStringWrapper, file);
- List<ImmutablePair<AnnotationTypeDefinition, Boolean>> typesResults =
- commonImportManager.createElementTypes(yamlStringWrapper.getInnerElement(),
- TypesUploadEndpoint::buildAnnotationFromFieldMap, annotationTypeOperations);
- HttpStatus status = getHttpStatus(typesResults);
- return Response.status(status.value()).entity(typesResults).build();
- }
-
- @VisibleForTesting
- static <T extends ToscaDataDefinition> HttpStatus getHttpStatus(List<ImmutablePair<T, Boolean>> typesResults) {
- boolean typeActionFailed = false;
- boolean typeExists = false;
- boolean typeActionSucceeded = false;
- for (ImmutablePair<T, Boolean> 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 extends ToscaDataDefinition> T buildAnnotationFromFieldMap(String typeName, Map<String, Object> 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<String> yamlStringWrapper = new Wrapper<>(); + try { + AbstractValidationsServlet.extractZipContents(yamlStringWrapper, file); + } catch (final ZipException e) { + LOGGER.error("Could not extract zip contents", e); + } + List<ImmutablePair<AnnotationTypeDefinition, Boolean>> typesResults = + commonImportManager.createElementTypes(yamlStringWrapper.getInnerElement(), + TypesUploadEndpoint::buildAnnotationFromFieldMap, annotationTypeOperations); + HttpStatus status = getHttpStatus(typesResults); + return Response.status(status.value()).entity(typesResults).build(); + } + + @VisibleForTesting + static <T extends ToscaDataDefinition> HttpStatus getHttpStatus(List<ImmutablePair<T, Boolean>> typesResults) { + boolean typeActionFailed = false; + boolean typeExists = false; + boolean typeActionSucceeded = false; + for (ImmutablePair<T, Boolean> 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 extends ToscaDataDefinition> T buildAnnotationFromFieldMap(String typeName, Map<String, Object> 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<ZipOutputStream, ResponseFormat> addSchemaFilesFromCassandra(ZipOutputStream zip, - byte[] schemaFileZip) { - + private Either<ZipOutputStream, ResponseFormat> 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); } |