diff options
Diffstat (limited to 'src/rpc-server/src')
-rw-r--r-- | src/rpc-server/src/commands/trex_rpc_cmd_general.cpp | 49 | ||||
-rw-r--r-- | src/rpc-server/src/commands/trex_rpc_cmd_test.cpp | 126 | ||||
-rw-r--r-- | src/rpc-server/src/commands/trex_rpc_cmds.h | 89 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_cmds_table.cpp | 65 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp | 194 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_req_resp_server.cpp | 146 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_server.cpp | 153 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_server_mock.cpp | 75 |
8 files changed, 897 insertions, 0 deletions
diff --git a/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp new file mode 100644 index 00000000..193ce8db --- /dev/null +++ b/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp @@ -0,0 +1,49 @@ +/* + 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; + +/** + * get status + * + */ +TrexRpcCommand::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); + } + + 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 (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 new file mode 100644 index 00000000..e2dc8959 --- /dev/null +++ b/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp @@ -0,0 +1,126 @@ +/* + 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 <iostream> +#include <sstream> +#include <trex_rpc_cmds_table.h> + +using namespace std; + +/** + * add command + * + */ +TrexRpcCommand::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); + } + + result["result"] = x.asInt() + y.asInt(); + return (RPC_CMD_OK); +} + +/** + * sub command + * + * @author imarom (16-Aug-15) + */ +TrexRpcCommand::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); + } + + result["result"] = x.asInt() - y.asInt(); + return (RPC_CMD_OK); +} + +/** + * ping command + */ +TrexRpcCommand::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); + } + + result["result"] = "ACK"; + return (RPC_CMD_OK); +} + +/** + * query command + */ +TrexRpcCommand::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); + } + + + TrexRpcCommandsTable::get_instance().query(cmds); + + Json::Value test = Json::arrayValue; + for (auto cmd : cmds) { + test.append(cmd); + } + + result["result"] = test; + + return (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 new file mode 100644 index 00000000..e37e1cda --- /dev/null +++ b/src/rpc-server/src/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 <trex_rpc_cmd_api.h> +#include <json/json.h> + +/* all the RPC commands decl. goes here */ + +/******************* test section ************/ + +/** + * add + * + */ +class TrexRpcCmdTestAdd : public TrexRpcCommand { +public: + TrexRpcCmdTestAdd() : TrexRpcCommand("test_add") {} +protected: + virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); +}; + +/** + * sub + * + */ +class TrexRpcCmdTestSub : public TrexRpcCommand { +public: + TrexRpcCmdTestSub() : TrexRpcCommand("test_sub") {} ; +protected: + virtual rpc_cmd_rc_e _run(const Json::Value ¶ms, Json::Value &result); +}; + +/** + * ping + * + */ +class TrexRpcCmdPing : public TrexRpcCommand { +public: + TrexRpcCmdPing() : TrexRpcCommand("ping") {}; +protected: + virtual 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 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 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_cmds_table.cpp b/src/rpc-server/src/trex_rpc_cmds_table.cpp new file mode 100644 index 00000000..04a56389 --- /dev/null +++ b/src/rpc-server/src/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 <trex_rpc_cmds_table.h> +#include <iostream> + +#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<string> &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 new file mode 100644 index 00000000..be1eb2f8 --- /dev/null +++ b/src/rpc-server/src/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 <trex_rpc_exception_api.h> +#include <trex_rpc_jsonrpc_v2_parser.h> +#include <trex_rpc_cmd_api.h> +#include <trex_rpc_cmds_table.h> + +#include <json/json.h> + +#include <iostream> + +/** + * 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; + + TrexRpcCommand::rpc_cmd_rc_e rc = m_cmd->run(m_params, result); + + switch (rc) { + case TrexRpcCommand::RPC_CMD_OK: + response["result"] = result["result"]; + break; + + case TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR: + case TrexRpcCommand::RPC_CMD_PARAM_PARSE_ERR: + response["error"]["code"] = JSONRPC_V2_ERR_INVALID_PARAMS; + response["error"]["message"] = "Bad paramters for method"; + response["error"]["specific_err"] = result["specific_err"]; + break; + + case TrexRpcCommand::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<TrexJsonRpcV2ParsedObject *> &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<TrexJsonRpcV2ParsedObject *> &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 new file mode 100644 index 00000000..7484758d --- /dev/null +++ b/src/rpc-server/src/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 <trex_rpc_server_api.h> +#include <trex_rpc_req_resp_server.h> +#include <trex_rpc_jsonrpc_v2_parser.h> + +#include <unistd.h> +#include <sstream> +#include <iostream> + +#include <zmq.h> +#include <json/json.h> + +/** + * 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<TrexJsonRpcV2ParsedObject *> 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 new file mode 100644 index 00000000..366bfc5b --- /dev/null +++ b/src/rpc-server/src/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 <trex_rpc_server_api.h> +#include <trex_rpc_req_resp_server.h> +#include <unistd.h> +#include <zmq.h> +#include <sstream> +#include <iostream> + +/************** 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 new file mode 100644 index 00000000..fd4f051c --- /dev/null +++ b/src/rpc-server/src/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 <trex_rpc_server_api.h> +#include <iostream> +#include <unistd.h> + +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") || (argc != 2) ) { + 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(); + + +} |