Esempio n. 1
0
        public IClient Create(
            string appId,
            ITransportClient transport,
            IProtocolImplementation protocol,
            IMarshallerProvider marshaller,
            Func <ClientOptionsBuilder, ClientOptionsBuilder> setup = default)
        {
            var builder = new ClientOptionsBuilder()
                          .WithApplicationId(appId)
                          .WithMarshaller(marshaller)
                          .WithProtocol(protocol)
                          .WithTransport(transport);

            if (setup != default)
            {
                builder = setup(builder);
            }
            return(new Client(builder.Build()));
        }
        public void InvocationShouldBeRoutedToAnotherInstanceEvenIfSourceAppCanHandleIt()
        {
            MethodCallContext receivedRequestContext = null;

            Task <EchoRequest> HandleAsync(EchoRequest request, MethodCallContext context)
            {
                receivedRequestContext = context;
                return(Task.FromResult(request));
            }

            RunWith10SecTimeout(async() =>
            {
                var echoServerFactory = new TestClientFactory(
                    (broker, id) =>
                {
                    var optionsBuilder = new ClientOptionsBuilder()
                                         .WithBrokerWorkingDir(_testBrokerFixture.SharedInstance.WorkingDir)
                                         .WithDefaultConfiguration()
                                         .WithProvidedService(
                        EchoService.Id,
                        x => x.WithUnaryMethod <EchoRequest, EchoRequest>("Unary", HandleAsync))
                                         .WithApplicationId(EchoServerClient.Id);

                    return(ClientFactory.Instance.Create(optionsBuilder.Build()));
                });
                var appLauncher = RegisterDisposable(
                    new TestAppLauncher(
                        _testBrokerFixture.SharedInstance,
                        new Dictionary <string, TestClientFactory> {
                    { EchoServerClient.Id, echoServerFactory }
                }
                        )
                    );
                await appLauncher.StartAsync();
                var server   = ConnectEchoServer();
                var request  = CreateTestRequest();
                var response = await server.CallInvoker.Call(EchoUnaryMethod, request);
                response.ShouldBe(request);
                receivedRequestContext.ShouldNotBeNull();
                receivedRequestContext.ConsumerConnectionId.ShouldBe(server.ConnectionId);
            });
        }
 public static ClientOptionsBuilder WithDefaultConfiguration(
     this ClientOptionsBuilder builder,
     string brokerWorkingDir = null)
 {
     if (brokerWorkingDir == null)
     {
         brokerWorkingDir = Environment.GetEnvironmentVariable("PLEXUS_BROKER_WORKING_DIR") ?? Directory.GetCurrentDirectory();
     }
     return(builder
            .WithMarshaller(
                new ProtobufMarshallerProvider())
            .WithProtocol(
                new ProtocolImplementation(
                    ProtocolMessagePool.Instance,
                    new ProtobufProtocolSerializerFactory()))
            .WithTransport(
                new TransportClient(
                    new PipeTransmissionClient(brokerWorkingDir),
                    new ProtobufTransportProtocolSerializationProvider())));
 }
        public void InvokeApplicationBeforeItsConnection()
        {
            RunWith10SecTimeout(async() =>
            {
                Task <GreetingResponse> HandleAsync(GreetingRequest request, MethodCallContext context)
                {
                    return(Task.FromResult(new GreetingResponse {
                        Greeting = request.Name + "1"
                    }));
                }

                var brokerInstance      = _testBrokerFixture.SharedInstance;
                var createdServersCount = 0;
                var createdServerClient = new TaskCompletionSource <IClient>();
                var echoServerFactory   = new TestClientFactory(
                    (broker, id) =>
                {
                    var optionsBuilder = new ClientOptionsBuilder()
                                         .WithBrokerWorkingDir(brokerInstance.WorkingDir)
                                         .WithAppInstanceId(id)
                                         .WithApplicationId(EchoServerClient.Id)
                                         .WithDefaultConfiguration()
                                         .WithProvidedService(
                        GreetingService.Id,
                        x => x.WithUnaryMethod <GreetingRequest, GreetingResponse>(GreetingService.HelloMethodId,
                                                                                   HandleAsync));
                    var serverClient = ClientFactory.Instance.Create(optionsBuilder.Build());
                    createdServerClient.SetResult(serverClient);
                    createdServersCount++;
                    return(Task.FromResult(serverClient));
                });

                var appLauncher = RegisterDisposable(
                    new TestAppLauncher(
                        brokerInstance,
                        new Dictionary <string, TestClientFactory>
                {
                    { EchoServerClient.Id, echoServerFactory }
                },
                        false
                        )
                    );
                await appLauncher.StartAsync();

                var client1 = CreateClient <EchoClient>();
                await client1.ConnectAsync();

                var client2 = CreateClient <EchoClient>();
                await client2.ConnectAsync();

                var helloTask = client1.GreetingService.Hello(new GreetingRequest {
                    Name = "Test1"
                }).ResponseAsync;
                var callUnconnectedServerTask = createdServerClient.Task.ContinueWith(async task =>
                {
                    var serverClient = task.Result;
                    await Task.Delay(TimeSpan.FromSeconds(1));
                    var providedMethodReference = ProvidedMethodReference.CreateWithAppInstanceId(GreetingService.Id,
                                                                                                  GreetingService.HelloMethodId, EchoServerClient.Id, serverClient.ApplicationInstanceId);
                    var methodCallDescriptor = new MethodCallDescriptor(providedMethodReference);
                    await client2.CallInvoker.CallUnary <GreetingRequest, GreetingResponse>(methodCallDescriptor,
                                                                                            new GreetingRequest()
                    {
                        Name = "Test2"
                    });
                }).Unwrap();

                var connectedServerAfterDelayTask = createdServerClient.Task.ContinueWith(async task =>
                {
                    var serverClient = task.Result;

                    await Task.Delay(TimeSpan.FromSeconds(3));

                    serverClient.ConnectionId.ShouldBe(UniqueId.Empty);
                    var onlineConnectionsResponse =
                        await client1.AppLifecycleService.GetConnections(new GetConnectionsRequest
                    {
                        AppInstanceId = serverClient.ApplicationInstanceId
                    });
                    onlineConnectionsResponse.Connections.Count.ShouldBe(0);

                    await serverClient.ConnectAsync();
                }).Unwrap();

                await Task.WhenAll(helloTask, callUnconnectedServerTask, connectedServerAfterDelayTask);

                createdServersCount.ShouldBe(1);
            });
        }
        public void InvocationShouldTriggerLaunchWithSingleInstanceModeByDefault()
        {
            var serverInvokedCount = 0;

            Task <GreetingResponse> HandleAsync(GreetingRequest greetingRequest, MethodCallContext context)
            {
                Interlocked.Increment(ref serverInvokedCount);
                return(Task.FromResult(new GreetingResponse {
                    Greeting = greetingRequest.Name
                }));
            }

            RunWith10SecTimeout(async() =>
            {
                var serverCreatedCount = 0;
                var echoServerFactory  = new TestClientFactory(
                    (broker, id) =>
                {
                    WriteLog("Launching server on demand");

                    var optionsBuilder = new ClientOptionsBuilder()
                                         .WithBrokerWorkingDir(_testBrokerFixture.SharedInstance.WorkingDir)
                                         .WithAppInstanceId(id)
                                         .WithApplicationId(EchoServerClient.Id)
                                         .WithDefaultConfiguration()
                                         .WithProvidedService(
                        GreetingService.Id,
                        x => x.WithUnaryMethod <GreetingRequest, GreetingResponse>("Hello", HandleAsync));

                    serverCreatedCount++;

                    return(ClientFactory.Instance.Create(optionsBuilder.Build()));
                });

                var appLauncher = RegisterDisposable(
                    new TestAppLauncher(
                        _testBrokerFixture.SharedInstance,
                        new Dictionary <string, TestClientFactory>
                {
                    { EchoServerClient.Id, echoServerFactory }
                }
                        )
                    );
                await appLauncher.StartAsync();
                var client = new EchoClient(s => s.WithBrokerWorkingDir(_testBrokerFixture.SharedInstance.WorkingDir));
                client.ConnectAsync().ShouldCompleteIn(Timeout5Sec);
                var callDescriptor = new MethodCallDescriptor(
                    ProvidedMethodReference.Create(GreetingService.Id, "Hello", EchoServerClient.Id));
                var call1 = client.CallInvoker.CallUnary(callDescriptor, new GreetingRequest {
                    Name = "Test"
                });
                var call2 = client.CallInvoker.CallUnary(callDescriptor, new GreetingRequest {
                    Name = "Test"
                });
                await Task.WhenAny(call1.AsTask(), call2.AsTask());
                WriteLog("Call 1 completed");
                await Task.WhenAll(call1.AsTask(), call2.AsTask());
                WriteLog("Call 2 completed");
                serverCreatedCount.ShouldBe(1);
                serverInvokedCount.ShouldBe(2);
            });
        }
        public void NewAppInstanceWillBeLaunchedOnInvocationWithinContext()
        {
            var serverCreatedCount = 0;

            Task <GreetingResponse> HandleAsync(GreetingRequest greetingRequest, MethodCallContext context)
            {
                return(Task.FromResult(new GreetingResponse {
                    Greeting = greetingRequest.Name + (serverCreatedCount)
                }));
            }

            RunWith10SecTimeout(async() =>
            {
                var echoServerFactory = new TestClientFactory(
                    (broker, id) =>
                {
                    var optionsBuilder = new ClientOptionsBuilder()
                                         .WithBrokerWorkingDir(_testBrokerFixture.SharedInstance.WorkingDir)
                                         .WithAppInstanceId(id)
                                         .WithApplicationId(EchoServerClient.Id)
                                         .WithDefaultConfiguration()
                                         .WithProvidedService(
                        GreetingService.Id,
                        x => x.WithUnaryMethod <GreetingRequest, GreetingResponse>("Hello", HandleAsync));

                    serverCreatedCount++;

                    return(ClientFactory.Instance.Create(optionsBuilder.Build()));
                });

                var appLauncher = RegisterDisposable(
                    new TestAppLauncher(
                        _testBrokerFixture.SharedInstance,
                        new Dictionary <string, TestClientFactory>
                {
                    { EchoServerClient.Id, echoServerFactory }
                }
                        )
                    );
                await appLauncher.StartAsync();
                var client = CreateClient <EchoClient>();
                await client.ConnectAsync();

                var result1 = await client.GreetingService.Hello(new GreetingRequest {
                    Name = "Test1"
                });
                result1.Greeting.ShouldBe("Test11");

                var result2 = await client.GreetingService.Hello(new GreetingRequest {
                    Name = "Test2"
                });
                result2.Greeting.ShouldBe("Test21");

                serverCreatedCount.ShouldBe(1);

                var newContext  = await client.ContextLinkageService.CreateContext2(new CreateContextRequest());
                var allContexts = await client.ContextLinkageService.GetContexts(new Empty());

                allContexts.Contexts.Count.ShouldBe(1);
                allContexts.Contexts[0].Id.ShouldBe(newContext.Id);

                var result3 = await client.CallInvoker.Call(
                    GreetingService.DefaultDescriptor.HelloMethod,
                    new GreetingRequest {
                    Name = "Test3"
                },
                    ContextLinkageOptions.WithCurrentContext());

                result3.Greeting.ShouldBe("Test32");

                serverCreatedCount.ShouldBe(2);

                WriteLog("Starting to read context loaded stream");

                var contextStatus = await client.ContextLinkageService.ContextLoadedStream(newContext).ResponseStream
                                    .FirstAsync(update => update.LoadedAppDescriptors.Any(appDescriptor => appDescriptor.AppId == EchoServerClient.Id));

                contextStatus.LoadedAppDescriptors.Any(descriptor => descriptor.AppId == EchoClient.Id);

                var linkedInvocations = await client.ContextLinkageService.GetLinkedInvocations(newContext);

                linkedInvocations.Invocations
                .Single(reference => reference.AppInfo.ProvidedServices.Any(service => service.ServiceId == GreetingService.Id))
                .ShouldNotBeNull();
            });
        }