GRPC C++  0.11.0.0
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rpc_service_method.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015, Google Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of Google Inc. nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 
34 #ifndef GRPCXX_IMPL_RPC_SERVICE_METHOD_H
35 #define GRPCXX_IMPL_RPC_SERVICE_METHOD_H
36 
37 #include <functional>
38 #include <map>
39 #include <memory>
40 #include <vector>
41 
42 #include <grpc++/impl/rpc_method.h>
43 #include <grpc++/support/config.h>
44 #include <grpc++/support/status.h>
46 
47 namespace grpc {
48 class ServerContext;
49 class StreamContextInterface;
50 
51 // TODO(rocking): we might need to split this file into multiple ones.
52 
53 // Base class for running an RPC handler.
55  public:
56  virtual ~MethodHandler() {}
58  HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req,
59  int max_size)
60  : call(c),
61  server_context(context),
62  request(req),
63  max_message_size(max_size) {}
66  // Handler required to grpc_byte_buffer_destroy this
67  grpc_byte_buffer* request;
69  };
70  virtual void RunHandler(const HandlerParameter& param) = 0;
71 };
72 
73 // A wrapper class of an application provided rpc method handler.
74 template <class ServiceType, class RequestType, class ResponseType>
75 class RpcMethodHandler : public MethodHandler {
76  public:
78  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
79  ResponseType*)> func,
80  ServiceType* service)
81  : func_(func), service_(service) {}
82 
83  void RunHandler(const HandlerParameter& param) GRPC_FINAL {
84  RequestType req;
86  param.request, &req, param.max_message_size);
87  ResponseType rsp;
88  if (status.ok()) {
89  status = func_(service_, param.server_context, &req, &rsp);
90  }
91 
92  GPR_ASSERT(!param.server_context->sent_initial_metadata_);
95  ops.SendInitialMetadata(param.server_context->initial_metadata_);
96  if (status.ok()) {
97  status = ops.SendMessage(rsp);
98  }
99  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
100  param.call->PerformOps(&ops);
101  param.call->cq()->Pluck(&ops);
102  }
103 
104  private:
105  // Application provided rpc handler function.
106  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
107  ResponseType*)> func_;
108  // The class the above handler function lives in.
109  ServiceType* service_;
110 };
111 
112 // A wrapper class of an application provided client streaming handler.
113 template <class ServiceType, class RequestType, class ResponseType>
114 class ClientStreamingHandler : public MethodHandler {
115  public:
117  std::function<Status(ServiceType*, ServerContext*,
118  ServerReader<RequestType>*, ResponseType*)> func,
119  ServiceType* service)
120  : func_(func), service_(service) {}
121 
123  ServerReader<RequestType> reader(param.call, param.server_context);
124  ResponseType rsp;
125  Status status = func_(service_, param.server_context, &reader, &rsp);
126 
127  GPR_ASSERT(!param.server_context->sent_initial_metadata_);
130  ops.SendInitialMetadata(param.server_context->initial_metadata_);
131  if (status.ok()) {
132  status = ops.SendMessage(rsp);
133  }
134  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
135  param.call->PerformOps(&ops);
136  param.call->cq()->Pluck(&ops);
137  }
138 
139  private:
140  std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
141  ResponseType*)> func_;
142  ServiceType* service_;
143 };
144 
145 // A wrapper class of an application provided server streaming handler.
146 template <class ServiceType, class RequestType, class ResponseType>
147 class ServerStreamingHandler : public MethodHandler {
148  public:
150  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
152  ServiceType* service)
153  : func_(func), service_(service) {}
154 
156  RequestType req;
158  param.request, &req, param.max_message_size);
159 
160  if (status.ok()) {
161  ServerWriter<ResponseType> writer(param.call, param.server_context);
162  status = func_(service_, param.server_context, &req, &writer);
163  }
164 
166  if (!param.server_context->sent_initial_metadata_) {
167  ops.SendInitialMetadata(param.server_context->initial_metadata_);
168  }
169  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
170  param.call->PerformOps(&ops);
171  param.call->cq()->Pluck(&ops);
172  }
173 
174  private:
175  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
177  ServiceType* service_;
178 };
179 
180 // A wrapper class of an application provided bidi-streaming handler.
181 template <class ServiceType, class RequestType, class ResponseType>
182 class BidiStreamingHandler : public MethodHandler {
183  public:
185  std::function<Status(ServiceType*, ServerContext*,
187  func,
188  ServiceType* service)
189  : func_(func), service_(service) {}
190 
193  param.server_context);
194  Status status = func_(service_, param.server_context, &stream);
195 
197  if (!param.server_context->sent_initial_metadata_) {
198  ops.SendInitialMetadata(param.server_context->initial_metadata_);
199  }
200  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
201  param.call->PerformOps(&ops);
202  param.call->cq()->Pluck(&ops);
203  }
204 
205  private:
206  std::function<Status(ServiceType*, ServerContext*,
208  ServiceType* service_;
209 };
210 
211 // Handle unknown method by returning UNIMPLEMENTED error.
213  public:
214  template <class T>
215  static void FillOps(ServerContext* context, T* ops) {
216  Status status(StatusCode::UNIMPLEMENTED, "");
217  if (!context->sent_initial_metadata_) {
218  ops->SendInitialMetadata(context->initial_metadata_);
219  context->sent_initial_metadata_ = true;
220  }
221  ops->ServerSendStatus(context->trailing_metadata_, status);
222  }
223 
226  FillOps(param.server_context, &ops);
227  param.call->PerformOps(&ops);
228  param.call->cq()->Pluck(&ops);
229  }
230 };
231 
232 // Server side rpc method class
233 class RpcServiceMethod : public RpcMethod {
234  public:
235  // Takes ownership of the handler
238  : RpcMethod(name, type), handler_(handler) {}
239 
240  MethodHandler* handler() { return handler_.get(); }
241 
242  private:
243  std::unique_ptr<MethodHandler> handler_;
244 };
245 
246 // This class contains all the method information for an rpc service. It is
247 // used for registering a service on a grpc server.
248 class RpcService {
249  public:
250  // Takes ownership.
251  void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
252 
253  RpcServiceMethod* GetMethod(int i) { return methods_[i].get(); }
254  int GetMethodCount() const { return methods_.size(); }
255 
256  private:
257  std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
258 };
259 
260 } // namespace grpc
261 
262 #endif // GRPCXX_IMPL_RPC_SERVICE_METHOD_H
Definition: rpc_service_method.h:54
void AddMethod(RpcServiceMethod *method)
Definition: rpc_service_method.h:251
RpcServiceMethod * GetMethod(int i)
Definition: rpc_service_method.h:253
ClientStreamingHandler(std::function< Status(ServiceType *, ServerContext *, ServerReader< RequestType > *, ResponseType *)> func, ServiceType *service)
Definition: rpc_service_method.h:116
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:224
ServerStreamingHandler(std::function< Status(ServiceType *, ServerContext *, const RequestType *, ServerWriter< ResponseType > *)> func, ServiceType *service)
Definition: rpc_service_method.h:149
int max_message_size
Definition: rpc_service_method.h:68
static void FillOps(ServerContext *context, T *ops)
Definition: rpc_service_method.h:215
ServerContext * server_context
Definition: rpc_service_method.h:65
RpcType
Definition: rpc_method.h:45
Call * call
Definition: rpc_service_method.h:64
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:155
Definition: call.h:353
#define GRPC_FINAL
Definition: config.h:71
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:122
Definition: completion_queue.h:55
Definition: rpc_service_method.h:233
Defines how to serialize and deserialize some type.
Definition: serialization_traits.h:64
Definition: rpc_service_method.h:212
Definition: call.h:179
Definition: rpc_service_method.h:248
virtual void RunHandler(const HandlerParameter &param)=0
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:191
Definition: call.h:560
Definition: completion_queue.h:61
RpcMethodHandler(std::function< Status(ServiceType *, ServerContext *, const RequestType *, ResponseType *)> func, ServiceType *service)
Definition: rpc_service_method.h:77
virtual ~MethodHandler()
Definition: rpc_service_method.h:56
Primary implementaiton of CallOpSetInterface.
Definition: call.h:502
Definition: server_context.h:89
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:83
Definition: completion_queue.h:57
Definition: rpc_method.h:43
BidiStreamingHandler(std::function< Status(ServiceType *, ServerContext *, ServerReaderWriter< ResponseType, RequestType > *)> func, ServiceType *service)
Definition: rpc_service_method.h:184
Server-side interface for bi-directional streaming.
Definition: completion_queue.h:59
bool ok() const
Is the status OK?
Definition: status.h:67
Definition: rpc_service_method.h:57
Did it work? If it didn't, why?
Definition: status.h:45
Operation is not implemented or not supported/enabled in this service.
Definition: status_code_enum.h:130
Definition: call.h:147
HandlerParameter(Call *c, ServerContext *context, grpc_byte_buffer *req, int max_size)
Definition: rpc_service_method.h:58
const char * name() const
Definition: rpc_method.h:61
MethodHandler * handler()
Definition: rpc_service_method.h:240
int GetMethodCount() const
Definition: rpc_service_method.h:254
grpc_byte_buffer * request
Definition: rpc_service_method.h:67
RpcServiceMethod(const char *name, RpcMethod::RpcType type, MethodHandler *handler)
Definition: rpc_service_method.h:236