public async Task CreateClient_ServerCallContextHasValues_PropogatedDeadlineAndCancellation()
        {
            // Arrange
            var baseAddress       = new Uri("http://localhost");
            var deadline          = DateTime.UtcNow.AddDays(1);
            var cancellationToken = new CancellationTokenSource().Token;

            CallOptions options = default;

            var services = new ServiceCollection();

            services.AddOptions();
            services.AddSingleton(CreateHttpContextAccessorWithServerCallContext(deadline, cancellationToken));
            services
            .AddGrpcClient <Greeter.GreeterClient>(o =>
            {
                o.Address = baseAddress;
            })
            .EnableCallContextPropagation()
            .AddInterceptor(() => new CallbackInterceptor(o => options = o))
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = CreateGrpcClientFactory(serviceProvider);
            var client        = clientFactory.CreateClient <Greeter.GreeterClient>(nameof(Greeter.GreeterClient));

            // Act
            await client.SayHelloAsync(new HelloRequest()).ResponseAsync.DefaultTimeout();

            // Assert
            Assert.AreEqual(deadline, options.Deadline);
            Assert.AreEqual(cancellationToken, options.CancellationToken);
        }
コード例 #2
0
        public void AddGrpcClient_ConfigureNamedOptions_OptionsSet()
        {
            // Arrange
            var baseAddress1 = new Uri("http://localhost");
            var baseAddress2 = new Uri("http://contoso");

            var services = new ServiceCollection();

            services
            .AddGrpcClient <Greeter.GreeterClient>("First", o =>
            {
                o.Address = baseAddress1;
            })
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));
            services
            .AddGrpcClient <Greeter.GreeterClient>("Second", o =>
            {
                o.Address = baseAddress2;
            })
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            // Act
            var optionsMonitor = serviceProvider.GetRequiredService <IOptionsMonitor <GrpcClientFactoryOptions> >();
            var options1       = optionsMonitor.Get("First");
            var options2       = optionsMonitor.Get("Second");

            // Assert
            Assert.AreEqual(baseAddress1, options1.Address);
            Assert.AreEqual(baseAddress2, options2.Address);
        }
        public async Task CreateClient_NoServerCallContextOnHttpContext_ThrowError()
        {
            // Arrange
            var baseAddress = new Uri("http://localhost");

            var services = new ServiceCollection();

            services.AddOptions();
            services.AddSingleton(CreateHttpContextAccessor(new DefaultHttpContext()));
            services
            .AddGrpcClient <Greeter.GreeterClient>(o =>
            {
                o.Address = baseAddress;
            })
            .EnableCallContextPropagation()
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = CreateGrpcClientFactory(serviceProvider);
            var client        = clientFactory.CreateClient <Greeter.GreeterClient>(nameof(Greeter.GreeterClient));

            // Act
            var ex = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() => client.SayHelloAsync(new HelloRequest(), new CallOptions()).ResponseAsync).DefaultTimeout();

            // Assert
            Assert.AreEqual("Unable to propagate server context values to the call. Can't find the gRPC ServerCallContext on the current HttpContext.", ex.Message);
        }
        public async Task CreateClient_NoServerCallContextOnHttpContextIgnoreError_Success()
        {
            // Arrange
            var testSink     = new TestSink();
            var testProvider = new TestLoggerProvider(testSink);

            var baseAddress = new Uri("http://localhost");

            var services = new ServiceCollection();

            services.AddLogging(o => o.AddProvider(testProvider).SetMinimumLevel(LogLevel.Debug));
            services.AddOptions();
            services.AddSingleton(CreateHttpContextAccessor(new DefaultHttpContext()));
            services
            .AddGrpcClient <Greeter.GreeterClient>(o =>
            {
                o.Address = baseAddress;
            })
            .EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true)
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = CreateGrpcClientFactory(serviceProvider);
            var client        = clientFactory.CreateClient <Greeter.GreeterClient>(nameof(Greeter.GreeterClient));

            // Act
            await client.SayHelloAsync(new HelloRequest(), new CallOptions()).ResponseAsync.DefaultTimeout();

            // Assert
            var log = testSink.Writes.Single(w => w.EventId.Name == "PropagateServerCallContextFailure");

            Assert.AreEqual("Unable to propagate server context values to the call. Can't find the gRPC ServerCallContext on the current HttpContext.", log.Message);
        }
