trex stateless changed to singleton.
authorimarom <[email protected]>
Sun, 6 Sep 2015 12:23:40 +0000 (15:23 +0300)
committerimarom <[email protected]>
Sun, 6 Sep 2015 12:23:40 +0000 (15:23 +0300)
added some more commands (remove all, get list of streams)

12 files changed:
scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py
src/rpc-server/commands/trex_rpc_cmd_general.cpp
src/rpc-server/commands/trex_rpc_cmd_stream.cpp
src/rpc-server/commands/trex_rpc_cmds.h
src/rpc-server/trex_rpc_cmds_table.cpp
src/rpc-server/trex_rpc_server.cpp
src/rpc-server/trex_rpc_server_api.h
src/rpc-server/trex_rpc_server_mock.cpp
src/stateless/trex_stateless.cpp
src/stateless/trex_stateless_api.h
src/stateless/trex_stream.cpp
src/stateless/trex_stream_api.h

index 054dc1a..b44b126 100644 (file)
@@ -44,12 +44,12 @@ class JsonRpcClient(object):
 
         try:
             # int numbers
-            pretty_str = re.sub(r'([ ]*:[ ]*)(\-?[1-9][0-9]*[^.])',r'\1{0}\2{1}'.format(bcolors.BLUE, bcolors.ENDC), pretty_str)
+            pretty_str = re.sub(r'([ ]*:[ ]+)(\-?[1-9][0-9]*[^.])',r'\1{0}\2{1}'.format(bcolors.BLUE, bcolors.ENDC), pretty_str)
             # float
-            pretty_str = re.sub(r'([ ]*:[ ]*)(\-?[1-9][0-9]*\.[0-9]+)',r'\1{0}\2{1}'.format(bcolors.MAGENTA, bcolors.ENDC), pretty_str)
+            pretty_str = re.sub(r'([ ]*:[ ]+)(\-?[1-9][0-9]*\.[0-9]+)',r'\1{0}\2{1}'.format(bcolors.MAGENTA, bcolors.ENDC), pretty_str)
             # strings
             
-            pretty_str = re.sub(r'([ ]*:[ ]*)("[^"]*")',r'\1{0}\2{1}'.format(bcolors.RED, bcolors.ENDC), pretty_str)
+            pretty_str = re.sub(r'([ ]*:[ ]+)("[^"]*")',r'\1{0}\2{1}'.format(bcolors.RED, bcolors.ENDC), pretty_str)
             pretty_str = re.sub(r"('[^']*')", r'{0}\1{1}'.format(bcolors.MAGENTA, bcolors.RED), pretty_str)
         except :
             pass
index 6b765ac..32952b1 100644 (file)
@@ -20,6 +20,7 @@ limitations under the License.
 */
 #include "trex_rpc_cmds.h"
 #include <trex_rpc_server_api.h>
+#include <trex_stateless_api.h>
 
 #ifndef TREX_RPC_MOCK_SERVER
     #include <../linux_dpdk/version.h>
