From 4aff8f5eafb6fbd6cc2c764fa1a5a676fa05c89c Mon Sep 17 00:00:00 2001 From: vasraz Date: Thu, 24 Mar 2022 18:31:14 +0000 Subject: Implement adding Interface to VFC Change-Id: I7cd8b82c306294d897d37d486aa3eeff7ca4206d Signed-off-by: Vasyl Razinkov Issue-ID: SDC-3893 Signed-off-by: andre.schmid --- .../ComponentInterfaceOperationBusinessLogic.java | 82 +++++++++++++++++++++- .../ComponentInterfaceOperationServlet.java | 61 ++++++++++++++-- .../be/servlets/ComponentNodeFilterServlet.java | 8 +-- 3 files changed, 141 insertions(+), 10 deletions(-) (limited to 'catalog-be') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java index 57571c0b49..4e44967dcb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.UUID; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; @@ -209,8 +210,7 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic lockComponent(componentId, component, "Update Interface Operation on Component instance"); wasLocked = true; } - final StorageOperationStatus status = - toscaOperationFacade.updateComponentInterfaces(component.getUniqueId(), component.getInterfaces(), interfaceDefinitionType); + final StorageOperationStatus status = toscaOperationFacade.updateComponentInterfaces(component, interfaceDefinitionType); if (status != StorageOperationStatus.OK) { janusGraphDao.rollback(); responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); @@ -233,6 +233,84 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic return Optional.of(component); } + public Optional createInterfaceOperationInResource(final String componentId, final InterfaceDefinition interfaceDefinition, + final ComponentTypeEnum componentTypeEnum, + final Wrapper errorWrapper, final boolean shouldLock) + throws BusinessLogicException { + final Component component = getComponent(componentId); + ResponseFormat responseFormat; + final String componentInterfaceUpdatedKey = interfaceDefinition.getType(); + + Map componentInterfaceMap = component.getInterfaces(); + if (MapUtils.isEmpty(componentInterfaceMap)) { + componentInterfaceMap = new HashMap<>(); + component.setInterfaces(componentInterfaceMap); + } + + interfaceDefinition.setUniqueId(componentInterfaceUpdatedKey); + interfaceDefinition.setToscaResourceName(componentInterfaceUpdatedKey); + + final Optional optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst(); + if (optionalOperationDataDefinition.isEmpty()) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND); + LOGGER.debug("Failed to found interface operation on component instance with id {}, error: {}", componentId, responseFormat); + errorWrapper.setInnerElement(responseFormat); + return Optional.empty(); + } + + final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get(); + updatedOperationDataDefinition.setUniqueId(UUID.randomUUID().toString()); + + final InterfaceDefinition interfaceDefinitionFound = componentInterfaceMap.get(componentInterfaceUpdatedKey); + if (interfaceDefinitionFound != null) { + final Map operationsFromComponent = interfaceDefinitionFound.getOperations(); + final String updatedOperationDataDefinitionName = updatedOperationDataDefinition.getName(); + final boolean find = operationsFromComponent.containsKey(updatedOperationDataDefinitionName); + if (find) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE, + updatedOperationDataDefinitionName); + LOGGER.error("Operation '{}' for Interface '{}' already exist, error: '{}'", updatedOperationDataDefinitionName, + componentInterfaceUpdatedKey, responseFormat); + errorWrapper.setInnerElement(responseFormat); + return Optional.empty(); + } else { + operationsFromComponent.put(updatedOperationDataDefinitionName, updatedOperationDataDefinition); + interfaceDefinition.setOperations(operationsFromComponent); + } + } + + componentInterfaceMap.put(componentInterfaceUpdatedKey, interfaceDefinition); + + boolean wasLocked = false; + try { + if (shouldLock) { + lockComponent(componentId, component, "Update Interface Operation on Component instance"); + wasLocked = true; + } + final Either operationStatusEither = + toscaOperationFacade.addInterfaceToComponent(componentInterfaceUpdatedKey, interfaceDefinition, component); + if (operationStatusEither.isRight()) { + janusGraphDao.rollback(); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat); + errorWrapper.setInnerElement(responseFormat); + return Optional.empty(); + } + janusGraphDao.commit(); + } catch (final Exception e) { + janusGraphDao.rollback(); + LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: ", e); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + errorWrapper.setInnerElement(responseFormat); + throw new BusinessLogicException(responseFormat); + } finally { + if (wasLocked) { + unlockComponent(component.getUniqueId(), componentTypeEnum); + } + } + return Optional.of(component); + } + public User validateUser(final String userId) { final User user = userValidations.validateUserExists(userId); userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN)); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java index 83ee15240f..3b8bfe5bd7 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInterfaceOperationServlet.java @@ -36,6 +36,7 @@ import java.util.Optional; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; 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; @@ -138,9 +139,8 @@ public class ComponentInterfaceOperationServlet extends AbstractValidationsServl } final Wrapper errorWrapper = new Wrapper<>(); try { - final Optional actionResponse = componentInterfaceOperationBusinessLogic - .updateComponentInstanceInterfaceOperation(componentId, componentInstanceId, mappedInterfaceOperationData.get(), componentTypeEnum, - errorWrapper, true); + final Optional actionResponse = componentInterfaceOperationBusinessLogic.updateComponentInstanceInterfaceOperation( + componentId, componentInstanceId, mappedInterfaceOperationData.get(), componentTypeEnum, errorWrapper, true); if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentInstanceId); return buildErrorResponse(errorWrapper.getInnerElement()); @@ -186,7 +186,60 @@ public class ComponentInterfaceOperationServlet extends AbstractValidationsServl final Wrapper errorWrapper = new Wrapper<>(); try { final Optional actionResponse = componentInterfaceOperationBusinessLogic - .updateResourceInterfaceOperation(componentId, mappedInterfaceOperationData.get(), componentTypeEnum, errorWrapper, true); + .updateResourceInterfaceOperation(componentId, mappedInterfaceOperationData.get(), componentTypeEnum, + errorWrapper, true); + if (actionResponse.isEmpty()) { + LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentId); + return buildErrorResponse(errorWrapper.getInnerElement()); + } else { + LOGGER.debug(INTERFACE_OPERATION_SUCCESSFULLY_UPDATED, componentId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.get()); + } + } catch (final Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_INTERFACE_OPERATION); + LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{componentType}/{componentId}/resource/interfaceOperation") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Create Interface Operation", method = "POST", summary = "Create Interface Operation on ComponentInstance", responses = { + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), + @ApiResponse(responseCode = "201", description = "Create Interface Operation"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) + public Response createInterfaceOperationInResource( + @Parameter(description = "valid values: resources", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME})) + @PathParam("componentType") final String componentType, + @Parameter(description = "Component Id") @PathParam("componentId") String componentId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { + LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); + LOGGER.debug(MODIFIER_ID_IS, userId); + final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId); + final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + if (componentTypeEnum == null) { + LOGGER.debug(UNSUPPORTED_COMPONENT_TYPE, componentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType)); + } + final byte[] bytes = IOUtils.toByteArray(request.getInputStream()); + if (bytes == null || bytes.length == 0) { + LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + final String data = new String(bytes); + final Optional mappedInterfaceOperationData = getMappedInterfaceData(data, userModifier, componentTypeEnum); + if (mappedInterfaceOperationData.isEmpty()) { + LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, data); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + final Wrapper errorWrapper = new Wrapper<>(); + try { + final Optional actionResponse = componentInterfaceOperationBusinessLogic.createInterfaceOperationInResource( + componentId, mappedInterfaceOperationData.get(), componentTypeEnum, errorWrapper, true); if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentId); return buildErrorResponse(errorWrapper.getInnerElement()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java index 77b0998e53..c66bb8a8ec 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java @@ -64,7 +64,7 @@ import org.openecomp.sdc.common.api.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Path("/v1/catalog/{componentType}/{componentId}/componentInstance/{componentInstanceId}/{constraintType}") +@Path("/v1/catalog") @Tags({@Tag(name = "SDCE-2 APIs")}) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @@ -99,7 +99,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("/nodeFilter") + @Path("/{componentType}/{componentId}/componentInstance/{componentInstanceId}/{constraintType}/nodeFilter") @Operation(description = "Add Component Filter Constraint", method = "POST", summary = "Add Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @ApiResponse(responseCode = "201", description = "Create Component Filter"), @@ -154,7 +154,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("/{constraintIndex}/nodeFilter") + @Path("/{componentType}/{componentId}/componentInstance/{componentInstanceId}/{constraintType}/{constraintIndex}/nodeFilter") @Operation(description = "Update Component Filter Constraint", method = "PUT", summary = "Update Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @ApiResponse(responseCode = "201", description = "Create Component Filter"), @@ -208,7 +208,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @DELETE @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("{constraintIndex}/nodeFilter") + @Path("/{componentType}/{componentId}/componentInstance/{componentInstanceId}/{constraintType}/{constraintIndex}/nodeFilter") @Operation(description = "Delete Component Filter Constraint", method = "Delete", summary = "Delete Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @ApiResponse(responseCode = "201", description = "Delete Component Filter Constraint"), -- cgit 1.2.3-korg