From d6ad9337e771941a90e62fa2b5866acb48b12809 Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Sat, 4 Feb 2023 11:39:58 +0100 Subject: [PATCH] OZG-2220 grpc for retrieving all supported Organisationseinheit IDs Sub-task: OZG-3411 --- TODO | 7 ++++ .../proto/organisationseinheit.model.proto | 34 +++++++++++++++ .../src/main/proto/organisationseinheit.proto | 40 ++++++++++++++++++ .../de/itvsh/kop/user/UserRepository.java | 8 ++++ .../java/de/itvsh/kop/user/UserService.java | 5 +++ .../OrganisationsEinheitGrpcService.java | 33 +++++++++++++++ .../itvsh/kop/user/UserRepositoryITCase.java | 19 +++++++++ .../de/itvsh/kop/user/UserRepositoryTest.java | 27 ++++++++++++ .../de/itvsh/kop/user/UserServiceTest.java | 12 ++++++ .../OrganisationseinheitGrpcServiceTest.java | 41 +++++++++++++++++++ 10 files changed, 226 insertions(+) create mode 100644 TODO create mode 100644 user-manager-interface/src/main/proto/organisationseinheit.model.proto create mode 100644 user-manager-interface/src/main/proto/organisationseinheit.proto create mode 100644 user-manager-server/src/main/java/de/itvsh/kop/user/organisationseinheit/OrganisationsEinheitGrpcService.java create mode 100644 user-manager-server/src/test/java/de/itvsh/kop/user/organisationseinheit/OrganisationseinheitGrpcServiceTest.java diff --git a/TODO b/TODO new file mode 100644 index 00000000..06a068d1 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +- naming: OrganisationsEinheit, OrganisationEinheit, Organisationseinheit +- package structure to distinguish http api, internal service grpc communication and domain, service, repository layers +- Console logs switch to regular line by line instead of JSON entries. For local development only. +- User managers needs to know it external hostname/address used by clients in order to put it in HAL response. So that the further REST calls are made to proper URI. + -> either frontend sends the URL in request + -> or find out something else +- package sync service -> user service Verletzung sync service soll kein user service nutzten \ No newline at end of file diff --git a/user-manager-interface/src/main/proto/organisationseinheit.model.proto b/user-manager-interface/src/main/proto/organisationseinheit.model.proto new file mode 100644 index 00000000..6e0dbc0a --- /dev/null +++ b/user-manager-interface/src/main/proto/organisationseinheit.model.proto @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 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. + */ +syntax = "proto3"; + +package de.itvsh.kop.user.grpc; + +option java_multiple_files = true; +option java_package = "de.itvsh.kop.user.organisationseinheit"; +option java_outer_classname = "OrganisationsEinheitModelProto"; + +message GrpcOrganisationsEinheit { + string organisationsEinheitId = 1; +} \ No newline at end of file diff --git a/user-manager-interface/src/main/proto/organisationseinheit.proto b/user-manager-interface/src/main/proto/organisationseinheit.proto new file mode 100644 index 00000000..450aee5f --- /dev/null +++ b/user-manager-interface/src/main/proto/organisationseinheit.proto @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 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. + */ +syntax = "proto3"; +import "google/protobuf/empty.proto"; +import "organisationseinheit.model.proto"; + +package de.itvsh.kop.user.grpc; + +option java_multiple_files = true; +option java_package = "de.itvsh.kop.user.grpc.organisationseinheit"; +option java_outer_classname = "OrganisationsEinheitProto"; + +service OrganisationsEinheitService { + rpc getSupportedOrganisationsEinheiten(google.protobuf.Empty) returns (GrpcGetSupportedOrganisationsEinheitenResponse); +} + +message GrpcGetSupportedOrganisationsEinheitenResponse { + repeated GrpcOrganisationsEinheit organisationseinheiten = 1; +} \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java b/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java index 4db774a6..bb34c979 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java @@ -25,6 +25,7 @@ package de.itvsh.kop.user; import static de.itvsh.kop.user.User.*; +import java.util.Collection; import java.util.Optional; import java.util.stream.Stream; @@ -32,6 +33,9 @@ import javax.enterprise.context.ApplicationScoped; import org.bson.types.ObjectId; +import com.google.common.collect.Lists; +import com.mongodb.client.model.Filters; + import de.itvsh.kop.common.logging.KopLogging; import de.itvsh.kop.user.common.errorhandling.ResourceNotFoundException; import io.quarkus.mongodb.panache.PanacheMongoRepository; @@ -85,4 +89,8 @@ class UserRepository implements PanacheMongoRepository<User> { return findByIdOptional(user.getId()) .orElse(findByExternalId(user.getExternalId()).orElseThrow(() -> new ResourceNotFoundException(User.class, user.getExternalId()))); } + + public Collection<String> findAllOrganisationsEinheitIds() { + return Lists.newArrayList(mongoCollection().distinct(User.ORGANISATIONS_EINHEIT_IDS_FIELD, Filters.eq(DELETED_FIELD, false), String.class)); + } } \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java index 29faba06..1f5b158c 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java @@ -23,6 +23,7 @@ */ package de.itvsh.kop.user; +import java.util.Collection; import java.util.Optional; import java.util.stream.Stream; @@ -92,4 +93,8 @@ public class UserService { public User findByExternalId(String id) { return repository.findByExternalId(id).orElseThrow(() -> new ResourceNotFoundException(User.class, id)); } + + public Collection<String> findAllOrganisationsEinheitIds() { + return repository.findAllOrganisationsEinheitIds(); + } } \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/organisationseinheit/OrganisationsEinheitGrpcService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/organisationseinheit/OrganisationsEinheitGrpcService.java new file mode 100644 index 00000000..0e7e0ee2 --- /dev/null +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/organisationseinheit/OrganisationsEinheitGrpcService.java @@ -0,0 +1,33 @@ +package de.itvsh.kop.user.organisationseinheit; + +import java.util.Collection; + +import javax.inject.Inject; + +import com.google.protobuf.Empty; + +import de.itvsh.kop.user.UserService; +import de.itvsh.kop.user.grpc.organisationseinheit.GrpcGetSupportedOrganisationsEinheitenResponse; +import de.itvsh.kop.user.grpc.organisationseinheit.OrganisationsEinheitServiceGrpc; +import io.grpc.stub.StreamObserver; + +public class OrganisationsEinheitGrpcService extends OrganisationsEinheitServiceGrpc.OrganisationsEinheitServiceImplBase { + + @Inject + private UserService userService; + + @Override + public void getSupportedOrganisationsEinheiten(Empty request, StreamObserver<GrpcGetSupportedOrganisationsEinheitenResponse> responseObserver) { + var organisationsEinheitIds = userService.findAllOrganisationsEinheitIds(); + var response = GrpcGetSupportedOrganisationsEinheitenResponse.newBuilder() + .addAllOrganisationseinheiten(mapToGrpc(organisationsEinheitIds)) + .build(); + + responseObserver.onNext(response); + responseObserver.onCompleted(); + } + + private Collection<GrpcOrganisationsEinheit> mapToGrpc(Collection<String> organisationsEinheitIds) { + return organisationsEinheitIds.stream().map(id -> GrpcOrganisationsEinheit.newBuilder().setOrganisationsEinheitId(id).build()).toList(); + } +} diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java index 3189e0c7..560504e7 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java @@ -38,6 +38,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import com.google.common.collect.Lists; import com.thedeanda.lorem.LoremIpsum; import de.itvsh.kop.user.common.MongoDbTestProfile; @@ -322,4 +323,22 @@ class UserRepositoryITCase { assertThat(user).usingRecursiveComparison().ignoringFields("id").isEqualTo(UserTestFactory.create()); } } + + @Nested + @DisplayName("Test finding all Organisationseinheiten IDs") + class TestFindAllOrganisationsEinheitIds { + @Test + void shouldFindAll() { + repository.persist(UserTestFactory.createBuilder().id(new ObjectId()).organisationsEinheitId("1").build()); + repository.persist(UserTestFactory.createBuilder().id(new ObjectId()).organisationsEinheitIds(Lists.newArrayList("A", "1", "B")).build()); + repository.persist(UserTestFactory.createBuilder().id(new ObjectId()).organisationsEinheitIds(Lists.newArrayList("A", "1", "B")).build()); + repository.persist(UserTestFactory.createBuilder().id(new ObjectId()).organisationsEinheitId("1").build()); + repository.persist(UserTestFactory.createBuilder().id(new ObjectId()).deleted(true).organisationsEinheitId("ABC").build()); + + var result = repository.findAllOrganisationsEinheitIds(); + + assertThat(result).hasSize(4); + assertThat(result).containsExactlyInAnyOrder("1", "A", "B", UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java index 94b1bc55..efa152d1 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Optional; import org.assertj.core.api.Condition; +import org.bson.conversions.Bson; import org.bson.types.ObjectId; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -40,6 +41,11 @@ import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.Spy; +import com.mongodb.client.DistinctIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mongodb.client.model.Filters; + import de.itvsh.kop.user.common.errorhandling.ResourceNotFoundException; import io.quarkus.mongodb.panache.PanacheQuery; import io.quarkus.mongodb.panache.common.PanacheUpdate; @@ -180,4 +186,25 @@ class UserRepositoryTest { assertThatExceptionOfType(ResourceNotFoundException.class).isThrownBy(() -> userRepository.refresh(UserTestFactory.create())); // NOSONAR } } + + @DisplayName("Test find Organisationseinheiten Ids") + @Nested + class TestFindOrganisationsEinheitIds { + + MongoCollection mongoCollection = mock(MongoCollection.class); + MongoCursor mongoCursor = mock(MongoCursor.class); + + @Test + void shouldFindAllOrganisationsEinheitIds() { + var iterable = mock(DistinctIterable.class); + when(iterable.iterator()).thenReturn(mongoCursor); + doReturn(mongoCollection).when(userRepository).mongoCollection(); + when(mongoCursor.next()).thenReturn(""); + when(mongoCollection.distinct(anyString(), any(Bson.class), any())).thenReturn(iterable); + + userRepository.findAllOrganisationsEinheitIds(); + + verify(mongoCollection).distinct(User.ORGANISATIONS_EINHEIT_IDS_FIELD, Filters.eq(User.DELETED_FIELD, false), String.class); + } + } } diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java index 43235c6e..f58b9c9e 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java @@ -204,4 +204,16 @@ class UserServiceTest { verify(repository).findUsers(SEARCH_QUERY, true, LIMIT); } } + + @DisplayName("Get Organisationseinheiten") + @Nested + class TestGetOrganisationsEinheiten { + + @Test + void shouldGetAllOrganisationsEinheitenForAllUsers() { + service.findAllOrganisationsEinheitIds(); + + verify(repository).findAllOrganisationsEinheitIds(); + } + } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/organisationseinheit/OrganisationseinheitGrpcServiceTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/organisationseinheit/OrganisationseinheitGrpcServiceTest.java new file mode 100644 index 00000000..ce249df2 --- /dev/null +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/organisationseinheit/OrganisationseinheitGrpcServiceTest.java @@ -0,0 +1,41 @@ +package de.itvsh.kop.user.organisationseinheit; + +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import com.google.protobuf.Empty; + +import de.itvsh.kop.user.UserService; +import de.itvsh.kop.user.grpc.organisationseinheit.GrpcGetSupportedOrganisationsEinheitenResponse; +import io.grpc.stub.StreamObserver; + +public class OrganisationseinheitGrpcServiceTest { + @InjectMocks + OrganisationsEinheitGrpcService organisationsEinheitGrpcService; + + @Mock + UserService userService; + + @Nested + @DisplayName("Get supported Organisationseinheiten") + class GetSupportedOrganisationsEinheiten { + + @Mock + private StreamObserver<GrpcGetSupportedOrganisationsEinheitenResponse> streamObserver; + + @Test + void shouldGetOrganisationsEinheiten() { + organisationsEinheitGrpcService.getSupportedOrganisationsEinheiten( + Empty.getDefaultInstance(), + streamObserver); + + verify(userService).findAllOrganisationsEinheitIds(); + } + } + +} -- GitLab