Skip to content
Snippets Groups Projects
Commit b9863ce6 authored by OZGCloud's avatar OZGCloud
Browse files

make grpc connection optional configurable; add paging

parent 2e5440af
No related branches found
No related tags found
No related merge requests found
Showing
with 223 additions and 28 deletions
......@@ -99,7 +99,7 @@
<showWarnings>true</showWarnings>
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
-Amapstruct.defaultComponentModel=default
</compilerArg>
<compilerArg>
-Amapstruct.unmappedTargetPolicy=WARN
......
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);
}
......
package de.ozgcloud.apilib.vorgang;
import org.mapstruct.Mapper;
@Mapper
public interface OzgCloudVorgangIdMapper {
OzgCloudVorgangId fromString(String id);
}
......@@ -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);
}
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();
}
}
......@@ -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;
}
}
......@@ -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();
}
}
......@@ -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);
}
......
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);
}
package de.ozgcloud.apilib.vorgang;
public class OzgCloudVorgangStubTestFactory {
public static OzgCloudVorgangStub create() {
return createBuilder().build();
}
public static OzgCloudVorgangStub.OzgCloudVorgangStubBuilder createBuilder() {
return OzgCloudVorgangStub.builder();
}
}
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);
}
}
......@@ -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);
}
}
}
}
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
......@@ -28,3 +28,5 @@ lombok.log.log4j.flagUsage = ERROR
lombok.data.flagUsage = ERROR
lombok.nonNull.exceptionType = IllegalArgumentException
lombok.addLombokGeneratedAnnotation = true
lombok.copyableAnnotations += net.devh.boot.grpc.client.inject.GrpcClient
\ No newline at end of file
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;
......
grpc:
client:
vorgang-manager:
# address: ${ozgcloud.vorgang-manager.url}
address: static://127.0.0.1:9090
negotiationType: PLAINTEXT
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment