X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fservlets%2FServiceServlet.java;h=daf4bcbcd03e6440a9459d93051fc521b2c6d715;hb=c469756a1092194adedd590d35f0f1f8feac3a36;hp=1affe7592cc362b595f2a80e2a00c34e078670f9;hpb=b1fc8c337d3b9750eff6e62b626c0bc3a1467a88;p=sdc.git diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java index 1affe7592c..daf4bcbcd0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java @@ -19,6 +19,8 @@ */ package org.openecomp.sdc.be.servlets; +import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.reflect.TypeToken; @@ -31,19 +33,20 @@ 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.servers.Server; -import io.swagger.v3.oas.annotations.servers.Servers; import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import javax.inject.Inject; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; +import javax.validation.constraints.NotNull; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -53,17 +56,20 @@ import javax.ws.rs.PUT; 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.apache.http.HttpStatus; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; +import org.keycloak.representations.AccessToken; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceImportBusinessLogic; import org.openecomp.sdc.be.components.impl.aaf.AafPermission; import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; @@ -92,14 +98,14 @@ import org.openecomp.sdc.common.log.elements.LoggerSupportability; import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions; import org.openecomp.sdc.common.log.enums.StatusCode; import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.common.util.Multitenancy; import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.stereotype.Controller; @Loggable(prepend = true, value = Loggable.DEBUG, trim = false) @Path("/v1/catalog") -@Tags({@Tag(name = "SDC Internal APIs")}) -@Servers({@Server(url = "/sdc2/rest")}) +@Server(url = "/sdc2/rest") @Controller public class ServiceServlet extends AbstractValidationsServlet { @@ -109,32 +115,35 @@ public class ServiceServlet extends AbstractValidationsServlet { private static final String MODIFIER_ID_IS = "modifier id is {}"; private final ElementBusinessLogic elementBusinessLogic; private final ServiceBusinessLogic serviceBusinessLogic; + private final UserBusinessLogic userBusinessLogic; @Inject - public ServiceServlet(UserBusinessLogic userBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, + public ServiceServlet(ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager, ServiceBusinessLogic serviceBusinessLogic, - ResourceBusinessLogic resourceBusinessLogic, ElementBusinessLogic elementBusinessLogic) { - super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); + ResourceBusinessLogic resourceBusinessLogic, ElementBusinessLogic elementBusinessLogic, UserBusinessLogic userBusinessLogic) { + super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); this.serviceBusinessLogic = serviceBusinessLogic; this.elementBusinessLogic = elementBusinessLogic; + this.userBusinessLogic = userBusinessLogic; } @POST @Path("/services") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Create Service", method = "POST", summary = "Returns created service", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), - @ApiResponse(responseCode = "201", description = "Service created"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "409", description = "Service already exist")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "201", description = "Service created"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Service already exist"), + @ApiResponse(responseCode = "401", description = "Unauthorized Tenant")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response createService(@Parameter(description = "Service object to be created", 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); - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); loggerSupportability.log(LoggerSupportabilityActions.CREATE_SERVICE, StatusCode.STARTED, "Starting to create a service by user {} ", userId); validateNotEmptyBody(data); @@ -142,37 +151,55 @@ public class ServiceServlet extends AbstractValidationsServlet { if (convertResponse.isRight()) { throw new ByResponseFormatComponentException(convertResponse.right().value()); } + Multitenancy keyaccess = new Multitenancy(); Service service = convertResponse.left().value(); - Either actionResponse = serviceBusinessLogic.createService(service, modifier); - if (actionResponse.isRight()) { - log.debug("Failed to create service"); - throw new ByResponseFormatComponentException(actionResponse.right().value()); + if (keyaccess.multiTenancyCheck()) { + AccessToken.Access realmAccess = keyaccess.getAccessToken(request).getRealmAccess(); + Set realmroles = realmAccess.getRoles(); + boolean match = realmroles.contains(service.getTenant()); + if (match) { + Either actionResponse = serviceBusinessLogic.createService(service, modifier); + if (actionResponse.isRight()) { + log.debug("Failed to create service"); + throw new ByResponseFormatComponentException(actionResponse.right().value()); + } + loggerSupportability.log(LoggerSupportabilityActions.CREATE_SERVICE, service.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, + "Service {} has been created by user {} ", service.getName(), userId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); + } else { + log.debug("Unauthorized Tenant"); + return Response.status(401, "Unauthorized Tenant").build(); + } + } else { + Either actionResponse = serviceBusinessLogic.createService(service, modifier); + if (actionResponse.isRight()) { + log.debug("Failed to create service"); + throw new ByResponseFormatComponentException(actionResponse.right().value()); + } + loggerSupportability.log(LoggerSupportabilityActions.CREATE_SERVICE, service.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, + "Service {} has been created by user {} ", service.getName(), userId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); } - loggerSupportability.log(LoggerSupportabilityActions.CREATE_SERVICE, service.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, - "Service {} has been created by user {} ", service.getName(), userId); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); } public Either parseToService(String serviceJson, User user) { return getComponentsUtils() - .convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + .convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE); } @GET @Path("/services/validate-name/{serviceName}") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "validate service name", method = "GET", summary = "checks if the chosen service name is available ", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), - @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), + @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response validateServiceName(@PathParam("serviceName") final String serviceName, @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); try { Either, ResponseFormat> actionResponse = serviceBusinessLogic.validateServiceNameExists(serviceName, userId); @@ -190,11 +217,12 @@ public class ServiceServlet extends AbstractValidationsServlet { @GET @Path("/audit-records/{componentType}/{componentUniqueId}") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "get component audit records", method = "GET", summary = "get audit records for a service or a resource", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), - @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), + @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response getComponentAuditRecords(@PathParam("componentType") final String componentType, @PathParam("componentUniqueId") final String componentUniqueId, @@ -204,8 +232,6 @@ public class ServiceServlet extends AbstractValidationsServlet { ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - User modifier = new User(); - modifier.setUserId(userId); log.debug(MODIFIER_ID_IS, userId); Wrapper responseWrapper = new Wrapper<>(); Wrapper uuidWrapper = new Wrapper<>(); @@ -215,11 +241,11 @@ public class ServiceServlet extends AbstractValidationsServlet { validateUserExist(responseWrapper, userWrapper, userId); if (responseWrapper.isEmpty()) { fillUUIDAndVersion(responseWrapper, uuidWrapper, versionWrapper, userWrapper.getInnerElement(), validateComponentType(componentType), - componentUniqueId, context); + componentUniqueId, context); } if (responseWrapper.isEmpty()) { Either>, ResponseFormat> eitherServiceAudit = serviceBusinessLogic - .getComponentAuditRecords(versionWrapper.getInnerElement(), uuidWrapper.getInnerElement(), userId); + .getComponentAuditRecords(versionWrapper.getInnerElement(), uuidWrapper.getInnerElement(), userId); if (eitherServiceAudit.isRight()) { Response errorResponse = buildErrorResponse(eitherServiceAudit.right().value()); responseWrapper.setInnerElement(errorResponse); @@ -260,34 +286,45 @@ public class ServiceServlet extends AbstractValidationsServlet { @DELETE @Path("/services/{serviceId}") + @Tag(name = "SDCE-2 APIs") @Operation(description = "Delete Service", method = "DELETE", summary = "Return no content", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), - @ApiResponse(responseCode = "204", description = "Service deleted"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "404", description = "Service not found")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "204", description = "Service deleted"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Service not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) - public Response deleteService(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request) { + public Response deleteService(@PathParam("serviceId") final String serviceId, + @Parameter(description = "Optional parameter to determine the delete action: " + + "DELETE, which will permanently delete theService from the system or " + + "MARK_AS_DELETE, which will logically mark the service as deleted. Default action is to MARK_AS_DELETE") + @QueryParam("deleteAction") final Action deleteAction, + @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); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); try { String serviceIdLower = serviceId.toLowerCase(); loggerSupportability - .log(LoggerSupportabilityActions.DELETE_SERVICE, StatusCode.STARTED, "Starting to delete service {} by user {} ", serviceIdLower, - userId); + .log(LoggerSupportabilityActions.DELETE_SERVICE, StatusCode.STARTED, "Starting to delete service {} by user {} ", serviceIdLower, + userId); ServiceBusinessLogic businessLogic = getServiceBL(context); - ResponseFormat actionResponse = businessLogic.deleteService(serviceIdLower, modifier); + ResponseFormat actionResponse; + if (Action.DELETE.equals(deleteAction)) { + businessLogic.deleteServiceAllVersions(serviceIdLower, modifier); + actionResponse = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + } else { + actionResponse = businessLogic.markServiceForDeletion(serviceIdLower, modifier); + } if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { log.debug("failed to delete service"); return buildErrorResponse(actionResponse); } loggerSupportability - .log(LoggerSupportabilityActions.DELETE_SERVICE, StatusCode.COMPLETE, "Ended deleting service {} by user {}", serviceIdLower, userId); + .log(LoggerSupportabilityActions.DELETE_SERVICE, StatusCode.COMPLETE, "Ended deleting service {} by user {}", serviceIdLower, userId); return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); } catch (Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service"); @@ -298,11 +335,12 @@ public class ServiceServlet extends AbstractValidationsServlet { @DELETE @Path("/services/{serviceName}/{version}") + @Tag(name = "SDCE-2 APIs") @Operation(description = "Delete Service By Name And Version", method = "DELETE", summary = "Returns no content", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))), - @ApiResponse(responseCode = "204", description = "Service deleted"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "404", description = "Service not found")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))), + @ApiResponse(responseCode = "204", description = "Service deleted"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Service not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response deleteServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { @@ -326,29 +364,27 @@ public class ServiceServlet extends AbstractValidationsServlet { 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); - return modifier; + return userBusinessLogic.getUser(userId); } @PUT @Path("/services/{serviceId}/metadata") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Update Service Metadata", method = "PUT", summary = "Returns updated service", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), - @ApiResponse(responseCode = "200", description = "Service Updated"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "200", description = "Service Updated"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response updateServiceMetadata(@PathParam("serviceId") final String serviceId, @Parameter(description = "Service object to be Updated", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) - throws IOException { + throws IOException { String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); try { String serviceIdLower = serviceId.toLowerCase(); @@ -387,13 +423,14 @@ public class ServiceServlet extends AbstractValidationsServlet { */ @PUT @Path("/{containerComponentType}/{serviceId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Update Group Instance Property Values", method = "PUT", summary = "Returns updated group instance", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), - @ApiResponse(responseCode = "200", description = "Group Instance Property Values Updated"), - @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "200", description = "Group Instance Property Values Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response updateGroupInstancePropertyValues(@PathParam("serviceId") final String serviceId, @PathParam("componentInstanceId") final String componentInstanceId, @@ -403,8 +440,7 @@ public class ServiceServlet extends AbstractValidationsServlet { @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws JsonProcessingException { String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); Either, ResponseFormat> actionResponse = null; try { @@ -418,7 +454,7 @@ public class ServiceServlet extends AbstractValidationsServlet { if (actionResponse == null) { log.debug("Start handle update group instance property values request. Received group instance is {}", groupInstanceId); actionResponse = serviceBusinessLogic - .updateGroupInstancePropertyValues(modifier, serviceId, componentInstanceId, groupInstanceId, newProperties); + .updateGroupInstancePropertyValues(modifier, serviceId, componentInstanceId, groupInstanceId, newProperties); if (actionResponse.isRight()) { actionResponse = Either.right(actionResponse.right().value()); } @@ -432,27 +468,27 @@ public class ServiceServlet extends AbstractValidationsServlet { return buildErrorResponse(actionResponse.right().value()); } } catch (Exception e) { - log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e); + log.error(BUSINESS_PROCESS_ERROR, this.getClass().getName(), "Exception occured during update Group Instance property values.", e); throw e; } } @GET @Path("/services/{serviceId}") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Retrieve Service", method = "GET", summary = "Returns service according to serviceId", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), - @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "404", description = "Service not found")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response getServiceById(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); // get modifier id - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); try { String serviceIdLower = serviceId.toLowerCase(); @@ -474,19 +510,18 @@ public class ServiceServlet extends AbstractValidationsServlet { @GET @Path("/services/serviceName/{serviceName}/serviceVersion/{serviceVersion}") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Retrieve Service", method = "GET", summary = "Returns service according to name and version", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), - @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "404", description = "Service not found")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response getServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { // get modifier id - User modifier = new User(); - modifier.setUserId(userId); log.debug(MODIFIER_ID_IS, userId); try { Either actionResponse = serviceBusinessLogic.getServiceByNameAndVersion(serviceName, serviceVersion, userId); @@ -505,21 +540,21 @@ public class ServiceServlet extends AbstractValidationsServlet { @POST @Path("/services/{serviceId}/distribution/{env}/activate") + @Tag(name = "SDCE-5 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Activate distribution", method = "POST", summary = "activate distribution", responses = { - @ApiResponse(responseCode = "200", description = "OK"), - @ApiResponse(responseCode = "409", description = "Service cannot be distributed due to missing deployment artifacts"), - @ApiResponse(responseCode = "404", description = "Requested service was not found"), - @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "409", description = "Service cannot be distributed due to missing deployment artifacts"), + @ApiResponse(responseCode = "404", description = "Requested service was not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response activateDistribution(@PathParam("serviceId") final String serviceId, @PathParam("env") final String env, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) - throws IOException { + throws IOException { String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); Either distResponse = serviceBusinessLogic.activateDistribution(serviceId, env, modifier, request); if (distResponse.isRight()) { @@ -540,23 +575,23 @@ public class ServiceServlet extends AbstractValidationsServlet { @POST @Path("/services/{serviceId}/distribution/{did}/markDeployed") + @Tag(name = "SDCE-5 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Mark distribution as deployed", method = "POST", summary = "relevant audit record will be created", responses = { - @ApiResponse(responseCode = "200", description = "Service was marked as deployed"), - @ApiResponse(responseCode = "409", description = "Restricted operation"), - @ApiResponse(responseCode = "403", description = "Service is not available"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "404", description = "Requested service was not found"), - @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) + @ApiResponse(responseCode = "200", description = "Service was marked as deployed"), + @ApiResponse(responseCode = "409", description = "Restricted operation"), + @ApiResponse(responseCode = "403", description = "Service is not available"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Requested service was not found"), + @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response markDistributionAsDeployed(@PathParam("serviceId") final String serviceId, @PathParam("did") final String did, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); try { Either distResponse = serviceBusinessLogic.markDistributionAsDeployed(serviceId, did, modifier); @@ -576,23 +611,22 @@ public class ServiceServlet extends AbstractValidationsServlet { @POST @Path("/services/{serviceId}/tempUrlToBeDeleted") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(responses = {@ApiResponse(responseCode = "200", description = "OK"), - @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) + @ApiResponse(responseCode = "500", description = "Internal Server Error. Please try again later.")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response tempUrlToBeDeleted(@PathParam("serviceId") final String serviceId, @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); - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); try { Service service = (serviceBusinessLogic.getService(serviceId, modifier)).left().value(); Either res = serviceBusinessLogic - .updateDistributionStatusForActivation(service, modifier, DistributionStatusEnum.DISTRIBUTED); + .updateDistributionStatusForActivation(service, modifier, DistributionStatusEnum.DISTRIBUTED); if (res.isRight()) { buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } @@ -606,20 +640,20 @@ public class ServiceServlet extends AbstractValidationsServlet { @GET @Path("/services/{serviceId}/linksMap") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Retrieve Service component relations map", method = "GET", summary = "Returns service components relations", responses = { - @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = ServiceRelations.class)))), - @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "404", description = "Service not found")}) + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = ServiceRelations.class)))), + @ApiResponse(responseCode = "200", description = "Service found"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Service not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response getServiceComponentRelationMap(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); // get modifier id - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug(MODIFIER_ID_IS, userId); try { String serviceIdLower = serviceId.toLowerCase(); @@ -641,48 +675,44 @@ public class ServiceServlet extends AbstractValidationsServlet { @POST @Path("/services/importService") + @Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Import Service", method = "POST", summary = "Returns imported service", responses = { - @ApiResponse(responseCode = "201", description = "Service created"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "409", description = "Service already exist")}) + @ApiResponse(responseCode = "201", description = "Service created"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Service already exist")}) public Response importNsService(@Parameter(description = "Service object to be imported", 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); initSpringFromContext(); 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; + log.debug(START_HANDLE_REQUEST_OF, url); + log.debug(MODIFIER_ID_IS, userId); try { - Wrapper responseWrapper = new Wrapper<>(); - performUIImport(responseWrapper, data, request, userId, null); + final Wrapper responseWrapper = performUIImport(data, request, userId); return responseWrapper.getInnerElement(); } catch (IOException | ZipException e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Service"); log.debug("import service failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } } - private void performUIImport(Wrapper responseWrapper, String data, final HttpServletRequest request, String userId, - String ServiceUniqueId) throws FileNotFoundException, ZipException { + private Wrapper performUIImport(String data, final HttpServletRequest request, + String userId) throws FileNotFoundException, ZipException { + Wrapper responseWrapper = new Wrapper<>(); Wrapper userWrapper = new Wrapper<>(); Wrapper uploadServiceInfoWrapper = new Wrapper<>(); Wrapper yamlStringWrapper = new Wrapper<>(); - ServiceAuthorityTypeEnum ServiceAuthorityEnum = ServiceAuthorityTypeEnum.USER_TYPE_UI; - commonServiceGeneralValidations(responseWrapper, userWrapper, uploadServiceInfoWrapper, ServiceAuthorityEnum, userId, data); - specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, - data, ServiceAuthorityEnum); + ServiceAuthorityTypeEnum serviceAuthorityTypeEnum = ServiceAuthorityTypeEnum.USER_TYPE_UI; + commonServiceGeneralValidations(responseWrapper, userWrapper, uploadServiceInfoWrapper, serviceAuthorityTypeEnum, userId, data); + specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, request, + data, serviceAuthorityTypeEnum); if (responseWrapper.isEmpty()) { - handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement(), - yamlStringWrapper.getInnerElement(), ServiceAuthorityEnum, true, ServiceUniqueId); + handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement()); } + return responseWrapper; } /** @@ -702,37 +732,36 @@ public class ServiceServlet extends AbstractValidationsServlet { */ @POST @Path("/services/serviceUUID/{uuid}/importReplaceService") + @Tag(name = "SDCE-2 APIs") @Produces(MediaType.APPLICATION_JSON) @Operation(description = "Import Service", method = "POST", summary = "Returns imported service", responses = { - @ApiResponse(responseCode = "201", description = "Service created"), @ApiResponse(responseCode = "403", description = "Restricted operation"), - @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), - @ApiResponse(responseCode = "409", description = "Service already exist")}) + @ApiResponse(responseCode = "201", description = "Service created"), @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "409", description = "Service already exist")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response importReplaceService( - @Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId, - @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, - @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, - @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept, - @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, - @Context final HttpServletRequest request, @Parameter(description = "FileInputStream") @FormDataParam("serviceZip") File file, - @Parameter(description = "ContentDisposition") @FormDataParam("serviceZip") FormDataContentDisposition contentDispositionHeader, - @Parameter(description = "serviceMetadata") @FormDataParam("serviceZipMetadata") String serviceInfoJsonString, - @Parameter(description = "The requested asset uuid", required = true) @PathParam("uuid") final String uuid) { + @Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @Context final HttpServletRequest request, @Parameter(description = "FileInputStream") @FormDataParam("serviceZip") File file, + @Parameter(description = "ContentDisposition") @FormDataParam("serviceZip") FormDataContentDisposition contentDispositionHeader, + @Parameter(description = "serviceMetadata") @FormDataParam("serviceZipMetadata") String serviceInfoJsonString, + @Parameter(description = "The requested asset uuid", required = true) @PathParam("uuid") final String uuid) { initSpringFromContext(); String requestURI = request.getRequestURI(); String url = request.getMethod() + " " + requestURI; log.debug("importReplaceService,Start handle request of {}", url); // get modifier id - User modifier = new User(); - modifier.setUserId(userId); + User modifier = new User(userId); log.debug("importReplaceService,modifier id is {}", userId); log.debug("importReplaceService,get file:{},fileName:{}", file, file.getName()); - Response response; ResponseFormat responseFormat = null; AuditingActionEnum auditingActionEnum = AuditingActionEnum.Import_Replace_Service; String assetType = "services"; Either, ResponseFormat> assetTypeData = elementBusinessLogic - .getCatalogComponentsByUuidAndAssetType(assetType, uuid); + .getCatalogComponentsByUuidAndAssetType(assetType, uuid); if (assetTypeData.isRight() || assetTypeData.left().value().size() != 1) { log.debug("getServiceAbstractStatus: Service Fetching Failed"); throw new ByResponseFormatComponentException(assetTypeData.right().value()); @@ -758,14 +787,14 @@ public class ServiceServlet extends AbstractValidationsServlet { ServiceUploadServlet.ServiceAuthorityTypeEnum serviceAuthorityEnum = ServiceUploadServlet.ServiceAuthorityTypeEnum.CSAR_TYPE_BE; // PayLoad Validations commonServiceGeneralValidations(responseWrapper, userWrapper, uploadServiceInfoWrapper, serviceAuthorityEnum, userId, - serviceInfoJsonString); + serviceInfoJsonString); fillServicePayload(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, modifier, serviceInfoJsonString, serviceAuthorityEnum, - file); - specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, - serviceInfoJsonString, serviceAuthorityEnum); + file); + specificServiceAuthorityValidations(responseWrapper, uploadServiceInfoWrapper, yamlStringWrapper, request, + serviceInfoJsonString, serviceAuthorityEnum); log.debug("importReplaceService:get payload:{}", uploadServiceInfoWrapper.getInnerElement().getPayloadData()); ServiceMetadataDataDefinition serviceMetadataDataDefinition = (ServiceMetadataDataDefinition) oldService.getComponentMetadataDefinition() - .getMetadataDataDefinition(); + .getMetadataDataDefinition(); uploadServiceInfoWrapper.getInnerElement().setServiceVendorModelNumber(serviceMetadataDataDefinition.getServiceVendorModelNumber()); uploadServiceInfoWrapper.getInnerElement().setDescription(oldService.getDescription()); uploadServiceInfoWrapper.getInnerElement().setCategories(oldService.getCategories()); @@ -773,15 +802,74 @@ public class ServiceServlet extends AbstractValidationsServlet { uploadServiceInfoWrapper.getInnerElement().setProjectCode(oldService.getProjectCode()); if (responseWrapper.isEmpty()) { log.debug("importReplaceService:start handleImportService"); - handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement(), - yamlStringWrapper.getInnerElement(), serviceAuthorityEnum, true, null); + handleImportService(responseWrapper, userWrapper.getInnerElement(), uploadServiceInfoWrapper.getInnerElement()); } return responseWrapper.getInnerElement(); - } catch (IOException | ZipException e) { + } catch (final ZipException e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Service"); log.debug("import service failed with exception", e); - response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - return response; + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } } + + + @PUT + @Path("/services/{serviceId}/toscaTemplate") + @Tag(name = "SDCE-2 APIs") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update service by tosca template import", method = "PUT", summary = "Returns updated service", + responses = { + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "200", description = "Service Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) + public Response importToscaTemplate(@PathParam("serviceId") final String serviceId, + @Parameter(description = "Service object to be Updated", required = true) final String data, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) throws IOException { + initSpringFromContext(); + final User modifier = getUser(request); + try { + final ServiceImportBusinessLogic serviceImportBusinessLogic = serviceImportManager.getServiceImportBusinessLogic(); + final Service updatedService = serviceImportBusinessLogic.updateServiceFromToscaTemplate(serviceId, modifier, data); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(updatedService)); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); + log.error("update service metadata failed with exception", e); + throw e; + } + } + + @PUT + @Path("/services/{serviceId}/toscaModel") + @Tag(name = "SDCE-2 APIs") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update service by tosca template model", method = "PUT", summary = "Returns updated service", + responses = { + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class)))), + @ApiResponse(responseCode = "200", description = "Service Updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) + public Response importToscaModel(@PathParam("serviceId") final String serviceId, + @NotNull @FormDataParam("upload") final InputStream fileToUpload, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) throws IOException { + initSpringFromContext(); + final User modifier = getUser(request); + try { + final ServiceImportBusinessLogic serviceImportBusinessLogic = serviceImportManager.getServiceImportBusinessLogic(); + final Service updatedService = serviceImportBusinessLogic.updateServiceFromToscaModel(serviceId, modifier, fileToUpload); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(updatedService)); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); + log.error("update service metadata failed with exception", e); + throw e; + } + } + + public enum Action {DELETE, MARK_AS_DELETE} }