MIRA
RPCServer.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_RPCSERVER_H_
48 #define _MIRA_RPCSERVER_H_
49 
50 #include <functional>
51 
52 #ifndef Q_MOC_RUN
53 #include <boost/preprocessor/repetition.hpp>
54 #include <boost/thread/mutex.hpp>
55 #endif
56 
57 #include <platform/Environment.h>
58 
60 
61 #include <error/LoggingCore.h>
62 #include <error/LoggingAux.h>
63 
64 #include <rpc/RPCSignature.h>
65 #include <rpc/RPCInvoker.h>
66 #include <rpc/RPCError.h>
67 #include <rpc/BinaryRPCBackend.h>
68 #include <rpc/JSONRPCBackend.h>
69 
71 
72 #include <utils/ToString.h>
73 
74 namespace mira {
75 
77 
108 {
109 public:
110 
116  {
118 
119  ParameterInfo(const std::string& iName, const std::string& iDescription)
120  : name(iName), description(iDescription) {}
121 
122  template<typename Reflector>
123  void reflect(Reflector& r)
124  {
125  r.member("Name", name, "");
126  r.member("Description", description, "");
127  }
128 
130  std::string name;
131 
133  std::string description;
134 
135  public:
136 
137  friend std::ostream& operator<<(std::ostream& s, const ParameterInfo& v)
138  {
139  s << v.name << " \t: " << v.description;
140  return s;
141  }
142  };
143 
144  typedef std::vector<ParameterInfo> ParameterDescriptions;
145 
150  struct MethodInfo
151  {
152  class ReflectMethodParamsDocumentation : public Singleton<ReflectMethodParamsDocumentation>
153  {
155 
156  protected:
157  ReflectMethodParamsDocumentation() : mReflectMethodParamsDocumentation(true)
158  {
159  try {
160  resolveEnvironmentVariable("MIRA_RPC_METHODS_REFLECT_NO_PARAMS_DOCUMENTATION");
161  // if resolve succeeds (--> variable exists), do not reflect version and parameter documentation
162  mReflectMethodParamsDocumentation = false;
163  MIRA_LOG(WARNING) << "Found definition of environment variable "
164  << "MIRA_RPC_METHODS_REFLECT_NO_PARAMS_DOCUMENTATION "
165  << "- RPC parameter documentation will not be shared with "
166  << "remote frameworks (ensuring backward compatibility)";
167  }
168  catch(...) {}
169  }
170 
171  public:
172  static bool enabled() { return instance().mReflectMethodParamsDocumentation; }
173 
174  private:
175  bool mReflectMethodParamsDocumentation;
176  };
177 
179 
180  MethodInfo(const RPCSignature& iSignature, const std::string& iComment) :
181  signature(iSignature), comment(iComment), parameterSamplesDefault(true) {}
182 
183  MethodInfo(const RPCSignature& iSignature, const std::string& iComment,
184  const ParameterDescriptions& iParameterDescriptions) :
185  signature(iSignature), comment(iComment),
186  parameterDesc(iParameterDescriptions), parameterSamplesDefault(true) {}
187 
188  template<typename Reflector>
189  void reflect(Reflector& r)
190  {
191  serialization::VersionType version = r.version(3, this);
192 
193  r.member("Signature", signature, "");
194  r.member("Comment", comment, "");
195 
196  if (version >= 2) {
197  r.member("ParameterDescriptions", parameterDesc, "");
198  r.member("ParameterSamples", parameterSamples, "");
199 
200  if (version >= 3)
201  r.member("ParameterSamplesDefault", parameterSamplesDefault, "");
202  }
203  }
204 
205  template<typename Reflector>
206  void reflectBinaryV0(Reflector& r)
207  {
208  serialization::VersionType version = 0;
209 
211  version = r.version(2, this); // version 3 did not exist with serialization format v0
212 
213  r.member("Signature", signature, "");
214  r.member("Comment", comment, "");
215 
216  if (version >= 2) {
217  r.member("ParameterDescriptions", parameterDesc, "");
218  r.member("ParameterSamples", parameterSamples, "");
219  }
220  }
221 
222  // Specialization for serialization format v0
223  template<typename Stream>
225  {
226  reflectBinaryV0(r);
227  }
228 
229  // Specialization for deserialization format v0
230  template<typename Stream>
232  {
233  reflectBinaryV0(r);
234  }
235 
236  bool operator<(const MethodInfo& rhs) const {
237  return signature < rhs.signature;
238  }
239 
240  bool operator==(const MethodInfo& rhs) const {
241  return signature==rhs.signature;
242  }
243 
244  std::string extendedSignature() const;
245 
247  std::string parameterDescriptions(const std::string& prefix = "") const;
248 
249  std::string sampleParametersSet(bool formatted = false) const;
250 
253 
255  std::string comment;
256 
259 
262  std::list<json::Value> parameterSamples;
263  };
264 
270  struct Method : public MethodInfo
271  {
272  Method(const RPCSignature& signature, const std::string& comment) :
274 
275  Method(const RPCSignature& signature, const std::string& comment,
278 
280  template<typename Backend>
282  {
283  invokers.insert(std::make_pair(typeId<Backend>(),
284  boost::shared_ptr<RPCInvoker>(invoker)));
285  }
286 
288  std::map<int, boost::shared_ptr<RPCInvoker>> invokers;
289  };
290 
291  typedef std::set<Method> MethodSet;
292 
293  typedef std::set<MethodInfo> MethodInfoSet;
294 
295 
301  template <typename TMethodSet>
302  struct ServiceInfo
303  {
304  ServiceInfo(const std::string& iName="") :
305  name(iName) {}
306 
307  template<typename Reflector>
308  void reflect(Reflector& r)
309  {
310  r.member("Name", name, "");
311  r.member("Methods", methods, "");
312  r.member("Interfaces", interfaces, "");
313  }
314 
316  std::string name;
318  TMethodSet methods;
320  std::set<std::string> interfaces;
321  };
322 
324 
325  typedef std::map<std::string, Service> ServiceMap;
326 
327 
339  class RPCReflector : public ReflectorInterface<RPCReflector>
340  {
341  public:
342 
354  RPCReflector(Service& iService) :
355  mService(iService) {}
356 
357 
358  public:
359 
361  template <typename Base>
362  void reflectBase(Base& base) {
363  // simplified (compared to AbstractReflector), but should be enough for the RPCServer
364  base.reflect(*this);
365  }
366 
367  public:
368 
370  const std::set<RPCSignature>& getAddedMethods() const {
371  return mAddedMethods;
372  }
373 
375  const std::set<std::string>& getAddedInterfaces() const {
376  return mAddedInterfaces;
377  }
378 
379  public:
380 
381  void interface(const char* name) {
382  if(mService.interfaces.insert(std::string(name)).second)
383  mAddedInterfaces.insert(std::string(name));
384  }
385 
386  /*
387  The following code uses boost preprocessor for generating the method(name, P1 ... Pn)
388  methods. Read documentation of boost preprocessor or use Eclipse to expand
389  the BOOST_PP_REPEAT macro below in order to see the code that is generated.
390  */
391 
393 
394  #define CREATE_WARN_MISSING_PARAMS_DOCUMENTATION(z,n, _) \
395  template<BOOST_PP_ENUM_PARAMS_Z(z,n,typename P)> \
396  MIRA_DEPRECATED("_________________Please provide parameter descriptions (and sample values, if appropriate) for RPC methods!_________________", \
397  void warnMissingParamsDocumentation##n (int dummy BOOST_PP_REPEAT_ ## z(n,RPCGEN_CALL_PARAM_DECL,nil))) {}
398 
399  BOOST_PP_REPEAT_FROM_TO(1, RPC_METHODS_MAX_PARAMS, CREATE_WARN_MISSING_PARAMS_DOCUMENTATION, nil)
400  #undef CREATE_WARN_MISSING_PARAMS_DOCUMENTATION
401 
402  #define RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE(z, n, _) \
403  typedef typename std::remove_const<typename std::remove_reference<P##n>::type>::type SampleType##n; \
404  m.parameterSamples.push_back(createParameterSample<SampleType##n>());
405 
406  #define RPCGEN_SERVER_METHODS_PUSH_SAMPLE(z, n, _) \
407  typedef typename std::remove_const<typename std::remove_reference<P##n>::type>::type SampleType##n; \
408  m.parameterSamples.push_back(createParameterSample<SampleType##n>(sample##n));
409 
410  // method(name, function<...>, comment)
411  #define RPCGEN_SERVER_METHODS(z,n,_) \
412  template<typename R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
413  void method(const char* name, R (*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), const char* comment) \
414  { \
415  warnMissingParamsDocumentation##n(0 BOOST_PP_REPEAT_ ## z(n,RPCGEN_SERVER_PARAM_DEFAULT,nil)); \
416  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment); \
417  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
418  m.addInvoker(make_RPCInvoker<BinaryRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
419  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
420  m.addInvoker(make_RPCInvoker<JSONRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
421  addMethod(m); \
422  } \
423  \
424  template<typename R, typename Class BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
425  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), Class* This, const char* comment)\
426  { \
427  warnMissingParamsDocumentation##n(0 BOOST_PP_REPEAT_ ## z(n,RPCGEN_SERVER_PARAM_DEFAULT,nil)); \
428  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment); \
429  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
430  m.addInvoker(make_RPCInvoker<BinaryRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
431  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
432  m.addInvoker(make_RPCInvoker<JSONRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
433  addMethod(m); \
434  } \
435  \
436  template<typename R, typename Class BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
437  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)) const, Class* This, const char* comment) \
438  { \
439  warnMissingParamsDocumentation##n(0 BOOST_PP_REPEAT_ ## z(n,RPCGEN_SERVER_PARAM_DEFAULT,nil)); \
440  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment); \
441  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
442  m.addInvoker(make_RPCInvoker<BinaryRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
443  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
444  m.addInvoker(make_RPCInvoker<JSONRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
445  addMethod(m); \
446  } \
447  \
448  template<typename R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
449  void method(const char* name, boost::function<R (BOOST_PP_ENUM_PARAMS_Z(z,n,P))> fn, const char* comment) \
450  { \
451  warnMissingParamsDocumentation##n(0 BOOST_PP_REPEAT_ ## z(n,RPCGEN_SERVER_PARAM_DEFAULT,nil)); \
452  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment); \
453  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
454  m.addInvoker(make_RPCInvoker<BinaryRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
455  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
456  m.addInvoker(make_RPCInvoker<JSONRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
457  addMethod(m); \
458  }
459 
460  BOOST_PP_REPEAT(BOOST_PP_INC(RPC_METHODS_MAX_PARAMS),RPCGEN_SERVER_METHODS,nil)
461  #undef RPCGEN_SERVER_METHODS
462 
463  #define RPCGEN_SERVER_PARAMINFO_NAME_DESC(z,n,_) ParameterInfo(name##n, description##n)
464 
465  // method(name, function<...>, comment, paramname, paramdescription, ... )
466  #define RPCGEN_SERVER_METHODS_PARAMDESC(z,n,_) \
467  template<typename R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
468  void method(const char* name, R (*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), \
469  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_DECL,nil)) \
470  { \
471  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
472  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
473  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
474  m.addInvoker(make_RPCInvoker<BinaryRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
475  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
476  m.addInvoker(make_RPCInvoker<JSONRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
477  addMethod(m); \
478  } \
479  \
480  template<typename R, typename Class BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
481  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), Class* This, \
482  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_DECL,nil)) \
483  { \
484  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
485  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
486  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
487  m.addInvoker(make_RPCInvoker<BinaryRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
488  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
489  m.addInvoker(make_RPCInvoker<JSONRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
490  addMethod(m); \
491  } \
492  \
493  template<typename R, typename Class BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
494  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)) const, Class* This, \
495  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_DECL,nil)) \
496  { \
497  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
498  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
499  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
500  m.addInvoker(make_RPCInvoker<BinaryRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
501  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
502  m.addInvoker(make_RPCInvoker<JSONRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
503  addMethod(m); \
504  } \
505  \
506  template<typename R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P)> \
507  void method(const char* name, boost::function<R (BOOST_PP_ENUM_PARAMS_Z(z,n,P))> fn, \
508  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_DECL,nil)) \
509  { \
510  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
511  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
512  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_DEFAULTSAMPLE, nil) \
513  m.addInvoker(make_RPCInvoker<BinaryRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
514  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
515  m.addInvoker(make_RPCInvoker<JSONRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
516  addMethod(m); \
517  } \
518 
519  // generate variants with parameter descriptions only for param count >= 1 (avoid duplication!)
520  BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_INC(RPC_METHODS_MAX_PARAMS),RPCGEN_SERVER_METHODS_PARAMDESC,nil)
521  #undef RPCGEN_SERVER_METHODS_PARAMDESC
522 
523  // method(name, function<...>, comment, paramname, paramdescription, paramsamplevalue, ... )
524  #define RPCGEN_SERVER_METHODS_PARAMDESCSAMPLE(z,n,_) \
525  template<typename R, BOOST_PP_ENUM(n,RPCGEN_CALL_TYPENAME_PARAM_DECL,nil)> \
526  void method(const char* name, R (*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), \
527  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_SAMPLE_DECL,nil)) \
528  { \
529  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
530  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
531  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_SAMPLE, nil) \
532  m.parameterSamplesDefault = false; \
533  m.addInvoker(make_RPCInvoker<BinaryRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
534  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
535  m.addInvoker(make_RPCInvoker<JSONRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
536  addMethod(m); \
537  } \
538  \
539  template<typename R, typename Class, BOOST_PP_ENUM(n,RPCGEN_CALL_TYPENAME_PARAM_DECL,nil)> \
540  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), Class* This, \
541  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_SAMPLE_DECL,nil)) \
542  { \
543  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
544  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
545  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_SAMPLE, nil) \
546  m.parameterSamplesDefault = false; \
547  m.addInvoker(make_RPCInvoker<BinaryRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
548  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
549  m.addInvoker(make_RPCInvoker<JSONRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
550  addMethod(m); \
551  } \
552  \
553  template<typename R, typename Class, BOOST_PP_ENUM(n,RPCGEN_CALL_TYPENAME_PARAM_DECL,nil)> \
554  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)) const, Class* This, \
555  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_SAMPLE_DECL,nil)) \
556  { \
557  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
558  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
559  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_SAMPLE, nil) \
560  m.parameterSamplesDefault = false; \
561  m.addInvoker(make_RPCInvoker<BinaryRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
562  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
563  m.addInvoker(make_RPCInvoker<JSONRPCBackend BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(std::mem_fn(fn),This)); \
564  addMethod(m); \
565  } \
566  \
567  template<typename R, BOOST_PP_ENUM(n,RPCGEN_CALL_TYPENAME_PARAM_DECL,nil)> \
568  void method(const char* name, boost::function<R (BOOST_PP_ENUM_PARAMS_Z(z,n,P))> fn, \
569  const char* comment, BOOST_PP_ENUM(n,RPCGEN_CALL_NAME_DESC_SAMPLE_DECL,nil)) \
570  { \
571  Method m(makeRPCSignature<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(name), comment, \
572  ParameterDescriptions{BOOST_PP_ENUM(n,RPCGEN_SERVER_PARAMINFO_NAME_DESC,nil)}); \
573  BOOST_PP_REPEAT_ ## z(n, RPCGEN_SERVER_METHODS_PUSH_SAMPLE, nil) \
574  m.parameterSamplesDefault = false; \
575  m.addInvoker(make_RPCInvoker<BinaryRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
576  m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
577  m.addInvoker(make_RPCInvoker<JSONRPCBackend,R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(fn)); \
578  addMethod(m); \
579  } \
580 
581  // generate variants with parameter descriptions+samples only for param count >= 1 (avoid duplication!)
582  BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_INC(RPC_METHODS_MAX_PARAMS),RPCGEN_SERVER_METHODS_PARAMDESCSAMPLE,nil)
583  #undef RPCGEN_SERVER_METHODS_PARAMDESCSAMPLE
584 
585  #undef RPCGEN_SERVER_PARAMINFO_NAME_DESC
586 
587  // method(name, function<...>, comment, ... )
588  // (these should match anything that does not match the more specific definitions above (i.e. it is invalid),
589  // will provide a much more informative error message than just failing to find a matching template instantiation)
590  #define RPCGEN_SERVER_METHODS_WRONG_ARGUMENT_NUMBER(z,n,_) \
591  template<typename R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P), typename... Args> \
592  void method(const char* name, R (*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), \
593  const char* comment, Args...) \
594  { \
595  invalid_method<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(); \
596  } \
597  template<typename R, typename Class BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P), typename... Args> \
598  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)), Class* This, \
599  const char* comment, Args...) \
600  { \
601  invalid_method<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(); \
602  } \
603  \
604  template<typename R, typename Class BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P), typename... Args> \
605  void method(const char* name, R (Class::*fn)(BOOST_PP_ENUM_PARAMS_Z(z,n,P)) const, Class* This, \
606  const char* comment, Args...) \
607  { \
608  invalid_method<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(); \
609  } \
610  \
611  template<typename R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,typename P), typename... Args> \
612  void method(const char* name, boost::function<R (BOOST_PP_ENUM_PARAMS_Z(z,n,P))> fn, \
613  const char* comment, Args...) \
614  { \
615  invalid_method<R BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,n,P)>(); \
616  } \
617 
619  #undef RPCGEN_SERVER_METHODS_WRONG_ARGUMENT_NUMBER
620 
621  private:
622 
623  void addMethod(const Method& method) {
624  foreach (const MethodInfo& m, mService.methods) {
625  // more than 1 method with same name and number of parameters?
626  if ((m.signature.name == method.signature.name) &&
627  (m.signature.parameterTypes.size() == method.signature.parameterTypes.size())) {
628  MIRA_LOG(WARNING) << mService.name << "." << m.signature << " and "
629  << mService.name << "." << method.signature
630  << " are ambiguous when called through JSON RPC"
631  << " - suggest choosing different method names.";
632  }
633  }
634 
635  if(mService.methods.insert(method).second)
636  mAddedMethods.insert(method.signature);
637  // adding the same method multiple times, is handled correctly
638  }
639 
640  template<typename T>
641  json::Value createParameterSample(const T& v = T()) {
642  return mJSONSerializer.serialize(v);
643  }
644 
645  private:
646 
648  Service& mService;
649 
651  std::set<RPCSignature> mAddedMethods;
652 
654  std::set<std::string> mAddedInterfaces;
655 
657  JSONSerializer mJSONSerializer;
658  };
659 
660 public:
661 
669  template <typename T>
670  const Service& registerServiceObject(const std::string& serviceName,
671  T& serviceObject,
672  std::set<RPCSignature>* addedMethods = NULL,
673  std::set<std::string>* addedInterfaces = NULL)
674  {
675  boost::mutex::scoped_lock lock(mMutex);
676 
677  // use already created service, or create new one
678  ServiceMap::iterator it = mServices.find(serviceName);
679  if (it==mServices.end())
680  it = mServices.insert(std::make_pair(serviceName,
681  Service(serviceName))).first;
682 
683  // reflect the service object and add its methods to the service
684  Service& s = it->second;
685  RPCReflector r(s);
686  serviceObject.reflect(r);
687 
688  MIRA_LOG(NOTICE) << "Registered service object for service: '" <<
689  serviceName << "'. With the following new methods:";
690  foreach(const RPCSignature& m, r.getAddedMethods())
691  MIRA_LOG(NOTICE) << " " << m;
692 
693  if(addedMethods!=NULL)
694  *addedMethods = r.getAddedMethods();
695 
696  if(addedInterfaces!=NULL)
697  *addedInterfaces = r.getAddedInterfaces();
698 
699  return s;
700  }
701 
706  void unregisterService(const std::string& serviceName)
707  {
708  boost::mutex::scoped_lock lock(mMutex);
709  MIRA_LOG(NOTICE) << "Unregistering service: '" << serviceName << "'.";
710  mServices.erase(serviceName);
711  }
712 
713 public:
714 
718  const ServiceMap& getServices() const
719  {
720  return mServices;
721  }
722 
728  const Service& getService(const std::string& name) const
729  {
730  boost::mutex::scoped_lock lock(mMutex);
731  auto i = mServices.find(name);
732  if (i == mServices.end())
733  MIRA_THROW(XInvalidParameter, "No such service '" << name << "'");
734 
735  return i->second;
736  }
737 
741  bool existsService(const std::string& name) const
742  {
743  boost::mutex::scoped_lock lock(mMutex);
744  auto i = mServices.find(name);
745  return i!= mServices.end();
746  }
747 
752  std::list<std::string> queryServicesForInterface(const std::string& interface) const
753  {
754  boost::mutex::scoped_lock lock(mMutex);
755  std::list<std::string> res;
756  // for all services
757  for(auto it=mServices.begin(); it!=mServices.end(); ++it)
758  // does service implements the desired interface?
759  if(it->second.interfaces.count(interface)!=0)
760  res.push_back(it->second.name); // yes? so add its name to the list
761  return res;
762  }
763 
767  bool implementsInterface(const std::string& name, const std::string& interface) const
768  {
769  boost::mutex::scoped_lock lock(mMutex);
770  auto it = mServices.find(name);
771  if (it == mServices.end())
772  return false;
773  return it->second.interfaces.count(interface) > 0;
774  }
775 
776 public:
777 
784  template <typename Backend>
785  void processCall(typename Backend::ServerRequest& request,
786  typename Backend::ServerResponse& response)
787  {
788  boost::shared_ptr<TRPCInvoker<Backend>> invoker;
789  Service* service;
790  std::string callId;
791 
792  Method* method = NULL;
793  if(!processCallCommon<Backend>(request, response, callId, invoker, service, method))
794  return; // an error has occured, abort, error already is reported in response
795 
796  // and finally invoke the method
797  response.setHeader(callId);
798  try
799  {
800  invoker->invoke(request, response);
801  }
802  catch(std::exception& ex) {
803  // handle possible exceptions in getParameter() and return them to caller
804  MIRA_LOG(WARNING) << "Invalid RPC Request: " << ex.what();
805  response.returnException(RPC_INVALID_PARAMS, ex.what());
806  }
807  }
808 
816  template <typename Backend>
818  {
819  public:
820  DeferredInvoker(typename Backend::ServerRequest& request,
821  typename Backend::ServerResponse& response,
822  const std::string& callId,
823  const std::string& service,
824  const std::string& method,
825  boost::shared_ptr<TRPCInvoker<Backend>> invoker) :
826  AbstractDeferredInvoker(callId,service,method),
827  mRequest(request), mResponse(response),
828  mInvoker(invoker) {}
829  public:
830  virtual void invoke() {
831  mResponse.setHeader(mCallId);
832  try
833  {
834  mInvoker->invoke(mRequest, mResponse);
835  }
836  catch(std::exception& ex) {
837  // handle possible exceptions in getParameter() and return them to caller
838  MIRA_LOG(WARNING) << "Invalid RPC Request: " << ex.what();
839  mResponse.returnException(RPC_INVALID_PARAMS, ex.what());
840  }
841  try {
842  if(mFinishHandler!=NULL)
844  } catch(std::exception& ex) {
845  // catch broken promise
847  }
848  }
849  private:
850  typename Backend::ServerRequest& mRequest;
851  typename Backend::ServerResponse& mResponse;
852  boost::shared_ptr<TRPCInvoker<Backend>> mInvoker;
853  };
854 
866  template <typename Backend>
867  AbstractDeferredInvokerPtr processCallDeferred(typename Backend::ServerRequest& request,
868  typename Backend::ServerResponse& response)
869  {
870  boost::shared_ptr<TRPCInvoker<Backend>> invoker;
871  Service* service = NULL;
872  std::string callId;
873 
874  Method* method;
875 
876  if(processCallCommon<Backend>(request, response, callId, invoker, service, method)) {
877  assert(service!=NULL);
878  AbstractDeferredInvokerPtr deferredInvoker(
879  new DeferredInvoker<Backend>(request, response, callId,
880  service->name,
881  method->signature.name, invoker));
882  return deferredInvoker;
883  } else {
884  // error already is reported in response
886  }
887  }
888 
889 protected:
890 
892  template <typename Backend>
893  bool processCallCommon(typename Backend::ServerRequest& request,
894  typename Backend::ServerResponse& response,
895  std::string &oCallId,
896  boost::shared_ptr<TRPCInvoker<Backend>>& oInvoker,
897  Service* &oService, Method* &oMethod)
898  {
899  std::string name;
900  std::string callId;
901  std::string serviceStr;
902 
903  try {
904  request.getHeader(callId, serviceStr);
905  } catch(std::exception& ex) {
906  // handle possible exceptions in getHeader() and return them to caller
907  MIRA_LOG(WARNING) << "Invalid RPC Request: " << ex.what();
908  generateErrorResponse<Backend>(callId, RPC_INVALID_REQUEST, ex.what(), response);
909  return false;
910  }
911 
912  boost::mutex::scoped_lock lock(mMutex);
913 
914  // find the service
915  auto serviceIt = mServices.find(serviceStr);
916 
917  if(serviceIt==mServices.end()) {
918  MIRA_LOG(WARNING) << "RPC service not found: " << serviceStr;
919  generateErrorResponse<Backend>(callId, RPC_METHOD_NOT_FOUND,
920  "Cannot process RPC call, a service named '"
921  + serviceStr + "' does not exist", response);
922  return false;
923  }
924 
925  Service& service = serviceIt->second;
926 
927  // find the method
928  oMethod=NULL;
929  Method* method = NULL;
930 
931  foreach(const Method& m, service.methods)
932  {
933  if(request.checkSignature(m.signature)) {
934  // found method with the correct signature
935  method = const_cast<Method*>(&m);
936  break; // break for each
937  }
938  }
939 
940  // abort, if we did not find the method, but produce a (hopefully)
941  // helpful exception message
942  if(method==NULL) {
943  std::string methodName = request.getSignature().name;
944  std::string candidates;
945  foreach(const Method& m, service.methods)
946  {
947  if(methodName == m.signature.name) {
948  if(!candidates.empty())
949  candidates += ", ";
950  candidates += toString(m.signature);
951  }
952  }
953 
954  if(!candidates.empty())
955  candidates = " Candidates are: " + candidates;
956  else
957  candidates = " No candidates found.";
958 
959  MIRA_LOG(WARNING) << "RPC method does not exist: "
960  << toString(request.getSignature())
961  << ", candidates: " << candidates;
962  generateErrorResponse<Backend>(callId,
963  RPC_INVALID_PARAMS, "Cannot process RPC call, the service '" +
964  serviceStr + "' does not have a method '" +
965  toString(request.getSignature()) + "'." + candidates,
966  response);
967  return false;
968  }
969 
970  // now get the invoker for our backend
971  auto invokerIt = method->invokers.find(typeId<Backend>());
972  if(invokerIt == method->invokers.end())
973  MIRA_THROW(XLogical, "Cannot process RPC call, no invoker for service method '" <<
974  serviceStr << "." << request.getSignature() <<
975  "' was registered for backend type '" <<
976  typeName<Backend>() << "'.");
977  // the above exception is not send to the caller, since it is caused by
978  // a problem here in our server
979 
980  // cast invoker into typed invoker for our Backend
981  oInvoker = boost::static_pointer_cast<TRPCInvoker<Backend>>(invokerIt->second);
982  oCallId = callId;
983  oService = &service;
984  oMethod = method;
985  return true;
986  }
987 
988  template <typename Backend>
989  void generateErrorResponse(const std::string& callId,
990  RPCError reason, const std::string& message,
991  typename Backend::ServerResponse& oResponse)
992  {
993  oResponse.setHeader(callId);
994  oResponse.returnException(reason, message);
995  }
996 
997 private:
998 
999  ServiceMap mServices;
1000  mutable boost::mutex mMutex;
1001 };
1002 
1004 
1005 } // namespace
1006 
1007 #endif /* _MIRA_RPCSERVER_H_ */
#define CREATE_WARN_MISSING_PARAMS_DOCUMENTATION(z, n, _)
Definition: RPCServer.h:394
DeferredInvoker(typename Backend::ServerRequest &request, typename Backend::ServerResponse &response, const std::string &callId, const std::string &service, const std::string &method, boost::shared_ptr< TRPCInvoker< Backend >> invoker)
Definition: RPCServer.h:820
ServiceInfo< MethodSet > Service
Definition: RPCServer.h:323
MethodInfo(const RPCSignature &iSignature, const std::string &iComment)
Definition: RPCServer.h:180
Definition: BinarySerializer.h:324
Contains all available information about a single RPC service, including the service&#39; name...
Definition: RPCServer.h:302
#define RPC_METHODS_MAX_PARAMS
Definition: ReflectorInterface.h:583
AbstractDeferredInvokerPtr processCallDeferred(typename Backend::ServerRequest &request, typename Backend::ServerResponse &response)
Similar to processCall() this method decodes the RPCRequest which was received from the client-side...
Definition: RPCServer.h:867
void unregisterService(const std::string &serviceName)
Unregisters the specified service with all methods of all service objects that were registered...
Definition: RPCServer.h:706
Method(const RPCSignature &signature, const std::string &comment, const ParameterDescriptions &parameterDescriptions)
Definition: RPCServer.h:275
Provides binary client and server side requests and responses.
bool implementsInterface(const std::string &name, const std::string &interface) const
Returns if the given service implements a certain interface.
Definition: RPCServer.h:767
std::string comment
User comments and description.
Definition: RPCServer.h:255
Contains information on an RPC method&#39;s parameter: name, description.
Definition: RPCServer.h:115
Invalid parameters were specified for the method.
Definition: RPCError.h:68
void reflect(ConcreteBinarySerializer< Stream, 0 > &r)
Definition: RPCServer.h:224
RPCReflector(Service &iService)
Definition: RPCServer.h:354
const std::set< std::string > & getAddedInterfaces() const
Returns all interfaces that were added to the service while visiting the service object.
Definition: RPCServer.h:375
Implementation of the CreationPolicy that is used by the Singleton template.
Definition: Singleton.h:174
#define RPCGEN_SERVER_METHODS(z, n, _)
Definition: RPCServer.h:411
Contains information on an existing RPC method: the signature of the method, comments, etc.
Definition: RPCServer.h:150
MethodInfo()
Definition: RPCServer.h:178
static Type & instance()
Returns a reference to the singleton instance.
Definition: Singleton.h:544
bool existsService(const std::string &name) const
Returns true, if a service with the specified name exists, otherwise false.
Definition: RPCServer.h:741
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
Error codes for reasons of errors/exceptions while processing an rpc call.
std::map< int, boost::shared_ptr< RPCInvoker > > invokers
stores corresponding RPCInvoker for each backend type
Definition: RPCServer.h:288
#define RPCGEN_SERVER_METHODS_WRONG_ARGUMENT_NUMBER(z, n, _)
Definition: RPCServer.h:590
Invoker that is used to invoke an RPC method call for a special backend.
Definition: RPCInvoker.h:94
#define MIRA_LOG(level)
Use this macro to log data.
Definition: LoggingCore.h:528
std::string description
Parameter description.
Definition: RPCServer.h:133
std::list< json::Value > parameterSamples
Definition: RPCServer.h:262
ParameterInfo()
Definition: RPCServer.h:117
Abstract interface for DeferredInvoker which is a class to support different RPC backends.
Definition: AbstractDeferredInvoker.h:80
Contains toString and fromString functions for converting data types to strings and the other way rou...
#define RPCGEN_SERVER_METHODS_PARAMDESCSAMPLE(z, n, _)
Definition: RPCServer.h:524
Definition: BinarySerializer.h:991
std::string extendedSignature() const
void reflect(Reflector &r)
Definition: RPCServer.h:123
void serialize(const std::string &name, const T &value, const std::string &comment="")
Serializes the specified object value under the given name.
Definition: Serializer.h:204
bool processCallCommon(typename Backend::ServerRequest &request, typename Backend::ServerResponse &response, std::string &oCallId, boost::shared_ptr< TRPCInvoker< Backend >> &oInvoker, Service *&oService, Method *&oMethod)
contains common functionality that is used by processCall() and processCallDeferred() ...
Definition: RPCServer.h:893
uint8 VersionType
Definition: ReflectorInterface.h:72
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:81
This is the public interface of all reflectors that are able to visit a class&#39; reflect() method...
Definition: ReflectorInterface.h:111
Provides JSON client and server side requests and responses.
std::string toString(const T &value, int precision=-1)
Converts any data type to string (the data type must support the stream << operator).
Definition: ToString.h:256
void reflectBinaryV0(Reflector &r)
Definition: RPCServer.h:206
const Service & registerServiceObject(const std::string &serviceName, T &serviceObject, std::set< RPCSignature > *addedMethods=NULL, std::set< std::string > *addedInterfaces=NULL)
Registers the methods of the specified service object under the specified service name...
Definition: RPCServer.h:670
TMethodSet methods
All methods that were registered for this service.
Definition: RPCServer.h:318
void warnMissingParamsDocumentation0(int)
Definition: RPCServer.h:392
Contains the base interface of all Reflectors, Serializers, etc.
Special visitor for the reflect() method that visits all method() and interface() calls within the re...
Definition: RPCServer.h:339
void interface(const char *name)
Definition: RPCServer.h:381
Auxiliary logging macros for special entities like exceptions, etc.
#define RPCGEN_SERVER_METHODS_PARAMDESC(z, n, _)
Definition: RPCServer.h:466
A singleton template class that can be freely configured using policies that control the instantiatio...
Definition: Singleton.h:531
MIRA_BASE_EXPORT std::string resolveEnvironmentVariable(const std::string &envVar)
Resolves an environmental variable.
Core class of the logging library.
std::string name
Parameter name.
Definition: RPCServer.h:130
RPCSignature for storing all information about an RPC method signature.
Contains all information on a registered RPC method, including the signature of the method...
Definition: RPCServer.h:270
Implements the RPCInvoker and TRPCInvoker classes.
bool operator<(const MethodInfo &rhs) const
Definition: RPCServer.h:236
void reflect(Reflector &r)
Definition: RPCServer.h:308
Abstract interface for DeferredInvoker.
ServiceInfo(const std::string &iName="")
Definition: RPCServer.h:304
std::string sampleParametersSet(bool formatted=false) const
std::string name
The method&#39;s name.
Definition: RPCSignature.h:134
std::string mCallId
Definition: AbstractDeferredInvoker.h:113
bool operator==(const MethodInfo &rhs) const
Definition: RPCServer.h:240
void generateErrorResponse(const std::string &callId, RPCError reason, const std::string &message, typename Backend::ServerResponse &oResponse)
Definition: RPCServer.h:989
RPCError
enumeration of possible reasons for errors/exceptions while performing an RPC call ...
Definition: RPCError.h:64
const std::set< RPCSignature > & getAddedMethods() const
Returns all methods that were added to the service while visiting the service object.
Definition: RPCServer.h:370
json_spirit::mValue Value
A value is an abstract description of data in JSON (underlying data can either be one of the JSON bas...
Definition: JSON.h:176
virtual void invoke()
Invokes the RPC call that is represented by this DeferredInvoker.
Definition: RPCServer.h:830
void method(const char *name, Method method, const char *comment, const char *paramName, const char *paramDescription, P paramSampleValue,...)
Specifies that the class that is reflected provides a service through the specified static member fun...
void addInvoker(TRPCInvoker< Backend > *invoker)
adds a new invoker that processes the method for a certain backend
Definition: RPCServer.h:281
void processCall(typename Backend::ServerRequest &request, typename Backend::ServerResponse &response)
Decodes the Request which was received from the client-side and invokes the RPC call immediately...
Definition: RPCServer.h:785
void reflectBase(Base &base)
implements ReflectorInterface (for documentation see ReflectorInterface)
Definition: RPCServer.h:362
std::list< std::string > queryServicesForInterface(const std::string &interface) const
Returns a string list with the names of all registered services, that implement the specified interfa...
Definition: RPCServer.h:752
#define MIRA_LOG_EXCEPTION(level, ex)
Log the specified exception, including all information that the exception object carries.
Definition: LoggingAux.h:107
std::set< MethodInfo > MethodInfoSet
Definition: RPCServer.h:293
std::map< std::string, Service > ServiceMap
Definition: RPCServer.h:325
Definition: LoggingCore.h:75
Functions for platform independent resolving of environment variables.
friend std::ostream & operator<<(std::ostream &s, const ParameterInfo &v)
Definition: RPCServer.h:137
RPCSignature signature
The signature of the method (including its name)
Definition: RPCServer.h:252
std::set< Method > MethodSet
Definition: RPCServer.h:291
std::set< std::string > interfaces
All interfaces that this service supports.
Definition: RPCServer.h:320
Requested method was not found.
Definition: RPCError.h:67
std::string name
The name of this service.
Definition: RPCServer.h:316
void reflect(ConcreteBinaryDeserializer< Stream, 0 > &r)
Definition: RPCServer.h:231
static bool enabled()
Definition: RPCServer.h:172
Definition: LoggingCore.h:74
const ServiceMap & getServices() const
Returns the map with all known services.
Definition: RPCServer.h:718
Stores the signature of an RPC method including the methods name and its parameter types...
Definition: RPCSignature.h:68
ParameterDescriptions parameterDesc
User info on method parameters.
Definition: RPCServer.h:258
The request is invalid or can not be parsed.
Definition: RPCError.h:66
virtual void onRPCfinished(AbstractDeferredInvoker *invoker)=0
called upon finish of the RPC call, the ID of the call is passed as parameter.
void reflect(Reflector &r)
Definition: RPCServer.h:189
ParameterInfo(const std::string &iName, const std::string &iDescription)
Definition: RPCServer.h:119
const Service & getService(const std::string &name) const
Returns a reference to the service with the given name.
Definition: RPCServer.h:728
bool parameterSamplesDefault
Sample parameter values.
Definition: RPCServer.h:261
Method(const RPCSignature &signature, const std::string &comment)
Definition: RPCServer.h:272
boost::shared_ptr< AbstractDeferredInvoker > AbstractDeferredInvokerPtr
Definition: AbstractDeferredInvoker.h:119
std::string parameterDescriptions(const std::string &prefix="") const
The RPCServer is responsible for handling the server-side of an rpc call.
Definition: RPCServer.h:107
MethodInfo(const RPCSignature &iSignature, const std::string &iComment, const ParameterDescriptions &iParameterDescriptions)
Definition: RPCServer.h:183
std::vector< ParameterInfo > ParameterDescriptions
Definition: RPCServer.h:144
Definition: LoggingCore.h:76
DeferredInvokerFinishHandler * mFinishHandler
Definition: AbstractDeferredInvoker.h:116
Stores all necessary information to invoke a previously decoded and prepared RPC call.
Definition: RPCServer.h:817