summaryrefslogtreecommitdiffstats
path: root/src/rpc-server/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc-server/src')
-rw-r--r--src/rpc-server/src/commands/trex_rpc_cmd_general.cpp49
-rw-r--r--src/rpc-server/src/commands/trex_rpc_cmd_test.cpp126
-rw-r--r--src/rpc-server/src/commands/trex_rpc_cmds.h89
-rw-r--r--src/rpc-server/src/trex_rpc_cmds_table.cpp65
-rw-r--r--src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp194
-rw-r--r--src/rpc-server/src/trex_rpc_req_resp_server.cpp146
-rw-r--r--src/rpc-server/src/trex_rpc_server.cpp153
-rw-r--r--src/rpc-server/src/trex_rpc_server_mock.cpp75
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 &params, 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 &section = 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 &params, 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 &params, 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 &params, 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 &params, 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 &params, Json::Value &result);
+};
+
+/**
+ * sub
+ *
+ */
+class TrexRpcCmdTestSub : public TrexRpcCommand {
+public:
+ TrexRpcCmdTestSub() : TrexRpcCommand("test_sub") {} ;
+protected:
+ virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
+};
+
+/**
+ * ping
+ *
+ */
+class TrexRpcCmdPing : public TrexRpcCommand {
+public:
+ TrexRpcCmdPing() : TrexRpcCommand("ping") {};
+protected:
+ virtual rpc_cmd_rc_e _run(const Json::Value &params, 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 &params, Json::Value &result);
+};
+
+/**
+ * get status
+ *
+ */
+class TrexRpcCmdGetStatus : public TrexRpcCommand {
+public:
+ TrexRpcCmdGetStatus() : TrexRpcCommand("get_status") {};
+protected:
+ virtual rpc_cmd_rc_e _run(const Json::Value &params, 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 &params) : 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();
+
+
+}