diff options
author | imarom <imarom@cisco.com> | 2015-08-24 15:25:19 +0300 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2015-08-24 15:25:19 +0300 |
commit | 5089a9b557fb3c0198a774f14cff53947a432398 (patch) | |
tree | 9ad07f83336f449f65e17a2fe43bca8b1e0a6166 /src/rpc-server | |
parent | 3bfe53394f43a37ce02b09c6420751027c602047 (diff) |
parsing enhancment
Diffstat (limited to 'src/rpc-server')
-rw-r--r-- | src/rpc-server/include/trex_rpc_cmd_api.h | 95 | ||||
-rw-r--r-- | src/rpc-server/include/trex_rpc_exception_api.h | 3 | ||||
-rw-r--r-- | src/rpc-server/src/commands/trex_rpc_cmd_general.cpp | 10 | ||||
-rw-r--r-- | src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp | 47 | ||||
-rw-r--r-- | src/rpc-server/src/commands/trex_rpc_cmd_test.cpp | 61 | ||||
-rw-r--r-- | src/rpc-server/src/commands/trex_rpc_cmds.h | 10 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_cmd.cpp | 144 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp | 10 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_server_mock.cpp | 2 |
9 files changed, 299 insertions, 83 deletions
diff --git a/src/rpc-server/include/trex_rpc_cmd_api.h b/src/rpc-server/include/trex_rpc_cmd_api.h index c773b15f..a2982f4a 100644 --- a/src/rpc-server/include/trex_rpc_cmd_api.h +++ b/src/rpc-server/include/trex_rpc_cmd_api.h @@ -25,6 +25,37 @@ limitations under the License. #include <string> #include <vector> #include <json/json.h> +#include <trex_rpc_exception_api.h> + +/** + * describe different types of rc for run() + */ +typedef enum trex_rpc_cmd_rc_ { + TREX_RPC_CMD_OK, + TREX_RPC_CMD_PARAM_COUNT_ERR = 1, + TREX_RPC_CMD_PARAM_PARSE_ERR, + TREX_RPC_CMD_INTERNAL_ERR +} trex_rpc_cmd_rc_e; + +/** + * simple exception for RPC command processing + * + * @author imarom (23-Aug-15) + */ +class TrexRpcCommandException : TrexRpcException { +public: + TrexRpcCommandException(trex_rpc_cmd_rc_e rc) : m_rc(rc) { + + } + + trex_rpc_cmd_rc_e get_rc() { + return m_rc; + + } + +protected: + trex_rpc_cmd_rc_e m_rc; +}; /** * interface for RPC command @@ -35,25 +66,17 @@ class TrexRpcCommand { public: /** - * 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, - RPC_CMD_INTERNAL_ERR - }; - - /** * method name and params */ TrexRpcCommand(const std::string &method_name) : m_name(method_name) { } - rpc_cmd_rc_e run(const Json::Value ¶ms, Json::Value &result) { - return _run(params, result); - } + /** + * entry point for executing RPC command + * + */ + trex_rpc_cmd_rc_e run(const Json::Value ¶ms, Json::Value &result); const std::string &get_name() { return m_name; @@ -64,25 +87,53 @@ public: protected: /** + * different types of fields + */ + enum field_type_e { + FIELD_TYPE_INT, + FIELD_TYPE_BOOL, + FIELD_TYPE_STR, + FIELD_TYPE_OBJ, + FILED_TYPE_ARRAY + }; + + /** * implemented by the dervied class * */ - virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result) = 0; + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result) = 0; + + /** + * check param count + */ + void check_param_count(const Json::Value ¶ms, int expected, Json::Value &result); + + /** + * check field type + * + */ + //void check_field_type(const Json::Value &field, field_type_e type, Json::Value &result); + void check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result); /** * error generating functions * */ - void genernate_err(Json::Value &result, const std::string &msg) { - result["specific_err"] = msg; - } + void generate_err(Json::Value &result, const std::string &msg); - void generate_err_param_count(Json::Value &result, int expected, int provided) { - std::stringstream ss; - ss << "method expects '" << expected << "' paramteres, '" << provided << "' provided"; - genernate_err(result, ss.str()); - } + /** + * translate enum to string + * + */ + const char * type_to_str(field_type_e type); + + /** + * translate JSON values to string + * + */ + const char * json_type_to_name(const Json::Value &value); + /* RPC command name */ std::string m_name; }; diff --git a/src/rpc-server/include/trex_rpc_exception_api.h b/src/rpc-server/include/trex_rpc_exception_api.h index 8783c219..e349b980 100644 --- a/src/rpc-server/include/trex_rpc_exception_api.h +++ b/src/rpc-server/include/trex_rpc_exception_api.h @@ -32,6 +32,9 @@ limitations under the License. class TrexRpcException : public std::runtime_error { public: + TrexRpcException() : std::runtime_error("") { + + } TrexRpcException(const std::string &what) : std::runtime_error(what) { } }; diff --git a/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp index 193ce8db..ac35babf 100644 --- a/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp @@ -28,14 +28,11 @@ using namespace std; * get status * */ -TrexRpcCommand::rpc_cmd_rc_e +trex_rpc_cmd_rc_e TrexRpcCmdGetStatus::_run(const Json::Value ¶ms, Json::Value &result) { /* validate count */ - if (params.size() != 0) { - generate_err_param_count(result, 0, params.size()); - return (TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR); - } + check_param_count(params, 0, result); Json::Value §ion = result["result"]; @@ -44,6 +41,7 @@ TrexRpcCmdGetStatus::_run(const Json::Value ¶ms, Json::Value &result) { section["general"]["build_time"] = get_build_time(); section["general"]["version_user"] = VERSION_USER; section["general"]["uptime"] = TrexRpcServer::get_server_uptime(); - return (RPC_CMD_OK); + + return (TREX_RPC_CMD_OK); } diff --git a/src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp new file mode 100644 index 00000000..a5b358d0 --- /dev/null +++ b/src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp @@ -0,0 +1,47 @@ +/* + Itay Marom + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "trex_rpc_cmds.h" +#include <../linux_dpdk/version.h> +#include <trex_rpc_server_api.h> + +using namespace std; + +/** + * add new stream + * + */ +trex_rpc_cmd_rc_e +TrexRpcCmdGetStatus::_run(const Json::Value ¶ms, Json::Value &result) { + + /* validate count */ + if (params.size() != 1) { + generate_err_param_count(result, 0, params.size()); + return (TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR); + } + + Json::Value &stream = result["stream"]; + + if (stream == Json::Value::null) { + generate_err_param_count + } + return (RPC_CMD_OK); +} + diff --git a/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp b/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp index e2dc8959..e67de286 100644 --- a/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp +++ b/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp @@ -29,31 +29,18 @@ using namespace std; * add command * */ -TrexRpcCommand::rpc_cmd_rc_e +trex_rpc_cmd_rc_e TrexRpcCmdTestAdd::_run(const Json::Value ¶ms, Json::Value &result) { const Json::Value &x = params["x"]; const Json::Value &y = params["y"]; - - /* validate count */ - if (params.size() != 2) { - generate_err_param_count(result, 2, params.size()); - return (TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR); - } - - /* check we have all the required paramters */ - if (!x.isInt()) { - genernate_err(result, "'x' is either missing or not an integer"); - return (TrexRpcCommand::RPC_CMD_PARAM_PARSE_ERR); - } - - if (!y.isInt()) { - genernate_err(result, "'y' is either missing or not an integer"); - return (TrexRpcCommand::RPC_CMD_PARAM_PARSE_ERR); - } + + check_param_count(params, 2, result); + check_field_type(params, "x", FIELD_TYPE_INT, result); + check_field_type(params, "y", FIELD_TYPE_INT, result); result["result"] = x.asInt() + y.asInt(); - return (RPC_CMD_OK); + return (TREX_RPC_CMD_OK); } /** @@ -61,56 +48,42 @@ TrexRpcCmdTestAdd::_run(const Json::Value ¶ms, Json::Value &result) { * * @author imarom (16-Aug-15) */ -TrexRpcCommand::rpc_cmd_rc_e +trex_rpc_cmd_rc_e TrexRpcCmdTestSub::_run(const Json::Value ¶ms, Json::Value &result) { const Json::Value &x = params["x"]; const Json::Value &y = params["y"]; - /* validate count */ - if (params.size() != 2) { - generate_err_param_count(result, 2, params.size()); - 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); - } + check_param_count(params, 2, result); + check_field_type(params, "x", TrexRpcCommand::FIELD_TYPE_INT, result); + check_field_type(params, "y", TrexRpcCommand::FIELD_TYPE_INT, result); result["result"] = x.asInt() - y.asInt(); - return (RPC_CMD_OK); + return (TREX_RPC_CMD_OK); } /** * ping command */ -TrexRpcCommand::rpc_cmd_rc_e +trex_rpc_cmd_rc_e TrexRpcCmdPing::_run(const Json::Value ¶ms, Json::Value &result) { /* validate count */ - if (params.size() != 0) { - generate_err_param_count(result, 0, params.size()); - return (TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR); - } + check_param_count(params, 0, result); result["result"] = "ACK"; - return (RPC_CMD_OK); + return (TREX_RPC_CMD_OK); } /** * query command */ -TrexRpcCommand::rpc_cmd_rc_e +trex_rpc_cmd_rc_e TrexRpcCmdGetReg::_run(const Json::Value ¶ms, Json::Value &result) { vector<string> cmds; /* validate count */ - if (params.size() != 0) { - generate_err_param_count(result, 0, params.size()); - return (TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR); - } - + check_param_count(params, 0, result); TrexRpcCommandsTable::get_instance().query(cmds); @@ -121,6 +94,6 @@ TrexRpcCmdGetReg::_run(const Json::Value ¶ms, Json::Value &result) { result["result"] = test; - return (RPC_CMD_OK); + return (TREX_RPC_CMD_OK); } diff --git a/src/rpc-server/src/commands/trex_rpc_cmds.h b/src/rpc-server/src/commands/trex_rpc_cmds.h index e37e1cda..39ccf27a 100644 --- a/src/rpc-server/src/commands/trex_rpc_cmds.h +++ b/src/rpc-server/src/commands/trex_rpc_cmds.h @@ -37,7 +37,7 @@ class TrexRpcCmdTestAdd : public TrexRpcCommand { public: TrexRpcCmdTestAdd() : TrexRpcCommand("test_add") {} protected: - virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); }; /** @@ -48,7 +48,7 @@ class TrexRpcCmdTestSub : public TrexRpcCommand { public: TrexRpcCmdTestSub() : TrexRpcCommand("test_sub") {} ; protected: - virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); }; /** @@ -59,7 +59,7 @@ class TrexRpcCmdPing : public TrexRpcCommand { public: TrexRpcCmdPing() : TrexRpcCommand("ping") {}; protected: - virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); }; /** @@ -70,7 +70,7 @@ class TrexRpcCmdGetReg : public TrexRpcCommand { public: TrexRpcCmdGetReg() : TrexRpcCommand("get_reg_cmds") {}; protected: - virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); }; /** @@ -81,7 +81,7 @@ class TrexRpcCmdGetStatus : public TrexRpcCommand { public: TrexRpcCmdGetStatus() : TrexRpcCommand("get_status") {}; protected: - virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); }; diff --git a/src/rpc-server/src/trex_rpc_cmd.cpp b/src/rpc-server/src/trex_rpc_cmd.cpp new file mode 100644 index 00000000..d1a9ebb0 --- /dev/null +++ b/src/rpc-server/src/trex_rpc_cmd.cpp @@ -0,0 +1,144 @@ +/* + Itay Marom + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include <trex_rpc_cmd_api.h> + +trex_rpc_cmd_rc_e +TrexRpcCommand::run(const Json::Value ¶ms, Json::Value &result) { + trex_rpc_cmd_rc_e rc; + + /* the internal run can throw a parser error / other error */ + try { + rc = _run(params, result); + } catch (TrexRpcCommandException &e) { + return e.get_rc(); + } + + return (rc); +} + +void +TrexRpcCommand::check_param_count(const Json::Value ¶ms, int expected, Json::Value &result) { + + if (params.size() != expected) { + std::stringstream ss; + ss << "method expects '" << expected << "' paramteres, '" << params.size() << "' provided"; + generate_err(result, ss.str()); + throw TrexRpcCommandException(TREX_RPC_CMD_PARAM_COUNT_ERR); + } +} + +const char * +TrexRpcCommand::type_to_str(field_type_e type) { + switch (type) { + case FIELD_TYPE_BOOL: + return "bool"; + case FIELD_TYPE_INT: + return "int"; + case FIELD_TYPE_OBJ: + return "object"; + case FIELD_TYPE_STR: + return "string"; + case FILED_TYPE_ARRAY: + return "array"; + + default: + return "UNKNOWN"; + } +} + +const char * +TrexRpcCommand::json_type_to_name(const Json::Value &value) { + + switch(value.type()) { + case Json::nullValue: + return "null"; + case Json::uintValue: + return "uint"; + case Json::realValue: + return "real"; + case Json::stringValue: + return "string"; + case Json::booleanValue: + return "boolean"; + case Json::arrayValue: + return "array"; + case Json::objectValue: + return "object"; + + default: + return "UNKNOWN"; + } + +} +void +TrexRpcCommand::check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result) { + std::stringstream ss; + + /* check if field exists , does not add the field because its const */ + const Json::Value &field = parent[name]; + + /* first check if field exists */ + if (field == Json::Value::null) { + ss << "field '" << name << "' missing"; + generate_err(result, ss.str()); + throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR)); + } + + bool rc = true; + + switch (type) { + case FIELD_TYPE_BOOL: + if (!field.isBool()) { + rc = false; + } + break; + + case FIELD_TYPE_INT: + if (!field.isInt()) { + rc = false; + } + break; + + case FIELD_TYPE_OBJ: + if (!field.isObject()) { + rc = false; + } + break; + + case FIELD_TYPE_STR: + if (!field.isString()) { + rc = false; + } + break; + } + + if (!rc) { + ss << "error at offset: " << field.getOffsetStart() << " - '" << name << "' is '" << json_type_to_name(field) << "', expecting '" << type_to_str(type) << "'"; + generate_err(result, ss.str()); + throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR)); + } + +} + +void +TrexRpcCommand::generate_err(Json::Value &result, const std::string &msg) { + result["specific_err"] = msg; +} diff --git a/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp b/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp index be1eb2f8..bf6056d5 100644 --- a/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp +++ b/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp @@ -71,21 +71,21 @@ public: virtual void _execute(Json::Value &response) { Json::Value result; - TrexRpcCommand::rpc_cmd_rc_e rc = m_cmd->run(m_params, result); + trex_rpc_cmd_rc_e rc = m_cmd->run(m_params, result); switch (rc) { - case TrexRpcCommand::RPC_CMD_OK: + case TREX_RPC_CMD_OK: response["result"] = result["result"]; break; - case TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR: - case TrexRpcCommand::RPC_CMD_PARAM_PARSE_ERR: + case TREX_RPC_CMD_PARAM_COUNT_ERR: + case TREX_RPC_CMD_PARAM_PARSE_ERR: response["error"]["code"] = JSONRPC_V2_ERR_INVALID_PARAMS; response["error"]["message"] = "Bad paramters for method"; response["error"]["specific_err"] = result["specific_err"]; break; - case TrexRpcCommand::RPC_CMD_INTERNAL_ERR: + case TREX_RPC_CMD_INTERNAL_ERR: response["error"]["code"] = JSONRPC_V2_ERR_INTERNAL_ERROR; response["error"]["message"] = "Internal Server Error"; response["error"]["specific_err"] = result["specific_err"]; diff --git a/src/rpc-server/src/trex_rpc_server_mock.cpp b/src/rpc-server/src/trex_rpc_server_mock.cpp index fd4f051c..98d1f35d 100644 --- a/src/rpc-server/src/trex_rpc_server_mock.cpp +++ b/src/rpc-server/src/trex_rpc_server_mock.cpp @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) { // gtest ? if (argc > 1) { - if ( (string(argv[1]) != "--ut") || (argc != 2) ) { + if (string(argv[1]) != "--ut") { cout << "\n[Usage] " << argv[0] << ": " << " [--ut]\n\n"; exit(-1); } |