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

OZG-6354 impl interface for stub handling

parent 94f69584
No related branches found
No related tags found
No related merge requests found
package de.ozgcloud.eingang.router;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import lombok.Builder;
@Builder
class ClosableStub<T> implements ManagableStub<T> {
private static final int SHUTDOWM_TIME = 10;
private ManagedChannel channel;
private Function<Channel, T> creationFunction;
private T stub;
@Override
public T get() {
if (Objects.isNull(stub)) {
stub = creationFunction.apply(channel);
}
return stub;
}
public void close() {
if (Objects.nonNull(stub)) {
shutdownChannel();
stub = null;
}
}
private void shutdownChannel() {
try {
channel.shutdown().awaitTermination(ClosableStub.SHUTDOWM_TIME, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new TechnicalException("Error shutting down grpc channel.", e);
}
}
@Override
public boolean isShutdownable() {
return true;
}
}
\ No newline at end of file
package de.ozgcloud.eingang.router;
import lombok.Builder;
@Builder
class ConsistingStub<T> implements ManagableStub<T> {
private T stub;
@Override
public T get() {
return stub;
}
@Override
public boolean isShutdownable() {
return false;
}
}
\ No newline at end of file
package de.ozgcloud.eingang.router;
interface ManagableStub<T> {
T get();
boolean isShutdownable();
}
\ No newline at end of file
...@@ -79,15 +79,16 @@ public class VorgangManagerServerResolver { ...@@ -79,15 +79,16 @@ public class VorgangManagerServerResolver {
.findFirst().orElseThrow(() -> new AdapterConfigurationException("Cannot find Stub-Factory for GRPC-" + stubClass)); .findFirst().orElseThrow(() -> new AdapterConfigurationException("Cannot find Stub-Factory for GRPC-" + stubClass));
} }
public VorgangServiceBlockingStub resolveVorgangServiceBlockingStubByOrganisationseinheitenId(Optional<String> organisationsEinheitId) { public ManagableStub<VorgangServiceBlockingStub> resolveVorgangServiceBlockingStubByOrganisationseinheitenId(
return (VorgangServiceBlockingStub) createStub(organisationsEinheitId, vorgangStubFactory, VorgangServiceBlockingStub.class); Optional<String> organisationsEinheitId) {
return (ManagableStub<VorgangServiceBlockingStub>) createStub(organisationsEinheitId, vorgangStubFactory, VorgangServiceBlockingStub.class);
} }
public BinaryFileServiceStub resolveBinaryFileServiceStubByOrganisationsEinheitId(Optional<String> organisationsEinheitId) { public ManagableStub<BinaryFileServiceStub> resolveBinaryFileServiceStubByOrganisationsEinheitId(Optional<String> organisationsEinheitId) {
return (BinaryFileServiceStub) createStub(organisationsEinheitId, binaryFileAsynStubFactory, BinaryFileServiceStub.class); return (ManagableStub<BinaryFileServiceStub>) createStub(organisationsEinheitId, binaryFileAsynStubFactory, BinaryFileServiceStub.class);
} }
AbstractStub<?> createStub(Optional<String> organisationsEinheitId, StubFactory stubFactory, Class<? extends AbstractStub<?>> stubClass) {// NOSONAR ManagableStub<?> createStub(Optional<String> organisationsEinheitId, StubFactory stubFactory, Class<? extends AbstractStub<?>> stubClass) {// NOSONAR
if (properties.getRoutingStrategy() == RoutingStrategy.ZUFI) { if (properties.getRoutingStrategy() == RoutingStrategy.ZUFI) {
return createStubUsingZufi(organisationsEinheitId, stubFactory, stubClass); return createStubUsingZufi(organisationsEinheitId, stubFactory, stubClass);
} else { } else {
...@@ -95,17 +96,17 @@ public class VorgangManagerServerResolver { ...@@ -95,17 +96,17 @@ public class VorgangManagerServerResolver {
} }
} }
AbstractStub<?> createStubUsingZufi(Optional<String> organisationsEinheitId, StubFactory stubFactory, ManagableStub<?> createStubUsingZufi(Optional<String> organisationsEinheitId, StubFactory stubFactory,
Class<? extends AbstractStub<?>> stubClass) { Class<? extends AbstractStub<?>> stubClass) {
return null; return null;
} }
AbstractStub<?> createStubByConfiguredChannels(Optional<String> organisationsEinheitId, StubFactory stubFactory, ManagableStub<?> createStubByConfiguredChannels(Optional<String> organisationsEinheitId, StubFactory stubFactory,
Class<? extends AbstractStub<?>> stubClass) { Class<? extends AbstractStub<?>> stubClass) {
var channelName = getChannelName(organisationsEinheitId); var channelName = getChannelName(organisationsEinheitId);
var stub = stubFactory.createStub(stubClass, createChannelByName(channelName)); var stub = stubFactory.createStub(stubClass, createChannelByName(channelName));
stub = applyStubTransformers(stub, channelName);
return applyStubTransformers(stub, channelName); return ConsistingStub.builder().stub(stub).build();
} }
String getChannelName(Optional<String> organisationsEinheitId) { String getChannelName(Optional<String> organisationsEinheitId) {
......
...@@ -67,21 +67,40 @@ public class VorgangRemoteService { ...@@ -67,21 +67,40 @@ public class VorgangRemoteService {
private VorgangManagerServerResolver vorgangManagerServerResolver; private VorgangManagerServerResolver vorgangManagerServerResolver;
public String createVorgang(FormData formData, GrpcEingang eingang, Optional<String> organisationsEinheitenId) { public String createVorgang(FormData formData, GrpcEingang eingang, Optional<String> organisationsEinheitenId) {
var vorgangManagerStub = vorgangManagerServerResolver.resolveVorgangServiceBlockingStubByOrganisationseinheitenId(organisationsEinheitenId); var vorgangServiceStub = getVorgangServiceStub(organisationsEinheitenId);
LOG.info("Connecting to vorgang-manager server " + vorgangManagerStub.getChannel().authority() + "; OrganisationsEinheitId: " + organisationsEinheitenId); var binaryFileServiceStub = getBinaryFileServiceStub(organisationsEinheitenId);
return createVorgang(formData, eingang, vorgangManagerStub, getBinaryFileServiceStub(organisationsEinheitenId)); logConnection(organisationsEinheitenId, vorgangServiceStub.get());
var vorgangId = createVorgang(formData, eingang, vorgangServiceStub.get(), binaryFileServiceStub.get());
finishStubConnections(List.of(vorgangServiceStub, binaryFileServiceStub));
return vorgangId;
}
void logConnection(Optional<String> organisationsEinheitenId, VorgangServiceBlockingStub vorgangStub) {
LOG.info("Connecting to vorgang-manager server " + vorgangStub.getChannel().authority() + "; OrganisationsEinheitId: "
+ organisationsEinheitenId);
} }
public String createVorgang(FormData formData, GrpcEingang eingang, VorgangServiceBlockingStub remoteStub, private ManagableStub<VorgangServiceBlockingStub> getVorgangServiceStub(Optional<String> organisationsEinheitenId) {
BinaryFileServiceStub remoteAsyncStub) { return vorgangManagerServerResolver.resolveVorgangServiceBlockingStubByOrganisationseinheitenId(organisationsEinheitenId);
return new VorgangCreator(formData, eingang, remoteStub, remoteAsyncStub).create();
} }
private BinaryFileServiceStub getBinaryFileServiceStub(Optional<String> organisationsEinheitenId) { private ManagableStub<BinaryFileServiceStub> getBinaryFileServiceStub(Optional<String> organisationsEinheitenId) {
return vorgangManagerServerResolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(organisationsEinheitenId); return vorgangManagerServerResolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(organisationsEinheitenId);
} }
public String createVorgang(FormData formData, GrpcEingang eingang, VorgangServiceBlockingStub vorgangStub,
BinaryFileServiceStub binaryFileStub) {
return new VorgangCreator(formData, eingang, vorgangStub, binaryFileStub).create();
}
void finishStubConnections(List<ManagableStub<?>> stubs) {
stubs.stream().filter(ManagableStub::isShutdownable).map(ClosableStub.class::cast).forEach(ClosableStub::close);
}
@RequiredArgsConstructor @RequiredArgsConstructor
public class VorgangCreator { public class VorgangCreator {
......
...@@ -96,7 +96,7 @@ class VorgangManagerServerResolverTest { ...@@ -96,7 +96,7 @@ class VorgangManagerServerResolverTest {
class TestResolveVorgangManagerServiceStubByOrganisationsEinheitenId { class TestResolveVorgangManagerServiceStubByOrganisationsEinheitenId {
@Mock @Mock
private VorgangServiceBlockingStub stub; private ManagableStub<VorgangServiceBlockingStub> stub;
private final Optional<String> organisationsEinheitenId = Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); private final Optional<String> organisationsEinheitenId = Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID);
...@@ -113,13 +113,13 @@ class VorgangManagerServerResolverTest { ...@@ -113,13 +113,13 @@ class VorgangManagerServerResolverTest {
} }
@Test @Test
void shouldReturnManageableStub() { void shouldReturnStub() {
var createdStub = resolveStub(); var createdStub = resolveStub();
assertThat(createdStub).isEqualTo(stub); assertThat(createdStub).isEqualTo(stub);
} }
private VorgangServiceBlockingStub resolveStub() { private ManagableStub<VorgangServiceBlockingStub> resolveStub() {
return resolver.resolveVorgangServiceBlockingStubByOrganisationseinheitenId(organisationsEinheitenId); return resolver.resolveVorgangServiceBlockingStubByOrganisationseinheitenId(organisationsEinheitenId);
} }
} }
...@@ -129,7 +129,7 @@ class VorgangManagerServerResolverTest { ...@@ -129,7 +129,7 @@ class VorgangManagerServerResolverTest {
class TestResolveBinaryFileServiceStubByOrganisationsEinheitenId { class TestResolveBinaryFileServiceStubByOrganisationsEinheitenId {
@Mock @Mock
private BinaryFileServiceStub stub; private ManagableStub<BinaryFileServiceStub> stub;
private final Optional<String> organisationsEinheitenId = Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); private final Optional<String> organisationsEinheitenId = Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID);
...@@ -146,13 +146,13 @@ class VorgangManagerServerResolverTest { ...@@ -146,13 +146,13 @@ class VorgangManagerServerResolverTest {
} }
@Test @Test
void shouldReturnManageableStub() { void shouldStub() {
var createdStub = resolveStub(); var createdStub = resolveStub();
assertThat(createdStub).isEqualTo(stub); assertThat(createdStub).isEqualTo(stub);
} }
private BinaryFileServiceStub resolveStub() { private ManagableStub<BinaryFileServiceStub> resolveStub() {
return resolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(organisationsEinheitenId); return resolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(organisationsEinheitenId);
} }
} }
...@@ -162,7 +162,7 @@ class VorgangManagerServerResolverTest { ...@@ -162,7 +162,7 @@ class VorgangManagerServerResolverTest {
class TestCreateStub { class TestCreateStub {
@Mock @Mock
private AbstractStub<?> createdStub; private ManagableStub<?> createdStub;
private Class<? extends AbstractStub<?>> stubClass = VorgangServiceBlockingStub.class; private Class<? extends AbstractStub<?>> stubClass = VorgangServiceBlockingStub.class;
private Optional<String> organisationsEinheitenId = Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID); private Optional<String> organisationsEinheitenId = Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID);
...@@ -217,7 +217,7 @@ class VorgangManagerServerResolverTest { ...@@ -217,7 +217,7 @@ class VorgangManagerServerResolverTest {
} }
} }
private AbstractStub<?> createStub() { private ManagableStub<?> createStub() {
return resolver.createStub(organisationsEinheitenId, stubFactory, stubClass); return resolver.createStub(organisationsEinheitenId, stubFactory, stubClass);
} }
} }
...@@ -230,6 +230,8 @@ class VorgangManagerServerResolverTest { ...@@ -230,6 +230,8 @@ class VorgangManagerServerResolverTest {
private Channel channel; private Channel channel;
@Mock @Mock
private StubFactory stubFactory; private StubFactory stubFactory;
@Mock
private AbstractStub<?> createdStub;
private Class<? extends AbstractStub<?>> stubClass = VorgangServiceBlockingStub.class; private Class<? extends AbstractStub<?>> stubClass = VorgangServiceBlockingStub.class;
...@@ -238,6 +240,7 @@ class VorgangManagerServerResolverTest { ...@@ -238,6 +240,7 @@ class VorgangManagerServerResolverTest {
doReturn(VorgangManagerListPropertiesTestFactory.CHANNEL_NAME).when(resolver).getChannelName(any()); doReturn(VorgangManagerListPropertiesTestFactory.CHANNEL_NAME).when(resolver).getChannelName(any());
doReturn(channel).when(resolver).createChannelByName(any()); doReturn(channel).when(resolver).createChannelByName(any());
setProperties(VorgangManagerListPropertiesTestFactory.createForSingleRouting()); setProperties(VorgangManagerListPropertiesTestFactory.createForSingleRouting());
doReturn(createdStub).when(resolver).applyStubTransformers(any(), any());
} }
@Test @Test
...@@ -261,7 +264,14 @@ class VorgangManagerServerResolverTest { ...@@ -261,7 +264,14 @@ class VorgangManagerServerResolverTest {
verify(stubFactory).createStub(eq(stubClass), any()); verify(stubFactory).createStub(eq(stubClass), any());
} }
private AbstractStub<?> createStubByConfiguredChannels() { @Test
void shouldReturnStub() {
var stub = createStubByConfiguredChannels();
assertThat(stub.get()).isEqualTo(createdStub);
}
private ManagableStub<?> createStubByConfiguredChannels() {
return resolver.createStubByConfiguredChannels(Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID), stubFactory, return resolver.createStubByConfiguredChannels(Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID), stubFactory,
stubClass); stubClass);
} }
......
...@@ -30,6 +30,7 @@ import static org.mockito.Mockito.*; ...@@ -30,6 +30,7 @@ import static org.mockito.Mockito.*;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
...@@ -37,6 +38,7 @@ import java.util.concurrent.TimeUnit; ...@@ -37,6 +38,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
...@@ -45,6 +47,7 @@ import org.mockito.ArgumentCaptor; ...@@ -45,6 +47,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Captor; import org.mockito.Captor;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Spy;
import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils.FileSender; import de.ozgcloud.common.binaryfile.GrpcFileUploadUtils.FileSender;
import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.common.errorhandling.TechnicalException;
...@@ -54,6 +57,7 @@ import de.ozgcloud.eingang.common.formdata.IncomingFile; ...@@ -54,6 +57,7 @@ import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory; import de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory;
import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
import de.ozgcloud.eingang.common.formdata.ZustaendigeStelleTestFactory;
import de.ozgcloud.eingang.router.VorgangRemoteService.VorgangCreator; import de.ozgcloud.eingang.router.VorgangRemoteService.VorgangCreator;
import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub;
import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData; import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileMetaData;
...@@ -70,14 +74,11 @@ import lombok.SneakyThrows; ...@@ -70,14 +74,11 @@ import lombok.SneakyThrows;
class VorgangRemoteServiceTest { class VorgangRemoteServiceTest {
@Spy
@InjectMocks @InjectMocks
private VorgangRemoteService remoteService; private VorgangRemoteService remoteService;
@Mock @Mock
private final VorgangServiceBlockingStub vorgangStub = VorgangManagerServerResolverTestFactory.createVorgangBlockingStub(); private VorgangManagerServerResolver resolver;
@Mock
private final BinaryFileServiceStub binaryFileStub = VorgangManagerServerResolverTestFactory.createBinaryFileStub();
@Mock
private GrpcEingangMapper eingangMapper;
private VorgangCreator vorgangCreator; private VorgangCreator vorgangCreator;
...@@ -87,7 +88,117 @@ class VorgangRemoteServiceTest { ...@@ -87,7 +88,117 @@ class VorgangRemoteServiceTest {
.addRepresentations(GrpcIncomingFileTestFactory.create()) .addRepresentations(GrpcIncomingFileTestFactory.create())
.build(); .build();
private final String vorgangId = UUID.randomUUID().toString(); private final String vorgangId = UUID.randomUUID().toString();
private String fileId = "42"; private final String fileId = "42";
@DisplayName("Create vorgang")
@Nested
class TestCreateVorgang {
@Mock
private ManagableStub<VorgangServiceBlockingStub> managableVorgangServiceStub;
@Mock
private VorgangServiceBlockingStub vorgangServiceStub;
@Mock
private ManagableStub<BinaryFileServiceStub> managableBinaryFileServiceStub;
@Mock
private BinaryFileServiceStub binaryFileServiceStub;
private final Optional<String> organisationsEinheitId = Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID);
@BeforeEach
void mock() {
doReturn(vorgangId).when(remoteService).createVorgang(any(), any(), any(), any());
when(resolver.resolveVorgangServiceBlockingStubByOrganisationseinheitenId(any())).thenReturn(managableVorgangServiceStub);
when(managableVorgangServiceStub.get()).thenReturn(vorgangServiceStub);
when(resolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(any())).thenReturn(managableBinaryFileServiceStub);
when(managableBinaryFileServiceStub.get()).thenReturn(binaryFileServiceStub);
doNothing().when(remoteService).logConnection(any(), any());
doNothing().when(remoteService).finishStubConnections(any());
}
@Test
void shouldGetVorgangService() {
createVorgang();
verify(resolver).resolveVorgangServiceBlockingStubByOrganisationseinheitenId(organisationsEinheitId);
}
@Test
void shouldGetBinaryFileService() {
createVorgang();
verify(resolver).resolveBinaryFileServiceStubByOrganisationsEinheitId(organisationsEinheitId);
}
@Test
void shouldCreateVorgang() {
createVorgang();
verify(remoteService).createVorgang(formData, eingang, vorgangServiceStub, binaryFileServiceStub);
}
@Test
void shouldFinishStubConnection() {
createVorgang();
verify(remoteService).finishStubConnections(List.of(managableVorgangServiceStub, managableBinaryFileServiceStub));
}
@Test
void shouldReturnVorgangId() {
var created = createVorgang();
assertThat(created).isEqualTo(vorgangId);
}
private String createVorgang() {
return remoteService.createVorgang(formData, eingang, organisationsEinheitId);
}
}
@DisplayName("Finish stub connections")
@Nested
class TestFinishStubConnections {
@Mock
private ClosableStub<VorgangServiceBlockingStub> closableStub;
@BeforeEach
void mock() {
when(closableStub.isShutdownable()).thenReturn(true);
doNothing().when(closableStub).close();
}
@Test
void shouldCheckIfSubIsShutdownable() {
remoteService.finishStubConnections(List.of(closableStub));
verify(closableStub).isShutdownable();
}
@Test
void shouldShutDownChannelForClosableStubs() {
remoteService.finishStubConnections(List.of(closableStub));
verify((ClosableStub) closableStub).close();
}
}
@DisplayName("VorgangCreator")
@Nested
class TestVorgangCreator {
@Mock
private final VorgangServiceBlockingStub vorgangStub = VorgangManagerServerResolverTestFactory.createVorgangBlockingStub();
@Mock
private final BinaryFileServiceStub binaryFileStub = VorgangManagerServerResolverTestFactory.createBinaryFileStub();
@Mock
private GrpcEingangMapper eingangMapper;
@BeforeEach @BeforeEach
void init() { void init() {
...@@ -310,24 +421,25 @@ class VorgangRemoteServiceTest { ...@@ -310,24 +421,25 @@ class VorgangRemoteServiceTest {
void shouldCloseFileContentStreamOnException(Class<Exception> exception) { void shouldCloseFileContentStreamOnException(Class<Exception> exception) {
doThrow(exception).when(streamFuture).get(anyLong(), any(TimeUnit.class)); doThrow(exception).when(streamFuture).get(anyLong(), any(TimeUnit.class));
try { waitUntilFutureToComplete();
vorgangCreator.waitUntilFutureToComplete(sender, inputStream);
} catch (Exception e) {
// ignored
}
verify(inputStream).close(); verify(inputStream).close();
} }
@Test @Test
@SneakyThrows @SneakyThrows
void shouldCloseFileContent() { void shouldCloseFileContent() {
waitUntilFutureToComplete();
verify(inputStream).close();
}
private void waitUntilFutureToComplete() {
try { try {
vorgangCreator.waitUntilFutureToComplete(sender, inputStream); vorgangCreator.waitUntilFutureToComplete(sender, inputStream);
} catch (Exception e) { } catch (Exception e) {
// ignored // ignored
} }
verify(inputStream).close();
} }
} }
...@@ -370,3 +482,4 @@ class VorgangRemoteServiceTest { ...@@ -370,3 +482,4 @@ class VorgangRemoteServiceTest {
} }
} }
} }
}
\ 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