diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java b/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java index fc033f658d18ce1a5726b631e32ab7b591c5817f..219022e4fff513843509b47afb2bafa07094c624 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/common/GrpcUtil.java @@ -40,6 +40,8 @@ public class GrpcUtil { public static final String ZUFI_MANAGER_GRPC_CLIENT = "zufi-manager"; + public static final String FILE_MANAGER_GRPC_CLIENT = "file-manager"; + public static final String SERVICE_KEY = "GRPC_SERVICE"; public static Key<String> keyOfString(String key) { diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java new file mode 100644 index 0000000000000000000000000000000000000000..568a2b6ec17ed7bf14ad074210305add9f529550 --- /dev/null +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/export/ExportVorgangController.java @@ -0,0 +1,51 @@ +package de.ozgcloud.alfa.export; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +import de.ozgcloud.alfa.common.GrpcUtil; +import de.ozgcloud.archive.grpc.export.ExportServiceGrpc.ExportServiceBlockingStub; +import de.ozgcloud.archive.grpc.export.GrpcExportVorgangRequest; +import de.ozgcloud.archive.grpc.export.GrpcExportVorgangResponse; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@RestController +@RequestMapping(ExportVorgangController.PATH) +public class ExportVorgangController { + + static final String PATH = "/api/vorgangs"; // NOSONAR + + private static final String EXPORT_FILENAME_TEMPLATE = "%s_Abgabe.Abgabe.0401.xdomea"; + + @GrpcClient(GrpcUtil.VORGANG_MANAGER_GRPC_CLIENT) + private ExportServiceBlockingStub grpcService; + + @GetMapping(value = "{vorgangId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) + public ResponseEntity<StreamingResponseBody> exportToXdomea(@PathVariable String vorgangId) { + var response = grpcService.exportVorgang(GrpcExportVorgangRequest.newBuilder().setVorgangId(vorgangId).build()); + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s", response.next().getVorgangFile().getFileName())) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(out -> writeResponse(response, out)); + } + + String buildZipFilename(String filenameId) { + return String.format(EXPORT_FILENAME_TEMPLATE, filenameId); + } + + void writeResponse(Iterator<GrpcExportVorgangResponse> response, OutputStream outputStream) throws IOException { + while (response.hasNext()) { + outputStream.write(response.next().getVorgangFile().getFileContent().toByteArray()); + } + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportRemoteService.java b/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..af08570cfa2d9c5baa25e2f4bd434f6ad6260829 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportRemoteService.java @@ -0,0 +1,20 @@ +package de.ozgcloud.alfa.export; + +import java.io.OutputStream; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.alfa.common.GrpcUtil; +import de.ozgcloud.archive.grpc.export.ExportServiceGrpc.ExportServiceBlockingStub; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service +class ExportRemoteService { + + @GrpcClient(GrpcUtil.FILE_MANAGER_GRPC_CLIENT) + private ExportServiceBlockingStub exportServiceStub; + + public void exportVorgang(String vorgangId, OutputStream archiveOut) { + + } +} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c4a5b3b4147b3222d476d7835ed42b5705898873 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/export/ExportVorgangControllerTest.java @@ -0,0 +1,95 @@ +package de.ozgcloud.alfa.export; + +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.UUID; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import de.ozgcloud.alfa.common.AlfaTestUtils; +import de.ozgcloud.alfa.vorgang.VorgangHeaderTestFactory; + +class ExportVorgangControllerTest { + + @Spy + @InjectMocks + private ExportVorgangController controller; + + private MockMvc mockMvc; + + @BeforeEach + void initTest() { + mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); + } + + @Nested + class TestBuildZipFilename { + + @Test + void shouldMatchPattern() { + var filename = controller.buildZipFilename(UUID.randomUUID().toString()); + + assertThat(filename).matches(AlfaTestUtils.uuidRegexWithSuffix("_Abgabe.Abgabe.0401.xdomea")); + } + } + +// @Nested +// class TestExportToXdomea { +// +// private static final String VORGANG_EXPORT_FILENAME = "00000000-0000-0000-0000-000000000000_Abgabe.Abgabe.0401.xml"; +// +// @Captor +// private ArgumentCaptor<String> filenameIdArgumentCaptor; +// +// @BeforeEach +// void init() { +// doReturn(VORGANG_EXPORT_FILENAME).when(controller).buildZipFilename(anyString()); +// } +// +// @Test +// void shouldHaveContentDispositonHeader() throws Exception { +// doRequest().andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + VORGANG_EXPORT_FILENAME)); +// } +// +// @Test +// void shouldCallXdomeaService() throws Exception { +// doRequest(); +// +// verify(xDomeaService).writeExport(eq(VorgangHeaderTestFactory.ID), filenameIdArgumentCaptor.capture(), any()); +// assertThat(filenameIdArgumentCaptor.getValue()).matches(AlfaTestUtils.UUID_REGEX); +// } +// +// @Test +// void shouldUseUUIDAsFilenameId() throws Exception { +// doRequest(); +// +// verify(controller).buildZipFilename(filenameIdArgumentCaptor.capture()); +// +// assertThat(filenameIdArgumentCaptor.getValue()).matches(AlfaTestUtils.UUID_REGEX); +// +// } +// +// private ResultActions doRequest() throws Exception { +// return mockMvc.perform(asyncDispatch( +// mockMvc.perform(get(ExportVorgangController.PATH + "/" + VorgangHeaderTestFactory.ID) +// .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE)).andReturn())) +// .andExpect(status().isOk()); +// } +// } + +} \ No newline at end of file