From b9863ce6fb2630d42d23e5a49503947034fedc23 Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Thu, 20 Jul 2023 08:54:04 +0200 Subject: [PATCH] make grpc connection optional configurable; add paging --- api-lib-core/pom.xml | 2 +- .../apilib/vorgang/OzgCloudVorgangId.java | 3 + .../vorgang/OzgCloudVorgangIdMapper.java | 9 +++ .../vorgang/OzgCloudVorgangService.java | 2 + .../java/de/ozgcloud/apilib/vorgang/Page.java | 18 +++++ .../vorgang/dummy/DummyVorgangService.java | 7 +- .../vorgang/grpc/GrpcVorgangService.java | 37 +++++++-- .../vorgang/grpc/OzgCloudVorgangMapper.java | 8 +- .../grpc/OzgCloudVorgangStubMapper.java | 18 +++++ .../OzgCloudVorgangStubTestFactory.java | 12 +++ .../grpc/GrpcVorgangHeaderTestFactory.java | 25 ++++++ .../vorgang/grpc/GrpcVorgangServiceTest.java | 79 +++++++++++++++++++ .../src/main/resources/application.yml | 2 +- lombok.config | 4 +- .../OzgCloudClientAutoConfiguration.java | 18 ++++- .../src/main/resources/application.yml | 7 -- 16 files changed, 223 insertions(+), 28 deletions(-) create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangIdMapper.java create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/Page.java create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangStubMapper.java create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangStubTestFactory.java create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangHeaderTestFactory.java delete mode 100644 ozg-cloud-spring-boot-starter/src/main/resources/application.yml diff --git a/api-lib-core/pom.xml b/api-lib-core/pom.xml index 192bc44..41dcf5e 100644 --- a/api-lib-core/pom.xml +++ b/api-lib-core/pom.xml @@ -99,7 +99,7 @@ <showWarnings>true</showWarnings> <compilerArgs> <compilerArg> - -Amapstruct.defaultComponentModel=spring + -Amapstruct.defaultComponentModel=default </compilerArg> <compilerArg> -Amapstruct.unmappedTargetPolicy=WARN diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangId.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangId.java index 62376f9..98b9dc3 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangId.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangId.java @@ -1,5 +1,7 @@ package de.ozgcloud.apilib.vorgang; +import org.mapstruct.ObjectFactory; + import de.itvsh.kop.common.datatype.StringBasedValue; public class OzgCloudVorgangId extends StringBasedValue { @@ -8,6 +10,7 @@ public class OzgCloudVorgangId extends StringBasedValue { super(vorgangId); } + @ObjectFactory public static OzgCloudVorgangId from(String id) { return new OzgCloudVorgangId(id); } diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangIdMapper.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangIdMapper.java new file mode 100644 index 0000000..3b201a3 --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangIdMapper.java @@ -0,0 +1,9 @@ +package de.ozgcloud.apilib.vorgang; + +import org.mapstruct.Mapper; + +@Mapper +public interface OzgCloudVorgangIdMapper { + + OzgCloudVorgangId fromString(String id); +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangService.java index 0c841e8..d3f5d80 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangService.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangService.java @@ -7,4 +7,6 @@ public interface OzgCloudVorgangService { public OzgCloudVorgang getById(OzgCloudVorgangId vorgangId); public List<OzgCloudVorgangStub> search(String searchString); + + public List<OzgCloudVorgangStub> search(String searchString, Page page); } diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/Page.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/Page.java new file mode 100644 index 0000000..45d1e56 --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/Page.java @@ -0,0 +1,18 @@ +package de.ozgcloud.apilib.vorgang; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class Page { + + @Builder.Default + private int limit = 100; + @Builder.Default + private int offset = 0; + + public static Page startPage() { + return Page.builder().build(); + } +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/dummy/DummyVorgangService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/dummy/DummyVorgangService.java index 37b5144..5e31042 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/dummy/DummyVorgangService.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/dummy/DummyVorgangService.java @@ -16,11 +16,12 @@ import de.ozgcloud.apilib.vorgang.OzgCloudVorgangHeader; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangService; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangStub; +import de.ozgcloud.apilib.vorgang.Page; import de.ozgcloud.apilib.vorgang.VorgangStatus; @Service @ConditionalOnMissingBean(OzgCloudVorgangService.class) -class DummyVorgangService implements OzgCloudVorgangService { +public class DummyVorgangService implements OzgCloudVorgangService { private final Map<OzgCloudVorgangId, OzgCloudVorgang> idToVorgang; private final List<OzgCloudVorgangStub> vorgangs; @@ -96,4 +97,8 @@ class DummyVorgangService implements OzgCloudVorgangService { return vorgangs; } + @Override + public List<OzgCloudVorgangStub> search(String searchString, Page page) { + return vorgangs; + } } diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangService.java index ca36aaf..a0a5982 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangService.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangService.java @@ -2,25 +2,33 @@ package de.ozgcloud.apilib.vorgang.grpc; import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; +import org.mapstruct.factory.Mappers; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; +import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangRequest; +import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangRequest.GrpcOrderBy; import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangWithEingangRequest; import de.itvsh.ozg.pluto.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; import de.ozgcloud.apilib.vorgang.OzgCloudVorgang; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangService; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangStub; +import de.ozgcloud.apilib.vorgang.Page; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import net.devh.boot.grpc.client.inject.GrpcClient; @Service -class GrpcVorgangService implements OzgCloudVorgangService { +@ConditionalOnProperty("ozgcloud.vorgang-manager.address") +@RequiredArgsConstructor +public class GrpcVorgangService implements OzgCloudVorgangService { @GrpcClient("vorgang-manager") - private VorgangServiceBlockingStub vorgangServiceStub; - @Autowired - private OzgCloudVorgangMapper mapper; + private final VorgangServiceBlockingStub vorgangServiceStub; + + private OzgCloudVorgangMapper mapper = Mappers.getMapper(OzgCloudVorgangMapper.class); + private OzgCloudVorgangStubMapper stubMapper = Mappers.getMapper(OzgCloudVorgangStubMapper.class); @Override public OzgCloudVorgang getById(@NonNull OzgCloudVorgangId vorgangId) { @@ -37,8 +45,23 @@ class GrpcVorgangService implements OzgCloudVorgangService { @Override public List<OzgCloudVorgangStub> search(@NonNull String searchString) { - // TODO Auto-generated method stub - return null; + return search(searchString, Page.startPage()); + } + + @Override + public List<OzgCloudVorgangStub> search(@NonNull String searchString, Page page) { + var response = vorgangServiceStub.findVorgang(buildSearchRequest(searchString, page)); + + return response.getVorgangList().stream().map(stubMapper::fromGrpc).toList(); + } + + GrpcFindVorgangRequest buildSearchRequest(@NonNull String searchString, Page page) { + return GrpcFindVorgangRequest.newBuilder() + .setSearchBy(searchString) + .setOffset(page.getOffset()) + .setLimit(page.getLimit()) + .setOrderBy(GrpcOrderBy.CREATED_AT_DESC) + .build(); } } diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangMapper.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangMapper.java index ab983e0..007daf0 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangMapper.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangMapper.java @@ -9,10 +9,10 @@ import de.itvsh.ozg.pluto.vorgang.GrpcVorgangWithEingang; import de.ozgcloud.apilib.user.UserId; import de.ozgcloud.apilib.vorgang.OzgCloudServiceKontoType; import de.ozgcloud.apilib.vorgang.OzgCloudVorgang; -import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper; import de.ozgcloud.apilib.vorgang.VorgangStatus; -@Mapper(uses = OzgCloudEingangMapper.class) +@Mapper(uses = { OzgCloudEingangMapper.class, OzgCloudVorgangIdMapper.class }) public interface OzgCloudVorgangMapper { @Mapping(target = "eingangs", ignore = true) @@ -28,10 +28,6 @@ public interface OzgCloudVorgangMapper { return Optional.ofNullable(type).map(OzgCloudServiceKontoType::from).orElse(null); } - default OzgCloudVorgangId toOzgCloudVorgangId(String vorgangId) { - return Optional.ofNullable(vorgangId).map(OzgCloudVorgangId::from).orElse(null); - } - default UserId toUserId(String userId) { return Optional.ofNullable(userId).map(UserId::from).orElse(null); } diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangStubMapper.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangStubMapper.java new file mode 100644 index 0000000..dbe1dff --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangStubMapper.java @@ -0,0 +1,18 @@ +package de.ozgcloud.apilib.vorgang.grpc; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import de.itvsh.ozg.pluto.vorgang.GrpcVorgangHeader; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangStub; + +@Mapper(uses = OzgCloudVorgangIdMapper.class) +public interface OzgCloudVorgangStubMapper { + + @Mapping(target = "header", ignore = true) + @Mapping(target = "vorgangName", ignore = true) + @Mapping(target = "vorgangNummer", ignore = true) + OzgCloudVorgangStub fromGrpc(GrpcVorgangHeader vorgang); + +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangStubTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangStubTestFactory.java new file mode 100644 index 0000000..226a9cf --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangStubTestFactory.java @@ -0,0 +1,12 @@ +package de.ozgcloud.apilib.vorgang; + +public class OzgCloudVorgangStubTestFactory { + + public static OzgCloudVorgangStub create() { + return createBuilder().build(); + } + + public static OzgCloudVorgangStub.OzgCloudVorgangStubBuilder createBuilder() { + return OzgCloudVorgangStub.builder(); + } +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangHeaderTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangHeaderTestFactory.java new file mode 100644 index 0000000..f59cdfc --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangHeaderTestFactory.java @@ -0,0 +1,25 @@ +package de.ozgcloud.apilib.vorgang.grpc; + +import static de.ozgcloud.apilib.vorgang.OzgCloudVorgangHeaderTestFactory.*; +import static de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory.*; + +import de.itvsh.ozg.pluto.vorgang.GrpcVorgangHeader; + +public class GrpcVorgangHeaderTestFactory { + + public static GrpcVorgangHeader create() { + return createBuilder().build(); + } + + public static GrpcVorgangHeader.Builder createBuilder() { + return GrpcVorgangHeader.newBuilder() + .setId(ID.toString()) + .setVersion(VERSION) + .setStatus(STATUS.toString()) + .setName(VORGANG_NAME) + .setCreatedAt(CREATED_AT_STR) + .setAktenzeichen(AKTENZEICHEN) + .setAssignedTo(ASSIGNED_TO.toString()) + .setNummer(VORGANG_NUMMER); + } +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangServiceTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangServiceTest.java index 4deb49f..0f9cc3c 100644 --- a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangServiceTest.java +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangServiceTest.java @@ -12,9 +12,14 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangRequest; +import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangResponse; import de.itvsh.ozg.pluto.vorgang.GrpcFindVorgangWithEingangRequest; +import de.itvsh.ozg.pluto.vorgang.GrpcVorgangHeader; import de.itvsh.ozg.pluto.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangStubTestFactory; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory; +import de.ozgcloud.apilib.vorgang.Page; class GrpcVorgangServiceTest { @@ -25,6 +30,8 @@ class GrpcVorgangServiceTest { private VorgangServiceBlockingStub stub; @Mock private OzgCloudVorgangMapper mapper; + @Mock + private OzgCloudVorgangStubMapper stubMapper; @Nested class TestGetById { @@ -69,4 +76,76 @@ class GrpcVorgangServiceTest { } } + @Nested + class TestSearch { + + private static final String SEARCH_STR = "search"; + + @Captor + private ArgumentCaptor<GrpcFindVorgangRequest> requestCaptor; + + @Nested + class BuildSearchRequest { + private static final Page PAGE = Page.builder().limit(40).offset(21).build(); + + @Test + void shouldSetSearchString() { + var request = service.buildSearchRequest(SEARCH_STR, PAGE); + + assertThat(request.getSearchBy()).isEqualTo(SEARCH_STR); + } + + @Test + void shouldSetLimit() { + var request = service.buildSearchRequest(SEARCH_STR, PAGE); + + assertThat(request.getLimit()).isEqualTo(40); + } + + @Test + void shouldSetOffset() { + var request = service.buildSearchRequest(SEARCH_STR, PAGE); + + assertThat(request.getOffset()).isEqualTo(21); + } + } + + @Nested + class doingRequest { + + private static final GrpcVorgangHeader VORGANG = GrpcVorgangHeaderTestFactory.create(); + private static final GrpcFindVorgangResponse RESPONSE = GrpcFindVorgangResponse.newBuilder() + .addVorgang(VORGANG).build(); + + @BeforeEach + void init() { + when(stub.findVorgang(any())).thenReturn(RESPONSE); + } + + @Test + void shouldCallStub() { + service.search(SEARCH_STR); + + verify(stub).findVorgang(notNull()); + } + + @Test + void shouldMapResponse() { + service.search(SEARCH_STR); + + verify(stubMapper).fromGrpc(notNull()); + } + + @Test + void shouldReturnResult() { + var vorgang = OzgCloudVorgangStubTestFactory.create(); + when(stubMapper.fromGrpc(any())).thenReturn(vorgang); + + var result = service.search(SEARCH_STR); + + assertThat(result).contains(vorgang); + } + } + + } } diff --git a/api-lib-demo/src/main/resources/application.yml b/api-lib-demo/src/main/resources/application.yml index 3f50825..fda4dff 100644 --- a/api-lib-demo/src/main/resources/application.yml +++ b/api-lib-demo/src/main/resources/application.yml @@ -1,3 +1,3 @@ ozgcloud: vorgang-manager: - url: static://127.0.0.1:9090 \ No newline at end of file + address: static://127.0.0.1:9090 \ No newline at end of file diff --git a/lombok.config b/lombok.config index d07dd9b..9a38fff 100644 --- a/lombok.config +++ b/lombok.config @@ -27,4 +27,6 @@ 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/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 aad5163..b6a3b42 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 @@ -1,26 +1,36 @@ package de.ozgcloud.client.autoconfigure; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Import; +import de.ozgcloud.apilib.vorgang.dummy.DummyVorgangService; +import de.ozgcloud.apilib.vorgang.grpc.GrpcVorgangService; import net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration; import net.devh.boot.grpc.client.config.GrpcChannelProperties; import net.devh.boot.grpc.client.config.GrpcChannelsProperties; import net.devh.boot.grpc.client.config.NegotiationType; @AutoConfiguration(before = GrpcClientAutoConfiguration.class) -@ComponentScan(basePackages = "de.ozgcloud.apilib.**") +@Import({ GrpcVorgangService.class, DummyVorgangService.class }) public class OzgCloudClientAutoConfiguration { + private static final String CLIENT_NAME_VORGANG_MANAGER = "vorgang-manager"; + + @Value("${ozgcloud.vorgang-manager.address:null}") + private String address; + @Bean + @ConditionalOnProperty("ozgcloud.vorgang-manager.address") GrpcChannelsProperties channelProperties() { var properties = new GrpcChannelsProperties(); var channelProps = new GrpcChannelProperties(); - properties.getClient().put("vorgang-manager", channelProps); + properties.getClient().put(CLIENT_NAME_VORGANG_MANAGER, channelProps); - channelProps.setAddress("static://127.0.0.1:9090"); + channelProps.setAddress(address); channelProps.setNegotiationType(NegotiationType.PLAINTEXT); return properties; diff --git a/ozg-cloud-spring-boot-starter/src/main/resources/application.yml b/ozg-cloud-spring-boot-starter/src/main/resources/application.yml deleted file mode 100644 index b770baa..0000000 --- a/ozg-cloud-spring-boot-starter/src/main/resources/application.yml +++ /dev/null @@ -1,7 +0,0 @@ -grpc: - client: - vorgang-manager: -# address: ${ozgcloud.vorgang-manager.url} - address: static://127.0.0.1:9090 - negotiationType: PLAINTEXT - \ No newline at end of file -- GitLab