diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java index e6d9f6836b5ef0d26087356de2545d512683b863..918de441398cb8e34af14340063760b6c1cd640f 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; import de.ozgcloud.eingang.common.errorhandling.TechnicalException; import de.ozgcloud.eingang.common.formdata.IncomingFile; import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; +import de.ozgcloud.eingang.xta.RepresentationsAttachmentsPair; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; @@ -23,7 +24,22 @@ public class XdomeaMessageDataMapper { private final XdomeaXMLValueReader valueReader; - public XdomeaMessageData mapIncomingFilesToXdomeaMessageData(List<IncomingFile> incomingFileList) { + public RepresentationsAttachmentsPair mapIncomingFilesToRepresentationsAttachmentsPair(List<IncomingFile> incomingFileList) { + var xdomeaMessageData = mapIncomingFilesToXdomeaMessageData(incomingFileList); + return RepresentationsAttachmentsPair.builder() + .representations(getPairRepresentations(xdomeaMessageData)) + .attachments(xdomeaMessageData.attachments()) + .build(); + } + + private List<IncomingFile> getPairRepresentations(XdomeaMessageData xdomeaMessageData) { + return Stream.concat( + Stream.of(xdomeaMessageData.metadataFile()), + xdomeaMessageData.representations().stream() + ).toList(); + } + + XdomeaMessageData mapIncomingFilesToXdomeaMessageData(List<IncomingFile> incomingFileList) { var xdomeaXMLFile = findXdomeaXMLFile(incomingFileList); var representationFileNames = valueReader.readRepresentationFileNames(xdomeaXMLFile); var attachmentFileNames = getFileNamesExcluding( diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/RepresentationsAttachmentsPair.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/RepresentationsAttachmentsPair.java new file mode 100644 index 0000000000000000000000000000000000000000..0639e78e5439c4811ba1cd3c57d6f780fb7b7cbe --- /dev/null +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/RepresentationsAttachmentsPair.java @@ -0,0 +1,14 @@ +package de.ozgcloud.eingang.xta; + +import java.util.List; + +import de.ozgcloud.eingang.common.formdata.IncomingFile; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; +import lombok.Builder; + +@Builder +public record RepresentationsAttachmentsPair( + List<IncomingFile> representations, + List<IncomingFileGroup> attachments +) { +} diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java index af561ff948a92bee781a4745cd9b98af4ece0c8e..35e60dc6ffa846c57121ad889fe7e3b524d3e129 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java @@ -1,18 +1,13 @@ package de.ozgcloud.eingang.xta; -import java.util.List; -import java.util.stream.Stream; - import org.mapstruct.Context; import org.mapstruct.Mapper; import org.mapstruct.Mapping; 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.vorgang.VorgangNummerSupplier; import de.ozgcloud.eingang.semantik.enginebased.FilesMapperHelper; -import de.ozgcloud.eingang.xdomea.XdomeaMessageData; @Mapper(imports = FilesMapperHelper.class) interface XtaMessageMapper { @@ -23,19 +18,12 @@ interface XtaMessageMapper { @Mapping(target = "id", ignore = true) @Mapping(target = "zustaendigeStelle", ignore = true) @Mapping(target = "header", source = "metaData") - @Mapping(target = "numberOfAttachments", expression = "java(FilesMapperHelper.countAttachedFiles(xdomeaMessageData.attachments()))") - @Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(getRepresentations(xdomeaMessageData).size())") - @Mapping(target = "representations", source = "xdomeaMessageData") + @Mapping(target = "numberOfAttachments", expression = "java(FilesMapperHelper.countAttachedFiles(representationsAttachmentsPair.attachments()))") + @Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(representationsAttachmentsPair.representations().size())") @Mapping(target = "representation", ignore = true) @Mapping(target = "attachment", ignore = true) - FormData toFormData(XdomeaMessageData xdomeaMessageData, XtaMessageMetaData metaData, @Context VorgangNummerSupplier vorgangNummerSupplier); - - default List<IncomingFile> getRepresentations(XdomeaMessageData xdomeaMessageData) { - return Stream.concat( - Stream.of(xdomeaMessageData.metadataFile()), - xdomeaMessageData.representations().stream() - ).toList(); - } + FormData toFormData(RepresentationsAttachmentsPair representationsAttachmentsPair, XtaMessageMetaData metaData, + @Context VorgangNummerSupplier vorgangNummerSupplier); @Mapping(target = "formId", source = "messageType") @Mapping(target = "requestId", source = "messageId") diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java index ae71ea062381ed78d7c32bb211100af55b55ed86..203cff44770add307aeab236f0bc9388427b9563 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java @@ -1,5 +1,8 @@ package de.ozgcloud.eingang.xta; +import static java.util.Collections.*; + +import java.util.List; import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -8,7 +11,9 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import de.ozgcloud.eingang.common.errorhandling.TechnicalException; import de.ozgcloud.eingang.common.formdata.FormData; +import de.ozgcloud.eingang.common.formdata.IncomingFile; import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier; import de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper; import lombok.NonNull; @@ -20,6 +25,8 @@ class XtaService { static final String XDOMEA_0201_MESSAGE_TYPE = "Geschaeftsgang.Geschaeftsgang.0201"; + static final String FIM_MESSAGE_TYPE_PREFIX = "fim."; + @Autowired private XtaRemoteService remoteService; @Autowired @@ -53,6 +60,10 @@ class XtaService { return true; } + if (StringUtils.startsWith(metaData.getMessageType(), FIM_MESSAGE_TYPE_PREFIX)) { + return true; + } + LOG.warn("Ignoring XTA-Message of type '{}'.", metaData.getMessageType()); return false; } @@ -60,9 +71,26 @@ class XtaService { public FormData getFormData(@NonNull XtaMessageMetaData metaData) { var msg = remoteService.getMessage(metaData.getMessageId()); var incomingFiles = xtaIncomingFilesMapper.toIncomingFiles(msg.getMessageFiles()); - var xdomeaMessageData = xdomeaMessageDataMapper.mapIncomingFilesToXdomeaMessageData(incomingFiles); - return mapper.toFormData(xdomeaMessageData, metaData, vorgangNummerSupplier); + return mapper.toFormData(getRepresentationsAttachmentsPair(metaData, incomingFiles), metaData, vorgangNummerSupplier); + } + + RepresentationsAttachmentsPair getRepresentationsAttachmentsPair(XtaMessageMetaData metaData, List<IncomingFile> incomingFiles) { + if (StringUtils.equals(metaData.getMessageType(), XDOMEA_0201_MESSAGE_TYPE)) { + return xdomeaMessageDataMapper.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFiles); + } + if (StringUtils.startsWith(metaData.getMessageType(), FIM_MESSAGE_TYPE_PREFIX)) { + return mapIncomingFilesToRepresentations(incomingFiles); + } + + throw new TechnicalException("Unexpected XTA message type: %s".formatted(metaData.getMessageType())); + } + + RepresentationsAttachmentsPair mapIncomingFilesToRepresentations(List<IncomingFile> incomingFiles) { + return RepresentationsAttachmentsPair.builder() + .representations(incomingFiles) + .attachments(emptyList()) + .build(); } public void acknowledgeReceive(@NonNull XtaMessageId messageId) { diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/RepresentationsAttachmentsPairTestFactory.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/RepresentationsAttachmentsPairTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..735e3d1f79b967c3b3f7401ece6183e91333c04b --- /dev/null +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/RepresentationsAttachmentsPairTestFactory.java @@ -0,0 +1,31 @@ +package de.ozgcloud.eingang.xta; + +import java.util.List; + +import de.ozgcloud.eingang.common.formdata.IncomingFile; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory; +import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; + +public class RepresentationsAttachmentsPairTestFactory { + static List<IncomingFile> PAIR_REPRESENTATIONS = List.of( + IncomingFileTestFactory.createBuilder().name("representation1.xml").build(), + IncomingFileTestFactory.createBuilder().name("representation1.pdf").build() + ); + + static List<IncomingFileGroup> PAIR_ATTACHMENTS = List.of( + IncomingFileGroupTestFactory.create(), + IncomingFileGroupTestFactory.create(), + IncomingFileGroupTestFactory.create() + ); + + static RepresentationsAttachmentsPair create() { + return createBuilder().build(); + } + + static RepresentationsAttachmentsPair.RepresentationsAttachmentsPairBuilder createBuilder() { + return RepresentationsAttachmentsPair.builder() + .representations(PAIR_REPRESENTATIONS) + .attachments(PAIR_ATTACHMENTS); + } +} diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java index e7525540e6bcc35f40434c68d1bcc0df7c12bbc5..6b3bcd60c522a6ceb8a602486baa69b51a269c8c 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaITCase.java @@ -164,6 +164,28 @@ class XtaITCase { assertThat(vorgangsNummer).hasSameSizeAs("20240404370530710707"); } + @DisplayName("should use xta vorgangsnummer for FIM") + @Test + void shouldUseVorgangsnummerForFIM() { + mockNachrichtenBroker("versammlungsanzeige.xml"); + + runner.runGetXtaMessages(); + + var vorgangNummer = captureEingang().getHeader().getVorgangNummer(); + assertThat(vorgangNummer).hasSize(9); + } + + @DisplayName("should have one attachment for FIM") + @Test + void shouldHaveOneRepresentationForFim() { + mockNachrichtenBroker("versammlungsanzeige.xml"); + + runner.runGetXtaMessages(); + + var eingang = captureEingang(); + assertThat(eingang.getNumberOfRepresentations()).isEqualTo(1); + } + private GrpcEingang captureEingang() { verify(vorgangRemoteService, times(1)) .createVorgang( @@ -174,7 +196,6 @@ class XtaITCase { assertThat(formDataArgumentCaptor.getValue()).isNotNull(); assertThat(eingangArgumentCaptor.getValue()).isNotNull(); - assertThat(organisationseinheitenIdArgumentCaptor.getValue()).isPresent(); return eingangArgumentCaptor.getValue(); } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java index b9bcda822a302872474e1c4341cbe08b11675b99..653f1c4f8884f1a61543b7bbc3be19af8042aa35 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java @@ -14,8 +14,6 @@ import org.mockito.Spy; import de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier; -import de.ozgcloud.eingang.xdomea.XdomeaMessageDataTestFactory; -import de.ozgcloud.eingang.xdomea.XdomeaMessageData; class XtaMessageMapperTest { @@ -30,12 +28,12 @@ class XtaMessageMapperTest { class TestToFormData { private XtaMessageMetaData xtaMessageMetaData; - private XdomeaMessageData xdomeaMessageData; + private RepresentationsAttachmentsPair representationsAttachmentsPair; @BeforeEach void mock() { xtaMessageMetaData = XtaMessageMetaDataTestFactory.create(); - xdomeaMessageData = XdomeaMessageDataTestFactory.create(); + representationsAttachmentsPair = RepresentationsAttachmentsPairTestFactory.create(); when(vorgangNummerSupplier.get(VORGANG_NUMMER_SUFFIX_LENGTH)).thenReturn(FormHeaderTestFactory.VORGANGNUMMER); } @@ -43,14 +41,14 @@ class XtaMessageMapperTest { void shouldMapRepresentations() { var formData = doMapping(); - assertThat(formData.getRepresentations()).containsExactly(xdomeaMessageData.metadataFile(), xdomeaMessageData.representations().getFirst()); + assertThat(formData.getRepresentations()).isEqualTo(representationsAttachmentsPair.representations()); } @Test void shouldSetNumberOfAttachments() { var formData = doMapping(); - assertThat(formData.getNumberOfAttachments()).isEqualTo(1); + assertThat(formData.getNumberOfAttachments()).isEqualTo(3); } @Test @@ -64,7 +62,7 @@ class XtaMessageMapperTest { void shouldMapAttachments() { var formData = doMapping(); - assertThat(formData.getAttachments()).isEqualTo(xdomeaMessageData.attachments()); + assertThat(formData.getAttachments()).isEqualTo(representationsAttachmentsPair.attachments()); } @Test @@ -75,7 +73,7 @@ class XtaMessageMapperTest { } private FormData doMapping() { - return mapper.toFormData(xdomeaMessageData, xtaMessageMetaData, vorgangNummerSupplier); + return mapper.toFormData(representationsAttachmentsPair, xtaMessageMetaData, vorgangNummerSupplier); } } } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java index 997ce3bf36df47953077bbda509fc1f68705f83f..0d05f6c1ae589350c8bdca53632a13844c2ead6b 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java @@ -1,5 +1,6 @@ package de.ozgcloud.eingang.xta; +import static de.ozgcloud.eingang.xta.XtaService.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -17,6 +18,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import de.ozgcloud.eingang.common.errorhandling.TechnicalException; +import de.ozgcloud.eingang.common.formdata.FormData; +import de.ozgcloud.eingang.common.formdata.IncomingFile; import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier; import de.ozgcloud.eingang.xdomea.XdomeaMessageData; @@ -104,10 +108,19 @@ class XtaServiceTest { class TestIsSupportedMessageType { @Test - void shouldAcceptDFoerdermittel() { - var metaDataDFoerder = XtaMessageMetaDataTestFactory.create(); + void shouldAcceptGeschaeftsgang() { + var geschaeftsgangMetaData = XtaMessageMetaDataTestFactory.create(); - assertThat(service.isSupportedMessageType(metaDataDFoerder)).isTrue(); + assertThat(service.isSupportedMessageType(geschaeftsgangMetaData)).isTrue(); + } + + @Test + void shouldAcceptFIM() { + var fimMetaData = XtaMessageMetaDataTestFactory.createBuilder() + .messageType(FIM_MESSAGE_TYPE_PREFIX + "34355") + .build(); + + assertThat(service.isSupportedMessageType(fimMetaData)).isTrue(); } @Test @@ -121,60 +134,138 @@ class XtaServiceTest { @Nested class TestGetFormData { + @Mock + private FormData formData; + private XtaMessage message; - private XdomeaMessageData classification; + private XtaMessageMetaData messageMetaData; + private RepresentationsAttachmentsPair classification; @Captor private ArgumentCaptor<XtaMessageMetaData> messageMetaDataCaptor; @Captor - private ArgumentCaptor<XdomeaMessageData> classificationCaptor; + private ArgumentCaptor<RepresentationsAttachmentsPair> classificationCaptor; @BeforeEach void init() { message = XtaMessageTestFactory.create(); when(remoteService.getMessage(any(XtaMessageId.class))).thenReturn(message); - - classification = XdomeaMessageDataTestFactory.create(); var incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create()); + + messageMetaData = XtaMessageMetaDataTestFactory.create(); + classification = RepresentationsAttachmentsPairTestFactory.create(); + doReturn(classification).when(service).getRepresentationsAttachmentsPair(messageMetaData, incomingFiles); when(incomingFilesMapper.toIncomingFiles(message.getMessageFiles())).thenReturn(incomingFiles); - classification = XdomeaMessageDataTestFactory.create(); - when(xdomeaMessageDataMapper.mapIncomingFilesToXdomeaMessageData(incomingFiles)).thenReturn(classification); + when(mapper.toFormData(classification, messageMetaData, vorgangNummerSupplier)).thenReturn(formData); } @Test void shouldCallRemoteService() { - service.getFormData(XtaMessageMetaDataTestFactory.create()); + service.getFormData(messageMetaData); verify(remoteService).getMessage(XtaMessageTestFactory.MESSAGE_ID); } @Test void shouldCallMapper() { - service.getFormData(XtaMessageMetaDataTestFactory.create()); + service.getFormData(messageMetaData); - verify(mapper).toFormData(any(), any(), eq(vorgangNummerSupplier)); + verify(mapper).toFormData(classification, messageMetaData, vorgangNummerSupplier); } @Test - void shouldHaveMetaData() { - XtaMessageMetaData metaData = XtaMessageMetaDataTestFactory.create(); - - service.getFormData(metaData); + void shouldCallMapperToFormData() { + service.getFormData(messageMetaData); verify(mapper).toFormData(classificationCaptor.capture(), messageMetaDataCaptor.capture(), eq(vorgangNummerSupplier)); - assertThat(messageMetaDataCaptor.getValue()).isEqualTo(metaData); + assertThat(messageMetaDataCaptor.getValue()).isEqualTo(messageMetaData); assertThat(classificationCaptor.getValue()).isEqualTo(classification); } @Test void shouldReturnMappedResult() { - var mapped = FormDataTestFactory.create(); - when(mapper.toFormData(any(), any(), eq(vorgangNummerSupplier))).thenReturn(mapped); + var result = service.getFormData(messageMetaData); + + assertThat(result).isEqualTo(formData); + } + } + + @DisplayName("get representations attachments pair") + @Nested + class TestGetRepresentationsAttachmentsPair { + + @Mock + private XtaMessageMetaData messageMetaData; + + @Mock + private RepresentationsAttachmentsPair classification; + + private List<IncomingFile> incomingFiles; + + @BeforeEach + void mock() { + incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create()); + } + + @DisplayName("should use correct mapper xdomea message type") + @Test + void shouldUseCorrectMapperXdomeaMessageType() { + when(messageMetaData.getMessageType()).thenReturn(XtaService.XDOMEA_0201_MESSAGE_TYPE); + when(xdomeaMessageDataMapper.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFiles)) + .thenReturn(classification); + + var result = service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles); - var result = service.getFormData(XtaMessageMetaDataTestFactory.create()); + assertThat(result).isEqualTo(classification); + } + + @DisplayName("should use correct mapping for FIM message") + @Test + void shouldUseCorrectMappingForFimMessage() { + when(messageMetaData.getMessageType()).thenReturn(FIM_MESSAGE_TYPE_PREFIX + "836487"); + doReturn(classification).when(service).mapIncomingFilesToRepresentations(incomingFiles); + + var result = service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles); + + assertThat(result).isEqualTo(classification); + } + + @DisplayName("should throw exception for unexpected message type") + @Test + void shouldThrowExceptionForUnexpectedMessageType() { + when(messageMetaData.getMessageType()).thenReturn("unexpected"); + + assertThatThrownBy(() -> service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles)) + .isInstanceOf(TechnicalException.class); + } + } + + @DisplayName("map incoming files to representations") + @Nested + class TestMapIncomingFilesToRepresentations { + + private List<IncomingFile> incomingFiles; + + @BeforeEach + void mock() { + incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create()); + + } + @DisplayName("should return representations with incoming files") + @Test + void shouldReturnRepresentationsWithIncomingFiles() { + var result = service.mapIncomingFilesToRepresentations(incomingFiles); + + assertThat(result.representations()).isEqualTo(incomingFiles); + } + + @DisplayName("should return attachments with empty list") + @Test + void shouldReturnAttachmentsWithEmptyList() { + var result = service.mapIncomingFilesToRepresentations(incomingFiles); - assertThat(result).isSameAs(mapped); + assertThat(result.attachments()).isEmpty(); } }