From 8be728f29621c120eeac17f96e638618563ebbe7 Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Wed, 22 Nov 2023 10:36:53 +0100
Subject: [PATCH] OZG-4606 implement ozgcloud user service

---
 api-lib-core/pom.xml                          |  8 +++
 .../user/GrpcOzgCloudUserProfileService.java  | 26 ++++++++
 .../apilib/user/OzgCloudUserProfile.java      | 15 +++++
 .../user/OzgCloudUserProfileService.java      |  6 ++
 .../apilib/user/UserProfileMapper.java        | 16 +++++
 ...GrpcGetUserProfileResponseTestFactory.java | 15 +++++
 .../GrpcOzgCloudUserProfileServiceTest.java   | 64 +++++++++++++++++++
 .../user/GrpcUserProfileTestFactory.java      | 20 ++++++
 .../user/OzgCloudUserProfileTestFactory.java  | 23 +++++++
 .../OzgCloudClientAutoConfiguration.java      | 25 ++++++--
 pom.xml                                       |  1 +
 11 files changed, 212 insertions(+), 7 deletions(-)
 create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileService.java
 create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfile.java
 create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfileService.java
 create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/user/UserProfileMapper.java
 create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcGetUserProfileResponseTestFactory.java
 create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileServiceTest.java
 create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcUserProfileTestFactory.java
 create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/user/OzgCloudUserProfileTestFactory.java

diff --git a/api-lib-core/pom.xml b/api-lib-core/pom.xml
index d9dac23..04fe74c 100644
--- a/api-lib-core/pom.xml
+++ b/api-lib-core/pom.xml
@@ -17,6 +17,8 @@
 		<maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
 		<maven-failsafe-plugin.version>3.1.2</maven-failsafe-plugin.version>
 		<jacoco.plugin.version>0.8.10</jacoco.plugin.version>
+		
+		<user-manager.version>2.0.0-SNAPSHOT</user-manager.version>
 	</properties>
 
 	<dependencies>
@@ -39,6 +41,12 @@
 			<groupId>de.itvsh.ozg.pluto</groupId>
 			<artifactId>pluto-utils</artifactId>
 		</dependency>
