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(); }); }