From 248cabeebca275bcd3092256f960762f6ef15895 Mon Sep 17 00:00:00 2001
From: Felix Reichenbach <felix.reichenbach@mgm-tp.com>
Date: Fri, 7 Feb 2025 10:00:00 +0100
Subject: [PATCH] OZG-6354 use correct zufi interface to get
 Organisationseinheit

---
 lombok.config                                 |  3 +-
 pom.xml                                       | 14 +--
 .../OrganisationsEinheitRemoteService.java    | 26 +++--
 .../eingang/common/zufi/ZufiService.java      |  2 +-
 ...ltipleOrganisationsEinheitenException.java | 34 +++++++
 ...nisationsEinheitIdRequestTestFactory.java} | 17 ++--
 ...nisationsEinheitIdResponseTestFactory.java | 41 ++++++++
 ...OrganisationsEinheitRemoteServiceTest.java | 94 ++++++++++++-------
 .../eingang/common/zufi/ZufiServiceTest.java  |  4 +-
 9 files changed, 175 insertions(+), 60 deletions(-)
 create mode 100644 router/src/main/java/de/ozgcloud/eingang/router/errorhandling/MultipleOrganisationsEinheitenException.java
 rename router/src/test/java/de/ozgcloud/eingang/common/zufi/{GrpcOrganisationsEinheitGetResponseTestFactory.java => GrpcGetByOrganisationsEinheitIdRequestTestFactory.java} (63%)
 create mode 100644 router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcGetByOrganisationsEinheitIdResponseTestFactory.java

diff --git a/lombok.config b/lombok.config
index 32903abaf..d248ae3c4 100644
--- a/lombok.config
+++ b/lombok.config
@@ -27,4 +27,5 @@ lombok.log.slf4j.flagUsage = ERROR
 lombok.log.log4j.flagUsage = ERROR
 lombok.data.flagUsage = ERROR
 lombok.nonNull.exceptionType = IllegalArgumentException
-lombok.addLombokGeneratedAnnotation = true
\ No newline at end of file
+lombok.addLombokGeneratedAnnotation = true
+lombok.copyableAnnotations += net.devh.boot.grpc.client.inject.GrpcClient
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 700589324..8629c9353 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,9 @@
     unter der Lizenz sind dem Lizenztext zu entnehmen.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 
 	<modelVersion>4.0.0</modelVersion>
 
@@ -32,7 +34,7 @@
 		<groupId>de.ozgcloud.common</groupId>
 		<artifactId>ozgcloud-common-parent</artifactId>
 		<version>4.9.0</version>
-		<relativePath/> <!-- lookup parent from repository -->
+		<relativePath /> <!-- lookup parent from repository -->
 	</parent>
 
 	<groupId>de.ozgcloud.eingang</groupId>
@@ -48,12 +50,12 @@
 		<module>semantik-adapter</module>
 		<module>formcycle-adapter</module>
 		<module>enterprise-adapter</module>
-        <module>fim-adapter</module>
-    </modules>
+		<module>fim-adapter</module>
+	</modules>
 
 	<properties>
 		<vorgang-manager.version>2.10.0</vorgang-manager.version>
-		<zufi-manager.version>1.2.0</zufi-manager.version>
+		<zufi-manager.version>1.7.0-SNAPSHOT</zufi-manager.version>
 
 		<jsoup.version>1.14.3</jsoup.version>
 		<xmlschema.version>2.3.0</xmlschema.version>
@@ -205,4 +207,4 @@
 		</snapshotRepository>
 	</distributionManagement>
 
-</project>
+</project>
\ No newline at end of file
diff --git a/router/src/main/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteService.java b/router/src/main/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteService.java
index c7e01f4c1..e42d5d210 100644
--- a/router/src/main/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteService.java
+++ b/router/src/main/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteService.java
@@ -23,25 +23,33 @@
  */
 package de.ozgcloud.eingang.common.zufi;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.eingang.Application;
-import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcOrganisationsEinheitGetRequest;
+import de.ozgcloud.eingang.router.errorhandling.MultipleOrganisationsEinheitenException;
+import de.ozgcloud.eingang.router.errorhandling.UnknownOrganisationseinheitException;
+import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcGetByOrganisationsEinheitIdRequest;
 import de.ozgcloud.zufi.grpc.organisationseinheit.OrganisationsEinheitServiceGrpc.OrganisationsEinheitServiceBlockingStub;
+import lombok.RequiredArgsConstructor;
 import net.devh.boot.grpc.client.inject.GrpcClient;
 
 @Service