コード例 #5
0
        public void CreateClient_MultipleNamedClients_ReturnMatchingClient()
        {
            // Arrange
            var services = new ServiceCollection();

            services
            .AddGrpcClient <TestGreeterClient>("contoso", options =>
            {
                options.Address = new Uri("http://contoso");
            })
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));
            services
            .AddGrpcClient <TestGreeterClient>("adventureworks", options =>
            {
                options.Address = new Uri("http://adventureworks");
            })
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var provider = services.BuildServiceProvider(validateScopes: true);

            // Act
            var clientFactory = provider.GetRequiredService <GrpcClientFactory>();

            var contosoClient        = clientFactory.CreateClient <TestGreeterClient>("contoso");
            var adventureworksClient = clientFactory.CreateClient <TestGreeterClient>("adventureworks");

            // Assert
            Assert.AreEqual("http://contoso", contosoClient.CallInvoker.Channel.Address.OriginalString);
            Assert.AreEqual("http://adventureworks", adventureworksClient.CallInvoker.Channel.Address.OriginalString);
        }
コード例 #6
0
        public void AddGrpcClient_AddSameClientTwice_MergeConfiguration()
        {
            // Arrange
            var services = new ServiceCollection();

            services
            .AddGrpcClient <Greeter.GreeterClient>(options =>
            {
                options.Address = new Uri("http://contoso");
            })
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));
            services
            .AddGrpcClient <Greeter.GreeterClient>(options =>
            {
                options.Interceptors.Add(new CallbackInterceptor(o => { }));
            })
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            // Act
            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            using (var scope = serviceProvider.CreateScope())
            {
                var optionsMonitor = serviceProvider.GetRequiredService <IOptionsMonitor <GrpcClientFactoryOptions> >();
                var options        = optionsMonitor.Get(nameof(Greeter.GreeterClient));

                // Assert
                Assert.AreEqual("http://contoso", options.Address !.OriginalString);
                Assert.AreEqual(1, options.Interceptors.Count);
            }
        }
コード例 #7
0
        public async Task CreateClient_LoggingSetup_ClientLogsToTestSink()
        {
            // Arrange
            var testSink = new TestSink();

            var services      = new ServiceCollection();
            var clientBuilder = services
                                .AddGrpcClient <TestGreeterClient>("contoso", options =>
            {
                options.Address = new Uri("http://contoso");
            })
                                .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            services.AddLogging(configure => configure.SetMinimumLevel(LogLevel.Trace));
            services.TryAddEnumerable(ServiceDescriptor.Singleton <ILoggerProvider, TestLoggerProvider>(s => new TestLoggerProvider(testSink, true)));

            var provider = services.BuildServiceProvider(validateScopes: true);

            // Act
            var clientFactory = provider.GetRequiredService <GrpcClientFactory>();

            var contosoClient = clientFactory.CreateClient <TestGreeterClient>("contoso");

            var response = await contosoClient.SayHelloAsync(new HelloRequest()).ResponseAsync.DefaultTimeout();

            // Assert
            Assert.AreEqual("http://contoso", contosoClient.CallInvoker.Channel.Address.OriginalString);

            Assert.IsTrue(testSink.Writes.Any(w => w.EventId.Name == "StartingCall"));
        }
コード例 #8
0
        public void CreateClient_MatchingConfigurationBasedOnCustomName_ReturnConfiguration()
        {
            // Arrange
            var address = new Uri("http://localhost");

            var services = new ServiceCollection();

            services.AddOptions();
            services
            .AddGrpcClient <TestGreeterClient>("Custom", o => o.Address = address)
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = new DefaultGrpcClientFactory(
                serviceProvider,
                serviceProvider.GetRequiredService <IHttpClientFactory>());

            // Act
            var client = clientFactory.CreateClient <TestGreeterClient>("Custom");

            // Assert
            Assert.IsNotNull(client);
            Assert.AreEqual(address, client.CallInvoker.Channel.Address);
        }
コード例 #9
0
        public void CreateClient_MatchingConfigurationBasedOnTypeName_ReturnConfiguration()
        {
            // Arrange
            var baseAddress = new Uri("http://localhost");

            var services = new ServiceCollection();

            services.AddOptions();
            services
            .AddGrpcClient <TestGreeterClient>(o => o.BaseAddress = baseAddress)
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider();

            var clientFactory = new DefaultGrpcClientFactory(
                serviceProvider,
                serviceProvider.GetRequiredService <IHttpClientFactory>(),
                serviceProvider.GetRequiredService <IOptionsMonitor <GrpcClientFactoryOptions> >());

            // Act
            var client = clientFactory.CreateClient <TestGreeterClient>(nameof(TestGreeterClient));

            // Assert
            Assert.IsNotNull(client);
            Assert.AreEqual(baseAddress, client.CallInvoker.BaseAddress);
        }
