1*cc02d7e2SAndroid Build Coastguard Worker // 2*cc02d7e2SAndroid Build Coastguard Worker // 3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors. 4*cc02d7e2SAndroid Build Coastguard Worker // 5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at 8*cc02d7e2SAndroid Build Coastguard Worker // 9*cc02d7e2SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 10*cc02d7e2SAndroid Build Coastguard Worker // 11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License. 16*cc02d7e2SAndroid Build Coastguard Worker // 17*cc02d7e2SAndroid Build Coastguard Worker // 18*cc02d7e2SAndroid Build Coastguard Worker 19*cc02d7e2SAndroid Build Coastguard Worker #ifndef GRPCPP_GENERIC_GENERIC_STUB_H 20*cc02d7e2SAndroid Build Coastguard Worker #define GRPCPP_GENERIC_GENERIC_STUB_H 21*cc02d7e2SAndroid Build Coastguard Worker 22*cc02d7e2SAndroid Build Coastguard Worker #include <functional> 23*cc02d7e2SAndroid Build Coastguard Worker 24*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/client_context.h> 25*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/rpc_method.h> 26*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/async_stream.h> 27*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/async_unary_call.h> 28*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/byte_buffer.h> 29*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/client_callback.h> 30*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/status.h> 31*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/stub_options.h> 32*cc02d7e2SAndroid Build Coastguard Worker 33*cc02d7e2SAndroid Build Coastguard Worker namespace grpc { 34*cc02d7e2SAndroid Build Coastguard Worker 35*cc02d7e2SAndroid Build Coastguard Worker class CompletionQueue; 36*cc02d7e2SAndroid Build Coastguard Worker 37*cc02d7e2SAndroid Build Coastguard Worker typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer> 38*cc02d7e2SAndroid Build Coastguard Worker GenericClientAsyncReaderWriter; 39*cc02d7e2SAndroid Build Coastguard Worker typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader; 40*cc02d7e2SAndroid Build Coastguard Worker 41*cc02d7e2SAndroid Build Coastguard Worker /// Generic stubs provide a type-unaware interface to call gRPC methods 42*cc02d7e2SAndroid Build Coastguard Worker /// by name. In practice, the Request and Response types should be basic 43*cc02d7e2SAndroid Build Coastguard Worker /// types like grpc::ByteBuffer or proto::MessageLite (the base protobuf). 44*cc02d7e2SAndroid Build Coastguard Worker template <class RequestType, class ResponseType> 45*cc02d7e2SAndroid Build Coastguard Worker class TemplatedGenericStub final { 46*cc02d7e2SAndroid Build Coastguard Worker public: TemplatedGenericStub(std::shared_ptr<grpc::ChannelInterface> channel)47*cc02d7e2SAndroid Build Coastguard Worker explicit TemplatedGenericStub(std::shared_ptr<grpc::ChannelInterface> channel) 48*cc02d7e2SAndroid Build Coastguard Worker : channel_(channel) {} 49*cc02d7e2SAndroid Build Coastguard Worker 50*cc02d7e2SAndroid Build Coastguard Worker /// Setup a call to a named method \a method using \a context, but don't 51*cc02d7e2SAndroid Build Coastguard Worker /// start it. Let it be started explicitly with StartCall and a tag. 52*cc02d7e2SAndroid Build Coastguard Worker /// The return value only indicates whether or not registration of the call 53*cc02d7e2SAndroid Build Coastguard Worker /// succeeded (i.e. the call won't proceed if the return value is nullptr). 54*cc02d7e2SAndroid Build Coastguard Worker std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>> PrepareCall(ClientContext * context,const std::string & method,grpc::CompletionQueue * cq)55*cc02d7e2SAndroid Build Coastguard Worker PrepareCall(ClientContext* context, const std::string& method, 56*cc02d7e2SAndroid Build Coastguard Worker grpc::CompletionQueue* cq) { 57*cc02d7e2SAndroid Build Coastguard Worker return CallInternal(channel_.get(), context, method, /*options=*/{}, cq, 58*cc02d7e2SAndroid Build Coastguard Worker false, nullptr); 59*cc02d7e2SAndroid Build Coastguard Worker } 60*cc02d7e2SAndroid Build Coastguard Worker 61*cc02d7e2SAndroid Build Coastguard Worker /// Setup a unary call to a named method \a method using \a context, and don't 62*cc02d7e2SAndroid Build Coastguard Worker /// start it. Let it be started explicitly with StartCall. 63*cc02d7e2SAndroid Build Coastguard Worker /// The return value only indicates whether or not registration of the call 64*cc02d7e2SAndroid Build Coastguard Worker /// succeeded (i.e. the call won't proceed if the return value is nullptr). PrepareUnaryCall(ClientContext * context,const std::string & method,const RequestType & request,grpc::CompletionQueue * cq)65*cc02d7e2SAndroid Build Coastguard Worker std::unique_ptr<ClientAsyncResponseReader<ResponseType>> PrepareUnaryCall( 66*cc02d7e2SAndroid Build Coastguard Worker ClientContext* context, const std::string& method, 67*cc02d7e2SAndroid Build Coastguard Worker const RequestType& request, grpc::CompletionQueue* cq) { 68*cc02d7e2SAndroid Build Coastguard Worker return std::unique_ptr<ClientAsyncResponseReader<ResponseType>>( 69*cc02d7e2SAndroid Build Coastguard Worker internal::ClientAsyncResponseReaderHelper::Create<ResponseType>( 70*cc02d7e2SAndroid Build Coastguard Worker channel_.get(), cq, 71*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod(method.c_str(), 72*cc02d7e2SAndroid Build Coastguard Worker /*suffix_for_stats=*/nullptr, 73*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod::NORMAL_RPC), 74*cc02d7e2SAndroid Build Coastguard Worker context, request)); 75*cc02d7e2SAndroid Build Coastguard Worker } 76*cc02d7e2SAndroid Build Coastguard Worker 77*cc02d7e2SAndroid Build Coastguard Worker /// DEPRECATED for multi-threaded use 78*cc02d7e2SAndroid Build Coastguard Worker /// Begin a call to a named method \a method using \a context. 79*cc02d7e2SAndroid Build Coastguard Worker /// A tag \a tag will be delivered to \a cq when the call has been started 80*cc02d7e2SAndroid Build Coastguard Worker /// (i.e, initial metadata has been sent). 81*cc02d7e2SAndroid Build Coastguard Worker /// The return value only indicates whether or not registration of the call 82*cc02d7e2SAndroid Build Coastguard Worker /// succeeded (i.e. the call won't proceed if the return value is nullptr). Call(ClientContext * context,const std::string & method,grpc::CompletionQueue * cq,void * tag)83*cc02d7e2SAndroid Build Coastguard Worker std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>> Call( 84*cc02d7e2SAndroid Build Coastguard Worker ClientContext* context, const std::string& method, 85*cc02d7e2SAndroid Build Coastguard Worker grpc::CompletionQueue* cq, void* tag) { 86*cc02d7e2SAndroid Build Coastguard Worker return CallInternal(channel_.get(), context, method, /*options=*/{}, cq, 87*cc02d7e2SAndroid Build Coastguard Worker true, tag); 88*cc02d7e2SAndroid Build Coastguard Worker } 89*cc02d7e2SAndroid Build Coastguard Worker 90*cc02d7e2SAndroid Build Coastguard Worker /// Setup and start a unary call to a named method \a method using 91*cc02d7e2SAndroid Build Coastguard Worker /// \a context and specifying the \a request and \a response buffers. UnaryCall(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,std::function<void (grpc::Status)> on_completion)92*cc02d7e2SAndroid Build Coastguard Worker void UnaryCall(ClientContext* context, const std::string& method, 93*cc02d7e2SAndroid Build Coastguard Worker StubOptions options, const RequestType* request, 94*cc02d7e2SAndroid Build Coastguard Worker ResponseType* response, 95*cc02d7e2SAndroid Build Coastguard Worker std::function<void(grpc::Status)> on_completion) { 96*cc02d7e2SAndroid Build Coastguard Worker UnaryCallInternal(context, method, options, request, response, 97*cc02d7e2SAndroid Build Coastguard Worker std::move(on_completion)); 98*cc02d7e2SAndroid Build Coastguard Worker } 99*cc02d7e2SAndroid Build Coastguard Worker 100*cc02d7e2SAndroid Build Coastguard Worker /// Setup a unary call to a named method \a method using 101*cc02d7e2SAndroid Build Coastguard Worker /// \a context and specifying the \a request and \a response buffers. 102*cc02d7e2SAndroid Build Coastguard Worker /// Like any other reactor-based RPC, it will not be activated until 103*cc02d7e2SAndroid Build Coastguard Worker /// StartCall is invoked on its reactor. PrepareUnaryCall(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,ClientUnaryReactor * reactor)104*cc02d7e2SAndroid Build Coastguard Worker void PrepareUnaryCall(ClientContext* context, const std::string& method, 105*cc02d7e2SAndroid Build Coastguard Worker StubOptions options, const RequestType* request, 106*cc02d7e2SAndroid Build Coastguard Worker ResponseType* response, ClientUnaryReactor* reactor) { 107*cc02d7e2SAndroid Build Coastguard Worker PrepareUnaryCallInternal(context, method, options, request, response, 108*cc02d7e2SAndroid Build Coastguard Worker reactor); 109*cc02d7e2SAndroid Build Coastguard Worker } 110*cc02d7e2SAndroid Build Coastguard Worker 111*cc02d7e2SAndroid Build Coastguard Worker /// Setup a call to a named method \a method using \a context and tied to 112*cc02d7e2SAndroid Build Coastguard Worker /// \a reactor . Like any other bidi streaming RPC, it will not be activated 113*cc02d7e2SAndroid Build Coastguard Worker /// until StartCall is invoked on its reactor. PrepareBidiStreamingCall(ClientContext * context,const std::string & method,StubOptions options,ClientBidiReactor<RequestType,ResponseType> * reactor)114*cc02d7e2SAndroid Build Coastguard Worker void PrepareBidiStreamingCall( 115*cc02d7e2SAndroid Build Coastguard Worker ClientContext* context, const std::string& method, StubOptions options, 116*cc02d7e2SAndroid Build Coastguard Worker ClientBidiReactor<RequestType, ResponseType>* reactor) { 117*cc02d7e2SAndroid Build Coastguard Worker PrepareBidiStreamingCallInternal(context, method, options, reactor); 118*cc02d7e2SAndroid Build Coastguard Worker } 119*cc02d7e2SAndroid Build Coastguard Worker 120*cc02d7e2SAndroid Build Coastguard Worker private: 121*cc02d7e2SAndroid Build Coastguard Worker std::shared_ptr<grpc::ChannelInterface> channel_; 122*cc02d7e2SAndroid Build Coastguard Worker UnaryCallInternal(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,std::function<void (grpc::Status)> on_completion)123*cc02d7e2SAndroid Build Coastguard Worker void UnaryCallInternal(ClientContext* context, const std::string& method, 124*cc02d7e2SAndroid Build Coastguard Worker StubOptions options, const RequestType* request, 125*cc02d7e2SAndroid Build Coastguard Worker ResponseType* response, 126*cc02d7e2SAndroid Build Coastguard Worker std::function<void(grpc::Status)> on_completion) { 127*cc02d7e2SAndroid Build Coastguard Worker internal::CallbackUnaryCall( 128*cc02d7e2SAndroid Build Coastguard Worker channel_.get(), 129*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod(method.c_str(), options.suffix_for_stats(), 130*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod::NORMAL_RPC), 131*cc02d7e2SAndroid Build Coastguard Worker context, request, response, std::move(on_completion)); 132*cc02d7e2SAndroid Build Coastguard Worker } 133*cc02d7e2SAndroid Build Coastguard Worker PrepareUnaryCallInternal(ClientContext * context,const std::string & method,StubOptions options,const RequestType * request,ResponseType * response,ClientUnaryReactor * reactor)134*cc02d7e2SAndroid Build Coastguard Worker void PrepareUnaryCallInternal(ClientContext* context, 135*cc02d7e2SAndroid Build Coastguard Worker const std::string& method, StubOptions options, 136*cc02d7e2SAndroid Build Coastguard Worker const RequestType* request, 137*cc02d7e2SAndroid Build Coastguard Worker ResponseType* response, 138*cc02d7e2SAndroid Build Coastguard Worker ClientUnaryReactor* reactor) { 139*cc02d7e2SAndroid Build Coastguard Worker internal::ClientCallbackUnaryFactory::Create<RequestType, ResponseType>( 140*cc02d7e2SAndroid Build Coastguard Worker channel_.get(), 141*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod(method.c_str(), options.suffix_for_stats(), 142*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod::NORMAL_RPC), 143*cc02d7e2SAndroid Build Coastguard Worker context, request, response, reactor); 144*cc02d7e2SAndroid Build Coastguard Worker } 145*cc02d7e2SAndroid Build Coastguard Worker PrepareBidiStreamingCallInternal(ClientContext * context,const std::string & method,StubOptions options,ClientBidiReactor<RequestType,ResponseType> * reactor)146*cc02d7e2SAndroid Build Coastguard Worker void PrepareBidiStreamingCallInternal( 147*cc02d7e2SAndroid Build Coastguard Worker ClientContext* context, const std::string& method, StubOptions options, 148*cc02d7e2SAndroid Build Coastguard Worker ClientBidiReactor<RequestType, ResponseType>* reactor) { 149*cc02d7e2SAndroid Build Coastguard Worker internal::ClientCallbackReaderWriterFactory<RequestType, ResponseType>:: 150*cc02d7e2SAndroid Build Coastguard Worker Create(channel_.get(), 151*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod( 152*cc02d7e2SAndroid Build Coastguard Worker method.c_str(), options.suffix_for_stats(), 153*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod::BIDI_STREAMING), 154*cc02d7e2SAndroid Build Coastguard Worker context, reactor); 155*cc02d7e2SAndroid Build Coastguard Worker } 156*cc02d7e2SAndroid Build Coastguard Worker 157*cc02d7e2SAndroid Build Coastguard Worker std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>> CallInternal(grpc::ChannelInterface * channel,ClientContext * context,const std::string & method,StubOptions options,grpc::CompletionQueue * cq,bool start,void * tag)158*cc02d7e2SAndroid Build Coastguard Worker CallInternal(grpc::ChannelInterface* channel, ClientContext* context, 159*cc02d7e2SAndroid Build Coastguard Worker const std::string& method, StubOptions options, 160*cc02d7e2SAndroid Build Coastguard Worker grpc::CompletionQueue* cq, bool start, void* tag) { 161*cc02d7e2SAndroid Build Coastguard Worker return std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>>( 162*cc02d7e2SAndroid Build Coastguard Worker internal::ClientAsyncReaderWriterFactory<RequestType, ResponseType>:: 163*cc02d7e2SAndroid Build Coastguard Worker Create(channel, cq, 164*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod( 165*cc02d7e2SAndroid Build Coastguard Worker method.c_str(), options.suffix_for_stats(), 166*cc02d7e2SAndroid Build Coastguard Worker grpc::internal::RpcMethod::BIDI_STREAMING), 167*cc02d7e2SAndroid Build Coastguard Worker context, start, tag)); 168*cc02d7e2SAndroid Build Coastguard Worker } 169*cc02d7e2SAndroid Build Coastguard Worker }; 170*cc02d7e2SAndroid Build Coastguard Worker 171*cc02d7e2SAndroid Build Coastguard Worker typedef TemplatedGenericStub<grpc::ByteBuffer, grpc::ByteBuffer> GenericStub; 172*cc02d7e2SAndroid Build Coastguard Worker 173*cc02d7e2SAndroid Build Coastguard Worker } // namespace grpc 174*cc02d7e2SAndroid Build Coastguard Worker 175*cc02d7e2SAndroid Build Coastguard Worker #endif // GRPCPP_GENERIC_GENERIC_STUB_H 176