draft
authorimarom <[email protected]>
Sun, 16 Aug 2015 15:06:30 +0000 (18:06 +0300)
committerimarom <[email protected]>
Sun, 16 Aug 2015 15:06:30 +0000 (18:06 +0300)
src/gtest/rpc_test.cpp
src/rpc-server/include/trex_rpc_cmd_api.h [new file with mode: 0644]
src/rpc-server/include/trex_rpc_cmds_table.h [moved from src/rpc-server/include/trex_rpc_commands.h with 63% similarity]
src/rpc-server/include/trex_rpc_jsonrpc_v2.h
src/rpc-server/src/commands/trex_rpc_cmd_test.cpp [new file with mode: 0644]
src/rpc-server/src/commands/trex_rpc_cmds.h [new file with mode: 0644]
src/rpc-server/src/trex_rpc_cmds_table.cpp [new file with mode: 0644]
src/rpc-server/src/trex_rpc_commands.cpp [deleted file]
src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp
src/rpc-server/src/trex_rpc_req_resp.cpp
src/rpc-server/src/trex_rpc_server.cpp

index d8fc538..0141dec 100644 (file)
@@ -105,6 +105,71 @@ TEST_F(RpcTest, basic_rpc_test) {
     EXPECT_EQ(response["jsonrpc"], "2.0");
     EXPECT_EQ(response["id"], 482);
     EXPECT_EQ(response["error"]["code"], -32601);
+
+    /* error but as notification */
+    req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"jfgldjlfds\"}";
+    resp_str = send_msg(req_str);
+
+    EXPECT_TRUE(reader.parse(resp_str, response, false));
+    EXPECT_TRUE(response == Json::Value::null);
+
+
+}
+
+TEST_F(RpcTest, test_add_command) {
+    Json::Value request;
+    Json::Value response;
+    Json::Reader reader;
+
+    string req_str;
+    string resp_str;
+
+    /* simple add - missing paramters */
+    req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_add\", \"id\": 488}";
+    resp_str = send_msg(req_str);
+
+    EXPECT_TRUE(reader.parse(resp_str, response, false));
+    EXPECT_EQ(response["jsonrpc"], "2.0");
+    EXPECT_EQ(response["id"], 488);
+    EXPECT_EQ(response["error"]["code"], -32602);
+
+    /* simple add that works */
+    req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_add\", \"params\": {\"x\": 17, \"y\": -13} , \"id\": \"itay\"}";
+    resp_str = send_msg(req_str);
+
+    EXPECT_TRUE(reader.parse(resp_str, response, false));
+    EXPECT_EQ(response["jsonrpc"], "2.0");
+    EXPECT_EQ(response["id"], "itay");
+    EXPECT_EQ(response["result"], 4);
+
+    /* add with bad paratemers types */
+    req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_add\", \"params\": {\"x\": \"blah\", \"y\": -13} , \"id\": 17}";
+    resp_str = send_msg(req_str);
+
+    EXPECT_TRUE(reader.parse(resp_str, response, false));
+    EXPECT_EQ(response["jsonrpc"], "2.0");
+    EXPECT_EQ(response["id"], 17);
+    EXPECT_EQ(response["error"]["code"], -32602);
+
+    /* add with invalid count of parameters */
+    req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_add\", \"params\": {\"y\": -13} , \"id\": 17}";
+    resp_str = send_msg(req_str);
+
+    EXPECT_TRUE(reader.parse(resp_str, response, false));
+    EXPECT_EQ(response["jsonrpc"], "2.0");
+    EXPECT_EQ(response["id"], 17);
+    EXPECT_EQ(response["error"]["code"], -32602);
+
+
+    /* big numbers */
+    req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_add\", \"params\": {\"x\": 4827371, \"y\": -39181273} , \"id\": \"itay\"}";
+    resp_str = send_msg(req_str);
+
+    EXPECT_TRUE(reader.parse(resp_str, response, false));
+    EXPECT_EQ(response["jsonrpc"], "2.0");
+    EXPECT_EQ(response["id"], "itay");
+    EXPECT_EQ(response["result"], -34353902);
+
 }
 
 TEST_F(RpcTest, batch_rpc_test) {
@@ -116,26 +181,36 @@ TEST_F(RpcTest, batch_rpc_test) {
     string resp_str;
 
     req_str = "[ \
-            {\"jsonrpc\": \"2.0\", \"method\": \"sum\", \"params\": [1,2,4], \"id\": \"1\"}, \
-            {\"jsonrpc\": \"2.0\", \"method\": \"notify_hello\", \"params\": [7]}, \
-            {\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42,23], \"id\": \"2\"}, \
+            {\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_add\", \"params\": {\"x\": 22, \"y\": 17}, \"id\": \"1\"}, \
+            {\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_sub\", \"params\": {\"x\": 22, \"y\": 17}, \"id\": \"2\"}, \
+            {\"jsonrpc\": \"2.0\", \"method\": \"test_rpc_add\", \"params\": {\"x\": 22, \"y\": \"itay\"}, \"id\": \"2\"}, \
             {\"foo\": \"boo\"}, \
             {\"jsonrpc\": \"2.0\", \"method\": \"foo.get\", \"params\": {\"name\": \"myself\"}, \"id\": \"5\"}, \
             {\"jsonrpc\": \"2.0\", \"method\": \"get_data\", \"id\": \"9\"} \
                ]";
 
     resp_str = send_msg(req_str);
-    cout << resp_str;
+
     EXPECT_TRUE(reader.parse(resp_str, response, false));
     EXPECT_TRUE(response.isArray());
 
     // message 1
     EXPECT_TRUE(response[0]["jsonrpc"] == "2.0");
     EXPECT_TRUE(response[0]["id"] == "1");
+    EXPECT_TRUE(response[0]["result"] == 39);
 
     // message 2
     EXPECT_TRUE(response[1]["jsonrpc"] == "2.0");
     EXPECT_TRUE(response[1]["id"] == "2");
+    EXPECT_TRUE(response[1]["result"] == 5);
+
+    // message 3
+    EXPECT_TRUE(response[2]["jsonrpc"] == "2.0");
+    EXPECT_TRUE(response[2]["id"] == "2");
+    EXPECT_TRUE(response[2]["error"]["code"] == -32602);
+
+    // message 4
+    EXPECT_TRUE(response[3] == Json::Value::null);
 
     return;
 }
diff --git a/src/rpc-server/include/trex_rpc_cmd_api.h b/src/rpc-server/include/trex_rpc_cmd_api.h
new file mode 100644 (file)
index 0000000..c041610
--- /dev/null
@@ -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.
+*/
+
+#ifndef __TREX_RPC_CMD_API_H__
+#define __TREX_RPC_CMD_API_H__
+
+#include <string>
+#include <vector>
+#include <json/json.h>
+
+/**
+ * interface for RPC command
+ * 
+ * @author imarom (13-Aug-15)
+ */
+class TrexRpcCommand {
+public:
+
+    /**
+     * describe different types of rc for run()
+     */
+    enum rpc_cmd_rc_e {
+        RPC_CMD_OK,
+        RPC_CMD_PARAM_COUNT_ERR = 1,
+        RPC_CMD_PARAM_PARSE_ERR
+    };
+
+    /**
+     * method name and params
+     */
+    TrexRpcCommand(const std::string &method_name) : m_name(method_name) {
+
+    }
+
+    rpc_cmd_rc_e run(const Json::Value &params, Json::Value &result) {
+        return _run(params, result);
+    }
+
+    const std::string &get_name() {
+        return m_name;
+    }
+
+    virtual ~TrexRpcCommand() {}
+
+protected:
+
+    /**
+     * implemented by the dervied class
+     * 
+     */
+    virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result) = 0;
+
+    std::string m_name;
+};
+
+#endif /* __TREX_RPC_CMD_API_H__ */
+
similarity index 63%
rename from src/rpc-server/include/trex_rpc_commands.h
rename to src/rpc-server/include/trex_rpc_cmds_table.h
index ef9f5ea..3cf6766 100644 (file)
@@ -19,52 +19,15 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-#ifndef __TREX_RPC_COMMANDS_H__
-#define __TREX_RPC_COMMANDS_H__
+#ifndef __TREX_RPC_CMDS_TABLE_H__
+#define __TREX_RPC_CMDS_TABLE_H__
 
 #include <unordered_map>
 #include <string>
 #include <vector>
 #include <json/json.h>
 
