diff --git a/pom.xml b/pom.xml index 935366a3ccd1f75db7dfeb8ec60f8986ddfd3388..4310022fcf6b7ccaf3c32f2e64439365000d885b 100644 --- a/pom.xml +++ b/pom.xml @@ -91,17 +91,27 @@ <artifactId>mapstruct</artifactId> </dependency> - <!-- Test --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> + <!-- Test --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.yaml</groupId> + <artifactId>snakeyaml</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-collections4</artifactId> + </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> diff --git a/src/main/java/de/ozgcloud/xta/client/model/XtaMessage.java b/src/main/java/de/ozgcloud/xta/client/model/XtaMessage.java index 39f333a24d76af9071651b323d8ce9077eb145a1..10cf16eb90b271057680c386fde04af0956da777 100644 --- a/src/main/java/de/ozgcloud/xta/client/model/XtaMessage.java +++ b/src/main/java/de/ozgcloud/xta/client/model/XtaMessage.java @@ -7,7 +7,7 @@ import jakarta.validation.constraints.NotNull; import lombok.Builder; -@Builder +@Builder(toBuilder = true) public record XtaMessage( @NotNull @Valid XtaMessageMetaData metaData, @NotNull @Valid XtaFile messageFile, diff --git a/src/main/java/de/ozgcloud/xta/client/model/XtaMessageMetaData.java b/src/main/java/de/ozgcloud/xta/client/model/XtaMessageMetaData.java index 5f1943e41d77cfc1f8124595efd23f59f730bc12..87fee1fb81f3729aa310ccfe06dd12820a899320 100644 --- a/src/main/java/de/ozgcloud/xta/client/model/XtaMessageMetaData.java +++ b/src/main/java/de/ozgcloud/xta/client/model/XtaMessageMetaData.java @@ -9,7 +9,7 @@ import jakarta.validation.constraints.PositiveOrZero; import lombok.Builder; -@Builder +@Builder(toBuilder = true) public record XtaMessageMetaData( @NotBlank String service, @NotBlank String businessScenarioCode, diff --git a/src/test/java/de/ozgcloud/xta/client/XtaDevServerSetupExtension.java b/src/test/java/de/ozgcloud/xta/client/XtaDevServerSetupExtension.java index 6eeca9bb83b1d3741e95a154df8165321b77a716..032410d619fd57c1b1f74b0d705626a8372dbd48 100644 --- a/src/test/java/de/ozgcloud/xta/client/XtaDevServerSetupExtension.java +++ b/src/test/java/de/ozgcloud/xta/client/XtaDevServerSetupExtension.java @@ -17,6 +17,7 @@ import de.ozgcloud.xta.client.model.XtaMessageMetaData; import de.ozgcloud.xta.client.model.XtaMessageMetaDataTestFactory; import de.ozgcloud.xta.client.model.XtaMessageTestFactory; import genv3.de.xoev.transport.xta.x211.ParameterIsNotValidException; +import genv3.de.xoev.transport.xta.x211.PermissionDeniedException; import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; @@ -33,7 +34,8 @@ public class XtaDevServerSetupExtension implements BeforeAllCallback, BeforeEach private XtaClientFactory clientFactory; static final String BASE_URL = "https://li33-0005.dp.dsecurecloud.de/MB_XTA-WS/XTA210"; - static final String CLIENT_IDENTIFIER1 = "dp:012345678910_XtaClientITCase1"; + // static final String CLIENT_IDENTIFIER1 = "dp:012345678910_XtaClientITCase1"; + static final String CLIENT_IDENTIFIER1 = "afmsh:ozg-cloud-dev001"; static final String CLIENT_IDENTIFIER2 = "dp:012345678910_XtaClientITCase2"; @Override @@ -84,19 +86,25 @@ public class XtaDevServerSetupExtension implements BeforeAllCallback, BeforeEach @SneakyThrows void sendTestMessageToClient2(Identifier author, Identifier reader) { var messageId = service.createMessageId(author); + var message = XtaMessageExampleLoader.load( + XtaMessageExampleLoader.MessageExampleConfig.builder() + .messageLabel("versammlungsanzeige_with_attachment") + .messageId(messageId) + .author(author) + .reader(reader) + .build()); try { - service.sendMessage(XtaMessageTestFactory.createBuilder() - .metaData(XtaMessageMetaDataTestFactory.createBuilder() - .authorIdentifier(author) - .readerIdentifier(reader) - .messageId(messageId) - .build()) - .build() - ); + log.info("Sending from author {} to reader {}.", message.metaData().authorIdentifier(), message.metaData().readerIdentifier()); + service.sendMessage(message); } catch (ParameterIsNotValidException e) { log.error("Failed to send test message to client2: {}", e.getFaultInfo().getErrorCode().getName()); throw e; + + } catch (PermissionDeniedException e) { + log.error("Failed to send test message to client2: {}", e.getFaultInfo().getErrorCode().getName()); + throw e; } + } @SneakyThrows diff --git a/src/test/java/de/ozgcloud/xta/client/XtaMessageExampleLoader.java b/src/test/java/de/ozgcloud/xta/client/XtaMessageExampleLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..a3737c9c5ba980f87914835826f9615b12d70eeb --- /dev/null +++ b/src/test/java/de/ozgcloud/xta/client/XtaMessageExampleLoader.java @@ -0,0 +1,125 @@ +package de.ozgcloud.xta.client; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Supplier; + +import jakarta.activation.DataHandler; +import jakarta.annotation.Nullable; +import jakarta.mail.util.ByteArrayDataSource; +import jakarta.validation.constraints.NotBlank; + +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.io.IOUtils; +import org.yaml.snakeyaml.Yaml; + +import de.ozgcloud.xta.client.model.Identifier; +import de.ozgcloud.xta.client.model.XtaFile; +import de.ozgcloud.xta.client.model.XtaMessage; +import de.ozgcloud.xta.client.model.XtaMessageMetaData; +import lombok.Builder; + +public class XtaMessageExampleLoader { + + static Yaml yaml = new Yaml(); + + @SuppressWarnings("unchecked") + public static XtaMessage load(MessageExampleConfig config) { + var messageDataMap = loadXtaMessageDataMap(config.messageLabel); + + return XtaMessage.builder() + .metaData(mapXtaMessageMetadata(getChild(messageDataMap, "metaData"), config)) + .messageFile(mapXtaFile(getChild(messageDataMap, "messageFile"), config.messageLabel + "/message")) + .attachmentFiles(mapXtaFiles((List<Map<String, Object>>) messageDataMap.get("attachmentFiles"), config.messageLabel + "/attachment")) + .build(); + } + + @Builder + public record MessageExampleConfig( + @NotBlank String messageLabel, + @Nullable String messageId, + @Nullable Identifier author, + @Nullable Identifier reader) { + } + + @SuppressWarnings("unchecked") + private static Map<String, Object> getChild(Map<String, Object> parent, String key) { + return Objects.requireNonNull((Map<String, Object>) MapUtils.getMap(parent, key), "Missing key: %s".formatted(key)); + } + + private static XtaFile mapXtaFile(Map<String, Object> messageFile, String resourcePrefix) { + Function<String, String> getString = key -> Objects.requireNonNull( + MapUtils.getString(messageFile, key), "[Failed mapping for %s] Missing key: %s".formatted(resourcePrefix, key)); + + return XtaFile.builder() + .name(getString.apply("name")) + .contentType(getString.apply("contentType")) + .content(createContentDataHandler(getMessageResourcePath(resourcePrefix, getString.apply("name")))) + .build(); + } + + private static List<XtaFile> mapXtaFiles(List<Map<String, Object>> attachmentFiles, String resourcePrefix) { + return attachmentFiles.stream() + .map(messageFileMap -> mapXtaFile(messageFileMap, resourcePrefix)) + .toList(); + } + + private static XtaMessageMetaData mapXtaMessageMetadata(Map<String, Object> metaData, MessageExampleConfig config) { + Function<String, String> getString = key -> Objects.requireNonNull( + MapUtils.getString(metaData, key), "metaData key missing: %s".formatted(key)); + return XtaMessageMetaData.builder() + .service(getString.apply("service")) + .businessScenarioCode(getString.apply("businessScenarioCode")) + .messageTypeCode(getString.apply("messageTypeCode")) + .messageTypePayloadSchema(getString.apply("messageTypePayloadSchema")) + .messageId(getIfConfigNull( + config.messageId, () -> getString.apply("messageId"))) + .authorIdentifier(getIfConfigNull( + config.author, + () -> mapIdentifier(getChild(metaData, "authorIdentifier")))) + .readerIdentifier(getIfConfigNull( + config.reader, + () -> mapIdentifier(getChild(metaData, "readerIdentifier")))) + .build(); + } + + private static <T> T getIfConfigNull(T configValue, Supplier<T> supplier) { + return configValue != null ? configValue : supplier.get(); + } + + private static Identifier mapIdentifier(Map<String, Object> identifier) { + Function<String, String> getString = key -> (String) identifier.get(key); + return Identifier.builder() + .name(getString.apply("name")) + .value(getString.apply("value")) + .category(getString.apply("category")) + .build(); + } + + private static LinkedHashMap<String, Object> loadXtaMessageDataMap(String messageLabel) { + var yamlFileData = readBytesFromResource(getMessageResourcePath(messageLabel, "xta-message.yaml")); + return yaml.load(new String(yamlFileData)); + } + + private static String getMessageResourcePath(String prefix, String suffix) { + return "/messages/%s/%s".formatted(prefix, suffix); + } + + private static DataHandler createContentDataHandler(String resourcePath) { + var data = readBytesFromResource(resourcePath); + return new DataHandler(new ByteArrayDataSource(data, "application/octet-stream")); + } + + private static byte[] readBytesFromResource(String path) { + try { + return IOUtils.toByteArray(Objects.requireNonNull(XtaMessageExampleLoader.class.getResourceAsStream(path))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/VO_EutinKarte.png b/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/VO_EutinKarte.png new file mode 100644 index 0000000000000000000000000000000000000000..164a96d0c3334cf72bb417cd4a680e3324b46d82 Binary files /dev/null and b/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/VO_EutinKarte.png differ diff --git a/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/WE_EutinPlatz.jpg b/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/WE_EutinPlatz.jpg new file mode 100644 index 0000000000000000000000000000000000000000..52f1b4269a2b72c7a294d33bd16d287e902a6809 Binary files /dev/null and b/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/WE_EutinPlatz.jpg differ diff --git a/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/WE_EutinSitztPlatz.jpg b/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/WE_EutinSitztPlatz.jpg new file mode 100644 index 0000000000000000000000000000000000000000..741838f4520c3dc3e00e7a6704f5beee294ed786 Binary files /dev/null and b/src/test/resources/messages/versammlungsanzeige_with_attachment/attachment/WE_EutinSitztPlatz.jpg differ diff --git a/src/test/resources/messages/versammlungsanzeige_with_attachment/message/Antrag.xml b/src/test/resources/messages/versammlungsanzeige_with_attachment/message/Antrag.xml new file mode 100644 index 0000000000000000000000000000000000000000..d6443d8c0c7cfef391fb24d72df9142d877af611 --- /dev/null +++ b/src/test/resources/messages/versammlungsanzeige_with_attachment/message/Antrag.xml @@ -0,0 +1 @@ +<fim.S17000652.17000652001004 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:xoev-de:xfall:standard:fim-s17000652_1.4"><G17003529><G05001479><G05001480><F05002750>d70979eb-0ab4-4f0b-81f8-1b7d3acb590b</F05002750><F05002751>23.07.2024 16:13:13</F05002751><F05002752>fim.S17000652.17000652001004</F05002752><F05002753>urn:fim:Versammlungsanzeige:1.4</F05002753></G05001480><G05001481><F05002754>Fachdienst Sicherheit und Ordnung</F05002754><F05002755>vbe:010550120100</F05002755><F05002756>Versammlungsbehörde</F05002756></G05001481><G05001482><F05002754>Dataport</F05002754><F05002755>ehp:010100100000</F05002755><F05002756>Versammlungsbehörde</F05002756></G05001482></G05001479><F17005454>true</F17005454><F17005455>false</F17005455><F17005533>d70979eb-0ab4-4f0b-81f8-1b7d3acb590b</F17005533></G17003529><F17009191>true</F17009191><G17005403><G17007200><F60000319>OrgName</F60000319><F17011809>OrgUnit</F17011809><G60000086><F60000243>OrgSteet</F60000243><F60000244>OrgNum</F60000244><F60000246>33333</F60000246><F60000247>OrgCity</F60000247></G60000086></G17007200><G17007201><F60000228>ContactName</F60000228><F60000227>ContactSureName</F60000227><F60000240>3334343444</F60000240><F60000242>Ansprechemail@example.com</F60000242></G17007201><G17002127><F60000228>VerantwortungVorname</F60000228><F60000227>VerantwortungNachname</F60000227><G60000086><F60000243>VerantwortungStraße</F60000243><F60000244>VerHNum</F60000244><F60000246>22222</F60000246><F60000247>VerOrt</F60000247><F60000248>VerAddresszusatz</F60000248></G60000086><F60000242>Verantwortungemail@example.com</F60000242></G17002127></G17005403><F17003371>Anzeigen einer ortsfesten Versammlung (Kundgebung / Demonstration)</F17003371><G17005404><G17007202><F17003373>Den Hintern platt sitzen</F17003373><F17011810>Vom Stehen ins Sitzen kommen!</F17011810><F17003377>Auf der Stelle</F17003377><G17005405><F60000296>VO_EutinKarte.png</F60000296></G17005405><G17005406><F60000048>2024-09-29</F60000048><F17001348>12.25</F17001348><F60000049>2024-09-29</F60000049><F17001349>13.75</F17001349></G17005406></G17007202><G17007205><F17003379>5</F17003379><F17003380>1</F17003380><F17003382>Tisch-Test-Unternehmen</F17003382><G17007234><F17011826>Keine</F17011826></G17007234><G17007235><F17011827>Keine</F17011827></G17007235><G17007210><F60000296>WE_EutinPlatz.jpg</F60000296><F60000296>WE_EutinSitztPlatz.jpg</F60000296></G17007210></G17007205></G17005404></fim.S17000652.17000652001004> \ No newline at end of file diff --git a/src/test/resources/messages/versammlungsanzeige_with_attachment/xta-message.yaml b/src/test/resources/messages/versammlungsanzeige_with_attachment/xta-message.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7796c3993d28f83b36b8cc095874dd624deb463f --- /dev/null +++ b/src/test/resources/messages/versammlungsanzeige_with_attachment/xta-message.yaml @@ -0,0 +1,26 @@ +metaData: + service: urn:fim:Versammlungsanzeige:1.4 + businessScenarioCode: FIM_DATA + messageTypeCode: fim.S17000652.17000652001004 + messageTypePayloadSchema: urn:xoev-de:xfall:standard:fim-s17000652_1.4 + authorIdentifier: + name: Dataport + category: Engagement- und Hobbyportal + value: ehp:010100100000 + readerIdentifier: + name: L100012.OE.279550874 + category: Versammlungsbehörde + value: afmsh:010600000000_Online-Dienste +messageFile: + contentType: application/xml + name: Antrag.xml +attachmentFiles: + - contentType: image/png + name: VO_EutinKarte.png + id: 0d929408-7c89-43ae-a303-71165be7b775 + - contentType: image/jpeg + name: WE_EutinPlatz.jpg + id: 175faaa1-1410-4a4d-8677-0f2984f5ed4e + - contentType: image/jpeg + name: WE_EutinSitztPlatz.jpg + id: 1734b13e-50b4-4367-954a-ee8da0c5348c \ No newline at end of file