47 #ifndef _MIRA_JSONRPCBACKEND_H_ 48 #define _MIRA_JSONRPCBACKEND_H_ 51 #include <boost/thread/future.hpp> 52 #include <boost/algorithm/string.hpp> 69 inline bool jsonRPChasExceptionHelper(boost::promise<R>& promise,
json::Value& value)
71 auto it = value.get_obj().find(
"error");
72 if(it!=value.get_obj().end()) {
73 auto& obj = it->second;
74 auto messageit = obj.get_obj().find(
"message");
75 if(messageit==obj.get_obj().end()) {
76 promise.set_exception(boost::copy_exception(
77 XRPC(
"RPC client response has invalid error format: message missing")));
81 XRPC ex(messageit->second.get_str());
83 auto stackit = obj.get_obj().find(
"callstack");
84 if(stackit==obj.get_obj().end()) {
85 promise.set_exception(boost::copy_exception(ex));
89 auto threadit = obj.get_obj().find(
"thread");
90 if(threadit==obj.get_obj().end()) {
91 ex.addInfo(
"RPC client response has invalid error format: callstack without thread id");
98 JSONDeserializer js(stackit->second);
99 js.deserialize(stack);
102 ex.addInfo(
"RPC client response has invalid error format: callstack unreadable");
104 promise.set_exception(boost::copy_exception(ex));
108 if(threadit!=obj.get_obj().end()) {
110 thread = threadit->second.get_uint64();
112 catch(std::runtime_error&) {
113 ex.addInfo(
"RPC client response has invalid error format: thread id unreadable");
118 ex.addExternalStackInfo<XRPC>(stack, thread);
121 auto excit = obj.get_obj().find(
"exception");
122 if(excit!=obj.get_obj().end()) {
124 SerializableException* origEx;
125 JSONDeserializer js(excit->second);
126 js.deserialize(origEx);
127 ex.setOrigException(origEx);
132 promise.set_exception(boost::copy_exception(ex));
136 it = value.get_obj().find(
"result");
137 if(it==value.get_obj().end()) {
138 promise.set_exception(boost::copy_exception(
139 XRPC(
"RPC client response has invalid result format")));
145 template <
typename R>
146 inline void jsonRPCreturnHelper(boost::promise<R>& promise,
json::Value& value)
148 if (jsonRPChasExceptionHelper(promise, value))
150 auto it = value.get_obj().find(
"result");
152 JSONDeserializer d(it->second);
154 promise.set_value(std::move(ret));
158 inline void jsonRPCreturnHelper(boost::promise<JSONRPCResponse>& promise,
json::Value& value)
160 promise.set_value(JSONRPCResponse(value));
164 inline void jsonRPCreturnHelper(boost::promise<void>& promise,
json::Value& value)
166 if (jsonRPChasExceptionHelper(promise, value))
219 auto it = mValue->get_obj().find(
"id");
220 if(it== mValue->get_obj().end())
221 MIRA_THROW(
XRPC,
"Server response is missing an 'id'. Response = " 236 jsonRPCreturnHelper(promise, *mValue);
268 static uint32 sID = 0;
279 void setHeader(
const std::string& callId,
const std::string& service,
282 std::string method = service +
"." + signature.
name;
286 mValue->get_obj()[
"id"] = id;
294 template <
typename P>
301 mParams = &mValue->get_obj()[
"params"];
303 mParams->get_array().push_back(mOut.
serialize(param));
342 mValue->get_obj()[
"id"] = id;
365 mValue->get_obj()[
"error"] = o;
390 o[
"callstack"] = js.
serialize(callstack);
391 o[
"thread"] =
json::Value((boost::uint64_t)getCurrentThreadID());
392 mValue->get_obj()[
"error"] = o;
417 o[
"thread"] =
json::Value((boost::uint64_t)getCurrentThreadID());
418 o[
"exception"] = js.serialize(&ex);
419 mValue->get_obj()[
"error"] = o;
430 mValue->get_obj()[
"result"] = mOut.
serialize(res);
473 auto it = request->get_obj().find(
"id");
474 if(it==request->get_obj().end())
487 auto it = request->get_obj().find(
"method");
488 if(it==request->get_obj().end())
489 MIRA_THROW(
XRPC,
"The JSON request is missing a 'method'. Request = " 492 std::string method = it->second.get_str();
494 MIRA_THROW(
XRPC,
"The JSON request has an empty 'method'. Request = " 497 std::vector<std::string> strs;
498 boost::split(strs, method, boost::is_from_range(
'.',
'.'));
499 oService = *strs.begin();
500 oMethod = *strs.rbegin();
511 void getHeader(std::string& oCallId, std::string& oService)
516 auto it = mValue->get_obj().find(
"params");
518 if(it==mValue->get_obj().end())
520 mParams = &it->second;
522 for(std::size_t i=0;i<mParams->get_array().size(); ++i)
528 case json_spirit::obj_type:
type=
"object";
break;
529 case json_spirit::array_type:
type=
"array";
break;
530 case json_spirit::str_type:
type=
"string";
break;
531 case json_spirit::bool_type:
type=
"bool";
break;
532 case json_spirit::int_type:
type=
"int";
break;
533 case json_spirit::real_type:
type=
"float";
break;
547 return signature.
name == mSignature.
name &&
564 template <
typename P>
571 assert(mIndex < (uint32)mParams->get_array().size());
572 const json::Value& v = mParams->get_array()[mIndex++];
578 catch(std::exception& ex)
580 MIRA_THROW(
XRPC,
"Parameter must be a valid object of type '" << typeName<P>()
581 <<
"'. " << ex.what());
585 MIRA_THROW(
XRPC,
"Parameter must be a valid object of type '" << typeName<P>() <<
"'");
Serializer for serializing objects in JSON format.
Definition: JSONSerializer.h:93
void deserialize(T &value)
Definition: JSONSerializer.h:427
Definition: JSONRPCBackend.h:188
std::string generateCallID()
Generates a unique call ID for a client request of this backend.
Definition: JSONRPCBackend.h:267
void setHeader(const std::string &callId)
Write the response header consisting of the ID of the call.
Definition: JSONRPCBackend.h:338
Invalid parameters were specified for the method.
Definition: RPCError.h:68
Provides JSON client and server side requests and responses.
Definition: JSONRPCBackend.h:177
Definition: JSONRPCBackend.h:191
ServerRequest(const json::Value *value)
Definition: JSONRPCBackend.h:461
json_spirit::mArray Array
A representation of an array (vector) in JSON.
Definition: JSON.h:190
json::Value ContainerType
Definition: JSONRPCBackend.h:194
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.
Definition: JSONRPCBackend.h:189
void getReturn(boost::promise< R > &promise) const
Obtain return value from response and set it using promise.set_value() or set exception using promise...
Definition: JSONRPCBackend.h:234
Contains toString and fromString functions for converting data types to strings and the other way rou...
uint32 ThreadID
Platform independent thread ID.
Definition: ThreadID.h:68
static void getServiceMethod(const json::Value *request, std::string &oService, std::string &oMethod)
Read service name and the method name from the given request.
Definition: JSONRPCBackend.h:485
JSON client-side response.
Definition: JSONRPCBackend.h:205
ClientResponse(json::Value *value)
Definition: JSONRPCBackend.h:209
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
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:82
ClientRequest(json::Value *value)
Definition: JSONRPCBackend.h:255
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 setParameter(const P ¶m)
Write the value of the next parameter to the request.
Definition: JSONRPCBackend.h:295
ServerResponse(json::Value *value)
Definition: JSONRPCBackend.h:324
MIRA_BASE_EXPORT void write(const Value &value, std::ostream &ioStream, bool formatted=false, int precision=-1)
Writes a json::Value into a given stream using the JSON format.
Deserializer for serializing objects from JSON format.
Definition: JSONSerializer.h:400
ErrorCode
Error codes as defined by the JSON RPC standard.
Definition: JSONRPCBackend.h:184
An exception that is thrown by the RPCServer if an RPC call fails.
Definition: RPCError.h:76
An exception has occurred within the method that was called.
Definition: RPCError.h:69
Definition: JSONRPCBackend.h:187
void getParameter(P &oParam)
Read and deserialize the next parameter from the request.
Definition: JSONRPCBackend.h:565
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
const RPCSignature & getSignature()
Return the signature, that was read from the request header in the previous getHeader() call above...
Definition: JSONRPCBackend.h:555
JSON client-side request.
Definition: JSONRPCBackend.h:251
bool checkSignature(const RPCSignature &signature)
Check, if the passed signature is compatible with the signature that was read from the request header...
Definition: JSONRPCBackend.h:545
MIRA_BASE_EXPORT void read(const std::string &s, Value &oValue)
Read a json::Value from a string that contains JSON format.
const CallStack & callStack() const
Returns the state of the callstack at the moment when the exception was thrown.
Definition: Exception.h:257
Special response type for JSON RPC calls.
std::string name
The method's name.
Definition: RPCSignature.h:134
void returnException(RPCError reason, SerializableException &ex)
Write exception as result an RPC call.
Definition: JSONRPCBackend.h:401
json_spirit::mObject Object
A representation of an object (class, struct) in JSON.
Definition: JSON.h:183
RPCError
enumeration of possible reasons for errors/exceptions while performing an RPC call ...
Definition: RPCError.h:64
Definition: JSONRPCBackend.h:190
void getHeader(std::string &oCallId) const
Read the response header (i.e.
Definition: JSONRPCBackend.h:217
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
void returnResult(const R &res)
Write result of an RPC call.
Definition: JSONRPCBackend.h:428
Contains methods for simple atomic operations (such as increment, etc.) that are thread-safe without ...
void setHeader(const std::string &callId, const std::string &service, const RPCSignature &signature)
Write the request header consisting of the call ID, the service name and the signature of the request...
Definition: JSONRPCBackend.h:279
Encapsulates unix call stack functionality.
Definition: CallStack.h:86
JSON server-side response.
Definition: JSONRPCBackend.h:320
JSON server-side request.
Definition: JSONRPCBackend.h:457
void getHeader(std::string &oCallId, std::string &oService)
Read the request header including the call ID, the service name and the signature of the method...
Definition: JSONRPCBackend.h:511
virtual const char * what() const MIRA_NOEXCEPT_OR_NOTHROW
Returns the text of exception containing the information given in MIRA_THROW and MIRA_RETHROW as well...
Requested method was not found.
Definition: RPCError.h:67
void returnException(RPCError reason, const std::string &message)
Write exception as result an RPC call.
Definition: JSONRPCBackend.h:351
Definition: JSONRPCBackend.h:186
Stores the signature of an RPC method including the methods name and its parameter types...
Definition: RPCSignature.h:68
The request is invalid or can not be parsed.
Definition: RPCError.h:66
void returnException(RPCError reason, const std::string &message, const CallStack &callstack)
Write exception as result an RPC call.
Definition: JSONRPCBackend.h:374
uint32 inc(volatile uint32 *var)
Increments the value of the variable pointed to by var and returns its old value. ...
Definition: Atomic.h:82
Definition: Exceptions.h:85
Serializer and Deserializer for JSON format.
static std::string getCallId(const json::Value *request)
Read call ID from the given request.
Definition: JSONRPCBackend.h:471
void returnVoid()
Write successful end of an RPC call.
Definition: JSONRPCBackend.h:438
ParameterTypes parameterTypes
Vector of the type of each parameter.
Definition: RPCSignature.h:140