-/**
- * interface for RPC command
- * 
- * @author imarom (13-Aug-15)
- */
-class TrexRpcCommand {
-public:
-
-    /**
-     * describe different types of rc for run()
-     */
-    enum rpc_cmd_rc_e {
-        RPC_CMD_OK,
-        RPC_CMD_PARAM_COUNT_ERR = 1,
-        RPC_CMD_PARAM_PARSE_ERR
-    };
-
-    /**
-     * method name and params
-     */
-    TrexRpcCommand(const std::string &method_name);
-
-    rpc_cmd_rc_e run(const Json::Value &params, std::string &output);
-
-    const std::string &get_name();
-
-    virtual ~TrexRpcCommand() {}
-
-protected:
-
-    /**
-     * implemented by the dervied class
-     * 
-     */
-    virtual rpc_cmd_rc_e _run(const Json::Value &params, std::string &output) = 0;
-
-    std::string m_name;
-};
+class TrexRpcCommand;
 
 /**
  * holds all the commands registered
@@ -86,6 +49,7 @@ public:
 
 private:
     TrexRpcCommandsTable();
+    ~TrexRpcCommandsTable();
 
     /* c++ 2011 style singleton */
     TrexRpcCommandsTable(TrexRpcCommandsTable const&)  = delete;  