@@ -41,8 +42,7 @@ TrexRpcCmdGetStatus::_run(const Json::Value &params, Json::Value &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();
+    section["general"]["built_by"]      = VERSION_USER;
 
     #else
 
@@ -50,10 +50,16 @@ TrexRpcCmdGetStatus::_run(const Json::Value &params, Json::Value &result) {
     section["general"]["build_date"]    = __DATE__;
     section["general"]["build_time"]    = __TIME__;
     section["general"]["version_user"]  = "MOCK";
-    section["general"]["uptime"]        = TrexRpcServer::get_server_uptime();
 
     #endif
 
+    section["general"]["uptime"]        = TrexRpcServer::get_server_uptime();
+    section["general"]["owner"]         = TrexRpcServer::get_owner();
+
+    // ports
+
+    section["ports"]["count"]           = TrexStateless::get_instance().get_port_count();
+
     return (TREX_RPC_CMD_OK);
 }
 
index 3ddf07f..6dfebe6 100644 (file)
@@ -52,21 +52,25 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
 
     stream->m_next_stream_id = parse_int(section, "next_stream_id", result);
 
-    const Json::Value &pkt = parse_array(section, "packet", result);
+    const Json::Value &pkt = parse_object(section, "packet", result);
+    const Json::Value &pkt_binary = parse_array(pkt, "binary", result);
 
     /* fetch the packet from the message */
 
-    stream->m_pkt_len = pkt.size();
-    stream->m_pkt = new uint8_t[pkt.size()];
-    if (!stream->m_pkt) {
+    stream->m_pkt.len    = pkt_binary.size();
+    stream->m_pkt.binary = new uint8_t[pkt_binary.size()];
+    if (!stream->m_pkt.binary) {
         generate_internal_err(result, "unable to allocate memory");
     }
 
     /* parse the packet */
-    for (int i = 0; i < pkt.size(); i++) {
-        stream->m_pkt[i] = parse_byte(pkt, i, result);
+    for (int i = 0; i < pkt_binary.size(); i++) {
+        stream->m_pkt.binary[i] = parse_byte(pkt_binary, i, result);
     }
 
+    /* meta data */
+    stream->m_pkt.meta = parse_string(pkt, "meta", result);
+
     /* parse RX info */
     const Json::Value &rx = parse_object(section, "rx_stats", result);
 
@@ -82,7 +86,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
     /* make sure this is a valid stream to add */
     validate_stream(stream, result);
 
-    TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(stream->m_port_id);
+    TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(stream->m_port_id);
     port->get_stream_table()->add_stream(stream);
 
     result["result"] = "ACK";
@@ -142,7 +146,7 @@ void
 TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &result) {
 
     /* check packet size */
-    if ( (stream->m_pkt_len < TrexStream::MIN_PKT_SIZE_BYTES) || (stream->m_pkt_len > TrexStream::MAX_PKT_SIZE_BYTES) ) {
+    if ( (stream->m_pkt.len < TrexStream::MIN_PKT_SIZE_BYTES) || (stream->m_pkt.len > TrexStream::MAX_PKT_SIZE_BYTES) ) {
         std::stringstream ss;
         ss << "bad packet size provided: should be between " << TrexStream::MIN_PKT_SIZE_BYTES << " and " << TrexStream::MAX_PKT_SIZE_BYTES;
         delete stream;
@@ -150,15 +154,15 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu
     }
 
     /* port id should be between 0 and count - 1 */
-    if (stream->m_port_id >= get_trex_stateless()->get_port_count()) {
+    if (stream->m_port_id >= TrexStateless::get_instance().get_port_count()) {
         std::stringstream ss;
-        ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+        ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1;
         delete stream;
         generate_execute_err(result, ss.str());
     }
 
      /* add the stream to the port's stream table */
-    TrexStatelessPort * port = get_trex_stateless()->get_port_by_id(stream->m_port_id);
+    TrexStatelessPort * port = TrexStateless::get_instance().get_port_by_id(stream->m_port_id);
 
     /* does such a stream exists ? */
     if (port->get_stream_table()->get_stream_by_id(stream->m_stream_id)) {
@@ -180,13 +184,13 @@ TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
     uint32_t stream_id = parse_int(params, "stream_id", result);
 
 
-    if (port_id >= get_trex_stateless()->get_port_count()) {
+    if (port_id >= TrexStateless::get_instance().get_port_count()) {
         std::stringstream ss;
-        ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+        ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1;
         generate_execute_err(result, ss.str());
     }
 
-    TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(port_id);
+    TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
     TrexStream *stream = port->get_stream_table()->get_stream_by_id(stream_id);
 
     if (!stream) {
@@ -198,6 +202,8 @@ TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
     port->get_stream_table()->remove_stream(stream);
 
     result["result"] = "ACK";
+
+    return (TREX_RPC_CMD_OK);
 }
 
 /***************************
@@ -209,15 +215,49 @@ trex_rpc_cmd_rc_e
 TrexRpcCmdRemoveAllStreams::_run(const Json::Value &params, Json::Value &result) {
     uint8_t  port_id = parse_byte(params, "port_id", result);
 
-    if (port_id >= get_trex_stateless()->get_port_count()) {
+    if (port_id >= TrexStateless::get_instance().get_port_count()) {
         std::stringstream ss;
-        ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+        ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1;
         generate_execute_err(result, ss.str());
     }
 
-       TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(port_id);
+       TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
        port->get_stream_table()->remove_and_delete_all_streams();
 
        result["result"] = "ACK";
+
+       return (TREX_RPC_CMD_OK);
+}
+
+/***************************
+ * get all streams configured 
+ * on specific port 
+ * 
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetStreamList::_run(const Json::Value &params, Json::Value &result) {
+    std::vector<uint32_t> stream_list;
+
+    uint8_t  port_id = parse_byte(params, "port_id", result);
+
+    if (port_id >= TrexStateless::get_instance().get_port_count()) {
+        std::stringstream ss;
+        ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1;
+        generate_execute_err(result, ss.str());
+    }
+
+       TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id);
+
+       port->get_stream_table()->get_stream_list(stream_list);
+
+       Json::Value json_list = Json::arrayValue;
+
+       for (auto stream_id : stream_list) {
+           json_list.append(stream_id);
+       }
+
+       result["result"] = json_list;
+
+       return (TREX_RPC_CMD_OK);
 }
 
index 64551fa..e9666f2 100644 (file)
@@ -74,4 +74,6 @@ void validate_stream(const TrexStream *stream, Json::Value &result);
 );
 
 
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStreamList, "get_stream_list", 1);
+
 #endif /* __TREX_RPC_CMD_H__ */
index 7d5d49a..fc6d7b8 100644 (file)
@@ -38,6 +38,7 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() {
     register_command(new TrexRpcCmdAddStream());
     register_command(new TrexRpcCmdRemoveStream());
     register_command(new TrexRpcCmdRemoveAllStreams());
+    register_command(new TrexRpcCmdGetStreamList());
 }
 
 TrexRpcCommandsTable::~TrexRpcCommandsTable() {
index 6b8c200..149bb66 100644 (file)
@@ -111,6 +111,7 @@ get_current_date_time() {
 }
 
 const std::string TrexRpcServer::s_server_uptime = get_current_date_time();
+std::string TrexRpcServer::s_owner = "none";
 
 TrexRpcServer::TrexRpcServer(const TrexRpcServerConfig &req_resp_cfg) {
 
index ab1bc45..b431367 100644 (file)
@@ -163,10 +163,34 @@ public:
         return s_server_uptime;
     }
 
+
+    /**
+     * query for ownership
+     * 
+     */
+    static const std::string &get_owner() {
+        return s_owner;
+    }
+
+    /**
+    * take ownership of the server array 
+    * this is static 
+    * ownership is total 
+    * 
+    */
+    static void set_owner(const std::string &owner) {
+        s_owner = owner;
+    }
+
+    static void clear_owner() {
+        s_owner = "none";
+    }
+
 private:
     std::vector<TrexRpcServerInterface *>   m_servers;
     bool                                    m_verbose;
     static const std::string                s_server_uptime;
+    static std::string                      s_owner;
 };
 
 #endif /* __TREX_RPC_SERVER_API_H__ */
index 98d1f35..a248558 100644 (file)
@@ -20,6 +20,8 @@ limitations under the License.
 */
 
 #include <trex_rpc_server_api.h>
+#include <trex_stateless_api.h>
+
 #include <iostream>
 #include <unistd.h>
 
@@ -54,6 +56,9 @@ int main(int argc, char *argv[]) {
     cout << "\n-= Starting RPC Server Mock =-\n\n";
     cout << "Listening on tcp://localhost:5050 [ZMQ]\n\n";
 
+    /* configure the stateless object with 4 ports */
+    TrexStateless::configure(4);
+
     TrexRpcServerConfig rpc_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5050);
     TrexRpcServer rpc(rpc_cfg);
 
index 0593198..ff469d7 100644 (file)
@@ -24,13 +24,30 @@ limitations under the License.
  * Trex stateless object
  * 
  **********************************************************/
-TrexStateless::TrexStateless(uint8_t port_count) : m_port_count(port_count) {
+TrexStateless::TrexStateless() {
+    m_is_configured = false;
+}
 
-    m_ports = new TrexStatelessPort*[port_count];
+/**
+ * one time configuration of the stateless object
+ * 
+ */
+void TrexStateless::configure(uint8_t port_count) {
 
-    for (int i = 0; i < m_port_count; i++) {
-        m_ports[i] = new TrexStatelessPort(i);
+    TrexStateless& instance = get_instance_internal();
+
+    if (instance.m_is_configured) {
+        throw TrexException("re-configuration of stateless object is not allowed");
     }
+
+    instance.m_port_count = port_count;
+    instance.m_ports = new TrexStatelessPort*[port_count];
+
+    for (int i = 0; i < instance.m_port_count; i++) {
+        instance.m_ports[i] = new TrexStatelessPort(i);
+    }
+
+    instance.m_is_configured = true;
 }
 
 TrexStateless::~TrexStateless() {
@@ -54,10 +71,3 @@ uint8_t TrexStateless::get_port_count() {
     return m_port_count;
 }
 
-/******** HACK - REMOVE ME ***********/
-TrexStateless * get_trex_stateless() {
-    static TrexStateless trex_stateless(8);
-    return &trex_stateless;
-
-}
-
index 6406a94..edd7b05 100644 (file)
@@ -71,26 +71,48 @@ private:
  */
 class TrexStateless {
 public:
+
     /**
-     * create a T-Rex stateless object
-     * 
-     * @author imarom (31-Aug-15)
+     * configure the stateless object singelton 
+     * reconfiguration is not allowed
+     * an exception will be thrown
+     */
+    static void configure(uint8_t port_count);
+
+    /**
+     * singleton public get instance
      * 
-     * @param port_count 
      */
-    TrexStateless(uint8_t port_count);
-    ~TrexStateless();
+    static TrexStateless& get_instance() {
+        TrexStateless& instance = get_instance_internal();
+
+        if (!instance.m_is_configured) {
+            throw TrexException("object is not configured");
+        }
+
+        return instance;
+    }
 
     TrexStatelessPort *get_port_by_id(uint8_t port_id);
     uint8_t            get_port_count();
 
 protected:
+    TrexStateless();
+    ~TrexStateless();
+
+    static TrexStateless& get_instance_internal () {
+        static TrexStateless instance;
+        return instance;
+    }
+
+     /* c++ 2011 style singleton */
+    TrexStateless(TrexStateless const&)      = delete;  
+    void operator=(TrexStateless const&)     = delete;
+
+    bool                m_is_configured;
     TrexStatelessPort  **m_ports;
     uint8_t             m_port_count;
 };
 
-/****** HACK *******/
-TrexStateless *get_trex_stateless();
-
 #endif /* __TREX_STATELESS_API_H__ */
 
index 1465b1b..b391977 100644 (file)
@@ -32,16 +32,16 @@ TrexStream::TrexStream(uint8_t port_id, uint32_t stream_id) : m_port_id(port_id)
     m_enabled    = false;
     m_self_start = false;
 
-    m_pkt = NULL;
-    m_pkt_len = 0;
+    m_pkt.binary = NULL;
+    m_pkt.len    = 0;
 
     m_rx_check.m_enable = false;
 
 }
 
 TrexStream::~TrexStream() {
-    if (m_pkt) {
-        delete [] m_pkt;
+    if (m_pkt.binary) {
+        delete [] m_pkt.binary;
     }
 }
 
@@ -91,3 +91,11 @@ TrexStream * TrexStreamTable::get_stream_by_id(uint32_t stream_id) {
         return NULL;
     }
 }
+
+void TrexStreamTable::get_stream_list(std::vector<uint32_t> &stream_list) {
+    stream_list.clear();
+
+    for (auto stream : m_stream_table) {
+        stream_list.push_back(stream.first);
+    }
+}
index f57b7aa..97e0b7f 100644 (file)
@@ -22,7 +22,9 @@ limitations under the License.
 #define __TREX_STREAM_API_H__
 
 #include <unordered_map>
+#include <vector>
 #include <stdint.h>
+#include <string>
 
 class TrexRpcCmdAddStream;
 
@@ -58,8 +60,11 @@ private:
     bool          m_self_start;
     
     /* pkt */
-    uint8_t      *m_pkt;
-    uint16_t      m_pkt_len;
+    struct {
+        uint8_t      *binary;
+        uint16_t      len;
+        std::string   meta;
+    } m_pkt;
 
     /* VM */
 
@@ -157,6 +162,15 @@ public:
      */
     TrexStream * get_stream_by_id(uint32_t stream_id);
 
+    /**
+     * populate a list with all the stream IDs
+     * 
+     * @author imarom (06-Sep-15)
+     * 
+     * @param stream_list 
+     */
+    void get_stream_list(std::vector<uint32_t> &stream_list);
+
 private:
     /**
      * holds all the stream in a hash table by stream id