Imported Upstream version 1.20.1
[platform/upstream/grpc.git] / src / csharp / Grpc.Core.Api / Interceptors / Interceptor.cs
1 #region Copyright notice and license
2
3 // Copyright 2018 gRPC authors.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16
17 #endregion
18
19 using System;
20 using System.Reflection;
21 using System.Threading.Tasks;
22 using Grpc.Core.Internal;
23
24 namespace Grpc.Core.Interceptors
25 {
26     /// <summary>
27     /// Serves as the base class for gRPC interceptors.
28     /// </summary>
29     public abstract class Interceptor
30     {
31         /// <summary>
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.
39         /// </summary>
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.
46         /// </param>
47         /// <returns>
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.
51         /// </returns>
52         public delegate TResponse BlockingUnaryCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
53             where TRequest : class
54             where TResponse : class;
55
56         /// <summary>
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.
64         /// </summary>
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.
71         /// </param>
72         /// <returns>
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.
77         /// </returns>
78         public delegate AsyncUnaryCall<TResponse> AsyncUnaryCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
79             where TRequest : class
80             where TResponse : class;
81
82         /// <summary>
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.
90         /// </summary>
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.
97         /// </param>
98         /// <returns>
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.
103         /// </returns>
104         public delegate AsyncServerStreamingCall<TResponse> AsyncServerStreamingCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
105             where TRequest : class
106             where TResponse : class;
107
108         /// <summary>
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.
116         /// </summary>
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.
122         /// </param>
123         /// <returns>
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.
128         /// </returns>
129         public delegate AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCallContinuation<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
130             where TRequest : class
131             where TResponse : class;
132
133         /// <summary>
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.
141         /// </summary>
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.
145         /// </param>
146         /// <returns>
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.
151         /// </returns>
152         public delegate AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCallContinuation<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
153             where TRequest : class
154             where TResponse : class;
155
156         /// <summary>
157         /// Intercepts a blocking invocation of a simple remote call.
158         /// </summary>
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.
163         /// </param>
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.
169         /// </param>
170         /// <returns>
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.
175         /// </returns>
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
179         {
180             return continuation(request, context);
181         }
182
183         /// <summary>
184         /// Intercepts an asynchronous invocation of a simple remote call.
185         /// </summary>
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.
190         /// </param>
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.
196         /// </param>
197         /// <returns>
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.
203         /// </returns>
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
207         {
208             return continuation(request, context);
209         }
210
211         /// <summary>
212         /// Intercepts an asynchronous invocation of a streaming remote call.
213         /// </summary>
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.
218         /// </param>
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.
224         /// </param>
225         /// <returns>
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.
231         /// </returns>
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
235         {
236             return continuation(request, context);
237         }
238
239         /// <summary>
240         /// Intercepts an asynchronous invocation of a client streaming call.
241         /// </summary>
242         /// <param name="context">
243         /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
244         /// associated with the current invocation.
245         /// </param>
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.
251         /// </param>
252         /// <returns>
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.
258         /// </returns>
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
262         {
263             return continuation(context);
264         }
265
266         /// <summary>
267         /// Intercepts an asynchronous invocation of a duplex streaming call.
268         /// </summary>
269         /// <param name="context">
270         /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
271         /// associated with the current invocation.
272         /// </param>
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.
278         /// </param>
279         /// <returns>
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.
285         /// </returns>
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
289         {
290             return continuation(context);
291         }
292
293         /// <summary>
294         /// Server-side handler for intercepting and incoming unary call.
295         /// </summary>
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.
302         /// </param>
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.
309         /// </param>
310         /// <returns>
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.
314         /// </returns>
315         public virtual Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
316             where TRequest : class
317             where TResponse : class
318         {
319             return continuation(request, context);
320         }
321
322         /// <summary>
323         /// Server-side handler for intercepting client streaming call.
324         /// </summary>
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.
331         /// </param>
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.
338         /// </param>
339         /// <returns>
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.
345         /// </returns>
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
349         {
350             return continuation(requestStream, context);
351         }
352
353         /// <summary>
354         /// Server-side handler for intercepting server streaming call.
355         /// </summary>
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.
363         /// </param>
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.
371         /// </param>
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
375         {
376             return continuation(request, responseStream, context);
377         }
378
379         /// <summary>
380         /// Server-side handler for intercepting bidirectional streaming calls.
381         /// </summary>
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.
389         /// </param>
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.
397         /// </param>
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
401         {
402             return continuation(requestStream, responseStream, context);
403         }
404     }
405 }