From 3e470eb8ec1da7f947b4b3e0dd9afdbdd6b29c78 Mon Sep 17 00:00:00 2001
From: Jan Zickermann <jan.zickermann@dataport.de>
Date: Tue, 26 Nov 2024 13:19:49 +0100
Subject: [PATCH] #4 OZG-7112 Add mapping for send request

---
 pom.xml                                       |   7 +-
 .../osiv2/OsiPostfachRemoteService.java       |  12 +-
 .../transfer/PostfachApiFacadeService.java    |  13 ++-
 .../osiv2/transfer/RequestMapper.java         |  20 +++-
 .../factory/DummyStringBasedIdentifier.java   |  23 ++++
 .../factory/PostfachAddressTestFactory.java   |  20 ++++
 .../factory/PostfachNachrichtTestFactory.java |  20 ++++
 .../osiv2/transfer/RequestMapperTest.java     | 107 ++++++++++++++++++
 8 files changed, 196 insertions(+), 26 deletions(-)
 create mode 100644 src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/DummyStringBasedIdentifier.java
 create mode 100644 src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java
 create mode 100644 src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java
 create mode 100644 src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapperTest.java

diff --git a/pom.xml b/pom.xml
index 1552a92..e373fe5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,6 @@
 		<mockserver-client.version>5.15.0</mockserver-client.version>
 		<openapi-generator.version>7.10.0</openapi-generator.version>
 		<swagger-parser.version>2.1.23</swagger-parser.version>
-		<jackson-databind-nullable.version>0.2.1</jackson-databind-nullable.version>
 	</properties>
 	<dependencies>
 		<!-- OZG-Cloud -->
@@ -55,11 +54,6 @@
 			<artifactId>mapstruct</artifactId>
 		</dependency>
 
-		<dependency>
-			<groupId>org.openapitools</groupId>
-			<artifactId>jackson-databind-nullable</artifactId>
-			<version>${jackson-databind-nullable.version}</version>
-		</dependency>
 		<dependency>
 			<groupId>io.swagger.parser.v3</groupId>
 			<artifactId>swagger-parser</artifactId>
@@ -158,6 +152,7 @@
 								<annotationLibrary>swagger2</annotationLibrary>
 								<apiPackage>de.ozgcloud.nachrichten.postfach.osiv2.gen.api</apiPackage>
 								<modelPackage>de.ozgcloud.nachrichten.postfach.osiv2.gen.model</modelPackage>
+								<openApiNullable>false</openApiNullable>
 							</configOptions>
 						</configuration>
 					</execution>
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java
index d4a61aa..aad81c5 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/OsiPostfachRemoteService.java
@@ -8,26 +8,20 @@ import org.springframework.stereotype.Service;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.PostfachRemoteService;
 import de.ozgcloud.nachrichten.postfach.osiv2.transfer.PostfachApiFacadeService;
