diff options
author | Mehrdad Afshari <mmx@google.com> | 2018-02-11 23:29:51 -0800 |
---|---|---|
committer | Mehrdad Afshari <mmx@google.com> | 2018-02-21 18:30:19 -0800 |
commit | 2354a1d76eecef541083f674a6c21592556ac54a (patch) | |
tree | 9ce09446db6864e7281f0e6f1dbdbb8469348b10 | |
parent | 4bc49f5c4b9b22c2d90e1933d3223799755c1e81 (diff) |
Add Intercept(metadata=>metadata) helper function
3 files changed, 60 insertions, 20 deletions
diff --git a/src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs b/src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs index 91c7d54181..880e4d2b19 100644 --- a/src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs +++ b/src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs @@ -32,38 +32,27 @@ namespace Grpc.Core.Interceptors.Tests { public class ClientInterceptorTest { - private class AddHeaderClientInterceptor : GenericInterceptor - { - readonly Metadata.Entry header; - public AddHeaderClientInterceptor(string key, string value) - { - this.header = new Metadata.Entry(key, value); - } - protected override ClientCallArbitrator<TRequest, TResponse> InterceptCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, bool clientStreaming, bool serverStreaming, TRequest request) - { - context.Options.Headers.Add(this.header); - return new ClientCallArbitrator<TRequest, TResponse> { Context = context }; - } - - public Metadata.Entry Header => this.header; - } - const string Host = "127.0.0.1"; [Test] public void AddRequestHeaderInClientInterceptor() { + const string HeaderKey = "x-client-interceptor"; + const string HeaderValue = "hello-world"; var helper = new MockServiceHelper(Host); - var interceptor = new AddHeaderClientInterceptor("x-client-interceptor", "hello world"); helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) => { - var interceptorHeader = context.RequestHeaders.Last(m => (m.Key == interceptor.Header.Key)).Value; - Assert.AreEqual(interceptorHeader, interceptor.Header.Value); + var interceptorHeader = context.RequestHeaders.Last(m => (m.Key == HeaderKey)).Value; + Assert.AreEqual(interceptorHeader, HeaderValue); return Task.FromResult("PASS"); }); var server = helper.GetServer(); server.Start(); - var callInvoker = helper.GetChannel().Intercept(interceptor); + var callInvoker = helper.GetChannel().Intercept(metadata => + { + metadata.Add(new Metadata.Entry(HeaderKey, HeaderValue)); + return metadata; + }); Assert.AreEqual("PASS", callInvoker.BlockingUnaryCall(new Method<string, string>(MethodType.Unary, MockServiceHelper.ServiceName, "Unary", Marshallers.StringMarshaller, Marshallers.StringMarshaller), Host, new CallOptions().WithHeaders(new Metadata()), "")); } } diff --git a/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs b/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs index 26e9f8802d..9cec66282f 100644 --- a/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs +++ b/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs @@ -101,6 +101,42 @@ namespace Grpc.Core.Interceptors } } + private class MetadataInterceptor : GenericInterceptor + { + readonly Func<Metadata, Metadata> interceptor; + + /// <summary> + /// Creates a new instance of MetadataInterceptor given the specified interceptor function. + /// </summary> + public MetadataInterceptor(Func<Metadata, Metadata> interceptor) + { + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, "interceptor"); + } + + protected override ClientCallArbitrator<TRequest, TResponse> InterceptCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, bool clientStreaming, bool serverStreaming, TRequest request) + { + return new ClientCallArbitrator<TRequest, TResponse> + { + Context = new ClientInterceptorContext<TRequest, TResponse>(context.Method, context.Host, context.Options.WithHeaders(interceptor(context.Options.Headers))) + }; + } + } + + /// <summary> + /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts + /// the invoker with the given interceptor. + /// </summary> + /// <param name="invoker">The underlying invoker to intercept.</param> + /// <param name="interceptor"> + /// An interceptor delegate that takes the request metadata to be sent with an outgoing call + /// and returns a <see cref="Grpc.Core.Metadata" /> instance that will replace the existing + /// invocation metadata. + /// </param> + public static CallInvoker Intercept(this CallInvoker invoker, Func<Metadata, Metadata> interceptor) + { + return new InterceptingCallInvoker(invoker, new MetadataInterceptor(interceptor)); + } + /// <summary> /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts /// the invoker with the given interceptor. diff --git a/src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs index 1a54b93dae..25d1724803 100644 --- a/src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs +++ b/src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs @@ -50,5 +50,20 @@ namespace Grpc.Core.Interceptors { return new DefaultCallInvoker(channel).Intercept(interceptors); } + + /// <summary> + /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts + /// the invoker with the given interceptor. + /// </summary> + /// <param name="channel">The channel to intercept.</param> + /// <param name="interceptor"> + /// An interceptor delegate that takes the request metadata to be sent with an outgoing call + /// and returns a <see cref="Grpc.Core.Metadata" /> instance that will replace the existing + /// invocation metadata. + /// </param> + public static CallInvoker Intercept(this Channel channel, Func<Metadata, Metadata> interceptor) + { + return new DefaultCallInvoker(channel).Intercept(interceptor); + } } } |