@@ -98,4 +62,4 @@ private:
     std::unordered_map<std::string, TrexRpcCommand *> m_rpc_cmd_table;
 };
 
-#endif /* __TREX_RPC_COMMANDS_H__ */
+#endif /* __TREX_RPC_CMDS_TABLE_H__ */
index 963dab7..a9b6faa 100644 (file)
@@ -37,6 +37,7 @@ class TrexJsonRpcV2ParsedObject {
 public:
 
     TrexJsonRpcV2ParsedObject(const Json::Value &msg_id, bool force);
+    virtual ~TrexJsonRpcV2ParsedObject() {}
 
     /**
      * main function to execute the command
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 (file)
index 0000000..913736a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ 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>
+
+using namespace std;
+
+/**
+ * add command
+ * 
+ */
+
+TestRpcAddMethod::TestRpcAddMethod() : TrexRpcCommand("test_rpc_add") {
+
+}
+
+TrexRpcCommand::rpc_cmd_rc_e 
+TestRpcAddMethod::_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) {
+        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);
+}
+
+/**
+ * sub command
+ * 
+ * @author imarom (16-Aug-15)
+ */
+
+TestRpcSubMethod::TestRpcSubMethod() : TrexRpcCommand("test_rpc_sub") {
+
+}
+
+TrexRpcCommand::rpc_cmd_rc_e 
+TestRpcSubMethod::_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) {
+        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);
+}
+
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 (file)
index 0000000..ea6e108
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ 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 ************/
+class TestRpcAddMethod : public TrexRpcCommand {
+public:
+     TestRpcAddMethod();
+protected:
+     virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
+};
+
+class TestRpcSubMethod : public TrexRpcCommand {
+public:
+     TestRpcSubMethod();
+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 (file)
index 0000000..4bc1ef2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ 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 TestRpcAddMethod());
+    register_command(new TestRpcSubMethod());
+}
+
+TrexRpcCommandsTable::~TrexRpcCommandsTable() {
+    for (auto cmd : m_rpc_cmd_table) {
+        delete cmd.second;
+    }
+}
+
+TrexRpcCommand * TrexRpcCommandsTable::lookup(const string &method_name) {
+    return m_rpc_cmd_table[method_name];
+}
+
+
+void TrexRpcCommandsTable::register_command(TrexRpcCommand *command) {
+
+    m_rpc_cmd_table[command->get_name()] = command;
+}
+
diff --git a/src/rpc-server/src/trex_rpc_commands.cpp b/src/rpc-server/src/trex_rpc_commands.cpp
deleted file mode 100644 (file)
index 8547384..0000000
+++ /dev/null
@@ -1,87 +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_commands.h>
-#include <iostream>
-#include <sstream>
-
-using namespace std;
-
-/***************** commands **********/
-class TestRpcAddRpcMethod : public TrexRpcCommand {
-public:
-
-    TestRpcAddRpcMethod() : TrexRpcCommand("test_rpc_add") {
-    }
-
-    virtual rpc_cmd_rc_e _run(const Json::Value &params, std::string &output) {
-        const Json::Value &x = params["x"];
-        const Json::Value &y = params["y"];
-        
-        /* validate count */
-        if (params.size() != 2) {
-            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);
-        }
-
-        std::stringstream ss;
-        ss << (x.asInt() + y.asInt());
-        output = ss.str();
-         
-        return (RPC_CMD_OK);
-    }
-};
-
-/*************** generic command methods *********/
-
-TrexRpcCommand::TrexRpcCommand(const string &method_name) : m_name(method_name) {
-}
-
-TrexRpcCommand::rpc_cmd_rc_e 
-TrexRpcCommand::run(const Json::Value &params, std::string &output) {
-    return _run(params, output);
-}
-
-const string & TrexRpcCommand::get_name() {
-    return m_name;
-}
-
-
-/************* table related methods ***********/
-TrexRpcCommandsTable::TrexRpcCommandsTable() {
-    /* add the test command (for gtest) */
-    register_command(new TestRpcAddRpcMethod());
-
-    TrexRpcCommand *cmd = m_rpc_cmd_table["test_rpc_add"];
-}
-
-TrexRpcCommand * TrexRpcCommandsTable::lookup(const string &method_name) {
-    return m_rpc_cmd_table[method_name];
-}
-
-
-void TrexRpcCommandsTable::register_command(TrexRpcCommand *command) {
-
-    m_rpc_cmd_table[command->get_name()] = command;
-}
index 2eec599..53811d7 100644 (file)
@@ -20,7 +20,8 @@ limitations under the License.
 */
 #include <trex_rpc_exception_api.h>
 #include <trex_rpc_jsonrpc_v2.h>