-import de.ozgcloud.nachrichten.postfach.osiv2.transfer.RequestMapper;
-import de.ozgcloud.nachrichten.postfach.osiv2.transfer.ResponseMapper;
 import lombok.extern.log4j.Log4j2;
 
 @Service
 @ConditionalOnProperty("ozgcloud.osiv2-postfach.enabled")
 @Log4j2
 public record OsiPostfachRemoteService(
-		PostfachApiFacadeService postfachApiFacadeService,
-		RequestMapper requestMapper,
-		ResponseMapper responseMapper
+		PostfachApiFacadeService postfachApiFacadeService
 ) implements PostfachRemoteService {
 	public static final String POSTFACH_TYPE_OSIV2 = "OSIV2";
 
 	@Override
 	public void sendMessage(PostfachNachricht nachricht) {
-		postfachApiFacadeService.sendMessage(
-				requestMapper.toMailboxId(nachricht),
-				requestMapper.mapOutSendMessageRequestV2(nachricht)
-		);
+		postfachApiFacadeService.sendMessage(nachricht);
+		// TODO handle exceptions?
 	}
 
 	@Override
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
index 860a644..8814a7e 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
@@ -2,18 +2,19 @@ package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
 import org.springframework.stereotype.Service;
 
+import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi;
-import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2;
 
 @Service
 public record PostfachApiFacadeService(
-		MessageExchangeApi messageExchangeApi
+		MessageExchangeApi messageExchangeApi,
+		RequestMapper requestMapper,
+		ResponseMapper responseMapper
 ) {
-	public void sendMessage(String mailboxId, OutSendMessageRequestV2 sendMessageRequest) {
+	public void sendMessage(PostfachNachricht nachricht) {
 		messageExchangeApi.messageExchangeV1SendMailboxIdPost(
-				mailboxId,
-				sendMessageRequest
+				requestMapper.mapMailboxId(nachricht),
+				requestMapper.mapOutSendMessageRequestV2(nachricht)
 		).block();
-		// TODO handle exceptions?
 	}
 }
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapper.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapper.java
index 73cf9e6..43f6b20 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapper.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapper.java
@@ -1,13 +1,17 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
+import java.util.Optional;
+
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.ReportingPolicy;
 
+import de.ozgcloud.nachrichten.postfach.PostfachAddress;
+import de.ozgcloud.nachrichten.postfach.PostfachAddressIdentifier;
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2;
 
-@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN)
+@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR)
 public interface RequestMapper {
 
 	@Mapping(target = "sequencenumber", ignore = true)
@@ -15,14 +19,20 @@ public interface RequestMapper {
 	@Mapping(target = "displayName", ignore = true)
 	@Mapping(target = "originSender", ignore = true)
 	@Mapping(target = "replyAction", ignore = true)
-	@Mapping(target = "eidasLevel", ignore = true)
-	@Mapping(target = "isObligatory", ignore = true)
+	@Mapping(target = "eidasLevel", constant = "MEDIUM")
+	@Mapping(target = "isObligatory", expression = "java( false )")
 	@Mapping(target = "isHtml", ignore = true)
 	@Mapping(target = "files", ignore = true)
 	@Mapping(target = "references", ignore = true)
 	OutSendMessageRequestV2 mapOutSendMessageRequestV2(PostfachNachricht nachricht);
 
-	default String toMailboxId(PostfachNachricht nachricht) {
-		return nachricht.getPostfachAddress().getIdentifier().toString();
+
+	default String mapMailboxId(PostfachNachricht nachricht) {
+		return Optional.ofNullable(nachricht.getPostfachAddress())
+				.map(PostfachAddress::getIdentifier)
+				.filter(PostfachAddressIdentifier::isStringBasedIdentifier)
+				.map(Object::toString)
+				.orElseThrow(() -> new IllegalArgumentException("Expect MailboxId to be a string-based PostfachAddress of PostfachNachricht!"));
 	}
+
 }
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/DummyStringBasedIdentifier.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/DummyStringBasedIdentifier.java
new file mode 100644
index 0000000..cc2ef17
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/DummyStringBasedIdentifier.java
@@ -0,0 +1,23 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.factory;
+
+import de.ozgcloud.nachrichten.postfach.PostfachAddressIdentifier;
+import lombok.Builder;
+import lombok.Getter;
+
+@Builder
+@Getter
+public class DummyStringBasedIdentifier implements PostfachAddressIdentifier {
+
+	private String mailboxId;
+
+	@Override
+	public boolean isStringBasedIdentifier() {
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return mailboxId;
+	}
+}
+
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java
new file mode 100644
index 0000000..a871295
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachAddressTestFactory.java
@@ -0,0 +1,20 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.factory;
+
+import de.ozgcloud.nachrichten.postfach.PostfachAddress;
+
+public class PostfachAddressTestFactory {
+
+	public static final String MAILBOX_ID = "testMailboxId";
+
+	public static PostfachAddress create() {
+		return createBuilder().build();
+	}
+
+	public static PostfachAddress.PostfachAddressBuilder createBuilder() {
+		return PostfachAddress.builder()
+				.type(1)
+				.identifier(DummyStringBasedIdentifier.builder()
+						.mailboxId(MAILBOX_ID)
+						.build());
+	}
+}
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java
new file mode 100644
index 0000000..2f217ee
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/PostfachNachrichtTestFactory.java
@@ -0,0 +1,20 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.factory;
+
+import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
+
+public class PostfachNachrichtTestFactory {
+	public static final String MAIL_BODY = "mail body";
+	public static final String MAIL_SUBJECT = "mail subject";
+
+
+	public static PostfachNachricht create() {
+		return createBuilder().build();
+	}
+
+	public static PostfachNachricht.PostfachNachrichtBuilder createBuilder() {
+		return PostfachNachricht.builder()
+				.mailBody(MAIL_BODY)
+				.subject(MAIL_SUBJECT)
+				.postfachAddress(PostfachAddressTestFactory.create());
+	}
+}
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapperTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapperTest.java
new file mode 100644
index 0000000..5ac7fea
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/RequestMapperTest.java
@@ -0,0 +1,107 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
+
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory.*;
+import static de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory.*;
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.mapstruct.factory.Mappers;
+
+import de.ozgcloud.nachrichten.postfach.PostfachAddress;
+import de.ozgcloud.nachrichten.postfach.PostfachAddressIdentifier;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachAddressTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1EidasLevel;
+
+class RequestMapperTest {
+
+	private final RequestMapper mapper = Mappers.getMapper(RequestMapper.class);
+
+	@DisplayName("map mailbox id")
+	@Nested
+	class TestMapMailboxId {
+
+		@DisplayName("should map postfach address to mailbox id")
+		@Test
+		void shouldMapPostfachAddressToMailboxId() {
+			var result = mapper.mapMailboxId(PostfachNachrichtTestFactory.create());
+
+			assertThat(result).isEqualTo(MAILBOX_ID);
+		}
+
+		@DisplayName("should throw on missing postfach address")
+		@ParameterizedTest
+		@MethodSource("badPostfachAddresses")
+		void shouldThrowOnMissingPostfachAddress(PostfachAddress badPostfachAddress) {
+			var nachrichtWithBadPostfachAddress = PostfachNachrichtTestFactory.createBuilder()
+					.postfachAddress(badPostfachAddress)
+					.build();
+
+			assertThatThrownBy(() -> mapper.mapMailboxId(nachrichtWithBadPostfachAddress))
+					.isInstanceOf(IllegalArgumentException.class);
+		}
+
+		static Stream<Arguments> badPostfachAddresses() {
+			return Stream.of(
+					null,
+					Arguments.of(PostfachAddressTestFactory.createBuilder()
+							.identifier(null)
+							.build()),
+					Arguments.of(PostfachAddressTestFactory.createBuilder()
+							.identifier(new PostfachAddressIdentifier() {
+
+							})
+							.build())
+			);
+		}
+	}
+
+	@DisplayName("map OutSendMessageRequestV2")
+	@Nested
+	class TestMapOutSendMessageRequestV2 {
+		@DisplayName("should map subject")
+		@Test
+		void shouldMapSubject() {
+			var result = doMapping();
+
+			assertThat(result.getSubject()).isEqualTo(MAIL_SUBJECT);
+		}
+
+		@DisplayName("should map body")
+		@Test
+		void shouldMapBody() {
+			var result = doMapping();
+
+			assertThat(result.getBody()).isEqualTo(MAIL_BODY);
+		}
+
+		@DisplayName("should set eidasLevel")
+		@Test
+		void shouldSetEidasLevel() {
+			var result = doMapping();
+
+			assertThat(result.getEidasLevel()).isEqualTo(V1EidasLevel.MEDIUM);
+		}
+
+		@DisplayName("should set isObligatory")
+		@Test
+		void shouldSetIsObligatory() {
+			var result = doMapping();
+
+			assertThat(result.getIsObligatory()).isFalse();
+		}
+
+		private OutSendMessageRequestV2 doMapping() {
+			return mapper.mapOutSendMessageRequestV2(PostfachNachrichtTestFactory.create());
+		}
+	}
+
+}
\ No newline at end of file
-- 
GitLab