From 59a1ca23845c434934087f72ace744b3deb1a3c3 Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Thu, 19 Mar 2026 18:46:24 +0000 Subject: [PATCH 01/10] DMP-5415 Interruption of deleting CR and UF files Added code to delete multiple ARM files --- build.gradle | 1 + .../darts/arm/ArmServiceFunctionalTest.java | 25 +++++++++ .../testutils/stubs/ArmServiceStubImpl.java | 6 ++ .../hmcts/darts/arm/service/ArmService.java | 2 + .../arm/service/impl/ArmServiceImpl.java | 55 +++++++++++++++++++ 5 files changed, 89 insertions(+) diff --git a/build.gradle b/build.gradle index 7b2bd8ea7e2..825fc7557db 100644 --- a/build.gradle +++ b/build.gradle @@ -458,6 +458,7 @@ dependencies { implementation platform('com.azure:azure-sdk-bom:1.3.4') implementation 'com.azure:azure-storage-blob' + implementation 'com.azure:azure-storage-blob-batch' implementation group: 'io.rest-assured', name: 'rest-assured' implementation group: 'org.flywaydb', name: 'flyway-core', version: '11.20.3' diff --git a/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java b/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java index 1cf4750adb6..d7220bf55fd 100644 --- a/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java +++ b/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java @@ -172,6 +172,31 @@ void listBlobsUsingMarkerTestContinuationToken() { } + @Test + void saveAndDeleteMultipleBlobs() { + log.info("------------------ saveAndDeleteMultipleBlobs test"); + + byte[] testStringInBytes = TEST_BINARY_STRING.getBytes(StandardCharsets.UTF_8); + BinaryData data = BinaryData.fromBytes(testStringInBytes); + String filename1 = String.format("%s_functional_test", UUID.randomUUID()); + String actualResult1 = armService.saveBlobData(armContainerName, filename1, data); + armSubmissionBlobsToBeDeleted.add(actualResult1); + assertNotNull(actualResult1); + log.info("Blob filename1: {}", actualResult1); + + String filename2 = String.format("%s_functional_test", UUID.randomUUID()); + String actualResult2 = armService.saveBlobData(armContainerName, filename2, data); + armSubmissionBlobsToBeDeleted.add(actualResult2); + assertNotNull(actualResult2); + log.info("Blob filename2: {}", actualResult2); + + armService.deleteMultipleBlobs(armContainerName, List.of( + armSubmissionDropZone + filename1, + armSubmissionDropZone + filename2 + )); + cleanupArmBlobData(); + } + private void uploadBatchedSubmissionBlobs(BinaryData data) { for (int counter = 0; counter < 11; counter++) { String filename = String.format("functional_test_%s", UUID.randomUUID()); diff --git a/src/integrationTest/java/uk/gov/hmcts/darts/testutils/stubs/ArmServiceStubImpl.java b/src/integrationTest/java/uk/gov/hmcts/darts/testutils/stubs/ArmServiceStubImpl.java index abbc3a15b31..024811e0553 100644 --- a/src/integrationTest/java/uk/gov/hmcts/darts/testutils/stubs/ArmServiceStubImpl.java +++ b/src/integrationTest/java/uk/gov/hmcts/darts/testutils/stubs/ArmServiceStubImpl.java @@ -76,6 +76,12 @@ public boolean deleteBlobData(String containerName, String blobPathAndName) { return true; } + @Override + public boolean deleteMultipleBlobs(String containerName, List blobPathAndName) { + logStubUsageWarning(); + return true; + } + private void logStubUsageWarning() { log.warn("### This implementation is intended only for integration tests. If you see this log message elsewhere" + " you should ask questions! ###"); diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/ArmService.java b/src/main/java/uk/gov/hmcts/darts/arm/service/ArmService.java index e995d85c919..8db89148865 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/ArmService.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/ArmService.java @@ -34,4 +34,6 @@ public interface ArmService { */ boolean deleteBlobData(String containerName, String blobPathAndName); + boolean deleteMultipleBlobs(String containerName, List blobPathAndName); + } diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java index 5d5a5495a1c..dd014130fc7 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java @@ -6,6 +6,9 @@ import com.azure.core.util.BinaryData; import com.azure.storage.blob.BlobClient; import com.azure.storage.blob.BlobContainerClient; +import com.azure.storage.blob.BlobServiceClient; +import com.azure.storage.blob.batch.BlobBatchClient; +import com.azure.storage.blob.batch.BlobBatchClientBuilder; import com.azure.storage.blob.models.BlobItem; import com.azure.storage.blob.models.BlobListDetails; import com.azure.storage.blob.models.DeleteSnapshotsOptionType; @@ -280,4 +283,56 @@ public boolean deleteBlobData(String containerName, String blobPathAndName) { } } + @Override + @SuppressWarnings({"PMD.ExceptionAsFlowControl"}) + public boolean deleteMultipleBlobs(String containerName, List blobPathAndName) { + if (blobPathAndName == null || blobPathAndName.isEmpty()) { + log.info("No blobs provided to delete for containerName={}", containerName); + return true; + } + + try { + BlobContainerClient containerClient = armDataManagementDao.getBlobContainerClient(containerName); + + // Delete *all* blobs in one go using Azure Storage Blob Batch. + // IMPORTANT: We intentionally do NOT fall back to single deletes because that can lead to partial deletion. + BlobServiceClient blobServiceClient = containerClient.getServiceClient(); + BlobBatchClient batchClient = new BlobBatchClientBuilder(blobServiceClient).buildClient(); + + // Azure SDK 12.29.x exposes per-blob results via deleteBlobs, which issues a single batch request. + boolean allSuccessful = true; + PagedIterable> responses = batchClient.deleteBlobs( + blobPathAndName, + DeleteSnapshotsOptionType.INCLUDE, + Duration.of(TIMEOUT, ChronoUnit.SECONDS), + null + ); + + int index = 0; + for (Response response : responses) { + int statusCode = response.getStatusCode(); + HttpStatus httpStatus = valueOf(statusCode); + String blobName = index < blobPathAndName.size() ? blobPathAndName.get(index) : ""; + index++; + + // treat NOT_FOUND as success (idempotent delete) + if (!(httpStatus.is2xxSuccessful() || NOT_FOUND.equals(httpStatus))) { + allSuccessful = false; + log.warn("Failed to delete blob in batch containerName={}, blobPathAndName={}, statusCode={}, httpStatus={}", + containerName, blobName, statusCode, httpStatus); + } + } + + if (allSuccessful) { + log.info("Successfully deleted {} blobs from containerName={} using batch", blobPathAndName.size(), containerName); + } else { + log.error("Batch deletion completed with one or more failures for containerName={}", containerName); + } + return allSuccessful; + } catch (Exception e) { + log.error("Could not delete multiple blobs from storage container={}", containerName, e); + return false; + } + } + } \ No newline at end of file From 2a6a2791f0ca30487b928f04df13e1cef2f15d31 Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:18:54 +0000 Subject: [PATCH 02/10] DMP-5415 Interruption of deleting CR and UF files Added code to delete multiple ARM files --- .../uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java | 4 ++-- .../uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java b/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java index d7220bf55fd..9b811a2cbed 100644 --- a/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java +++ b/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java @@ -191,8 +191,8 @@ void saveAndDeleteMultipleBlobs() { log.info("Blob filename2: {}", actualResult2); armService.deleteMultipleBlobs(armContainerName, List.of( - armSubmissionDropZone + filename1, - armSubmissionDropZone + filename2 + actualResult1, + actualResult2 )); cleanupArmBlobData(); } diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java index dd014130fc7..31d06669191 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java @@ -39,7 +39,7 @@ @Service @Slf4j -@SuppressWarnings("PMD.TooManyMethods")//TODO - refactor to reduce methods when this class is next edited +@SuppressWarnings({"PMD.TooManyMethods", "PMD.CouplingBetweenObjects"}) public class ArmServiceImpl implements ArmService { private static final String FILE_PATH_DELIMITER = "/"; @@ -284,7 +284,6 @@ public boolean deleteBlobData(String containerName, String blobPathAndName) { } @Override - @SuppressWarnings({"PMD.ExceptionAsFlowControl"}) public boolean deleteMultipleBlobs(String containerName, List blobPathAndName) { if (blobPathAndName == null || blobPathAndName.isEmpty()) { log.info("No blobs provided to delete for containerName={}", containerName); @@ -295,11 +294,9 @@ public boolean deleteMultipleBlobs(String containerName, List blobPathAn BlobContainerClient containerClient = armDataManagementDao.getBlobContainerClient(containerName); // Delete *all* blobs in one go using Azure Storage Blob Batch. - // IMPORTANT: We intentionally do NOT fall back to single deletes because that can lead to partial deletion. BlobServiceClient blobServiceClient = containerClient.getServiceClient(); BlobBatchClient batchClient = new BlobBatchClientBuilder(blobServiceClient).buildClient(); - // Azure SDK 12.29.x exposes per-blob results via deleteBlobs, which issues a single batch request. boolean allSuccessful = true; PagedIterable> responses = batchClient.deleteBlobs( blobPathAndName, From 92bf90d891be0776d04a34ae6669775402a84b2f Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:55:21 +0000 Subject: [PATCH 03/10] DMP-5415 Interruption of deleting CR and UF files Added code to delete multiple ARM files --- .../uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java index 31d06669191..baf3cd71774 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java @@ -311,8 +311,7 @@ public boolean deleteMultipleBlobs(String containerName, List blobPathAn HttpStatus httpStatus = valueOf(statusCode); String blobName = index < blobPathAndName.size() ? blobPathAndName.get(index) : ""; index++; - - // treat NOT_FOUND as success (idempotent delete) + if (!(httpStatus.is2xxSuccessful() || NOT_FOUND.equals(httpStatus))) { allSuccessful = false; log.warn("Failed to delete blob in batch containerName={}, blobPathAndName={}, statusCode={}, httpStatus={}", From f0c1c4ef048c2335d1e8c42feab9e78d53f3e3fa Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Fri, 20 Mar 2026 09:47:13 +0000 Subject: [PATCH 04/10] DMP-5415 Interruption of deleting CR and UF files Added some tests --- .../DataManagementServiceFunctionalTest.java | 8 +- .../arm/service/impl/ArmServiceImpl.java | 4 +- .../arm/service/impl/ArmServiceImplTest.java | 85 ++++++++++++++++++- 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java b/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java index 3a97ffada27..93bf276d108 100644 --- a/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java +++ b/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java @@ -43,14 +43,14 @@ class DataManagementServiceFunctionalTest extends FunctionalTest { private static final String TEST_BLOB_ID = "b0f23c62-8dd3-4e4e-ae6a-321ff6eb61d8"; @Value("${darts.storage.blob.container-name.unstructured}") - String unstructuredStorageContainerName; + private String unstructuredStorageContainerName; @Autowired - DataManagementService dataManagementService; + private DataManagementService dataManagementService; @Autowired - DataManagementConfiguration dataManagementConfiguration; + private DataManagementConfiguration dataManagementConfiguration; @Autowired - ArmDataManagementConfiguration armDataManagementConfiguration; + private ArmDataManagementConfiguration armDataManagementConfiguration; @Test void saveBinaryDataToBlobStorage() { diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java index baf3cd71774..f1b1409a801 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImpl.java @@ -287,7 +287,7 @@ public boolean deleteBlobData(String containerName, String blobPathAndName) { public boolean deleteMultipleBlobs(String containerName, List blobPathAndName) { if (blobPathAndName == null || blobPathAndName.isEmpty()) { log.info("No blobs provided to delete for containerName={}", containerName); - return true; + return false; } try { @@ -311,7 +311,7 @@ public boolean deleteMultipleBlobs(String containerName, List blobPathAn HttpStatus httpStatus = valueOf(statusCode); String blobName = index < blobPathAndName.size() ? blobPathAndName.get(index) : ""; index++; - + if (!(httpStatus.is2xxSuccessful() || NOT_FOUND.equals(httpStatus))) { allSuccessful = false; log.warn("Failed to delete blob in batch containerName={}, blobPathAndName={}, statusCode={}, httpStatus={}", diff --git a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java index 429c15c51ec..e1655f96cf4 100644 --- a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java @@ -5,6 +5,9 @@ import com.azure.core.util.BinaryData; import com.azure.storage.blob.BlobClient; import com.azure.storage.blob.BlobContainerClient; +import com.azure.storage.blob.BlobServiceClient; +import com.azure.storage.blob.batch.BlobBatchClient; +import com.azure.storage.blob.batch.BlobBatchClientBuilder; import com.azure.storage.blob.models.BlobItem; import com.azure.storage.blob.models.DeleteSnapshotsOptionType; import org.junit.jupiter.api.BeforeEach; @@ -16,6 +19,7 @@ import uk.gov.hmcts.darts.arm.config.ArmDataManagementConfiguration; import uk.gov.hmcts.darts.arm.dao.ArmDataManagementDao; import uk.gov.hmcts.darts.arm.model.blobs.ContinuationTokenBlobs; +import uk.gov.hmcts.darts.common.exception.AzureDeleteBlobException; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -26,7 +30,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -191,7 +198,7 @@ void testListResponseBlobsUsingBatch() { @Test void listSubmissionBlobsWithMarker_ShouldSucceed() { - PagedIterable mockPagedIterable = mock(PagedIterable.class); + PagedIterable mockPagedIterable = (PagedIterable) mock(PagedIterable.class); when(blobContainerClient.listBlobs(any(), any(), any())).thenReturn(mockPagedIterable); when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); @@ -210,7 +217,7 @@ void listSubmissionBlobsWithMarker_ShouldSucceed() { @Test void listResponseBlobsWithMarker_ShouldReturnToken() { - PagedIterable mockPagedTableEntities = mock(PagedIterable.class); + PagedIterable mockPagedTableEntities = (PagedIterable) mock(PagedIterable.class); when(blobContainerClient.listBlobs(any(), any(), any())).thenReturn(mockPagedTableEntities); when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); @@ -225,4 +232,78 @@ void listResponseBlobsWithMarker_ShouldReturnToken() { ARM_BLOB_CONTAINER_NAME, prefix, 10, null); assertNotNull(continuationTokenBlobs); } + + @Test + void deleteMultipleBlobs_shouldReturnFalseAndNotCallAzure_whenNoBlobsProvided() { + assertFalse(armService.deleteMultipleBlobs(ARM_BLOB_CONTAINER_NAME, null)); + assertFalse(armService.deleteMultipleBlobs(ARM_BLOB_CONTAINER_NAME, List.of())); + } + + @Test + void deleteMultipleBlobs_shouldReturnTrue_whenAllDeletesSucceed() { + when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); + BlobServiceClient blobServiceClient = mock(BlobServiceClient.class); + when(blobContainerClient.getServiceClient()).thenReturn(blobServiceClient); + + + PagedIterable> pagedResponses = (PagedIterable>) mock(PagedIterable.class); + Response r1 = (Response) mock(Response.class); + Response r2 = (Response) mock(Response.class); + when(r1.getStatusCode()).thenReturn(202); + when(r2.getStatusCode()).thenReturn(404); + when(pagedResponses.iterator()).thenReturn(List.of(r1, r2).iterator()); + + BlobBatchClient batchClient = mock(BlobBatchClient.class); + when(batchClient.deleteBlobs(anyList(), eq(DeleteSnapshotsOptionType.INCLUDE), any(Duration.class), eq(null))) + .thenReturn(pagedResponses); + + try (var ignored = mockConstruction(BlobBatchClientBuilder.class, + (builder, context) -> when(builder.buildClient()).thenReturn(batchClient))) { + boolean result = armService.deleteMultipleBlobs(ARM_BLOB_CONTAINER_NAME, List.of("blob1", "blob2")); + assertTrue(result); + } + } + + @Test + void deleteMultipleBlobs_shouldReturnFalse_whenAnyDeleteFails() { + when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); + BlobServiceClient blobServiceClient = mock(BlobServiceClient.class); + when(blobContainerClient.getServiceClient()).thenReturn(blobServiceClient); + + PagedIterable> pagedResponses = (PagedIterable>) mock(PagedIterable.class); + Response r1 = (Response) mock(Response.class); + Response r2 = (Response) mock(Response.class); + when(r1.getStatusCode()).thenReturn(202); + when(r2.getStatusCode()).thenReturn(500); + when(pagedResponses.iterator()).thenReturn(List.of(r1, r2).iterator()); + + BlobBatchClient batchClient = mock(BlobBatchClient.class); + when(batchClient.deleteBlobs(anyList(), eq(DeleteSnapshotsOptionType.INCLUDE), any(Duration.class), eq(null))) + .thenReturn(pagedResponses); + + try (var ignored = mockConstruction(BlobBatchClientBuilder.class, + (builder, context) -> when(builder.buildClient()).thenReturn(batchClient))) { + boolean result = armService.deleteMultipleBlobs(ARM_BLOB_CONTAINER_NAME, List.of("blob1", "blob2")); + assertFalse(result); + } + } + + @Test + void deleteMultipleBlobs_shouldReturnFalse_whenAzureThrowsException() { + when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); + BlobServiceClient blobServiceClient = mock(BlobServiceClient.class); + when(blobContainerClient.getServiceClient()).thenReturn(blobServiceClient); + + BlobBatchClient batchClient = mock(BlobBatchClient.class); + when(batchClient.deleteBlobs(anyList(), eq(DeleteSnapshotsOptionType.INCLUDE), any(Duration.class), eq(null))) + .thenThrow(new AzureDeleteBlobException("Azure error")); + + try (var ignored = mockConstruction(BlobBatchClientBuilder.class, + (builder, context) -> when(builder.buildClient()).thenReturn(batchClient))) { + boolean result = armService.deleteMultipleBlobs(ARM_BLOB_CONTAINER_NAME, List.of("blob1", "blob2")); + assertFalse(result); + } + } + + } From 895aabdbbdb089934ef83138a70726dd34b3f7ac Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Fri, 20 Mar 2026 09:56:37 +0000 Subject: [PATCH 05/10] DMP-5415 Interruption of deleting CR and UF files Added some tests --- .../arm/service/impl/ArmServiceImplTest.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java index e1655f96cf4..faebe8bf822 100644 --- a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java @@ -19,7 +19,6 @@ import uk.gov.hmcts.darts.arm.config.ArmDataManagementConfiguration; import uk.gov.hmcts.darts.arm.dao.ArmDataManagementDao; import uk.gov.hmcts.darts.arm.model.blobs.ContinuationTokenBlobs; -import uk.gov.hmcts.darts.common.exception.AzureDeleteBlobException; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -63,7 +62,7 @@ void beforeEach() { } @Test - void testSaveBlobDataUsingFilename() { + void saveBlobData_shouldSaveBlobUsingFilename() { var foldersConfig = new ArmDataManagementConfiguration.Folders(); foldersConfig.setSubmission(TEST_BINARY_STRING); when(armDataManagementConfiguration.getFolders()).thenReturn(foldersConfig); @@ -77,7 +76,7 @@ void testSaveBlobDataUsingFilename() { } @Test - void testSaveBlobDataUsingBlobPathAndFilename() { + void saveBlobData_shouldSaveBlobUsingBlobPathAndFilename() { String blobPathAndFilename = TEST_DROP_ZONE + BLOB_FILENAME; when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); when(armDataManagementDao.getBlobClient(any(), any())).thenReturn(blobClient); @@ -87,7 +86,7 @@ void testSaveBlobDataUsingBlobPathAndFilename() { } @Test - void testListSubmissionBlobs() { + void listSubmissionBlobs_shouldListSubmissionBlobs() { PagedIterable pagedIterable = (PagedIterable) mock(PagedIterable.class); when(blobContainerClient.listBlobsByHierarchy(any(), any(), any())).thenReturn(pagedIterable); when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); @@ -104,7 +103,7 @@ void testListSubmissionBlobs() { } @Test - void testListResponseBlobs() { + void listResponseBlobs_shouldListResponseBlobs() { PagedIterable pagedIterable = (PagedIterable) mock(PagedIterable.class); when(blobContainerClient.listBlobsByHierarchy(any(), any(), any())).thenReturn(pagedIterable); when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); @@ -121,7 +120,7 @@ void testListResponseBlobs() { } @Test - void testGetBlobData() { + void getBlobData_shouldReturnBlob() { when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); when(armDataManagementDao.getBlobClient(any(), any())).thenReturn(blobClient); when(blobClient.exists()).thenReturn(Boolean.TRUE); @@ -146,7 +145,7 @@ void testDeleteResponseBlobIsSuccessful() { } @Test - void testDeleteResponseBlobIsNotSuccessful() { + void deleteResponseBlob_shouldReturnIsNotSuccessful_when500Error() { when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); when(armDataManagementDao.getBlobClient(any(), any())).thenReturn(blobClient); @@ -160,7 +159,7 @@ void testDeleteResponseBlobIsNotSuccessful() { } @Test - void testListSubmissionBlobsUsingBatch() { + void listSubmissionBlobsUsingBatch_shouldListSubmissionBlobsUsingBatch() { PagedIterable pagedIterable = (PagedIterable) mock(PagedIterable.class); when(blobContainerClient.listBlobs(any(), any())).thenReturn(pagedIterable); when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); @@ -178,7 +177,7 @@ void testListSubmissionBlobsUsingBatch() { } @Test - void testListResponseBlobsUsingBatch() { + void listResponseBlobsUsingBatch_shouldListResponseBlobsUsingBatch() { PagedIterable pagedIterable = (PagedIterable) mock(PagedIterable.class); when(blobContainerClient.listBlobs(any(), any())).thenReturn(pagedIterable); when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); @@ -296,7 +295,7 @@ void deleteMultipleBlobs_shouldReturnFalse_whenAzureThrowsException() { BlobBatchClient batchClient = mock(BlobBatchClient.class); when(batchClient.deleteBlobs(anyList(), eq(DeleteSnapshotsOptionType.INCLUDE), any(Duration.class), eq(null))) - .thenThrow(new AzureDeleteBlobException("Azure error")); + .thenThrow(new RuntimeException("Azure error")); try (var ignored = mockConstruction(BlobBatchClientBuilder.class, (builder, context) -> when(builder.buildClient()).thenReturn(batchClient))) { From 10f1ed77530d548922fc01fc9c409bca8ba971a5 Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Fri, 20 Mar 2026 10:24:12 +0000 Subject: [PATCH 06/10] DMP-5415 Interruption of deleting CR and UF files Added some tests --- .../gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java index faebe8bf822..2f1a89d72fe 100644 --- a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/ArmServiceImplTest.java @@ -131,7 +131,7 @@ void getBlobData_shouldReturnBlob() { } @Test - void testDeleteResponseBlobIsSuccessful() { + void deleteResponseBlob_shouldReturnIsSuccessful() { when(armDataManagementDao.getBlobContainerClient(ARM_BLOB_CONTAINER_NAME)).thenReturn(blobContainerClient); when(armDataManagementDao.getBlobClient(any(), any())).thenReturn(blobClient); @@ -304,5 +304,4 @@ void deleteMultipleBlobs_shouldReturnFalse_whenAzureThrowsException() { } } - } From 3e0b33babf610c187f0b312ad540accf93c801c4 Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:30:49 +0000 Subject: [PATCH 07/10] DMP-5415 Interruption of deleting CR and UF files Added some tests --- .../hmcts/darts/arm/ArmServiceFunctionalTest.java | 2 +- .../DataManagementServiceFunctionalTest.java | 3 --- .../impl/DeleteArmResponseFilesHelperIntTest.java | 11 +++++------ .../hmcts/darts/arm/api/ArmDataManagementApi.java | 2 ++ .../arm/api/impl/ArmDataManagementApiImpl.java | 6 ++++++ .../arm/service/DeleteArmResponseFilesHelper.java | 6 ++++-- .../impl/AbstractArmBatchProcessResponseFiles.java | 12 ++++++------ .../impl/DeleteArmResponseFilesHelperImpl.java | 14 +++++++++----- .../impl/DeleteArmResponseFilesHelperImplTest.java | 8 ++++---- 9 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java b/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java index 9b811a2cbed..573f689b42a 100644 --- a/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java +++ b/src/functionalTest/java/uk/gov/hmcts/darts/arm/ArmServiceFunctionalTest.java @@ -184,7 +184,7 @@ void saveAndDeleteMultipleBlobs() { assertNotNull(actualResult1); log.info("Blob filename1: {}", actualResult1); - String filename2 = String.format("%s_functional_test", UUID.randomUUID()); + String filename2 = String.format("%s_functional_test2", UUID.randomUUID()); String actualResult2 = armService.saveBlobData(armContainerName, filename2, data); armSubmissionBlobsToBeDeleted.add(actualResult2); assertNotNull(actualResult2); diff --git a/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java b/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java index 93bf276d108..d8ec5e0bfe4 100644 --- a/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java +++ b/src/functionalTest/java/uk/gov/hmcts/darts/datamanagement/DataManagementServiceFunctionalTest.java @@ -12,7 +12,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import uk.gov.hmcts.darts.FunctionalTest; -import uk.gov.hmcts.darts.arm.config.ArmDataManagementConfiguration; import uk.gov.hmcts.darts.common.datamanagement.component.impl.DownloadResponseMetaData; import uk.gov.hmcts.darts.common.datamanagement.enums.DatastoreContainerType; import uk.gov.hmcts.darts.common.exception.AzureDeleteBlobException; @@ -49,8 +48,6 @@ class DataManagementServiceFunctionalTest extends FunctionalTest { private DataManagementService dataManagementService; @Autowired private DataManagementConfiguration dataManagementConfiguration; - @Autowired - private ArmDataManagementConfiguration armDataManagementConfiguration; @Test void saveBinaryDataToBlobStorage() { diff --git a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java index d6815c3617f..1ab36980cc4 100644 --- a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java @@ -66,7 +66,7 @@ void setUp() { } @Test - void deleteResponseBlobsByManifestName_shouldDeleteBlobsWhenAllResponsesAreCompletedAndCleaned() { + void deleteResponseBlobsByManifestName_shouldDeleteBlobsIndividuallyWhenAllResponsesAreCompletedAndCleaned() { // given String manifestName = MANIFEST_PREFIX + ".a360"; eodRpoPending.setManifestFile(manifestName); @@ -107,13 +107,13 @@ void deleteDanglingResponses_shouldDeleteDanglingResponses() { } @Test - void deleteResponseBlobs_shouldDeleteAllResponseBlobs() { + void deleteResponseBlobsIndividually_shouldDeleteAllResponseBlobsIndividually() { // given List responseBlobs = List.of("blob1", "blob2"); when(armDataManagementApi.deleteBlobData(anyString())).thenReturn(true); // when - List result = deleteArmResponseFilesHelper.deleteResponseBlobs(responseBlobs); + List result = deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(responseBlobs); // then assertTrue(result.stream().allMatch(Boolean::booleanValue)); @@ -134,14 +134,13 @@ void deleteResponseBlobs_shouldUpdateEodWhenResponsesAreDeleted() { .uploadFileFilenameProcessor(new UploadFileFilenameProcessor(uploadFileFilename1)) .build(); - when(armDataManagementApi.deleteBlobData(anyString())).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(any())).thenReturn(true); // when deleteArmResponseFilesHelper.deleteResponseBlobs(batchData); // then - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); verifyNoMoreInteractions(armDataManagementApi); } diff --git a/src/main/java/uk/gov/hmcts/darts/arm/api/ArmDataManagementApi.java b/src/main/java/uk/gov/hmcts/darts/arm/api/ArmDataManagementApi.java index 7479db68dea..160da9c3882 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/api/ArmDataManagementApi.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/api/ArmDataManagementApi.java @@ -27,6 +27,8 @@ public interface ArmDataManagementApi extends BlobContainerDownloadable { boolean deleteBlobData(String blobPathAndName); + boolean deleteMultipleBlobs(List blobPathAndNames); + UpdateMetadataResponse updateMetadata(String externalRecordId, OffsetDateTime eventTimestamp, RetentionConfidenceScoreEnum retConfScore, diff --git a/src/main/java/uk/gov/hmcts/darts/arm/api/impl/ArmDataManagementApiImpl.java b/src/main/java/uk/gov/hmcts/darts/arm/api/impl/ArmDataManagementApiImpl.java index a101dba8b29..fdc3b9f6a0e 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/api/impl/ArmDataManagementApiImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/api/impl/ArmDataManagementApiImpl.java @@ -26,6 +26,7 @@ @Service @RequiredArgsConstructor +@SuppressWarnings({"PMD.TooManyMethods"}) public class ArmDataManagementApiImpl implements ArmDataManagementApi { private final ArmService armService; @@ -88,6 +89,11 @@ public boolean deleteBlobData(String blobPathAndName) { return armService.deleteBlobData(armDataManagementConfiguration.getContainerName(), blobPathAndName); } + @Override + public boolean deleteMultipleBlobs(List blobPathAndNames) { + return armService.deleteMultipleBlobs(armDataManagementConfiguration.getContainerName(), blobPathAndNames); + } + @Override public UpdateMetadataResponse updateMetadata(String externalRecordId, OffsetDateTime eventTimestamp, diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java b/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java index 3aaaa214793..66ce9332b7c 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java @@ -11,10 +11,12 @@ public interface DeleteArmResponseFilesHelper { void deleteDanglingResponses(BatchInputUploadFileFilenameProcessor batchUploadFileFilenameProcessor); - List deleteResponseBlobs(List responseBlobsToBeDeleted); + List deleteResponseBlobsIndividually(List responseBlobsToBeDeleted); + + Boolean deleteResponseBlobs(List responseBlobsToBeDeleted); void deleteResponseBlobs(ArmResponseBatchData armResponseBatchData); List getResponseBlobsToBeDeleted(ArmResponseBatchData armResponseBatchData); - + } diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java index 81ae2475106..423484ee706 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java @@ -575,7 +575,7 @@ private ArmResponseCreateRecord getResponseCreateRecordOrDelete(String createRec return objectMapper.readValue(createRecordBinary.toString(), ArmResponseCreateRecord.class); } catch (Exception e) { log.error("Unable to read ARM response create record file {} - About to delete ", createRecordFilenameAndPath, e); - deleteArmResponseFilesHelper.deleteResponseBlobs(List.of(createRecordFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(createRecordFilenameAndPath)); throw e; } } @@ -628,7 +628,7 @@ private ArmResponseUploadFileRecord getResponseUploadFileRecordOrDelete(String u return objectMapper.readValue(uploadFileBinary.toString(), ArmResponseUploadFileRecord.class); } catch (Exception e) { log.error("Unable to read ARM response upload file {} - About to delete ", uploadFileFilenameAndPath, e); - deleteArmResponseFilesHelper.deleteResponseBlobs(List.of(uploadFileFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(uploadFileFilenameAndPath)); throw e; } } @@ -759,7 +759,7 @@ private ResponseFilenames getArmResponseFilenames(List responseFiles, St } catch (IllegalArgumentException e) { // This occurs when the filename is not parsable log.error("Invalid ARM response filename: {} for manifest {}", responseFile, manifestName); - deleteArmResponseFilesHelper.deleteResponseBlobs(List.of(responseFile)); + deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(responseFile)); } } return responseFilenames; @@ -798,7 +798,7 @@ private void readInvalidLineFile(BinaryData invalidLineFileBinary, InvalidLineFi } else { log.warn("Failed to obtain EOD id (relation id) from invalid line record {} from file {}", input, invalidLineFileFilenameProcessor.getInvalidLineFilename()); - deleteArmResponseFilesHelper.deleteResponseBlobs(List.of(invalidLineFileFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(invalidLineFileFilenameAndPath)); } } catch (Exception e) { @@ -815,7 +815,7 @@ private ArmResponseInvalidLineRecord getResponseInvalidLineRecordOrDelete(String return objectMapper.readValue(invalidLineFileBinary.toString(), ArmResponseInvalidLineRecord.class); } catch (Exception e) { log.error("Unable to read ARM response {} - About to delete ", invalidLineFileFilenameAndPath, e); - deleteArmResponseFilesHelper.deleteResponseBlobs(List.of(invalidLineFileFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(invalidLineFileFilenameAndPath)); throw e; } } @@ -852,7 +852,7 @@ private void processInvalidLineFile(long externalObjectDirectoryId, InvalidLineF invalidLineFileFilenameProcessor.getInvalidLineFileFilenameAndPath(), armResponseFile); List invalidResponseFiles = getInvalidResponseFiles(invalidLineFileFilenameProcessor, armResponseFile); - deleteArmResponseFilesHelper.deleteResponseBlobs(invalidResponseFiles); + deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(invalidResponseFiles); } } catch (Exception e) { log.error("Unable to update invalid line responses", e); diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java index 9783b976b90..dc3920e2061 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java @@ -74,7 +74,7 @@ public void deleteDanglingResponses(BatchInputUploadFileFilenameProcessor batchU } if (CollectionUtils.isNotEmpty(responseFiles)) { - List deletedResponseBlobStatuses = deleteResponseBlobs(responseFiles); + List deletedResponseBlobStatuses = deleteResponseBlobsIndividually(responseFiles); if (deletedResponseBlobStatuses.contains(false)) { log.warn("Unable to delete dangling ARM batch input upload file {} as referenced data is not all deleted", @@ -90,14 +90,18 @@ public void deleteDanglingResponses(BatchInputUploadFileFilenameProcessor batchU } @Override - public List deleteResponseBlobs(List responseBlobsToBeDeleted) { + public List deleteResponseBlobsIndividually(List responseBlobsToBeDeleted) { return responseBlobsToBeDeleted.stream() .map(armDataManagementApi::deleteBlobData) .toList(); } @Override - @SuppressWarnings("PMD.CyclomaticComplexity") + public Boolean deleteResponseBlobs(List responseBlobsToBeDeleted) { + return armDataManagementApi.deleteMultipleBlobs(responseBlobsToBeDeleted); + } + + @Override public void deleteResponseBlobs(ArmResponseBatchData armResponseBatchData) { List responseBlobsToBeDeleted = getResponseBlobsToBeDeleted(armResponseBatchData); ExternalObjectDirectoryEntity externalObjectDirectory = getExternalObjectDirectory(armResponseBatchData.getExternalObjectDirectoryId()); @@ -109,9 +113,9 @@ public void deleteResponseBlobs(ArmResponseBatchData armResponseBatchData) { || ARM_RESPONSE_MANIFEST_FAILED.equals(status) || ARM_RESPONSE_CHECKSUM_VERIFICATION_FAILED.equals(status)) { log.info("About to delete ARM responses for EOD {}", externalObjectDirectory.getId()); - List deletedResponseBlobStatuses = deleteResponseBlobs(responseBlobsToBeDeleted); + boolean deletedResponseBlobStatuses = deleteResponseBlobs(responseBlobsToBeDeleted); - if (deletedResponseBlobStatuses.size() == 2 && !deletedResponseBlobStatuses.contains(false)) { + if (deletedResponseBlobStatuses) { externalObjectDirectory.setResponseCleaned(true); externalObjectDirectoryRepository.saveAndFlush(externalObjectDirectory); } else { diff --git a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java index 7dcf2899b98..9d068f00564 100644 --- a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java @@ -68,7 +68,7 @@ public static void close() { } @Test - void deleteResponseBlobsByManifestName_shouldDeleteBlobsWhenAllResponsesAreCompletedAndCleaned() { + void deleteResponseBlobsByManifestName_shouldDeleteBlobsIndividuallyWhenAllResponsesAreCompletedAndCleaned() { // given String manifestName = "DARTS_6a374f19a9ce7dc9cc480ea8d4eca0fb.a360"; eod.setStatus(EodHelper.armRpoPendingStatus()); @@ -108,21 +108,21 @@ void deleteDanglingResponses_shouldDeleteDanglingResponses() { } @Test - void deleteResponseBlobs_shouldDeleteAllResponseBlobs() { + void deleteResponseBlobs_shouldDeleteAllResponseBlobsIndividually() { // given List responseBlobs = List.of("blob1", "blob2"); when(armDataManagementApi.deleteBlobData("blob1")).thenReturn(true); when(armDataManagementApi.deleteBlobData("blob2")).thenReturn(true); // when - List result = deleteArmResponseFilesHelper.deleteResponseBlobs(responseBlobs); + List result = deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(responseBlobs); // then assertTrue(result.stream().allMatch(Boolean::booleanValue)); } @Test - void deleteResponseBlobs_shouldUpdateEodWhenResponsesAreDeleted() { + void deleteResponseBlobs_Individually_shouldUpdateEodWhenResponsesAreDeleted() { // given ArmResponseBatchData batchData = mock(ArmResponseBatchData.class); when(batchData.getExternalObjectDirectoryId()).thenReturn(1L); From e90baadacac6a75dc94ea0615361fc65e35e4c6f Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:38:40 +0000 Subject: [PATCH 08/10] DMP-5415 Interruption of deleting CR and UF files Added some tests --- .../service/impl/DeleteArmResponseFilesHelperIntTest.java | 4 ---- .../service/impl/DeleteArmResponseFilesHelperImplTest.java | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java index 1ab36980cc4..1722de135e0 100644 --- a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java @@ -6,7 +6,6 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; import uk.gov.hmcts.darts.arm.api.ArmDataManagementApi; import uk.gov.hmcts.darts.arm.model.blobs.ArmResponseBatchData; -import uk.gov.hmcts.darts.arm.service.ExternalObjectDirectoryService; import uk.gov.hmcts.darts.arm.util.files.BatchInputUploadFileFilenameProcessor; import uk.gov.hmcts.darts.arm.util.files.CreateRecordFilenameProcessor; import uk.gov.hmcts.darts.arm.util.files.UploadFileFilenameProcessor; @@ -45,9 +44,6 @@ class DeleteArmResponseFilesHelperIntTest extends PostgresIntegrationBase { @MockitoBean private UserIdentity userIdentity; - @Autowired - private ExternalObjectDirectoryService externalObjectDirectoryService; - @Autowired private DeleteArmResponseFilesHelperImpl deleteArmResponseFilesHelper; diff --git a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java index 9d068f00564..28f4d6f22d9 100644 --- a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java @@ -22,7 +22,7 @@ import java.util.Optional; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -122,7 +122,7 @@ void deleteResponseBlobs_shouldDeleteAllResponseBlobsIndividually() { } @Test - void deleteResponseBlobs_Individually_shouldUpdateEodWhenResponsesAreDeleted() { + void deleteResponseBlobs_shouldUpdateEodWhenResponsesAreDeleted() { // given ArmResponseBatchData batchData = mock(ArmResponseBatchData.class); when(batchData.getExternalObjectDirectoryId()).thenReturn(1L); @@ -130,7 +130,7 @@ void deleteResponseBlobs_Individually_shouldUpdateEodWhenResponsesAreDeleted() { eod.setStatus(EodHelper.armResponseChecksumVerificationFailedStatus()); - when(armDataManagementApi.deleteBlobData(anyString())).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(anyList())).thenReturn(true); when(batchData.getCreateRecordFilenameProcessor()).thenReturn(createRecordFilenameProcessor); when(batchData.getUploadFileFilenameProcessor()).thenReturn(uploadFileFilenameProcessor); when(batchData.getInvalidLineFileFilenameProcessors()).thenReturn(Collections.emptyList()); From 1d3dd7306bb03ee921d44d9ad9f2b442c8b6ac72 Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Sun, 22 Mar 2026 21:53:05 +0000 Subject: [PATCH 09/10] DMP-5415 Interruption of deleting CR and UF files Added some tests --- ...ctArmBatchProcessResponseFilesIntTest.java | 179 ++++++------------ .../DeleteArmResponseFilesHelperIntTest.java | 23 ++- .../service/DeleteArmResponseFilesHelper.java | 2 +- .../AbstractArmBatchProcessResponseFiles.java | 12 +- .../DeleteArmResponseFilesHelperImpl.java | 16 +- .../DeleteArmResponseFilesHelperImplTest.java | 15 +- 6 files changed, 90 insertions(+), 157 deletions(-) diff --git a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java index 76bcdc36ae1..9fefcaa9dbb 100644 --- a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java @@ -240,12 +240,12 @@ void batchProcessResponseFiles_WithMediaReturnsSuccess() throws IOException { String uploadFileFilename3 = String.format("%s_04e6bc3b-952a-79b6-8362-13259aae1897_1_uf.rsp", hashcode1); String invalidLineFileFilename3 = String.format("%s_a17b9015-e6ad-77c5-8d1e-13259aae1897_0_il.rsp", hashcode1); String invalidLineFileFilename4 = String.format("%s_a17b9015-e6ad-77c5-8d1e-13259aae1892_0_il.rsp", hashcode1); - String invalidLineFileFilename5 = String.format("%s_a17b9015-e6ad-77c5-8d1e-13259aae1893_0_il.rsp", hashcode1); + String invalidLineFileFilename4b = String.format("%s_a17b9015-e6ad-77c5-8d1e-13259aae1893_0_il.rsp", hashcode1); List hashcodeResponses = List.of(createRecordFilename1, uploadFileFilename1, createRecordFilename2, invalidLineFileFilename2, uploadFileFilename3, invalidLineFileFilename3, - invalidLineFileFilename4, invalidLineFileFilename5); + invalidLineFileFilename4, invalidLineFileFilename4b); when(armDataManagementApi.listResponseBlobs(hashcode1)).thenReturn(hashcodeResponses); @@ -256,7 +256,7 @@ void batchProcessResponseFiles_WithMediaReturnsSuccess() throws IOException { String validUploadFileTest3 = "tests/arm/service/ArmBatchResponseFilesProcessorTest/ValidResponses/UploadFile.rsp"; String invalidLineFileTest3 = "tests/arm/service/ArmBatchResponseFilesProcessorTest/ValidResponses/InvalidLineFile.rsp"; String invalidLineFileTest4 = "tests/arm/service/ArmBatchResponseFilesProcessorTest/ValidResponses/InvalidLineFile.rsp"; - String invalidLineFileTest5 = "tests/arm/service/ArmBatchResponseFilesProcessorTest/ValidResponses/InvalidLineFile2.rsp"; + String invalidLineFileTest4b = "tests/arm/service/ArmBatchResponseFilesProcessorTest/ValidResponses/InvalidLineFile2.rsp"; BinaryData createRecordBinaryDataTest1 = convertStringToBinaryData(getCreateRecordFileContents(createRecordFileTest1, armEod1.getId())); BinaryData uploadFileBinaryDataTest1 = convertStringToBinaryData(getUploadFileContents(validUploadFileTest1, armEod1.getId(), media1.getChecksum())); @@ -265,7 +265,7 @@ void batchProcessResponseFiles_WithMediaReturnsSuccess() throws IOException { BinaryData uploadFileBinaryDataTest3 = convertStringToBinaryData(getUploadFileContents(validUploadFileTest3, armEod3.getId(), media3.getChecksum())); BinaryData invalidLineFileBinaryDataTest3 = convertStringToBinaryData(getInvalidLineFileContents(invalidLineFileTest3, armEod3.getId())); BinaryData invalidLineFileBinaryDataTest4 = convertStringToBinaryData(getInvalidLineFileContents(invalidLineFileTest4, armEod4.getId())); - BinaryData invalidLineFileBinaryDataTest5 = convertStringToBinaryData(getInvalidLineFileContents(invalidLineFileTest5, armEod4.getId())); + BinaryData invalidLineFileBinaryDataTest4b = convertStringToBinaryData(getInvalidLineFileContents(invalidLineFileTest4b, armEod4.getId())); when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); @@ -274,16 +274,7 @@ void batchProcessResponseFiles_WithMediaReturnsSuccess() throws IOException { when(armDataManagementApi.getBlobData(uploadFileFilename3)).thenReturn(uploadFileBinaryDataTest3); when(armDataManagementApi.getBlobData(invalidLineFileFilename3)).thenReturn(invalidLineFileBinaryDataTest3); when(armDataManagementApi.getBlobData(invalidLineFileFilename4)).thenReturn(invalidLineFileBinaryDataTest4); - when(armDataManagementApi.getBlobData(invalidLineFileFilename5)).thenReturn(invalidLineFileBinaryDataTest5); - - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename4)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename5)).thenReturn(true); + when(armDataManagementApi.getBlobData(invalidLineFileFilename4b)).thenReturn(invalidLineFileBinaryDataTest4b); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(endTime2); @@ -294,7 +285,7 @@ void batchProcessResponseFiles_WithMediaReturnsSuccess() throws IOException { when(armDataManagementApi.getBlobData(uploadFileFilename3)).thenReturn(uploadFileBinaryDataTest3); when(armDataManagementApi.getBlobData(invalidLineFileFilename3)).thenReturn(invalidLineFileBinaryDataTest3); when(armDataManagementApi.getBlobData(invalidLineFileFilename4)).thenReturn(invalidLineFileBinaryDataTest4); - when(armDataManagementApi.getBlobData(invalidLineFileFilename5)).thenReturn(invalidLineFileBinaryDataTest5); + when(armDataManagementApi.getBlobData(invalidLineFileFilename4b)).thenReturn(invalidLineFileBinaryDataTest4b); String hashcode2 = "7a374f19a9ce7dc9cc480ea8d4eca0fc"; String createRecordFilename5 = String.format("dropzone/DARTS/response/%s_a17b9015-e6ad-77c5-8d1e-13259aae1890_1_cr.rsp", hashcode2); @@ -304,17 +295,10 @@ void batchProcessResponseFiles_WithMediaReturnsSuccess() throws IOException { BinaryData createRecordBinaryDataTest5 = convertStringToBinaryData(getCreateRecordFileContents(createRecordFileTest5, armEod5.getId())); when(armDataManagementApi.getBlobData(createRecordFilename5)).thenReturn(createRecordBinaryDataTest5); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(blobNameAndPath1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename4)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename5)).thenReturn(true); - - when(armDataManagementApi.deleteBlobData(createRecordFilename5)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(invalidLineFileFilename4, invalidLineFileFilename4b))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(endTime2); @@ -395,22 +379,16 @@ void batchProcessResponseFiles_WithMediaReturnsSuccess() throws IOException { verify(armDataManagementApi).getBlobData(invalidLineFileFilename2); verify(armDataManagementApi).getBlobData(invalidLineFileFilename3); - verify(armDataManagementApi).deleteBlobData(createRecordFilename2); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename2); - - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); - - verify(armDataManagementApi).deleteBlobData(uploadFileFilename3); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename3); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2)); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); verify(armDataManagementApi).listResponseBlobs(hashcode2); verify(armDataManagementApi).getBlobData(createRecordFilename5); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename4); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename5); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(invalidLineFileFilename4, invalidLineFileFilename4b)); verify(armDataManagementApi, never()).deleteBlobData(blobNameAndPath2); } @@ -464,8 +442,7 @@ void batchProcessResponseFiles_WithInvalidLineFileAndCreateRecordFileSuccess() t when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(invalidLineFileFilename2)).thenReturn(invalidLineFileBinaryDataTest2); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, invalidLineFileFilename2))).thenReturn(true); // when armBatchProcessResponseFiles.processResponseFiles(BATCH_SIZE, asyncTaskConfig); @@ -488,8 +465,7 @@ void batchProcessResponseFiles_WithInvalidLineFileAndCreateRecordFileSuccess() t verify(armDataManagementApi).getBlobData(invalidLineFileFilename2); verify(armDataManagementApi).getBlobData(blobNameAndPath1); - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename2); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, invalidLineFileFilename2)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); verifyNoMoreInteractions(armDataManagementApi); @@ -558,8 +534,7 @@ void batchProcessResponseFiles_successful_withUploadFileAndCreateRecordFile() th when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); // when armBatchProcessResponseFiles.processResponseFiles(BATCH_SIZE, asyncTaskConfig); @@ -582,8 +557,7 @@ void batchProcessResponseFiles_successful_withUploadFileAndCreateRecordFile() th verify(armDataManagementApi).getBlobData(uploadFileFilename1); verify(armDataManagementApi).getBlobData(blobNameAndPath1); - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); verifyNoMoreInteractions(armDataManagementApi); @@ -642,8 +616,7 @@ void batchProcessResponseFiles_throwsException_whenUploadFileIsInvalid() throws when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); // when armBatchProcessResponseFiles.processResponseFiles(BATCH_SIZE, asyncTaskConfig); @@ -664,8 +637,7 @@ void batchProcessResponseFiles_throwsException_whenUploadFileIsInvalid() throws verify(armDataManagementApi).getBlobData(blobNameAndPath1); - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); verifyNoMoreInteractions(armDataManagementApi); @@ -725,18 +697,12 @@ void batchProcessResponseFiles_With3InvalidLineFilesCausingFailure() throws IOEx when(armDataManagementApi.getBlobData(invalidLineFileFilename2)).thenReturn(invalidLineFileBinaryDataTest2); when(armDataManagementApi.getBlobData(invalidLineFileFilename3)).thenReturn(invalidLineFileBinaryDataTest3); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(invalidLineFileFilename1, invalidLineFileFilename2, invalidLineFileFilename3))).thenReturn(true); when(armDataManagementApi.getBlobData(invalidLineFileFilename1)).thenReturn(invalidLineFileBinaryDataTest1); when(armDataManagementApi.getBlobData(invalidLineFileFilename2)).thenReturn(invalidLineFileBinaryDataTest2); when(armDataManagementApi.getBlobData(invalidLineFileFilename3)).thenReturn(invalidLineFileBinaryDataTest3); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); - // when armBatchProcessResponseFiles.processResponseFiles(BATCH_SIZE, asyncTaskConfig); @@ -757,9 +723,7 @@ void batchProcessResponseFiles_With3InvalidLineFilesCausingFailure() throws IOEx verify(armDataManagementApi).getBlobData(invalidLineFileFilename2); verify(armDataManagementApi).getBlobData(invalidLineFileFilename3); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename1); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename2); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename3); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(invalidLineFileFilename1, invalidLineFileFilename2, invalidLineFileFilename3)); verify(armDataManagementApi).getBlobData(blobNameAndPath1); @@ -879,12 +843,9 @@ void batchProcessResponseFiles_WithMediaUsingSmallContinuationTokenReturnsSucces BinaryData createRecordBinaryDataTest5 = convertStringToBinaryData(getCreateRecordFileContents(createRecordFileTest5, armEod5.getId())); when(armDataManagementApi.getBlobData(createRecordFilename5)).thenReturn(createRecordBinaryDataTest5); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3))).thenReturn(true); when(armDataManagementApi.deleteBlobData(blobNameAndPath1)).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(endTime2); @@ -948,14 +909,9 @@ void batchProcessResponseFiles_WithMediaUsingSmallContinuationTokenReturnsSucces verify(armDataManagementApi).getBlobData(invalidLineFileFilename2); verify(armDataManagementApi).getBlobData(invalidLineFileFilename3); - verify(armDataManagementApi).deleteBlobData(createRecordFilename2); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename2); - - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); - - verify(armDataManagementApi).deleteBlobData(uploadFileFilename3); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename3); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2)); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); @@ -1077,12 +1033,9 @@ void batchProcessResponseFiles_GetBlobsThrowsException() throws IOException { BinaryData createRecordBinaryDataTest4 = convertStringToBinaryData(getCreateRecordFileContents(createRecordFileTest4, armEod4.getId())); when(armDataManagementApi.getBlobData(createRecordFilename4)).thenReturn(createRecordBinaryDataTest4); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(endTime2); @@ -1265,12 +1218,9 @@ void batchProcessResponseFiles_WithInvalidJson() throws IOException { BinaryData createRecordBinaryDataTest4 = convertStringToBinaryData(getCreateRecordFileContents(createRecordFileTest4, armEod4.getId())); when(armDataManagementApi.getBlobData(createRecordFilename4)).thenReturn(createRecordBinaryDataTest4); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(endTime2); @@ -1392,10 +1342,8 @@ void batchProcessResponseFiles_WithInvalidFilenameStatus() throws IOException { when(armDataManagementApi.getBlobData(createRecordFilename2)).thenReturn(createRecordBinaryDataTest2); when(armDataManagementApi.getBlobData(invalidLineFileFilename2)).thenReturn(invalidLineFileBinaryDataTest2); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(endTime); @@ -1497,8 +1445,7 @@ void batchProcessResponseFiles_WithInvalidTranscriptionChecksum() throws IOExcep when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(transcriptionEntity.getEndTime()); @@ -1568,8 +1515,7 @@ void batchProcessResponseFiles_WithAnnotationReturnsSuccess() throws IOException when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(annotationDocument.getUploadedDateTime()); @@ -1590,9 +1536,7 @@ void batchProcessResponseFiles_WithAnnotationReturnsSuccess() throws IOException verify(armDataManagementApi).getBlobData(createRecordFilename1); verify(armDataManagementApi).getBlobData(uploadFileFilename1); - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); - + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); } @@ -1664,8 +1608,7 @@ void batchProcessResponseFiles_WithCaseDocumentReturnsSuccess() throws IOExcepti when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(caseDocument.getCreatedDateTime()); @@ -1686,8 +1629,7 @@ void batchProcessResponseFiles_WithCaseDocumentReturnsSuccess() throws IOExcepti verify(armDataManagementApi).getBlobData(createRecordFilename1); verify(armDataManagementApi).getBlobData(uploadFileFilename1); - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); } @@ -1767,8 +1709,7 @@ void batchProcessResponseFiles_WithCaseDocumentInvalidResponseFilenames() throws when(armDataManagementApi.getBlobData(uploadFileFilename3)).thenReturn(uploadFileBinaryDataTest3); when(armDataManagementApi.getBlobData(invalidLineFileFilename3)).thenReturn(invalidLineFileBinaryDataTest3); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(caseDocument.getCreatedDateTime()); @@ -1845,8 +1786,15 @@ void batchProcessResponseFiles_WithCaseDocumentInvalidResponseFilenamesNoEod() t when(armDataManagementApi.getBlobData(uploadFileFilename3)).thenReturn(uploadFileBinaryDataTest3); when(armDataManagementApi.getBlobData(invalidLineFileFilename3)).thenReturn(invalidLineFileBinaryDataTest3); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3))).thenReturn(true); + + // When no EOD exists for a response file, the code treats it as a dangling response and deletes it individually. + when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); + when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); + when(armDataManagementApi.deleteBlobData(uploadFileFilename3)).thenReturn(true); + when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(caseDocument.getCreatedDateTime()); @@ -1869,7 +1817,6 @@ void batchProcessResponseFiles_WithCaseDocumentInvalidResponseFilenamesNoEod() t verify(armDataManagementApi).deleteBlobData(createRecordFilename2); verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename2); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename3); verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename3); @@ -1930,8 +1877,7 @@ void batchProcessResponseFiles_WithResponseAsInvalidManifestFile() throws IOExce when(armDataManagementApi.getBlobData(createRecordFilename2)).thenReturn(createRecordBinaryDataTest2); when(armDataManagementApi.getBlobData(invalidLineFileFilename2)).thenReturn(invalidLineFileBinaryDataTest2); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, invalidLineFileFilename2))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(caseDocument.getCreatedDateTime()); @@ -1999,8 +1945,7 @@ void batchProcessResponseFiles_WithErrorCodeInResponse() throws IOException { when(armDataManagementApi.getBlobData(createRecordFilename2)).thenReturn(createRecordBinaryDataTest2); when(armDataManagementApi.getBlobData(uploadFileFileFilename2)).thenReturn(uploadFileBinaryDataTest2); - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFileFilename2)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename2, uploadFileFileFilename2))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(caseDocument.getCreatedDateTime()); @@ -2158,8 +2103,7 @@ void batchProcessResponseFiles_WithNullTranscriptionChecksum() throws IOExceptio when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(transcriptionEntity.getEndTime()); @@ -2229,8 +2173,7 @@ void batchProcessResponseFiles_WithNullAnnotationChecksum() throws IOException { when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(annotationDocument.getUploadedDateTime()); @@ -2293,8 +2236,7 @@ void batchProcessResponseFiles_WithAnnotationNoEodFound() throws IOException { when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(armDataManagementApi.deleteBlobData(blobNameAndPath1)).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(annotationDocument.getUploadedDateTime()); @@ -2312,8 +2254,7 @@ void batchProcessResponseFiles_WithAnnotationNoEodFound() throws IOException { verify(armDataManagementApi).getBlobData(createRecordFilename1); verify(armDataManagementApi).getBlobData(uploadFileFilename1); - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); } @@ -2434,8 +2375,7 @@ private void batchProcessResponseFiles_WithTranscriptionReturnsSuccess(String te when(armDataManagementApi.getBlobData(createRecordFilename1)).thenReturn(createRecordBinaryDataTest1); when(armDataManagementApi.getBlobData(uploadFileFilename1)).thenReturn(uploadFileBinaryDataTest1); - when(armDataManagementApi.deleteBlobData(createRecordFilename1)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename1)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(transcriptionEntity.getEndTime()); @@ -2456,8 +2396,7 @@ private void batchProcessResponseFiles_WithTranscriptionReturnsSuccess(String te verify(armDataManagementApi).getBlobData(createRecordFilename1); verify(armDataManagementApi).getBlobData(uploadFileFilename1); - verify(armDataManagementApi).deleteBlobData(createRecordFilename1); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename1); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(createRecordFilename1, uploadFileFilename1)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); } diff --git a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java index 1722de135e0..c5bff83278c 100644 --- a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperIntTest.java @@ -13,7 +13,6 @@ import uk.gov.hmcts.darts.common.entity.ExternalObjectDirectoryEntity; import uk.gov.hmcts.darts.common.entity.MediaEntity; import uk.gov.hmcts.darts.common.entity.UserAccountEntity; -import uk.gov.hmcts.darts.common.repository.ExternalObjectDirectoryRepository; import uk.gov.hmcts.darts.testutils.PostgresIntegrationBase; import java.util.List; @@ -35,9 +34,6 @@ class DeleteArmResponseFilesHelperIntTest extends PostgresIntegrationBase { private static final String MANIFEST_PREFIX = "DARTS_6a374f19a9ce7dc9cc480ea8d4eca0fb"; private static final String RESPONSE_FILE_PREFIX = "04e6bc3b-952a-79b6-8362-13259aae1895"; - @Autowired - private ExternalObjectDirectoryRepository externalObjectDirectoryRepository; - @MockitoBean private ArmDataManagementApi armDataManagementApi; @@ -88,33 +84,36 @@ void deleteResponseBlobsByManifestName_shouldDeleteBlobsIndividuallyWhenAllRespo void deleteDanglingResponses_shouldDeleteDanglingResponses() { // given BatchInputUploadFileFilenameProcessor batchInputUploadFileFilenameProcessor = new BatchInputUploadFileFilenameProcessor(DARTS_INPUT_UPLOAD_FILE); - String responseFile = "dropzone/DARTS/response/" + RESPONSE_FILE_PREFIX + "_ABC_1_rsp"; - when(armDataManagementApi.listResponseBlobs(any())).thenReturn(List.of(responseFile)); + String otherResponseFile = "dropzone/DARTS/response/" + RESPONSE_FILE_PREFIX + "_ABC_1_rsp"; + String crResponseFile = "dropzone/DARTS/response/" + RESPONSE_FILE_PREFIX + "_b17b9015-e6ad-77c5-8d1e-13259aae1896_0_cr.rsp"; + String ilResponseFile = "dropzone/DARTS/response/" + RESPONSE_FILE_PREFIX + "_c17b9015-e6ad-77c5-8d1e-13259aae1896_1_il.rsp"; + + when(armDataManagementApi.listResponseBlobs(any())).thenReturn(List.of(otherResponseFile, crResponseFile, ilResponseFile)); + when(armDataManagementApi.deleteMultipleBlobs(any())).thenReturn(true); when(armDataManagementApi.deleteBlobData(anyString())).thenReturn(true); // when deleteArmResponseFilesHelper.deleteDanglingResponses(batchInputUploadFileFilenameProcessor); // then - verify(armDataManagementApi).deleteBlobData(responseFile); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(otherResponseFile, crResponseFile, ilResponseFile)); verify(armDataManagementApi).deleteBlobData(DARTS_INPUT_UPLOAD_FILE); verify(armDataManagementApi).listResponseBlobs(batchInputUploadFileFilenameProcessor.getHashcode()); verifyNoMoreInteractions(armDataManagementApi); } @Test - void deleteResponseBlobsIndividually_shouldDeleteAllResponseBlobsIndividually() { + void deleteResponseBlobsIndividually_shouldDeleteAllResponseBlobIndividually() { // given - List responseBlobs = List.of("blob1", "blob2"); + String responseBlob = "blob1"; when(armDataManagementApi.deleteBlobData(anyString())).thenReturn(true); // when - List result = deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(responseBlobs); + Boolean result = deleteArmResponseFilesHelper.deleteResponseBlobIndividually(responseBlob); // then - assertTrue(result.stream().allMatch(Boolean::booleanValue)); + assertTrue(result); verify(armDataManagementApi).deleteBlobData("blob1"); - verify(armDataManagementApi).deleteBlobData("blob2"); verifyNoMoreInteractions(armDataManagementApi); } diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java b/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java index 66ce9332b7c..e1b5b14695d 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/DeleteArmResponseFilesHelper.java @@ -11,7 +11,7 @@ public interface DeleteArmResponseFilesHelper { void deleteDanglingResponses(BatchInputUploadFileFilenameProcessor batchUploadFileFilenameProcessor); - List deleteResponseBlobsIndividually(List responseBlobsToBeDeleted); + Boolean deleteResponseBlobIndividually(String responseBlobsToBeDeleted); Boolean deleteResponseBlobs(List responseBlobsToBeDeleted); diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java index 423484ee706..f98382cd811 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFiles.java @@ -575,7 +575,7 @@ private ArmResponseCreateRecord getResponseCreateRecordOrDelete(String createRec return objectMapper.readValue(createRecordBinary.toString(), ArmResponseCreateRecord.class); } catch (Exception e) { log.error("Unable to read ARM response create record file {} - About to delete ", createRecordFilenameAndPath, e); - deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(createRecordFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobIndividually(createRecordFilenameAndPath); throw e; } } @@ -628,7 +628,7 @@ private ArmResponseUploadFileRecord getResponseUploadFileRecordOrDelete(String u return objectMapper.readValue(uploadFileBinary.toString(), ArmResponseUploadFileRecord.class); } catch (Exception e) { log.error("Unable to read ARM response upload file {} - About to delete ", uploadFileFilenameAndPath, e); - deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(uploadFileFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobIndividually(uploadFileFilenameAndPath); throw e; } } @@ -759,7 +759,7 @@ private ResponseFilenames getArmResponseFilenames(List responseFiles, St } catch (IllegalArgumentException e) { // This occurs when the filename is not parsable log.error("Invalid ARM response filename: {} for manifest {}", responseFile, manifestName); - deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(responseFile)); + deleteArmResponseFilesHelper.deleteResponseBlobIndividually(responseFile); } } return responseFilenames; @@ -798,7 +798,7 @@ private void readInvalidLineFile(BinaryData invalidLineFileBinary, InvalidLineFi } else { log.warn("Failed to obtain EOD id (relation id) from invalid line record {} from file {}", input, invalidLineFileFilenameProcessor.getInvalidLineFilename()); - deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(invalidLineFileFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobIndividually(invalidLineFileFilenameAndPath); } } catch (Exception e) { @@ -815,7 +815,7 @@ private ArmResponseInvalidLineRecord getResponseInvalidLineRecordOrDelete(String return objectMapper.readValue(invalidLineFileBinary.toString(), ArmResponseInvalidLineRecord.class); } catch (Exception e) { log.error("Unable to read ARM response {} - About to delete ", invalidLineFileFilenameAndPath, e); - deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(List.of(invalidLineFileFilenameAndPath)); + deleteArmResponseFilesHelper.deleteResponseBlobIndividually(invalidLineFileFilenameAndPath); throw e; } } @@ -852,7 +852,7 @@ private void processInvalidLineFile(long externalObjectDirectoryId, InvalidLineF invalidLineFileFilenameProcessor.getInvalidLineFileFilenameAndPath(), armResponseFile); List invalidResponseFiles = getInvalidResponseFiles(invalidLineFileFilenameProcessor, armResponseFile); - deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(invalidResponseFiles); + deleteArmResponseFilesHelper.deleteResponseBlobs(invalidResponseFiles); } } catch (Exception e) { log.error("Unable to update invalid line responses", e); diff --git a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java index dc3920e2061..4ce35322536 100644 --- a/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImpl.java @@ -74,14 +74,14 @@ public void deleteDanglingResponses(BatchInputUploadFileFilenameProcessor batchU } if (CollectionUtils.isNotEmpty(responseFiles)) { - List deletedResponseBlobStatuses = deleteResponseBlobsIndividually(responseFiles); + boolean deletedResponseBlobStatuses = deleteResponseBlobs(responseFiles); - if (deletedResponseBlobStatuses.contains(false)) { - log.warn("Unable to delete dangling ARM batch input upload file {} as referenced data is not all deleted", - batchUploadFileFilenameProcessor.getBatchMetadataFilename()); - } else { + if (deletedResponseBlobStatuses) { log.info("About to delete dangling ARM input upload file {}", batchUploadFileFilenameProcessor.getBatchMetadataFilename()); armDataManagementApi.deleteBlobData(batchUploadFileFilenameProcessor.getBatchMetadataFilenameAndPath()); + } else { + log.warn("Unable to delete dangling ARM batch input upload file {} as referenced data is not all deleted", + batchUploadFileFilenameProcessor.getBatchMetadataFilename()); } } else { log.info("Unable to delete dangling ARM input upload file {}", batchUploadFileFilenameProcessor.getBatchMetadataFilename()); @@ -90,10 +90,8 @@ public void deleteDanglingResponses(BatchInputUploadFileFilenameProcessor batchU } @Override - public List deleteResponseBlobsIndividually(List responseBlobsToBeDeleted) { - return responseBlobsToBeDeleted.stream() - .map(armDataManagementApi::deleteBlobData) - .toList(); + public Boolean deleteResponseBlobIndividually(String responseBlobToBeDeleted) { + return armDataManagementApi.deleteBlobData(responseBlobToBeDeleted); } @Override diff --git a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java index 28f4d6f22d9..5252ee92af6 100644 --- a/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/arm/service/impl/DeleteArmResponseFilesHelperImplTest.java @@ -45,7 +45,6 @@ class DeleteArmResponseFilesHelperImplTest { private ExternalObjectDirectoryEntity eod; - private DeleteArmResponseFilesHelperImpl deleteArmResponseFilesHelper; @BeforeEach @@ -95,7 +94,7 @@ void deleteDanglingResponses_shouldDeleteDanglingResponses() { BatchInputUploadFileFilenameProcessor processor = mock(BatchInputUploadFileFilenameProcessor.class); when(processor.getHashcode()).thenReturn("testHashcode"); when(armDataManagementApi.listResponseBlobs("testHashcode")).thenReturn(List.of("responseBlob")); - when(armDataManagementApi.deleteBlobData("responseBlob")).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of("responseBlob"))).thenReturn(true); when(processor.getBatchMetadataFilename()).thenReturn("testFile"); when(processor.getBatchMetadataFilenameAndPath()).thenReturn("testFilePath"); @@ -103,22 +102,20 @@ void deleteDanglingResponses_shouldDeleteDanglingResponses() { deleteArmResponseFilesHelper.deleteDanglingResponses(processor); // then - verify(armDataManagementApi).deleteBlobData("responseBlob"); - verify(armDataManagementApi).deleteBlobData("testFilePath"); + verify(armDataManagementApi).deleteMultipleBlobs(List.of("responseBlob")); } @Test - void deleteResponseBlobs_shouldDeleteAllResponseBlobsIndividually() { + void deleteResponseBlob_shouldDeletResponseBlob() { // given - List responseBlobs = List.of("blob1", "blob2"); + String responseBlob = "blob1"; when(armDataManagementApi.deleteBlobData("blob1")).thenReturn(true); - when(armDataManagementApi.deleteBlobData("blob2")).thenReturn(true); // when - List result = deleteArmResponseFilesHelper.deleteResponseBlobsIndividually(responseBlobs); + Boolean result = deleteArmResponseFilesHelper.deleteResponseBlobIndividually(responseBlob); // then - assertTrue(result.stream().allMatch(Boolean::booleanValue)); + assertTrue(result); } @Test From 98c64c30b8c4eaa5371d3319afd87bc125938aed Mon Sep 17 00:00:00 2001 From: karen-hedges <133129444+karen-hedges@users.noreply.github.com> Date: Sun, 22 Mar 2026 22:41:58 +0000 Subject: [PATCH 10/10] DMP-5415 Interruption of deleting CR and UF files Added some tests --- .../AbstractArmBatchProcessResponseFilesIntTest.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java index 9fefcaa9dbb..b1838dda65c 100644 --- a/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/darts/arm/service/impl/AbstractArmBatchProcessResponseFilesIntTest.java @@ -1791,10 +1791,8 @@ void batchProcessResponseFiles_WithCaseDocumentInvalidResponseFilenamesNoEod() t when(armDataManagementApi.deleteMultipleBlobs(List.of(uploadFileFilename3, invalidLineFileFilename3))).thenReturn(true); // When no EOD exists for a response file, the code treats it as a dangling response and deletes it individually. - when(armDataManagementApi.deleteBlobData(createRecordFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename2)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(uploadFileFilename3)).thenReturn(true); - when(armDataManagementApi.deleteBlobData(invalidLineFileFilename3)).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(invalidLineFileFilename2, createRecordFilename2))).thenReturn(true); + when(armDataManagementApi.deleteMultipleBlobs(List.of(invalidLineFileFilename3, uploadFileFilename3))).thenReturn(true); when(currentTimeHelper.currentOffsetDateTime()).thenReturn(caseDocument.getCreatedDateTime()); @@ -1815,10 +1813,8 @@ void batchProcessResponseFiles_WithCaseDocumentInvalidResponseFilenamesNoEod() t verify(armDataManagementApi).getBlobData(uploadFileFilename3); verify(armDataManagementApi).getBlobData(invalidLineFileFilename3); - verify(armDataManagementApi).deleteBlobData(createRecordFilename2); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename2); - verify(armDataManagementApi).deleteBlobData(uploadFileFilename3); - verify(armDataManagementApi).deleteBlobData(invalidLineFileFilename3); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(invalidLineFileFilename2, createRecordFilename2)); + verify(armDataManagementApi).deleteMultipleBlobs(List.of(invalidLineFileFilename3, uploadFileFilename3)); verify(armDataManagementApi).deleteBlobData(blobNameAndPath1); }