From 219246026f814772682aeeaff8de9cde76730dfd Mon Sep 17 00:00:00 2001 From: Priyanka Verma Date: Wed, 30 Oct 2024 20:42:59 +0000 Subject: [PATCH] LAU-979 request limit addition --- .../ccd/parameter/TestParameterResolver.java | 9 ++ .../ccd/config/TestParameterResolver.java | 8 ++ .../parameter/DefaultParameterResolver.java | 8 ++ .../ccd/parameter/ParameterResolver.java | 2 + .../ccd/service/CaseDeletionService.java | 14 ++- src/main/resources/application.yaml | 2 + .../ccd/service/CaseDeletionServiceTest.java | 86 +++++++++++++++++++ 7 files changed, 126 insertions(+), 3 deletions(-) diff --git a/src/functionalTest/java/uk/gov/hmcts/reform/ccd/parameter/TestParameterResolver.java b/src/functionalTest/java/uk/gov/hmcts/reform/ccd/parameter/TestParameterResolver.java index 15855770..62c909f4 100644 --- a/src/functionalTest/java/uk/gov/hmcts/reform/ccd/parameter/TestParameterResolver.java +++ b/src/functionalTest/java/uk/gov/hmcts/reform/ccd/parameter/TestParameterResolver.java @@ -68,6 +68,9 @@ public class TestParameterResolver implements ParameterResolver { @Value("${thread.queue_capacity}") private Integer threadQueueCapacity; + @Value("${requests.limit}") + private Integer requestsLimit; + @Override public List getElasticsearchHosts() { return elasticsearchHosts.stream() @@ -186,4 +189,10 @@ public Integer getThreadCorePoolSize() { public Integer getThreadQueueCapacity() { return threadQueueCapacity; } + + @Override + public Integer getRequestsLimit() { + return requestsLimit; + } + } diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/ccd/config/TestParameterResolver.java b/src/integrationTest/java/uk/gov/hmcts/reform/ccd/config/TestParameterResolver.java index f1e2d65d..f3e399b1 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/ccd/config/TestParameterResolver.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/ccd/config/TestParameterResolver.java @@ -60,6 +60,9 @@ public class TestParameterResolver implements ParameterResolver { @Value("${thread.queue_capacity}") private Integer threadQueueCapacity; + @Value("${requests.limit}") + private Integer requestsLimit; + @Override public Integer getElasticsearchRequestTimeout() { return elasticsearchRequestTimeout; @@ -181,4 +184,9 @@ public Integer getThreadQueueCapacity() { return threadQueueCapacity; } + @Override + public Integer getRequestsLimit() { + return requestsLimit; + } + } diff --git a/src/main/java/uk/gov/hmcts/reform/ccd/parameter/DefaultParameterResolver.java b/src/main/java/uk/gov/hmcts/reform/ccd/parameter/DefaultParameterResolver.java index 62a8fa11..c8e54589 100644 --- a/src/main/java/uk/gov/hmcts/reform/ccd/parameter/DefaultParameterResolver.java +++ b/src/main/java/uk/gov/hmcts/reform/ccd/parameter/DefaultParameterResolver.java @@ -68,6 +68,9 @@ public class DefaultParameterResolver implements ParameterResolver { @Value("${thread.queue_capacity}") private Integer threadQueueCapacity; + @Value("${requests.limit}") + private Integer requestsLimit; + @Override public List getElasticsearchHosts() { return elasticsearchHosts.stream() @@ -180,4 +183,9 @@ public Integer getThreadCorePoolSize() { public Integer getThreadQueueCapacity() { return threadQueueCapacity; } + + @Override + public Integer getRequestsLimit() { + return requestsLimit; + } } diff --git a/src/main/java/uk/gov/hmcts/reform/ccd/parameter/ParameterResolver.java b/src/main/java/uk/gov/hmcts/reform/ccd/parameter/ParameterResolver.java index 5b3e2333..fa05c3b0 100644 --- a/src/main/java/uk/gov/hmcts/reform/ccd/parameter/ParameterResolver.java +++ b/src/main/java/uk/gov/hmcts/reform/ccd/parameter/ParameterResolver.java @@ -44,4 +44,6 @@ public interface ParameterResolver { Integer getThreadCorePoolSize(); Integer getThreadQueueCapacity(); + + Integer getRequestsLimit(); } diff --git a/src/main/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionService.java b/src/main/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionService.java index 2e0e6270..8919fd84 100644 --- a/src/main/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionService.java +++ b/src/main/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionService.java @@ -12,6 +12,7 @@ import uk.gov.hmcts.reform.ccd.data.entity.CaseLinkPrimaryKey; import uk.gov.hmcts.reform.ccd.data.model.CaseData; import uk.gov.hmcts.reform.ccd.data.model.CaseFamily; +import uk.gov.hmcts.reform.ccd.parameter.ParameterResolver; import uk.gov.hmcts.reform.ccd.service.remote.RemoteDisposeService; import uk.gov.hmcts.reform.ccd.util.FailedToDeleteCaseFamilyHolder; import uk.gov.hmcts.reform.ccd.util.Snooper; @@ -29,6 +30,7 @@ public class CaseDeletionService { private final RemoteDisposeService remoteDisposeService; private final Snooper snooper; private final FailedToDeleteCaseFamilyHolder failedToDeleteCaseFamilyHolder; + private final ParameterResolver parameterResolver; @Inject public CaseDeletionService(final CaseDataRepository caseDataRepository, @@ -36,19 +38,25 @@ public CaseDeletionService(final CaseDataRepository caseDataRepository, final CaseLinkRepository caseLinkRepository, final FailedToDeleteCaseFamilyHolder failedToDeleteCaseFamilyHolder, final RemoteDisposeService remoteDisposeService, - final Snooper snooper) { + final Snooper snooper, + final ParameterResolver parameterResolver) { this.caseDataRepository = caseDataRepository; this.caseEventRepository = caseEventRepository; this.caseLinkRepository = caseLinkRepository; this.failedToDeleteCaseFamilyHolder = failedToDeleteCaseFamilyHolder; this.snooper = snooper; this.remoteDisposeService = remoteDisposeService; + this.parameterResolver = parameterResolver; } @Transactional public void deleteLinkedCaseFamilies(@NonNull final List linkedCaseFamilies) { - linkedCaseFamilies.forEach(this::deleteLinkedCases); - linkedCaseFamilies.forEach(this::deleteCase); + int index = 0; + while (index < parameterResolver.getRequestsLimit() && index < linkedCaseFamilies.size()) { + deleteLinkedCases(linkedCaseFamilies.get(index)); + deleteCase(linkedCaseFamilies.get(index)); + index++; + } } void deleteCase(final CaseFamily caseFamily) { diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index bf1a923e..7b1eab23 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -36,6 +36,8 @@ elasticsearch: deletable.case.types: ${DELETE_CASE_TYPES:} simulated.case.types: ${SIMULATED_CASE_TYPES:} +requests.limit: ${CCD_DISPOSER_REQUEST_LIMIT:100} + ccd: document.store: host: ${DOCUMENT_STORE_HOST:http://localhost:4506} diff --git a/src/test/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionServiceTest.java b/src/test/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionServiceTest.java index 7200c4b1..da8025be 100644 --- a/src/test/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/ccd/service/CaseDeletionServiceTest.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.reform.ccd.service; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -14,6 +15,7 @@ import uk.gov.hmcts.reform.ccd.data.model.CaseData; import uk.gov.hmcts.reform.ccd.data.model.CaseFamily; import uk.gov.hmcts.reform.ccd.fixture.CaseLinkEntityBuilder; +import uk.gov.hmcts.reform.ccd.parameter.ParameterResolver; import uk.gov.hmcts.reform.ccd.service.remote.RemoteDisposeService; import uk.gov.hmcts.reform.ccd.util.FailedToDeleteCaseFamilyHolder; import uk.gov.hmcts.reform.ccd.util.Snooper; @@ -36,6 +38,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; +import static org.springframework.test.util.ReflectionTestUtils.setField; import static uk.gov.hmcts.reform.ccd.fixture.TestData.DELETABLE_CASE_ENTITY_WITH_PAST_TTL; import static uk.gov.hmcts.reform.ccd.fixture.TestData.DELETABLE_CASE_TYPE; import static uk.gov.hmcts.reform.ccd.fixture.TestData.JURISDICTION; @@ -55,6 +59,8 @@ class CaseDeletionServiceTest { private RemoteDisposeService remoteDisposeService; @Mock private FailedToDeleteCaseFamilyHolder failedToDeleteCaseFamilyHolder; + @Mock + private ParameterResolver parameterResolver; @Mock private Snooper snooper; @@ -77,6 +83,11 @@ class CaseDeletionServiceTest { private final CaseFamily defaultCaseFamily = new CaseFamily(caseData, List.of(linkedCaseData1, linkedCaseData2)); + @BeforeEach + void setUp() { + setField(underTest, "parameterResolver", parameterResolver); + } + @Test void testDeleteCaseWithNoLinkedCases() { final CaseFamily caseFamily = new CaseFamily(caseData, emptyList()); @@ -162,6 +173,7 @@ void testShouldRaiseNullPointerExceptionWhenParameterIsNull() { @Test void testDeleteCases() { + when(parameterResolver.getRequestsLimit()).thenReturn(1); // GIVEN final List linkedFamilies = List.of(defaultCaseFamily); List.of(1L, 10L, 11L) @@ -209,4 +221,78 @@ void testShouldLogErrorWhenDeleteLinkedCasesFails() { verify(failedToDeleteCaseFamilyHolder, times(2)).addCaseFamily(defaultCaseFamily); verifyNoMoreInteractions(caseLinkRepository); } + + @Test + void shouldLimitCaseDeletionToRequestsLimit() { + // Given + when(parameterResolver.getRequestsLimit()).thenReturn(2); + final CaseFamily caseFamily2 = new CaseFamily(caseData, emptyList()); + final CaseFamily caseFamily3 = new CaseFamily(caseData, emptyList()); + + final List linkedFamilies = List.of(defaultCaseFamily, caseFamily2, caseFamily3); + + doReturn(Optional.of(caseLinkEntity1), Optional.of(caseLinkEntity2)) + .when(caseLinkRepository).findById(any(CaseLinkPrimaryKey.class)); + doNothing().when(caseLinkRepository).delete(any(CaseLinkEntity.class)); + doNothing().when(caseDataRepository).delete(any(CaseDataEntity.class)); + doNothing().when(remoteDisposeService).remoteDeleteAll(any(CaseData.class)); + + doNothing().when(caseEventRepository).deleteByCaseDataId(anyLong()); + doReturn(Optional.of(DELETABLE_CASE_ENTITY_WITH_PAST_TTL)).when(caseDataRepository).findById(anyLong()); + + // When + underTest.deleteLinkedCaseFamilies(linkedFamilies); + + // Then + verify(caseEventRepository,times(2)).deleteByCaseDataId(1L); + verify(caseDataRepository,times(2)).findById(1L); + + List.of(10L, 11L).forEach(caseId -> { + verify(caseEventRepository).deleteByCaseDataId(caseId); + verify(caseDataRepository).findById(caseId); + }); + + verify(caseLinkRepository).findById(new CaseLinkPrimaryKey(1L, 10L)); + verify(caseLinkRepository).findById(new CaseLinkPrimaryKey(1L, 11L)); + verify(caseLinkRepository, times(2)).delete(any(CaseLinkEntity.class)); + verify(caseDataRepository, times(4)).delete(any(CaseDataEntity.class)); + verify(remoteDisposeService, times(4)).remoteDeleteAll(any(CaseData.class)); + } + + @Test + void shouldDeleteAllCasesIfRequestsLimitGreaterThanCases() { + // Given + when(parameterResolver.getRequestsLimit()).thenReturn(10); + final CaseFamily caseFamily2 = new CaseFamily(caseData, emptyList()); + final CaseFamily caseFamily3 = new CaseFamily(caseData, emptyList()); + + final List linkedFamilies = List.of(defaultCaseFamily, caseFamily2, caseFamily3); + + doReturn(Optional.of(caseLinkEntity1), Optional.of(caseLinkEntity2)) + .when(caseLinkRepository).findById(any(CaseLinkPrimaryKey.class)); + doNothing().when(caseLinkRepository).delete(any(CaseLinkEntity.class)); + doNothing().when(caseDataRepository).delete(any(CaseDataEntity.class)); + doNothing().when(remoteDisposeService).remoteDeleteAll(any(CaseData.class)); + + doNothing().when(caseEventRepository).deleteByCaseDataId(anyLong()); + doReturn(Optional.of(DELETABLE_CASE_ENTITY_WITH_PAST_TTL)).when(caseDataRepository).findById(anyLong()); + + // When + underTest.deleteLinkedCaseFamilies(linkedFamilies); + + // Then + verify(caseEventRepository,times(3)).deleteByCaseDataId(1L); + verify(caseDataRepository,times(3)).findById(1L); + + List.of(10L, 11L).forEach(caseId -> { + verify(caseEventRepository).deleteByCaseDataId(caseId); + verify(caseDataRepository).findById(caseId); + }); + + verify(caseLinkRepository).findById(new CaseLinkPrimaryKey(1L, 10L)); + verify(caseLinkRepository).findById(new CaseLinkPrimaryKey(1L, 11L)); + verify(caseLinkRepository, times(2)).delete(any(CaseLinkEntity.class)); + verify(caseDataRepository, times(5)).delete(any(CaseDataEntity.class)); + verify(remoteDisposeService, times(5)).remoteDeleteAll(any(CaseData.class)); + } }