+@RequiredArgsConstructor
 class OrganisationsEinheitRemoteService {
 
 	@GrpcClient(Application.ZUFI_MANAGER_GRPC_CLIENT)
-	private OrganisationsEinheitServiceBlockingStub serviceStub;
-	@Autowired
-	private OrganisationsEinheitMapper mapper;
+	private final OrganisationsEinheitServiceBlockingStub serviceStub;
+	private final OrganisationsEinheitMapper mapper;
 
-	public OrganisationsEinheit getById(String id) {
-		var response = serviceStub.getById(GrpcOrganisationsEinheitGetRequest.newBuilder().setId(id).build());
-
-		return mapper.fromGrpc(response.getOrganisationsEinheit());
+	public OrganisationsEinheit getByOrganisationEinheitId(String id) {
+		var response = serviceStub
+				.getByOrganisationsEinheitId(GrpcGetByOrganisationsEinheitIdRequest.newBuilder().setOrganisationsEinheitId(id).build());
+		if (response.getOrganisationsEinheitenCount() > 1) {
+			throw new MultipleOrganisationsEinheitenException(id);
+		}
+		if (response.getOrganisationsEinheitenCount() == 0) {
+			throw new UnknownOrganisationseinheitException();
+		}
+		return mapper.fromGrpc(response.getOrganisationsEinheitenList().get(0));
 	}
 }
diff --git a/router/src/main/java/de/ozgcloud/eingang/common/zufi/ZufiService.java b/router/src/main/java/de/ozgcloud/eingang/common/zufi/ZufiService.java
index 96e89340a..c015f0e10 100644
--- a/router/src/main/java/de/ozgcloud/eingang/common/zufi/ZufiService.java
+++ b/router/src/main/java/de/ozgcloud/eingang/common/zufi/ZufiService.java
@@ -34,6 +34,6 @@ public class ZufiService {
 	private final OrganisationsEinheitRemoteService remoteService;
 
 	public String getVorgangManagerUrl(String organisationsEinheitId) {
-		return remoteService.getById(organisationsEinheitId).getVorgangManagerAddress();
+		return remoteService.getByOrganisationEinheitId(organisationsEinheitId).getVorgangManagerAddress();
 	}
 }
\ No newline at end of file
diff --git a/router/src/main/java/de/ozgcloud/eingang/router/errorhandling/MultipleOrganisationsEinheitenException.java b/router/src/main/java/de/ozgcloud/eingang/router/errorhandling/MultipleOrganisationsEinheitenException.java
new file mode 100644
index 000000000..e59a88e4b
--- /dev/null
+++ b/router/src/main/java/de/ozgcloud/eingang/router/errorhandling/MultipleOrganisationsEinheitenException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.eingang.router.errorhandling;
+
+public class MultipleOrganisationsEinheitenException extends RuntimeException {
+
+	private static final long serialVersionUID = 1L;
+
+	public MultipleOrganisationsEinheitenException(String organisationEinheitId) {
+		super("Multiple Organisationseinheiten with Id %s found!".formatted(organisationEinheitId));
+	}
+
+}
diff --git a/router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcOrganisationsEinheitGetResponseTestFactory.java b/router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcGetByOrganisationsEinheitIdRequestTestFactory.java
similarity index 63%
rename from router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcOrganisationsEinheitGetResponseTestFactory.java
rename to router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcGetByOrganisationsEinheitIdRequestTestFactory.java
index d74aa9d39..234b90f18 100644
--- a/router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcOrganisationsEinheitGetResponseTestFactory.java
+++ b/router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcGetByOrganisationsEinheitIdRequestTestFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
  * Ministerpräsidenten des Landes Schleswig-Holstein
  * Staatskanzlei
  * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
@@ -23,16 +23,17 @@
  */
 package de.ozgcloud.eingang.common.zufi;
 
-import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcOrganisationsEinheitGetResponse;
+import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcGetByOrganisationsEinheitIdRequest;
 
-public class GrpcOrganisationsEinheitGetResponseTestFactory {
+public class GrpcGetByOrganisationsEinheitIdRequestTestFactory {
 
-	public static GrpcOrganisationsEinheitGetResponse create() {
+	private static final String ORGANISATION_EINHEIT_ID = OrganisationsEinheitTestFactory.ID;
+
+	public static GrpcGetByOrganisationsEinheitIdRequest create() {
 		return createBuilder().build();
 	}
 
-	public static GrpcOrganisationsEinheitGetResponse.Builder createBuilder() {
-		return GrpcOrganisationsEinheitGetResponse.newBuilder()
-				.setOrganisationsEinheit(GrpcOrganisationsEinheitTestFactory.create());
+	public static GrpcGetByOrganisationsEinheitIdRequest.Builder createBuilder() {
+		return GrpcGetByOrganisationsEinheitIdRequest.newBuilder().setOrganisationsEinheitId(ORGANISATION_EINHEIT_ID);
 	}
-}
\ No newline at end of file
+}
diff --git a/router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcGetByOrganisationsEinheitIdResponseTestFactory.java b/router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcGetByOrganisationsEinheitIdResponseTestFactory.java
new file mode 100644
index 000000000..df5cfb822
--- /dev/null
+++ b/router/src/test/java/de/ozgcloud/eingang/common/zufi/GrpcGetByOrganisationsEinheitIdResponseTestFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.eingang.common.zufi;
+
+import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcGetByOrganisationsEinheitIdResponse;
+import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcOrganisationsEinheit;
+
+public class GrpcGetByOrganisationsEinheitIdResponseTestFactory {
+
+	public static final GrpcOrganisationsEinheit ORGANISATIONS_EINHEIT = GrpcOrganisationsEinheitTestFactory.create();
+
+	public static GrpcGetByOrganisationsEinheitIdResponse create() {
+		return createBuilder().build();
+	}
+
+	public static GrpcGetByOrganisationsEinheitIdResponse.Builder createBuilder() {
+		return GrpcGetByOrganisationsEinheitIdResponse.newBuilder()
+				.addOrganisationsEinheiten(ORGANISATIONS_EINHEIT);
+	}
+}
\ No newline at end of file
diff --git a/router/src/test/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteServiceTest.java b/router/src/test/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteServiceTest.java
index 6c25468db..3561c1f85 100644
--- a/router/src/test/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteServiceTest.java
+++ b/router/src/test/java/de/ozgcloud/eingang/common/zufi/OrganisationsEinheitRemoteServiceTest.java
@@ -28,19 +28,14 @@ import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 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.mockito.ArgumentCaptor;
-import org.mockito.Captor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 
-import de.ozgcloud.eingang.common.zufi.OrganisationsEinheit;
-import de.ozgcloud.eingang.common.zufi.OrganisationsEinheitMapper;
-import de.ozgcloud.eingang.common.zufi.OrganisationsEinheitRemoteService;
-import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcOrganisationsEinheitGetRequest;
-import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcOrganisationsEinheitGetResponse;
+import de.ozgcloud.eingang.router.errorhandling.MultipleOrganisationsEinheitenException;
+import de.ozgcloud.eingang.router.errorhandling.UnknownOrganisationseinheitException;
+import de.ozgcloud.zufi.grpc.organisationseinheit.GrpcGetByOrganisationsEinheitIdResponse;
 import de.ozgcloud.zufi.grpc.organisationseinheit.OrganisationsEinheitServiceGrpc.OrganisationsEinheitServiceBlockingStub;
 
 class OrganisationsEinheitRemoteServiceTest {
@@ -52,42 +47,75 @@ class OrganisationsEinheitRemoteServiceTest {
 	@Mock
 	private OrganisationsEinheitMapper mapper;
 
-	@DisplayName("Get by id")
 	@Nested
-	class TestGetById {
+	class TestGetByOrganisationEinheitId {
 
-		private final GrpcOrganisationsEinheitGetResponse response = GrpcOrganisationsEinheitGetResponseTestFactory.create();
-		private final OrganisationsEinheit mappedOrganisationsEinheit = OrganisationsEinheitTestFactory.create();
+		@Nested
+		class TestOnSingleOrganisationEinheitFound {
 
-		@BeforeEach
-		void mock() {
-			when(stub.getById(any())).thenReturn(response);
-			when(mapper.fromGrpc(any())).thenReturn(mappedOrganisationsEinheit);
-		}
+			private final GrpcGetByOrganisationsEinheitIdResponse response = GrpcGetByOrganisationsEinheitIdResponseTestFactory.create();
+			private final OrganisationsEinheit mappedOrganisationsEinheit = OrganisationsEinheitTestFactory.create();
+
+			@BeforeEach
+			void mock() {
+				when(stub.getByOrganisationsEinheitId(any())).thenReturn(response);
+				when(mapper.fromGrpc(any())).thenReturn(mappedOrganisationsEinheit);
+			}
+
+			@Test
+			void shouldCallRemoteService() {
+				service.getByOrganisationEinheitId(OrganisationsEinheitTestFactory.ID);
 
-		@Captor
-		private ArgumentCaptor<GrpcOrganisationsEinheitGetRequest> requestCaptor;
+				verify(stub).getByOrganisationsEinheitId(GrpcGetByOrganisationsEinheitIdRequestTestFactory.create());
+			}
 
-		@Test
-		void shouldCallRemoteService() {
-			service.getById(OrganisationsEinheitTestFactory.ID);
+			@Test
+			void shouldCallMapper() {
+				service.getByOrganisationEinheitId(OrganisationsEinheitTestFactory.ID);
 
-			verify(stub).getById(requestCaptor.capture());
-			assertThat(requestCaptor.getValue().getId()).isEqualTo(OrganisationsEinheitTestFactory.ID);
+				verify(mapper).fromGrpc(GrpcGetByOrganisationsEinheitIdResponseTestFactory.ORGANISATIONS_EINHEIT);
+			}
+
+			@Test
+			void shouldReturnValue() {
+				var organisationsEinheit = service.getByOrganisationEinheitId(OrganisationsEinheitTestFactory.ID);
+
+				assertThat(organisationsEinheit).isEqualTo(mappedOrganisationsEinheit);
+			}
 		}
 
-		@Test
-		void shouldCallMapper() {
-			service.getById(OrganisationsEinheitTestFactory.ID);
+		@Nested
+		class TestOnMultipleOrganisationEinheitFound {
+
+			private final GrpcGetByOrganisationsEinheitIdResponse response = GrpcGetByOrganisationsEinheitIdResponseTestFactory.createBuilder()
+					.addOrganisationsEinheiten(GrpcOrganisationsEinheitTestFactory.create())
+					.build();
 
-			verify(mapper).fromGrpc(response.getOrganisationsEinheit());
+			@Test
+			void shouldThrowMultipleOrganisationsEinheitenException() {
+				when(stub.getByOrganisationsEinheitId(any())).thenReturn(response);
+
+				assertThatExceptionOfType(MultipleOrganisationsEinheitenException.class)
+						.isThrownBy(() -> service.getByOrganisationEinheitId(OrganisationsEinheitTestFactory.ID));
+
+			}
 		}
 
-		@Test
-		void shouldReturnValue() {
-			var organisationsEinheit = service.getById(OrganisationsEinheitTestFactory.ID);
+		@Nested
+		class TestOnNoOrganisationEinheitFound {
+
+			private final GrpcGetByOrganisationsEinheitIdResponse response = GrpcGetByOrganisationsEinheitIdResponseTestFactory.createBuilder()
+					.clearOrganisationsEinheiten()
+					.build();
+
+			@Test
+			void shouldThrowUnknownOrganisationseinheitException() {
+				when(stub.getByOrganisationsEinheitId(any())).thenReturn(response);
+
+				assertThatExceptionOfType(UnknownOrganisationseinheitException.class)
+						.isThrownBy(() -> service.getByOrganisationEinheitId(OrganisationsEinheitTestFactory.ID));
 
-			assertThat(organisationsEinheit).isEqualTo(mappedOrganisationsEinheit);
+			}
 		}
 	}
-}
+}
\ No newline at end of file
diff --git a/router/src/test/java/de/ozgcloud/eingang/common/zufi/ZufiServiceTest.java b/router/src/test/java/de/ozgcloud/eingang/common/zufi/ZufiServiceTest.java
index c89a22966..5348135ee 100644
--- a/router/src/test/java/de/ozgcloud/eingang/common/zufi/ZufiServiceTest.java
+++ b/router/src/test/java/de/ozgcloud/eingang/common/zufi/ZufiServiceTest.java
@@ -49,14 +49,14 @@ class ZufiServiceTest {
 
 		@BeforeEach
 		void mock() {
-			when(remoteService.getById(any())).thenReturn(organisationsEinheit);
+			when(remoteService.getByOrganisationEinheitId(any())).thenReturn(organisationsEinheit);
 		}
 
 		@Test
 		void shouldCallRemoteService() {
 			service.getVorgangManagerUrl(OrganisationsEinheitTestFactory.ID);
 
-			verify(remoteService).getById(OrganisationsEinheitTestFactory.ID);
+			verify(remoteService).getByOrganisationEinheitId(OrganisationsEinheitTestFactory.ID);
 		}
 
 		@Test
-- 
GitLab