From: aribeiro Date: Mon, 24 Aug 2020 16:09:20 +0000 (+0100) Subject: Add node_filter capabilities X-Git-Tag: 1.7.1~38 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=c70b7081d70edf93aefae514dc688d8dc1835db2;p=sdc.git Add node_filter capabilities Issue-ID: SDC-3263 Signed-off-by: aribeiro Change-Id: I2965c8b0b9331b035ba5f9cc7f58d9ea3af26402 --- diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java index de6836d993..ac5af15d6e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java @@ -32,8 +32,11 @@ import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.NodeFilterValidator; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.User; @@ -166,15 +169,14 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return Optional.ofNullable(result.left().value()); } - - public Optional addNodeFilter(final String componentId, final String componentInstanceId, final NodeFilterConstraintAction action, final String propertyName, final String constraint, final boolean shouldLock, - final ComponentTypeEnum componentTypeEnum) + final ComponentTypeEnum componentTypeEnum, + final NodeFilterConstraintType nodeFilterConstraintType) throws BusinessLogicException { final Component component = getComponent(componentId); @@ -186,13 +188,13 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { lockComponent(component.getUniqueId(), component,"Add Node Filter on Component"); wasLocked = true; } - final RequirementNodeFilterPropertyDataDefinition newProperty = + final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition(); - newProperty.setName(propertyName); - newProperty.setConstraints(Collections.singletonList(constraint)); - final Either result = nodeFilterOperation - .addNewProperty(componentId, componentInstanceId, nodeFilterDataDefinition, newProperty); - + requirementNodeFilterPropertyDataDefinition.setName(propertyName); + requirementNodeFilterPropertyDataDefinition.setConstraints(Collections.singletonList(constraint)); + final Either result = addNewNodeFilter(componentId, + componentInstanceId, propertyName, nodeFilterConstraintType, nodeFilterDataDefinition, + requirementNodeFilterPropertyDataDefinition); if (result.isRight()) { janusGraphDao.rollback(); throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils @@ -322,6 +324,30 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return Optional.ofNullable(nodeFilterDataDefinition); } + private Either addNewNodeFilter( + final String componentId, + final String componentInstanceId, + final String propertyName, + final NodeFilterConstraintType nodeFilterConstraintType, + final CINodeFilterDataDefinition nodeFilterDataDefinition, + final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition) { + + if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { + return nodeFilterOperation.addNewProperty(componentId, componentInstanceId, nodeFilterDataDefinition, + requirementNodeFilterPropertyDataDefinition); + } + final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = + new RequirementNodeFilterCapabilityDataDefinition(); + requirementNodeFilterCapabilityDataDefinition.setName(propertyName); + final ListDataDefinition + propertyDataDefinitionListDataDefinition = new ListDataDefinition<>(); + propertyDataDefinitionListDataDefinition.getListToscaDataDefinition().addAll( + Collections.singleton(requirementNodeFilterPropertyDataDefinition)); + requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionListDataDefinition); + return nodeFilterOperation.addNewCapabilities(componentId, componentInstanceId, nodeFilterDataDefinition, + requirementNodeFilterCapabilityDataDefinition); + } + private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) { graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType()); @@ -398,4 +424,4 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { .getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); } } -} \ No newline at end of file +} 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 aa9b931057..a682dc9bed 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 @@ -53,6 +53,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.model.User; @@ -64,7 +65,7 @@ import org.openecomp.sdc.common.api.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Path("/v1/catalog/{componentType}/{componentId}/resourceInstances/{componentInstanceId}/nodeFilter") +@Path("/v1/catalog/{componentType}/{componentId}/resourceInstances/{componentInstanceId}/nodeFilter/{constraintType}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Singleton @@ -104,7 +105,6 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("/") @Operation(description = "Add Component Filter Constraint", method = "POST", summary = "Add Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @@ -120,6 +120,10 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { schema = @Schema(allowableValues = { ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + @Parameter(description = "Constraint type. Valid values: properties / capabilities", + schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) + @PathParam("constraintType") final String constraintType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { @@ -138,9 +142,17 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { final UIConstraint uiConstraint = convertResponse.get(); final String constraint = new ConstraintConvertor().convert(uiConstraint); + final Optional nodeFilterConstraintType = + NodeFilterConstraintType.parse(constraintType); + if (!nodeFilterConstraintType.isPresent()) { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, + "Invalid value for NodeFilterConstraintType enum %s", constraintType)); + } + final Optional actionResponse = componentNodeFilterBusinessLogic .addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, - uiConstraint.getServicePropertyName(), constraint, true, componentTypeEnum); + uiConstraint.getServicePropertyName(), constraint, true, componentTypeEnum, + nodeFilterConstraintType.get()); if (!actionResponse.isPresent()) { LOGGER.error(FAILED_TO_CREATE_NODE_FILTER); @@ -160,7 +172,6 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("/") @Operation(description = "Update Component Filter Constraint", method = "PUT", summary = "Update Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @@ -176,6 +187,10 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { schema = @Schema(allowableValues = { ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + @Parameter(description = "Constraint type. Valid values: properties / capabilities", + schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) + @PathParam("constraintType") final String constraintType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); @@ -230,6 +245,10 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { schema = @Schema(allowableValues = { ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + @Parameter(description = "Constraint type. Valid values: properties / capabilities", + schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) + @PathParam("constraintType") final String constraintType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java index c4a4acecbc..6996465a82 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java @@ -25,6 +25,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -43,7 +45,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoExtension; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; @@ -57,8 +58,10 @@ import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.ComponentInstance; @@ -145,7 +148,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); - when(componentsUtils.convertFromStorageResponse(Mockito.any())).thenReturn(ActionStatus.GENERAL_ERROR); + when(componentsUtils.convertFromStorageResponse(any())).thenReturn(ActionStatus.GENERAL_ERROR); when(nodeFilterOperation.createNodeFilter(componentId, componentInstanceId)) .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) @@ -245,6 +248,76 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); } + @Test + public void addNodeFilterPropertiesTest() throws BusinessLogicException { + componentInstance.setNodeFilter(ciNodeFilterDataDefinition); + + when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); + when(nodeFilterValidator + .validateFilter(resource, componentInstanceId, + requirementNodeFilterPropertyDataDefinition.getConstraints(), + NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); + when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) + .thenReturn(Either.left(true)); + when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) + .thenReturn(StorageOperationStatus.OK); + when(nodeFilterOperation.addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(RequirementNodeFilterPropertyDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); + when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) + .thenReturn(StorageOperationStatus.OK); + + final Optional result = componentNodeFilterBusinessLogic + .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, + "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES); + + assertThat(result).isPresent(); + assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); + verify(toscaOperationFacade, times(1)).getToscaElement(componentId); + verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, + Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); + verify(nodeFilterOperation, times(1)) + .addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(RequirementNodeFilterPropertyDataDefinition.class)); + verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); + } + + @Test + public void addNodeFilterCapabilitiesTest() throws BusinessLogicException { + componentInstance.setNodeFilter(ciNodeFilterDataDefinition); + + when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); + when(nodeFilterValidator + .validateFilter(resource, componentInstanceId, + requirementNodeFilterPropertyDataDefinition.getConstraints(), + NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); + when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) + .thenReturn(Either.left(true)); + when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) + .thenReturn(StorageOperationStatus.OK); + when(nodeFilterOperation.addNewCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(RequirementNodeFilterCapabilityDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); + when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) + .thenReturn(StorageOperationStatus.OK); + + final Optional result = componentNodeFilterBusinessLogic + .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, + "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.CAPABILITIES); + + assertThat(result).isPresent(); + assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); + verify(toscaOperationFacade, times(1)).getToscaElement(componentId); + verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, + Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); + verify(nodeFilterOperation, times(1)) + .addNewCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(RequirementNodeFilterCapabilityDataDefinition.class)); + verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); + } + @Test public void addNodeFilterFailTest() { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); @@ -264,7 +337,8 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock final List constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE)); + "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); @@ -285,7 +359,8 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE)); + "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES)); } @Test @@ -477,4 +552,4 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock fail(e.getMessage()); } } -} \ No newline at end of file +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java index 08890ef3e7..3bad7dd497 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java @@ -72,6 +72,7 @@ import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; @@ -143,10 +144,11 @@ public class ComponentNodeFilterServletTest extends JerseyTest { } @Test - public void addNodeFilterSuccessTest() throws BusinessLogicException, JsonProcessingException { + public void addNodeFilterPropertiesSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -160,7 +162,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { assertThat(sourceName).isEqualToIgnoringCase(uiConstraint.getSourceName()); assertThat(propertyValue).isEqualToIgnoringCase(uiConstraint.getValue().toString()); - when(componentsUtils.parseToConstraint(anyString(), any(User.class),ArgumentMatchers.any(ComponentTypeEnum.class))) + when(componentsUtils.parseToConstraint(anyString(), any(User.class), ArgumentMatchers.any(ComponentTypeEnum.class))) .thenReturn(Optional.of(uiConstraint)); assertNotNull(constraint); @@ -169,7 +171,8 @@ public class ComponentNodeFilterServletTest extends JerseyTest { assertThat("resourceType: {equal: resourceTypeValue}\n").isEqualToIgnoringCase(constraint); when(componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, - uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE)) + uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES)) .thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() @@ -179,8 +182,44 @@ public class ComponentNodeFilterServletTest extends JerseyTest { .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), anyString(), anyBoolean(), - ArgumentMatchers.any(ComponentTypeEnum.class)); + .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), + anyString(), anyBoolean(), ArgumentMatchers.any(ComponentTypeEnum.class), + ArgumentMatchers.any(NodeFilterConstraintType.class)); + + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); + } + + @Test + public void addNodeFilterCapabilitiesSuccessTest() throws BusinessLogicException, JsonProcessingException { + initComponentData(); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME); + + when(userValidations.validateUserExists(user)).thenReturn(user); + when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); + when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); + when(componentsUtils.parseToConstraint(anyString(), any(User.class),ArgumentMatchers.any(ComponentTypeEnum.class))) + .thenReturn(Optional.of(uiConstraint)); + + assertThat(ciNodeFilterDataDefinition.getProperties().getListToscaDataDefinition()).hasSize(1); + when(componentNodeFilterBusinessLogic + .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, + uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.CAPABILITIES)) + .thenReturn(Optional.of(ciNodeFilterDataDefinition)); + + final Response response = target() + .path(path) + .request(MediaType.APPLICATION_JSON) + .header(USER_ID_HEADER, USER_ID) + .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); + + verify(componentNodeFilterBusinessLogic, times(1)) + .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), + anyString(), anyBoolean(), ArgumentMatchers.any(ComponentTypeEnum.class), + ArgumentMatchers.any(NodeFilterConstraintType.class)); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); } @@ -188,8 +227,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void addNodeFilterFailTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -202,7 +242,8 @@ public class ComponentNodeFilterServletTest extends JerseyTest { when(componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, - uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE)) + uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES)) .thenReturn(Optional.empty()); final Response response = target() @@ -211,18 +252,14 @@ public class ComponentNodeFilterServletTest extends JerseyTest { .header(USER_ID_HEADER, USER_ID) .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); - verify(componentNodeFilterBusinessLogic, times(1)) - .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), anyString(), anyBoolean(), - ArgumentMatchers.any(ComponentTypeEnum.class)); - assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); } @Test public void addNodeFilterFailConstraintParseTest() throws JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -247,8 +284,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void addNodeFilterFailConvertTest() throws JsonProcessingException, BusinessLogicException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES.getType()); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -273,8 +311,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -306,8 +345,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterFailTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -338,8 +378,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterFailConstraintParseTest() throws JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -360,8 +401,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterFailConvertTest() throws JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -384,8 +426,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void deleteNodeFilterSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance, 0); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 0); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -413,8 +456,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void deleteNodeFilterFailTest() { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance, 1); + final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s/%s"; + final String path = String.format(pathFormat, componentType, componentId, componentInstance, + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 1); final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) @@ -488,4 +532,4 @@ public class ComponentNodeFilterServletTest extends JerseyTest { return mapper.writeValueAsString(uiConstraint); } -} \ No newline at end of file +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java index 69c9f4e59d..02f8e83dde 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java @@ -33,6 +33,7 @@ import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.model.Component; @@ -115,6 +116,22 @@ public class NodeFilterOperation extends BaseOperation { return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition); } + public Either addNewCapabilities( + final String componentId, final String componentInstanceId, + final CINodeFilterDataDefinition nodeFilterDataDefinition, + final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition) { + + ListDataDefinition capabilities = + nodeFilterDataDefinition.getCapabilities(); + if(capabilities == null) { + capabilities = new ListDataDefinition<>(); + nodeFilterDataDefinition.setCapabilities(capabilities); + } + capabilities.getListToscaDataDefinition().add(requirementNodeFilterCapabilityDataDefinition); + nodeFilterDataDefinition.setCapabilities(capabilities); + return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition); + } + public Either updateProperties( final String serviceId, final String componentInstanceId, final CINodeFilterDataDefinition nodeFilterDataDefinition, diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeFilterConstraintType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeFilterConstraintType.java new file mode 100644 index 0000000000..76db876b04 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeFilterConstraintType.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.openecomp.sdc.be.datatypes.enums; + +import java.util.Optional; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Represents the type of a node filter constraint. + */ +@Getter +@AllArgsConstructor +public enum NodeFilterConstraintType { + + PROPERTIES(NodeFilterConstraintType.PROPERTIES_PARAM_NAME), + CAPABILITIES(NodeFilterConstraintType.CAPABILITIES_PARAM_NAME); + + private final String type; + + // Those values are needed as constants for Swagger allowedValues param + public static final String PROPERTIES_PARAM_NAME = "properties"; + public static final String CAPABILITIES_PARAM_NAME = "capabilities"; + + /** + * Parse a String to the related {@link NodeFilterConstraintType}. + * + * @param type the {@link NodeFilterConstraintType} type + * @return The {@link NodeFilterConstraintType} representing the given type. + */ + public static Optional parse(final String type) { + for (final NodeFilterConstraintType nodeFilterConstraintType : values()) { + if (nodeFilterConstraintType.getType().equals(type)) { + return Optional.of(nodeFilterConstraintType); + } + } + return Optional.empty(); + } +}