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/VorgangServiceTest.java b/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java index a78d71e8cdf178413195e438ec4d4820d62e1707..0fd92377847155e2fa6e268595caed0394116583 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,99 @@ 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(); + + @BeforeEach + void mock() { + } + + @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 + 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 {