private async static Task <EpoxyTransport> SetupAsync() { var transport = new EpoxyTransportBuilder() .SetLogSink(new ConsoleLogger()) .Construct(); var pingPongService = new PingPongService(); EpoxyListener pingPongListener = transport.MakeListener(PingEndpoint); pingPongListener.AddService(pingPongService); var reversePingPongService = new ReversePingPongService(); EpoxyListener reversePingPongListener = transport.MakeListener(ReversePingEndpoint); reversePingPongListener.AddService(reversePingPongService); await Task.WhenAll( pingPongListener.StartAsync(), reversePingPongListener.StartAsync()); pingConnection = await transport.ConnectToAsync(PingUri); reverseConnection = await transport.ConnectToAsync(ReversePingUri); return(transport); }
public static void Main() { // Bond has an abstraction for network protocols called a Transport. Epoxy is a custom protocol that is // lightweight and built into Bond.Comm. If it doesn't meet your needs, you can write your own Transport. var transport = new EpoxyTransportBuilder().Construct(); var connection = transport.ConnectToAsync(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultPort)).Result; // For each service, Bond will generate a proxy with methods corresponding to the service methods you defined. var proxy = new CalculatorProxy <EpoxyConnection>(connection); var addArgs = new BinaryOpArgs { left = 2, right = 2 }; // The result of a Bond call is a IMessage, which is either a payload or an error. // Display() shows how to handle both cases. var addResult = proxy.AddAsync(addArgs).Result; Display("Add", addArgs, addResult); var divArgs = new BinaryOpArgs { left = 1, right = 0 }; var divResult = proxy.DivideAsync(divArgs).Result; Display("Divide", divArgs, divResult); Console.ReadLine(); }
public async Task Tls_ServerBadCert_ConnectionFails() { var serverTlsConfig = new EpoxyServerTlsConfig(testServerCert, checkCertificateRevocation: false); var serverTransport = new EpoxyTransportBuilder().SetServerTlsConfig(serverTlsConfig) .Construct(); transports.Add(serverTransport); var listener = serverTransport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultSecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); var clientTlsConfig = new EpoxyClientTlsConfig( checkCertificateRevocation: false, // Intentionally set this to null so that the client gets an // invalid certificate. If this test passes on your machine, // it's probably because you've installed the Bond test root // certificate as a trusted root. This certificate cannot be // trusted, so you should uninstall it. remoteCertificateValidationCallback: null); var clientTransport = new EpoxyTransportBuilder() .SetResolver(ResolveEverythingToLocalhost) .SetClientTlsConfig(clientTlsConfig) .Construct(); transports.Add(clientTransport); Assert.Throws <AuthenticationException>(async() => await clientTransport.ConnectToAsync("epoxys://bond-test-server1")); }
private async static Task <EpoxyTransport> SetupAsync() { var transport = new EpoxyTransportBuilder() .SetLogSink(new ConsoleLogger()) .SetMetricsSink(new ConsoleMetricsSink()) .Construct(); var pingEndpoint = new IPEndPoint(IPAddress.Loopback, pingPort); var reversePingEndpoint = new IPEndPoint(IPAddress.Loopback, reversePingPort); var pingPongService = new PingPongService(); EpoxyListener pingPongListener = transport.MakeListener(pingEndpoint); pingPongListener.AddService(pingPongService); var reversePingPongService = new ReversePingPongService(); EpoxyListener reversePingPongListener = transport.MakeListener(reversePingEndpoint); reversePingPongListener.AddService(reversePingPongService); await Task.WhenAll( pingPongListener.StartAsync(), reversePingPongListener.StartAsync()); s_pingConnection = await transport.ConnectToAsync(pingPongListener.ListenEndpoint, CancellationToken.None); s_reverseConnection = await transport.ConnectToAsync(reversePingPongListener.ListenEndpoint, CancellationToken.None); return(transport); }
public async Task <TestClientServer <TService> > SetupTestClientServer <TService>( ILayerStackProvider serviceLayerStackProvider = null, ILayerStackProvider clientLayerStackProvider = null ) where TService : class, IService, new() { var testService = new TService(); EpoxyTransport serviceTransport = new EpoxyTransportBuilder() .SetLayerStackProvider(serviceLayerStackProvider) .Construct(); listener = serviceTransport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultInsecurePort)); listener.AddService(testService); await listener.StartAsync(); EpoxyTransport clientTransport = new EpoxyTransportBuilder() .SetLayerStackProvider(clientLayerStackProvider) .Construct(); EpoxyConnection clientConnection = await clientTransport.ConnectToAsync("epoxy://127.0.0.1"); return(new TestClientServer <TService> { Service = testService, ServiceTransport = serviceTransport, Listener = listener, ClientConnection = clientConnection, ClientTransport = clientTransport }); }
private static async Task <EpoxyConnection> ClientConn(IPEndPoint endPoint) { var transport = new EpoxyTransportBuilder() .Construct(); return(await transport.ConnectToAsync(endPoint)); }
public static async Task <TestClientServer <TService> > SetupTestClientServer <TService>(ILayerStack serviceLayerStack = null, ILayerStack clientLayerStack = null) where TService : class, IService, new() { var testService = new TService(); EpoxyTransport serviceTransport = new EpoxyTransportBuilder() .SetLayerStack(serviceLayerStack) .Construct(); EpoxyListener listener = serviceTransport.MakeListener(new IPEndPoint(IPAddress.Loopback, 0)); listener.AddService(testService); await listener.StartAsync(); EpoxyTransport clientTransport = new EpoxyTransportBuilder() // some tests rely on the use of DebugExceptionHandler to assert things about the error message .SetLayerStack(clientLayerStack) .Construct(); EpoxyConnection clientConnection = await clientTransport.ConnectToAsync(listener.ListenEndpoint); return(new TestClientServer <TService> { Service = testService, ServiceTransport = serviceTransport, Listener = listener, ClientConnection = clientConnection, ClientTransport = clientTransport }); }
private static async Task <EpoxyConnection> ClientConn(string address) { var transport = new EpoxyTransportBuilder() .Construct(); return(await transport.ConnectToAsync(address)); }
private async static Task<EpoxyTransport> SetupAsync() { var transport = new EpoxyTransportBuilder() .SetLogSink(new ConsoleLogger()) .SetMetricsSink(new ConsoleMetricsSink()) .Construct(); var pingEndpoint = new IPEndPoint(IPAddress.Loopback, pingPort); var reversePingEndpoint = new IPEndPoint(IPAddress.Loopback, reversePingPort); var pingPongService = new PingPongService(); EpoxyListener pingPongListener = transport.MakeListener(pingEndpoint); pingPongListener.AddService(pingPongService); var reversePingPongService = new ReversePingPongService(); EpoxyListener reversePingPongListener = transport.MakeListener(reversePingEndpoint); reversePingPongListener.AddService(reversePingPongService); await Task.WhenAll( pingPongListener.StartAsync(), reversePingPongListener.StartAsync()); s_pingConnection = await transport.ConnectToAsync(pingPongListener.ListenEndpoint, CancellationToken.None); s_reverseConnection = await transport.ConnectToAsync(reversePingPongListener.ListenEndpoint, CancellationToken.None); return transport; }
public async Task Tls_Mutual_CanAuthenticate() { var serverTlsConfig = new EpoxyServerTlsConfig( testServerCert, checkCertificateRevocation: false, clientCertificateRequired: true, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate ); var clientTlsConfig = new EpoxyClientTlsConfig( certificate: testClientCert, checkCertificateRevocation: false, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate); var transport = new EpoxyTransportBuilder() .SetResolver(ResolveEverythingToLocalhost) .SetServerTlsConfig(serverTlsConfig) .SetClientTlsConfig(clientTlsConfig) .Construct(); transports.Add(transport); var listener = transport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultSecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); EpoxyConnection clientConnection = await transport.ConnectToAsync("epoxys://bond-test-server1"); var proxy = new DummyTestProxy <EpoxyConnection>(clientConnection); await AssertRequestResponseWorksAsync(proxy); }
private EpoxyTransport MakeTransport() { var transport = new EpoxyTransportBuilder().Construct(); transports.Add(transport); return(transport); }
private static async Task<EpoxyConnection> ClientConn(string address) { var transport = new EpoxyTransportBuilder() .Construct(); return await transport.ConnectToAsync(address); }
public void Builder_Construct_NoArgs_Succeeds() { var builder = new EpoxyTransportBuilder(); EpoxyTransport result = builder.Construct(); Assert.NotNull(result); transports.Add(result); }
private static async Task <PingPongProxy <EpoxyConnection> > SetupProxyAsync(ILayerStackProvider layerStack) { var transport = new EpoxyTransportBuilder().SetLayerStackProvider(layerStack).Construct(); var endpoint = new EpoxyTransport.Endpoint(IPAddress.Loopback.ToString(), 25188, false); var conn = await transport.ConnectToAsync(endpoint, CancellationToken.None); return(new PingPongProxy <EpoxyConnection>(conn)); }
private static async Task SetupAsync(ILayerStackProvider layerStackProvider) { var endpoint = new IPEndPoint(IPAddress.Loopback, (int)PingConstants.Port); EpoxyTransport transport = new EpoxyTransportBuilder().SetLayerStackProvider(layerStackProvider).Construct(); EpoxyListener pingPongListener = transport.MakeListener(endpoint); var pingPongService = new PingPongService(); pingPongListener.AddService(pingPongService); await pingPongListener.StartAsync(); }
public async Task TransportWithCustomResolver_UsesResolver() { await SetupTestClientServer <DummyTestService>(); var clientTransport = new EpoxyTransportBuilder().SetResolver(ResolveEverythingToLocalhost).Construct(); transports.Add(clientTransport); EpoxyConnection clientConnection = await clientTransport.ConnectToAsync("epoxy://resolve-this-to-localhost/"); var proxy = new DummyTestProxy <EpoxyConnection>(clientConnection); await AssertRequestResponseWorksAsync(proxy); }
public async Task Tls_MutualNoClientCert_ProxyDoesNotWork() { var serverTlsConfig = new EpoxyServerTlsConfig( testServerCert, checkCertificateRevocation: false, clientCertificateRequired: true, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate ); var clientTlsConfig = new EpoxyClientTlsConfig(certificate: null, checkCertificateRevocation: false, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate); var transport = new EpoxyTransportBuilder() .SetResolver(ResolveEverythingToLocalhost) .SetServerTlsConfig(serverTlsConfig) .SetClientTlsConfig(clientTlsConfig) .Construct(); listener = transport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultSecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); try { // The .NET SslStream implementation currently does not give us // a way to signal during TLS handshaking that the server is // rejecting the connection. Instead, we have to RST the // underlying socket. With Epoxy's current implementation, this // can't reliably be detected at connection time. So we attempt // to exercise the connection using a proxy and expect that to fail. EpoxyConnection clientConnection = await transport.ConnectToAsync("epoxys://bond-test-server1"); var proxy = new DummyTestProxy <EpoxyConnection>(clientConnection); await AssertRequestResponseWorksAsync(proxy); } catch (Exception ex) when(ex is InvalidOperationException || ex is AuthenticationException) { // An expected exception type, depending on timing, so pass the // test. } catch (Exception ex) { Assert.Fail("Unexpected exception of type {0}: {1}", ex.GetType(), ex); } finally { await transport.StopAsync(); } }
static async Task MainAsync(X509Certificate2 serverCertificate) { var tlsConfig = new EpoxyServerTlsConfig(serverCertificate); EpoxyTransport transport = new EpoxyTransportBuilder().SetServerTlsConfig(tlsConfig).Construct(); await StartServiceListenersAsync(transport); var connection = await transport.ConnectToAsync("epoxys://localhost"); var proxy = new SimpleProxy <EpoxyConnection>(connection); IMessage <SimpleResult> response = await proxy.SimpleMethodAsync(); PrintResponse(response); }
static async Task MainAsync(X509Certificate2 serverCertificate) { var tlsConfig = new EpoxyServerTlsConfig(serverCertificate); EpoxyTransport transport = new EpoxyTransportBuilder().SetServerTlsConfig(tlsConfig).Construct(); EpoxyListener listener = transport.MakeListener(serviceEndpoint); listener.AddService(new SimpleService()); await listener.StartAsync(); var connection = await transport.ConnectToAsync("epoxys://localhost"); var proxy = new SimpleProxy<EpoxyConnection>(connection); IMessage<SimpleResult> response = await proxy.SimpleMethodAsync(); PrintResponse(response); }
private static async Task <EpoxyTransport> Server( ILogSink logSink, IMetricsSink metricsSink, IPEndPoint endPoint) { var transport = new EpoxyTransportBuilder() .SetLogSink(logSink) .SetMetricsSink(metricsSink) .Construct(); var service = new DummyTestService(); var listener = transport.MakeListener(endPoint); listener.AddService(service); await listener.StartAsync(); return(transport); }
private async Task<EpoxyTransport> Server( ILogSink logSink, IMetricsSink metricsSink, IPEndPoint endPoint) { var transport = new EpoxyTransportBuilder() .SetLogSink(logSink) .SetMetricsSink(metricsSink) .Construct(); var service = new DummyTestService(); var listener = transport.MakeListener(endPoint); listeners.Add(listener); listener.AddService(service); await listener.StartAsync(); return transport; }
private async static Task<EpoxyTransport> SetupAsync() { var transport = new EpoxyTransportBuilder() .SetLogSink(new ConsoleLogger()) .Construct(); var assignAPortEndPoint = new IPEndPoint(IPAddress.Loopback, 0); var notifyService = new NotifyEventService(); EpoxyListener notifyListener = transport.MakeListener(assignAPortEndPoint); notifyListener.AddService(notifyService); await notifyListener.StartAsync(); s_connection = await transport.ConnectToAsync(notifyListener.ListenEndpoint, CancellationToken.None); return transport; }
private async static Task <EpoxyTransport> SetupAsync() { var transport = new EpoxyTransportBuilder() .SetLogSink(new ConsoleLogger()) .Construct(); var assignAPortEndPoint = new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultInsecurePort); var notifyService = new NotifyEventService(); EpoxyListener notifyListener = transport.MakeListener(assignAPortEndPoint); notifyListener.AddService(notifyService); await notifyListener.StartAsync(); s_connection = await transport.ConnectToAsync("epoxy://127.0.0.1", CancellationToken.None); return(transport); }
public static void Main() { // Provide a sink so you can get Bond's log messages and forward them to your favorite logging system. // There is a similar interface for per-connection and per-request metrics. Log.SetHandler(new ConsoleLogger()); // Bond has an abstraction for network protocols called a Transport. Epoxy is a custom protocol that is // lightweight and built into Bond.Comm. If it doesn't meet your needs, you can write your own Transports. var transport = new EpoxyTransportBuilder().Construct(); var listener = transport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultPort)); listener.AddService(new CalculatorService()); // When this Task completes, your service will be up and accepting requests. listener.StartAsync().Wait(); // Block and let the service run. Console.WriteLine($"{nameof(CalculatorService)} up and running. Press enter to exit."); Console.ReadLine(); }
private async static Task <EpoxyTransport> SetupAsync() { var handler = new ConsoleLogger(); Log.SetHandler(handler); var transport = new EpoxyTransportBuilder().Construct(); var assignAPortEndPoint = new IPEndPoint(IPAddress.Loopback, 0); var notifyService = new NotifyEventService(); EpoxyListener notifyListener = transport.MakeListener(assignAPortEndPoint); notifyListener.AddService(notifyService); await notifyListener.StartAsync(); s_connection = await transport.ConnectToAsync(notifyListener.ListenEndpoint, CancellationToken.None); return(transport); }
public async Task IPv6Listener_RequestReply_PayloadResponse() { var transport = new EpoxyTransportBuilder().Construct(); transports.Add(transport); var listener = transport.MakeListener(new IPEndPoint(IPAddress.IPv6Loopback, EpoxyTransport.DefaultInsecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); EpoxyConnection conn = await transport.ConnectToAsync("epoxy://[::1]"); var proxy = new DummyTestProxy <EpoxyConnection>(conn); var request = new Dummy { int_value = 100 }; IMessage <Dummy> response = await proxy.ReqRspMethodAsync(request); Assert.IsFalse(response.IsError); Assert.AreEqual(101, response.Payload.Deserialize().int_value); }
private async static Task<EpoxyTransport> SetupAsync() { var transport = new EpoxyTransportBuilder() .SetLogSink(new ConsoleLogger()) .Construct(); var pingPongService = new PingPongService(); EpoxyListener pingPongListener = transport.MakeListener(PingEndpoint); pingPongListener.AddService(pingPongService); var reversePingPongService = new ReversePingPongService(); EpoxyListener reversePingPongListener = transport.MakeListener(ReversePingEndpoint); reversePingPongListener.AddService(reversePingPongService); await Task.WhenAll( pingPongListener.StartAsync(), reversePingPongListener.StartAsync()); pingConnection = await transport.ConnectToAsync(PingUri); reverseConnection = await transport.ConnectToAsync(ReversePingUri); return transport; }
private async Task Server_MetricsAreEmitted(MessageType messageType) { // There are several invariants around metrics that involve cross-request and cross-connection state. // Bring up a service, connect to it several times, and make several requests each time. const string expectedServiceName = "unittest.comm.DummyTest"; string expectedMethodName; Action<DummyTestProxy<EpoxyConnection>> doRpc; switch (messageType) { case MessageType.REQUEST: expectedMethodName = "ReqRspMethod"; doRpc = async proxy => await proxy.ReqRspMethodAsync(new Dummy()); break; case MessageType.EVENT: expectedMethodName = "EventMethod"; doRpc = proxy => proxy.EventMethodAsync(new Dummy()); break; default: throw new ArgumentException(nameof(messageType)); } var metricsSink = new TestMetricsSink(); var serverTransport = new EpoxyTransportBuilder().SetMetricsSink(metricsSink).Construct(); var listener = serverTransport.MakeListener("127.0.0.1"); listener.AddService(new DummyTestService()); await listener.StartAsync(); var serverEndpoint = listener.ListenEndpoint.ToString(); var connectionsSeen = 0; var requestsSeen = 0; var connectionIdsSeen = new HashSet<string>(); var requestIdsSeen = new HashSet<string>(); for (var i = 0; i < 3; i++) { var clientTransport = new EpoxyTransportBuilder().Construct(); var clientConn = await clientTransport.ConnectToAsync("epoxy://127.0.0.1"); var clientEndpoint = clientConn.LocalEndPoint.ToString(); var proxy = new DummyTestProxy<EpoxyConnection>(clientConn); string currentConnectionId = null; for (var j = 0; j < 3; j++) { doRpc(proxy); WaitForMetrics(); Assert.AreEqual(requestsSeen + 1, metricsSink.RequestMetricsReceived, "Did not get a RequestMetrics."); Assert.NotNull(metricsSink.LastRequestMetrics); var requestMetrics = metricsSink.LastRequestMetrics; // The new RequestMetrics should have non-empty unique IDs. The request ID should be unique // and the connection ID should match that of any requests previously made on this connection. AssertValidId(requestMetrics.request_id); AssertValidId(requestMetrics.connection_id); CollectionAssert.DoesNotContain(requestIdsSeen, requestMetrics.request_id, "Got two RequestMetrics with the same request ID."); requestIdsSeen.Add(requestMetrics.request_id); if (currentConnectionId == null) { currentConnectionId = requestMetrics.connection_id; } else { Assert.AreEqual(currentConnectionId, requestMetrics.connection_id, "Got two different connection IDs in RequestMetrics for the same connection."); } Assert.AreEqual(serverEndpoint, requestMetrics.local_endpoint); Assert.AreEqual(clientEndpoint, requestMetrics.remote_endpoint); Assert.AreEqual(expectedServiceName, requestMetrics.service_name); Assert.AreEqual(expectedMethodName, requestMetrics.method_name); Assert.Null(requestMetrics.error); Assert.Greater(requestMetrics.total_time_millis, 0.0); Assert.Greater(requestMetrics.service_method_time_millis, 0.0); Assert.Greater(requestMetrics.total_time_millis, requestMetrics.service_method_time_millis); requestsSeen++; } // We're still connected, so there shouldn't be any new connection metrics. Assert.AreEqual(connectionsSeen, metricsSink.ConnectionMetricsReceived); await clientConn.StopAsync(); WaitForMetrics(); Assert.AreEqual(connectionsSeen + 1, metricsSink.ConnectionMetricsReceived); Assert.NotNull(metricsSink.LastConnectionMetrics); var connectionMetrics = metricsSink.LastConnectionMetrics; AssertValidId(connectionMetrics.connection_id); // The connection ID in the new ConnectionMetrics must match the one seen by the requests. Assert.AreEqual(currentConnectionId, connectionMetrics.connection_id, "Got a different connection IDs in ConnectionMetrics and this connection's RequestMetrics."); CollectionAssert.DoesNotContain(connectionIdsSeen, connectionMetrics.connection_id, "Got two different ConnectionMetrics with the same connection ID."); connectionIdsSeen.Add(connectionMetrics.connection_id); Assert.AreEqual(serverEndpoint, connectionMetrics.local_endpoint); Assert.AreEqual(clientEndpoint, connectionMetrics.remote_endpoint); Assert.Greater(connectionMetrics.duration_millis, 0.0); connectionsSeen++; } await listener.StopAsync(); }
public void Builder_Construct_NoArgs_Succeeds() { var builder = new EpoxyTransportBuilder(); Assert.NotNull(builder.Construct()); }
public async Task TransportWithCustomResolver_UsesResolver() { await SetupTestClientServer<DummyTestService>(); var clientTransport = new EpoxyTransportBuilder().SetResolver(ResolveEverythingToLocalhost).Construct(); EpoxyConnection clientConnection = await clientTransport.ConnectToAsync("epoxy://resolve-this-to-localhost/"); var proxy = new DummyTestProxy<EpoxyConnection>(clientConnection); await AssertRequestResponseWorksAsync(proxy); await clientTransport.StopAsync(); }
private static EpoxyTransport MakeTransport() { var transport = new EpoxyTransportBuilder().Construct(); return transport; }
public async Task Tls_ServerBadCert_ConnectionFails() { var serverTlsConfig = new EpoxyServerTlsConfig(testServerCert, checkCertificateRevocation: false); var serverTransport = new EpoxyTransportBuilder().SetServerTlsConfig(serverTlsConfig).Construct(); listener = serverTransport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultSecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); var clientTlsConfig = new EpoxyClientTlsConfig( checkCertificateRevocation: false, // Intentionally set this to null so that the client gets an // invalid certificate. If this test passes on your machine, // it's probably because you've installed the Bond test root // certificate as a trusted root. This certificate cannot be // trusted, so you should uninstall it. remoteCertificateValidationCallback: null); var clientTransport = new EpoxyTransportBuilder() .SetResolver(ResolveEverythingToLocalhost) .SetClientTlsConfig(clientTlsConfig) .Construct(); Assert.Throws<AuthenticationException>(async () => await clientTransport.ConnectToAsync("epoxys://bond-test-server1")); await clientTransport.StopAsync(); await serverTransport.StopAsync(); }
public async Task Tls_Mutual_CanAuthenticate() { var serverTlsConfig = new EpoxyServerTlsConfig( testServerCert, checkCertificateRevocation: false, clientCertificateRequired: true, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate ); var clientTlsConfig = new EpoxyClientTlsConfig( certificate: testClientCert, checkCertificateRevocation: false, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate); var transport = new EpoxyTransportBuilder() .SetResolver(ResolveEverythingToLocalhost) .SetServerTlsConfig(serverTlsConfig) .SetClientTlsConfig(clientTlsConfig) .Construct(); listener = transport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultSecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); EpoxyConnection clientConnection = await transport.ConnectToAsync("epoxys://bond-test-server1"); var proxy = new DummyTestProxy<EpoxyConnection>(clientConnection); await AssertRequestResponseWorksAsync(proxy); await transport.StopAsync(); }
public async Task Tls_MutualNoClientCert_ProxyDoesNotWork() { var serverTlsConfig = new EpoxyServerTlsConfig( testServerCert, checkCertificateRevocation: false, clientCertificateRequired: true, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate ); var clientTlsConfig = new EpoxyClientTlsConfig(certificate: null, checkCertificateRevocation: false, remoteCertificateValidationCallback: EnsureRootedWithTestCertificate); var transport = new EpoxyTransportBuilder() .SetResolver(ResolveEverythingToLocalhost) .SetServerTlsConfig(serverTlsConfig) .SetClientTlsConfig(clientTlsConfig) .Construct(); listener = transport.MakeListener(new IPEndPoint(IPAddress.Loopback, EpoxyTransport.DefaultSecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); try { // The .NET SslStream implementation currently does not give us // a way to signal during TLS handshaking that the server is // rejecting the connection. Instead, we have to RST the // underlying socket. With Epoxy's current implementation, this // can't reliably be detected at connection time. So we attempt // to exercise the connection using a proxy and expect that to fail. EpoxyConnection clientConnection = await transport.ConnectToAsync("epoxys://bond-test-server1"); var proxy = new DummyTestProxy<EpoxyConnection>(clientConnection); await AssertRequestResponseWorksAsync(proxy); } catch (Exception ex) when (ex is InvalidOperationException || ex is AuthenticationException) { // An expected exception type, depending on timing, so pass the // test. } catch (Exception ex) { Assert.Fail("Unexpected exception of type {0}: {1}", ex.GetType(), ex); } finally { await transport.StopAsync(); } }
private static EpoxyTransport MakeTransport() { var transport = new EpoxyTransportBuilder().Construct(); return(transport); }
public async Task IPv6Listener_RequestReply_PayloadResponse() { var transport = new EpoxyTransportBuilder().Construct(); listener = transport.MakeListener(new IPEndPoint(IPAddress.IPv6Loopback, EpoxyTransport.DefaultInsecurePort)); listener.AddService(new DummyTestService()); await listener.StartAsync(); EpoxyConnection conn = await transport.ConnectToAsync("epoxy://[::1]"); var proxy = new DummyTestProxy<EpoxyConnection>(conn); var request = new Dummy { int_value = 100 }; IMessage<Dummy> response = await proxy.ReqRspMethodAsync(request); Assert.IsFalse(response.IsError); Assert.AreEqual(101, response.Payload.Deserialize().int_value); await transport.StopAsync(); }
private async Task Server_MetricsAreEmitted(MessageType messageType) { // There are several invariants around metrics that involve cross-request and cross-connection state. // Bring up a service, connect to it several times, and make several requests each time. const string expectedServiceName = "unittest.comm.DummyTest"; string expectedMethodName; Action <DummyTestProxy <EpoxyConnection> > doRpc; switch (messageType) { case MessageType.REQUEST: expectedMethodName = "ReqRspMethod"; doRpc = async proxy => await proxy.ReqRspMethodAsync(new Dummy()); break; case MessageType.EVENT: expectedMethodName = "EventMethod"; doRpc = proxy => proxy.EventMethodAsync(new Dummy()); break; default: throw new ArgumentException(nameof(messageType)); } var metricsSink = new TestMetricsSink(); var serverTransport = new EpoxyTransportBuilder().SetMetricsSink(metricsSink).Construct(); var listener = serverTransport.MakeListener("127.0.0.1"); listener.AddService(new DummyTestService()); await listener.StartAsync(); var serverEndpoint = listener.ListenEndpoint.ToString(); var connectionsSeen = 0; var requestsSeen = 0; var connectionIdsSeen = new HashSet <string>(); var requestIdsSeen = new HashSet <string>(); for (var i = 0; i < 3; i++) { var clientTransport = new EpoxyTransportBuilder().Construct(); var clientConn = await clientTransport.ConnectToAsync("epoxy://127.0.0.1"); var clientEndpoint = clientConn.LocalEndPoint.ToString(); var proxy = new DummyTestProxy <EpoxyConnection>(clientConn); string currentConnectionId = null; for (var j = 0; j < 3; j++) { doRpc(proxy); WaitForMetrics(); Assert.AreEqual(requestsSeen + 1, metricsSink.RequestMetricsReceived, "Did not get a RequestMetrics."); Assert.NotNull(metricsSink.LastRequestMetrics); var requestMetrics = metricsSink.LastRequestMetrics; // The new RequestMetrics should have non-empty unique IDs. The request ID should be unique // and the connection ID should match that of any requests previously made on this connection. AssertValidId(requestMetrics.request_id); AssertValidId(requestMetrics.connection_id); CollectionAssert.DoesNotContain(requestIdsSeen, requestMetrics.request_id, "Got two RequestMetrics with the same request ID."); requestIdsSeen.Add(requestMetrics.request_id); if (currentConnectionId == null) { currentConnectionId = requestMetrics.connection_id; } else { Assert.AreEqual(currentConnectionId, requestMetrics.connection_id, "Got two different connection IDs in RequestMetrics for the same connection."); } Assert.AreEqual(serverEndpoint, requestMetrics.local_endpoint); Assert.AreEqual(clientEndpoint, requestMetrics.remote_endpoint); Assert.AreEqual(expectedServiceName, requestMetrics.service_name); Assert.AreEqual(expectedMethodName, requestMetrics.method_name); Assert.Null(requestMetrics.error); Assert.Greater(requestMetrics.total_time_millis, 0.0); Assert.Greater(requestMetrics.service_method_time_millis, 0.0); Assert.Greater(requestMetrics.total_time_millis, requestMetrics.service_method_time_millis); requestsSeen++; } // We're still connected, so there shouldn't be any new connection metrics. Assert.AreEqual(connectionsSeen, metricsSink.ConnectionMetricsReceived); await clientConn.StopAsync(); WaitForMetrics(); Assert.AreEqual(connectionsSeen + 1, metricsSink.ConnectionMetricsReceived); Assert.NotNull(metricsSink.LastConnectionMetrics); var connectionMetrics = metricsSink.LastConnectionMetrics; AssertValidId(connectionMetrics.connection_id); // The connection ID in the new ConnectionMetrics must match the one seen by the requests. Assert.AreEqual(currentConnectionId, connectionMetrics.connection_id, "Got a different connection IDs in ConnectionMetrics and this connection's RequestMetrics."); CollectionAssert.DoesNotContain(connectionIdsSeen, connectionMetrics.connection_id, "Got two different ConnectionMetrics with the same connection ID."); connectionIdsSeen.Add(connectionMetrics.connection_id); Assert.AreEqual(serverEndpoint, connectionMetrics.local_endpoint); Assert.AreEqual(clientEndpoint, connectionMetrics.remote_endpoint); Assert.Greater(connectionMetrics.duration_millis, 0.0); connectionsSeen++; } await listener.StopAsync(); }