diff options
-rw-r--r-- | src/rpc-server/include/trex_rpc_commands.h | 34 | ||||
-rw-r--r-- | src/rpc-server/include/trex_rpc_jsonrpc_v2.h | 17 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_commands.cpp | 60 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp | 84 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_req_resp.cpp | 2 |
5 files changed, 160 insertions, 37 deletions
diff --git a/src/rpc-server/include/trex_rpc_commands.h b/src/rpc-server/include/trex_rpc_commands.h index 4a445dac..ef9f5eaa 100644 --- a/src/rpc-server/include/trex_rpc_commands.h +++ b/src/rpc-server/include/trex_rpc_commands.h @@ -25,6 +25,7 @@ limitations under the License. #include <unordered_map> #include <string> #include <vector> +#include <json/json.h> /** * interface for RPC command @@ -33,17 +34,36 @@ limitations under the License. */ class TrexRpcCommand { public: - TrexRpcCommand(const std::string &method_name, const std::vector<std::string> ¶ms); /** - * implemented by the derived class - * - * @author imarom (13-Aug-15) + * describe different types of rc for run() + */ + enum rpc_cmd_rc_e { + RPC_CMD_OK, + RPC_CMD_PARAM_COUNT_ERR = 1, + RPC_CMD_PARAM_PARSE_ERR + }; + + /** + * method name and params */ - virtual void run() = 0; + TrexRpcCommand(const std::string &method_name); + + rpc_cmd_rc_e run(const Json::Value ¶ms, std::string &output); + + const std::string &get_name(); + + virtual ~TrexRpcCommand() {} protected: - std::vector<std::string> params; + + /** + * implemented by the dervied class + * + */ + virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, std::string &output) = 0; + + std::string m_name; }; /** @@ -60,7 +80,7 @@ public: return instance; } - void register_command(const TrexRpcCommand &command); + void register_command(TrexRpcCommand *command); TrexRpcCommand * lookup(const std::string &method_name); diff --git a/src/rpc-server/include/trex_rpc_jsonrpc_v2.h b/src/rpc-server/include/trex_rpc_jsonrpc_v2.h index ac04fb99..963dab7b 100644 --- a/src/rpc-server/include/trex_rpc_jsonrpc_v2.h +++ b/src/rpc-server/include/trex_rpc_jsonrpc_v2.h @@ -26,15 +26,17 @@ limitations under the License. #include <vector> #include <json/json.h> +class TrexRpcCommand; + /** - * JSON RPC V2 command + * JSON RPC V2 parsed object * * @author imarom (12-Aug-15) */ -class TrexJsonRpcV2Command { +class TrexJsonRpcV2ParsedObject { public: - TrexJsonRpcV2Command(const Json::Value &msg_id); + TrexJsonRpcV2ParsedObject(const Json::Value &msg_id, bool force); /** * main function to execute the command @@ -46,11 +48,14 @@ protected: /** * instance private implementation - * + * should provide implementation with response + * and without response value */ virtual void _execute(Json::Value &response) = 0; + virtual void _execute() = 0; Json::Value m_msg_id; + bool m_respond; }; /** @@ -76,7 +81,7 @@ public: * * @author imarom (12-Aug-15) */ - void parse(std::vector<TrexJsonRpcV2Command *> &commands); + void parse(std::vector<TrexJsonRpcV2ParsedObject *> &commands); private: @@ -84,7 +89,7 @@ private: * handle a single request * */ - void parse_single_request(Json::Value &request, std::vector<TrexJsonRpcV2Command *> &commands); + void parse_single_request(Json::Value &request, std::vector<TrexJsonRpcV2ParsedObject *> &commands); std::string m_msg; }; diff --git a/src/rpc-server/src/trex_rpc_commands.cpp b/src/rpc-server/src/trex_rpc_commands.cpp index d7a1646a..8547384a 100644 --- a/src/rpc-server/src/trex_rpc_commands.cpp +++ b/src/rpc-server/src/trex_rpc_commands.cpp @@ -19,11 +19,69 @@ See the License for the specific language governing permissions and limitations under the License. */ #include <trex_rpc_commands.h> +#include <iostream> +#include <sstream> +using namespace std; + +/***************** commands **********/ +class TestRpcAddRpcMethod : public TrexRpcCommand { +public: + + TestRpcAddRpcMethod() : TrexRpcCommand("test_rpc_add") { + } + + virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, std::string &output) { + const Json::Value &x = params["x"]; + const Json::Value &y = params["y"]; + + /* validate count */ + if (params.size() != 2) { + return (TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR); + } + + /* check we have all the required paramters */ + if (!x.isInt() || !y.isInt()) { + return (TrexRpcCommand::RPC_CMD_PARAM_PARSE_ERR); + } + + std::stringstream ss; + ss << (x.asInt() + y.asInt()); + output = ss.str(); + + return (RPC_CMD_OK); + } +}; + +/*************** generic command methods *********/ + +TrexRpcCommand::TrexRpcCommand(const string &method_name) : m_name(method_name) { +} + +TrexRpcCommand::rpc_cmd_rc_e +TrexRpcCommand::run(const Json::Value ¶ms, std::string &output) { + return _run(params, output); +} + +const string & TrexRpcCommand::get_name() { + return m_name; +} + + +/************* table related methods ***********/ TrexRpcCommandsTable::TrexRpcCommandsTable() { + /* add the test command (for gtest) */ + register_command(new TestRpcAddRpcMethod()); + TrexRpcCommand *cmd = m_rpc_cmd_table["test_rpc_add"]; } -TrexRpcCommand * TrexRpcCommandsTable::lookup(const std::string &method_name) { +TrexRpcCommand * TrexRpcCommandsTable::lookup(const string &method_name) { return m_rpc_cmd_table[method_name]; } + + +void TrexRpcCommandsTable::register_command(TrexRpcCommand *command) { + + m_rpc_cmd_table[command->get_name()] = command; +} diff --git a/src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp b/src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp index 0e649ac5..2eec599a 100644 --- a/src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp +++ b/src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp @@ -37,44 +37,82 @@ enum { JSONRPC_V2_ERR_INTERNAL_ERROR = -32603 }; -/* dummy command */ -class DumymCommand : public TrexJsonRpcV2Command { + +/*************** JSON RPC parsed object base type ************/ + +TrexJsonRpcV2ParsedObject::TrexJsonRpcV2ParsedObject(const Json::Value &msg_id, bool force = false) : m_msg_id(msg_id) { + /* if we have msg_id or a force was issued - write resposne */ + m_respond = (msg_id != Json::Value::null) || force; +} + +void TrexJsonRpcV2ParsedObject::execute(Json::Value &response) { + + /* common fields */ + if (m_respond) { + response["jsonrpc"] = "2.0"; + response["id"] = m_msg_id; + _execute(response); + } else { + _execute(); + } +} + +/****************** valid method return value **************/ +class JsonRpcMethod : public TrexJsonRpcV2ParsedObject { public: - virtual void _execute(Json::Value &response) { + JsonRpcMethod(const Json::Value &msg_id, TrexRpcCommand *cmd, const Json::Value ¶ms) : TrexJsonRpcV2ParsedObject(msg_id), m_cmd(cmd), m_params(params) { + } -}; -/*************** JSON RPC command base type ************/ + virtual void _execute(Json::Value &response) { + std::string output; + + TrexRpcCommand::rpc_cmd_rc_e rc = m_cmd->run(m_params, output); -TrexJsonRpcV2Command::TrexJsonRpcV2Command(const Json::Value &msg_id) : m_msg_id(msg_id) { + switch (rc) { + case TrexRpcCommand::RPC_CMD_OK: + response["result"] = output; + break; -} + case TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR: + case TrexRpcCommand::RPC_CMD_PARAM_PARSE_ERR: + response["error"]["code"] = JSONRPC_V2_ERR_INVALID_PARAMS; + response["error"]["message"] = "Bad paramters for method"; + break; + } -void TrexJsonRpcV2Command::execute(Json::Value &response) { - /* common fields */ - response["jsonrpc"] = "2.0"; - response["id"] = m_msg_id; + } - /* call the underlying implementation to add the reset of the sections */ - _execute(response); -} + virtual void _execute() { + std::string output; + m_cmd->run(m_params, output); + } + +private: + TrexRpcCommand *m_cmd; + Json::Value m_params; +}; + +/******************* RPC error **************/ /** * describes the parser error * */ -class JsonRpcError : public TrexJsonRpcV2Command { +class JsonRpcError : public TrexJsonRpcV2ParsedObject { public: - JsonRpcError(const Json::Value &msg_id, int code, const std::string &msg) : TrexJsonRpcV2Command(msg_id), m_code(code), m_msg(msg) { + JsonRpcError(const Json::Value &msg_id, int code, const std::string &msg, bool force = false) : TrexJsonRpcV2ParsedObject(msg_id, force), m_code(code), m_msg(msg) { } virtual void _execute(Json::Value &response) { - response["error"]["code"] = m_code; response["error"]["message"] = m_msg; - + } + + virtual void _execute() { + /* nothing to do with no response */ } private: @@ -87,7 +125,7 @@ TrexJsonRpcV2Parser::TrexJsonRpcV2Parser(const std::string &msg) : m_msg(msg) { } -void TrexJsonRpcV2Parser::parse(std::vector<TrexJsonRpcV2Command *> &commands) { +void TrexJsonRpcV2Parser::parse(std::vector<TrexJsonRpcV2ParsedObject *> &commands) { Json::Reader reader; Json::Value request; @@ -95,7 +133,7 @@ void TrexJsonRpcV2Parser::parse(std::vector<TrexJsonRpcV2Command *> &commands) { /* basic JSON parsing */ bool rc = reader.parse(m_msg, request, false); if (!rc) { - commands.push_back(new JsonRpcError(Json::Value::null, JSONRPC_V2_ERR_PARSE, "Bad JSON Format")); + commands.push_back(new JsonRpcError(Json::Value::null, JSONRPC_V2_ERR_PARSE, "Bad JSON Format", true)); return; } @@ -115,7 +153,7 @@ void TrexJsonRpcV2Parser::parse(std::vector<TrexJsonRpcV2Command *> &commands) { void TrexJsonRpcV2Parser::parse_single_request(Json::Value &request, - std::vector<TrexJsonRpcV2Command *> &commands) { + std::vector<TrexJsonRpcV2ParsedObject *> &commands) { Json::Value msg_id = request["id"]; @@ -132,12 +170,14 @@ void TrexJsonRpcV2Parser::parse_single_request(Json::Value &request, return; } + /* lookup the method in the DB */ TrexRpcCommand * rpc_cmd = TrexRpcCommandsTable::get_instance().lookup(method_name); if (!rpc_cmd) { commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_METHOD_NOT_FOUND, "Method not registered")); return; } - /* TODO - add commands */ + /* create a method object */ + commands.push_back(new JsonRpcMethod(msg_id, rpc_cmd, request["params"])); } diff --git a/src/rpc-server/src/trex_rpc_req_resp.cpp b/src/rpc-server/src/trex_rpc_req_resp.cpp index feb57b44..7acd1e09 100644 --- a/src/rpc-server/src/trex_rpc_req_resp.cpp +++ b/src/rpc-server/src/trex_rpc_req_resp.cpp @@ -85,7 +85,7 @@ void TrexRpcServerReqRes::_stop_rpc_thread() { } void TrexRpcServerReqRes::handle_request(const std::string &request) { - std::vector<TrexJsonRpcV2Command *> commands; + std::vector<TrexJsonRpcV2ParsedObject *> commands; Json::FastWriter writer; Json::Value response; |