diff options
author | Yash Tibrewal <yashkt@google.com> | 2018-10-03 09:27:15 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-03 09:27:15 -0700 |
commit | c3c40f8ec7b7e32c9e8dbffac38ceb33656f3da0 (patch) | |
tree | 166d3e5f596dee6abc0e22e19c2b8ddbd6ad7c5c | |
parent | 9f332fafbeddc6c377698bd6ef3651c73beb8a16 (diff) | |
parent | 130eeeaeb9fa5eedb2c627791fc52e6d3a25834c (diff) |
Merge pull request #16716 from yashykt/interceptors_initial
Create interfaces and initial plumbing for interception API
28 files changed, 398 insertions, 28 deletions
@@ -1982,6 +1982,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", @@ -1989,6 +1990,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/core_codegen_interface.h", "include/grpcpp/impl/codegen/create_auth_context.h", "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c91dd3664..dcd7adeebe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3075,6 +3075,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -3082,6 +3083,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -3644,6 +3646,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -3651,6 +3654,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4051,6 +4055,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -4058,6 +4063,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4230,6 +4236,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -4237,6 +4244,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4550,6 +4558,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -4557,6 +4566,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -5428,6 +5428,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -5435,6 +5436,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6006,6 +6008,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6013,6 +6016,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6398,6 +6402,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6405,6 +6410,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6554,6 +6560,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6561,6 +6568,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6879,6 +6887,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6886,6 +6895,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ diff --git a/build.yaml b/build.yaml index 3bc78d9299..6f81bf7afc 100644 --- a/build.yaml +++ b/build.yaml @@ -1171,6 +1171,7 @@ filegroups: - include/grpcpp/impl/codegen/channel_interface.h - include/grpcpp/impl/codegen/client_callback.h - include/grpcpp/impl/codegen/client_context.h + - include/grpcpp/impl/codegen/client_interceptor.h - include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/completion_queue.h - include/grpcpp/impl/codegen/completion_queue_tag.h @@ -1178,6 +1179,7 @@ filegroups: - include/grpcpp/impl/codegen/core_codegen_interface.h - include/grpcpp/impl/codegen/create_auth_context.h - include/grpcpp/impl/codegen/grpc_library.h + - include/grpcpp/impl/codegen/interceptor.h - include/grpcpp/impl/codegen/metadata_map.h - include/grpcpp/impl/codegen/method_handler_impl.h - include/grpcpp/impl/codegen/rpc_method.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index b51c14eba9..f2d9a814c3 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -132,6 +132,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/channel_interface.h', 'include/grpcpp/impl/codegen/client_callback.h', 'include/grpcpp/impl/codegen/client_context.h', + 'include/grpcpp/impl/codegen/client_interceptor.h', 'include/grpcpp/impl/codegen/client_unary_call.h', 'include/grpcpp/impl/codegen/completion_queue.h', 'include/grpcpp/impl/codegen/completion_queue_tag.h', @@ -139,6 +140,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/core_codegen_interface.h', 'include/grpcpp/impl/codegen/create_auth_context.h', 'include/grpcpp/impl/codegen/grpc_library.h', + 'include/grpcpp/impl/codegen/interceptor.h', 'include/grpcpp/impl/codegen/metadata_map.h', 'include/grpcpp/impl/codegen/method_handler_impl.h', 'include/grpcpp/impl/codegen/rpc_method.h', diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index f1dba5b8ad..b7c9e354de 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -24,6 +24,7 @@ #include <grpc/grpc.h> #include <grpcpp/impl/call.h> #include <grpcpp/impl/codegen/channel_interface.h> +#include <grpcpp/impl/codegen/client_interceptor.h> #include <grpcpp/impl/codegen/config.h> #include <grpcpp/impl/codegen/grpc_library.h> @@ -62,8 +63,14 @@ class Channel final : public ChannelInterface, friend class internal::BlockingUnaryCallImpl; friend void experimental::ChannelResetConnectionBackoff(Channel* channel); friend std::shared_ptr<Channel> CreateChannelInternal( - const grpc::string& host, grpc_channel* c_channel); - Channel(const grpc::string& host, grpc_channel* c_channel); + const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); + Channel(const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); internal::Call CreateCall(const internal::RpcMethod& method, ClientContext* context, @@ -91,6 +98,9 @@ class Channel final : public ChannelInterface, // It is _not owned_ by the channel; ownership belongs with its internal // shutdown callback tag (invoked when the CQ is fully shutdown). CompletionQueue* callback_cq_ = nullptr; + + std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> + interceptor_creators_; }; } // namespace grpc diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 7a505a7127..43188d09e7 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -22,6 +22,7 @@ #include <memory> #include <grpcpp/channel.h> +#include <grpcpp/impl/codegen/client_interceptor.h> #include <grpcpp/security/credentials.h> #include <grpcpp/support/channel_arguments.h> #include <grpcpp/support/config.h> @@ -53,6 +54,26 @@ std::shared_ptr<Channel> CreateCustomChannel( const std::shared_ptr<ChannelCredentials>& creds, const ChannelArguments& args); +namespace experimental { +/// Create a new \em custom \a Channel pointing to \a target with \a +/// interceptors being invoked per call. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr<Channel> CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr<ChannelCredentials>& creds, + const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); +} // namespace experimental } // namespace grpc #endif // GRPCPP_CREATE_CHANNEL_H diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index 9bf5acc45c..808514041b 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.h @@ -45,6 +45,23 @@ std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target, std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd( const grpc::string& target, int fd, const ChannelArguments& args); +namespace experimental { + +/// Create a new \a Channel communicating over given file descriptor with custom +/// channel arguments. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +/// \param args Options for channel creation. +/// \param interceptor_creators Vector of interceptor factory objects. +std::shared_ptr<Channel> CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); + +} // namespace experimental + #endif // GPR_SUPPORT_CHANNELS_FROM_FD } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h new file mode 100644 index 0000000000..f460c5ac0c --- /dev/null +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2018 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_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H +#define GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H + +#include <grpcpp/impl/codegen/interceptor.h> + +namespace grpc { +namespace experimental { +class ClientInterceptor { + public: + virtual ~ClientInterceptor() {} + + virtual void Intercept(InterceptorBatchMethods* methods) = 0; +}; + +class ClientRpcInfo {}; + +class ClientInterceptorFactoryInterface { + public: + virtual ~ClientInterceptorFactoryInterface() {} + virtual ClientInterceptor* CreateClientInterceptor(ClientRpcInfo* info) = 0; +}; + +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h new file mode 100644 index 0000000000..6402a3a946 --- /dev/null +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -0,0 +1,67 @@ +/* + * + * Copyright 2018 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_IMPL_CODEGEN_INTERCEPTOR_H +#define GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H + +namespace grpc { +namespace experimental { +class InterceptedMessage { + public: + template <class M> + bool Extract(M* msg); // returns false if definitely invalid extraction + template <class M> + M* MutableExtract(); + uint64_t length(); // length on wire +}; + +enum class InterceptionHookPoints { + /* The first two in this list are for clients and servers */ + PRE_SEND_INITIAL_METADATA, + PRE_SEND_MESSAGE, + PRE_SEND_STATUS /* server only */, + /* 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 */ + POST_RECV_INITIAL_METADATA, + POST_RECV_MESSAGE, + POST_RECV_STATUS /* client only */, + POST_RECV_CLOSE /* server only */, + NUM_INTERCEPTION_HOOKS +}; + +class InterceptorBatchMethods { + public: + virtual ~InterceptorBatchMethods(); + // Queries to check 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 + 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) + virtual void Hijack() = 0; +}; +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index bfadc15df5..8dfbdec3e6 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -24,6 +24,7 @@ #include <vector> #include <grpc/grpc_security_constants.h> +#include <grpcpp/impl/codegen/client_interceptor.h> #include <grpcpp/impl/codegen/grpc_library.h> #include <grpcpp/security/auth_context.h> #include <grpcpp/support/status.h> @@ -38,6 +39,18 @@ class SecureChannelCredentials; class CallCredentials; class SecureCallCredentials; +class ChannelCredentials; + +namespace experimental { +std::shared_ptr<Channel> CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr<ChannelCredentials>& creds, + const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); +} // namespace experimental + /// A channel credentials object encapsulates all the state needed by a client /// to authenticate with a server for a given channel. /// It can make various assertions, e.g., about the client’s identity, role @@ -62,8 +75,27 @@ class ChannelCredentials : private GrpcLibraryCodegen { const std::shared_ptr<ChannelCredentials>& creds, const ChannelArguments& args); + friend std::shared_ptr<Channel> + experimental::CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr<ChannelCredentials>& creds, + const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); + virtual std::shared_ptr<Channel> CreateChannel( const grpc::string& target, const ChannelArguments& args) = 0; + + // This function should have been a pure virtual function, but it is + // implemented as a virtual function so that it does not break API. + virtual std::shared_ptr<Channel> CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) { + return nullptr; + }; }; /// A call credentials object encapsulates the state needed by a client to diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 72544c0f0b..8d3e856502 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -28,6 +28,7 @@ #include <grpc/compression.h> #include <grpcpp/completion_queue.h> #include <grpcpp/impl/call.h> +#include <grpcpp/impl/codegen/client_interceptor.h> #include <grpcpp/impl/codegen/grpc_library.h> #include <grpcpp/impl/codegen/server_interface.h> #include <grpcpp/impl/rpc_service_method.h> @@ -99,6 +100,30 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// Establish a channel for in-process communication std::shared_ptr<Channel> InProcessChannel(const ChannelArguments& args); + /// NOTE: class experimental_type is not part of the public API of this class. + /// TODO(yashykt): Integrate into public API when this is no longer + /// experimental. + class experimental_type { + public: + explicit experimental_type(Server* server) : server_(server) {} + + /// Establish a channel for in-process communication with client + /// interceptors + std::shared_ptr<Channel> InProcessChannelWithInterceptors( + const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); + + private: + Server* server_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + protected: /// Register a service. This call does not take ownership of the service. /// The service must exist for the lifetime of the Server instance. diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 31c02893b1..2cab41b3f5 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -51,8 +51,16 @@ namespace grpc { static internal::GrpcLibraryInitializer g_gli_initializer; -Channel::Channel(const grpc::string& host, grpc_channel* channel) +Channel::Channel( + const grpc::string& host, grpc_channel* channel, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) : host_(host), c_channel_(channel) { + auto* vector = interceptor_creators.release(); + if (vector != nullptr) { + interceptor_creators_ = std::move(*vector); + } g_gli_initializer.summon(); } diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 67a46ce0e1..efdff6c265 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -39,11 +39,43 @@ std::shared_ptr<Channel> CreateCustomChannel( const std::shared_ptr<ChannelCredentials>& creds, const ChannelArguments& args) { GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. - return creds ? creds->CreateChannel(target, args) - : CreateChannelInternal( - "", grpc_lame_client_channel_create( - nullptr, GRPC_STATUS_INVALID_ARGUMENT, - "Invalid credentials.")); + return creds + ? creds->CreateChannel(target, args) + : CreateChannelInternal("", + grpc_lame_client_channel_create( + nullptr, GRPC_STATUS_INVALID_ARGUMENT, + "Invalid credentials."), + nullptr); } +namespace experimental { +/// Create a new \em custom \a Channel pointing to \a target with \a +/// interceptors being invoked per call. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr<Channel> CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr<ChannelCredentials>& creds, + const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) { + return creds + ? creds->CreateChannelWithInterceptors( + target, args, std::move(interceptor_creators)) + : CreateChannelInternal("", + grpc_lame_client_channel_create( + nullptr, GRPC_STATUS_INVALID_ARGUMENT, + "Invalid credentials."), + nullptr); +} +} // namespace experimental + } // namespace grpc diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index aa96edfcff..313d682aae 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -24,8 +24,12 @@ struct grpc_channel; namespace grpc { -std::shared_ptr<Channel> CreateChannelInternal(const grpc::string& host, - grpc_channel* c_channel) { - return std::shared_ptr<Channel>(new Channel(host, c_channel)); +std::shared_ptr<Channel> CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) { + return std::shared_ptr<Channel>( + new Channel(host, c_channel, std::move(interceptor_creators))); } } // namespace grpc diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index 86e8167277..512fc22866 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -21,6 +21,7 @@ #include <memory> +#include <grpcpp/impl/codegen/client_interceptor.h> #include <grpcpp/support/config.h> struct grpc_channel; @@ -28,8 +29,11 @@ struct grpc_channel; namespace grpc { class Channel; -std::shared_ptr<Channel> CreateChannelInternal(const grpc::string& host, - grpc_channel* c_channel); +std::shared_ptr<Channel> CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators); } // namespace grpc diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index f9285c9b28..8d775e7a87 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -33,7 +33,8 @@ std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target, internal::GrpcLibrary init_lib; init_lib.init(); return CreateChannelInternal( - "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr)); + "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), + nullptr); } std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd( @@ -42,10 +43,31 @@ std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd( init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal("", grpc_insecure_channel_create_from_fd( - target.c_str(), fd, &channel_args)); + return CreateChannelInternal( + "", + grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), + nullptr); +} + +namespace experimental { + +std::shared_ptr<Channel> CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) { + internal::GrpcLibrary init_lib; + init_lib.init(); + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return CreateChannelInternal( + "", + grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), + std::move(interceptor_creators)); } +} // namespace experimental + #endif // GPR_SUPPORT_CHANNELS_FROM_FD } // namespace grpc diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index 5c65ad05ea..09a76b428c 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -31,16 +31,25 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { std::shared_ptr<grpc::Channel> CreateChannel( const string& target, const grpc::ChannelArguments& args) override { - grpc_channel_args channel_args; - args.SetChannelArgs(&channel_args); - return CreateChannelInternal( - "", grpc_cronet_secure_channel_create(engine_, target.c_str(), - &channel_args, nullptr)); + return CreateChannelWithInterceptors(target, args, nullptr); } SecureChannelCredentials* AsSecureCredentials() override { return nullptr; } private: + std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) override { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return CreateChannelInternal( + "", + grpc_cronet_secure_channel_create(engine_, target.c_str(), + &channel_args, nullptr), + std::move(interceptor_creators)); + } void* engine_; }; diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 04dc5c0bcc..b816e0c59a 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -32,11 +32,20 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: std::shared_ptr<grpc::Channel> CreateChannel( const string& target, const grpc::ChannelArguments& args) override { + return CreateChannelWithInterceptors(target, args, nullptr); + } + + std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); return CreateChannelInternal( "", - grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr)); + grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr), + std::move(interceptor_creators)); } SecureChannelCredentials* AsSecureCredentials() override { return nullptr; } diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index e48fbeb86d..d1cd78e755 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -36,12 +36,22 @@ SecureChannelCredentials::SecureChannelCredentials( std::shared_ptr<grpc::Channel> SecureChannelCredentials::CreateChannel( const string& target, const grpc::ChannelArguments& args) { + return CreateChannelWithInterceptors(target, args, nullptr); +} + +std::shared_ptr<grpc::Channel> +SecureChannelCredentials::CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); return CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, - nullptr)); + nullptr), + std::move(interceptor_creators)); } SecureCallCredentials::SecureCallCredentials(grpc_call_credentials* c_creds) diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 85cb54227c..bfb6e17ee9 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -36,9 +36,15 @@ class SecureChannelCredentials final : public ChannelCredentials { std::shared_ptr<grpc::Channel> CreateChannel( const string& target, const grpc::ChannelArguments& args) override; + SecureChannelCredentials* AsSecureCredentials() override { return this; } private: + std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 36f7eb81f9..7c764f4bce 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -473,7 +473,21 @@ std::shared_ptr<Channel> Server::InProcessChannel( const ChannelArguments& args) { grpc_channel_args channel_args = args.c_channel_args(); return CreateChannelInternal( - "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr)); + "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), + nullptr); +} + +std::shared_ptr<Channel> +Server::experimental_type::InProcessChannelWithInterceptors( + const ChannelArguments& args, + std::unique_ptr<std::vector< + std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>> + interceptor_creators) { + grpc_channel_args channel_args = args.c_channel_args(); + return CreateChannelInternal( + "inproc", + grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), + std::move(interceptor_creators)); } static grpc_server_register_method_payload_handling PayloadHandlingForMethod( diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 9516b2e3e2..389b888084 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -133,8 +133,10 @@ static void BM_LameChannelCallCreateCpp(benchmark::State& state) { TrackCounters track_counters; auto stub = grpc::testing::EchoTestService::NewStub(grpc::CreateChannelInternal( - "", grpc_lame_client_channel_create( - "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah"))); + "", + grpc_lame_client_channel_create("localhost:1234", + GRPC_STATUS_UNAUTHENTICATED, "blah"), + nullptr)); grpc::CompletionQueue cq; grpc::testing::EchoRequest send_request; grpc::testing::EchoResponse recv_response; diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index d390ae08f6..7188a2a28a 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -218,7 +218,7 @@ class EndpointPairFixture : public BaseFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport_); grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr); - channel_ = CreateChannelInternal("", channel); + channel_ = CreateChannelInternal("", channel, nullptr); } } diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index 0ea3181f7e..7b51260e5b 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -118,7 +118,7 @@ class EndpointPairFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - channel_ = CreateChannelInternal("", channel); + channel_ = CreateChannelInternal("", channel, nullptr); } } diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 3b7fd1fa8e..97599be443 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -949,6 +949,7 @@ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ +include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -958,6 +959,7 @@ include/grpcpp/impl/codegen/core_codegen.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ +include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c1bcdfd3d0..c852b29fce 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -950,6 +950,7 @@ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ +include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -960,6 +961,7 @@ include/grpcpp/impl/codegen/core_codegen.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ +include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 3df0ff58dc..8749593ed5 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11071,6 +11071,7 @@ "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", @@ -11078,6 +11079,7 @@ "include/grpcpp/impl/codegen/core_codegen_interface.h", "include/grpcpp/impl/codegen/create_auth_context.h", "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", @@ -11139,6 +11141,7 @@ "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", @@ -11146,6 +11149,7 @@ "include/grpcpp/impl/codegen/core_codegen_interface.h", "include/grpcpp/impl/codegen/create_auth_context.h", "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", |