47 #ifndef _MIRA_RPCSERVER_H_ 48 #define _MIRA_RPCSERVER_H_ 53 #include <boost/thread/mutex.hpp> 121 template<
typename Reflector>
124 r.member(
"Name",
name,
"");
161 mReflectMethodParamsDocumentation =
false;
163 <<
"MIRA_RPC_METHODS_REFLECT_NO_PARAMS_DOCUMENTATION " 164 <<
"- RPC parameter documentation will not be shared with " 165 <<
"remote frameworks (ensuring backward compatibility)";
174 bool mReflectMethodParamsDocumentation;
187 template<
typename Reflector>
193 r.member(
"Comment",
comment,
"");
204 template<
typename Reflector>
210 version = r.version(2,
this);
213 r.member(
"Comment",
comment,
"");
222 template<
typename Stream>
229 template<
typename Stream>
279 template<
typename Backend>
282 invokers.insert(std::make_pair(typeId<Backend>(),
283 boost::shared_ptr<RPCInvoker>(invoker)));
287 std::map<int, boost::shared_ptr<RPCInvoker>>
invokers;
300 template <
typename TMethodSet>
306 template<
typename Reflector>
309 r.member(
"Name",
name,
"");
310 r.member(
"Methods",
methods,
"");
354 mService(iService) {}
360 template <
typename Base>
370 return mAddedMethods;
375 return mAddedInterfaces;
381 if(mService.
interfaces.insert(std::string(name)).second)
382 mAddedInterfaces.insert(std::string(name));
385 template<
typename R,
typename... Args,
typename F,
typename... Description>
387 method(
const char*, F&&, Description&&...)
392 template<
typename F,
typename... Description>
394 method(
const char*, F&&, Description&&...)
399 template<
typename R,
typename Class,
typename... Args,
typename... Description>
406 template<
typename R,
typename Class,
typename... Args,
typename... Description>
413 template<
typename R,
typename... Args,
typename F,
typename... Description>
415 method(
const char* name, F&& fn, Description&&... descriptions)
417 concreteMethod<R, Args...>(name, std::forward<F>(fn), std::forward<Description>(descriptions)...);
420 template<
typename F,
typename... Description>
422 method(
const char* name, F&& fn, Description&&... descriptions)
424 concreteMethodHelper<typename Private::FunctionTraits<F>::ReturnValue>(
426 std::forward<Description>(descriptions)...);
429 template<
typename R,
typename Class,
typename... Args,
typename... Description>
431 method(
const char* name, R (
Class::*fn)(Args...),
Class* This, Description&&... descriptions)
434 concreteMethod<R, Args...>(name, std::move(func), std::forward<Description>(descriptions)...);
437 template<
typename R,
typename Class,
typename... Args,
typename... Description>
439 method(
const char* name, R (
Class::*fn)(Args...)
const,
Class* This, Description&&... descriptions)
442 concreteMethod<R, Args...>(name, std::move(func), std::forward<Description>(descriptions)...);
446 template<
typename R,
typename... Args,
typename F,
typename... Description>
448 Description&&... descriptions)
450 concreteMethod<R, Args...>(name, std::forward<F>(fn), std::forward<Description>(descriptions)...);
453 template<
typename R,
typename... Args,
typename F,
typename Comment,
typename... Description>
454 void concreteMethod(
const char* name, F&& fn, Comment&& comment, Description&&... descriptions)
456 Method m(makeRPCSignature<R, Args...>(name), std::forward<Comment>(comment));
457 m.parameterDesc.reserve(
sizeof...(Args));
458 addParameterDescription<Args...>(m, std::forward<Description>(descriptions)...);
459 m.addInvoker(make_RPCInvoker<BinaryRPCBackend, R, Args...>(fn));
460 m.addInvoker(make_RPCInvoker<BinaryRPCBackendLegacy, R, Args...>(fn));
461 m.addInvoker(make_RPCInvoker<JSONRPCBackend, R, Args...>(fn));
467 void addMethod(
const Method&
method) {
468 foreach (
const MethodInfo& m, mService.
methods) {
470 if ((m.signature.name ==
method.signature.name) &&
471 (m.signature.parameterTypes.size() ==
method.signature.parameterTypes.size())) {
474 <<
" are ambiguous when called through JSON RPC" 475 <<
" - choosing different method names is strongly recommended!";
480 mAddedMethods.insert(
method.signature);
484 template<
typename... RECURSIONSTOP>
485 typename std::enable_if<(
sizeof...(RECURSIONSTOP)) == 0>
::type addParameterDescription(Method& m)
488 template<
typename ParameterType,
typename... Args>
489 MIRA_DEPRECATED(
"_________________Please provide parameter descriptions (and sample values, if appropriate) for RPC methods!_________________",
490 void addParameterDescription(Method& m)
492 m.parameterSamples.emplace_back(createParameterSample<Private::StrippedType<ParameterType>>());
493 addParameterDescription<Args...>(m);
497 template<
typename ParameterType,
typename... Args,
class Name,
class Description,
typename... Tail,
498 typename =
typename std::enable_if<(
sizeof...(Args)) * 2 ==
sizeof...(Tail)>
::type>
499 void addParameterDescription(Method& m, Name&& name, Description&& description, Tail&&... tail)
501 m.parameterDesc.emplace_back(std::forward<Name>(name), std::forward<Description>(description));
502 m.parameterSamples.emplace_back(createParameterSample<Private::StrippedType<ParameterType>>());
503 addParameterDescription<Args...>(m, std::forward<Tail>(tail)...);
506 template<
typename ParameterType,
typename... Args,
class Name,
class Description,
class Example,
508 typename =
typename std::enable_if<(
sizeof...(Args)) * 3 ==
sizeof...(Tail)>::
type>
509 void addParameterDescription(Method& m, Name&& name, Description&& description, Example&& example,
512 m.parameterDesc.emplace_back(std::forward<Name>(name), std::forward<Description>(description));
513 m.parameterSamples.emplace_back(
514 createParameterSample<Private::StrippedType<ParameterType>>(std::forward<Example>(example)));
515 m.parameterSamplesDefault =
false;
517 addParameterDescription<Args...>(m, std::forward<Tail>(tail)...);
521 json::Value createParameterSample(
const T& v = T())
523 return mJSONSerializer.serialize(v);
527 JSONSerializer mJSONSerializer;
535 std::set<RPCSignature> mAddedMethods;
538 std::set<std::string> mAddedInterfaces;
550 template <
typename T>
553 std::set<RPCSignature>* addedMethods = NULL,
554 std::set<std::string>* addedInterfaces = NULL)
556 boost::mutex::scoped_lock lock(mMutex);
559 ServiceMap::iterator it = mServices.find(serviceName);
560 if (it==mServices.end())
561 it = mServices.insert(std::make_pair(serviceName,
567 serviceObject.reflect(r);
570 serviceName <<
"'. With the following new methods:";
574 if(addedMethods!=NULL)
577 if(addedInterfaces!=NULL)
589 boost::mutex::scoped_lock lock(mMutex);
590 MIRA_LOG(
NOTICE) <<
"Unregistering service: '" << serviceName <<
"'.";
591 mServices.erase(serviceName);
611 boost::mutex::scoped_lock lock(mMutex);
612 auto i = mServices.find(name);
613 if (i == mServices.end())
614 MIRA_THROW(XInvalidParameter,
"No such service '" << name <<
"'");
624 boost::mutex::scoped_lock lock(mMutex);
625 auto i = mServices.find(name);
626 return i!= mServices.end();
635 boost::mutex::scoped_lock lock(mMutex);
636 std::list<std::string> res;
638 for(
auto it=mServices.begin(); it!=mServices.end(); ++it)
640 if(it->second.interfaces.count(interface)!=0)
641 res.push_back(it->second.name);
650 boost::mutex::scoped_lock lock(mMutex);
651 auto it = mServices.find(name);
652 if (it == mServices.end())
654 return it->second.interfaces.count(interface) > 0;
665 template <
typename Backend>
667 typename Backend::ServerResponse& response)
669 boost::shared_ptr<TRPCInvoker<Backend>> invoker;
674 if(!processCallCommon<Backend>(request, response, callId, invoker, service, method))
678 response.setHeader(callId);
681 invoker->invoke(request, response);
683 catch(std::exception& ex) {
697 template <
typename Backend>
702 typename Backend::ServerResponse& response,
703 const std::string& callId,
704 const std::string& service,
705 const std::string& method,
708 mRequest(request), mResponse(response),
715 mInvoker->invoke(mRequest, mResponse);
717 catch(std::exception& ex) {
725 }
catch(std::exception& ex) {
731 typename Backend::ServerRequest& mRequest;
732 typename Backend::ServerResponse& mResponse;
733 boost::shared_ptr<TRPCInvoker<Backend>> mInvoker;
747 template <
typename Backend>
749 typename Backend::ServerResponse& response)
751 boost::shared_ptr<TRPCInvoker<Backend>> invoker;
757 if(processCallCommon<Backend>(request, response, callId, invoker, service, method)) {
758 assert(service!=NULL);
763 return deferredInvoker;
773 template <
typename Backend>
775 typename Backend::ServerResponse& response,
776 std::string &oCallId,
782 std::string serviceStr;
785 request.getHeader(callId, serviceStr);
786 }
catch(std::exception& ex) {
793 boost::mutex::scoped_lock lock(mMutex);
796 auto serviceIt = mServices.find(serviceStr);
798 if(serviceIt==mServices.end()) {
801 "Cannot process RPC call, a service named '" 802 + serviceStr +
"' does not exist", response);
806 Service& service = serviceIt->second;
814 if(request.checkSignature(m.
signature)) {
816 method =
const_cast<Method*
>(&m);
824 std::string methodName = request.getSignature().name;
825 std::string candidates;
829 if(!candidates.empty())
835 if(!candidates.empty())
836 candidates =
" Candidates are: " + candidates;
838 candidates =
" No candidates found.";
842 <<
", candidates: " << candidates;
843 generateErrorResponse<Backend>(callId,
845 serviceStr +
"' does not have a method '" +
846 toString(request.getSignature()) +
"'." + candidates,
852 auto invokerIt = method->
invokers.find(typeId<Backend>());
853 if(invokerIt == method->
invokers.end())
854 MIRA_THROW(XLogical,
"Cannot process RPC call, no invoker for service method '" <<
855 serviceStr <<
"." << request.getSignature() <<
856 "' was registered for backend type '" <<
857 typeName<Backend>() <<
"'.");
869 template <
typename Backend>
871 RPCError reason,
const std::string& message,
872 typename Backend::ServerResponse& oResponse)
874 oResponse.setHeader(callId);
875 oResponse.returnException(reason, message);
881 mutable boost::mutex mMutex;
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:701
ServiceInfo< MethodSet > Service
Definition: RPCServer.h:322
MethodInfo(const RPCSignature &iSignature, const std::string &iComment)
Definition: RPCServer.h:179
Definition: BinarySerializer.h:316
Contains all available information about a single RPC service, including the service' name...
Definition: RPCServer.h:301
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:748
void unregisterService(const std::string &serviceName)
Unregisters the specified service with all methods of all service objects that were registered...
Definition: RPCServer.h:587
Method(const RPCSignature &signature, const std::string &comment, const ParameterDescriptions ¶meterDescriptions)
Definition: RPCServer.h:274
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:648
std::string comment
User comments and description.
Definition: RPCServer.h:254
std::string resolveEnvironmentVariable(const std::string &envVar)
Resolves an environmental variable.
Definition: RPCPatternCheck.h:82
Contains information on an RPC method's parameter: name, description.
Definition: RPCServer.h:114
Invalid parameters were specified for the method.
Definition: RPCError.h:68
void reflect(ConcreteBinarySerializer< Stream, 0 > &r)
Definition: RPCServer.h:223
RPCReflector(Service &iService)
Definition: RPCServer.h:353
const std::set< std::string > & getAddedInterfaces() const
Returns all interfaces that were added to the service while visiting the service object.
Definition: RPCServer.h:374
ValidRPCDescription< R(Class::*)(Args...), Description... > method(const char *name, R(Class::*fn)(Args...), Class *This, Description &&... descriptions)
Definition: RPCServer.h:431
Implementation of the CreationPolicy that is used by the Singleton template.
Definition: Singleton.h:149
Contains information on an existing RPC method: the signature of the method, comments, etc.
Definition: RPCServer.h:149
MethodInfo()
Definition: RPCServer.h:177
static Type & instance()
Returns a reference to the singleton instance.
Definition: Singleton.h:508
bool existsService(const std::string &name) const
Returns true, if a service with the specified name exists, otherwise false.
Definition: RPCServer.h:622
InvalidRPCDescription< R(Args...), Description... > method(const char *, F &&, Description &&...)
Definition: RPCServer.h:387
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:287
InvalidRPCDescription< R(Class::*)(Args...) const, Description... > method(const char *, R(Class::*)(Args...) const, Class *, Description &&...)
Definition: RPCServer.h:408
ReflectMethodParamsDocumentation()
Definition: RPCServer.h:156
Invoker that is used to invoke an RPC method call for a special backend.
Definition: RPCInvoker.h:91
#define MIRA_LOG(level)
Use this macro to log data.
Definition: LoggingCore.h:529
std::string description
Parameter description.
Definition: RPCServer.h:132
Class object which supports some kind of class reflection.
Definition: Class.h:97
std::list< json::Value > parameterSamples
Definition: RPCServer.h:261
ParameterInfo()
Definition: RPCServer.h:116
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...
Definition: BinarySerializer.h:980
std::string extendedSignature() const
void reflect(Reflector &r)
Definition: RPCServer.h:122
Definition: RPCServer.h:151
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:774
uint8 VersionType
Definition: ReflectorInterface.h:72
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:78
This is the public interface of all reflectors that are able to visit a class' reflect() method...
Definition: ReflectorInterface.h:111
Provides JSON client and server side requests and responses.
Definition: RPCInvoker.h:178
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:252
void reflectBinaryV0(Reflector &r)
Definition: RPCServer.h:205
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:551
TMethodSet methods
All methods that were registered for this service.
Definition: RPCServer.h:317
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:338
void interface(const char *name)
Definition: RPCServer.h:380
Auxiliary logging macros for special entities like exceptions, etc.
InvalidRPCDescription< F, Description... > method(const char *, F &&, Description &&...)
Definition: RPCServer.h:394
A singleton template class that can be freely configured using policies that control the instantiatio...
Definition: Singleton.h:495
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
Core class of the logging library.
std::string name
Parameter name.
Definition: RPCServer.h:129
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:269
Implements the RPCInvoker and TRPCInvoker classes.
bool operator<(const MethodInfo &rhs) const
Definition: RPCServer.h:235
void reflect(Reflector &r)
Definition: RPCServer.h:307
Abstract interface for DeferredInvoker.
ServiceInfo(const std::string &iName="")
Definition: RPCServer.h:303
std::string sampleParametersSet(bool formatted=false) const
std::string name
The method's name.
Definition: RPCSignature.h:130
std::string mCallId
Definition: AbstractDeferredInvoker.h:113
bool operator==(const MethodInfo &rhs) const
Definition: RPCServer.h:239
void generateErrorResponse(const std::string &callId, RPCError reason, const std::string &message, typename Backend::ServerResponse &oResponse)
Definition: RPCServer.h:870
RPCError
enumeration of possible reasons for errors/exceptions while performing an RPC call ...
Definition: RPCError.h:64
typename std::enable_if< Private::rpc::isValid< F, Description... >()>::type ValidRPCDescription
Definition: RPCPatternCheck.h:307
const std::set< RPCSignature > & getAddedMethods() const
Returns all methods that were added to the service while visiting the service object.
Definition: RPCServer.h:369
typename std::enable_if<!Private::rpc::isValid< F, Description... >()>::type InvalidRPCDescription
Definition: RPCPatternCheck.h:310
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:174
virtual void invoke()
Invokes the RPC call that is represented by this DeferredInvoker.
Definition: RPCServer.h:711
void addInvoker(TRPCInvoker< Backend > *invoker)
adds a new invoker that processes the method for a certain backend
Definition: RPCServer.h:280
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:666
void reflectBase(Base &base)
implements ReflectorInterface (for documentation see ReflectorInterface)
Definition: RPCServer.h:361
InvalidRPCDescription< R(Class::*)(Args...), Description... > method(const char *, R(Class::*)(Args...), Class *, Description &&...)
Definition: RPCServer.h:401
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:633
#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:292
std::map< std::string, Service > ServiceMap
Definition: RPCServer.h:324
Definition: RPCPatternCheck.h:88
Definition: LoggingCore.h:76
ValidRPCDescription< R(Class::*)(Args...) const, Description... > method(const char *name, R(Class::*fn)(Args...) const, Class *This, Description &&... descriptions)
Definition: RPCServer.h:439
Functions for platform independent resolving of environment variables.
friend std::ostream & operator<<(std::ostream &s, const ParameterInfo &v)
Definition: RPCServer.h:136
RPCSignature signature
The signature of the method (including its name)
Definition: RPCServer.h:251
std::set< Method > MethodSet
Definition: RPCServer.h:290
std::set< std::string > interfaces
All interfaces that this service supports.
Definition: RPCServer.h:319
Requested method was not found.
Definition: RPCError.h:67
std::string name
The name of this service.
Definition: RPCServer.h:315
void reflect(ConcreteBinaryDeserializer< Stream, 0 > &r)
Definition: RPCServer.h:230
static bool enabled()
Definition: RPCServer.h:171
Definition: LoggingCore.h:75
const ServiceMap & getServices() const
Returns the map with all known services.
Definition: RPCServer.h:599
Stores the signature of an RPC method including the methods name and its parameter types...
Definition: RPCSignature.h:64
ParameterDescriptions parameterDesc
User info on method parameters.
Definition: RPCServer.h:257
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:188
ParameterInfo(const std::string &iName, const std::string &iDescription)
Definition: RPCServer.h:118
const Service & getService(const std::string &name) const
Returns a reference to the service with the given name.
Definition: RPCServer.h:609
bool parameterSamplesDefault
Sample parameter values.
Definition: RPCServer.h:260
Method(const RPCSignature &signature, const std::string &comment)
Definition: RPCServer.h:271
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:106
MethodInfo(const RPCSignature &iSignature, const std::string &iComment, const ParameterDescriptions &iParameterDescriptions)
Definition: RPCServer.h:182
std::vector< ParameterInfo > ParameterDescriptions
Definition: RPCServer.h:143
ValidRPCDescription< R(Args...), Description... > method(const char *name, F &&fn, Description &&... descriptions)
Definition: RPCServer.h:415
Definition: LoggingCore.h:77
constexpr std::enable_if<!FunctionTraits< F >::isFunction >::type invalidAssertion()
Definition: RPCPatternCheck.h:282
DeferredInvokerFinishHandler * mFinishHandler
Definition: AbstractDeferredInvoker.h:116
ValidRPCDescription< F, Description... > method(const char *name, F &&fn, Description &&... descriptions)
Definition: RPCServer.h:422
Stores all necessary information to invoke a previously decoded and prepared RPC call.
Definition: RPCServer.h:698