Example #1
0
        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);
        }
Example #2
0
        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();
        }
Example #3
0
        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"));
        }
Example #4
0
        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);
        }
Example #5
0
        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
            });
        }
Example #6
0
        private static async Task <EpoxyConnection> ClientConn(IPEndPoint endPoint)
        {
            var transport = new EpoxyTransportBuilder()
                            .Construct();

            return(await transport.ConnectToAsync(endPoint));
        }
Example #7
0
        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
            });
        }
Example #8
0
        private static async Task <EpoxyConnection> ClientConn(string address)
        {
            var transport = new EpoxyTransportBuilder()
                            .Construct();

            return(await transport.ConnectToAsync(address));
        }
Example #9
0
        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;
        }
Example #10
0
        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);
        }
Example #12
0
        private static async Task<EpoxyConnection> ClientConn(string address)
        {
            var transport = new EpoxyTransportBuilder()
                .Construct();

            return await transport.ConnectToAsync(address);

        }
Example #13
0
        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();
        }
Example #16
0
        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);
        }
Example #17
0
        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();
            }
        }
Example #18
0
        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);
        }
Example #19
0
        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);
        }
Example #20
0
        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);
        }
Example #21
0
        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;
        }
Example #22
0
        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;
        }
Example #23
0
        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);
        }
Example #24
0
        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();
        }
Example #25
0
        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);
        }
Example #26
0
        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);
        }
Example #27
0
        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;
        }
Example #28
0
        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();
        }
Example #29
0
 public void Builder_Construct_NoArgs_Succeeds()
 {
     var builder = new EpoxyTransportBuilder();
     Assert.NotNull(builder.Construct());
 }
Example #30
0
        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();
        }
Example #31
0
 private static EpoxyTransport MakeTransport()
 {
     var transport = new EpoxyTransportBuilder().Construct();
     return transport;
 }
Example #32
0
        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();
        }
Example #33
0
        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();
        }
Example #34
0
        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();
            }
        }
Example #35
0
        private static EpoxyTransport MakeTransport()
        {
            var transport = new EpoxyTransportBuilder().Construct();

            return(transport);
        }
Example #36
0
        public void Builder_Construct_NoArgs_Succeeds()
        {
            var builder = new EpoxyTransportBuilder();

            Assert.NotNull(builder.Construct());
        }
Example #37
0
        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();
        }