/*- * ============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.util.Collections; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; import org.openecomp.sdc.be.ui.model.UiServiceDataTransfer; import org.openecomp.sdc.be.user.UserBusinessLogic; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.ResponseFormat; import com.google.common.collect.Sets; import com.jcabi.aspects.Loggable; import fj.data.Either; 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; @Loggable(prepend = true, value = Loggable.DEBUG, trim = false) @Path("/v1/catalog/services/{serviceId}/paths") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @OpenAPIDefinition(info = @Info(title = "Service Forwarding Path", description = "Service Forwarding Path Servlet")) @Singleton public class ServiceForwardingPathServlet extends AbstractValidationsServlet { private static final Logger log = Logger.getLogger(ServiceForwardingPathServlet.class); private final ServiceBusinessLogic serviceBusinessLogic; @Inject public ServiceForwardingPathServlet(UserBusinessLogic userBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager, ServiceBusinessLogic serviceBusinessLogic) { super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager); this.serviceBusinessLogic = serviceBusinessLogic; } @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/") @Operation(description = "Create Forwarding Path", method = "POST", summary = "Create Forwarding Path",responses = @ApiResponse( content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Forwarding Path"), @ApiResponse(responseCode = "403", description = "Restricted operation"), @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) public Response createForwardingPath( @Parameter(description = "Forwarding Path to create", required = true) String data, @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { return createOrUpdate(data, serviceId, request, userId, false); } @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/") @Operation(description = "Update Forwarding Path", method = "PUT", summary = "Update Forwarding Path",responses = @ApiResponse( content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Forwarding Path"), @ApiResponse(responseCode = "403", description = "Restricted operation"), @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) public Response updateForwardingPath( @Parameter(description = "Update Path to create", required = true) String data, @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { return createOrUpdate(data, serviceId, request, userId, true); } private Response createOrUpdate( String data, String serviceId, HttpServletRequest request, String userId, boolean isUpdate) { 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); Response response; try { String serviceIdLower = serviceId.toLowerCase(); Either convertResponse = parseToService(data, modifier); if (convertResponse.isRight()) { log.debug("failed to parse service"); response = buildErrorResponse(convertResponse.right().value()); return response; } Service updatedService = convertResponse.left().value(); Either actionResponse ; if (isUpdate) { actionResponse = serviceBusinessLogic.updateForwardingPath(serviceIdLower, updatedService, modifier, true); } else { actionResponse = serviceBusinessLogic.createForwardingPath(serviceIdLower, updatedService, modifier, true); } if (actionResponse.isRight()) { log.debug("failed to update or create paths"); response = buildErrorResponse(actionResponse.right().value()); return response; } Service service = actionResponse.left().value(); Object result = RepresentationUtils.toRepresentation(service); return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); } catch (Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Forward Path Creation or update"); log.debug("create or update forwarding path with an error", e); response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); return response; } } @GET @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{forwardingPathId}") @Operation(description = "Get Forwarding Path", method = "GET", summary = "GET Forwarding Path",responses = @ApiResponse( content = @Content(array = @ArraySchema(schema = @Schema(implementation = ForwardingPathDataDefinition.class))))) @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Get Forwarding Path"), @ApiResponse(responseCode = "403", description = "Restricted operation"), @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) public Response getForwardingPath( @Parameter(description = "Forwarding Path to create", required = true) String datax, @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, @Parameter(description = "Forwarding Path Id") @PathParam("forwardingPathId") String forwardingPathId, @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); log.debug("modifier id is {}", userId); try { Either serviceResponse = serviceBusinessLogic.getComponentDataFilteredByParams(serviceId, modifier, Collections.singletonList(ComponentFieldsEnum.FORWARDING_PATHS.getValue())); if (serviceResponse.isRight()) { return buildErrorResponse(serviceResponse.right().value()); } UiServiceDataTransfer uiServiceDataTransfer = (UiServiceDataTransfer) serviceResponse.left().value(); ForwardingPathDataDefinition forwardingPathDataDefinition = new ForwardingPathDataDefinition(); if (!MapUtils.isEmpty(uiServiceDataTransfer.getForwardingPaths())) { forwardingPathDataDefinition = uiServiceDataTransfer.getForwardingPaths().get(forwardingPathId); } return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(forwardingPathDataDefinition)); } catch (Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); log.debug("update service metadata failed with exception", e); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } } @DELETE @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{forwardingPathId}") @Operation(description = "Delete Forwarding Path", method = "DELETE", summary = "Delete Forwarding Path",responses = @ApiResponse( content = @Content(array = @ArraySchema(schema = @Schema(implementation = Service.class))))) @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Forwarding Path"), @ApiResponse(responseCode = "403", description = "Restricted operation"), @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), @ApiResponse(responseCode = "409", description = "Forwarding Path already exist")}) public Response deleteForwardingPath( @Parameter(description = "Forwarding Path Id") @PathParam("forwardingPathId") String forwardingPathId, @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId, @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); log.debug("modifier id is {}", userId); Response response; try { String serviceIdLower = serviceId.toLowerCase(); Either, ResponseFormat> actionResponse = serviceBusinessLogic.deleteForwardingPaths(serviceIdLower, Sets.newHashSet(forwardingPathId), modifier, true); if (actionResponse.isRight()) { log.debug("failed to delete paths"); response = buildErrorResponse(actionResponse.right().value()); return response; } Set deletedPaths = actionResponse.left().value(); Object result = RepresentationUtils.toRepresentation(deletedPaths); return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); } catch (Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete forward paths"); log.debug("Delete service paths with an error", e); response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); return response; } } private Either parseToService(String serviceJson, User user) { return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);//TODO: change sSERVICE constant } }