From c52ae0d0005ccf98c6e734db34cd2634e5aa26ef Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 17 Dec 2018 13:27:42 -0800 Subject: Give the interceptors header files in include/grpcpp/support --- include/grpcpp/support/client_interceptor.h | 24 ++++++++++++++++++++++++ include/grpcpp/support/interceptor.h | 24 ++++++++++++++++++++++++ include/grpcpp/support/server_interceptor.h | 24 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 include/grpcpp/support/client_interceptor.h create mode 100644 include/grpcpp/support/interceptor.h create mode 100644 include/grpcpp/support/server_interceptor.h (limited to 'include') diff --git a/include/grpcpp/support/client_interceptor.h b/include/grpcpp/support/client_interceptor.h new file mode 100644 index 0000000000..50810e3fe3 --- /dev/null +++ b/include/grpcpp/support/client_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H diff --git a/include/grpcpp/support/interceptor.h b/include/grpcpp/support/interceptor.h new file mode 100644 index 0000000000..7ff79516ba --- /dev/null +++ b/include/grpcpp/support/interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_SUPPORT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_INTERCEPTOR_H diff --git a/include/grpcpp/support/server_interceptor.h b/include/grpcpp/support/server_interceptor.h new file mode 100644 index 0000000000..b0a6229b66 --- /dev/null +++ b/include/grpcpp/support/server_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H +#define GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H -- cgit v1.2.3 From eb9064db2fd38025dfa4fbe813de8798b5f1d0ed Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 18 Dec 2018 10:35:07 -0800 Subject: Clarify compression algorithm enum order --- include/grpc/impl/codegen/compression_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h index e35d892967..f778b005b9 100644 --- a/include/grpc/impl/codegen/compression_types.h +++ b/include/grpc/impl/codegen/compression_types.h @@ -52,7 +52,8 @@ extern "C" { "grpc.compression_enabled_algorithms_bitset" /** \} */ -/** The various compression algorithms supported by gRPC */ +/** The various compression algorithms supported by gRPC (not sorted by + * compression level) */ typedef enum { GRPC_COMPRESS_NONE = 0, GRPC_COMPRESS_DEFLATE, -- cgit v1.2.3 From 233123ae3fa73b632c7b81b1131edb83c4fcf13a Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Fri, 14 Dec 2018 15:06:35 -0800 Subject: Improve metadata documentation for the user --- include/grpcpp/impl/codegen/client_context.h | 7 +++++++ include/grpcpp/impl/codegen/server_context.h | 14 ++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'include') diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 0a71f3d9b6..5946488566 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -200,6 +200,13 @@ class ClientContext { /// 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); diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index ccb5925e7d..affe61b547 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -131,6 +131,13 @@ class ServerContext { /// end in "-bin". /// \param 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 AddInitialMetadata(const grpc::string& key, const grpc::string& value); /// Add the (\a key, \a value) pair to the initial metadata @@ -145,6 +152,13 @@ class ServerContext { /// it must end in "-bin". /// \param 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 AddTrailingMetadata(const grpc::string& key, const grpc::string& value); /// IsCancelled is always safe to call when using sync or callback API. -- cgit v1.2.3 From d5905834569d2d3c53e80722e4389cf03d689132 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 18 Dec 2018 12:10:20 -0800 Subject: Allow interceptor creators to return nullptr --- include/grpcpp/impl/codegen/client_interceptor.h | 15 +++++++++++++-- include/grpcpp/impl/codegen/server_interceptor.h | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 2bae11a251..da75bde499 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -38,9 +38,17 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ClientRpcInfo; +// A factory interface for creation of client interceptors. A vector of +// factories can be provided at channel creation which will be used to create a +// new vector of client interceptors per RPC. Client interceptor authors should +// create a subclass of ClientInterceptorFactorInterface which creates objects +// of their interceptors. class ClientInterceptorFactoryInterface { public: virtual ~ClientInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateClientInterceptor(ClientRpcInfo* info) = 0; }; } // namespace experimental @@ -120,8 +128,11 @@ class ClientRpcInfo { } for (auto it = creators.begin() + interceptor_pos; it != creators.end(); ++it) { - interceptors_.push_back(std::unique_ptr( - (*it)->CreateClientInterceptor(this))); + auto* interceptor = (*it)->CreateClientInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } if (internal::g_global_client_interceptor_factory != nullptr) { interceptors_.push_back(std::unique_ptr( diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index afc3c198cc..8652ec5c64 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -37,9 +37,17 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ServerRpcInfo; +// A factory interface for creation of server interceptors. A vector of +// factories can be provided to ServerBuilder which will be used to create a new +// vector of server interceptors per RPC. Server interceptor authors should +// create a subclass of ServerInterceptorFactorInterface which creates objects +// of their interceptors. class ServerInterceptorFactoryInterface { public: virtual ~ServerInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0; }; @@ -90,8 +98,11 @@ class ServerRpcInfo { std::unique_ptr>& creators) { for (const auto& creator : creators) { - interceptors_.push_back(std::unique_ptr( - creator->CreateServerInterceptor(this))); + auto* interceptor = creator->CreateServerInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } } -- cgit v1.2.3 From cfe08f35f30d272a8f2e851fb9e069498b264f5f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Dec 2018 12:52:26 -0800 Subject: Add comments explaining purpose and validity of interception API --- include/grpcpp/impl/codegen/client_interceptor.h | 15 +++ include/grpcpp/impl/codegen/interceptor.h | 130 +++++++++++++++-------- include/grpcpp/impl/codegen/server_interceptor.h | 14 +++ 3 files changed, 115 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 2bae11a251..2eca596f1d 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -50,11 +50,16 @@ extern experimental::ClientInterceptorFactoryInterface* g_global_client_interceptor_factory; } +/// ClientRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateClientInterceptor method of the application's +/// ClientInterceptorFactoryInterface implementation namespace experimental { class ClientRpcInfo { public: // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN // from the list of possible Types. + /// Type categorizes RPCs by unary or streaming type enum class Type { UNARY, CLIENT_STREAMING, @@ -65,13 +70,23 @@ class ClientRpcInfo { ~ClientRpcInfo(){}; + // Delete copy constructor but allow default move constructor ClientRpcInfo(const ClientRpcInfo&) = delete; ClientRpcInfo(ClientRpcInfo&&) = default; // Getter methods + + /// Return the fully-specified method name const char* method() const { return method_; } + + /// Return a pointer to the channel on which the RPC is being sent ChannelInterface* channel() { return channel_; } + + /// Return a pointer to the underlying ClientContext structure associated + /// with the RPC to support features that apply to it grpc::ClientContext* client_context() { return ctx_; } + + /// Return the type of the RPC (unary or a streaming flavor) Type type() const { return type_; } private: diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23..46175cd73b 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -31,99 +31,141 @@ class ChannelInterface; class Status; namespace experimental { -class InterceptedMessage { - public: - template - bool Extract(M* msg); // returns false if definitely invalid extraction - template - M* MutableExtract(); - uint64_t length(); // length on wire -}; +/// An enumeration of different possible points at which the \a Intercept +/// method of the \a Interceptor interface may be called. Any given call +/// to \a Intercept will include one or more of these hook points, and +/// each hook point makes certain types of information available to the +/// interceptor. +/// In these enumeration names, PRE_SEND means that an interception has taken +/// place between the time the application provided a certain type of data +/// (e.g., initial metadata, status) and the time that that data goes to the +/// other side. POST_SEND means that the data has been committed for going to +/// the other side (even if it has not yet been received at the other side). +/// PRE_RECV means an interception between the time that a certain +/// operation has been requested and it is available. POST_RECV means that a +/// result is available but has not yet been passed back to the application. enum class InterceptionHookPoints { - /* The first two in this list are for clients and servers */ + /// The first two in this list are for clients and servers PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, - PRE_SEND_STATUS /* server only */, - PRE_SEND_CLOSE /* client only */, - /* The following three are for hijacked clients only and can only be - registered by the global interceptor */ + PRE_SEND_STATUS, // server only + PRE_SEND_CLOSE, // client only: WritesDone for stream; after write in unary + /// The following three are for hijacked clients only and can only be + /// registered by the global interceptor PRE_RECV_INITIAL_METADATA, PRE_RECV_MESSAGE, PRE_RECV_STATUS, - /* The following two are for all clients and servers */ + /// The following two are for all clients and servers POST_RECV_INITIAL_METADATA, POST_RECV_MESSAGE, - POST_RECV_STATUS /* client only */, - POST_RECV_CLOSE /* server only */, - /* This is a special hook point available to both clients and servers when - TryCancel() is performed. - - No other hook points will be present along with this. - - It is illegal for an interceptor to block/delay this operation. - - ALL interceptors see this hook point irrespective of whether the RPC was - hijacked or not. */ + POST_RECV_STATUS, // client only + POST_RECV_CLOSE, // server only + /// This is a special hook point available to both clients and servers when + /// TryCancel() is performed. + /// - No other hook points will be present along with this. + /// - It is illegal for an interceptor to block/delay this operation. + /// - ALL interceptors see this hook point irrespective of whether the + /// RPC was hijacked or not. PRE_SEND_CANCEL, NUM_INTERCEPTION_HOOKS }; +/// Class that is passed as an argument to the \a Intercept method +/// of the application's \a Interceptor interface implementation. It has five +/// purposes: +/// 1. Indicate which hook points are present at a specific interception +/// 2. Allow an interceptor to inform the library that an RPC should +/// continue to the next stage of its processing (which may be another +/// interceptor or the main path of the library) +/// 3. Allow an interceptor to hijack the processing of the RPC (only for +/// client-side RPCs with PRE_SEND_INITIAL_METADATA) so that it does not +/// proceed with normal processing beyond that stage +/// 4. Access the relevant fields of an RPC at each interception point +/// 5. Set some fields of an RPC at each interception point, when possible class InterceptorBatchMethods { public: virtual ~InterceptorBatchMethods(){}; - // Queries to check whether the current batch has an interception hook point - // of type \a type + /// Determine whether the current batch has an interception hook point + /// of type \a type virtual bool QueryInterceptionHookPoint(InterceptionHookPoints type) = 0; - // Calling this will signal that the interceptor is done intercepting the - // current batch of the RPC. - // Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning - // from the Intercept method does the job of continuing the RPC in this case. + /// Signal that the interceptor is done intercepting the current batch of the + /// RPC. Every interceptor must either call Proceed or Hijack on each + /// interception. In most cases, only Proceed will be used. Explicit use of + /// Proceed is what enables interceptors to delay the processing of RPCs + /// while they perform other work. + /// Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning + /// from the Intercept method does the job of continuing the RPC in this case. + /// This is because PRE_SEND_CANCEL is always in a separate batch and is not + /// allowed to be delayed. virtual void Proceed() = 0; - // Calling this indicates that the interceptor has hijacked the RPC (only - // valid if the batch contains send_initial_metadata on the client side) + /// Indicate that the interceptor has hijacked the RPC (only valid if the + /// batch contains send_initial_metadata on the client side). Later + /// interceptors in the interceptor list will not be called. Later batches + /// on the same RPC will go through interception, but only up to the point + /// of the hijacking interceptor. virtual void Hijack() = 0; - // Returns a modifable ByteBuffer holding serialized form of the message to be - // sent + /// Returns a modifable ByteBuffer holding the serialized form of the message + /// that is going to be sent. Valid for PRE_SEND_MESSAGE interceptions. + /// A return value of nullptr indicates that this ByteBuffer is not valid. virtual ByteBuffer* GetSendMessage() = 0; - // Returns a modifiable multimap of the initial metadata to be sent + /// Returns a modifiable multimap of the initial metadata to be sent. Valid + /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendInitialMetadata() = 0; - // Returns the status to be sent + /// Returns the status to be sent. Valid for PRE_SEND_STATUS interceptions. virtual Status GetSendStatus() = 0; - // Modifies the status with \a status + /// Overwrites the status with \a status. Valid for PRE_SEND_STATUS + /// interceptions. virtual void ModifySendStatus(const Status& status) = 0; - // Returns a modifiable multimap of the trailing metadata to be sent + /// Returns a modifiable multimap of the trailing metadata to be sent. Valid + /// for PRE_SEND_STATUS interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendTrailingMetadata() = 0; - // Returns a pointer to the modifiable received message. Note that the message - // is already deserialized + /// Returns a pointer to the modifiable received message. Note that the + /// message is already deserialized but the type is not set; the interceptor + /// should static_cast to the appropriate type before using it. This is valid + /// for POST_RECV_MESSAGE interceptions; nullptr for not valid virtual void* GetRecvMessage() = 0; - // Returns a modifiable multimap of the received initial metadata + /// Returns a modifiable multimap of the received initial metadata. + /// Valid for POST_RECV_INITIAL_METADATA interceptions; nullptr if not valid virtual std::multimap* GetRecvInitialMetadata() = 0; - // Returns a modifiable view of the received status + /// Returns a modifiable view of the received status on POST_RECV_STATUS + /// interceptions; nullptr if not valid. virtual Status* GetRecvStatus() = 0; - // Returns a modifiable multimap of the received trailing metadata + /// Returns a modifiable multimap of the received trailing metadata on + /// POST_RECV_STATUS interceptions; nullptr if not valid virtual std::multimap* GetRecvTrailingMetadata() = 0; - // Gets an intercepted channel. When a call is started on this interceptor, - // only interceptors after the current interceptor are created from the - // factory objects registered with the channel. + /// Gets an intercepted channel. When a call is started on this interceptor, + /// only interceptors after the current interceptor are created from the + /// factory objects registered with the channel. This allows calls to be + /// started from interceptors without infinite regress through the interceptor + /// list. virtual std::unique_ptr GetInterceptedChannel() = 0; }; +/// Interface for an interceptor. Interceptor authors must create a class +/// that derives from this parent class. class Interceptor { public: virtual ~Interceptor() {} + /// The one public method of an Interceptor interface. Override this to + /// trigger the desired actions at the hook points described above. virtual void Intercept(InterceptorBatchMethods* methods) = 0; }; diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index afc3c198cc..6664d09e4a 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -43,19 +43,33 @@ class ServerInterceptorFactoryInterface { virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0; }; +/// ServerRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateServerInterceptor method of the application's +/// ServerInterceptorFactoryInterface implementation class ServerRpcInfo { public: + /// Type categorizes RPCs by unary or streaming type enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING }; ~ServerRpcInfo(){}; + // Delete all copy and move constructors and assignments ServerRpcInfo(const ServerRpcInfo&) = delete; + ServerRpcInfo& operator=(const ServerRpcInfo&) = delete; ServerRpcInfo(ServerRpcInfo&&) = delete; ServerRpcInfo& operator=(ServerRpcInfo&&) = delete; // Getter methods + + /// Return the fully-specified method name const char* method() const { return method_; } + + /// Return the type of the RPC (unary or a streaming flavor) Type type() const { return type_; } + + /// Return a pointer to the underlying ServerContext structure associated + /// with the RPC to support features that apply to it grpc::ServerContext* server_context() { return ctx_; } private: -- cgit v1.2.3