Imported Upstream version 1.22.0
[platform/upstream/grpc.git] / src / objective-c / GRPCClient / GRPCCall.h
1 /*
2  *
3  * Copyright 2015 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  */
18
19 /**
20  * The gRPC protocol is an RPC protocol on top of HTTP2.
21  *
22  * While the most common type of RPC receives only one request message and returns only one response
23  * message, the protocol also supports RPCs that return multiple individual messages in a streaming
24  * fashion, RPCs that accept a stream of request messages, or RPCs with both streaming requests and
25  * responses.
26  *
27  * Conceptually, each gRPC call consists of a bidirectional stream of binary messages, with RPCs of
28  * the "non-streaming type" sending only one message in the corresponding direction (the protocol
29  * doesn't make any distinction).
30  *
31  * Each RPC uses a different HTTP2 stream, and thus multiple simultaneous RPCs can be multiplexed
32  * transparently on the same TCP connection.
33  */
34
35 #import <Foundation/Foundation.h>
36 #import <RxLibrary/GRXWriter.h>
37
38 #include <AvailabilityMacros.h>
39
40 #include "GRPCCallOptions.h"
41
42 NS_ASSUME_NONNULL_BEGIN
43
44 #pragma mark gRPC errors
45
46 /** Domain of NSError objects produced by gRPC. */
47 extern NSString *const kGRPCErrorDomain;
48
49 /**
50  * gRPC error codes.
51  * Note that a few of these are never produced by the gRPC libraries, but are of general utility for
52  * server applications to produce.
53  */
54 typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
55   /** The operation was cancelled (typically by the caller). */
56   GRPCErrorCodeCancelled = 1,
57
58   /**
59    * Unknown error. Errors raised by APIs that do not return enough error information may be
60    * converted to this error.
61    */
62   GRPCErrorCodeUnknown = 2,
63
64   /**
65    * The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
66    * INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
67    * server (e.g., a malformed file name).
68    */
69   GRPCErrorCodeInvalidArgument = 3,
70
71   /**
72    * Deadline expired before operation could complete. For operations that change the state of the
73    * server, this error may be returned even if the operation has completed successfully. For
74    * example, a successful response from the server could have been delayed long enough for the
75    * deadline to expire.
76    */
77   GRPCErrorCodeDeadlineExceeded = 4,
78
79   /** Some requested entity (e.g., file or directory) was not found. */
80   GRPCErrorCodeNotFound = 5,
81
82   /** Some entity that we attempted to create (e.g., file or directory) already exists. */
83   GRPCErrorCodeAlreadyExists = 6,
84
85   /**
86    * The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
87    * used for rejections caused by exhausting some resource (RESOURCE_EXHAUSTED is used instead for
88    * those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
89    * (UNAUTHENTICATED is used instead for those errors).
90    */
91   GRPCErrorCodePermissionDenied = 7,
92
93   /**
94    * The request does not have valid authentication credentials for the operation (e.g. the caller's
95    * identity can't be verified).
96    */
97   GRPCErrorCodeUnauthenticated = 16,
98
99   /** Some resource has been exhausted, perhaps a per-user quota. */
100   GRPCErrorCodeResourceExhausted = 8,
101
102   /**
103    * The RPC was rejected because the server is not in a state required for the procedure's
104    * execution. For example, a directory to be deleted may be non-empty, etc.
105    * The client should not retry until the server state has been explicitly fixed (e.g. by
106    * performing another RPC). The details depend on the service being called, and should be found in
107    * the NSError's userInfo.
108    */
109   GRPCErrorCodeFailedPrecondition = 9,
110
111   /**
112    * The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
113    * transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
114    * modify-write sequence).
115    */
116   GRPCErrorCodeAborted = 10,
117
118   /**
119    * The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
120    * Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state
121    * changes. For example, an RPC to get elements of a list will generate INVALID_ARGUMENT if asked
122    * to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
123    * the element at an index past the current size of the list.
124    */
125   GRPCErrorCodeOutOfRange = 11,
126
127   /** The procedure is not implemented or not supported/enabled in this server. */
128   GRPCErrorCodeUnimplemented = 12,
129
130   /**
131    * Internal error. Means some invariant expected by the server application or the gRPC library has
132    * been broken.
133    */
134   GRPCErrorCodeInternal = 13,
135
136   /**
137    * The server is currently unavailable. This is most likely a transient condition and may be
138    * corrected by retrying with a backoff. Note that it is not always safe to retry
139    * non-idempotent operations.
140    */
141   GRPCErrorCodeUnavailable = 14,
142
143   /** Unrecoverable data loss or corruption. */
144   GRPCErrorCodeDataLoss = 15,
145 };
146
147 /**
148  * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
149  * the server.
150  */
151 extern NSString *const kGRPCHeadersKey;
152 extern NSString *const kGRPCTrailersKey;
153
154 /** An object can implement this protocol to receive responses from server from a call. */
155 @protocol GRPCResponseHandler<NSObject>
156
157 @required
158
159 /**
160  * All the responses must be issued to a user-provided dispatch queue. This property specifies the
161  * dispatch queue to be used for issuing the notifications.
162  */
163 @property(atomic, readonly) dispatch_queue_t dispatchQueue;
164
165 @optional
166
167 /**
168  * Issued when initial metadata is received from the server.
169  */
170 - (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata;
171
172 /**
173  * This method is deprecated and does not work with interceptors. To use GRPCCall2 interface with
174  * interceptor, implement didReceiveData: instead. To implement an interceptor, please leave this
175  * method unimplemented and implement didReceiveData: method instead. If this method and
176  * didReceiveRawMessage are implemented at the same time, implementation of this method will be
177  * ignored.
178  *
179  * Issued when a message is received from the server. The message is the raw data received from the
180  * server, with decompression and without proto deserialization.
181  */
182 - (void)didReceiveRawMessage:(nullable NSData *)message;
183
184 /**
185  * Issued when a decompressed message is received from the server. The message is decompressed, and
186  * deserialized if a marshaller is provided to the call (marshaller is work in progress).
187  */
188 - (void)didReceiveData:(id)data;
189
190 /**
191  * Issued when a call finished. If the call finished successfully, \a error is nil and \a
192  * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error
193  * is non-nil and contains the corresponding error information, including gRPC error codes and
194  * error descriptions.
195  */
196 - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata
197                                error:(nullable NSError *)error;
198
199 /**
200  * Issued when flow control is enabled for the call and a message written with writeData: method of
201  * GRPCCall2 is passed to gRPC core with SEND_MESSAGE operation.
202  */
203 - (void)didWriteData;
204
205 @end
206
207 /**
208  * Call related parameters. These parameters are automatically specified by Protobuf. If directly
209  * using the \a GRPCCall2 class, users should specify these parameters manually.
210  */
211 @interface GRPCRequestOptions : NSObject<NSCopying>
212
213 - (instancetype)init NS_UNAVAILABLE;
214
215 + (instancetype) new NS_UNAVAILABLE;
216
217 /** Initialize with all properties. */
218 - (instancetype)initWithHost:(NSString *)host
219                         path:(NSString *)path
220                       safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER;
221
222 /** The host serving the RPC service. */
223 @property(copy, readonly) NSString *host;
224 /** The path to the RPC call. */
225 @property(copy, readonly) NSString *path;
226 /**
227  * Specify whether the call is idempotent or cachable. gRPC may select different HTTP verbs for the
228  * call based on this information. The default verb used by gRPC is POST.
229  */
230 @property(readonly) GRPCCallSafety safety;
231
232 @end
233
234 #pragma mark GRPCCall
235
236 /**
237  * A \a GRPCCall2 object represents an RPC call.
238  */
239 @interface GRPCCall2 : NSObject
240
241 - (instancetype)init NS_UNAVAILABLE;
242
243 + (instancetype) new NS_UNAVAILABLE;
244
245 /**
246  * Designated initializer for a call.
247  * \param requestOptions Protobuf generated parameters for the call.
248  * \param responseHandler The object to which responses should be issued.
249  * \param callOptions Options for the call.
250  */
251 - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
252                        responseHandler:(id<GRPCResponseHandler>)responseHandler
253                            callOptions:(nullable GRPCCallOptions *)callOptions
254     NS_DESIGNATED_INITIALIZER;
255 /**
256  * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for
257  * the default options).
258  */
259 - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
260                        responseHandler:(id<GRPCResponseHandler>)responseHandler;
261
262 /**
263  * Starts the call. This function must only be called once for each instance.
264  */
265 - (void)start;
266
267 /**
268  * Cancel the request of this call at best effort. It attempts to notify the server that the RPC
269  * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code
270  * CANCELED if no other error code has already been issued.
271  */
272 - (void)cancel;
273
274 /**
275  * Send a message to the server. The data is subject to marshaller serialization and compression
276  * (marshaller is work in progress).
277  */
278 - (void)writeData:(id)data;
279
280 /**
281  * Finish the RPC request and half-close the call. The server may still send messages and/or
282  * trailers to the client. The method must only be called once and after start is called.
283  */
284 - (void)finish;
285
286 /**
287  * Tell gRPC to receive the next N gRPC message from gRPC core.
288  *
289  * This method should only be used when flow control is enabled. When flow control is not enabled,
290  * this method is a no-op.
291  */
292 - (void)receiveNextMessages:(NSUInteger)numberOfMessages;
293
294 /**
295  * Get a copy of the original call options.
296  */
297 @property(readonly, copy) GRPCCallOptions *callOptions;
298
299 /** Get a copy of the original request options. */
300 @property(readonly, copy) GRPCRequestOptions *requestOptions;
301
302 @end
303
304 NS_ASSUME_NONNULL_END
305
306 #pragma clang diagnostic push
307 #pragma clang diagnostic ignored "-Wnullability-completeness"
308
309 /**
310  * This interface is deprecated. Please use \a GRPCcall2.
311  *
312  * Represents a single gRPC remote call.
313  */
314 @interface GRPCCall : GRXWriter
315
316 - (instancetype)init NS_UNAVAILABLE;
317
318 /**
319  * The container of the request headers of an RPC conforms to this protocol, which is a subset of
320  * NSMutableDictionary's interface. It will become a NSMutableDictionary later on.
321  * The keys of this container are the header names, which per the HTTP standard are case-
322  * insensitive. They are stored in lowercase (which is how HTTP/2 mandates them on the wire), and
323  * can only consist of ASCII characters.
324  * A header value is a NSString object (with only ASCII characters), unless the header name has the
325  * suffix "-bin", in which case the value has to be a NSData object.
326  */
327 /**
328  * These HTTP headers will be passed to the server as part of this call. Each HTTP header is a
329  * name-value pair with string names and either string or binary values.
330  *
331  * The passed dictionary has to use NSString keys, corresponding to the header names. The value
332  * associated to each can be a NSString object or a NSData object. E.g.:
333  *
334  * call.requestHeaders = @{@"authorization": @"Bearer ..."};
335  *
336  * call.requestHeaders[@"my-header-bin"] = someData;
337  *
338  * After the call is started, trying to modify this property is an error.
339  *
340  * The property is initialized to an empty NSMutableDictionary.
341  */
342 @property(atomic, readonly) NSMutableDictionary *requestHeaders;
343
344 /**
345  * This dictionary is populated with the HTTP headers received from the server. This happens before
346  * any response message is received from the server. It has the same structure as the request
347  * headers dictionary: Keys are NSString header names; names ending with the suffix "-bin" have a
348  * NSData value; the others have a NSString value.
349  *
350  * The value of this property is nil until all response headers are received, and will change before
351  * any of -writeValue: or -writesFinishedWithError: are sent to the writeable.
352  */
353 @property(atomic, readonly) NSDictionary *responseHeaders;
354
355 /**
356  * Same as responseHeaders, but populated with the HTTP trailers received from the server before the
357  * call finishes.
358  *
359  * The value of this property is nil until all response trailers are received, and will change
360  * before -writesFinishedWithError: is sent to the writeable.
361  */
362 @property(atomic, readonly) NSDictionary *responseTrailers;
363
364 /**
365  * The request writer has to write NSData objects into the provided Writeable. The server will
366  * receive each of those separately and in order as distinct messages.
367  * A gRPC call might not complete until the request writer finishes. On the other hand, the request
368  * finishing doesn't necessarily make the call to finish, as the server might continue sending
369  * messages to the response side of the call indefinitely (depending on the semantics of the
370  * specific remote method called).
371  * To finish a call right away, invoke cancel.
372  * host parameter should not contain the scheme (http:// or https://), only the name or IP addr
373  * and the port number, for example @"localhost:5050".
374  */
375 - (instancetype)initWithHost:(NSString *)host
376                         path:(NSString *)path
377               requestsWriter:(GRXWriter *)requestWriter;
378
379 /**
380  * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and
381  * finishes the response side of the call with an error of code CANCELED.
382  */
383 - (void)cancel;
384
385 /**
386  * The following methods are deprecated.
387  */
388 + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path;
389 @property(atomic, copy, readwrite) NSString *serverName;
390 @property NSTimeInterval timeout;
391 - (void)setResponseDispatchQueue:(dispatch_queue_t)queue;
392
393 @end
394
395 #pragma mark Backwards compatibiity
396
397 /** This protocol is kept for backwards compatibility with existing code. */
398 DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.")
399 @protocol GRPCRequestHeaders<NSObject>
400 @property(nonatomic, readonly) NSUInteger count;
401
402 - (id)objectForKeyedSubscript:(id)key;
403 - (void)setObject:(id)obj forKeyedSubscript:(id)key;
404
405 - (void)removeAllObjects;
406 - (void)removeObjectForKey:(id)key;
407 @end
408
409 #pragma clang diagnostic push
410 #pragma clang diagnostic ignored "-Wdeprecated"
411 /** This is only needed for backwards-compatibility. */
412 @interface NSMutableDictionary (GRPCRequestHeaders)<GRPCRequestHeaders>
413 @end
414 #pragma clang diagnostic pop
415 #pragma clang diagnostic pop