Home | History | Annotate | Download | only in codegen
      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 /// A ClientContext allows the person implementing a service client to:
     20 ///
     21 /// - Add custom metadata key-value pairs that will propagated to the server
     22 /// side.
     23 /// - Control call settings such as compression and authentication.
     24 /// - Initial and trailing metadata coming from the server.
     25 /// - Get performance metrics (ie, census).
     26 ///
     27 /// Context settings are only relevant to the call they are invoked with, that
     28 /// is to say, they aren't sticky. Some of these settings, such as the
     29 /// compression options, can be made persistent at channel construction time
     30 /// (see \a grpc::CreateCustomChannel).
     31 ///
     32 /// \warning ClientContext instances should \em not be reused across rpcs.
     33 
     34 #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H
     35 #define GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H
     36 
     37 #include <map>
     38 #include <memory>
     39 #include <mutex>
     40 #include <string>
     41 
     42 #include <grpc/impl/codegen/compression_types.h>
     43 #include <grpc/impl/codegen/propagation_bits.h>
     44 #include <grpcpp/impl/codegen/config.h>
     45 #include <grpcpp/impl/codegen/core_codegen_interface.h>
     46 #include <grpcpp/impl/codegen/create_auth_context.h>
     47 #include <grpcpp/impl/codegen/metadata_map.h>
     48 #include <grpcpp/impl/codegen/security/auth_context.h>
     49 #include <grpcpp/impl/codegen/slice.h>
     50 #include <grpcpp/impl/codegen/status.h>
     51 #include <grpcpp/impl/codegen/string_ref.h>
     52 #include <grpcpp/impl/codegen/time.h>
     53 
     54 struct census_context;
     55 struct grpc_call;
     56 
     57 namespace grpc {
     58 
     59 class Channel;
     60 class ChannelInterface;
     61 class CompletionQueue;
     62 class CallCredentials;
     63 class ClientContext;
     64 
     65 namespace internal {
     66 class RpcMethod;
     67 class CallOpClientRecvStatus;
     68 class CallOpRecvInitialMetadata;
     69 template <class InputMessage, class OutputMessage>
     70 class BlockingUnaryCallImpl;
     71 template <class InputMessage, class OutputMessage>
     72 class CallbackUnaryCallImpl;
     73 }  // namespace internal
     74 
     75 template <class R>
     76 class ClientReader;
     77 template <class W>
     78 class ClientWriter;
     79 template <class W, class R>
     80 class ClientReaderWriter;
     81 template <class R>
     82 class ClientAsyncReader;
     83 template <class W>
     84 class ClientAsyncWriter;
     85 template <class W, class R>
     86 class ClientAsyncReaderWriter;
     87 template <class R>
     88 class ClientAsyncResponseReader;
     89 class ServerContext;
     90 
     91 /// Options for \a ClientContext::FromServerContext specifying which traits from
     92 /// the \a ServerContext to propagate (copy) from it into a new \a
     93 /// ClientContext.
     94 ///
     95 /// \see ClientContext::FromServerContext
     96 class PropagationOptions {
     97  public:
     98   PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
     99 
    100   PropagationOptions& enable_deadline_propagation() {
    101     propagate_ |= GRPC_PROPAGATE_DEADLINE;
    102     return *this;
    103   }
    104 
    105   PropagationOptions& disable_deadline_propagation() {
    106     propagate_ &= ~GRPC_PROPAGATE_DEADLINE;
    107     return *this;
    108   }
    109 
    110   PropagationOptions& enable_census_stats_propagation() {
    111     propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
    112     return *this;
    113   }
    114 
    115   PropagationOptions& disable_census_stats_propagation() {
    116     propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
    117     return *this;
    118   }
    119 
    120   PropagationOptions& enable_census_tracing_propagation() {
    121     propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
    122     return *this;
    123   }
    124 
    125   PropagationOptions& disable_census_tracing_propagation() {
    126     propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
    127     return *this;
    128   }
    129 
    130   PropagationOptions& enable_cancellation_propagation() {
    131     propagate_ |= GRPC_PROPAGATE_CANCELLATION;
    132     return *this;
    133   }
    134 
    135   PropagationOptions& disable_cancellation_propagation() {
    136     propagate_ &= ~GRPC_PROPAGATE_CANCELLATION;
    137     return *this;
    138   }
    139 
    140   uint32_t c_bitmask() const { return propagate_; }
    141 
    142  private:
    143   uint32_t propagate_;
    144 };
    145 
    146 namespace testing {
    147 class InteropClientContextInspector;
    148 }  // namespace testing
    149 
    150 /// A ClientContext allows the person implementing a service client to:
    151 ///
    152 /// - Add custom metadata key-value pairs that will propagated to the server
    153 ///   side.
    154 /// - Control call settings such as compression and authentication.
    155 /// - Initial and trailing metadata coming from the server.
    156 /// - Get performance metrics (ie, census).
    157 ///
    158 /// Context settings are only relevant to the call they are invoked with, that
    159 /// is to say, they aren't sticky. Some of these settings, such as the
    160 /// compression options, can be made persistent at channel construction time
    161 /// (see \a grpc::CreateCustomChannel).
    162 ///
    163 /// \warning ClientContext instances should \em not be reused across rpcs.
    164 class ClientContext {
    165  public:
    166   ClientContext();
    167   ~ClientContext();
    168 
    169   /// Create a new \a ClientContext as a child of an incoming server call,
    170   /// according to \a options (\see PropagationOptions).
    171   ///
    172   /// \param server_context The source server context to use as the basis for
    173   /// constructing the client context.
    174   /// \param options The options controlling what to copy from the \a
    175   /// server_context.
    176   ///
    177   /// \return A newly constructed \a ClientContext instance based on \a
    178   /// server_context, with traits propagated (copied) according to \a options.
    179   static std::unique_ptr<ClientContext> FromServerContext(
    180       const ServerContext& server_context,
    181       PropagationOptions options = PropagationOptions());
    182 
    183   /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
    184   /// a client call. These are made available at the server side by the \a
    185   /// grpc::ServerContext::client_metadata() method.
    186   ///
    187   /// \warning This method should only be called before invoking the rpc.
    188   ///
    189   /// \param meta_key The metadata key. If \a meta_value is binary data, it must
    190   /// end in "-bin".
    191   /// \param meta_value The metadata value. If its value is binary, the key name
    192   /// must end in "-bin".
    193   void AddMetadata(const grpc::string& meta_key,
    194                    const grpc::string& meta_value);
    195 
    196   /// Return a collection of initial metadata key-value pairs. Note that keys
    197   /// may happen more than once (ie, a \a std::multimap is returned).
    198   ///
    199   /// \warning This method should only be called after initial metadata has been
    200   /// received. For streaming calls, see \a
    201   /// ClientReaderInterface::WaitForInitialMetadata().
    202   ///
    203   /// \return A multimap of initial metadata key-value pairs from the server.
    204   const std::multimap<grpc::string_ref, grpc::string_ref>&
    205   GetServerInitialMetadata() const {
    206     GPR_CODEGEN_ASSERT(initial_metadata_received_);
    207     return *recv_initial_metadata_.map();
    208   }
    209 
    210   /// Return a collection of trailing metadata key-value pairs. Note that keys
    211   /// may happen more than once (ie, a \a std::multimap is returned).
    212   ///
    213   /// \warning This method is only callable once the stream has finished.
    214   ///
    215   /// \return A multimap of metadata trailing key-value pairs from the server.
    216   const std::multimap<grpc::string_ref, grpc::string_ref>&
    217   GetServerTrailingMetadata() const {
    218     // TODO(yangg) check finished
    219     return *trailing_metadata_.map();
    220   }
    221 
    222   /// Set the deadline for the client call.
    223   ///
    224   /// \warning This method should only be called before invoking the rpc.
    225   ///
    226   /// \param deadline the deadline for the client call. Units are determined by
    227   /// the type used.
    228   template <typename T>
    229   void set_deadline(const T& deadline) {
    230     TimePoint<T> deadline_tp(deadline);
    231     deadline_ = deadline_tp.raw_time();
    232   }
    233 
    234   /// EXPERIMENTAL: Indicate that this request is idempotent.
    235   /// By default, RPCs are assumed to <i>not</i> be idempotent.
    236   ///
    237   /// If true, the gRPC library assumes that it's safe to initiate
    238   /// this RPC multiple times.
    239   void set_idempotent(bool idempotent) { idempotent_ = idempotent; }
    240 
    241   /// EXPERIMENTAL: Set this request to be cacheable.
    242   /// If set, grpc is free to use the HTTP GET verb for sending the request,
    243   /// with the possibility of receiving a cached response.
    244   void set_cacheable(bool cacheable) { cacheable_ = cacheable; }
    245 
    246   /// EXPERIMENTAL: Trigger wait-for-ready or not on this request.
    247   /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.
    248   /// If set, if an RPC is made when a channel's connectivity state is
    249   /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast",
    250   /// and the channel will wait until the channel is READY before making the
    251   /// call.
    252   void set_wait_for_ready(bool wait_for_ready) {
    253     wait_for_ready_ = wait_for_ready;
    254     wait_for_ready_explicitly_set_ = true;
    255   }
    256 
    257   /// DEPRECATED: Use set_wait_for_ready() instead.
    258   void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); }
    259 
    260   /// Return the deadline for the client call.
    261   std::chrono::system_clock::time_point deadline() const {
    262     return Timespec2Timepoint(deadline_);
    263   }
    264 
    265   /// Return a \a gpr_timespec representation of the client call's deadline.
    266   gpr_timespec raw_deadline() const { return deadline_; }
    267 
    268   /// Set the per call authority header (see
    269   /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
    270   void set_authority(const grpc::string& authority) { authority_ = authority; }
    271 
    272   /// Return the authentication context for this client call.
    273   ///
    274   /// \see grpc::AuthContext.
    275   std::shared_ptr<const AuthContext> auth_context() const {
    276     if (auth_context_.get() == nullptr) {
    277       auth_context_ = CreateAuthContext(call_);
    278     }
    279     return auth_context_;
    280   }
    281 
    282   /// Set credentials for the client call.
    283   ///
    284   /// A credentials object encapsulates all the state needed by a client to
    285   /// authenticate with a server and make various assertions, e.g., about the
    286   /// clients identity, role, or whether it is authorized to make a particular
    287   /// call.
    288   ///
    289   /// \see  https://grpc.io/docs/guides/auth.html
    290   void set_credentials(const std::shared_ptr<CallCredentials>& creds) {
    291     creds_ = creds;
    292   }
    293 
    294   /// Return the compression algorithm the client call will request be used.
    295   /// Note that the gRPC runtime may decide to ignore this request, for example,
    296   /// due to resource constraints.
    297   grpc_compression_algorithm compression_algorithm() const {
    298     return compression_algorithm_;
    299   }
    300 
    301   /// Set \a algorithm to be the compression algorithm used for the client call.
    302   ///
    303   /// \param algorithm The compression algorithm used for the client call.
    304   void set_compression_algorithm(grpc_compression_algorithm algorithm);
    305 
    306   /// Flag whether the initial metadata should be \a corked
    307   ///
    308   /// If \a corked is true, then the initial metadata will be coalesced with the
    309   /// write of first message in the stream. As a result, any tag set for the
    310   /// initial metadata operation (starting a client-streaming or bidi-streaming
    311   /// RPC) will not actually be sent to the completion queue or delivered
    312   /// via Next.
    313   ///
    314   /// \param corked The flag indicating whether the initial metadata is to be
    315   /// corked or not.
    316   void set_initial_metadata_corked(bool corked) {
    317     initial_metadata_corked_ = corked;
    318   }
    319 
    320   /// Return the peer uri in a string.
    321   ///
    322   /// \warning This value is never authenticated or subject to any security
    323   /// related code. It must not be used for any authentication related
    324   /// functionality. Instead, use auth_context.
    325   ///
    326   /// \return The call's peer URI.
    327   grpc::string peer() const;
    328 
    329   /// Get and set census context.
    330   void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
    331   struct census_context* census_context() const {
    332     return census_context_;
    333   }
    334 
    335   /// Send a best-effort out-of-band cancel on the call associated with
    336   /// this client context.  The call could be in any stage; e.g., if it is
    337   /// already finished, it may still return success.
    338   ///
    339   /// There is no guarantee the call will be cancelled.
    340   ///
    341   /// Note that TryCancel() does not change any of the tags that are pending
    342   /// on the completion queue. All pending tags will still be delivered
    343   /// (though their ok result may reflect the effect of cancellation).
    344   void TryCancel();
    345 
    346   /// Global Callbacks
    347   ///
    348   /// Can be set exactly once per application to install hooks whenever
    349   /// a client context is constructed and destructed.
    350   class GlobalCallbacks {
    351    public:
    352     virtual ~GlobalCallbacks() {}
    353     virtual void DefaultConstructor(ClientContext* context) = 0;
    354     virtual void Destructor(ClientContext* context) = 0;
    355   };
    356   static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
    357 
    358   /// Should be used for framework-level extensions only.
    359   /// Applications never need to call this method.
    360   grpc_call* c_call() { return call_; }
    361 
    362   /// EXPERIMENTAL debugging API
    363   ///
    364   /// if status is not ok() for an RPC, this will return a detailed string
    365   /// of the gRPC Core error that led to the failure. It should not be relied
    366   /// upon for anything other than gaining more debug data in failure cases.
    367   grpc::string debug_error_string() const { return debug_error_string_; }
    368 
    369  private:
    370   // Disallow copy and assign.
    371   ClientContext(const ClientContext&);
    372   ClientContext& operator=(const ClientContext&);
    373 
    374   friend class ::grpc::testing::InteropClientContextInspector;
    375   friend class ::grpc::internal::CallOpClientRecvStatus;
    376   friend class ::grpc::internal::CallOpRecvInitialMetadata;
    377   friend class Channel;
    378   template <class R>
    379   friend class ::grpc::ClientReader;
    380   template <class W>
    381   friend class ::grpc::ClientWriter;
    382   template <class W, class R>
    383   friend class ::grpc::ClientReaderWriter;
    384   template <class R>
    385   friend class ::grpc::ClientAsyncReader;
    386   template <class W>
    387   friend class ::grpc::ClientAsyncWriter;
    388   template <class W, class R>
    389   friend class ::grpc::ClientAsyncReaderWriter;
    390   template <class R>
    391   friend class ::grpc::ClientAsyncResponseReader;
    392   template <class InputMessage, class OutputMessage>
    393   friend class ::grpc::internal::BlockingUnaryCallImpl;
    394   template <class InputMessage, class OutputMessage>
    395   friend class ::grpc::internal::CallbackUnaryCallImpl;
    396 
    397   // Used by friend class CallOpClientRecvStatus
    398   void set_debug_error_string(const grpc::string& debug_error_string) {
    399     debug_error_string_ = debug_error_string;
    400   }
    401 
    402   grpc_call* call() const { return call_; }
    403   void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
    404 
    405   uint32_t initial_metadata_flags() const {
    406     return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
    407            (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) |
    408            (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) |
    409            (wait_for_ready_explicitly_set_
    410                 ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET
    411                 : 0) |
    412            (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0);
    413   }
    414 
    415   grpc::string authority() { return authority_; }
    416 
    417   bool initial_metadata_received_;
    418   bool wait_for_ready_;
    419   bool wait_for_ready_explicitly_set_;
    420   bool idempotent_;
    421   bool cacheable_;
    422   std::shared_ptr<Channel> channel_;
    423   std::mutex mu_;
    424   grpc_call* call_;
    425   bool call_canceled_;
    426   gpr_timespec deadline_;
    427   grpc::string authority_;
    428   std::shared_ptr<CallCredentials> creds_;
    429   mutable std::shared_ptr<const AuthContext> auth_context_;
    430   struct census_context* census_context_;
    431   std::multimap<grpc::string, grpc::string> send_initial_metadata_;
    432   mutable internal::MetadataMap recv_initial_metadata_;
    433   mutable internal::MetadataMap trailing_metadata_;
    434 
    435   grpc_call* propagate_from_call_;
    436   PropagationOptions propagation_options_;
    437 
    438   grpc_compression_algorithm compression_algorithm_;
    439   bool initial_metadata_corked_;
    440 
    441   grpc::string debug_error_string_;
    442 };
    443 
    444 }  // namespace grpc
    445 
    446 #endif  // GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H
    447