diff --git a/formsolutions-adapter/src/test/java/de/ozgcloud/eingang/formsolutions/FormsolutionsITCase.java b/formsolutions-adapter/src/test/java/de/ozgcloud/eingang/formsolutions/FormsolutionsITCase.java index 8a2f3c291eb730fa9a0f93b6291bdd2e15dc9555..1024f573ab906e15942513d187b3afda11c8af1e 100644 --- a/formsolutions-adapter/src/test/java/de/ozgcloud/eingang/formsolutions/FormsolutionsITCase.java +++ b/formsolutions-adapter/src/test/java/de/ozgcloud/eingang/formsolutions/FormsolutionsITCase.java @@ -21,6 +21,7 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.util.ReflectionTestUtils; import de.ozgcloud.common.test.TestUtils; +import de.ozgcloud.eingang.router.ManagableStub; import de.ozgcloud.eingang.router.VorgangManagerServerResolver; import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; import de.ozgcloud.vorgang.grpc.binaryFile.GrpcUploadBinaryFileRequest; @@ -49,17 +50,23 @@ public class FormsolutionsITCase { @Mock private VorgangServiceBlockingStub blockingStub; @Mock + private ManagableStub<VorgangServiceBlockingStub> managableVorgangServiceBlockingStub; + @Mock private BinaryFileServiceStub fileStub; @Mock + private ManagableStub<BinaryFileServiceStub> managableBinaryFileStub; + @Mock private CallStreamObserver<GrpcUploadBinaryFileRequest> fileStreamObserver; @BeforeEach void initVorgangManagerResolver() { - when(resolver.resolveVorgangServiceBlockingStubByOrganisationseinheitenId(any())).thenReturn(blockingStub); - when(resolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(any())).thenReturn(fileStub); - + when(resolver.resolveVorgangServiceBlockingStubByOrganisationseinheitenId(any())).thenReturn(managableVorgangServiceBlockingStub); + when(managableVorgangServiceBlockingStub.get()).thenReturn(blockingStub); + when(resolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(any())).thenReturn(managableBinaryFileStub); + when(managableBinaryFileStub.get()).thenReturn(fileStub); + Channel mockChannel = mock(Channel.class); - when(blockingStub.getChannel()).thenReturn(mockChannel ); + when(blockingStub.getChannel()).thenReturn(mockChannel); when(blockingStub.startCreation(any())).thenReturn(GrpcCreateVorgangResponse.newBuilder().setVorgangId("42").build()); when(fileStub.uploadBinaryFileAsStream(any())).thenReturn(fileStreamObserver); diff --git a/router/src/main/java/de/ozgcloud/eingang/router/ClosableStub.java b/router/src/main/java/de/ozgcloud/eingang/router/ClosableStub.java index 5599172eed8316fdb56c14a43de2921325bbdf99..2f85a16cf1840901b66addcb92bf12f86cefa632 100644 --- a/router/src/main/java/de/ozgcloud/eingang/router/ClosableStub.java +++ b/router/src/main/java/de/ozgcloud/eingang/router/ClosableStub.java @@ -5,24 +5,25 @@ 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; +import lombok.Getter; +@Getter @Builder class ClosableStub<T> implements ManagableStub<T> { private static final int SHUTDOWM_TIME = 10; private ManagedChannel channel; - private Function<Channel, T> creationFunction; + private Function<ManagedChannel, T> createFunction; private T stub; @Override public T get() { if (Objects.isNull(stub)) { - stub = creationFunction.apply(channel); + stub = createFunction.apply(channel); } return stub; } diff --git a/router/src/main/java/de/ozgcloud/eingang/router/ManagableStub.java b/router/src/main/java/de/ozgcloud/eingang/router/ManagableStub.java index 8ffa720b62ab5117f372ea79028fbe7fe95b1c57..bce38696c16e1ac7ccf385b21deb6e1e0c1548f0 100644 --- a/router/src/main/java/de/ozgcloud/eingang/router/ManagableStub.java +++ b/router/src/main/java/de/ozgcloud/eingang/router/ManagableStub.java @@ -1,6 +1,6 @@ package de.ozgcloud.eingang.router; -interface ManagableStub<T> { +public interface ManagableStub<T> { T get(); diff --git a/router/src/main/java/de/ozgcloud/eingang/router/VorgangManagerServerResolver.java b/router/src/main/java/de/ozgcloud/eingang/router/VorgangManagerServerResolver.java index c88208ab3b4c1b60c73db922604597e0cc02783f..9cffc945d5cf6353bcee7af9f5f0b2adab98b01c 100644 --- a/router/src/main/java/de/ozgcloud/eingang/router/VorgangManagerServerResolver.java +++ b/router/src/main/java/de/ozgcloud/eingang/router/VorgangManagerServerResolver.java @@ -26,6 +26,7 @@ package de.ozgcloud.eingang.router; import java.util.Collection; import java.util.Collections; import java.util.Optional; +import java.util.function.Function; import jakarta.annotation.PostConstruct; import jakarta.validation.Valid; @@ -33,13 +34,19 @@ import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import de.ozgcloud.common.errorhandling.TechnicalException; +import de.ozgcloud.eingang.common.zufi.ZufiService; import de.ozgcloud.eingang.router.VorgangManagerListProperties.FallbackStrategy; import de.ozgcloud.eingang.router.VorgangManagerListProperties.RoutingStrategy; import de.ozgcloud.eingang.router.errorhandling.AdapterConfigurationException; import de.ozgcloud.eingang.router.errorhandling.UnknownOrganisationseinheitException; +import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc; import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; +import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc; import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; import io.grpc.Channel; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; import io.grpc.stub.AbstractStub; import lombok.NonNull; import lombok.extern.log4j.Log4j2; @@ -67,6 +74,9 @@ public class VorgangManagerServerResolver { private StubFactory vorgangStubFactory; private StubFactory binaryFileAsynStubFactory; + @Autowired + private ZufiService zufiService; + @PostConstruct void findApplicableStubFactories() { vorgangStubFactory = findStubFactory(VorgangServiceBlockingStub.class); @@ -81,24 +91,41 @@ public class VorgangManagerServerResolver { public ManagableStub<VorgangServiceBlockingStub> resolveVorgangServiceBlockingStubByOrganisationseinheitenId( Optional<String> organisationsEinheitId) { - return (ManagableStub<VorgangServiceBlockingStub>) createStub(organisationsEinheitId, vorgangStubFactory, VorgangServiceBlockingStub.class); + if (isZufiStrategy()) { + return createStub(organisationsEinheitId, VorgangServiceGrpc::newBlockingStub); + } + return (ManagableStub<VorgangServiceBlockingStub>) createStubByConfiguredChannels(organisationsEinheitId, vorgangStubFactory, + VorgangServiceBlockingStub.class); } public ManagableStub<BinaryFileServiceStub> resolveBinaryFileServiceStubByOrganisationsEinheitId(Optional<String> organisationsEinheitId) { - return (ManagableStub<BinaryFileServiceStub>) createStub(organisationsEinheitId, binaryFileAsynStubFactory, BinaryFileServiceStub.class); + if (isZufiStrategy()) { + return createStub(organisationsEinheitId, BinaryFileServiceGrpc::newStub); + } + return (ManagableStub<BinaryFileServiceStub>) createStubByConfiguredChannels(organisationsEinheitId, binaryFileAsynStubFactory, + BinaryFileServiceStub.class); } - ManagableStub<?> createStub(Optional<String> organisationsEinheitId, StubFactory stubFactory, Class<? extends AbstractStub<?>> stubClass) {// NOSONAR - if (properties.getRoutingStrategy() == RoutingStrategy.ZUFI) { - return createStubUsingZufi(organisationsEinheitId, stubFactory, stubClass); - } else { - return createStubByConfiguredChannels(organisationsEinheitId, stubFactory, stubClass); - } + private boolean isZufiStrategy() { + return properties.getRoutingStrategy() == RoutingStrategy.ZUFI; } - ManagableStub<?> createStubUsingZufi(Optional<String> organisationsEinheitId, StubFactory stubFactory, - Class<? extends AbstractStub<?>> stubClass) { - return null; + <T> ManagableStub<T> createStub(Optional<String> organisationsEinheitId, Function<ManagedChannel, T> createFunction) { + return ClosableStub.<T>builder() + .channel(createChannel(organisationsEinheitId)) + .createFunction(createFunction) + .build(); + } + + ManagedChannel createChannel(Optional<String> organisationsEinheitId) { + return ManagedChannelBuilder.forTarget(getVorgangManagerAddress(organisationsEinheitId)).usePlaintext().build(); + } + + private String getVorgangManagerAddress(Optional<String> organisationsEinheitId) { + if (organisationsEinheitId.isEmpty()) { + throw new TechnicalException("No organisationsEinheitId exists, can not build connection to vorgang-manager."); + } + return zufiService.getVorgangManagerUrl(organisationsEinheitId.get()); } ManagableStub<?> createStubByConfiguredChannels(Optional<String> organisationsEinheitId, StubFactory stubFactory, diff --git a/router/src/test/java/de/ozgcloud/eingang/router/VorgangManagerServerResolverTest.java b/router/src/test/java/de/ozgcloud/eingang/router/VorgangManagerServerResolverTest.java index 23daf33f29dcf1f011a88e94f160fb08154ae5ea..5bafbdcec6f41c2c094b7803a8317bb85ef9a9b8 100644 --- a/router/src/test/java/de/ozgcloud/eingang/router/VorgangManagerServerResolverTest.java +++ b/router/src/test/java/de/ozgcloud/eingang/router/VorgangManagerServerResolverTest.java @@ -31,22 +31,27 @@ import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.Collections; import java.util.Optional; +import java.util.function.Function; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatchers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.springframework.test.util.ReflectionTestUtils; +import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.eingang.common.formdata.ZustaendigeStelleTestFactory; +import de.ozgcloud.eingang.common.zufi.ZufiService; import de.ozgcloud.eingang.router.errorhandling.AdapterConfigurationException; import de.ozgcloud.eingang.router.errorhandling.UnknownOrganisationseinheitException; import de.ozgcloud.vorgang.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceStub; import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; import io.grpc.Channel; +import io.grpc.ManagedChannel; import io.grpc.stub.AbstractStub; import net.devh.boot.grpc.client.channelfactory.GrpcChannelFactory; import net.devh.boot.grpc.client.inject.StubTransformer; @@ -63,6 +68,9 @@ class VorgangManagerServerResolverTest { @Mock private StubFactory stubFactory; + @Mock + private ZufiService zufiService; + @Nested class TestFindStubFactory { @@ -100,23 +108,55 @@ class VorgangManagerServerResolverTest { private final Optional<String> organisationsEinheitenId = Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); - @BeforeEach - void mock() { - doReturn(stub).when(resolver).createStub(any(), any(), any()); - } + @DisplayName("On zufi strategy") + @Nested + class TestOnZufiRoutingStrategy { - @Test - void shouldCallCreateStub() { - resolveStub(); + @BeforeEach + void mock() { + doReturn(stub).when(resolver).createStub(any(), any()); + setProperties(VorgangManagerListPropertiesTestFactory.createForZufiRouting()); + } + + @Test + void shouldCallCreateStub() { + resolveStub(); + + verify(resolver).createStub(eq(organisationsEinheitenId), + ArgumentMatchers.<Function<ManagedChannel, VorgangServiceBlockingStub>>any()); + } + + @Test + void shouldReturnStub() { + var createdStub = resolveStub(); - verify(resolver).createStub(eq(organisationsEinheitenId), any(), eq(VorgangServiceBlockingStub.class)); + assertThat(createdStub).isEqualTo(stub); + } } - @Test - void shouldReturnStub() { - var createdStub = resolveStub(); + @DisplayName("On other routing strategy") + @Nested + class TestOnOtherRoutingStrategy { + + @BeforeEach + void mock() { + doReturn(stub).when(resolver).createStubByConfiguredChannels(any(), any(), any()); + setProperties(VorgangManagerListPropertiesTestFactory.createForSingleRouting()); + } + + @Test + void shouldCallCreateStub() { + resolveStub(); - assertThat(createdStub).isEqualTo(stub); + verify(resolver).createStubByConfiguredChannels(eq(organisationsEinheitenId), any(), eq(VorgangServiceBlockingStub.class)); + } + + @Test + void shouldReturnStub() { + var createdStub = resolveStub(); + + assertThat(createdStub).isEqualTo(stub); + } } private ManagableStub<VorgangServiceBlockingStub> resolveStub() { @@ -133,23 +173,55 @@ class VorgangManagerServerResolverTest { private final Optional<String> organisationsEinheitenId = Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID); - @BeforeEach - void mock() { - doReturn(stub).when(resolver).createStub(any(), any(), any()); - } + @DisplayName("On zufi strategy") + @Nested + class TestOnZufiRoutingStrategy { - @Test - void shouldCallCreateStub() { - resolveStub(); + @BeforeEach + void mock() { + doReturn(stub).when(resolver).createStub(any(), any()); + setProperties(VorgangManagerListPropertiesTestFactory.createForZufiRouting()); + } - verify(resolver).createStub(eq(organisationsEinheitenId), any(), eq(BinaryFileServiceStub.class)); + @Test + void shouldCallCreateStub() { + resolveStub(); + + verify(resolver).createStub(eq(organisationsEinheitenId), + ArgumentMatchers.<Function<ManagedChannel, BinaryFileServiceStub>>any()); + } + + @Test + void shouldReturnStub() { + var createdStub = resolveStub(); + + assertThat(createdStub).isEqualTo(stub); + } } - @Test - void shouldStub() { - var createdStub = resolveStub(); + @DisplayName("On other routing strategy") + @Nested + class TestOnOtherRoutingStrategy { - assertThat(createdStub).isEqualTo(stub); + @BeforeEach + void mock() { + doReturn(stub).when(resolver).createStubByConfiguredChannels(any(), any(), any()); + setProperties(VorgangManagerListPropertiesTestFactory.createForSingleRouting()); + } + + @Test + void shouldCallCreateStub() { + resolveStub(); + + verify(resolver).createStubByConfiguredChannels(eq(organisationsEinheitenId), any(), eq(BinaryFileServiceStub.class)); + } + + @Test + void shouldReturnStub() { + var createdStub = resolveStub(); + + assertThat(createdStub).isEqualTo(stub); + } } private ManagableStub<BinaryFileServiceStub> resolveStub() { @@ -163,62 +235,73 @@ class VorgangManagerServerResolverTest { @Mock private ManagableStub<?> createdStub; + @Mock + private Function<ManagedChannel, AbstractStub<?>> createFunction; + @Mock + private ManagedChannel managedChannel; - private Class<? extends AbstractStub<?>> stubClass = VorgangServiceBlockingStub.class; private Optional<String> organisationsEinheitenId = Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID); - @DisplayName("on zufi routing") - @Nested - class TestOnZufiRouting { + @BeforeEach + void mock() { + doReturn(managedChannel).when(resolver).createChannel(any()); + } - @BeforeEach - void mock() { - setProperties(VorgangManagerListPropertiesTestFactory.createForZufiRouting()); - doReturn(createdStub).when(resolver).createStubUsingZufi(any(), any(), any()); - } + @Test + void shouldCreateChannel() { + createStub(); - @Test - void shouldCreateStubUsingZufi() { - createStub(); + verify(resolver).createChannel(organisationsEinheitenId); + } - verify(resolver).createStubUsingZufi(organisationsEinheitenId, stubFactory, stubClass); - } + @Test + void shouldReturnStub() { + var createdStub = (ClosableStub) createStub(); - @Test - void shouldReturnCreatedStub() { - var stub = createStub(); + assertThat(createdStub).isNotNull(); + assertThat(createdStub.getChannel()).isEqualTo(managedChannel); + assertThat(createdStub.getCreateFunction()).isEqualTo(createFunction); + } - assertThat(stub).isEqualTo(createdStub); - } + private ManagableStub<?> createStub() { + return resolver.createStub(organisationsEinheitenId, createFunction); } + } - @DisplayName("On other routing") - @Nested - class TestOnOtherRouting { + @DisplayName("Create Channel") + @Nested + class TestCreateChannel { - @BeforeEach - void mock() { - setProperties(VorgangManagerListPropertiesTestFactory.createForSingleRouting()); - doReturn(createdStub).when(resolver).createStubByConfiguredChannels(any(), any(), any()); - } + private final Optional<String> organisationsEinheitenId = Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID); + private final String vorgangManagerAddress = "DummyVorgangManagerAddress"; - @Test - void shouldCreateStubByConfiguredChannels() { - createStub(); + @Test + void shouldCallZufiService() { + when(zufiService.getVorgangManagerUrl(any())).thenReturn(vorgangManagerAddress); - verify(resolver).createStubByConfiguredChannels(organisationsEinheitenId, stubFactory, stubClass); - } + createChannel(); - @Test - void shouldReturnCreatedStub() { - var stub = createStub(); + verify(zufiService).getVorgangManagerUrl(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID); + } - assertThat(stub).isEqualTo(createdStub); - } + @Test + void shouldThrowExceptionIfOrganisationsEinheitIsNotPresent() { + var emptyOrganisationsEinheitId = Optional.<String>empty(); + + assertThatThrownBy(() -> resolver.createChannel(emptyOrganisationsEinheitId)).isInstanceOf(TechnicalException.class); } - private ManagableStub<?> createStub() { - return resolver.createStub(organisationsEinheitenId, stubFactory, stubClass); + @Test + void shouldReturnChannel() { + when(zufiService.getVorgangManagerUrl(any())).thenReturn(vorgangManagerAddress); + + var createdChannel = createChannel(); + + assertThat(createdChannel).isNotNull(); + } + + private ManagedChannel createChannel() { + return resolver.createChannel(organisationsEinheitenId); } } @@ -413,14 +496,14 @@ class VorgangManagerServerResolverTest { ReflectionTestUtils.setField(resolver, "properties", properties); } - @Test - void shouldUseZufiToCreateChannel() { - Optional<String> oeId = Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID); - - resolver.createStub(oeId, stubFactory, stubClass); - - verify(resolver).createStubUsingZufi(oeId, stubFactory, stubClass); - } +// @Test +// void shouldUseZufiToCreateChannel() { +// Optional<String> oeId = Optional.of(VorgangManagerListPropertiesTestFactory.ORGANISATIONSEINHEIT_ID); +// +// resolver.createStub(oeId, stubFactory, stubClass); +// +// verify(resolver).createStubUsingZufi(oeId, stubFactory, stubClass); +// } } }