diff --git a/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java b/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java index 54523201fd281dea6af56fdf32489b5e0ead3316..9860796131f316f3e145390f8c1b0de0f0d057b4 100644 --- a/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java +++ b/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java @@ -382,15 +382,6 @@ class FormDataEndpointITCase { assertThat(file.getContent().size()).isZero(); } - @Test - void checkForAttachmentFileContentStream() { - sendRequest(); - - var fileStream = formDataCaptor.getValue().getAttachments().get(0).getFiles().get(0).getContentStream(); - - assertThat(fileStream).isNotNull(); - } - @Test void checkAttachmentGroup2Count() { sendRequest(); @@ -437,14 +428,6 @@ class FormDataEndpointITCase { assertThat(file.getContent().size()).isZero(); } - @Test - void checkForRepresentationFileContentStream() { - sendRequest(); - - var fileStream = formDataCaptor.getValue().getRepresentations().get(0).getContentStream(); - - assertThat(fileStream).isNotNull(); - } } @DisplayName("service konto") diff --git a/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java b/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java index 5d1293168a6770fd9a8afa0e863afd08cd4750ca..260cdc3818a4af61e2f93d632a66afb75a31062f 100644 --- a/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java +++ b/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java @@ -159,7 +159,7 @@ public class VorgangRemoteService { } String uploadIncomingFile(IncomingFile incomingFile) { - var fileContentStream = incomingFile.getContentStreamForFinalRead(); + var fileContentStream = incomingFile.getContentStream(); var resultFuture = GrpcFileUploadUtils.createSender(this::buildChunkRequest, fileContentStream, this::buildCallStreamObserver) diff --git a/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java b/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java index 22abba8cb58224ab8a14a838630ed6698c096137..a5ae891ce8936a906686b30057301f893e3da193 100644 --- a/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java +++ b/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java @@ -23,25 +23,64 @@ */ package de.ozgcloud.eingang.router; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; import org.springframework.stereotype.Service; import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.FormHeader; +import de.ozgcloud.eingang.common.formdata.IncomingFile; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; import de.ozgcloud.eingang.common.formdata.ServiceKonto; import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle; import lombok.AllArgsConstructor; +import lombok.extern.log4j.Log4j2; @AllArgsConstructor @Service +@Log4j2 public class VorgangService { private final VorgangRemoteService remoteService; public String createVorgang(FormData formData) { - return createVorgangForOrganisationsEinheitIds(getOrganisationsEinheitIds(formData), preserveConsistency(formData)); + var vorgangId = createVorgangForOrganisationsEinheitIds(getOrganisationsEinheitIds(formData), preserveConsistency(formData)); + cleanupFormDataFiles(formData); + return vorgangId; + } + + void cleanupFormDataFiles(FormData formData) { + getFormDataFiles(formData) + .map(IncomingFile::getFile) + .map(File::toPath) + .forEach(this::deleteIncomingFile); + } + + void deleteIncomingFile(Path path) { + try { + Files.deleteIfExists(path); + } catch (IOException e) { + logErrorOnDeleteFailure(e); + } + } + + void logErrorOnDeleteFailure(Exception e) { + LOG.error("Failed to delete temp-file of incoming file!", e); + } + + Stream<IncomingFile> getFormDataFiles(FormData formData) { + return Stream.concat( + formData.getRepresentations().stream(), + formData.getAttachments().stream() + .map(IncomingFileGroup::getFiles) + .flatMap(List::stream) + ); } String createVorgangForOrganisationsEinheitIds(List<String> organisationsEinheitIds, FormData preparedFormData) { diff --git a/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java b/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java index 1a8161b18bb9c02dce8ec7ee65ccd05f16707345..0fd01eaa035fb5ceeb124fffc5f32e5dc66a0c2b 100644 --- a/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java +++ b/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java @@ -431,6 +431,55 @@ class VorgangRemoteServiceTest { } } + @DisplayName("update incoming file") + @Nested + class TestUpdateIncomingFile { + + @Mock + private IncomingFile incomingFile; + + @Mock + private InputStream inputStream; + + @Mock + private GrpcUploadBinaryFileResponse response; + + @Mock + private GrpcUploadBinaryFileRequest request; + + @BeforeEach + void mock() { + doReturn(response).when(vorgangCreator).waitUntilFutureToComplete(any(), any()); + when(incomingFile.getContentStream()).thenReturn(inputStream); + doReturn(request).when(vorgangCreator).buildMetaDataRequest(any()); + } + + @DisplayName("should call get content stream") + @Test + void shouldCallGetContentStream() { + vorgangCreator.uploadIncomingFile(incomingFile); + + verify(incomingFile).getContentStream(); + } + + @DisplayName("should call build request with incoming file") + @Test + void shouldCallBuildRequestWithIncomingFile() { + vorgangCreator.uploadIncomingFile(incomingFile); + + verify(vorgangCreator).buildMetaDataRequest(incomingFile); + } + + @DisplayName("should call wait until future complete") + @Test + void shouldCallWaitUntilFutureComplete() { + vorgangCreator.uploadIncomingFile(incomingFile); + + verify(vorgangCreator).waitUntilFutureToComplete(any(), eq(inputStream)); + } + + } + @Nested class TestWaitUntilFutureToComplete { diff --git a/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java b/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java index a78d71e8cdf178413195e438ec4d4820d62e1707..74cd1e901ea5260c9ab606fd0f7b00d00fd6fb23 100644 --- a/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java +++ b/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java @@ -29,8 +29,12 @@ import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -44,6 +48,8 @@ import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.FormDataTestFactory; import de.ozgcloud.eingang.common.formdata.FormHeader; import de.ozgcloud.eingang.common.formdata.FormHeaderTestFactory; +import de.ozgcloud.eingang.common.formdata.IncomingFile; +import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; import de.ozgcloud.eingang.common.formdata.ServiceKonto; import de.ozgcloud.eingang.common.formdata.ServiceKontoTestFactory; import de.ozgcloud.eingang.common.formdata.ZustaendigeStelleTestFactory; @@ -56,19 +62,20 @@ class VorgangServiceTest { @Mock private VorgangRemoteService remoteService; + private final FormData formData = FormDataTestFactory.create(); + @DisplayName("Create vorgang") @Nested class TestCreateVorgang { - - private final FormData formData = FormDataTestFactory.create(); private final FormData preservedFormData = FormDataTestFactory.create(); private final List<String> organisationseinheitIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); @BeforeEach void mockEingangMapper() { - doReturn(preservedFormData).when(service).preserveConsistency(formData); + doReturn(preservedFormData).when(service).preserveConsistency(any()); doReturn(organisationseinheitIds).when(service).getOrganisationsEinheitIds(any()); - doReturn(VORGANG_ID).when(service).createVorgangForOrganisationsEinheitIds(organisationseinheitIds, preservedFormData); + doReturn(VORGANG_ID).when(service).createVorgangForOrganisationsEinheitIds(any(), any()); + doNothing().when(service).cleanupFormDataFiles(any()); } @Test @@ -102,11 +109,95 @@ class VorgangServiceTest { assertThat(vorgangId).isEqualTo(VORGANG_ID); } + @DisplayName("should call cleanup form data files") + @Test + void shouldCallCleanupFormDataFiles() { + callCreateVorgang(); + + verify(service).cleanupFormDataFiles(formData); + } + private String callCreateVorgang() { return service.createVorgang(formData); } } + @DisplayName("cleanup form data files") + @Nested + class TestCleanupFormDataFiles { + private final IncomingFile incomingFile = IncomingFileTestFactory.create(); + + @BeforeEach + void mock() { + doReturn(Stream.of(incomingFile)).when(service).getFormDataFiles(formData); + } + + @DisplayName("should call delete incoming file") + @Test + void shouldCallDeleteIncomingFile() { + service.cleanupFormDataFiles(formData); + + verify(service).deleteIncomingFile(incomingFile.getFile().toPath()); + } + } + + @DisplayName("get form data files") + @Nested + class TestGetFormDataFiles { + + private final FormData formData = FormDataTestFactory.create(); + + @DisplayName("should return attachments and representations") + @Test + void shouldReturnAttachmentsAndRepresentations() { + var files = service.getFormDataFiles(formData).toList(); + + assertThat(files).hasSize(3); + } + } + + @DisplayName("delete incoming file") + @Nested + class TestDeleteIncomingFile { + + @Mock + private Path path; + + @DisplayName("should call deleteIfExists") + @Test + void shouldCallDeleteIfExists() { + try (var staticMock = mockStatic(Files.class)) { + service.deleteIncomingFile(path); + + staticMock.verify(() -> Files.deleteIfExists(path)); + } + } + + @DisplayName("should return") + @Test + void shouldReturn() { + try (var staticMock = mockStatic(Files.class)) { + staticMock.when(() -> Files.deleteIfExists(path)).thenReturn(true); + + service.deleteIncomingFile(path); + } + } + + @DisplayName("should log on error") + @Test + void shouldLogOnError() { + var exception = new IOException(); + try (var staticMock = mockStatic(Files.class)) { + staticMock.when(() -> Files.deleteIfExists(path)).thenThrow(exception); + + service.deleteIncomingFile(path); + + verify(service).logErrorOnDeleteFailure(exception); + } + } + + } + @DisplayName("create vorgang for organisationsEinheitIds") @Nested class TestCreateVorgangForOrganisationsEinheitIds {