xref: /aosp_15_r20/external/grpc-grpc/include/grpcpp/impl/rpc_service_method.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2016 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #ifndef GRPCPP_IMPL_RPC_SERVICE_METHOD_H
20 #define GRPCPP_IMPL_RPC_SERVICE_METHOD_H
21 
22 #include <climits>
23 #include <functional>
24 #include <map>
25 #include <memory>
26 #include <vector>
27 
28 #include <grpc/support/log.h>
29 #include <grpcpp/impl/rpc_method.h>
30 #include <grpcpp/support/byte_buffer.h>
31 #include <grpcpp/support/config.h>
32 #include <grpcpp/support/status.h>
33 
34 namespace grpc {
35 class ServerContextBase;
36 namespace internal {
37 /// Base class for running an RPC handler.
38 class MethodHandler {
39  public:
~MethodHandler()40   virtual ~MethodHandler() {}
41   struct HandlerParameter {
42     /// Constructor for HandlerParameter
43     ///
44     /// \param c : the gRPC Call structure for this server call
45     /// \param context : the ServerContext structure for this server call
46     /// \param req : the request payload, if appropriate for this RPC
47     /// \param req_status : the request status after any interceptors have run
48     /// \param handler_data: internal data for the handler.
49     /// \param requester : used only by the callback API. It is a function
50     ///        called by the RPC Controller to request another RPC (and also
51     ///        to set up the state required to make that request possible)
HandlerParameterHandlerParameter52     HandlerParameter(Call* c, grpc::ServerContextBase* context, void* req,
53                      Status req_status, void* handler_data,
54                      std::function<void()> requester)
55         : call(c),
56           server_context(context),
57           request(req),
58           status(req_status),
59           internal_data(handler_data),
60           call_requester(std::move(requester)) {}
~HandlerParameterHandlerParameter61     ~HandlerParameter() {}
62     Call* const call;
63     grpc::ServerContextBase* const server_context;
64     void* const request;
65     const Status status;
66     void* const internal_data;
67     const std::function<void()> call_requester;
68   };
69   virtual void RunHandler(const HandlerParameter& param) = 0;
70 
71   // Returns a pointer to the deserialized request. \a status reflects the
72   // result of deserialization. This pointer and the status should be filled in
73   // a HandlerParameter and passed to RunHandler. It is illegal to access the
74   // pointer after calling RunHandler. Ownership of the deserialized request is
75   // retained by the handler. Returns nullptr if deserialization failed.
Deserialize(grpc_call *,grpc_byte_buffer * req,Status *,void **)76   virtual void* Deserialize(grpc_call* /*call*/, grpc_byte_buffer* req,
77                             Status* /*status*/, void** /*handler_data*/) {
78     GPR_ASSERT(req == nullptr);
79     return nullptr;
80   }
81 };
82 
83 /// Server side rpc method class
84 class RpcServiceMethod : public RpcMethod {
85  public:
86   /// Takes ownership of the handler
RpcServiceMethod(const char * name,RpcMethod::RpcType type,MethodHandler * handler)87   RpcServiceMethod(const char* name, RpcMethod::RpcType type,
88                    MethodHandler* handler)
89       : RpcMethod(name, type),
90         server_tag_(nullptr),
91         api_type_(ApiType::SYNC),
92         handler_(handler) {}
93 
94   enum class ApiType {
95     SYNC,
96     ASYNC,
97     RAW,
98     CALL_BACK,  // not CALLBACK because that is reserved in Windows
99     RAW_CALL_BACK,
100   };
101 
set_server_tag(void * tag)102   void set_server_tag(void* tag) { server_tag_ = tag; }
server_tag()103   void* server_tag() const { return server_tag_; }
104   /// if MethodHandler is nullptr, then this is an async method
handler()105   MethodHandler* handler() const { return handler_.get(); }
api_type()106   ApiType api_type() const { return api_type_; }
SetHandler(MethodHandler * handler)107   void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
SetServerApiType(RpcServiceMethod::ApiType type)108   void SetServerApiType(RpcServiceMethod::ApiType type) {
109     if ((api_type_ == ApiType::SYNC) &&
110         (type == ApiType::ASYNC || type == ApiType::RAW)) {
111       // this marks this method as async
112       handler_.reset();
113     } else if (api_type_ != ApiType::SYNC) {
114       // this is not an error condition, as it allows users to declare a server
115       // like WithRawMethod_foo<AsyncService>. However since it
116       // overwrites behavior, it should be logged.
117       gpr_log(
118           GPR_INFO,
119           "You are marking method %s as '%s', even though it was "
120           "previously marked '%s'. This behavior will overwrite the original "
121           "behavior. If you expected this then ignore this message.",
122           name(), TypeToString(api_type_), TypeToString(type));
123     }
124     api_type_ = type;
125   }
126 
127  private:
128   void* server_tag_;
129   ApiType api_type_;
130   std::unique_ptr<MethodHandler> handler_;
131 
TypeToString(RpcServiceMethod::ApiType type)132   const char* TypeToString(RpcServiceMethod::ApiType type) {
133     switch (type) {
134       case ApiType::SYNC:
135         return "sync";
136       case ApiType::ASYNC:
137         return "async";
138       case ApiType::RAW:
139         return "raw";
140       case ApiType::CALL_BACK:
141         return "callback";
142       case ApiType::RAW_CALL_BACK:
143         return "raw_callback";
144       default:
145         GPR_UNREACHABLE_CODE(return "unknown");
146     }
147   }
148 };
149 }  // namespace internal
150 
151 }  // namespace grpc
152 
153 #endif  // GRPCPP_IMPL_RPC_SERVICE_METHOD_H
154