コード例 #10
0
        public async Task CreateClient_MultipleConfiguration_ConfigurationAppliedPerClient()
        {
            // Arrange
            var testSink     = new TestSink();
            var testProvider = new TestLoggerProvider(testSink);

            var baseAddress = new Uri("http://localhost");

            var services = new ServiceCollection();

            services.AddLogging(o => o.AddProvider(testProvider).SetMinimumLevel(LogLevel.Debug));
            services.AddOptions();
            services.AddSingleton(CreateHttpContextAccessor(null));
            services
            .AddGrpcClient <Greeter.GreeterClient>(o =>
            {
                o.Address = baseAddress;
            })
            .EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true)
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));
            services
            .AddGrpcClient <SecondGreeter.SecondGreeterClient>(o =>
            {
                o.Address = baseAddress;
            })
            .EnableCallContextPropagation()
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = CreateGrpcClientFactory(serviceProvider);
            var client1       = clientFactory.CreateClient <Greeter.GreeterClient>(nameof(Greeter.GreeterClient));
            var client2       = clientFactory.CreateClient <SecondGreeter.SecondGreeterClient>(nameof(SecondGreeter.SecondGreeterClient));

            // Act 1
            await client1.SayHelloAsync(new HelloRequest(), new CallOptions()).ResponseAsync.DefaultTimeout();

            // Assert 1
            var log = testSink.Writes.Single(w => w.EventId.Name == "PropagateServerCallContextFailure");

            Assert.AreEqual("Unable to propagate server context values to the call. Can't find the current HttpContext.", log.Message);

            // Act 2
            var ex = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() => client2.SayHelloAsync(new HelloRequest(), new CallOptions()).ResponseAsync).DefaultTimeout();

            // Assert 2
            Assert.AreEqual("Unable to propagate server context values to the call. Can't find the current HttpContext.", ex.Message);
        }
コード例 #11
0
        public void CreateClient_Default_DefaultInvokerSet()
        {
            // Arrange
            var services = new ServiceCollection();

            services
            .AddGrpcClient <TestGreeterClient>(o => o.Address = new Uri("http://localhost"))
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = CreateGrpcClientFactory(serviceProvider);

            // Act
            var client = clientFactory.CreateClient <TestGreeterClient>(nameof(TestGreeterClient));

            // Assert
            Assert.IsInstanceOf(typeof(HttpMessageInvoker), client.CallInvoker.Channel.HttpInvoker);
        }
コード例 #12
0
        public void CreateClient_NoMatchingConfiguration_ThrowError()
        {
            // Arrange
            var services = new ServiceCollection();

            services.AddOptions();
            services
            .AddGrpcClient <TestGreeterClient>()
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var clientFactory = CreateGrpcClientFactory(serviceProvider);

            // Act
            var ex = Assert.Throws <InvalidOperationException>(() => clientFactory.CreateClient <Greeter.GreeterClient>("Test")) !;

            // Assert
            Assert.AreEqual("No gRPC client configured with name 'Test'.", ex.Message);
        }
コード例 #13
0
        public void AddGrpcClient_ConfigureOptions_OptionsSet()
        {
            // Arrange
            var baseAddress = new Uri("http://localhost");

            ServiceCollection services = new ServiceCollection();

            services
            .AddGrpcClient <Greeter.GreeterClient>(o =>
            {
                o.BaseAddress = baseAddress;
            })
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider();

            // Act
            var optionsMonitor = serviceProvider.GetRequiredService <IOptionsMonitor <GrpcClientFactoryOptions> >();
            var options        = optionsMonitor.Get(nameof(Greeter.GreeterClient));

            // Assert
            Assert.AreEqual(baseAddress, options.BaseAddress);
        }
コード例 #14
0
        public void AddGrpcClient_AddsClientBaseClient_Succeeds()
        {
            // Arrange
            var baseAddress = new Uri("http://localhost");

            var services = new ServiceCollection();

            services
            .AddGrpcClient <Greeter.GreeterClient>(o =>
            {
                o.Address = baseAddress;
            })
            .ConfigurePrimaryHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            // Act
            var serviceProvider = services.BuildServiceProvider(validateScopes: true);

            // Assert
            using (var scope = serviceProvider.CreateScope())
            {
                Assert.IsNotNull(serviceProvider.GetRequiredService <Greeter.GreeterClient>());
            }
        }
コード例 #15
0
        public void CreateClient_NoMatchingConfiguration_ThrowError()
        {
            // Arrange
            var services = new ServiceCollection();

            services.AddOptions();
            services
            .AddGrpcClient <TestGreeterClient>(o => { })
            .AddHttpMessageHandler(() => ClientTestHelpers.CreateTestMessageHandler(new HelloReply()));

            var serviceProvider = services.BuildServiceProvider();

            var clientFactory = new DefaultGrpcClientFactory(
                serviceProvider,
                serviceProvider.GetRequiredService <IHttpClientFactory>(),
                serviceProvider.GetRequiredService <IOptionsMonitor <GrpcClientFactoryOptions> >());

            // Act
            var ex = Assert.Throws <InvalidOperationException>(() => clientFactory.CreateClient <Greet.Greeter.GreeterClient>("Test"));

            // Assert
            Assert.AreEqual("No gRPC client configured with name 'Test'.", ex.Message);
        }