From 5245765964178c6ae5fed599e918177846b6a62d Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 12 Sep 2018 00:35:42 +0200 Subject: [PATCH] JSON API expose retroshare version Added a couple of macro to reduce boilerplate in manually written API wrappers, use them in auto-generated wrappers too --- .../async-method-wrapper-template.cpp.tmpl | 14 +-- .../src/method-wrapper-template.cpp.tmpl | 24 +---- libretroshare/src/jsonapi/jsonapi.cpp | 91 ++++++++++++------- 3 files changed, 62 insertions(+), 67 deletions(-) diff --git a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl index 9a9c8eada..d5ca5c828 100644 --- a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl +++ b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl @@ -31,19 +31,7 @@ registerHandler("$%apiPath%$", const std::shared_ptr session, const rb::Bytes& body ) { - RsGenericSerializer::SerializeContext cReq( - nullptr, 0, - RsGenericSerializer::SERIALIZATION_FLAG_YIELDING ); - RsJson& jReq(cReq.mJson); - jReq.Parse(reinterpret_cast(body.data()), body.size()); - - RsGenericSerializer::SerializeContext cAns; - RsJson& jAns(cAns.mJson); - - // if caller specified caller_data put it back in the answhere - const char kcd[] = "caller_data"; - if(jReq.HasMember(kcd)) - jAns.AddMember(kcd, jReq[kcd], jAns.GetAllocator()); + INITIALIZE_API_CALL_JSON_CONTEXT; if( !checkRsServicePtrReady( $%instanceName%$, "$%instanceName%$", cAns, session ) ) diff --git a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl index 4e1e76133..4125e1b69 100644 --- a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl +++ b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl @@ -24,19 +24,7 @@ registerHandler("$%apiPath%$", const std::shared_ptr session, const rb::Bytes& body ) { - RsGenericSerializer::SerializeContext cReq( - nullptr, 0, - RsGenericSerializer::SERIALIZATION_FLAG_YIELDING ); - RsJson& jReq(cReq.mJson); - jReq.Parse(reinterpret_cast(body.data()), body.size()); - - RsGenericSerializer::SerializeContext cAns; - RsJson& jAns(cAns.mJson); - - // if caller specified caller_data put it back in the answhere - const char kcd[] = "caller_data"; - if(jReq.HasMember(kcd)) - jAns.AddMember(kcd, jReq[kcd], jAns.GetAllocator()); + INITIALIZE_API_CALL_JSON_CONTEXT; if( !checkRsServicePtrReady( $%instanceName%$, "$%instanceName%$", cAns, session ) ) @@ -54,15 +42,7 @@ $%functionCall%$ $%outputParamsSerialization%$ // return them to the API caller - std::stringstream ss; - ss << jAns; - std::string&& ans(ss.str()); - const std::multimap headers - { - { "Content-Type", "text/json" }, - { "Content-Length", std::to_string(ans.length()) } - }; - session->close(rb::OK, ans, headers); + DEFAULT_API_CALL_JSON_RETURN(rb::OK); } ); }); diff --git a/libretroshare/src/jsonapi/jsonapi.cpp b/libretroshare/src/jsonapi/jsonapi.cpp index b8e982312..e8d8f9345 100644 --- a/libretroshare/src/jsonapi/jsonapi.cpp +++ b/libretroshare/src/jsonapi/jsonapi.cpp @@ -26,10 +26,38 @@ #include "util/rsjson.h" #include "retroshare/rsfiles.h" #include "util/radix64.h" +#include "retroshare/rsversion.h" // Generated at compile time #include "jsonapi-includes.inl" +#define INITIALIZE_API_CALL_JSON_CONTEXT \ + RsGenericSerializer::SerializeContext cReq( \ + nullptr, 0, \ + RsGenericSerializer::SERIALIZATION_FLAG_YIELDING ); \ + RsJson& jReq(cReq.mJson); \ + jReq.Parse(reinterpret_cast(body.data()), body.size()); \ +\ + RsGenericSerializer::SerializeContext cAns; \ + RsJson& jAns(cAns.mJson); \ +\ + /* if caller specified caller_data put it back in the answhere */ \ + const char kcd[] = "caller_data"; \ + if(jReq.HasMember(kcd)) \ + jAns.AddMember(kcd, jReq[kcd], jAns.GetAllocator()) + +#define DEFAULT_API_CALL_JSON_RETURN(RET_CODE) \ + std::stringstream ss; \ + ss << jAns; \ + std::string&& ans(ss.str()); \ + const std::multimap headers \ + { \ + { "Content-Type", "text/json" }, \ + { "Content-Length", std::to_string(ans.length()) } \ + }; \ + session->close(RET_CODE, ans, headers) + + static bool checkRsServicePtrReady( void* serviceInstance, const std::string& serviceName, RsGenericSerializer::SerializeContext& ctx, @@ -45,18 +73,12 @@ static bool checkRsServicePtrReady( RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); RS_SERIAL_PROCESS(jsonApiError); - std::stringstream ss; - ss << ctx.mJson; - std::string&& ans(ss.str()); - const std::multimap headers - { - { "Content-Type", "text/json" }, - { "Content-Length", std::to_string(ans.length()) } - }; - session->close(rb::CONFLICT, ans, headers); + RsJson& jAns(ctx.mJson); + DEFAULT_API_CALL_JSON_RETURN(rb::CONFLICT); return false; } + JsonApiServer::JsonApiServer( uint16_t port, const std::string& bindAddress, const std::function shutdownCallback ) : @@ -69,6 +91,32 @@ JsonApiServer::JsonApiServer( shutdown(); }); + registerHandler("/jsonApiServer/version", + [](const std::shared_ptr session) + { + size_t reqSize = session->get_request()->get_header("Content-Length", 0); + session->fetch( reqSize, []( + const std::shared_ptr session, + const rb::Bytes& body ) + { + INITIALIZE_API_CALL_JSON_CONTEXT; + + uint32_t major = RS_MAJOR_VERSION; + uint32_t minor = RS_MINOR_VERSION; + uint32_t mini = RS_MINI_VERSION; + std::string human = RS_HUMAN_READABLE_VERSION; + + RsGenericSerializer::SerializeContext& ctx(cAns); + RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); + RS_SERIAL_PROCESS(major); + RS_SERIAL_PROCESS(minor); + RS_SERIAL_PROCESS(mini); + RS_SERIAL_PROCESS(human); + + DEFAULT_API_CALL_JSON_RETURN(rb::OK); + } ); + }); + registerHandler("/rsFiles/getFileData", [](const std::shared_ptr session) { @@ -77,19 +125,7 @@ JsonApiServer::JsonApiServer( const std::shared_ptr session, const rb::Bytes& body ) { - RsGenericSerializer::SerializeContext cReq( - nullptr, 0, - RsGenericSerializer::SERIALIZATION_FLAG_YIELDING ); - RsJson& jReq(cReq.mJson); - jReq.Parse(reinterpret_cast(body.data()), body.size()); - - RsGenericSerializer::SerializeContext cAns; - RsJson& jAns(cAns.mJson); - - // if caller specified caller_data put it back in the answhere - const char kcd[] = "caller_data"; - if(jReq.HasMember(kcd)) - jAns.AddMember(kcd, jReq[kcd], jAns.GetAllocator()); + INITIALIZE_API_CALL_JSON_CONTEXT; if(!checkRsServicePtrReady(rsFiles, "rsFiles", cAns, session)) return; @@ -133,16 +169,7 @@ JsonApiServer::JsonApiServer( if(!errorMessage.empty()) RS_SERIAL_PROCESS(errorMessage); } - // return them to the API caller - std::stringstream ss; - ss << jAns; - std::string&& ans(ss.str()); - const std::multimap headers - { - { "Content-Type", "text/json" }, - { "Content-Length", std::to_string(ans.length()) } - }; - session->close(rb::OK, ans, headers); + DEFAULT_API_CALL_JSON_RETURN(rb::OK); } ); });