From f1360a3e83a808d34540b31012865225f270adfe Mon Sep 17 00:00:00 2001
From: Jan Zickermann <jan.zickermann@dataport.de>
Date: Wed, 26 Mar 2025 15:14:03 +0100
Subject: [PATCH 1/3] OZG-7978 servicekonto: Catch runtime-exception in
 getPostfachAddressType

---
 .../semantik/common/ServiceKontoFactory.java  |  7 ++-
 .../common/ServiceKontoFactoryTest.java       | 59 ++++++++++++++++++-
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java
index f41a76e44..8f9aa3d8b 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java
@@ -102,7 +102,12 @@ public class ServiceKontoFactory {
 	}
 
 	int getPostfachAddressType(Map<String, Object> restResponseName) {
-		return getMailboxType(restResponseName);
+		try {
+			return getMailboxType(restResponseName);
+		} catch (RuntimeException e) {
+			LOG.error("Error while getting mailbox type from rest response name", e);
+			return POSTFACH_ADDRESS_DEFAULT;
+		}
 	}
 
 	private Integer getMailboxType(Map<String, Object> restResponseName) {
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java
index 5f9fba08b..c62d3cd37 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java
@@ -23,6 +23,7 @@
  */
 package de.ozgcloud.eingang.semantik.common;
 
+import static de.ozgcloud.eingang.semantik.common.ServiceKontoFactory.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
@@ -34,6 +35,8 @@ import org.junit.jupiter.api.BeforeEach;
 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.ValueSource;
 import org.mockito.InjectMocks;
 import org.mockito.Spy;
 
@@ -41,10 +44,10 @@ import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormDataUtils;
 import de.ozgcloud.eingang.common.formdata.PostfachAddressTestFactory;
 import de.ozgcloud.eingang.common.formdata.ServiceKonto;
+import de.ozgcloud.eingang.common.formdata.ServiceKonto.PostfachAddress;
 import de.ozgcloud.eingang.common.formdata.ServiceKonto.TrustLevel;
 import de.ozgcloud.eingang.common.formdata.ServiceKontoTestFactory;
 import de.ozgcloud.eingang.common.formdata.StringBasedIdentifier;
-import de.ozgcloud.eingang.common.formdata.ServiceKonto.PostfachAddress;
 
 class ServiceKontoFactoryTest {
 
@@ -104,8 +107,9 @@ class ServiceKontoFactoryTest {
 			@Nested
 			class TestWithRestResponseName {
 
+				@DisplayName("should call buildOsiPostfachV1Address")
 				@Test
-				void shouldCallBuildAddresses() {
+				void shouldCallBuildOsiPostfachV1Address() {
 					getPostfachAddresses();
 
 					verify(factory).buildOsiPostfachV1Address(any(), anyInt());
@@ -123,11 +127,62 @@ class ServiceKontoFactoryTest {
 					assertThat(addresses.get(0).getType()).isEqualTo(PostfachAddressTestFactory.POSTFACH_ADDRESS_TYPE);
 				}
 
+				@DisplayName("should return with postfach address type")
+				@ParameterizedTest
+				@ValueSource(ints = { 1, 2, 3 })
+				void shouldReturnWithPostfachAddressType(int postfachAddressType) {
+					var formDataWithPostfachAddressType = FormDataUtils.from(FORM_DATA)
+							.put(ServiceKontoFactory.REST_RESPONSE_NAME, List.of(Map.of(
+									ServiceKontoFactory.REST_RESPONSE_NAME_MEMBER_SCOPE,
+									List.of(Map.of(ServiceKontoFactory.REST_RESPONSE_NAME_MEMBER_SCOPE_MAILBOX_TYPE,
+											postfachAddressType))))
+							)
+							.build();
+
+					var addresses = buildServiceKonto(formDataWithPostfachAddressType);
+
+					var types = addresses.getPostfachAddresses()
+							.stream()
+							.map(PostfachAddress::getType)
+							.toList();
+					assertThat(types).containsExactly(postfachAddressType);
+				}
+
 				private List<PostfachAddress> getPostfachAddresses() {
 					return buildServiceKonto(FORM_DATA).getPostfachAddresses();
 				}
 			}
 
+			@DisplayName("with bad rest_response_name")
+			@Nested
+			class TestWithBadRestResponseName {
+
+				private final FormData formDataWithBadRestResponseName = FormDataUtils.from(FORM_DATA)
+						.put(ServiceKontoFactory.REST_RESPONSE_NAME, List.of(Map.of())).build();
+
+				@DisplayName("should call buildOsiPostfachV1Address")
+				@Test
+				void shouldCallBuildOsiPostfachV1Address() {
+					getPostfachAddresses();
+
+					verify(factory).buildOsiPostfachV1Address(any(), anyInt());
+				}
+
+				@DisplayName("should return postfach address with default type")
+				@Test
+				void shouldReturnPostfachAddressWithDefaultType() {
+					var addresses = getPostfachAddresses();
+
+					assertThat(addresses)
+							.extracting("type")
+							.containsExactly(POSTFACH_ADDRESS_DEFAULT);
+				}
+
+				private List<PostfachAddress> getPostfachAddresses() {
+					return buildServiceKonto(formDataWithBadRestResponseName).getPostfachAddresses();
+				}
+			}
+
 			@DisplayName("without rest_response_name")
 			@Nested
 			class TestWithoutRestResponseName {
-- 
GitLab


From fe0c4ff88f926d1d433297c6bcaa7bfef4c19f58 Mon Sep 17 00:00:00 2001
From: Jan Zickermann <jan.zickermann@dataport.de>
Date: Fri, 25 Apr 2025 11:24:18 +0200
Subject: [PATCH 2/3] OZG-7978 servicekonto: Cleanup test

---
 .../common/ServiceKontoFactoryTest.java       | 41 +++++++++----------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java
index c62d3cd37..28ce6dec1 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactoryTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.*;
 import java.util.List;
 import java.util.Map;
 
+import org.assertj.core.api.InstanceOfAssertFactories;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
@@ -116,7 +117,7 @@ class ServiceKontoFactoryTest {
 				}
 
 				@Test
-				void shouldReturnPostfachAddresses() {
+				void shouldBuildPostfachAddresses() {
 					var addresses = getPostfachAddresses();
 
 					assertThat(addresses).hasSize(1);
@@ -127,10 +128,10 @@ class ServiceKontoFactoryTest {
 					assertThat(addresses.get(0).getType()).isEqualTo(PostfachAddressTestFactory.POSTFACH_ADDRESS_TYPE);
 				}
 
-				@DisplayName("should return with postfach address type")
+				@DisplayName("should build with postfach address type")
 				@ParameterizedTest
 				@ValueSource(ints = { 1, 2, 3 })
-				void shouldReturnWithPostfachAddressType(int postfachAddressType) {
+				void shouldBuildWithPostfachAddressType(int postfachAddressType) {
 					var formDataWithPostfachAddressType = FormDataUtils.from(FORM_DATA)
 							.put(ServiceKontoFactory.REST_RESPONSE_NAME, List.of(Map.of(
 									ServiceKontoFactory.REST_RESPONSE_NAME_MEMBER_SCOPE,
@@ -139,13 +140,12 @@ class ServiceKontoFactoryTest {
 							)
 							.build();
 
-					var addresses = buildServiceKonto(formDataWithPostfachAddressType);
+					var serviceKonto = buildServiceKonto(formDataWithPostfachAddressType);
 
-					var types = addresses.getPostfachAddresses()
-							.stream()
-							.map(PostfachAddress::getType)
-							.toList();
-					assertThat(types).containsExactly(postfachAddressType);
+					assertThat(serviceKonto)
+							.extracting(ServiceKonto::getPostfachAddresses, InstanceOfAssertFactories.list(PostfachAddress.class))
+							.extracting(PostfachAddress::getType)
+							.containsExactly(postfachAddressType);
 				}
 
 				private List<PostfachAddress> getPostfachAddresses() {
@@ -153,34 +153,31 @@ class ServiceKontoFactoryTest {
 				}
 			}
 
-			@DisplayName("with bad rest_response_name")
+			@DisplayName("with unexpected rest_response_name")
 			@Nested
-			class TestWithBadRestResponseName {
+			class TestWithUnexpectedRestResponseName {
 
-				private final FormData formDataWithBadRestResponseName = FormDataUtils.from(FORM_DATA)
+				private final FormData formDataWithUnexpectedRestResponseName = FormDataUtils.from(FORM_DATA)
 						.put(ServiceKontoFactory.REST_RESPONSE_NAME, List.of(Map.of())).build();
 
 				@DisplayName("should call buildOsiPostfachV1Address")
 				@Test
 				void shouldCallBuildOsiPostfachV1Address() {
-					getPostfachAddresses();
+					buildServiceKonto(formDataWithUnexpectedRestResponseName);
 
 					verify(factory).buildOsiPostfachV1Address(any(), anyInt());
 				}
 
-				@DisplayName("should return postfach address with default type")
+				@DisplayName("should build postfach address with default type")
 				@Test
-				void shouldReturnPostfachAddressWithDefaultType() {
-					var addresses = getPostfachAddresses();
+				void shouldBuildPostfachAddressWithDefaultType() {
+					var serviceKonto = buildServiceKonto(formDataWithUnexpectedRestResponseName);
 
-					assertThat(addresses)
-							.extracting("type")
+					assertThat(serviceKonto)
+							.extracting(ServiceKonto::getPostfachAddresses, InstanceOfAssertFactories.list(PostfachAddress.class))
+							.extracting(PostfachAddress::getType)
 							.containsExactly(POSTFACH_ADDRESS_DEFAULT);
 				}
-
-				private List<PostfachAddress> getPostfachAddresses() {
-					return buildServiceKonto(formDataWithBadRestResponseName).getPostfachAddresses();
-				}
 			}
 
 			@DisplayName("without rest_response_name")
-- 
GitLab


From aec75ff196beaca13e0b5785021f656e68aae71c Mon Sep 17 00:00:00 2001
From: Jan Zickermann <jan.zickermann@dataport.de>
Date: Fri, 25 Apr 2025 11:35:20 +0200
Subject: [PATCH 3/3] OZG-7978 servicekonto: Avoid try catch block

---
 .../semantik/common/ServiceKontoFactory.java  | 29 ++++++++++++-------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java
index 8f9aa3d8b..41a984e1a 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/common/ServiceKontoFactory.java
@@ -23,11 +23,13 @@
  */
 package de.ozgcloud.eingang.semantik.common;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.apache.commons.collections.MapUtils;
 import org.springframework.stereotype.Component;
@@ -102,21 +104,28 @@ public class ServiceKontoFactory {
 	}
 
 	int getPostfachAddressType(Map<String, Object> restResponseName) {
-		try {
-			return getMailboxType(restResponseName);
-		} catch (RuntimeException e) {
-			LOG.error("Error while getting mailbox type from rest response name", e);
-			return POSTFACH_ADDRESS_DEFAULT;
-		}
+		return getMailboxType(restResponseName)
+				.orElseGet(() -> {
+					LOG.warn("Mailbox type not found in rest_response_name! Using default value '{}'", POSTFACH_ADDRESS_DEFAULT);
+					return POSTFACH_ADDRESS_DEFAULT;
+				});
 	}
 
-	private Integer getMailboxType(Map<String, Object> restResponseName) {
-		return (Integer) getMemberScope(restResponseName).get(REST_RESPONSE_NAME_MEMBER_SCOPE_MAILBOX_TYPE);
+	private Optional<Integer> getMailboxType(Map<String, Object> restResponseName) {
+		return getMemberScope(restResponseName)
+				.map(scope -> scope.get(REST_RESPONSE_NAME_MEMBER_SCOPE_MAILBOX_TYPE))
+				.filter(Integer.class::isInstance)
+				.map(Integer.class::cast);
 	}
 
 	@SuppressWarnings("unchecked")
-	private Map<String, Object> getMemberScope(Map<String, Object> restResponseName) {
-		return ((List<Map<String, Object>>) restResponseName.get(REST_RESPONSE_NAME_MEMBER_SCOPE)).get(0);
+	private Optional<Map<String, Object>> getMemberScope(Map<String, Object> restResponseName) {
+		return Optional.ofNullable(restResponseName.get(REST_RESPONSE_NAME_MEMBER_SCOPE))
+				.filter(List.class::isInstance)
+				.map(List.class::cast)
+				.map(Collection::stream)
+				.flatMap(Stream::findFirst)
+				.filter(Map.class::isInstance);
 	}
 
 	public Optional<ServiceKonto> createBayernIdServiceKonto(Map<String, Object> formDataHeaders) {
-- 
GitLab