From 2adc8696b8f1a9f9038a1e6377ac23e1bfd03ceb Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 24 Aug 2015 15:32:53 +0300 Subject: moved files to be on a single directory --- linux/ws_main.py | 8 +- linux_dpdk/ws_main.py | 4 +- src/rpc-server/commands/trex_rpc_cmd_general.cpp | 47 +++++ src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 47 +++++ src/rpc-server/commands/trex_rpc_cmd_test.cpp | 99 +++++++++++ src/rpc-server/commands/trex_rpc_cmds.h | 89 ++++++++++ src/rpc-server/include/trex_rpc_cmd_api.h | 141 --------------- src/rpc-server/include/trex_rpc_cmds_table.h | 79 --------- src/rpc-server/include/trex_rpc_exception_api.h | 42 ----- .../include/trex_rpc_jsonrpc_v2_parser.h | 94 ---------- src/rpc-server/include/trex_rpc_req_resp_server.h | 51 ------ src/rpc-server/include/trex_rpc_server_api.h | 165 ------------------ .../src/commands/trex_rpc_cmd_general.cpp | 47 ----- .../src/commands/trex_rpc_cmd_stream.cpp | 47 ----- src/rpc-server/src/commands/trex_rpc_cmd_test.cpp | 99 ----------- src/rpc-server/src/commands/trex_rpc_cmds.h | 89 ---------- src/rpc-server/src/trex_rpc_cmd.cpp | 144 --------------- src/rpc-server/src/trex_rpc_cmds_table.cpp | 65 ------- src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp | 194 --------------------- src/rpc-server/src/trex_rpc_req_resp_server.cpp | 146 ---------------- src/rpc-server/src/trex_rpc_server.cpp | 153 ---------------- src/rpc-server/src/trex_rpc_server_mock.cpp | 75 -------- src/rpc-server/trex_rpc_cmd.cpp | 144 +++++++++++++++ src/rpc-server/trex_rpc_cmd_api.h | 141 +++++++++++++++ src/rpc-server/trex_rpc_cmds_table.cpp | 65 +++++++ src/rpc-server/trex_rpc_cmds_table.h | 79 +++++++++ src/rpc-server/trex_rpc_exception_api.h | 42 +++++ src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp | 194 +++++++++++++++++++++ src/rpc-server/trex_rpc_jsonrpc_v2_parser.h | 94 ++++++++++ src/rpc-server/trex_rpc_req_resp_server.cpp | 146 ++++++++++++++++ src/rpc-server/trex_rpc_req_resp_server.h | 51 ++++++ src/rpc-server/trex_rpc_server.cpp | 153 ++++++++++++++++ src/rpc-server/trex_rpc_server_api.h | 165 ++++++++++++++++++ src/rpc-server/trex_rpc_server_mock.cpp | 75 ++++++++ 34 files changed, 1637 insertions(+), 1637 deletions(-) create mode 100644 src/rpc-server/commands/trex_rpc_cmd_general.cpp create mode 100644 src/rpc-server/commands/trex_rpc_cmd_stream.cpp create mode 100644 src/rpc-server/commands/trex_rpc_cmd_test.cpp create mode 100644 src/rpc-server/commands/trex_rpc_cmds.h delete mode 100644 src/rpc-server/include/trex_rpc_cmd_api.h delete mode 100644 src/rpc-server/include/trex_rpc_cmds_table.h delete mode 100644 src/rpc-server/include/trex_rpc_exception_api.h delete mode 100644 src/rpc-server/include/trex_rpc_jsonrpc_v2_parser.h delete mode 100644 src/rpc-server/include/trex_rpc_req_resp_server.h delete mode 100644 src/rpc-server/include/trex_rpc_server_api.h delete mode 100644 src/rpc-server/src/commands/trex_rpc_cmd_general.cpp delete mode 100644 src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp delete mode 100644 src/rpc-server/src/commands/trex_rpc_cmd_test.cpp delete mode 100644 src/rpc-server/src/commands/trex_rpc_cmds.h delete mode 100644 src/rpc-server/src/trex_rpc_cmd.cpp delete mode 100644 src/rpc-server/src/trex_rpc_cmds_table.cpp delete mode 100644 src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp delete mode 100644 src/rpc-server/src/trex_rpc_req_resp_server.cpp delete mode 100644 src/rpc-server/src/trex_rpc_server.cpp delete mode 100644 src/rpc-server/src/trex_rpc_server_mock.cpp create mode 100644 src/rpc-server/trex_rpc_cmd.cpp create mode 100644 src/rpc-server/trex_rpc_cmd_api.h create mode 100644 src/rpc-server/trex_rpc_cmds_table.cpp create mode 100644 src/rpc-server/trex_rpc_cmds_table.h create mode 100644 src/rpc-server/trex_rpc_exception_api.h create mode 100644 src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp create mode 100644 src/rpc-server/trex_rpc_jsonrpc_v2_parser.h create mode 100644 src/rpc-server/trex_rpc_req_resp_server.cpp create mode 100644 src/rpc-server/trex_rpc_req_resp_server.h create mode 100644 src/rpc-server/trex_rpc_server.cpp create mode 100644 src/rpc-server/trex_rpc_server_api.h create mode 100644 src/rpc-server/trex_rpc_server_mock.cpp diff --git a/linux/ws_main.py b/linux/ws_main.py index 9ee9a465..7d9aae3b 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -139,7 +139,7 @@ net_src = SrcGroup(dir='src/common/Network/Packet', 'VLANHeader.cpp']); # RPC code -rpc_server_src = SrcGroup(dir='src/rpc-server/src', +rpc_server_src = SrcGroup(dir='src/rpc-server/', src_list=[ 'trex_rpc_server.cpp', 'trex_rpc_req_resp_server.cpp', @@ -153,10 +153,10 @@ rpc_server_src = SrcGroup(dir='src/rpc-server/src', ]) # RPC mock server (test) -rpc_server_mock_src = SrcGroup(dir='src/rpc-server/src', +rpc_server_mock_src = SrcGroup(dir='src/rpc-server/', src_list=[ 'trex_rpc_server_mock.cpp', - '../../gtest/rpc_test.cpp', + '../gtest/rpc_test.cpp', ]) # JSON package @@ -224,7 +224,7 @@ cxxflags_base =['-DWIN_UCODE_SIM', includes_path =''' ../src/pal/linux/ ../src/zmq/include/ ../src/ - ../src/rpc-server/include + ../src/rpc-server/ ../external_libs/json/ ../yaml-cpp/include/ '''; diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py index 6bae1348..aef36244 100755 --- a/linux_dpdk/ws_main.py +++ b/linux_dpdk/ws_main.py @@ -137,7 +137,7 @@ json_src = SrcGroup(dir='external_libs/json', ]) # RPC code -rpc_server_src = SrcGroup(dir='src/rpc-server/src', +rpc_server_src = SrcGroup(dir='src/rpc-server/', src_list=[ 'trex_rpc_server.cpp', 'trex_rpc_req_resp_server.cpp', @@ -400,7 +400,7 @@ common_flags_old = common_flags + [ includes_path =''' ../src/pal/linux_dpdk/ ../src/ ../external_libs/json/ - ../src/rpc-server/include + ../src/rpc-server/ ../yaml-cpp/include/ ../src/zmq/include/ ../src/dpdk_lib18/librte_eal/linuxapp/eal/include/ diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp new file mode 100644 index 00000000..ac35babf --- /dev/null +++ b/src/rpc-server/commands/trex_rpc_cmd_general.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 + +using namespace std; + +/** + * get status + * + */ +trex_rpc_cmd_rc_e +TrexRpcCmdGetStatus::_run(const Json::Value ¶ms, Json::Value &result) { + + /* validate count */ + check_param_count(params, 0, result); + + Json::Value §ion = result["result"]; + + section["general"]["version"] = VERSION_BUILD_NUM; + section["general"]["build_date"] = get_build_date(); + section["general"]["build_time"] = get_build_time(); + section["general"]["version_user"] = VERSION_USER; + section["general"]["uptime"] = TrexRpcServer::get_server_uptime(); + + return (TREX_RPC_CMD_OK); +} + diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp new file mode 100644 index 00000000..a5b358d0 --- /dev/null +++ b/src/rpc-server/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 + +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/commands/trex_rpc_cmd_test.cpp b/src/rpc-server/commands/trex_rpc_cmd_test.cpp new file mode 100644 index 00000000..e67de286 --- /dev/null +++ b/src/rpc-server/commands/trex_rpc_cmd_test.cpp @@ -0,0 +1,99 @@ +/* + 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 +#include +#include + +using namespace std; + +/** + * add command + * + */ +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"]; + + 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 (TREX_RPC_CMD_OK); +} + +/** + * sub command + * + * @author imarom (16-Aug-15) + */ +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"]; + + 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 (TREX_RPC_CMD_OK); +} + +/** + * ping command + */ +trex_rpc_cmd_rc_e +TrexRpcCmdPing::_run(const Json::Value ¶ms, Json::Value &result) { + + /* validate count */ + check_param_count(params, 0, result); + + result["result"] = "ACK"; + return (TREX_RPC_CMD_OK); +} + +/** + * query command + */ +trex_rpc_cmd_rc_e +TrexRpcCmdGetReg::_run(const Json::Value ¶ms, Json::Value &result) { + vector cmds; + + /* validate count */ + check_param_count(params, 0, result); + + TrexRpcCommandsTable::get_instance().query(cmds); + + Json::Value test = Json::arrayValue; + for (auto cmd : cmds) { + test.append(cmd); + } + + result["result"] = test; + + return (TREX_RPC_CMD_OK); +} + diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h new file mode 100644 index 00000000..39ccf27a --- /dev/null +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -0,0 +1,89 @@ +/* + 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. +*/ + +#ifndef __TREX_RPC_CMD_H__ +#define __TREX_RPC_CMD_H__ + +#include +#include + +/* all the RPC commands decl. goes here */ + +/******************* test section ************/ + +/** + * add + * + */ +class TrexRpcCmdTestAdd : public TrexRpcCommand { +public: + TrexRpcCmdTestAdd() : TrexRpcCommand("test_add") {} +protected: + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); +}; + +/** + * sub + * + */ +class TrexRpcCmdTestSub : public TrexRpcCommand { +public: + TrexRpcCmdTestSub() : TrexRpcCommand("test_sub") {} ; +protected: + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); +}; + +/** + * ping + * + */ +class TrexRpcCmdPing : public TrexRpcCommand { +public: + TrexRpcCmdPing() : TrexRpcCommand("ping") {}; +protected: + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); +}; + +/** + * get all registered commands + * + */ +class TrexRpcCmdGetReg : public TrexRpcCommand { +public: + TrexRpcCmdGetReg() : TrexRpcCommand("get_reg_cmds") {}; +protected: + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); +}; + +/** + * get status + * + */ +class TrexRpcCmdGetStatus : public TrexRpcCommand { +public: + TrexRpcCmdGetStatus() : TrexRpcCommand("get_status") {}; +protected: + virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); +}; + + +/**************** test section end *************/ +#endif /* __TREX_RPC_CMD_H__ */ diff --git a/src/rpc-server/include/trex_rpc_cmd_api.h b/src/rpc-server/include/trex_rpc_cmd_api.h deleted file mode 100644 index a2982f4a..00000000 --- a/src/rpc-server/include/trex_rpc_cmd_api.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - 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. -*/ - -#ifndef __TREX_RPC_CMD_API_H__ -#define __TREX_RPC_CMD_API_H__ - -#include -#include -#include -#include - -/** - * 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 - * - * @author imarom (13-Aug-15) - */ -class TrexRpcCommand { -public: - - /** - * method name and params - */ - TrexRpcCommand(const std::string &method_name) : m_name(method_name) { - - } - - /** - * 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; - } - - virtual ~TrexRpcCommand() {} - -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 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 generate_err(Json::Value &result, const std::string &msg); - - /** - * 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; -}; - -#endif /* __TREX_RPC_CMD_API_H__ */ - diff --git a/src/rpc-server/include/trex_rpc_cmds_table.h b/src/rpc-server/include/trex_rpc_cmds_table.h deleted file mode 100644 index a41944f1..00000000 --- a/src/rpc-server/include/trex_rpc_cmds_table.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - 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. -*/ - -#ifndef __TREX_RPC_CMDS_TABLE_H__ -#define __TREX_RPC_CMDS_TABLE_H__ - -#include -#include -#include -#include - -class TrexRpcCommand; - -/** - * holds all the commands registered - * - * @author imarom (13-Aug-15) - */ -class TrexRpcCommandsTable { - -public: - - static TrexRpcCommandsTable& get_instance() { - static TrexRpcCommandsTable instance; - return instance; - } - - /** - * register a new command - * - */ - void register_command(TrexRpcCommand *command); - - /** - * lookup for a command - * - */ - TrexRpcCommand * lookup(const std::string &method_name); - - /** - * query all commands registered - * - */ - void query(std::vector &cmds); - -private: - TrexRpcCommandsTable(); - ~TrexRpcCommandsTable(); - - /* c++ 2011 style singleton */ - TrexRpcCommandsTable(TrexRpcCommandsTable const&) = delete; - void operator=(TrexRpcCommandsTable const&) = delete; - - /** - * holds all the registered RPC commands - * - */ - std::unordered_map m_rpc_cmd_table; -}; - -#endif /* __TREX_RPC_CMDS_TABLE_H__ */ diff --git a/src/rpc-server/include/trex_rpc_exception_api.h b/src/rpc-server/include/trex_rpc_exception_api.h deleted file mode 100644 index e349b980..00000000 --- a/src/rpc-server/include/trex_rpc_exception_api.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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. -*/ - -#ifndef __TREX_RPC_EXCEPTION_API_H__ -#define __TREX_RPC_EXCEPTION_API_H__ - -#include -#include - -/** - * generic exception for RPC errors - * - */ -class TrexRpcException : public std::runtime_error -{ -public: - TrexRpcException() : std::runtime_error("") { - - } - TrexRpcException(const std::string &what) : std::runtime_error(what) { - } -}; - -#endif /* __TREX_RPC_EXCEPTION_API_H__ */ diff --git a/src/rpc-server/include/trex_rpc_jsonrpc_v2_parser.h b/src/rpc-server/include/trex_rpc_jsonrpc_v2_parser.h deleted file mode 100644 index 3367ad6a..00000000 --- a/src/rpc-server/include/trex_rpc_jsonrpc_v2_parser.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - 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. -*/ - -#ifndef __TREX_RPC_JSONRPC_V2_PARSER_H__ -#define __TREX_RPC_JSONRPC_V2_PARSER_H__ - -#include -#include -#include - -/** - * JSON RPC V2 parsed object - * - * @author imarom (12-Aug-15) - */ -class TrexJsonRpcV2ParsedObject { -public: - - TrexJsonRpcV2ParsedObject(const Json::Value &msg_id, bool force); - virtual ~TrexJsonRpcV2ParsedObject() {} - - /** - * main function to execute the command - * - */ - void execute(Json::Value &response); - -protected: - - /** - * instance private implementation - */ - virtual void _execute(Json::Value &response) = 0; - - Json::Value m_msg_id; - bool m_respond; -}; - -/** - * JSON RPC V2 parser - * - * @author imarom (12-Aug-15) - */ -class TrexJsonRpcV2Parser { - -public: - - /** - * creates a JSON-RPC object from a string - * - * @author imarom (12-Aug-15) - * - * @param msg - */ - TrexJsonRpcV2Parser(const std::string &msg); - - /** - * parses the string to a executable commands vector - * - * @author imarom (12-Aug-15) - */ - void parse(std::vector &commands); - -private: - - /** - * handle a single request - * - */ - void parse_single_request(Json::Value &request, std::vector &commands); - - std::string m_msg; -}; - -#endif /* __TREX_RPC_JSONRPC_V2_PARSER_H__ */ - diff --git a/src/rpc-server/include/trex_rpc_req_resp_server.h b/src/rpc-server/include/trex_rpc_req_resp_server.h deleted file mode 100644 index f12d0540..00000000 --- a/src/rpc-server/include/trex_rpc_req_resp_server.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - 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. -*/ - -#ifndef __TREX_RPC_REQ_RESP_API_H__ -#define __TREX_RPC_REQ_RESP_API_H__ - -#include - -/** - * request-response RPC server - * - * @author imarom (11-Aug-15) - */ -class TrexRpcServerReqRes : public TrexRpcServerInterface { -public: - - TrexRpcServerReqRes(const TrexRpcServerConfig &cfg); - -protected: - void _rpc_thread_cb(); - void _stop_rpc_thread(); - -private: - void handle_request(const std::string &request); - - static const int RPC_MAX_MSG_SIZE = 2048; - void *m_context; - void *m_socket; - uint8_t m_msg_buffer[RPC_MAX_MSG_SIZE]; -}; - - -#endif /* __TREX_RPC_REQ_RESP_API_H__ */ diff --git a/src/rpc-server/include/trex_rpc_server_api.h b/src/rpc-server/include/trex_rpc_server_api.h deleted file mode 100644 index 6bb81c73..00000000 --- a/src/rpc-server/include/trex_rpc_server_api.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - 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. -*/ - -#ifndef __TREX_RPC_SERVER_API_H__ -#define __TREX_RPC_SERVER_API_H__ - -#include -#include -#include -#include -#include -#include - -class TrexRpcServerInterface; - -/** - * defines a configuration of generic RPC server - * - * @author imarom (17-Aug-15) - */ -class TrexRpcServerConfig { -public: - - enum rpc_prot_e { - RPC_PROT_TCP - }; - - TrexRpcServerConfig(rpc_prot_e protocol, uint16_t port) : m_protocol(protocol), m_port(port) { - - } - - uint16_t get_port() { - return m_port; - } - - rpc_prot_e get_protocol() { - return m_protocol; - } - -private: - rpc_prot_e m_protocol; - uint16_t m_port; -}; - -/** - * generic type RPC server instance - * - * @author imarom (12-Aug-15) - */ -class TrexRpcServerInterface { -public: - - TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name); - virtual ~TrexRpcServerInterface(); - - /** - * starts the server - * - */ - void start(); - - /** - * stops the server - * - */ - void stop(); - - /** - * set verbose on or off - * - */ - void set_verbose(bool verbose); - - /** - * return TRUE if server is active - * - */ - bool is_running(); - - /** - * is the server verbose or not - * - */ - bool is_verbose(); - -protected: - /** - * instances implement this - * - */ - virtual void _rpc_thread_cb() = 0; - virtual void _stop_rpc_thread() = 0; - - /** - * prints a verbosed message (if enabled) - * - */ - void verbose_msg(const std::string &msg); - - TrexRpcServerConfig m_cfg; - bool m_is_running; - bool m_is_verbose; - std::thread *m_thread; - std::string m_name; -}; - -/** - * TREX RPC server - * may contain serveral types of RPC servers - * (request response, async and etc.) - * - * @author imarom (12-Aug-15) - */ -class TrexRpcServer { -public: - - /* currently only request response server config is required */ - TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg); - ~TrexRpcServer(); - - /** - * starts the RPC server - * - * @author imarom (19-Aug-15) - */ - void start(); - - /** - * stops the RPC server - * - * @author imarom (19-Aug-15) - */ - void stop(); - - void set_verbose(bool verbose); - - static const std::string &get_server_uptime() { - return s_server_uptime; - } - -private: - std::vector m_servers; - bool m_verbose; - static const std::string s_server_uptime; -}; - -#endif /* __TREX_RPC_SERVER_API_H__ */ diff --git a/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp deleted file mode 100644 index ac35babf..00000000 --- a/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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 - -using namespace std; - -/** - * get status - * - */ -trex_rpc_cmd_rc_e -TrexRpcCmdGetStatus::_run(const Json::Value ¶ms, Json::Value &result) { - - /* validate count */ - check_param_count(params, 0, result); - - Json::Value §ion = result["result"]; - - section["general"]["version"] = VERSION_BUILD_NUM; - section["general"]["build_date"] = get_build_date(); - section["general"]["build_time"] = get_build_time(); - section["general"]["version_user"] = VERSION_USER; - section["general"]["uptime"] = TrexRpcServer::get_server_uptime(); - - 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 deleted file mode 100644 index a5b358d0..00000000 --- a/src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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 - -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 deleted file mode 100644 index e67de286..00000000 --- a/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - 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 -#include -#include - -using namespace std; - -/** - * add command - * - */ -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"]; - - 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 (TREX_RPC_CMD_OK); -} - -/** - * sub command - * - * @author imarom (16-Aug-15) - */ -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"]; - - 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 (TREX_RPC_CMD_OK); -} - -/** - * ping command - */ -trex_rpc_cmd_rc_e -TrexRpcCmdPing::_run(const Json::Value ¶ms, Json::Value &result) { - - /* validate count */ - check_param_count(params, 0, result); - - result["result"] = "ACK"; - return (TREX_RPC_CMD_OK); -} - -/** - * query command - */ -trex_rpc_cmd_rc_e -TrexRpcCmdGetReg::_run(const Json::Value ¶ms, Json::Value &result) { - vector cmds; - - /* validate count */ - check_param_count(params, 0, result); - - TrexRpcCommandsTable::get_instance().query(cmds); - - Json::Value test = Json::arrayValue; - for (auto cmd : cmds) { - test.append(cmd); - } - - result["result"] = test; - - 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 deleted file mode 100644 index 39ccf27a..00000000 --- a/src/rpc-server/src/commands/trex_rpc_cmds.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - 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. -*/ - -#ifndef __TREX_RPC_CMD_H__ -#define __TREX_RPC_CMD_H__ - -#include -#include - -/* all the RPC commands decl. goes here */ - -/******************* test section ************/ - -/** - * add - * - */ -class TrexRpcCmdTestAdd : public TrexRpcCommand { -public: - TrexRpcCmdTestAdd() : TrexRpcCommand("test_add") {} -protected: - virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); -}; - -/** - * sub - * - */ -class TrexRpcCmdTestSub : public TrexRpcCommand { -public: - TrexRpcCmdTestSub() : TrexRpcCommand("test_sub") {} ; -protected: - virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); -}; - -/** - * ping - * - */ -class TrexRpcCmdPing : public TrexRpcCommand { -public: - TrexRpcCmdPing() : TrexRpcCommand("ping") {}; -protected: - virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); -}; - -/** - * get all registered commands - * - */ -class TrexRpcCmdGetReg : public TrexRpcCommand { -public: - TrexRpcCmdGetReg() : TrexRpcCommand("get_reg_cmds") {}; -protected: - virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); -}; - -/** - * get status - * - */ -class TrexRpcCmdGetStatus : public TrexRpcCommand { -public: - TrexRpcCmdGetStatus() : TrexRpcCommand("get_status") {}; -protected: - virtual trex_rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); -}; - - -/**************** test section end *************/ -#endif /* __TREX_RPC_CMD_H__ */ diff --git a/src/rpc-server/src/trex_rpc_cmd.cpp b/src/rpc-server/src/trex_rpc_cmd.cpp deleted file mode 100644 index d1a9ebb0..00000000 --- a/src/rpc-server/src/trex_rpc_cmd.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - 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_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_cmds_table.cpp b/src/rpc-server/src/trex_rpc_cmds_table.cpp deleted file mode 100644 index 04a56389..00000000 --- a/src/rpc-server/src/trex_rpc_cmds_table.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - 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 -#include - -#include "commands/trex_rpc_cmds.h" - -using namespace std; - -/************* table related methods ***********/ -TrexRpcCommandsTable::TrexRpcCommandsTable() { - /* add the test command (for gtest) */ - register_command(new TrexRpcCmdTestAdd()); - register_command(new TrexRpcCmdTestSub()); - register_command(new TrexRpcCmdPing()); - register_command(new TrexRpcCmdGetReg()); - register_command(new TrexRpcCmdGetStatus()); -} - -TrexRpcCommandsTable::~TrexRpcCommandsTable() { - for (auto cmd : m_rpc_cmd_table) { - delete cmd.second; - } -} - -TrexRpcCommand * TrexRpcCommandsTable::lookup(const string &method_name) { - auto search = m_rpc_cmd_table.find(method_name); - - if (search != m_rpc_cmd_table.end()) { - return search->second; - } else { - return NULL; - } -} - - -void TrexRpcCommandsTable::register_command(TrexRpcCommand *command) { - - m_rpc_cmd_table[command->get_name()] = command; -} - -void TrexRpcCommandsTable::query(vector &cmds) { - for (auto cmd : m_rpc_cmd_table) { - cmds.push_back(cmd.first); - } -} - diff --git a/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp b/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp deleted file mode 100644 index bf6056d5..00000000 --- a/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - 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 -#include -#include -#include - -#include - -#include - -/** - * error as described in the RFC - * http://www.jsonrpc.org/specification - */ -enum { - JSONRPC_V2_ERR_PARSE = -32700, - JSONRPC_V2_ERR_INVALID_REQ = -32600, - JSONRPC_V2_ERR_METHOD_NOT_FOUND = -32601, - JSONRPC_V2_ERR_INVALID_PARAMS = -32602, - JSONRPC_V2_ERR_INTERNAL_ERROR = -32603 -}; - - -/*************** 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 { - Json::Value dummy; - _execute(dummy); - } -} - -/****************** valid method return value **************/ -class JsonRpcMethod : public TrexJsonRpcV2ParsedObject { -public: - JsonRpcMethod(const Json::Value &msg_id, TrexRpcCommand *cmd, const Json::Value ¶ms) : TrexJsonRpcV2ParsedObject(msg_id), m_cmd(cmd), m_params(params) { - - } - - virtual void _execute(Json::Value &response) { - Json::Value result; - - trex_rpc_cmd_rc_e rc = m_cmd->run(m_params, result); - - switch (rc) { - case TREX_RPC_CMD_OK: - response["result"] = result["result"]; - break; - - 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 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"]; - break; - } - - } - -private: - TrexRpcCommand *m_cmd; - Json::Value m_params; -}; - -/******************* RPC error **************/ - -/** - * describes the parser error - * - */ -class JsonRpcError : public TrexJsonRpcV2ParsedObject { -public: - - 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; - } - -private: - int m_code; - std::string m_msg; -}; - - -/************** JSON RPC V2 parser implementation *************/ - -TrexJsonRpcV2Parser::TrexJsonRpcV2Parser(const std::string &msg) : m_msg(msg) { - -} - -/** - * parse a batch of commands - * - * @author imarom (17-Aug-15) - * - * @param commands - */ -void TrexJsonRpcV2Parser::parse(std::vector &commands) { - - Json::Reader reader; - Json::Value request; - - /* 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", true)); - return; - } - - /* request can be an array of requests */ - if (request.isArray()) { - /* handle each command */ - for (auto single_request : request) { - parse_single_request(single_request, commands); - } - } else { - /* handle single command */ - parse_single_request(request, commands); - } - - -} - - -void TrexJsonRpcV2Parser::parse_single_request(Json::Value &request, - std::vector &commands) { - - Json::Value msg_id = request["id"]; - - /* check version */ - if (request["jsonrpc"] != "2.0") { - commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_INVALID_REQ, "Invalid JSONRPC Version")); - return; - } - - /* check method name */ - std::string method_name = request["method"].asString(); - if (method_name == "") { - commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_INVALID_REQ, "Missing Method Name")); - 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; - } - - /* 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_server.cpp b/src/rpc-server/src/trex_rpc_req_resp_server.cpp deleted file mode 100644 index 7484758d..00000000 --- a/src/rpc-server/src/trex_rpc_req_resp_server.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - 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 -#include -#include - -#include -#include -#include - -#include -#include - -/** - * ZMQ based request-response server - * - */ -TrexRpcServerReqRes::TrexRpcServerReqRes(const TrexRpcServerConfig &cfg) : TrexRpcServerInterface(cfg, "req resp") { - /* ZMQ is not thread safe - this should be outside */ - m_context = zmq_ctx_new(); -} - -/** - * main entry point for the server - * this function will be created on a different thread - * - * @author imarom (17-Aug-15) - */ -void TrexRpcServerReqRes::_rpc_thread_cb() { - std::stringstream ss; - - /* create a socket based on the configuration */ - - m_socket = zmq_socket (m_context, ZMQ_REP); - - switch (m_cfg.get_protocol()) { - case TrexRpcServerConfig::RPC_PROT_TCP: - ss << "tcp://*:"; - break; - default: - throw TrexRpcException("unknown protocol for RPC"); - } - - ss << m_cfg.get_port(); - - /* bind the scoket */ - int rc = zmq_bind (m_socket, ss.str().c_str()); - if (rc != 0) { - throw TrexRpcException("Unable to start ZMQ server at: " + ss.str()); - } - - /* server main loop */ - while (m_is_running) { - int msg_size = zmq_recv (m_socket, m_msg_buffer, sizeof(m_msg_buffer), 0); - - /* msg_size of -1 is an error - decode it */ - if (msg_size == -1) { - /* normal shutdown and zmq_term was called */ - if (errno == ETERM) { - break; - } else { - throw TrexRpcException("Unhandled error of zmq_recv"); - } - } - - /* transform it to a string */ - std::string request((const char *)m_msg_buffer, msg_size); - - verbose_msg("Server Received: " + request); - - handle_request(request); - } - - /* must be done from the same thread */ - zmq_close(m_socket); -} - -/** - * stops the ZMQ based RPC server - * - */ -void TrexRpcServerReqRes::_stop_rpc_thread() { - /* by calling zmq_term we signal the blocked thread to exit */ - zmq_term(m_context); - -} - -/** - * handles a request given to the server - * respondes to the request - */ -void TrexRpcServerReqRes::handle_request(const std::string &request) { - std::vector commands; - Json::FastWriter writer; - Json::Value response; - - /* first parse the request using JSON RPC V2 parser */ - TrexJsonRpcV2Parser rpc_request(request); - rpc_request.parse(commands); - - int index = 0; - - /* for every command parsed - launch it */ - for (auto command : commands) { - Json::Value single_response; - - command->execute(single_response); - delete command; - - response[index++] = single_response; - - } - - /* write the JSON to string and sever on ZMQ */ - std::string response_str; - - if (response.size() == 1) { - response_str = writer.write(response[0]); - } else { - response_str = writer.write(response); - } - - verbose_msg("Server Replied: " + response_str); - - zmq_send(m_socket, response_str.c_str(), response_str.size(), 0); - -} diff --git a/src/rpc-server/src/trex_rpc_server.cpp b/src/rpc-server/src/trex_rpc_server.cpp deleted file mode 100644 index 366bfc5b..00000000 --- a/src/rpc-server/src/trex_rpc_server.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - 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 -#include -#include -#include -#include -#include - -/************** RPC server interface ***************/ - -TrexRpcServerInterface::TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name) : m_cfg(cfg), m_name(name) { - m_is_running = false; - m_is_verbose = false; -} - -TrexRpcServerInterface::~TrexRpcServerInterface() { - if (m_is_running) { - stop(); - } -} - -void TrexRpcServerInterface::verbose_msg(const std::string &msg) { - if (!m_is_verbose) { - return; - } - - std::cout << "[verbose][" << m_name << "] " << msg << "\n"; -} - -/** - * starts a RPC specific server - * - * @author imarom (17-Aug-15) - */ -void TrexRpcServerInterface::start() { - m_is_running = true; - - verbose_msg("Starting RPC Server"); - - m_thread = new std::thread(&TrexRpcServerInterface::_rpc_thread_cb, this); - if (!m_thread) { - throw TrexRpcException("unable to create RPC thread"); - } -} - -void TrexRpcServerInterface::stop() { - m_is_running = false; - - verbose_msg("Attempting To Stop RPC Server"); - - /* call the dynamic type class stop */ - _stop_rpc_thread(); - - /* hold until thread has joined */ - m_thread->join(); - - verbose_msg("Server Stopped"); - - delete m_thread; -} - -void TrexRpcServerInterface::set_verbose(bool verbose) { - m_is_verbose = verbose; -} - -bool TrexRpcServerInterface::is_verbose() { - return m_is_verbose; -} - -bool TrexRpcServerInterface::is_running() { - return m_is_running; -} - - -/************** RPC server *************/ - -static const std::string -get_current_date_time() { - time_t now = time(0); - struct tm tstruct; - char buf[80]; - tstruct = *localtime(&now); - strftime(buf, sizeof(buf), "%b %d %Y @ %X", &tstruct); - - return buf; -} - -const std::string TrexRpcServer::s_server_uptime = get_current_date_time(); - -TrexRpcServer::TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg) { - - /* add the request response server */ - m_servers.push_back(new TrexRpcServerReqRes(req_resp_cfg)); -} - -TrexRpcServer::~TrexRpcServer() { - - /* make sure they are all stopped */ - stop(); - - for (auto server : m_servers) { - delete server; - } -} - -/** - * start the server array - * - */ -void TrexRpcServer::start() { - for (auto server : m_servers) { - server->start(); - } -} - -/** - * stop the server array - * - */ -void TrexRpcServer::stop() { - for (auto server : m_servers) { - if (server->is_running()) { - server->stop(); - } - } -} - -void TrexRpcServer::set_verbose(bool verbose) { - for (auto server : m_servers) { - server->set_verbose(verbose); - } -} - diff --git a/src/rpc-server/src/trex_rpc_server_mock.cpp b/src/rpc-server/src/trex_rpc_server_mock.cpp deleted file mode 100644 index 98d1f35d..00000000 --- a/src/rpc-server/src/trex_rpc_server_mock.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - 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 -#include -#include - -using namespace std; - -/** - * on simulation this is not rebuild every version - * (improved stub) - * - */ -extern "C" const char * get_build_date(void){ - return (__DATE__); -} - -extern "C" const char * get_build_time(void){ - return (__TIME__ ); -} - -int gtest_main(int argc, char **argv); - -int main(int argc, char *argv[]) { - - // gtest ? - if (argc > 1) { - if (string(argv[1]) != "--ut") { - cout << "\n[Usage] " << argv[0] << ": " << " [--ut]\n\n"; - exit(-1); - } - return gtest_main(argc, argv); - } - - cout << "\n-= Starting RPC Server Mock =-\n\n"; - cout << "Listening on tcp://localhost:5050 [ZMQ]\n\n"; - - TrexRpcServerConfig rpc_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5050); - TrexRpcServer rpc(rpc_cfg); - - /* init the RPC server */ - rpc.start(); - - cout << "Setting Server To Full Verbose\n\n"; - rpc.set_verbose(true); - - cout << "Server Started\n\n"; - - while (true) { - sleep(1); - } - - rpc.stop(); - - -} diff --git a/src/rpc-server/trex_rpc_cmd.cpp b/src/rpc-server/trex_rpc_cmd.cpp new file mode 100644 index 00000000..d1a9ebb0 --- /dev/null +++ b/src/rpc-server/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_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/trex_rpc_cmd_api.h b/src/rpc-server/trex_rpc_cmd_api.h new file mode 100644 index 00000000..a2982f4a --- /dev/null +++ b/src/rpc-server/trex_rpc_cmd_api.h @@ -0,0 +1,141 @@ +/* + 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. +*/ + +#ifndef __TREX_RPC_CMD_API_H__ +#define __TREX_RPC_CMD_API_H__ + +#include +#include +#include +#include + +/** + * 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 + * + * @author imarom (13-Aug-15) + */ +class TrexRpcCommand { +public: + + /** + * method name and params + */ + TrexRpcCommand(const std::string &method_name) : m_name(method_name) { + + } + + /** + * 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; + } + + virtual ~TrexRpcCommand() {} + +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 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 generate_err(Json::Value &result, const std::string &msg); + + /** + * 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; +}; + +#endif /* __TREX_RPC_CMD_API_H__ */ + diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp new file mode 100644 index 00000000..04a56389 --- /dev/null +++ b/src/rpc-server/trex_rpc_cmds_table.cpp @@ -0,0 +1,65 @@ +/* + 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 +#include + +#include "commands/trex_rpc_cmds.h" + +using namespace std; + +/************* table related methods ***********/ +TrexRpcCommandsTable::TrexRpcCommandsTable() { + /* add the test command (for gtest) */ + register_command(new TrexRpcCmdTestAdd()); + register_command(new TrexRpcCmdTestSub()); + register_command(new TrexRpcCmdPing()); + register_command(new TrexRpcCmdGetReg()); + register_command(new TrexRpcCmdGetStatus()); +} + +TrexRpcCommandsTable::~TrexRpcCommandsTable() { + for (auto cmd : m_rpc_cmd_table) { + delete cmd.second; + } +} + +TrexRpcCommand * TrexRpcCommandsTable::lookup(const string &method_name) { + auto search = m_rpc_cmd_table.find(method_name); + + if (search != m_rpc_cmd_table.end()) { + return search->second; + } else { + return NULL; + } +} + + +void TrexRpcCommandsTable::register_command(TrexRpcCommand *command) { + + m_rpc_cmd_table[command->get_name()] = command; +} + +void TrexRpcCommandsTable::query(vector &cmds) { + for (auto cmd : m_rpc_cmd_table) { + cmds.push_back(cmd.first); + } +} + diff --git a/src/rpc-server/trex_rpc_cmds_table.h b/src/rpc-server/trex_rpc_cmds_table.h new file mode 100644 index 00000000..a41944f1 --- /dev/null +++ b/src/rpc-server/trex_rpc_cmds_table.h @@ -0,0 +1,79 @@ +/* + 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. +*/ + +#ifndef __TREX_RPC_CMDS_TABLE_H__ +#define __TREX_RPC_CMDS_TABLE_H__ + +#include +#include +#include +#include + +class TrexRpcCommand; + +/** + * holds all the commands registered + * + * @author imarom (13-Aug-15) + */ +class TrexRpcCommandsTable { + +public: + + static TrexRpcCommandsTable& get_instance() { + static TrexRpcCommandsTable instance; + return instance; + } + + /** + * register a new command + * + */ + void register_command(TrexRpcCommand *command); + + /** + * lookup for a command + * + */ + TrexRpcCommand * lookup(const std::string &method_name); + + /** + * query all commands registered + * + */ + void query(std::vector &cmds); + +private: + TrexRpcCommandsTable(); + ~TrexRpcCommandsTable(); + + /* c++ 2011 style singleton */ + TrexRpcCommandsTable(TrexRpcCommandsTable const&) = delete; + void operator=(TrexRpcCommandsTable const&) = delete; + + /** + * holds all the registered RPC commands + * + */ + std::unordered_map m_rpc_cmd_table; +}; + +#endif /* __TREX_RPC_CMDS_TABLE_H__ */ diff --git a/src/rpc-server/trex_rpc_exception_api.h b/src/rpc-server/trex_rpc_exception_api.h new file mode 100644 index 00000000..e349b980 --- /dev/null +++ b/src/rpc-server/trex_rpc_exception_api.h @@ -0,0 +1,42 @@ +/* + 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. +*/ + +#ifndef __TREX_RPC_EXCEPTION_API_H__ +#define __TREX_RPC_EXCEPTION_API_H__ + +#include +#include + +/** + * generic exception for RPC errors + * + */ +class TrexRpcException : public std::runtime_error +{ +public: + TrexRpcException() : std::runtime_error("") { + + } + TrexRpcException(const std::string &what) : std::runtime_error(what) { + } +}; + +#endif /* __TREX_RPC_EXCEPTION_API_H__ */ diff --git a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp new file mode 100644 index 00000000..bf6056d5 --- /dev/null +++ b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp @@ -0,0 +1,194 @@ +/* + 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 +#include +#include +#include + +#include + +#include + +/** + * error as described in the RFC + * http://www.jsonrpc.org/specification + */ +enum { + JSONRPC_V2_ERR_PARSE = -32700, + JSONRPC_V2_ERR_INVALID_REQ = -32600, + JSONRPC_V2_ERR_METHOD_NOT_FOUND = -32601, + JSONRPC_V2_ERR_INVALID_PARAMS = -32602, + JSONRPC_V2_ERR_INTERNAL_ERROR = -32603 +}; + + +/*************** 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 { + Json::Value dummy; + _execute(dummy); + } +} + +/****************** valid method return value **************/ +class JsonRpcMethod : public TrexJsonRpcV2ParsedObject { +public: + JsonRpcMethod(const Json::Value &msg_id, TrexRpcCommand *cmd, const Json::Value ¶ms) : TrexJsonRpcV2ParsedObject(msg_id), m_cmd(cmd), m_params(params) { + + } + + virtual void _execute(Json::Value &response) { + Json::Value result; + + trex_rpc_cmd_rc_e rc = m_cmd->run(m_params, result); + + switch (rc) { + case TREX_RPC_CMD_OK: + response["result"] = result["result"]; + break; + + 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 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"]; + break; + } + + } + +private: + TrexRpcCommand *m_cmd; + Json::Value m_params; +}; + +/******************* RPC error **************/ + +/** + * describes the parser error + * + */ +class JsonRpcError : public TrexJsonRpcV2ParsedObject { +public: + + 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; + } + +private: + int m_code; + std::string m_msg; +}; + + +/************** JSON RPC V2 parser implementation *************/ + +TrexJsonRpcV2Parser::TrexJsonRpcV2Parser(const std::string &msg) : m_msg(msg) { + +} + +/** + * parse a batch of commands + * + * @author imarom (17-Aug-15) + * + * @param commands + */ +void TrexJsonRpcV2Parser::parse(std::vector &commands) { + + Json::Reader reader; + Json::Value request; + + /* 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", true)); + return; + } + + /* request can be an array of requests */ + if (request.isArray()) { + /* handle each command */ + for (auto single_request : request) { + parse_single_request(single_request, commands); + } + } else { + /* handle single command */ + parse_single_request(request, commands); + } + + +} + + +void TrexJsonRpcV2Parser::parse_single_request(Json::Value &request, + std::vector &commands) { + + Json::Value msg_id = request["id"]; + + /* check version */ + if (request["jsonrpc"] != "2.0") { + commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_INVALID_REQ, "Invalid JSONRPC Version")); + return; + } + + /* check method name */ + std::string method_name = request["method"].asString(); + if (method_name == "") { + commands.push_back(new JsonRpcError(msg_id, JSONRPC_V2_ERR_INVALID_REQ, "Missing Method Name")); + 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; + } + + /* create a method object */ + commands.push_back(new JsonRpcMethod(msg_id, rpc_cmd, request["params"])); +} + diff --git a/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h new file mode 100644 index 00000000..3367ad6a --- /dev/null +++ b/src/rpc-server/trex_rpc_jsonrpc_v2_parser.h @@ -0,0 +1,94 @@ +/* + 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. +*/ + +#ifndef __TREX_RPC_JSONRPC_V2_PARSER_H__ +#define __TREX_RPC_JSONRPC_V2_PARSER_H__ + +#include +#include +#include + +/** + * JSON RPC V2 parsed object + * + * @author imarom (12-Aug-15) + */ +class TrexJsonRpcV2ParsedObject { +public: + + TrexJsonRpcV2ParsedObject(const Json::Value &msg_id, bool force); + virtual ~TrexJsonRpcV2ParsedObject() {} + + /** + * main function to execute the command + * + */ + void execute(Json::Value &response); + +protected: + + /** + * instance private implementation + */ + virtual void _execute(Json::Value &response) = 0; + + Json::Value m_msg_id; + bool m_respond; +}; + +/** + * JSON RPC V2 parser + * + * @author imarom (12-Aug-15) + */ +class TrexJsonRpcV2Parser { + +public: + + /** + * creates a JSON-RPC object from a string + * + * @author imarom (12-Aug-15) + * + * @param msg + */ + TrexJsonRpcV2Parser(const std::string &msg); + + /** + * parses the string to a executable commands vector + * + * @author imarom (12-Aug-15) + */ + void parse(std::vector &commands); + +private: + + /** + * handle a single request + * + */ + void parse_single_request(Json::Value &request, std::vector &commands); + + std::string m_msg; +}; + +#endif /* __TREX_RPC_JSONRPC_V2_PARSER_H__ */ + diff --git a/src/rpc-server/trex_rpc_req_resp_server.cpp b/src/rpc-server/trex_rpc_req_resp_server.cpp new file mode 100644 index 00000000..7484758d --- /dev/null +++ b/src/rpc-server/trex_rpc_req_resp_server.cpp @@ -0,0 +1,146 @@ +/* + 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 +#include +#include + +#include +#include +#include + +#include +#include + +/** + * ZMQ based request-response server + * + */ +TrexRpcServerReqRes::TrexRpcServerReqRes(const TrexRpcServerConfig &cfg) : TrexRpcServerInterface(cfg, "req resp") { + /* ZMQ is not thread safe - this should be outside */ + m_context = zmq_ctx_new(); +} + +/** + * main entry point for the server + * this function will be created on a different thread + * + * @author imarom (17-Aug-15) + */ +void TrexRpcServerReqRes::_rpc_thread_cb() { + std::stringstream ss; + + /* create a socket based on the configuration */ + + m_socket = zmq_socket (m_context, ZMQ_REP); + + switch (m_cfg.get_protocol()) { + case TrexRpcServerConfig::RPC_PROT_TCP: + ss << "tcp://*:"; + break; + default: + throw TrexRpcException("unknown protocol for RPC"); + } + + ss << m_cfg.get_port(); + + /* bind the scoket */ + int rc = zmq_bind (m_socket, ss.str().c_str()); + if (rc != 0) { + throw TrexRpcException("Unable to start ZMQ server at: " + ss.str()); + } + + /* server main loop */ + while (m_is_running) { + int msg_size = zmq_recv (m_socket, m_msg_buffer, sizeof(m_msg_buffer), 0); + + /* msg_size of -1 is an error - decode it */ + if (msg_size == -1) { + /* normal shutdown and zmq_term was called */ + if (errno == ETERM) { + break; + } else { + throw TrexRpcException("Unhandled error of zmq_recv"); + } + } + + /* transform it to a string */ + std::string request((const char *)m_msg_buffer, msg_size); + + verbose_msg("Server Received: " + request); + + handle_request(request); + } + + /* must be done from the same thread */ + zmq_close(m_socket); +} + +/** + * stops the ZMQ based RPC server + * + */ +void TrexRpcServerReqRes::_stop_rpc_thread() { + /* by calling zmq_term we signal the blocked thread to exit */ + zmq_term(m_context); + +} + +/** + * handles a request given to the server + * respondes to the request + */ +void TrexRpcServerReqRes::handle_request(const std::string &request) { + std::vector commands; + Json::FastWriter writer; + Json::Value response; + + /* first parse the request using JSON RPC V2 parser */ + TrexJsonRpcV2Parser rpc_request(request); + rpc_request.parse(commands); + + int index = 0; + + /* for every command parsed - launch it */ + for (auto command : commands) { + Json::Value single_response; + + command->execute(single_response); + delete command; + + response[index++] = single_response; + + } + + /* write the JSON to string and sever on ZMQ */ + std::string response_str; + + if (response.size() == 1) { + response_str = writer.write(response[0]); + } else { + response_str = writer.write(response); + } + + verbose_msg("Server Replied: " + response_str); + + zmq_send(m_socket, response_str.c_str(), response_str.size(), 0); + +} diff --git a/src/rpc-server/trex_rpc_req_resp_server.h b/src/rpc-server/trex_rpc_req_resp_server.h new file mode 100644 index 00000000..f12d0540 --- /dev/null +++ b/src/rpc-server/trex_rpc_req_resp_server.h @@ -0,0 +1,51 @@ +/* + 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. +*/ + +#ifndef __TREX_RPC_REQ_RESP_API_H__ +#define __TREX_RPC_REQ_RESP_API_H__ + +#include + +/** + * request-response RPC server + * + * @author imarom (11-Aug-15) + */ +class TrexRpcServerReqRes : public TrexRpcServerInterface { +public: + + TrexRpcServerReqRes(const TrexRpcServerConfig &cfg); + +protected: + void _rpc_thread_cb(); + void _stop_rpc_thread(); + +private: + void handle_request(const std::string &request); + + static const int RPC_MAX_MSG_SIZE = 2048; + void *m_context; + void *m_socket; + uint8_t m_msg_buffer[RPC_MAX_MSG_SIZE]; +}; + + +#endif /* __TREX_RPC_REQ_RESP_API_H__ */ diff --git a/src/rpc-server/trex_rpc_server.cpp b/src/rpc-server/trex_rpc_server.cpp new file mode 100644 index 00000000..366bfc5b --- /dev/null +++ b/src/rpc-server/trex_rpc_server.cpp @@ -0,0 +1,153 @@ +/* + 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 +#include +#include +#include +#include +#include + +/************** RPC server interface ***************/ + +TrexRpcServerInterface::TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name) : m_cfg(cfg), m_name(name) { + m_is_running = false; + m_is_verbose = false; +} + +TrexRpcServerInterface::~TrexRpcServerInterface() { + if (m_is_running) { + stop(); + } +} + +void TrexRpcServerInterface::verbose_msg(const std::string &msg) { + if (!m_is_verbose) { + return; + } + + std::cout << "[verbose][" << m_name << "] " << msg << "\n"; +} + +/** + * starts a RPC specific server + * + * @author imarom (17-Aug-15) + */ +void TrexRpcServerInterface::start() { + m_is_running = true; + + verbose_msg("Starting RPC Server"); + + m_thread = new std::thread(&TrexRpcServerInterface::_rpc_thread_cb, this); + if (!m_thread) { + throw TrexRpcException("unable to create RPC thread"); + } +} + +void TrexRpcServerInterface::stop() { + m_is_running = false; + + verbose_msg("Attempting To Stop RPC Server"); + + /* call the dynamic type class stop */ + _stop_rpc_thread(); + + /* hold until thread has joined */ + m_thread->join(); + + verbose_msg("Server Stopped"); + + delete m_thread; +} + +void TrexRpcServerInterface::set_verbose(bool verbose) { + m_is_verbose = verbose; +} + +bool TrexRpcServerInterface::is_verbose() { + return m_is_verbose; +} + +bool TrexRpcServerInterface::is_running() { + return m_is_running; +} + + +/************** RPC server *************/ + +static const std::string +get_current_date_time() { + time_t now = time(0); + struct tm tstruct; + char buf[80]; + tstruct = *localtime(&now); + strftime(buf, sizeof(buf), "%b %d %Y @ %X", &tstruct); + + return buf; +} + +const std::string TrexRpcServer::s_server_uptime = get_current_date_time(); + +TrexRpcServer::TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg) { + + /* add the request response server */ + m_servers.push_back(new TrexRpcServerReqRes(req_resp_cfg)); +} + +TrexRpcServer::~TrexRpcServer() { + + /* make sure they are all stopped */ + stop(); + + for (auto server : m_servers) { + delete server; + } +} + +/** + * start the server array + * + */ +void TrexRpcServer::start() { + for (auto server : m_servers) { + server->start(); + } +} + +/** + * stop the server array + * + */ +void TrexRpcServer::stop() { + for (auto server : m_servers) { + if (server->is_running()) { + server->stop(); + } + } +} + +void TrexRpcServer::set_verbose(bool verbose) { + for (auto server : m_servers) { + server->set_verbose(verbose); + } +} + diff --git a/src/rpc-server/trex_rpc_server_api.h b/src/rpc-server/trex_rpc_server_api.h new file mode 100644 index 00000000..6bb81c73 --- /dev/null +++ b/src/rpc-server/trex_rpc_server_api.h @@ -0,0 +1,165 @@ +/* + 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. +*/ + +#ifndef __TREX_RPC_SERVER_API_H__ +#define __TREX_RPC_SERVER_API_H__ + +#include +#include +#include +#include +#include +#include + +class TrexRpcServerInterface; + +/** + * defines a configuration of generic RPC server + * + * @author imarom (17-Aug-15) + */ +class TrexRpcServerConfig { +public: + + enum rpc_prot_e { + RPC_PROT_TCP + }; + + TrexRpcServerConfig(rpc_prot_e protocol, uint16_t port) : m_protocol(protocol), m_port(port) { + + } + + uint16_t get_port() { + return m_port; + } + + rpc_prot_e get_protocol() { + return m_protocol; + } + +private: + rpc_prot_e m_protocol; + uint16_t m_port; +}; + +/** + * generic type RPC server instance + * + * @author imarom (12-Aug-15) + */ +class TrexRpcServerInterface { +public: + + TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name); + virtual ~TrexRpcServerInterface(); + + /** + * starts the server + * + */ + void start(); + + /** + * stops the server + * + */ + void stop(); + + /** + * set verbose on or off + * + */ + void set_verbose(bool verbose); + + /** + * return TRUE if server is active + * + */ + bool is_running(); + + /** + * is the server verbose or not + * + */ + bool is_verbose(); + +protected: + /** + * instances implement this + * + */ + virtual void _rpc_thread_cb() = 0; + virtual void _stop_rpc_thread() = 0; + + /** + * prints a verbosed message (if enabled) + * + */ + void verbose_msg(const std::string &msg); + + TrexRpcServerConfig m_cfg; + bool m_is_running; + bool m_is_verbose; + std::thread *m_thread; + std::string m_name; +}; + +/** + * TREX RPC server + * may contain serveral types of RPC servers + * (request response, async and etc.) + * + * @author imarom (12-Aug-15) + */ +class TrexRpcServer { +public: + + /* currently only request response server config is required */ + TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg); + ~TrexRpcServer(); + + /** + * starts the RPC server + * + * @author imarom (19-Aug-15) + */ + void start(); + + /** + * stops the RPC server + * + * @author imarom (19-Aug-15) + */ + void stop(); + + void set_verbose(bool verbose); + + static const std::string &get_server_uptime() { + return s_server_uptime; + } + +private: + std::vector m_servers; + bool m_verbose; + static const std::string s_server_uptime; +}; + +#endif /* __TREX_RPC_SERVER_API_H__ */ diff --git a/src/rpc-server/trex_rpc_server_mock.cpp b/src/rpc-server/trex_rpc_server_mock.cpp new file mode 100644 index 00000000..98d1f35d --- /dev/null +++ b/src/rpc-server/trex_rpc_server_mock.cpp @@ -0,0 +1,75 @@ +/* + 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 +#include +#include + +using namespace std; + +/** + * on simulation this is not rebuild every version + * (improved stub) + * + */ +extern "C" const char * get_build_date(void){ + return (__DATE__); +} + +extern "C" const char * get_build_time(void){ + return (__TIME__ ); +} + +int gtest_main(int argc, char **argv); + +int main(int argc, char *argv[]) { + + // gtest ? + if (argc > 1) { + if (string(argv[1]) != "--ut") { + cout << "\n[Usage] " << argv[0] << ": " << " [--ut]\n\n"; + exit(-1); + } + return gtest_main(argc, argv); + } + + cout << "\n-= Starting RPC Server Mock =-\n\n"; + cout << "Listening on tcp://localhost:5050 [ZMQ]\n\n"; + + TrexRpcServerConfig rpc_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5050); + TrexRpcServer rpc(rpc_cfg); + + /* init the RPC server */ + rpc.start(); + + cout << "Setting Server To Full Verbose\n\n"; + rpc.set_verbose(true); + + cout << "Server Started\n\n"; + + while (true) { + sleep(1); + } + + rpc.stop(); + + +} -- cgit 1.2.3-korg