-#include <trex_rpc_commands.h>
+#include <trex_rpc_cmd_api.h>
+#include <trex_rpc_cmds_table.h>
 
 #include <json/json.h>
 
@@ -65,13 +66,13 @@ public:
     }
 
     virtual void _execute(Json::Value &response) {
-        std::string output;
+        Json::Value result;
 
-        TrexRpcCommand::rpc_cmd_rc_e rc = m_cmd->run(m_params, output);
+        TrexRpcCommand::rpc_cmd_rc_e rc = m_cmd->run(m_params, result);
 
         switch (rc) {
         case TrexRpcCommand::RPC_CMD_OK:
-            response["result"] = output;
+            response["result"] = result["result"];
             break;
 
         case TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR:
@@ -84,8 +85,8 @@ public:
     }
 
     virtual void _execute() {
-        std::string output;
-        m_cmd->run(m_params, output);
+        Json::Value result;
+        m_cmd->run(m_params, result);
     }
 
 private:
index 7acd1e0..e533c4f 100644 (file)
@@ -99,6 +99,7 @@ void TrexRpcServerReqRes::handle_request(const std::string &request) {
         Json::Value single_response;
 
         command->execute(single_response);
+        delete command;
 
         response[index++] = single_response;
 
index 3f6f510..5c29b6d 100644 (file)
@@ -92,6 +92,7 @@ void TrexRpcServerInterface::stop() {
     
     /* hold until thread has joined */    
     m_thread->join();
+    delete m_thread;
 }
 
 bool TrexRpcServerInterface::is_running() {