+		
+		<dependency>
+			<groupId>de.ozgcloud.user</groupId>
+			<artifactId>user-manager-interface</artifactId>
+			<version>${user-manager.version}</version>
+		</dependency>
 
 		<!--spring -->
 		<dependency>
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileService.java
new file mode 100644
index 0000000..549ac07
--- /dev/null
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileService.java
@@ -0,0 +1,26 @@
+package de.ozgcloud.apilib.user;
+
+import de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub;
+import de.ozgcloud.user.userprofile.GrpcGetUserProfileRequest;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public class GrpcOzgCloudUserProfileService implements OzgCloudUserProfileService {
+
+	private final UserProfileServiceBlockingStub serviceStub;
+
+	private final UserProfileMapper mapper;
+
+	@Override
+	public OzgCloudUserProfile getById(OzgCloudUserId userId) {
+		var grpcUserProfileResponse = serviceStub.getById(buildGetUserRequest(userId));
+
+		return mapper.mapFromGrpc(grpcUserProfileResponse.getUserProfile());
+	}
+
+	private GrpcGetUserProfileRequest buildGetUserRequest(OzgCloudUserId id) {
+		return GrpcGetUserProfileRequest.newBuilder()
+				.setUserId(id.toString())
+				.build();
+	}
+}
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfile.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfile.java
new file mode 100644
index 0000000..f8c9089
--- /dev/null
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfile.java
@@ -0,0 +1,15 @@
+package de.ozgcloud.apilib.user;
+
+import lombok.Builder;
+import lombok.Getter;
+
+@Builder
+@Getter
+public class OzgCloudUserProfile {
+
+	private OzgCloudUserId id;
+
+	private String firstName;
+	private String lastName;
+	private String email;
+}
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfileService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfileService.java
new file mode 100644
index 0000000..a769f63
--- /dev/null
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/OzgCloudUserProfileService.java
@@ -0,0 +1,6 @@
+package de.ozgcloud.apilib.user;
+
+public interface OzgCloudUserProfileService {
+
+	public OzgCloudUserProfile getById(OzgCloudUserId userId);
+}
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/user/UserProfileMapper.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/UserProfileMapper.java
new file mode 100644
index 0000000..5ae1f4e
--- /dev/null
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/user/UserProfileMapper.java
@@ -0,0 +1,16 @@
+package de.ozgcloud.apilib.user;
+
+import org.mapstruct.Mapper;
+
+import de.ozgcloud.user.userprofile.GrpcUserProfile;
+import lombok.NonNull;
+
+@Mapper
+public interface UserProfileMapper {
+
+	OzgCloudUserProfile mapFromGrpc(GrpcUserProfile userProfile);
+
+	default OzgCloudUserId toOzgCloudUserId(@NonNull String id) {
+		return OzgCloudUserId.from(id);
+	}
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcGetUserProfileResponseTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcGetUserProfileResponseTestFactory.java
new file mode 100644
index 0000000..3c9ec6e
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcGetUserProfileResponseTestFactory.java
@@ -0,0 +1,15 @@
+package de.ozgcloud.apilib.user;
+
+import de.ozgcloud.user.userprofile.GrpcGetUserProfileResponse;
+
+public class GrpcGetUserProfileResponseTestFactory {
+
+	public static GrpcGetUserProfileResponse create() {
+		return createBuilder().build();
+	}
+
+	public static GrpcGetUserProfileResponse.Builder createBuilder() {
+		return GrpcGetUserProfileResponse.newBuilder()
+				.setUserProfile(GrpcUserProfileTestFactory.create());
+	}
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileServiceTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileServiceTest.java
new file mode 100644
index 0000000..0e15fa0
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcOzgCloudUserProfileServiceTest.java
@@ -0,0 +1,64 @@
+package de.ozgcloud.apilib.user;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.BeforeEach;
+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.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub;
+import de.ozgcloud.user.userprofile.GrpcGetUserProfileRequest;
+
+class GrpcOzgCloudUserProfileServiceTest {
+
+	@InjectMocks
+	private GrpcOzgCloudUserProfileService service;
+
+	@Mock
+	private UserProfileServiceBlockingStub userProfileServiceStub;
+	@Mock
+	private UserProfileMapper mapper;
+
+	@Nested
+	class TestGetById {
+		@Captor
+		private ArgumentCaptor<GrpcGetUserProfileRequest> requestCaptor;
+
+		private OzgCloudUserProfile mappedUserProfile = OzgCloudUserProfileTestFactory.create();
+
+		@BeforeEach
+		void init() {
+			when(userProfileServiceStub.getById(any())).thenReturn(GrpcGetUserProfileResponseTestFactory.create());
+			when(mapper.mapFromGrpc(any())).thenReturn(mappedUserProfile);
+		}
+
+		@Test
+		void shouldCallStub() {
+			service.getById(OzgCloudUserProfileTestFactory.ID);
+
+			verify(userProfileServiceStub).getById(requestCaptor.capture());
+			assertThat(requestCaptor.getValue().getUserId()).isEqualTo(OzgCloudUserProfileTestFactory.ID.toString());
+		}
+
+		@Test
+		void shouldCallMapper() {
+			service.getById(OzgCloudUserProfileTestFactory.ID);
+
+			verify(mapper).mapFromGrpc(any());
+		}
+
+		@Test
+		void shouldReturnResult() {
+			var result = service.getById(OzgCloudUserProfileTestFactory.ID);
+
+			assertThat(result).isSameAs(mappedUserProfile);
+		}
+	}
+
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcUserProfileTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcUserProfileTestFactory.java
new file mode 100644
index 0000000..b34ec0e
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/GrpcUserProfileTestFactory.java
@@ -0,0 +1,20 @@
+package de.ozgcloud.apilib.user;
+
+import static de.ozgcloud.apilib.user.OzgCloudUserProfileTestFactory.*;
+
+import de.ozgcloud.user.userprofile.GrpcUserProfile;
+
+public class GrpcUserProfileTestFactory {
+
+	public static GrpcUserProfile create() {
+		return createBuilder().build();
+	}
+
+	public static GrpcUserProfile.Builder createBuilder() {
+		return GrpcUserProfile.newBuilder()
+				.setId(ID.toString())
+				.setFirstName(FIRST_NAME)
+				.setLastName(LAST_NAME);
+
+	}
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/user/OzgCloudUserProfileTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/OzgCloudUserProfileTestFactory.java
new file mode 100644
index 0000000..ecd77ac
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/user/OzgCloudUserProfileTestFactory.java
@@ -0,0 +1,23 @@
+package de.ozgcloud.apilib.user;
+
+import java.util.UUID;
+
+public class OzgCloudUserProfileTestFactory {
+
+	public static final OzgCloudUserId ID = OzgCloudUserId.from(UUID.randomUUID().toString());
+	public static final String FIRST_NAME = "Theo";
+	public static final String LAST_NAME = "Test";
+	public static final String EMAIL = "theo@local";
+
+	public static OzgCloudUserProfile create() {
+		return createBuilder().build();
+	}
+
+	public static OzgCloudUserProfile.OzgCloudUserProfileBuilder createBuilder() {
+		return OzgCloudUserProfile.builder()
+				.id(ID)
+				.firstName(FIRST_NAME)
+				.lastName(LAST_NAME)
+				.email(EMAIL);
+	}
+}
diff --git a/ozg-cloud-spring-boot-starter/src/main/java/de/ozgcloud/client/autoconfigure/OzgCloudClientAutoConfiguration.java b/ozg-cloud-spring-boot-starter/src/main/java/de/ozgcloud/client/autoconfigure/OzgCloudClientAutoConfiguration.java
index de90768..c471069 100644
--- a/ozg-cloud-spring-boot-starter/src/main/java/de/ozgcloud/client/autoconfigure/OzgCloudClientAutoConfiguration.java
+++ b/ozg-cloud-spring-boot-starter/src/main/java/de/ozgcloud/client/autoconfigure/OzgCloudClientAutoConfiguration.java
@@ -25,12 +25,16 @@ import de.ozgcloud.apilib.common.command.grpc.CommandMapper;
 import de.ozgcloud.apilib.common.command.grpc.GrpcOzgCloudCommandService;
 import de.ozgcloud.apilib.file.dummy.DummyOzgCloudFileService;
 import de.ozgcloud.apilib.file.grpc.GrpcOzgCloudFileService;
+import de.ozgcloud.apilib.user.GrpcOzgCloudUserProfileService;
+import de.ozgcloud.apilib.user.OzgCloudUserProfileService;
+import de.ozgcloud.apilib.user.UserProfileMapper;
 import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper;
 import de.ozgcloud.apilib.vorgang.OzgCloudVorgangService;
 import de.ozgcloud.apilib.vorgang.dummy.DummyVorgangService;
 import de.ozgcloud.apilib.vorgang.grpc.GrpcOzgCloudVorgangService;
 import de.ozgcloud.apilib.vorgang.grpc.OzgCloudVorgangMapper;
 import de.ozgcloud.apilib.vorgang.grpc.OzgCloudVorgangStubMapper;
+import de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceBlockingStub;
 import net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration;
 import net.devh.boot.grpc.client.config.GrpcChannelProperties;
 import net.devh.boot.grpc.client.config.GrpcChannelsProperties;
@@ -56,10 +60,10 @@ public class OzgCloudClientAutoConfiguration {
 	@Autowired
 	private OzgCloudCommandManagerProperties commandManagerProperties;
 
-	//	@Bean
-	//	@ConditionalOnProperty("ozgcloud.vorgang-manager.address")
+	// @Bean
+	// @ConditionalOnProperty("ozgcloud.vorgang-manager.address")
 	GrpcChannelsProperties channelProperties(GrpcChannelsProperties properties) {
-		//		var properties = new GrpcChannelsProperties();
+		// var properties = new GrpcChannelsProperties();
 		var clientMap = properties.getClient();
 
 		addVorgangManager(clientMap);
@@ -111,8 +115,8 @@ public class OzgCloudClientAutoConfiguration {
 	@Bean("ozgCloudVorgangService")
 	@ConditionalOnProperty("ozgcloud.vorgang-manager.address")
 	OzgCloudVorgangService grpcOzgCloudVorgangService(VorgangServiceBlockingStub vorgangServiceStub,
-		OzgCloudVorgangMapper mapper,
-		OzgCloudVorgangStubMapper stubMapper, OzgCloudCallContextProvider contextProvider) {
+			OzgCloudVorgangMapper mapper,
+			OzgCloudVorgangStubMapper stubMapper, OzgCloudCallContextProvider contextProvider) {
 
 		return new GrpcOzgCloudVorgangService(vorgangServiceStub, mapper, stubMapper, contextProvider);
 	}
@@ -141,9 +145,9 @@ public class OzgCloudClientAutoConfiguration {
 	@Bean
 	@ConditionalOnProperty("ozgcloud.command-manager.address")
 	OzgCloudCommandService grpcOzgCloudCommandService(@GrpcClient("command-manager") CommandServiceBlockingStub commandServiceStub,
-		CommandMapper commandMapper, OzgCloudCallContextProvider contextProvider) {
+			CommandMapper commandMapper, OzgCloudCallContextProvider contextProvider) {
 		return new GrpcOzgCloudCommandService(commandServiceStub, commandMapper, contextProvider,
-			GrpcOzgCloudCommandService.DEFAULT_COMMAND_REQUEST_THRESHOLD_MILLIS);
+				GrpcOzgCloudCommandService.DEFAULT_COMMAND_REQUEST_THRESHOLD_MILLIS);
 	}
 
 	@Bean
@@ -163,4 +167,11 @@ public class OzgCloudClientAutoConfiguration {
 	AlfaService alfaService() {
 		return new DummyAlfaService();
 	}
+
+	@Bean
+	@ConditionalOnProperty("ozgcloud.user-manager.address")
+	OzgCloudUserProfileService grpcOzgCloudUserProfileService(@GrpcClient("user-manager") UserProfileServiceBlockingStub grpcStub,
+			UserProfileMapper mapper) {
+		return new GrpcOzgCloudUserProfileService(grpcStub, mapper);
+	}
 }
diff --git a/pom.xml b/pom.xml
index 5eb6fa5..b943bbf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,7 @@
 					</execution>
 				</executions>
 			</plugin>
+			
 		</plugins>
 	</build>
 
-- 
GitLab