rc, msg = self.rpc_client.query_rpc_server()
if rc:
- lst = msg.split('\n')
- self.supported_rpc = [str(x) for x in lst if x]
+ self.supported_rpc = [str(x) for x in msg if x]
# a cool hack - i stole this function and added space
def completenames(self, text, *ignored):
if not rc:
print "\n*** Failed to query RPC server: " + str(msg)
- print "\nRPC server supports the following commands: \n\n" + msg
+ print "\nRPC server supports the following commands: \n\n"
+ for func in msg:
+ if func:
+ print func
+ print "\n"
def do_ping (self, line):
'''\npings the RPC server\n'''
else:
print "[FAILED]\n"
- print "Server Response:\n\n{0}\n".format(json.dumps(msg))
def complete_rpc (self, text, line, begidx, endidx):
return [x for x in self.supported_rpc if x.startswith(text)]
def main ():
# RPC client
- try:
- rpc_client = RpcClient("localhost", 5050)
- rpc_client.connect()
- except Exception as e:
- print "\n*** " + str(e) + "\n"
+ rpc_client = RpcClient("localhost", 5050)
+ rc, msg = rpc_client.connect()
+ if not rc:
+ print "\n*** " + msg + "\n"
exit(-1)
# console
import zmq\r
import json\r
from time import sleep\r
+import random\r
\r
class RpcClient():\r
\r
\r
return rc\r
\r
+ def pretty_json (self, json_str):\r
+ return json.dumps(json.loads(json_str), indent = 4, separators=(',', ': '))\r
+\r
+ def verbose_msg (self, msg):\r
+ if not self.verbose:\r
+ return\r
+\r
+ print "[verbose] " + msg\r
+\r
+\r
def create_jsonrpc_v2 (self, method_name, params = {}, id = None):\r
msg = {}\r
msg["jsonrpc"] = "2.0"\r
return json.dumps(msg)\r
\r
def invoke_rpc_method (self, method_name, params = {}, block = True):\r
- msg = self.create_jsonrpc_v2(method_name, params, id = 1)\r
+ id = random.randint(1, 1000)\r
+ msg = self.create_jsonrpc_v2(method_name, params, id = id)\r
\r
- if self.verbose:\r
- print "\n[verbose] Sending Request To Server: " + str(msg) + "\n"\r
+ self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n")\r
\r
if block:\r
self.socket.send(msg)\r
if not got_response:\r
return False, "Failed To Get Server Response"\r
\r
- if self.verbose:\r
- print "[verbose] Server Response: " + str(response)\r
+ self.verbose_msg("Server Response:\n\n" + self.pretty_json(response) + "\n")\r
\r
# decode\r
response_json = json.loads(response)\r
if (response_json.get("jsonrpc") != "2.0"):\r
return False, "Malfromed Response ({0})".format(str(response))\r
\r
+ if (response_json.get("id") != id):\r
+ return False, "Server Replied With Bad ID ({0})".format(str(response))\r
+\r
# error reported by server\r
if ("error" in response_json):\r
return False, response_json["error"]["message"]\r
rc, err = self.ping_rpc_server()\r
if not rc:\r
self.context.destroy(linger = 0)\r
- raise Exception(err)\r
+ return False, err\r
\r
#print "Connection Established !\n"\r
print "[SUCCESS]\n"\r
-\r
+ return True, ""\r
\r
def __del__ (self):\r
print "Shutting down RPC client\n"\r
class TrexRpcServerInterface {
public:
- TrexRpcServerInterface(const TrexRpcServerConfig &cfg);
+ TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name);
virtual ~TrexRpcServerInterface();
/**
*/
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;
+ 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;
};
/**
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<TrexRpcServerInterface *> m_servers;
- static const std::string s_server_uptime;
+ std::vector<TrexRpcServerInterface *> m_servers;
+ bool m_verbose;
+ static const std::string s_server_uptime;
};
#endif /* __TREX_RPC_SERVER_API_H__ */
TrexRpcCommand::rpc_cmd_rc_e
TrexRpcCmdGetReg::_run(const Json::Value ¶ms, Json::Value &result) {
vector<string> cmds;
- stringstream ss;
/* validate count */
if (params.size() != 0) {
TrexRpcCommandsTable::get_instance().query(cmds);
+
+ Json::Value test = Json::arrayValue;
for (auto cmd : cmds) {
- ss << cmd << "\n";
+ test.append(cmd);
}
- result["result"] = ss.str();
+ result["result"] = test;
+
return (RPC_CMD_OK);
}
* ZMQ based request-response server
*
*/
-TrexRpcServerReqRes::TrexRpcServerReqRes(const TrexRpcServerConfig &cfg) : TrexRpcServerInterface(cfg) {
+TrexRpcServerReqRes::TrexRpcServerReqRes(const TrexRpcServerConfig &cfg) : TrexRpcServerInterface(cfg, "req resp") {
/* ZMQ is not thread safe - this should be outside */
m_context = zmq_ctx_new();
}
/* transform it to a string */
std::string request((const char *)m_msg_buffer, msg_size);
+
+ verbose_msg("Server Received: " + request);
+
handle_request(request);
}
}
/* write the JSON to string and sever on ZMQ */
- std::string reponse_str;
+ std::string response_str;
if (response.size() == 1) {
- reponse_str = writer.write(response[0]);
+ response_str = writer.write(response[0]);
} else {
- reponse_str = writer.write(response);
+ response_str = writer.write(response);
}
- zmq_send(m_socket, reponse_str.c_str(), reponse_str.size(), 0);
+ verbose_msg("Server Replied: " + response_str);
+
+ zmq_send(m_socket, response_str.c_str(), response_str.size(), 0);
}
#include <unistd.h>
#include <zmq.h>
#include <sstream>
+#include <iostream>
/************** RPC server interface ***************/
-TrexRpcServerInterface::TrexRpcServerInterface(const TrexRpcServerConfig &cfg) : m_cfg(cfg) {
+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() {
}
}
+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
*
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;
}
}
}
+void TrexRpcServer::set_verbose(bool verbose) {
+ for (auto server : m_servers) {
+ server->set_verbose(verbose);
+ }
+}
+
/* 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) {