| /* |
| * |
| * Copyright 2015 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| /// A ClientContext allows the person implementing a service client to: |
| /// |
| /// - Add custom metadata key-value pairs that will propagated to the server |
| /// side. |
| /// - Control call settings such as compression and authentication. |
| /// - Initial and trailing metadata coming from the server. |
| /// - Get performance metrics (ie, census). |
| /// |
| /// Context settings are only relevant to the call they are invoked with, that |
| /// is to say, they aren't sticky. Some of these settings, such as the |
| /// compression options, can be made persistent at channel construction time |
| /// (see \a grpc::CreateCustomChannel). |
| /// |
| /// \warning ClientContext instances should \em not be reused across rpcs. |
| |
| #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H |
| #define GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H |
| |
| #include <map> |
| #include <memory> |
| #include <mutex> |
| #include <string> |
| |
| #include <grpc/impl/codegen/compression_types.h> |
| #include <grpc/impl/codegen/propagation_bits.h> |
| #include <grpcpp/impl/codegen/client_interceptor.h> |
| #include <grpcpp/impl/codegen/config.h> |
| #include <grpcpp/impl/codegen/core_codegen_interface.h> |
| #include <grpcpp/impl/codegen/create_auth_context.h> |
| #include <grpcpp/impl/codegen/metadata_map.h> |
| #include <grpcpp/impl/codegen/rpc_method.h> |
| #include <grpcpp/impl/codegen/security/auth_context.h> |
| #include <grpcpp/impl/codegen/slice.h> |
| #include <grpcpp/impl/codegen/status.h> |
| #include <grpcpp/impl/codegen/string_ref.h> |
| #include <grpcpp/impl/codegen/sync.h> |
| #include <grpcpp/impl/codegen/time.h> |
| |
| struct census_context; |
| struct grpc_call; |
| |
| namespace grpc { |
| |
| class Channel; |
| class ChannelInterface; |
| class CompletionQueue; |
| class CallCredentials; |
| class ClientContext; |
| |
| namespace internal { |
| class RpcMethod; |
| class CallOpClientRecvStatus; |
| class CallOpRecvInitialMetadata; |
| template <class InputMessage, class OutputMessage> |
| class BlockingUnaryCallImpl; |
| template <class InputMessage, class OutputMessage> |
| class CallbackUnaryCallImpl; |
| template <class Request, class Response> |
| class ClientCallbackReaderWriterImpl; |
| template <class Response> |
| class ClientCallbackReaderImpl; |
| template <class Request> |
| class ClientCallbackWriterImpl; |
| } // namespace internal |
| |
| template <class R> |
| class ClientReader; |
| template <class W> |
| class ClientWriter; |
| template <class W, class R> |
| class ClientReaderWriter; |
| template <class R> |
| class ClientAsyncReader; |
| template <class W> |
| class ClientAsyncWriter; |
| template <class W, class R> |
| class ClientAsyncReaderWriter; |
| template <class R> |
| class ClientAsyncResponseReader; |
| class ServerContext; |
| |
| /// Options for \a ClientContext::FromServerContext specifying which traits from |
| /// the \a ServerContext to propagate (copy) from it into a new \a |
| /// ClientContext. |
| /// |
| /// \see ClientContext::FromServerContext |
| class PropagationOptions { |
| public: |
| PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {} |
| |
| PropagationOptions& enable_deadline_propagation() { |
| propagate_ |= GRPC_PROPAGATE_DEADLINE; |
| return *this; |
| } |
| |
| PropagationOptions& disable_deadline_propagation() { |
| propagate_ &= ~GRPC_PROPAGATE_DEADLINE; |
| return *this; |
| } |
| |
| PropagationOptions& enable_census_stats_propagation() { |
| propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; |
| return *this; |
| } |
| |
| PropagationOptions& disable_census_stats_propagation() { |
| propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; |
| return *this; |
| } |
| |
| PropagationOptions& enable_census_tracing_propagation() { |
| propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; |
| return *this; |
| } |
| |
| PropagationOptions& disable_census_tracing_propagation() { |
| propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; |
| return *this; |
| } |
| |
| PropagationOptions& enable_cancellation_propagation() { |
| propagate_ |= GRPC_PROPAGATE_CANCELLATION; |
| return *this; |
| } |
| |
| PropagationOptions& disable_cancellation_propagation() { |
| propagate_ &= ~GRPC_PROPAGATE_CANCELLATION; |
| return *this; |
| } |
| |
| uint32_t c_bitmask() const { return propagate_; } |
| |
| private: |
| uint32_t propagate_; |
| }; |
| |
| namespace testing { |
| class InteropClientContextInspector; |
| } // namespace testing |
| |
| /// A ClientContext allows the person implementing a service client to: |
| /// |
| /// - Add custom metadata key-value pairs that will propagated to the server |
| /// side. |
| /// - Control call settings such as compression and authentication. |
| /// - Initial and trailing metadata coming from the server. |
| /// - Get performance metrics (ie, census). |
| /// |
| /// Context settings are only relevant to the call they are invoked with, that |
| /// is to say, they aren't sticky. Some of these settings, such as the |
| /// compression options, can be made persistent at channel construction time |
| /// (see \a grpc::CreateCustomChannel). |
| /// |
| /// \warning ClientContext instances should \em not be reused across rpcs. |
| /// \warning The ClientContext instance used for creating an rpc must remain |
| /// alive and valid for the lifetime of the rpc. |
| class ClientContext { |
| public: |
| ClientContext(); |
| ~ClientContext(); |
| |
| /// Create a new \a ClientContext as a child of an incoming server call, |
| /// according to \a options (\see PropagationOptions). |
| /// |
| /// \param server_context The source server context to use as the basis for |
| /// constructing the client context. |
| /// \param options The options controlling what to copy from the \a |
| /// server_context. |
| /// |
| /// \return A newly constructed \a ClientContext instance based on \a |
| /// server_context, with traits propagated (copied) according to \a options. |
| static std::unique_ptr<ClientContext> FromServerContext( |
| const ServerContext& server_context, |
| PropagationOptions options = PropagationOptions()); |
| |
| /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with |
| /// a client call. These are made available at the server side by the \a |
| /// grpc::ServerContext::client_metadata() method. |
| /// |
| /// \warning This method should only be called before invoking the rpc. |
| /// |
| /// \param meta_key The metadata key. If \a meta_value is binary data, it must |
| /// end in "-bin". |
| /// \param meta_value The metadata value. If its value is binary, the key name |
| /// must end in "-bin". |
| /// |
| /// Metadata must conform to the following format: |
| /// Custom-Metadata -> Binary-Header / ASCII-Header |
| /// Binary-Header -> {Header-Name "-bin" } {binary value} |
| /// ASCII-Header -> Header-Name ASCII-Value |
| /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . |
| /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII |
| void AddMetadata(const grpc::string& meta_key, |
| const grpc::string& meta_value); |
| |
| /// Return a collection of initial metadata key-value pairs. Note that keys |
| /// may happen more than once (ie, a \a std::multimap is returned). |
| /// |
| /// \warning This method should only be called after initial metadata has been |
| /// received. For streaming calls, see \a |
| /// ClientReaderInterface::WaitForInitialMetadata(). |
| /// |
| /// \return A multimap of initial metadata key-value pairs from the server. |
| const std::multimap<grpc::string_ref, grpc::string_ref>& |
| GetServerInitialMetadata() const { |
| GPR_CODEGEN_ASSERT(initial_metadata_received_); |
| return *recv_initial_metadata_.map(); |
| } |
| |
| /// Return a collection of trailing metadata key-value pairs. Note that keys |
| /// may happen more than once (ie, a \a std::multimap is returned). |
| /// |
| /// \warning This method is only callable once the stream has finished. |
| /// |
| /// \return A multimap of metadata trailing key-value pairs from the server. |
| const std::multimap<grpc::string_ref, grpc::string_ref>& |
| GetServerTrailingMetadata() const { |
| // TODO(yangg) check finished |
| return *trailing_metadata_.map(); |
| } |
| |
| /// Set the deadline for the client call. |
| /// |
| /// \warning This method should only be called before invoking the rpc. |
| /// |
| /// \param deadline the deadline for the client call. Units are determined by |
| /// the type used. The deadline is an absolute (not relative) time. |
| template <typename T> |
| void set_deadline(const T& deadline) { |
| TimePoint<T> deadline_tp(deadline); |
| deadline_ = deadline_tp.raw_time(); |
| } |
| |
| /// EXPERIMENTAL: Indicate that this request is idempotent. |
| /// By default, RPCs are assumed to <i>not</i> be idempotent. |
| /// |
| /// If true, the gRPC library assumes that it's safe to initiate |
| /// this RPC multiple times. |
| void set_idempotent(bool idempotent) { idempotent_ = idempotent; } |
| |
| /// EXPERIMENTAL: Set this request to be cacheable. |
| /// If set, grpc is free to use the HTTP GET verb for sending the request, |
| /// with the possibility of receiving a cached response. |
| void set_cacheable(bool cacheable) { cacheable_ = cacheable; } |
| |
| /// EXPERIMENTAL: Trigger wait-for-ready or not on this request. |
| /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. |
| /// If set, if an RPC is made when a channel's connectivity state is |
| /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast", |
| /// and the channel will wait until the channel is READY before making the |
| /// call. |
| void set_wait_for_ready(bool wait_for_ready) { |
| wait_for_ready_ = wait_for_ready; |
| wait_for_ready_explicitly_set_ = true; |
| } |
| |
| /// DEPRECATED: Use set_wait_for_ready() instead. |
| void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); } |
| |
| /// Return the deadline for the client call. |
| std::chrono::system_clock::time_point deadline() const { |
| return Timespec2Timepoint(deadline_); |
| } |
| |
| /// Return a \a gpr_timespec representation of the client call's deadline. |
| gpr_timespec raw_deadline() const { return deadline_; } |
| |
| /// Set the per call authority header (see |
| /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3). |
| void set_authority(const grpc::string& authority) { authority_ = authority; } |
| |
| /// Return the authentication context for this client call. |
| /// |
| /// \see grpc::AuthContext. |
| std::shared_ptr<const AuthContext> auth_context() const { |
| if (auth_context_.get() == nullptr) { |
| auth_context_ = CreateAuthContext(call_); |
| } |
| return auth_context_; |
| } |
| |
| /// Set credentials for the client call. |
| /// |
| /// A credentials object encapsulates all the state needed by a client to |
| /// authenticate with a server and make various assertions, e.g., about the |
| /// client’s identity, role, or whether it is authorized to make a particular |
| /// call. |
| /// |
| /// \see https://grpc.io/docs/guides/auth.html |
| void set_credentials(const std::shared_ptr<CallCredentials>& creds) { |
| creds_ = creds; |
| } |
| |
| /// Return the compression algorithm the client call will request be used. |
| /// Note that the gRPC runtime may decide to ignore this request, for example, |
| /// due to resource constraints. |
| grpc_compression_algorithm compression_algorithm() const { |
| return compression_algorithm_; |
| } |
| |
| /// Set \a algorithm to be the compression algorithm used for the client call. |
| /// |
| /// \param algorithm The compression algorithm used for the client call. |
| void set_compression_algorithm(grpc_compression_algorithm algorithm); |
| |
| /// Flag whether the initial metadata should be \a corked |
| /// |
| /// If \a corked is true, then the initial metadata will be coalesced with the |
| /// write of first message in the stream. As a result, any tag set for the |
| /// initial metadata operation (starting a client-streaming or bidi-streaming |
| /// RPC) will not actually be sent to the completion queue or delivered |
| /// via Next. |
| /// |
| /// \param corked The flag indicating whether the initial metadata is to be |
| /// corked or not. |
| void set_initial_metadata_corked(bool corked) { |
| initial_metadata_corked_ = corked; |
| } |
| |
| /// Return the peer uri in a string. |
| /// |
| /// \warning This value is never authenticated or subject to any security |
| /// related code. It must not be used for any authentication related |
| /// functionality. Instead, use auth_context. |
| /// |
| /// \return The call's peer URI. |
| grpc::string peer() const; |
| |
| /// Get and set census context. |
| void set_census_context(struct census_context* ccp) { census_context_ = ccp; } |
| struct census_context* census_context() const { |
| return census_context_; |
| } |
| |
| /// Send a best-effort out-of-band cancel on the call associated with |
| /// this client context. The call could be in any stage; e.g., if it is |
| /// already finished, it may still return success. |
| /// |
| /// There is no guarantee the call will be cancelled. |
| /// |
| /// Note that TryCancel() does not change any of the tags that are pending |
| /// on the completion queue. All pending tags will still be delivered |
| /// (though their ok result may reflect the effect of cancellation). |
| void TryCancel(); |
| |
| /// Global Callbacks |
| /// |
| /// Can be set exactly once per application to install hooks whenever |
| /// a client context is constructed and destructed. |
| class GlobalCallbacks { |
| public: |
| virtual ~GlobalCallbacks() {} |
| virtual void DefaultConstructor(ClientContext* context) = 0; |
| virtual void Destructor(ClientContext* context) = 0; |
| }; |
| static void SetGlobalCallbacks(GlobalCallbacks* callbacks); |
| |
| /// Should be used for framework-level extensions only. |
| /// Applications never need to call this method. |
| grpc_call* c_call() { return call_; } |
| |
| /// EXPERIMENTAL debugging API |
| /// |
| /// if status is not ok() for an RPC, this will return a detailed string |
| /// of the gRPC Core error that led to the failure. It should not be relied |
| /// upon for anything other than gaining more debug data in failure cases. |
| grpc::string debug_error_string() const { return debug_error_string_; } |
| |
| private: |
| // Disallow copy and assign. |
| ClientContext(const ClientContext&); |
| ClientContext& operator=(const ClientContext&); |
| |
| friend class ::grpc::testing::InteropClientContextInspector; |
| friend class ::grpc::internal::CallOpClientRecvStatus; |
| friend class ::grpc::internal::CallOpRecvInitialMetadata; |
| friend class Channel; |
| template <class R> |
| friend class ::grpc::ClientReader; |
| template <class W> |
| friend class ::grpc::ClientWriter; |
| template <class W, class R> |
| friend class ::grpc::ClientReaderWriter; |
| template <class R> |
| friend class ::grpc::ClientAsyncReader; |
| template <class W> |
| friend class ::grpc::ClientAsyncWriter; |
| template <class W, class R> |
| friend class ::grpc::ClientAsyncReaderWriter; |
| template <class R> |
| friend class ::grpc::ClientAsyncResponseReader; |
| template <class InputMessage, class OutputMessage> |
| friend class ::grpc::internal::BlockingUnaryCallImpl; |
| template <class InputMessage, class OutputMessage> |
| friend class ::grpc::internal::CallbackUnaryCallImpl; |
| template <class Request, class Response> |
| friend class ::grpc::internal::ClientCallbackReaderWriterImpl; |
| template <class Response> |
| friend class ::grpc::internal::ClientCallbackReaderImpl; |
| template <class Request> |
| friend class ::grpc::internal::ClientCallbackWriterImpl; |
| |
| // Used by friend class CallOpClientRecvStatus |
| void set_debug_error_string(const grpc::string& debug_error_string) { |
| debug_error_string_ = debug_error_string; |
| } |
| |
| grpc_call* call() const { return call_; } |
| void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel); |
| |
| experimental::ClientRpcInfo* set_client_rpc_info( |
| const char* method, internal::RpcMethod::RpcType type, |
| grpc::ChannelInterface* channel, |
| const std::vector< |
| std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>& |
| creators, |
| size_t interceptor_pos) { |
| rpc_info_ = experimental::ClientRpcInfo(this, type, method, channel); |
| rpc_info_.RegisterInterceptors(creators, interceptor_pos); |
| return &rpc_info_; |
| } |
| |
| uint32_t initial_metadata_flags() const { |
| return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) | |
| (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) | |
| (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) | |
| (wait_for_ready_explicitly_set_ |
| ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET |
| : 0) | |
| (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0); |
| } |
| |
| grpc::string authority() { return authority_; } |
| |
| void SendCancelToInterceptors(); |
| |
| bool initial_metadata_received_; |
| bool wait_for_ready_; |
| bool wait_for_ready_explicitly_set_; |
| bool idempotent_; |
| bool cacheable_; |
| std::shared_ptr<Channel> channel_; |
| grpc::internal::Mutex mu_; |
| grpc_call* call_; |
| bool call_canceled_; |
| gpr_timespec deadline_; |
| grpc::string authority_; |
| std::shared_ptr<CallCredentials> creds_; |
| mutable std::shared_ptr<const AuthContext> auth_context_; |
| struct census_context* census_context_; |
| std::multimap<grpc::string, grpc::string> send_initial_metadata_; |
| mutable internal::MetadataMap recv_initial_metadata_; |
| mutable internal::MetadataMap trailing_metadata_; |
| |
| grpc_call* propagate_from_call_; |
| PropagationOptions propagation_options_; |
| |
| grpc_compression_algorithm compression_algorithm_; |
| bool initial_metadata_corked_; |
| |
| grpc::string debug_error_string_; |
| |
| experimental::ClientRpcInfo rpc_info_; |
| }; |
| |
| } // namespace grpc |
| |
| #endif // GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H |