New generic Ledger RPC handler.

This commit is contained in:
Tom Ritchford
2014-12-03 18:15:28 -05:00
committed by Vinnie Falco
parent 1cbcc7be21
commit 167f4666e2
8 changed files with 285 additions and 122 deletions

View File

@@ -23,6 +23,7 @@
#include <ripple/server/Role.h> #include <ripple/server/Role.h>
#include <ripple/core/Config.h> #include <ripple/core/Config.h>
#include <ripple/net/InfoSub.h> #include <ripple/net/InfoSub.h>
#include <ripple/rpc/Yield.h>
namespace ripple { namespace ripple {
@@ -34,16 +35,20 @@ public:
explicit RPCHandler ( explicit RPCHandler (
NetworkOPs& netOps, InfoSub::pointer infoSub = nullptr); NetworkOPs& netOps, InfoSub::pointer infoSub = nullptr);
using Yield = RPC::Yield;
Json::Value doCommand ( Json::Value doCommand (
Json::Value const& request, Json::Value const& request,
Role role, Role role,
Resource::Charge& loadType); Resource::Charge& loadType,
Yield yield = {});
Json::Value doRpcCommand ( Json::Value doRpcCommand (
std::string const& command, std::string const& command,
Json::Value const& params, Json::Value const& params,
Role role, Role role,
Resource::Charge& loadType); Resource::Charge& loadType,
Yield yield = {});
private: private:
NetworkOPs& netOps_; NetworkOPs& netOps_;

View File

@@ -38,7 +38,6 @@ Json::Value doFeature (RPC::Context&);
Json::Value doFetchInfo (RPC::Context&); Json::Value doFetchInfo (RPC::Context&);
Json::Value doGetCounts (RPC::Context&); Json::Value doGetCounts (RPC::Context&);
Json::Value doInternal (RPC::Context&); Json::Value doInternal (RPC::Context&);
Json::Value doLedger (RPC::Context&);
Json::Value doLedgerAccept (RPC::Context&); Json::Value doLedgerAccept (RPC::Context&);
Json::Value doLedgerCleaner (RPC::Context&); Json::Value doLedgerCleaner (RPC::Context&);
Json::Value doLedgerClosed (RPC::Context&); Json::Value doLedgerClosed (RPC::Context&);

View File

@@ -17,77 +17,73 @@
*/ */
//============================================================================== //==============================================================================
#include <ripple/app/ledger/LedgerToJson.h>
#include <ripple/core/LoadFeeTrack.h> #include <ripple/core/LoadFeeTrack.h>
#include <ripple/rpc/ErrorCodes.h>
#include <ripple/rpc/handlers/Ledger.h>
#include <ripple/rpc/impl/JsonObject.h>
#include <ripple/server/Role.h> #include <ripple/server/Role.h>
namespace ripple { namespace ripple {
namespace RPC {
// ledger [id|index|current|closed] [full] LedgerHandler::LedgerHandler (Context& context) : context_ (context)
// {
// ledger: 'current' | 'closed' | <uint256> | <number>, // optional
// full: true | false // optional, defaults to false.
// }
Json::Value doLedger (RPC::Context& context)
{ {
if (!context.params.isMember ("ledger") }
&& !context.params.isMember ("ledger_hash")
&& !context.params.isMember ("ledger_index")) Status LedgerHandler::check (Json::Value& error)
{
bool needsLedger = context_.params.isMember (jss::ledger) ||
context_.params.isMember (jss::ledger_hash) ||
context_.params.isMember (jss::ledger_index);
if (!needsLedger)
return Status::OK;
lookupResult_ = RPC::lookupLedger (
context_.params, ledger_, context_.netOps);
if (!ledger_)
{ {
Json::Value ret (Json::objectValue), current (Json::objectValue), error = lookupResult_;
closed (Json::objectValue); auto code = error_code_i (error[jss::error_code].asInt());
return {code, {error[jss::error_message].asString()}};
getApp().getLedgerMaster ().getCurrentLedger ()->addJson (current, 0);
getApp().getLedgerMaster ().getClosedLedger ()->addJson (closed, 0);
ret["open"] = current;
ret["closed"] = closed;
return ret;
} }
Ledger::pointer lpLedger; bool bFull = context_.params.isMember (jss::full)
Json::Value jvResult = RPC::lookupLedger ( && context_.params[jss::full].asBool ();
context.params, lpLedger, context.netOps); bool bTransactions = context_.params.isMember (jss::transactions)
&& context_.params[jss::transactions].asBool ();
if (!lpLedger) bool bAccounts = context_.params.isMember (jss::accounts)
return jvResult; && context_.params[jss::accounts].asBool ();
bool bExpand = context_.params.isMember (jss::expand)
bool bFull = context.params.isMember ("full") && context_.params[jss::expand].asBool ();
&& context.params["full"].asBool (); options_ = (bFull ? LEDGER_JSON_FULL : 0)
bool bTransactions = context.params.isMember ("transactions") | (bExpand ? LEDGER_JSON_EXPAND : 0)
&& context.params["transactions"].asBool (); | (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0)
bool bAccounts = context.params.isMember ("accounts") | (bAccounts ? LEDGER_JSON_DUMP_STATE : 0);
&& context.params["accounts"].asBool ();
bool bExpand = context.params.isMember ("expand")
&& context.params["expand"].asBool ();
int iOptions = (bFull ? LEDGER_JSON_FULL : 0)
| (bExpand ? LEDGER_JSON_EXPAND : 0)
| (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0)
| (bAccounts ? LEDGER_JSON_DUMP_STATE : 0);
if (bFull || bAccounts) if (bFull || bAccounts)
{ {
if (context_.role != Role::ADMIN)
if (context.role != Role::ADMIN)
{ {
// Until some sane way to get full ledgers has been implemented, // Until some sane way to get full ledgers has been implemented,
// disallow retrieving all state nodes. // disallow retrieving all state nodes.
return rpcError (rpcNO_PERMISSION); error = rpcError (rpcNO_PERMISSION);
return rpcNO_PERMISSION;
} }
if (getApp().getFeeTrack().isLoadedLocal() && if (getApp().getFeeTrack().isLoadedLocal() &&
context.role != Role::ADMIN) context_.role != Role::ADMIN)
{ {
WriteLog (lsDEBUG, Peer) << "Too busy to give full ledger"; error = rpcError(rpcTOO_BUSY);
return rpcError(rpcTOO_BUSY); return rpcTOO_BUSY;
} }
context.loadType = Resource::feeHighBurdenRPC; context_.loadType = Resource::feeHighBurdenRPC;
} }
std::cerr << "!!! LedgerHandler::check FIVE - true\n";
lpLedger->addJson (jvResult, iOptions); return Status::OK;
return jvResult;
} }
} // RPC
} // ripple } // ripple

View File

@@ -0,0 +1,102 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLED_RIPPLE_RPC_HANDLERS_LEDGER_H
#define RIPPLED_RIPPLE_RPC_HANDLERS_LEDGER_H
#include <ripple/app/ledger/LedgerToJson.h>
#include <ripple/core/LoadFeeTrack.h>
#include <ripple/rpc/impl/JsonObject.h>
#include <ripple/server/Role.h>
namespace ripple {
namespace RPC {
class Object;
// ledger [id|index|current|closed] [full]
// {
// ledger: 'current' | 'closed' | <uint256> | <number>, // optional
// full: true | false // optional, defaults to false.
// }
class LedgerHandler {
public:
explicit LedgerHandler (Context&);
Status check (Json::Value& error);
template <class Object>
void writeResult (Object&);
static const char* const name()
{
return "ledger";
}
static Role role()
{
return Role::USER;
}
static Condition condition()
{
return NEEDS_NETWORK_CONNECTION;
}
private:
Context& context_;
Ledger::pointer ledger_;
Json::Value lookupResult_;
int options_;
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Implementation.
template <class Object>
void LedgerHandler::writeResult (Object& value)
{
if (ledger_)
{
RPC::copyFrom (value, lookupResult_);
addJson (*ledger_, value, options_, context_.yield);
}
else
{
auto& master = getApp().getLedgerMaster ();
auto& yield = context_.yield;
{
auto&& closed = RPC::addObject (value, jss::closed);
addJson (*master.getClosedLedger(), closed, 0, yield);
}
{
auto&& open = RPC::addObject (value, jss::open);
addJson (*master.getCurrentLedger(), open, 0, yield);
}
}
}
} // RPC
} // ripple
#endif

View File

@@ -21,6 +21,7 @@
#define RIPPLE_RPC_CONTEXT #define RIPPLE_RPC_CONTEXT
#include <ripple/core/Config.h> #include <ripple/core/Config.h>
#include <ripple/rpc/Yield.h>
#include <ripple/server/ServerHandler.h> #include <ripple/server/ServerHandler.h>
namespace ripple { namespace ripple {
@@ -34,6 +35,7 @@ struct Context
NetworkOPs& netOps; NetworkOPs& netOps;
InfoSub::pointer infoSub; InfoSub::pointer infoSub;
Role role; Role role;
RPC::Yield yield;
}; };
} // RPC } // RPC

View File

@@ -24,11 +24,28 @@ namespace ripple {
namespace RPC { namespace RPC {
namespace { namespace {
/** Adjust an old-style handler to be call-by-reference. */
template <typename Function>
Handler::Method<Json::Value> byRef (Function const& f)
{
return [f] (Context& context, Json::Value& result)
{
result = f (context);
return Status();
};
}
class HandlerTable { class HandlerTable {
public: public:
HandlerTable(std::vector<Handler> const& entries) { HandlerTable (std::vector<Handler> const& entries) {
for (auto& entry: entries) for (auto& entry: entries)
{
assert (table_.find(entry.name_) == table_.end());
table_[entry.name_] = entry; table_[entry.name_] = entry;
}
// This is where the new-style handlers are added.
addHandler<LedgerHandler>();
} }
const Handler* getHandler(std::string name) { const Handler* getHandler(std::string name) {
@@ -38,75 +55,109 @@ class HandlerTable {
private: private:
std::map<std::string, Handler> table_; std::map<std::string, Handler> table_;
template <class Impl>
void addHandler()
{
assert (table_.find(Impl::name()) == table_.end());
auto valueMethod = [] (Context& context, Json::Value& object)
{
Impl handler (context);
auto status = handler.check (object);
if (!status)
handler.writeResult (object);
return status;
};
auto objectMethod = [] (Context& context, Object& object)
{
Impl handler (context);
Json::Value error;
auto status = handler.check (error);
if (!status)
handler.writeResult (object);
else
RPC::copyFrom (object, error);
return status;
};
auto handler = Handler {
Impl::name(),
valueMethod,
Impl::role(),
Impl::condition(),
objectMethod};
table_[Impl::name()] = handler;
};
}; };
HandlerTable HANDLERS({ HandlerTable HANDLERS({
// Request-response methods // Request-response methods
{ "account_info", &doAccountInfo, Role::USER, NEEDS_CURRENT_LEDGER }, { "account_info", byRef (&doAccountInfo), Role::USER, NEEDS_CURRENT_LEDGER },
{ "account_currencies", &doAccountCurrencies, Role::USER, NEEDS_CURRENT_LEDGER }, { "account_currencies", byRef (&doAccountCurrencies), Role::USER, NEEDS_CURRENT_LEDGER },
{ "account_lines", &doAccountLines, Role::USER, NEEDS_CURRENT_LEDGER }, { "account_lines", byRef (&doAccountLines), Role::USER, NEEDS_CURRENT_LEDGER },
{ "account_offers", &doAccountOffers, Role::USER, NEEDS_CURRENT_LEDGER }, { "account_offers", byRef (&doAccountOffers), Role::USER, NEEDS_CURRENT_LEDGER },
{ "account_tx", &doAccountTxSwitch, Role::USER, NEEDS_NETWORK_CONNECTION }, { "account_tx", byRef (&doAccountTxSwitch), Role::USER, NEEDS_NETWORK_CONNECTION },
{ "blacklist", &doBlackList, Role::ADMIN, NO_CONDITION }, { "blacklist", byRef (&doBlackList), Role::ADMIN, NO_CONDITION },
{ "book_offers", &doBookOffers, Role::USER, NEEDS_CURRENT_LEDGER }, { "book_offers", byRef (&doBookOffers), Role::USER, NEEDS_CURRENT_LEDGER },
{ "can_delete", &doCanDelete, Role::ADMIN, NO_CONDITION }, { "can_delete", byRef (&doCanDelete), Role::ADMIN, NO_CONDITION },
{ "connect", &doConnect, Role::ADMIN, NO_CONDITION }, { "connect", byRef (&doConnect), Role::ADMIN, NO_CONDITION },
{ "consensus_info", &doConsensusInfo, Role::ADMIN, NO_CONDITION }, { "consensus_info", byRef (&doConsensusInfo), Role::ADMIN, NO_CONDITION },
{ "get_counts", &doGetCounts, Role::ADMIN, NO_CONDITION }, { "get_counts", byRef (&doGetCounts), Role::ADMIN, NO_CONDITION },
{ "internal", &doInternal, Role::ADMIN, NO_CONDITION }, { "internal", byRef (&doInternal), Role::ADMIN, NO_CONDITION },
{ "feature", &doFeature, Role::ADMIN, NO_CONDITION }, { "feature", byRef (&doFeature), Role::ADMIN, NO_CONDITION },
{ "fetch_info", &doFetchInfo, Role::ADMIN, NO_CONDITION }, { "fetch_info", byRef (&doFetchInfo), Role::ADMIN, NO_CONDITION },
{ "ledger", &doLedger, Role::USER, NEEDS_NETWORK_CONNECTION }, { "ledger_accept", byRef (&doLedgerAccept), Role::ADMIN, NEEDS_CURRENT_LEDGER },
{ "ledger_accept", &doLedgerAccept, Role::ADMIN, NEEDS_CURRENT_LEDGER }, { "ledger_cleaner", byRef (&doLedgerCleaner), Role::ADMIN, NEEDS_NETWORK_CONNECTION },
{ "ledger_cleaner", &doLedgerCleaner, Role::ADMIN, NEEDS_NETWORK_CONNECTION }, { "ledger_closed", byRef (&doLedgerClosed), Role::USER, NEEDS_CLOSED_LEDGER },
{ "ledger_closed", &doLedgerClosed, Role::USER, NEEDS_CLOSED_LEDGER }, { "ledger_current", byRef (&doLedgerCurrent), Role::USER, NEEDS_CURRENT_LEDGER },
{ "ledger_current", &doLedgerCurrent, Role::USER, NEEDS_CURRENT_LEDGER }, { "ledger_data", byRef (&doLedgerData), Role::USER, NEEDS_CURRENT_LEDGER },
{ "ledger_data", &doLedgerData, Role::USER, NEEDS_CURRENT_LEDGER }, { "ledger_entry", byRef (&doLedgerEntry), Role::USER, NEEDS_CURRENT_LEDGER },
{ "ledger_entry", &doLedgerEntry, Role::USER, NEEDS_CURRENT_LEDGER }, { "ledger_header", byRef (&doLedgerHeader), Role::USER, NEEDS_CURRENT_LEDGER },
{ "ledger_header", &doLedgerHeader, Role::USER, NEEDS_CURRENT_LEDGER }, { "ledger_request", byRef (&doLedgerRequest), Role::ADMIN, NO_CONDITION },
{ "ledger_request", &doLedgerRequest, Role::ADMIN, NO_CONDITION }, { "log_level", byRef (&doLogLevel), Role::ADMIN, NO_CONDITION },
{ "log_level", &doLogLevel, Role::ADMIN, NO_CONDITION }, { "logrotate", byRef (&doLogRotate), Role::ADMIN, NO_CONDITION },
{ "logrotate", &doLogRotate, Role::ADMIN, NO_CONDITION }, { "owner_info", byRef (&doOwnerInfo), Role::USER, NEEDS_CURRENT_LEDGER },
{ "owner_info", &doOwnerInfo, Role::USER, NEEDS_CURRENT_LEDGER }, { "peers", byRef (&doPeers), Role::ADMIN, NO_CONDITION },
{ "peers", &doPeers, Role::ADMIN, NO_CONDITION }, { "path_find", byRef (&doPathFind), Role::USER, NEEDS_CURRENT_LEDGER },
{ "path_find", &doPathFind, Role::USER, NEEDS_CURRENT_LEDGER }, { "ping", byRef (&doPing), Role::USER, NO_CONDITION },
{ "ping", &doPing, Role::USER, NO_CONDITION }, { "print", byRef (&doPrint), Role::ADMIN, NO_CONDITION },
{ "print", &doPrint, Role::ADMIN, NO_CONDITION }, // { "profile", byRef (&doProfile), Role::USER, NEEDS_CURRENT_LEDGER },
// { "profile", &doProfile, Role::USER, NEEDS_CURRENT_LEDGER }, { "proof_create", byRef (&doProofCreate), Role::ADMIN, NO_CONDITION },
{ "proof_create", &doProofCreate, Role::ADMIN, NO_CONDITION }, { "proof_solve", byRef (&doProofSolve), Role::ADMIN, NO_CONDITION },
{ "proof_solve", &doProofSolve, Role::ADMIN, NO_CONDITION }, { "proof_verify", byRef (&doProofVerify), Role::ADMIN, NO_CONDITION },
{ "proof_verify", &doProofVerify, Role::ADMIN, NO_CONDITION }, { "random", byRef (&doRandom), Role::USER, NO_CONDITION },
{ "random", &doRandom, Role::USER, NO_CONDITION }, { "ripple_path_find", byRef (&doRipplePathFind), Role::USER, NEEDS_CURRENT_LEDGER },
{ "ripple_path_find", &doRipplePathFind, Role::USER, NEEDS_CURRENT_LEDGER }, { "sign", byRef (&doSign), Role::USER, NO_CONDITION },
{ "sign", &doSign, Role::USER, NO_CONDITION }, { "submit", byRef (&doSubmit), Role::USER, NEEDS_CURRENT_LEDGER },
{ "submit", &doSubmit, Role::USER, NEEDS_CURRENT_LEDGER }, { "server_info", byRef (&doServerInfo), Role::USER, NO_CONDITION },
{ "server_info", &doServerInfo, Role::USER, NO_CONDITION }, { "server_state", byRef (&doServerState), Role::USER, NO_CONDITION },
{ "server_state", &doServerState, Role::USER, NO_CONDITION }, { "sms", byRef (&doSMS), Role::ADMIN, NO_CONDITION },
{ "sms", &doSMS, Role::ADMIN, NO_CONDITION }, { "stop", byRef (&doStop), Role::ADMIN, NO_CONDITION },
{ "stop", &doStop, Role::ADMIN, NO_CONDITION }, { "transaction_entry", byRef (&doTransactionEntry), Role::USER, NEEDS_CURRENT_LEDGER },
{ "transaction_entry", &doTransactionEntry, Role::USER, NEEDS_CURRENT_LEDGER }, { "tx", byRef (&doTx), Role::USER, NEEDS_NETWORK_CONNECTION },
{ "tx", &doTx, Role::USER, NEEDS_NETWORK_CONNECTION }, { "tx_history", byRef (&doTxHistory), Role::USER, NO_CONDITION },
{ "tx_history", &doTxHistory, Role::USER, NO_CONDITION }, { "unl_add", byRef (&doUnlAdd), Role::ADMIN, NO_CONDITION },
{ "unl_add", &doUnlAdd, Role::ADMIN, NO_CONDITION }, { "unl_delete", byRef (&doUnlDelete), Role::ADMIN, NO_CONDITION },
{ "unl_delete", &doUnlDelete, Role::ADMIN, NO_CONDITION }, { "unl_list", byRef (&doUnlList), Role::ADMIN, NO_CONDITION },
{ "unl_list", &doUnlList, Role::ADMIN, NO_CONDITION }, { "unl_load", byRef (&doUnlLoad), Role::ADMIN, NO_CONDITION },
{ "unl_load", &doUnlLoad, Role::ADMIN, NO_CONDITION }, { "unl_network", byRef (&doUnlNetwork), Role::ADMIN, NO_CONDITION },
{ "unl_network", &doUnlNetwork, Role::ADMIN, NO_CONDITION }, { "unl_reset", byRef (&doUnlReset), Role::ADMIN, NO_CONDITION },
{ "unl_reset", &doUnlReset, Role::ADMIN, NO_CONDITION }, { "unl_score", byRef (&doUnlScore), Role::ADMIN, NO_CONDITION },
{ "unl_score", &doUnlScore, Role::ADMIN, NO_CONDITION }, { "validation_create", byRef (&doValidationCreate), Role::ADMIN, NO_CONDITION },
{ "validation_create", &doValidationCreate, Role::ADMIN, NO_CONDITION }, { "validation_seed", byRef (&doValidationSeed), Role::ADMIN, NO_CONDITION },
{ "validation_seed", &doValidationSeed, Role::ADMIN, NO_CONDITION }, { "wallet_accounts", byRef (&doWalletAccounts), Role::USER, NEEDS_CURRENT_LEDGER },
{ "wallet_accounts", &doWalletAccounts, Role::USER, NEEDS_CURRENT_LEDGER }, { "wallet_propose", byRef (&doWalletPropose), Role::ADMIN, NO_CONDITION },
{ "wallet_propose", &doWalletPropose, Role::ADMIN, NO_CONDITION }, { "wallet_seed", byRef (&doWalletSeed), Role::ADMIN, NO_CONDITION },
{ "wallet_seed", &doWalletSeed, Role::ADMIN, NO_CONDITION },
// Evented methods // Evented methods
{ "subscribe", &doSubscribe, Role::USER, NO_CONDITION }, { "subscribe", byRef (&doSubscribe), Role::USER, NO_CONDITION },
{ "unsubscribe", &doUnsubscribe, Role::USER, NO_CONDITION }, { "unsubscribe", byRef (&doUnsubscribe), Role::USER, NO_CONDITION },
}); });
} // namespace } // namespace
const Handler* getHandler(std::string name) { const Handler* getHandler(std::string const& name) {
return HANDLERS.getHandler(name); return HANDLERS.getHandler(name);
} }

View File

@@ -22,10 +22,13 @@
#include <ripple/core/Config.h> #include <ripple/core/Config.h>
#include <ripple/rpc/RPCHandler.h> #include <ripple/rpc/RPCHandler.h>
#include <ripple/rpc/Status.h>
namespace ripple { namespace ripple {
namespace RPC { namespace RPC {
class Object;
// Under what condition can we call this RPC? // Under what condition can we call this RPC?
enum Condition { enum Condition {
NO_CONDITION = 0, NO_CONDITION = 0,
@@ -36,15 +39,17 @@ enum Condition {
struct Handler struct Handler
{ {
typedef Json::Value (*Method) (Context&); template <class JsonValue>
using Method = std::function <Status (Context&, JsonValue&)>;
const char* name_; const char* name_;
Method method_; Method<Json::Value> valueMethod_;
Role role_; Role role_;
RPC::Condition condition_; RPC::Condition condition_;
Method<Object> objectMethod_;
}; };
const Handler* getHandler(std::string name); const Handler* getHandler (std::string const&);
/** Return a Json::objectValue with a single entry. */ /** Return a Json::objectValue with a single entry. */
template <class Value> template <class Value>

View File

@@ -43,7 +43,8 @@ Json::Value RPCHandler::doRpcCommand (
const std::string& strMethod, const std::string& strMethod,
Json::Value const& jvParams, Json::Value const& jvParams,
Role role, Role role,
Resource::Charge& loadType) Resource::Charge& loadType,
Yield yield)
{ {
WriteLog (lsTRACE, RPCHandler) WriteLog (lsTRACE, RPCHandler)
<< "doRpcCommand:" << strMethod << ":" << jvParams; << "doRpcCommand:" << strMethod << ":" << jvParams;
@@ -60,7 +61,7 @@ Json::Value RPCHandler::doRpcCommand (
// Provide the JSON-RPC method as the field "command" in the request. // Provide the JSON-RPC method as the field "command" in the request.
params[jss::command] = strMethod; params[jss::command] = strMethod;
Json::Value jvResult = doCommand (params, role, loadType); Json::Value jvResult = doCommand (params, role, loadType, yield);
// Always report "status". On an error report the request as received. // Always report "status". On an error report the request as received.
if (jvResult.isMember ("error")) if (jvResult.isMember ("error"))
@@ -79,7 +80,8 @@ Json::Value RPCHandler::doRpcCommand (
Json::Value RPCHandler::doCommand ( Json::Value RPCHandler::doCommand (
const Json::Value& params, const Json::Value& params,
Role role, Role role,
Resource::Charge& loadType) Resource::Charge& loadType,
Yield yield)
{ {
if (role != Role::ADMIN) if (role != Role::ADMIN)
{ {
@@ -139,9 +141,10 @@ Json::Value RPCHandler::doCommand (
{ {
LoadEvent::autoptr ev = getApp().getJobQueue().getLoadEventAP( LoadEvent::autoptr ev = getApp().getJobQueue().getLoadEventAP(
jtGENERIC, "cmd:" + strCommand); jtGENERIC, "cmd:" + strCommand);
RPC::Context context {params, loadType, netOps_, infoSub_, role_}; RPC::Context context {
auto result = handler->method_(context); params, loadType, netOps_, infoSub_, role_, yield};
assert (result.isObject()); Json::Value result (Json::objectValue);
handler->valueMethod_ (context, result);
return result; return result;
} }
catch (std::exception& e) catch (std::exception& e)