diff options
Diffstat (limited to 'include/grpcpp')
-rw-r--r-- | include/grpcpp/channel.h | 14 | ||||
-rw-r--r-- | include/grpcpp/create_channel.h | 21 | ||||
-rw-r--r-- | include/grpcpp/create_channel_posix.h | 17 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/client_interceptor.h | 44 | ||||
-rw-r--r-- | include/grpcpp/impl/codegen/interceptor.h | 67 | ||||
-rw-r--r-- | include/grpcpp/security/credentials.h | 32 | ||||
-rw-r--r-- | include/grpcpp/server.h | 25 |
7 files changed, 218 insertions, 2 deletions
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. |