mirror of https://github.com/oxen-io/lokinet
Convert from rapidjson to use nlohmann::json
This commit is contained in:
parent
93399fdbb4
commit
31441b46dc
|
@ -18,8 +18,8 @@ namespace abyss
|
|||
namespace http
|
||||
{
|
||||
using RPC_Method_t = std::string;
|
||||
using RPC_Params = llarp::json::Value;
|
||||
using RPC_Response = llarp::json::Document;
|
||||
using RPC_Params = nlohmann::json;
|
||||
using RPC_Response = nlohmann::json;
|
||||
using Headers_t = std::unordered_multimap< std::string, std::string >;
|
||||
struct ConnImpl;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <util/string_view.hpp>
|
||||
#include <util/time.hpp>
|
||||
|
||||
#include <absl/types/optional.h>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -21,14 +22,13 @@ namespace abyss
|
|||
struct IRPCHandler
|
||||
{
|
||||
using Method_t = std::string;
|
||||
using Params = llarp::json::Value;
|
||||
using Response = llarp::json::Writer;
|
||||
using Params = nlohmann::json;
|
||||
using Response = nlohmann::json;
|
||||
|
||||
IRPCHandler(ConnImpl* impl);
|
||||
|
||||
virtual bool
|
||||
HandleJSONRPC(Method_t method, const Params& params,
|
||||
Response& response) = 0;
|
||||
virtual absl::optional< Response >
|
||||
HandleJSONRPC(Method_t method, const Params& params) = 0;
|
||||
|
||||
virtual ~IRPCHandler();
|
||||
|
||||
|
|
|
@ -11,14 +11,12 @@ struct DemoHandler : public abyss::httpd::IRPCHandler
|
|||
{
|
||||
}
|
||||
|
||||
bool
|
||||
HandleJSONRPC(Method_t method, __attribute__((unused)) const Params& params,
|
||||
Response& resp) override
|
||||
absl::optional< Response >
|
||||
HandleJSONRPC(Method_t method,
|
||||
__attribute__((unused)) const Params& params) override
|
||||
{
|
||||
llarp::LogInfo("method: ", method);
|
||||
resp.StartObject();
|
||||
resp.EndObject();
|
||||
return true;
|
||||
return Response::object();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -81,9 +79,7 @@ struct DemoClient : public abyss::http::JSONRPC
|
|||
void
|
||||
DoDemoRequest()
|
||||
{
|
||||
llarp::json::Value params;
|
||||
params.SetObject();
|
||||
QueueRPC("test", std::move(params),
|
||||
QueueRPC("test", nlohmann::json::object(),
|
||||
std::bind(&DemoClient::NewConn, this, std::placeholders::_1));
|
||||
Flush();
|
||||
};
|
||||
|
|
|
@ -14,11 +14,11 @@ namespace abyss
|
|||
// big
|
||||
static const size_t MAX_BODY_SIZE = (1024 * 1024);
|
||||
llarp_tcp_conn* m_Conn;
|
||||
json::Document m_RequestBody;
|
||||
nlohmann::json m_RequestBody;
|
||||
Headers_t m_SendHeaders;
|
||||
IRPCClientHandler* handler;
|
||||
std::unique_ptr< json::IParser > m_BodyParser;
|
||||
json::Document m_Response;
|
||||
nlohmann::json m_Response;
|
||||
|
||||
enum State
|
||||
{
|
||||
|
@ -31,9 +31,12 @@ namespace abyss
|
|||
|
||||
State state;
|
||||
|
||||
ConnImpl(llarp_tcp_conn* conn, RPC_Method_t method, RPC_Params params,
|
||||
JSONRPC::HandlerFactory factory)
|
||||
: m_Conn(conn), state(eInitial)
|
||||
ConnImpl(llarp_tcp_conn* conn, const RPC_Method_t& method,
|
||||
const RPC_Params& params, JSONRPC::HandlerFactory factory)
|
||||
: m_Conn(conn)
|
||||
, m_RequestBody(nlohmann::json::object())
|
||||
, m_Response(nlohmann::json::object())
|
||||
, state(eInitial)
|
||||
{
|
||||
srand(time(nullptr));
|
||||
conn->user = this;
|
||||
|
@ -43,18 +46,12 @@ namespace abyss
|
|||
|
||||
handler = factory(this);
|
||||
|
||||
m_RequestBody.SetObject();
|
||||
auto& alloc = m_RequestBody.GetAllocator();
|
||||
m_RequestBody.AddMember("jsonrpc", json::Value().SetString("2.0"),
|
||||
alloc);
|
||||
m_RequestBody["jsonrpc"] = "2.0";
|
||||
llarp::AlignedBuffer< 8 > p;
|
||||
p.Randomize();
|
||||
std::string str = p.ToHex();
|
||||
m_RequestBody.AddMember(
|
||||
"id", json::Value().SetString(str.c_str(), alloc), alloc);
|
||||
m_RequestBody.AddMember(
|
||||
"method", json::Value().SetString(method.c_str(), alloc), alloc);
|
||||
m_RequestBody.AddMember("params", params, alloc);
|
||||
m_RequestBody["id"] = p.ToHex();
|
||||
m_RequestBody["method"] = method;
|
||||
m_RequestBody["params"] = params;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -220,8 +217,7 @@ namespace abyss
|
|||
// create request body
|
||||
std::string body;
|
||||
std::stringstream ss;
|
||||
json::ToString(m_RequestBody, ss);
|
||||
body = ss.str();
|
||||
body = m_RequestBody.dump();
|
||||
m_SendHeaders.emplace("Content-Type", "application/json");
|
||||
m_SendHeaders.emplace("Content-Length", std::to_string(body.size()));
|
||||
m_SendHeaders.emplace("Accept", "application/json");
|
||||
|
@ -347,8 +343,7 @@ namespace abyss
|
|||
}
|
||||
auto& front = m_PendingCalls.front();
|
||||
ConnImpl* connimpl =
|
||||
new ConnImpl(conn, std::move(front.method), std::move(front.params),
|
||||
std::move(front.createHandler));
|
||||
new ConnImpl(conn, front.method, front.params, front.createHandler);
|
||||
m_PendingCalls.pop_front();
|
||||
m_Conns.emplace_back(connimpl->handler);
|
||||
connimpl->SendRequest();
|
||||
|
|
|
@ -24,10 +24,7 @@ namespace abyss
|
|||
llarp_time_t m_ReadTimeout;
|
||||
bool m_Bad;
|
||||
std::unique_ptr< json::IParser > m_BodyParser;
|
||||
json::Document m_Request;
|
||||
std::stringstream m_ResponseBuffer;
|
||||
json::Stream m_ResponseStream;
|
||||
json::Writer m_Response;
|
||||
nlohmann::json m_Request;
|
||||
|
||||
enum HTTPState
|
||||
{
|
||||
|
@ -43,10 +40,7 @@ namespace abyss
|
|||
HTTPState m_State;
|
||||
|
||||
ConnImpl(BaseReqHandler* p, llarp_tcp_conn* c, llarp_time_t readtimeout)
|
||||
: _conn(c)
|
||||
, _parent(p)
|
||||
, m_ResponseStream(m_ResponseBuffer)
|
||||
, m_Response(m_ResponseStream)
|
||||
: _conn(c), _parent(p)
|
||||
{
|
||||
handler = nullptr;
|
||||
m_LastActive = p->now();
|
||||
|
@ -154,14 +148,13 @@ namespace abyss
|
|||
// initialize body parser
|
||||
if(m_BodyParser == nullptr)
|
||||
{
|
||||
ssize_t contentLength = 0;
|
||||
auto itr = Header.Headers.find("content-length");
|
||||
auto itr = Header.Headers.find("content-length");
|
||||
if(itr == Header.Headers.end())
|
||||
{
|
||||
return WriteResponseSimple(400, "Bad Request", "text/plain",
|
||||
"no content length");
|
||||
}
|
||||
contentLength = std::stoll(itr->second);
|
||||
ssize_t contentLength = std::stoll(itr->second);
|
||||
if(contentLength <= 0)
|
||||
{
|
||||
return WriteResponseSimple(400, "Bad Request", "text/plain",
|
||||
|
@ -186,22 +179,21 @@ namespace abyss
|
|||
return WriteResponseSimple(400, "Bad Request", "text/plain",
|
||||
"bad json object");
|
||||
case json::IParser::eDone:
|
||||
if(m_Request.IsObject() && m_Request.HasMember("params")
|
||||
&& m_Request.HasMember("method") && m_Request.HasMember("id")
|
||||
&& m_Request["id"].IsString() && m_Request["method"].IsString()
|
||||
&& m_Request["params"].IsObject())
|
||||
if(m_Request.is_object() && m_Request.count("params")
|
||||
&& m_Request.count("method") && m_Request.count("id")
|
||||
&& m_Request["id"].is_string() && m_Request["method"].is_string()
|
||||
&& m_Request["params"].is_object())
|
||||
{
|
||||
m_Response.StartObject();
|
||||
m_Response.Key("jsonrpc");
|
||||
m_Response.String("2.0");
|
||||
m_Response.Key("id");
|
||||
m_Response.String(m_Request["id"].GetString());
|
||||
m_Response.Key("result");
|
||||
if(handler->HandleJSONRPC(m_Request["method"].GetString(),
|
||||
m_Request["params"], m_Response))
|
||||
nlohmann::json response;
|
||||
response["jsonrpc"] = "2.0";
|
||||
response["id"] = m_Request["id"];
|
||||
auto value = handler->HandleJSONRPC(
|
||||
m_Request["method"].get< std::string >(),
|
||||
m_Request["params"]);
|
||||
if(value)
|
||||
{
|
||||
m_Response.EndObject();
|
||||
return WriteResponseJSON();
|
||||
response["result"] = value.value();
|
||||
return WriteResponseJSON(response);
|
||||
}
|
||||
}
|
||||
return WriteResponseSimple(500, "internal error", "text/plain",
|
||||
|
@ -212,13 +204,11 @@ namespace abyss
|
|||
}
|
||||
|
||||
bool
|
||||
WriteResponseJSON()
|
||||
WriteResponseJSON(const nlohmann::json& response)
|
||||
{
|
||||
std::string response;
|
||||
m_ResponseStream.Flush();
|
||||
response = m_ResponseBuffer.str();
|
||||
std::string responseStr = response.dump();
|
||||
return WriteResponseSimple(200, "OK", "application/json",
|
||||
response.c_str());
|
||||
responseStr.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -25,23 +25,28 @@ namespace llarp
|
|||
}
|
||||
|
||||
virtual bool
|
||||
HandleJSONResult(const json::Value& val) = 0;
|
||||
HandleJSONResult(const nlohmann::json& val) = 0;
|
||||
|
||||
bool
|
||||
HandleResponse(::abyss::http::RPC_Response response)
|
||||
{
|
||||
if(!response.IsObject())
|
||||
if(!response.is_object())
|
||||
{
|
||||
return HandleJSONResult({});
|
||||
}
|
||||
const auto itr = response.FindMember("result");
|
||||
if(itr == response.MemberEnd())
|
||||
const auto itr = response.find("result");
|
||||
if(itr == response.end())
|
||||
{
|
||||
return HandleJSONResult({});
|
||||
}
|
||||
if(itr->value.IsObject())
|
||||
return HandleJSONResult(itr->value);
|
||||
return false;
|
||||
else if(itr.value().is_object())
|
||||
{
|
||||
return HandleJSONResult(itr.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -65,42 +70,40 @@ namespace llarp
|
|||
}
|
||||
|
||||
bool
|
||||
HandleJSONResult(const json::Value& result) override
|
||||
HandleJSONResult(const nlohmann::json& result) override
|
||||
{
|
||||
PubkeyList_t keys;
|
||||
if(!result.IsObject())
|
||||
if(!result.is_object())
|
||||
{
|
||||
LogWarn("Invalid result: not an object");
|
||||
handler({}, false);
|
||||
return false;
|
||||
}
|
||||
const auto itr = result.FindMember("keys");
|
||||
if(itr == result.MemberEnd())
|
||||
const auto itr = result.find("keys");
|
||||
if(itr == result.end())
|
||||
{
|
||||
LogWarn("Invalid result: no keys member");
|
||||
handler({}, false);
|
||||
return false;
|
||||
}
|
||||
if(!itr->value.IsArray())
|
||||
if(!itr.value().is_array())
|
||||
{
|
||||
LogWarn("Invalid result: keys is not an array");
|
||||
handler({}, false);
|
||||
return false;
|
||||
}
|
||||
auto key_itr = itr->value.Begin();
|
||||
while(key_itr != itr->value.End())
|
||||
for(const auto item : itr.value())
|
||||
{
|
||||
if(key_itr->IsString())
|
||||
if(item.is_string())
|
||||
{
|
||||
keys.emplace_back();
|
||||
std::string str = key_itr->GetString();
|
||||
std::string str = item.get< std::string >();
|
||||
if(!Base32Decode(str, keys.back()))
|
||||
{
|
||||
LogWarn("Invalid key: ", str);
|
||||
keys.pop_back();
|
||||
}
|
||||
}
|
||||
++key_itr;
|
||||
}
|
||||
handler(keys, true);
|
||||
return true;
|
||||
|
@ -149,9 +152,7 @@ namespace llarp
|
|||
AsyncUpdatePubkeyList()
|
||||
{
|
||||
LogInfo("Updating service node list");
|
||||
json::Value params;
|
||||
params.SetObject();
|
||||
QueueRPC("get_all_service_nodes_keys", std::move(params),
|
||||
QueueRPC("get_all_service_nodes_keys", nlohmann::json::object(),
|
||||
std::bind(&CallerImpl::NewAsyncUpdatePubkeyListConn, this,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
@ -211,75 +212,59 @@ namespace llarp
|
|||
{
|
||||
}
|
||||
|
||||
bool
|
||||
DumpState(Response& resp) const
|
||||
Response
|
||||
DumpState() const
|
||||
{
|
||||
util::StatusObject dump = router->ExtractStatus();
|
||||
dump.Impl.Accept(resp);
|
||||
return true;
|
||||
return dump.get();
|
||||
}
|
||||
|
||||
bool
|
||||
ListExitLevels(Response& resp) const
|
||||
Response
|
||||
ListExitLevels() const
|
||||
{
|
||||
exit::Context::TrafficStats stats;
|
||||
router->exitContext().CalculateExitTraffic(stats);
|
||||
resp.StartArray();
|
||||
auto itr = stats.begin();
|
||||
while(itr != stats.end())
|
||||
Response resp;
|
||||
|
||||
for(const auto& stat : stats)
|
||||
{
|
||||
resp.StartObject();
|
||||
resp.Key("ident");
|
||||
resp.String(itr->first.ToHex().c_str());
|
||||
resp.Key("tx");
|
||||
resp.Uint64(itr->second.first);
|
||||
resp.Key("rx");
|
||||
resp.Uint64(itr->second.second);
|
||||
resp.EndObject();
|
||||
++itr;
|
||||
resp.emplace_back(Response{
|
||||
{"ident", stat.first.ToHex()},
|
||||
{"tx", stat.second.first},
|
||||
{"rx", stat.second.second},
|
||||
});
|
||||
}
|
||||
resp.EndArray();
|
||||
return true;
|
||||
return resp;
|
||||
}
|
||||
|
||||
bool
|
||||
ListNeighboors(Response& resp) const
|
||||
Response
|
||||
ListNeighboors() const
|
||||
{
|
||||
resp.StartArray();
|
||||
Response resp = Response::array();
|
||||
router->ForEachPeer([&](const ILinkSession* session, bool outbound) {
|
||||
resp.StartObject();
|
||||
auto ident = RouterID(session->GetPubKey()).ToString();
|
||||
resp.Key("ident");
|
||||
resp.String(ident.c_str());
|
||||
|
||||
auto addr = session->GetRemoteEndpoint().ToString();
|
||||
resp.Key("addr");
|
||||
resp.String(addr.c_str());
|
||||
|
||||
resp.Key("outbound");
|
||||
resp.Bool(outbound);
|
||||
resp.EndObject();
|
||||
resp.emplace_back(
|
||||
Response{{"ident", RouterID(session->GetPubKey()).ToString()},
|
||||
{"addr", session->GetRemoteEndpoint().ToString()},
|
||||
{"outbound", outbound}});
|
||||
});
|
||||
resp.EndArray();
|
||||
return true;
|
||||
return resp;
|
||||
}
|
||||
|
||||
bool
|
||||
absl::optional< Response >
|
||||
HandleJSONRPC(Method_t method,
|
||||
__attribute__((unused)) const Params& params,
|
||||
Response& response)
|
||||
__attribute__((unused)) const Params& params)
|
||||
{
|
||||
if(method == "llarp.admin.link.neighboors")
|
||||
{
|
||||
return ListNeighboors(response);
|
||||
return ListNeighboors();
|
||||
}
|
||||
else if(method == "llarp.admin.exit.list")
|
||||
{
|
||||
return ListExitLevels(response);
|
||||
return ListExitLevels();
|
||||
}
|
||||
else if(method == "llarp.admin.dumpstate")
|
||||
{
|
||||
return DumpState(response);
|
||||
return DumpState();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,12 @@ namespace llarp
|
|||
{
|
||||
namespace json
|
||||
{
|
||||
struct RapidJSONParser : public IParser
|
||||
struct NlohmannJSONParser : public IParser
|
||||
{
|
||||
RapidJSONParser(size_t contentSize) : m_Buf(contentSize + 1), m_Offset(0)
|
||||
NlohmannJSONParser(size_t contentSize)
|
||||
: m_Buf(contentSize + 1), m_Offset(0)
|
||||
{
|
||||
assert(contentSize != 0);
|
||||
}
|
||||
|
||||
std::vector< char > m_Buf;
|
||||
|
@ -23,36 +25,34 @@ namespace llarp
|
|||
{
|
||||
if(m_Offset + sz > m_Buf.size() - 1)
|
||||
return false;
|
||||
memcpy(m_Buf.data() + m_Offset, buf, sz);
|
||||
std::copy(buf, buf + sz, m_Buf.begin());
|
||||
m_Offset += sz;
|
||||
m_Buf[m_Offset] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
Result
|
||||
Parse(Document& obj) const
|
||||
Parse(nlohmann::json& obj) const
|
||||
{
|
||||
if(m_Offset < m_Buf.size() - 1)
|
||||
return eNeedData;
|
||||
obj.Parse(m_Buf.data());
|
||||
if(obj.HasParseError())
|
||||
|
||||
try
|
||||
{
|
||||
obj = nlohmann::json::parse(m_Buf.data());
|
||||
return eDone;
|
||||
}
|
||||
catch(const nlohmann::json::exception&)
|
||||
{
|
||||
return eParseError;
|
||||
return eDone;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IParser*
|
||||
MakeParser(size_t contentSize)
|
||||
{
|
||||
return new RapidJSONParser(contentSize);
|
||||
}
|
||||
|
||||
void
|
||||
ToString(const json::Document& val, std::ostream& out)
|
||||
{
|
||||
Stream s(out);
|
||||
rapidjson::Writer< Stream > writer(s);
|
||||
val.Accept(writer);
|
||||
return new NlohmannJSONParser(contentSize);
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
|
|
@ -6,81 +6,13 @@
|
|||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace json
|
||||
{
|
||||
/// add this because debian stable doesn't have it
|
||||
template < typename StreamType >
|
||||
class BasicOStreamWrapper
|
||||
{
|
||||
public:
|
||||
typedef typename StreamType::char_type Ch;
|
||||
BasicOStreamWrapper(StreamType& stream) : stream_(stream)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Put(Ch c)
|
||||
{
|
||||
stream_.put(c);
|
||||
}
|
||||
|
||||
void
|
||||
Flush()
|
||||
{
|
||||
stream_.flush();
|
||||
}
|
||||
|
||||
// Not implemented
|
||||
char
|
||||
Peek() const
|
||||
{
|
||||
RAPIDJSON_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
char
|
||||
Take()
|
||||
{
|
||||
RAPIDJSON_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
size_t
|
||||
Tell() const
|
||||
{
|
||||
RAPIDJSON_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
char*
|
||||
PutBegin()
|
||||
{
|
||||
RAPIDJSON_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
size_t
|
||||
PutEnd(char*)
|
||||
{
|
||||
RAPIDJSON_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
BasicOStreamWrapper(const BasicOStreamWrapper&);
|
||||
BasicOStreamWrapper&
|
||||
operator=(const BasicOStreamWrapper&);
|
||||
|
||||
StreamType& stream_;
|
||||
};
|
||||
|
||||
using Document = rapidjson::Document;
|
||||
using Value = rapidjson::Value;
|
||||
using Stream = BasicOStreamWrapper< std::ostream >;
|
||||
using Writer = rapidjson::Writer< Stream >;
|
||||
} // namespace json
|
||||
|
||||
namespace json
|
||||
{
|
||||
struct IParser
|
||||
|
@ -103,16 +35,13 @@ namespace llarp
|
|||
FeedData(const char* buf, size_t sz) = 0;
|
||||
/// parse internal buffer
|
||||
virtual Result
|
||||
Parse(Document& obj) const = 0;
|
||||
Parse(nlohmann::json& obj) const = 0;
|
||||
};
|
||||
|
||||
/// create new parser
|
||||
IParser*
|
||||
MakeParser(size_t contentSize);
|
||||
|
||||
void
|
||||
ToString(const json::Document& obj, std::ostream& out);
|
||||
|
||||
} // namespace json
|
||||
} // namespace llarp
|
||||
|
||||
|
|
|
@ -1,21 +1,54 @@
|
|||
#include <util/status.hpp>
|
||||
|
||||
#include <util/traits.hpp>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
StatusObject::StatusObject(const StatusObject& other)
|
||||
struct StatusVisitor
|
||||
{
|
||||
Impl.SetObject();
|
||||
auto& a = Impl.GetAllocator();
|
||||
Impl.CopyFrom(other.Impl, a);
|
||||
}
|
||||
|
||||
StatusObject::~StatusObject()
|
||||
{
|
||||
Impl.RemoveAllMembers();
|
||||
}
|
||||
std::string name;
|
||||
std::reference_wrapper< nlohmann::json > data;
|
||||
|
||||
StatusVisitor(StatusObject::String_t n, nlohmann::json& d)
|
||||
: name(n), data(d)
|
||||
{
|
||||
}
|
||||
void
|
||||
operator()(uint64_t val)
|
||||
{
|
||||
data.get()[name] = val;
|
||||
}
|
||||
void
|
||||
operator()(const std::string& val)
|
||||
{
|
||||
data.get()[name] = val;
|
||||
}
|
||||
void
|
||||
operator()(bool val)
|
||||
{
|
||||
data.get()[name] = val;
|
||||
}
|
||||
void
|
||||
operator()(const StatusObject& obj)
|
||||
{
|
||||
data.get()[name] = obj.Impl;
|
||||
}
|
||||
void
|
||||
operator()(const std::vector< std::string >& val)
|
||||
{
|
||||
data.get()[name] = val;
|
||||
}
|
||||
void
|
||||
operator()(const std::vector< StatusObject >& val)
|
||||
{
|
||||
auto arr = nlohmann::json::array();
|
||||
std::transform(val.begin(), val.end(), std::back_inserter(arr),
|
||||
[](const auto& x) { return x.Impl; });
|
||||
data.get()[name] = arr;
|
||||
}
|
||||
};
|
||||
void
|
||||
StatusObject::Put(const value_type& val)
|
||||
{
|
||||
|
@ -23,99 +56,9 @@ namespace llarp
|
|||
}
|
||||
|
||||
void
|
||||
StatusObject::Put(String_t name, const Variant& val)
|
||||
StatusObject::Put(String_t name, const Variant& data)
|
||||
{
|
||||
if(absl::holds_alternative< uint64_t >(val))
|
||||
PutInt(name, absl::get< uint64_t >(val));
|
||||
else if(absl::holds_alternative< std::string >(val))
|
||||
PutString(name, absl::get< std::string >(val));
|
||||
else if(absl::holds_alternative< bool >(val))
|
||||
PutBool(name, absl::get< bool >(val));
|
||||
else if(absl::holds_alternative< StatusObject >(val))
|
||||
PutObject(name, absl::get< StatusObject >(val));
|
||||
else if(absl::holds_alternative< std::vector< std::string > >(val))
|
||||
PutStringArray(name, absl::get< std::vector< std::string > >(val));
|
||||
else if(absl::holds_alternative< std::vector< StatusObject > >(val))
|
||||
PutObjectArray(name, absl::get< std::vector< StatusObject > >(val));
|
||||
}
|
||||
|
||||
void
|
||||
StatusObject::PutBool(String_t name, bool val)
|
||||
{
|
||||
auto& a = Impl.GetAllocator();
|
||||
Value_t v;
|
||||
v.SetBool(val);
|
||||
auto s = llarp::string_view_string(name);
|
||||
Value_t k(s.c_str(), a);
|
||||
Impl.AddMember(k, v, a);
|
||||
}
|
||||
|
||||
void
|
||||
StatusObject::PutInt(String_t name, uint64_t val)
|
||||
{
|
||||
auto& a = Impl.GetAllocator();
|
||||
Value_t v;
|
||||
v.SetUint64(val);
|
||||
auto s = llarp::string_view_string(name);
|
||||
Value_t k(s.c_str(), a);
|
||||
Impl.AddMember(k, v, a);
|
||||
}
|
||||
|
||||
void
|
||||
StatusObject::PutObject(String_t name, const StatusObject& val)
|
||||
{
|
||||
auto& a = Impl.GetAllocator();
|
||||
Value_t v;
|
||||
v.SetObject();
|
||||
v.CopyFrom(val.Impl, a);
|
||||
auto s = llarp::string_view_string(name);
|
||||
Value_t k(s.c_str(), a);
|
||||
Impl.AddMember(k, v, a);
|
||||
}
|
||||
|
||||
void
|
||||
StatusObject::PutObjectArray(String_t name,
|
||||
const std::vector< StatusObject >& arr)
|
||||
{
|
||||
auto& a = Impl.GetAllocator();
|
||||
Value_t v;
|
||||
v.SetArray();
|
||||
Value_t i;
|
||||
for(const auto& obj : arr)
|
||||
{
|
||||
v.PushBack(i.SetObject().CopyFrom(obj.Impl, a), a);
|
||||
}
|
||||
auto s = llarp::string_view_string(name);
|
||||
Value_t k(s.c_str(), a);
|
||||
Impl.AddMember(k, v, a);
|
||||
}
|
||||
|
||||
void
|
||||
StatusObject::PutStringArray(String_t name,
|
||||
const std::vector< std::string >& arr)
|
||||
{
|
||||
auto& a = Impl.GetAllocator();
|
||||
Value_t v;
|
||||
v.SetArray();
|
||||
Value_t i;
|
||||
for(const auto& str : arr)
|
||||
{
|
||||
v.PushBack(i.SetString(str.c_str(), a), a);
|
||||
}
|
||||
auto s = llarp::string_view_string(name);
|
||||
Value_t k(s.c_str(), a);
|
||||
Impl.AddMember(k, v, a);
|
||||
}
|
||||
|
||||
void
|
||||
StatusObject::PutString(String_t name, const std::string& val)
|
||||
{
|
||||
auto& a = Impl.GetAllocator();
|
||||
Value_t v;
|
||||
v.SetString(val.c_str(), a);
|
||||
auto s = llarp::string_view_string(name);
|
||||
Value_t k(s.c_str(), a);
|
||||
Impl.AddMember(k, v, a);
|
||||
absl::visit(StatusVisitor{name, Impl}, data);
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace llarp
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#ifndef LLARP_UTIL_STATUS_HPP
|
||||
#define LLARP_UTIL_STATUS_HPP
|
||||
|
||||
#include <util/json.hpp>
|
||||
#include <util/string_view.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
@ -13,23 +14,17 @@ namespace llarp
|
|||
{
|
||||
namespace util
|
||||
{
|
||||
using StatusObject_Impl = json::Document;
|
||||
using Value_t = json::Value;
|
||||
|
||||
struct StatusVisitor;
|
||||
struct StatusObject
|
||||
{
|
||||
using String_t = string_view;
|
||||
using Variant = absl::variant< uint64_t, std::string, bool, StatusObject,
|
||||
std::vector< std::string >,
|
||||
std::vector< StatusObject > >;
|
||||
using value_type = std::tuple< String_t, Variant >;
|
||||
|
||||
StatusObject(const StatusObject&);
|
||||
~StatusObject();
|
||||
using value_type = std::pair< String_t, Variant >;
|
||||
|
||||
StatusObject(std::initializer_list< value_type > vals)
|
||||
{
|
||||
Impl.SetObject();
|
||||
std::for_each(vals.begin(), vals.end(),
|
||||
[&](const value_type& item) { Put(item); });
|
||||
}
|
||||
|
@ -40,21 +35,15 @@ namespace llarp
|
|||
void
|
||||
Put(const value_type& value);
|
||||
|
||||
StatusObject_Impl Impl;
|
||||
nlohmann::json
|
||||
get() const
|
||||
{
|
||||
return Impl;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
PutBool(String_t name, bool val);
|
||||
void
|
||||
PutInt(String_t name, uint64_t val);
|
||||
void
|
||||
PutObject(String_t name, const StatusObject& val);
|
||||
void
|
||||
PutObjectArray(String_t name, const std::vector< StatusObject >& arr);
|
||||
void
|
||||
PutStringArray(String_t name, const std::vector< std::string >& arr);
|
||||
void
|
||||
PutString(String_t name, const std::string& val);
|
||||
friend struct StatusVisitor;
|
||||
nlohmann::json Impl;
|
||||
};
|
||||
|
||||
/// an entity that has a status that can be extracted
|
||||
|
|
|
@ -110,7 +110,7 @@ struct ClientHandler : public abyss::http::IRPCClientHandler
|
|||
void
|
||||
HandleError()
|
||||
{
|
||||
ASSERT_TRUE(false);
|
||||
FAIL() << "unexpected error";
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -134,15 +134,12 @@ struct ServerHandler : public abyss::httpd::IRPCHandler
|
|||
{
|
||||
}
|
||||
|
||||
bool
|
||||
HandleJSONRPC(Method_t method, __attribute__((unused)) const Params& params,
|
||||
Response& response)
|
||||
absl::optional< Response >
|
||||
HandleJSONRPC(Method_t method, __attribute__((unused)) const Params& params)
|
||||
{
|
||||
test->AssertMethod(method);
|
||||
test->called = true;
|
||||
response.StartObject();
|
||||
response.EndObject();
|
||||
return true;
|
||||
return Response();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -200,9 +197,7 @@ struct AbyssTest : public AbyssTestBase,
|
|||
TEST_F(AbyssTest, TestClientAndServer)
|
||||
{
|
||||
Start();
|
||||
llarp::json::Value params;
|
||||
params.SetObject();
|
||||
QueueRPC(method, std::move(params),
|
||||
QueueRPC(method, nlohmann::json::object(),
|
||||
std::bind(&AbyssTest::NewConn, this, std::placeholders::_1));
|
||||
|
||||
AsyncFlush();
|
||||
|
|
Loading…
Reference in New Issue