1 #region Copyright notice and license
3 // Copyright 2018 gRPC authors.
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
20 using System.Reflection;
21 using System.Threading.Tasks;
22 using Grpc.Core.Internal;
24 namespace Grpc.Core.Interceptors
27 /// Serves as the base class for gRPC interceptors.
29 public abstract class Interceptor
32 /// Represents a continuation for intercepting simple blocking invocations.
33 /// A delegate of this type is passed to the BlockingUnaryCall method
34 /// when an outgoing invocation is being intercepted and calling the
35 /// delegate will invoke the next interceptor in the chain, or the underlying
36 /// call invoker if called from the last interceptor. The interceptor is
37 /// allowed to call it zero, one, or multiple times, passing it the appropriate
38 /// context and request values as it sees fit.
40 /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
41 /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
42 /// <param name="request">The request value to continue the invocation with.</param>
43 /// <param name="context">
44 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
45 /// instance to pass to the next step in the invocation process.
48 /// The response value of the invocation to return to the caller.
49 /// The interceptor can choose to return the return value of the
50 /// continuation delegate or an arbitrary value as it sees fit.
52 public delegate TResponse BlockingUnaryCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
53 where TRequest : class
54 where TResponse : class;
57 /// Represents a continuation for intercepting simple asynchronous invocations.
58 /// A delegate of this type is passed to the AsyncUnaryCall method
59 /// when an outgoing invocation is being intercepted and calling the
60 /// delegate will invoke the next interceptor in the chain, or the underlying
61 /// call invoker if called from the last interceptor. The interceptor is
62 /// allowed to call it zero, one, or multiple times, passing it the appropriate
63 /// request value and context as it sees fit.
65 /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
66 /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
67 /// <param name="request">The request value to continue the invocation with.</param>
68 /// <param name="context">
69 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
70 /// instance to pass to the next step in the invocation process.
73 /// An instance of <see cref="Grpc.Core.AsyncUnaryCall{TResponse}" />
74 /// representing an asynchronous invocation of a unary RPC.
75 /// The interceptor can choose to return the same object returned from
76 /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
78 public delegate AsyncUnaryCall<TResponse> AsyncUnaryCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
79 where TRequest : class
80 where TResponse : class;
83 /// Represents a continuation for intercepting asynchronous server-streaming invocations.
84 /// A delegate of this type is passed to the AsyncServerStreamingCall method
85 /// when an outgoing invocation is being intercepted and calling the
86 /// delegate will invoke the next interceptor in the chain, or the underlying
87 /// call invoker if called from the last interceptor. The interceptor is
88 /// allowed to call it zero, one, or multiple times, passing it the appropriate
89 /// request value and context as it sees fit.
91 /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
92 /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
93 /// <param name="request">The request value to continue the invocation with.</param>
94 /// <param name="context">
95 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
96 /// instance to pass to the next step in the invocation process.
99 /// An instance of <see cref="Grpc.Core.AsyncServerStreamingCall{TResponse}" />
100 /// representing an asynchronous invocation of a server-streaming RPC.
101 /// The interceptor can choose to return the same object returned from
102 /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
104 public delegate AsyncServerStreamingCall<TResponse> AsyncServerStreamingCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
105 where TRequest : class
106 where TResponse : class;
109 /// Represents a continuation for intercepting asynchronous client-streaming invocations.
110 /// A delegate of this type is passed to the AsyncClientStreamingCall method
111 /// when an outgoing invocation is being intercepted and calling the
112 /// delegate will invoke the next interceptor in the chain, or the underlying
113 /// call invoker if called from the last interceptor. The interceptor is
114 /// allowed to call it zero, one, or multiple times, passing it the appropriate
115 /// request value and context as it sees fit.
117 /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
118 /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
119 /// <param name="context">
120 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
121 /// instance to pass to the next step in the invocation process.
124 /// An instance of <see cref="Grpc.Core.AsyncClientStreamingCall{TRequest, TResponse}" />
125 /// representing an asynchronous invocation of a client-streaming RPC.
126 /// The interceptor can choose to return the same object returned from
127 /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
129 public delegate AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCallContinuation<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
130 where TRequest : class
131 where TResponse : class;
134 /// Represents a continuation for intercepting asynchronous duplex invocations.
135 /// A delegate of this type is passed to the AsyncDuplexStreamingCall method
136 /// when an outgoing invocation is being intercepted and calling the
137 /// delegate will invoke the next interceptor in the chain, or the underlying
138 /// call invoker if called from the last interceptor. The interceptor is
139 /// allowed to call it zero, one, or multiple times, passing it the appropriate
140 /// request value and context as it sees fit.
142 /// <param name="context">
143 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
144 /// instance to pass to the next step in the invocation process.
147 /// An instance of <see cref="Grpc.Core.AsyncDuplexStreamingCall{TRequest, TResponse}" />
148 /// representing an asynchronous invocation of a duplex-streaming RPC.
149 /// The interceptor can choose to return the same object returned from
150 /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
152 public delegate AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCallContinuation<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
153 where TRequest : class
154 where TResponse : class;
157 /// Intercepts a blocking invocation of a simple remote call.
159 /// <param name="request">The request message of the invocation.</param>
160 /// <param name="context">
161 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
162 /// associated with the current invocation.
164 /// <param name="continuation">
165 /// The callback that continues the invocation process.
166 /// This can be invoked zero or more times by the interceptor.
167 /// The interceptor can invoke the continuation passing the given
168 /// request value and context arguments, or substitute them as it sees fit.
171 /// The response message of the current invocation.
172 /// The interceptor can simply return the return value of the
173 /// continuation delegate passed to it intact, or an arbitrary
174 /// value as it sees fit.
176 public virtual TResponse BlockingUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, BlockingUnaryCallContinuation<TRequest, TResponse> continuation)
177 where TRequest : class
178 where TResponse : class
180 return continuation(request, context);
184 /// Intercepts an asynchronous invocation of a simple remote call.
186 /// <param name="request">The request message of the invocation.</param>
187 /// <param name="context">
188 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
189 /// associated with the current invocation.
191 /// <param name="continuation">
192 /// The callback that continues the invocation process.
193 /// This can be invoked zero or more times by the interceptor.
194 /// The interceptor can invoke the continuation passing the given
195 /// request value and context arguments, or substitute them as it sees fit.
198 /// An instance of <see cref="Grpc.Core.AsyncUnaryCall{TResponse}" />
199 /// representing an asynchronous unary invocation.
200 /// The interceptor can simply return the return value of the
201 /// continuation delegate passed to it intact, or construct its
202 /// own substitute as it sees fit.
204 public virtual AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
205 where TRequest : class
206 where TResponse : class
208 return continuation(request, context);
212 /// Intercepts an asynchronous invocation of a streaming remote call.
214 /// <param name="request">The request message of the invocation.</param>
215 /// <param name="context">
216 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
217 /// associated with the current invocation.
219 /// <param name="continuation">
220 /// The callback that continues the invocation process.
221 /// This can be invoked zero or more times by the interceptor.
222 /// The interceptor can invoke the continuation passing the given
223 /// request value and context arguments, or substitute them as it sees fit.
226 /// An instance of <see cref="Grpc.Core.AsyncServerStreamingCall{TResponse}" />
227 /// representing an asynchronous server-streaming invocation.
228 /// The interceptor can simply return the return value of the
229 /// continuation delegate passed to it intact, or construct its
230 /// own substitute as it sees fit.
232 public virtual AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncServerStreamingCallContinuation<TRequest, TResponse> continuation)
233 where TRequest : class
234 where TResponse : class
236 return continuation(request, context);
240 /// Intercepts an asynchronous invocation of a client streaming call.
242 /// <param name="context">
243 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
244 /// associated with the current invocation.
246 /// <param name="continuation">
247 /// The callback that continues the invocation process.
248 /// This can be invoked zero or more times by the interceptor.
249 /// The interceptor can invoke the continuation passing the given
250 /// context argument, or substitute as it sees fit.
253 /// An instance of <see cref="Grpc.Core.AsyncClientStreamingCall{TRequest, TResponse}" />
254 /// representing an asynchronous client-streaming invocation.
255 /// The interceptor can simply return the return value of the
256 /// continuation delegate passed to it intact, or construct its
257 /// own substitute as it sees fit.
259 public virtual AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)
260 where TRequest : class
261 where TResponse : class
263 return continuation(context);
267 /// Intercepts an asynchronous invocation of a duplex streaming call.
269 /// <param name="context">
270 /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
271 /// associated with the current invocation.
273 /// <param name="continuation">
274 /// The callback that continues the invocation process.
275 /// This can be invoked zero or more times by the interceptor.
276 /// The interceptor can invoke the continuation passing the given
277 /// context argument, or substitute as it sees fit.
280 /// An instance of <see cref="Grpc.Core.AsyncDuplexStreamingCall{TRequest, TResponse}" />
281 /// representing an asynchronous duplex-streaming invocation.
282 /// The interceptor can simply return the return value of the
283 /// continuation delegate passed to it intact, or construct its
284 /// own substitute as it sees fit.
286 public virtual AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncDuplexStreamingCallContinuation<TRequest, TResponse> continuation)
287 where TRequest : class
288 where TResponse : class
290 return continuation(context);
294 /// Server-side handler for intercepting and incoming unary call.
296 /// <typeparam name="TRequest">Request message type for this method.</typeparam>
297 /// <typeparam name="TResponse">Response message type for this method.</typeparam>
298 /// <param name="request">The request value of the incoming invocation.</param>
299 /// <param name="context">
300 /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
301 /// the context of the invocation.
303 /// <param name="continuation">
304 /// A delegate that asynchronously proceeds with the invocation, calling
305 /// the next interceptor in the chain, or the service request handler,
306 /// in case of the last interceptor and return the response value of
307 /// the RPC. The interceptor can choose to call it zero or more times
308 /// at its discretion.
311 /// A future representing the response value of the RPC. The interceptor
312 /// can simply return the return value from the continuation intact,
313 /// or an arbitrary response value as it sees fit.
315 public virtual Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
316 where TRequest : class
317 where TResponse : class
319 return continuation(request, context);
323 /// Server-side handler for intercepting client streaming call.
325 /// <typeparam name="TRequest">Request message type for this method.</typeparam>
326 /// <typeparam name="TResponse">Response message type for this method.</typeparam>
327 /// <param name="requestStream">The request stream of the incoming invocation.</param>
328 /// <param name="context">
329 /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
330 /// the context of the invocation.
332 /// <param name="continuation">
333 /// A delegate that asynchronously proceeds with the invocation, calling
334 /// the next interceptor in the chain, or the service request handler,
335 /// in case of the last interceptor and return the response value of
336 /// the RPC. The interceptor can choose to call it zero or more times
337 /// at its discretion.
340 /// A future representing the response value of the RPC. The interceptor
341 /// can simply return the return value from the continuation intact,
342 /// or an arbitrary response value as it sees fit. The interceptor has
343 /// the ability to wrap or substitute the request stream when calling
344 /// the continuation.
346 public virtual Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod<TRequest, TResponse> continuation)
347 where TRequest : class
348 where TResponse : class
350 return continuation(requestStream, context);
354 /// Server-side handler for intercepting server streaming call.
356 /// <typeparam name="TRequest">Request message type for this method.</typeparam>
357 /// <typeparam name="TResponse">Response message type for this method.</typeparam>
358 /// <param name="request">The request value of the incoming invocation.</param>
359 /// <param name="responseStream">The response stream of the incoming invocation.</param>
360 /// <param name="context">
361 /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
362 /// the context of the invocation.
364 /// <param name="continuation">
365 /// A delegate that asynchronously proceeds with the invocation, calling
366 /// the next interceptor in the chain, or the service request handler,
367 /// in case of the last interceptor and the interceptor can choose to
368 /// call it zero or more times at its discretion. The interceptor has
369 /// the ability to wrap or substitute the request value and the response stream
370 /// when calling the continuation.
372 public virtual Task ServerStreamingServerHandler<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, ServerStreamingServerMethod<TRequest, TResponse> continuation)
373 where TRequest : class
374 where TResponse : class
376 return continuation(request, responseStream, context);
380 /// Server-side handler for intercepting bidirectional streaming calls.
382 /// <typeparam name="TRequest">Request message type for this method.</typeparam>
383 /// <typeparam name="TResponse">Response message type for this method.</typeparam>
384 /// <param name="requestStream">The request stream of the incoming invocation.</param>
385 /// <param name="responseStream">The response stream of the incoming invocation.</param>
386 /// <param name="context">
387 /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
388 /// the context of the invocation.
390 /// <param name="continuation">
391 /// A delegate that asynchronously proceeds with the invocation, calling
392 /// the next interceptor in the chain, or the service request handler,
393 /// in case of the last interceptor and the interceptor can choose to
394 /// call it zero or more times at its discretion. The interceptor has
395 /// the ability to wrap or substitute the request and response streams
396 /// when calling the continuation.
398 public virtual Task DuplexStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod<TRequest, TResponse> continuation)
399 where TRequest : class
400 where TResponse : class
402 return continuation(requestStream, responseStream, context);