From: adheli.tavares Date: Fri, 8 Aug 2025 15:29:10 +0000 (+0100) Subject: Add a new filter to /instances endpoint X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=b833b8b5e03c06043f6399fb87a3531b1f7711f3;p=policy%2Fclamp.git Add a new filter to /instances endpoint Issue-ID: POLICY-5425 Change-Id: Ia8ff03956b1b1ddd2bbbd71e134821c30f2d1af4 Signed-off-by: adheli.tavares --- diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java index c8a862cba..eb0d9b471 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java @@ -335,17 +335,22 @@ public class AutomationCompositionProvider { * Retrieves a list of AutomationComposition instances filtered by the specified state change results * and deployment states. The result can be paginated and sorted based on the provided parameters. * + * @param compositionIds a list of composition UUIDs to filter the AutomationComposition instances * @param stateChangeResults a list of StateChangeResult values to filter the AutomationComposition instances * @param deployStates a list of DeployState values to filter the AutomationComposition instances * @param pageable the pagination information including page size and page number * @return a list of AutomationComposition instances that match the specified filters */ - public List getAcInstancesByStateResultDeployState( + public List getAcInstancesByFilter( + @NonNull final List compositionIds, @NonNull final List stateChangeResults, @NonNull final List deployStates, @NonNull final Pageable pageable) { Page page; - if (stateChangeResults.isEmpty() && deployStates.isEmpty()) { + + if (!compositionIds.isEmpty()) { + page = filterWithCompositionIds(compositionIds, stateChangeResults, deployStates, pageable); + } else if (stateChangeResults.isEmpty() && deployStates.isEmpty()) { page = automationCompositionRepository.findAll(pageable); } else if (!stateChangeResults.isEmpty() && deployStates.isEmpty()) { page = automationCompositionRepository.findByStateChangeResultIn(stateChangeResults, pageable); @@ -358,4 +363,22 @@ public class AutomationCompositionProvider { return ProviderUtils.asEntityList(page.toList()); } + + private Page filterWithCompositionIds(final List compositionIds, + final List stages, + final List deployStates, + final Pageable pageable) { + if (stages.isEmpty() && deployStates.isEmpty()) { + return automationCompositionRepository.findByCompositionIdIn(compositionIds, pageable); + } else if (!stages.isEmpty() && deployStates.isEmpty()) { + return automationCompositionRepository.findByCompositionIdInAndStateChangeResultIn( + compositionIds, stages, pageable); + } else if (stages.isEmpty()) { + return automationCompositionRepository.findByCompositionIdInAndDeployStateIn( + compositionIds, deployStates, pageable); + } else { + return automationCompositionRepository.findByCompositionIdInAndStateChangeResultInAndDeployStateIn( + compositionIds, stages, deployStates, pageable); + } + } } diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java index 10fe0b1df..7fa164791 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionRepository.java @@ -52,4 +52,16 @@ public interface AutomationCompositionRepository extends JpaRepository findByStateChangeResultIn(Collection stateChangeResults, Pageable pageable); + + Page findByCompositionIdIn(Collection compositionIds, Pageable pageable); + + Page findByCompositionIdInAndStateChangeResultIn( + Collection compositionIds, Collection stateChangeResults, Pageable pageable); + + Page findByCompositionIdInAndDeployStateIn( + Collection compositionIds, Collection deployStates, Pageable pageable); + + Page findByCompositionIdInAndStateChangeResultInAndDeployStateIn( + Collection compositionIds, Collection stateChangeResults, + Collection deployStates, Pageable pageable); } diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java index c9df95ded..0e51a2408 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProviderTest.java @@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; 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.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyCollection; import static org.mockito.ArgumentMatchers.anyIterable; @@ -188,6 +189,7 @@ class AutomationCompositionProviderTest { when(automationCompositionRepository.findById(automationComposition.getInstanceId().toString())) .thenReturn(Optional.of(inputAutomationCompositionsJpa.get(0))); acOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId()); + assertTrue(acOpt.isPresent()); assertEquals(automationComposition, acOpt.get()); } @@ -417,7 +419,7 @@ class AutomationCompositionProviderTest { } @Test - void testGetAcInstancesByFilter() { + void testGetAcInstancesByFilter_WithoutCompositionIds() { Page mockPage = new PageImpl<>(inputAutomationCompositionsJpa); var acRepository = mock(AutomationCompositionRepository.class); when(acRepository.findByStateChangeResultIn(anyCollection(), any(Pageable.class))) @@ -425,6 +427,7 @@ class AutomationCompositionProviderTest { when(acRepository.findByDeployStateIn(anyCollection(), any(Pageable.class))) .thenReturn(mockPage); + var acIds = new ArrayList(); var stateChangeResults = new ArrayList(); var deployStates = new ArrayList(); var pageable = Pageable.unpaged(); @@ -434,20 +437,59 @@ class AutomationCompositionProviderTest { var acProvider = new AutomationCompositionProvider(acRepository, mock(AutomationCompositionElementRepository.class), mock(AutomationCompositionRollbackRepository.class)); - var acInstances = acProvider.getAcInstancesByStateResultDeployState(stateChangeResults, deployStates, pageable); + var acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); assertNotNull(acInstances); assertEquals(2, acInstances.size()); stateChangeResults.add(StateChangeResult.NO_ERROR); - acInstances = acProvider.getAcInstancesByStateResultDeployState(stateChangeResults, deployStates, pageable); + acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); assertNotNull(acInstances); deployStates.add(DeployState.DEPLOYED); - acInstances = acProvider.getAcInstancesByStateResultDeployState(stateChangeResults, deployStates, pageable); + acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); assertNotNull(acInstances); stateChangeResults.clear(); - acInstances = acProvider.getAcInstancesByStateResultDeployState(stateChangeResults, deployStates, pageable); + acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); + assertNotNull(acInstances); + } + + @Test + void testGetAcInstancesByFilter_WithCompositionIds() { + Page mockPage = new PageImpl<>(inputAutomationCompositionsJpa); + var acRepository = mock(AutomationCompositionRepository.class); + + var acIds = new ArrayList(); + var stateChangeResults = new ArrayList(); + var deployStates = new ArrayList(); + var pageable = Pageable.unpaged(); + + when(acRepository.findByCompositionIdInAndStateChangeResultInAndDeployStateIn( + acIds, stateChangeResults, deployStates, pageable)).thenReturn(mockPage); + when(acRepository.findByCompositionIdInAndStateChangeResultIn(acIds, stateChangeResults, pageable)) + .thenReturn(mockPage); + when(acRepository.findByCompositionIdInAndDeployStateIn(acIds, deployStates, pageable)).thenReturn(mockPage); + when(acRepository.findByCompositionIdIn(acIds, pageable)).thenReturn(mockPage); + + var acProvider = new AutomationCompositionProvider(acRepository, + mock(AutomationCompositionElementRepository.class), mock(AutomationCompositionRollbackRepository.class)); + + acIds.add(inputAutomationCompositions.getAutomationCompositionList().get(0).getCompositionId().toString()); + + var acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); + assertNotNull(acInstances); + assertEquals(2, acInstances.size()); + + stateChangeResults.add(StateChangeResult.NO_ERROR); + acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); + assertNotNull(acInstances); + + deployStates.add(DeployState.DEPLOYED); + acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); + assertNotNull(acInstances); + + stateChangeResults.clear(); + acInstances = acProvider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, pageable); assertNotNull(acInstances); } @@ -455,14 +497,17 @@ class AutomationCompositionProviderTest { void testGetAcInstancesByFilterWithNull() { var provider = new AutomationCompositionProvider(mock(AutomationCompositionRepository.class), mock(AutomationCompositionElementRepository.class), mock(AutomationCompositionRollbackRepository.class)); + var acIds = new ArrayList(); var stateChangeResults = new ArrayList(); var deployStates = new ArrayList(); var pageable = Pageable.unpaged(); assertThrows(NullPointerException.class, () -> - provider.getAcInstancesByStateResultDeployState(null, deployStates, pageable)); + provider.getAcInstancesByFilter(null, stateChangeResults, deployStates, pageable)); + assertThrows(NullPointerException.class, () -> + provider.getAcInstancesByFilter(acIds, null, deployStates, pageable)); assertThrows(NullPointerException.class, () -> - provider.getAcInstancesByStateResultDeployState(stateChangeResults, null, pageable)); + provider.getAcInstancesByFilter(acIds, stateChangeResults, null, pageable)); assertThrows(NullPointerException.class, () -> - provider.getAcInstancesByStateResultDeployState(stateChangeResults, deployStates, null)); + provider.getAcInstancesByFilter(acIds, stateChangeResults, deployStates, null)); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java index c6190153a..670f30bcd 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java @@ -487,7 +487,7 @@ public class AutomationCompositionInstantiationProvider { dbAcElement.setDefinition(element.getValue().getDefinition()); } } - // Remove element which is not present in the new Ac instance + // Remove elements which are not present in the new Ac instance var elementsRemoved = getElementRemoved(acToBeUpdated, automationComposition); elementsRemoved.forEach(element -> acToBeUpdated.getElements().remove(element.getId())); @@ -511,15 +511,21 @@ public class AutomationCompositionInstantiationProvider { * Retrieves a list of AutomationComposition instances filtered by the specified state change results * and deployment states. The result can be paginated and sorted based on the provided parameters. * + * @param compositionIds a list of composition UUIDs to filter the AutomationComposition instances * @param stateChangeResults a list of StateChangeResult values to filter the AutomationComposition instances * @param deployStates a list of DeployState values to filter the AutomationComposition instances * @param pageable the pagination information including page size and page number * @return a list of AutomationComposition instances that match the specified filters */ - public AutomationCompositions getAcInstancesByStateResultDeployState( - final String stateChangeResults, final String deployStates, + public AutomationCompositions getAcInstancesByFilter( + final String compositionIds, final String stateChangeResults, final String deployStates, final Pageable pageable) { + List acIds = new ArrayList<>(); + if (compositionIds != null) { + Arrays.stream(compositionIds.split(",")).forEach(acId -> acIds.add(acId.trim())); + } + List stateChangeResultList = new ArrayList<>(); if (stateChangeResults != null) { Arrays.stream(stateChangeResults.split(",")) @@ -532,7 +538,7 @@ public class AutomationCompositionInstantiationProvider { .forEach(deployState -> deployStateList.add(DeployState.valueOf(deployState))); } - var instances = automationCompositionProvider.getAcInstancesByStateResultDeployState(stateChangeResultList, + var instances = automationCompositionProvider.getAcInstancesByFilter(acIds, stateChangeResultList, deployStateList, pageable); return new AutomationCompositions(instances); } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java index 5fc5f2cb7..0e4efdd8a 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/InstantiationController.java @@ -111,10 +111,11 @@ public class InstantiationController extends AbstractRestController implements A * @return a {@link ResponseEntity} containing an {@link AutomationCompositions} object */ @Override - public ResponseEntity queryCompositionInstancesByStateChangeDeployState(String deployStates, - String stateChangeResults, Integer page, Integer size, String sort, String sortOrder, UUID requestId) { + public ResponseEntity queryCompositionInstancesByFilter( + String compositionIds, String deployStates, String stateChangeResults, + Integer page, Integer size, String sort, String sortOrder, UUID requestId) { var pageable = getPageableWithSorting(page, size, sort, sortOrder); - var instances = provider.getAcInstancesByStateResultDeployState(stateChangeResults, deployStates, pageable); + var instances = provider.getAcInstancesByFilter(compositionIds, stateChangeResults, deployStates, pageable); return ResponseEntity.ok().body(instances); } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/stub/InstantiationControllerStub.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/stub/InstantiationControllerStub.java index 269c86c4e..fc16be800 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/stub/InstantiationControllerStub.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/stub/InstantiationControllerStub.java @@ -97,8 +97,9 @@ public class InstantiationControllerStub extends AbstractRestController implemen } @Override - public ResponseEntity queryCompositionInstancesByStateChangeDeployState(String deployState, - String stateChangeResult, Integer page, Integer size, String sort, String sortOrder, UUID onapRequestId) { + public ResponseEntity queryCompositionInstancesByFilter( + String compositionIds, String deployState, String stateChangeResult, + Integer page, Integer size, String sort, String sortOrder, UUID onapRequestId) { return stubUtils.getResponse(pathToAllInstances, AutomationCompositions.class); } } diff --git a/runtime-acm/src/main/resources/openapi/openapi.yaml b/runtime-acm/src/main/resources/openapi/openapi.yaml index d070178fa..0953e76d4 100644 --- a/runtime-acm/src/main/resources/openapi/openapi.yaml +++ b/runtime-acm/src/main/resources/openapi/openapi.yaml @@ -1923,8 +1923,14 @@ paths: - Automation Composition Instance summary: Query a list of automation composition instances description: Query a list of automation composition instances based on the query filter - operationId: queryCompositionInstancesByStateChangeDeployState + operationId: queryCompositionInstancesByFilter parameters: + - name: compositionIds + in: query + required: false + schema: + type: string + description: Filter to get instances by compositionId (two or more to be comma-separated) - name: deployState in: query required: false diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java index 33703ee49..2ce195c96 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java @@ -454,7 +454,7 @@ class InstantiationControllerTest extends CommonRestController { } @Test - void test_QueryCompositionInstancesByStateChangeDeployState() { + void test_queryCompositionInstancesByFilter_WithoutCompositionIds() { // test setup var compositionId = createAcDefinitionInDB("Query"); var automationComposition = @@ -475,6 +475,27 @@ class InstantiationControllerTest extends CommonRestController { validateQueryPageable("instances?sort=name&sortOrder=DESC", 10); } + @Test + void test_queryCompositionInstancesByFilter_WithCompositionIds() { + // test setup + var compositionId = createAcDefinitionInDB("Query"); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query"); + assertNotNull(automationComposition); + automationComposition.setCompositionId(compositionId); + for (var i = 0; i < NUMBER_INSTANCES; i++) { + automationComposition.setName("acmr_" + i); + instantiationProvider.createAutomationComposition(compositionId, automationComposition); + } + + validateQueryPageable("instances?compositionIds=" + compositionId, 10); + validateQueryPageable("instances?page=1&size=4&compositionIds=" + compositionId, 4); + validateQueryPageable("instances?size=4&compositionIds=" + compositionId, 10); + validateQueryPageable("instances?stateChangeResult=FAILED,TIMEOUT&compositionIds=" + compositionId, 0); + validateQueryPageable("instances?deployState=UNDEPLOYED&compositionIds=" + compositionId, 10); + validateQueryPageable("instances?sort=name&sortOrder=DESC&compositionIds=" + compositionId, 10); + } + private UUID createAcDefinitionInDB(String name) { var serviceTemplateCreate = new ToscaServiceTemplate(serviceTemplate); serviceTemplateCreate.setName(name);