summaryrefslogtreecommitdiffstats
path: root/src/rpc-server
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2015-08-24 15:25:19 +0300
committerimarom <imarom@cisco.com>2015-08-24 15:25:19 +0300
commit5089a9b557fb3c0198a774f14cff53947a432398 (patch)
tree9ad07f83336f449f65e17a2fe43bca8b1e0a6166 /src/rpc-server
parent3bfe53394f43a37ce02b09c6420751027c602047 (diff)
parsing enhancment
Diffstat (limited to 'src/rpc-server')
-rw-r--r--src/rpc-server/include/trex_rpc_cmd_api.h95
-rw-r--r--src/rpc-server/include/trex_rpc_exception_api.h3
-rw-r--r--src/rpc-server/src/commands/trex_rpc_cmd_general.cpp10
-rw-r--r--src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp47
-rw-r--r--src/rpc-server/src/commands/trex_rpc_cmd_test.cpp61
-rw-r--r--src/rpc-server/src/commands/trex_rpc_cmds.h10
-rw-r--r--src/rpc-server/src/trex_rpc_cmd.cpp144
-rw-r--r--src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp10
-rw-r--r--src/rpc-server/src/trex_rpc_server_mock.cpp2
9 files changed, 299 insertions, 83 deletions
diff --git a/src/rpc-server/include/trex_rpc_cmd_api.h b/src/rpc-server/include/trex_rpc_cmd_api.h
index c773b15f..a2982f4a 100644
--- a/src/rpc-server/include/trex_rpc_cmd_api.h
+++ b/src/rpc-server/include/trex_rpc_cmd_api.h
@@ -25,6 +25,37 @@ limitations under the License.
#include <string>
#include <vector>
#include <json/json.h>
+#include <trex_rpc_exception_api.h>
+
+/**
+ * describe different types of rc for run()
+ */
+typedef enum trex_rpc_cmd_rc_ {
+ TREX_RPC_CMD_OK,
+ TREX_RPC_CMD_PARAM_COUNT_ERR = 1,
+ TREX_RPC_CMD_PARAM_PARSE_ERR,
+ TREX_RPC_CMD_INTERNAL_ERR
+} trex_rpc_cmd_rc_e;
+
+/**
+ * simple exception for RPC command processing
+ *
+ * @author imarom (23-Aug-15)
+ */
+class TrexRpcCommandException : TrexRpcException {
+public:
+ TrexRpcCommandException(trex_rpc_cmd_rc_e rc) : m_rc(rc) {
+
+ }
+
+ trex_rpc_cmd_rc_e get_rc() {
+ return m_rc;
+
+ }
+
+protected:
+ trex_rpc_cmd_rc_e m_rc;
+};
/**
* interface for RPC command
@@ -35,25 +66,17 @@ 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,
- RPC_CMD_INTERNAL_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);
- }
+ /**
+ * entry point for executing RPC command
+ *
+ */
+ trex_rpc_cmd_rc_e run(const Json::Value &params, Json::Value &result);
const std::string &get_name() {
return m_name;
@@ -64,25 +87,53 @@ public:
protected:
/**
+ * different types of fields
+ */
+ enum field_type_e {
+ FIELD_TYPE_INT,
+ FIELD_TYPE_BOOL,
+ FIELD_TYPE_STR,
+ FIELD_TYPE_OBJ,
+ FILED_TYPE_ARRAY
+ };
+
+ /**
* implemented by the dervied class
*
*/
- virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result) = 0;
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result) = 0;
+
+ /**
+ * check param count
+ */
+ void check_param_count(const Json::Value &params, int expected, Json::Value &result);
+
+ /**
+ * check field type
+ *
+ */
+ //void check_field_type(const Json::Value &field, field_type_e type, Json::Value &result);
+ void check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result);
/**
* error generating functions
*
*/
- void genernate_err(Json::Value &result, const std::string &msg) {
- result["specific_err"] = msg;
- }
+ void generate_err(Json::Value &result, const std::string &msg);
- void generate_err_param_count(Json::Value &result, int expected, int provided) {
- std::stringstream ss;
- ss << "method expects '" << expected << "' paramteres, '" << provided << "' provided";
- genernate_err(result, ss.str());
- }
+ /**
+ * translate enum to string
+ *
+ */
+ const char * type_to_str(field_type_e type);
+
+ /**
+ * translate JSON values to string
+ *
+ */
+ const char * json_type_to_name(const Json::Value &value);
+ /* RPC command name */
std::string m_name;
};
diff --git a/src/rpc-server/include/trex_rpc_exception_api.h b/src/rpc-server/include/trex_rpc_exception_api.h
index 8783c219..e349b980 100644
--- a/src/rpc-server/include/trex_rpc_exception_api.h
+++ b/src/rpc-server/include/trex_rpc_exception_api.h
@@ -32,6 +32,9 @@ limitations under the License.
class TrexRpcException : public std::runtime_error
{
public:
+ TrexRpcException() : std::runtime_error("") {
+
+ }
TrexRpcException(const std::string &what) : std::runtime_error(what) {
}
};
diff --git a/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp
index 193ce8db..ac35babf 100644
--- a/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/src/commands/trex_rpc_cmd_general.cpp
@@ -28,14 +28,11 @@ using namespace std;
* get status
*
*/
-TrexRpcCommand::rpc_cmd_rc_e
+trex_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);
- }
+ check_param_count(params, 0, result);
Json::Value &section = result["result"];
@@ -44,6 +41,7 @@ TrexRpcCmdGetStatus::_run(const Json::Value &params, Json::Value &result) {
section["general"]["build_time"] = get_build_time();
section["general"]["version_user"] = VERSION_USER;
section["general"]["uptime"] = TrexRpcServer::get_server_uptime();
- return (RPC_CMD_OK);
+
+ return (TREX_RPC_CMD_OK);
}
diff --git a/src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp
new file mode 100644
index 00000000..a5b358d0
--- /dev/null
+++ b/src/rpc-server/src/commands/trex_rpc_cmd_stream.cpp
@@ -0,0 +1,47 @@
+/*
+ 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;
+
+/**
+ * add new stream
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetStatus::_run(const Json::Value &params, Json::Value &result) {
+
+ /* validate count */
+ if (params.size() != 1) {
+ generate_err_param_count(result, 0, params.size());
+ return (TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR);
+ }
+
+ Json::Value &stream = result["stream"];
+
+ if (stream == Json::Value::null) {
+ generate_err_param_count
+ }
+ 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
index e2dc8959..e67de286 100644
--- a/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp
+++ b/src/rpc-server/src/commands/trex_rpc_cmd_test.cpp
@@ -29,31 +29,18 @@ using namespace std;
* add command
*
*/
-TrexRpcCommand::rpc_cmd_rc_e
+trex_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);
- }
+
+ check_param_count(params, 2, result);
+ check_field_type(params, "x", FIELD_TYPE_INT, result);
+ check_field_type(params, "y", FIELD_TYPE_INT, result);
result["result"] = x.asInt() + y.asInt();
- return (RPC_CMD_OK);
+ return (TREX_RPC_CMD_OK);
}
/**
@@ -61,56 +48,42 @@ TrexRpcCmdTestAdd::_run(const Json::Value &params, Json::Value &result) {
*
* @author imarom (16-Aug-15)
*/
-TrexRpcCommand::rpc_cmd_rc_e
+trex_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);
- }
+ check_param_count(params, 2, result);
+ check_field_type(params, "x", TrexRpcCommand::FIELD_TYPE_INT, result);
+ check_field_type(params, "y", TrexRpcCommand::FIELD_TYPE_INT, result);
result["result"] = x.asInt() - y.asInt();
- return (RPC_CMD_OK);
+ return (TREX_RPC_CMD_OK);
}
/**
* ping command
*/
-TrexRpcCommand::rpc_cmd_rc_e
+trex_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);
- }
+ check_param_count(params, 0, result);
result["result"] = "ACK";
- return (RPC_CMD_OK);
+ return (TREX_RPC_CMD_OK);
}
/**
* query command
*/
-TrexRpcCommand::rpc_cmd_rc_e
+trex_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);
- }
-
+ check_param_count(params, 0, result);
TrexRpcCommandsTable::get_instance().query(cmds);
@@ -121,6 +94,6 @@ TrexRpcCmdGetReg::_run(const Json::Value &params, Json::Value &result) {
result["result"] = test;
- return (RPC_CMD_OK);
+ return (TREX_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
index e37e1cda..39ccf27a 100644
--- a/src/rpc-server/src/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/src/commands/trex_rpc_cmds.h
@@ -37,7 +37,7 @@ class TrexRpcCmdTestAdd : public TrexRpcCommand {
public:
TrexRpcCmdTestAdd() : TrexRpcCommand("test_add") {}
protected:
- virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
};
/**
@@ -48,7 +48,7 @@ class TrexRpcCmdTestSub : public TrexRpcCommand {
public:
TrexRpcCmdTestSub() : TrexRpcCommand("test_sub") {} ;
protected:
- virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
};
/**
@@ -59,7 +59,7 @@ class TrexRpcCmdPing : public TrexRpcCommand {
public:
TrexRpcCmdPing() : TrexRpcCommand("ping") {};
protected:
- virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
};
/**
@@ -70,7 +70,7 @@ class TrexRpcCmdGetReg : public TrexRpcCommand {
public:
TrexRpcCmdGetReg() : TrexRpcCommand("get_reg_cmds") {};
protected:
- virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
};
/**
@@ -81,7 +81,7 @@ class TrexRpcCmdGetStatus : public TrexRpcCommand {
public:
TrexRpcCmdGetStatus() : TrexRpcCommand("get_status") {};
protected:
- virtual rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
+ virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);
};
diff --git a/src/rpc-server/src/trex_rpc_cmd.cpp b/src/rpc-server/src/trex_rpc_cmd.cpp
new file mode 100644
index 00000000..d1a9ebb0
--- /dev/null
+++ b/src/rpc-server/src/trex_rpc_cmd.cpp
@@ -0,0 +1,144 @@
+/*
+ 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_cmd_api.h>
+
+trex_rpc_cmd_rc_e
+TrexRpcCommand::run(const Json::Value &params, Json::Value &result) {
+ trex_rpc_cmd_rc_e rc;
+
+ /* the internal run can throw a parser error / other error */
+ try {
+ rc = _run(params, result);
+ } catch (TrexRpcCommandException &e) {
+ return e.get_rc();
+ }
+
+ return (rc);
+}
+
+void
+TrexRpcCommand::check_param_count(const Json::Value &params, int expected, Json::Value &result) {
+
+ if (params.size() != expected) {
+ std::stringstream ss;
+ ss << "method expects '" << expected << "' paramteres, '" << params.size() << "' provided";
+ generate_err(result, ss.str());
+ throw TrexRpcCommandException(TREX_RPC_CMD_PARAM_COUNT_ERR);
+ }
+}
+
+const char *
+TrexRpcCommand::type_to_str(field_type_e type) {
+ switch (type) {
+ case FIELD_TYPE_BOOL:
+ return "bool";
+ case FIELD_TYPE_INT:
+ return "int";
+ case FIELD_TYPE_OBJ:
+ return "object";
+ case FIELD_TYPE_STR:
+ return "string";
+ case FILED_TYPE_ARRAY:
+ return "array";
+
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const char *
+TrexRpcCommand::json_type_to_name(const Json::Value &value) {
+
+ switch(value.type()) {
+ case Json::nullValue:
+ return "null";
+ case Json::uintValue:
+ return "uint";
+ case Json::realValue:
+ return "real";
+ case Json::stringValue:
+ return "string";
+ case Json::booleanValue:
+ return "boolean";
+ case Json::arrayValue:
+ return "array";
+ case Json::objectValue:
+ return "object";
+
+ default:
+ return "UNKNOWN";
+ }
+
+}
+void
+TrexRpcCommand::check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result) {
+ std::stringstream ss;
+
+ /* check if field exists , does not add the field because its const */
+ const Json::Value &field = parent[name];
+
+ /* first check if field exists */
+ if (field == Json::Value::null) {
+ ss << "field '" << name << "' missing";
+ generate_err(result, ss.str());
+ throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR));
+ }
+
+ bool rc = true;
+
+ switch (type) {
+ case FIELD_TYPE_BOOL:
+ if (!field.isBool()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_INT:
+ if (!field.isInt()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_OBJ:
+ if (!field.isObject()) {
+ rc = false;
+ }
+ break;
+
+ case FIELD_TYPE_STR:
+ if (!field.isString()) {
+ rc = false;
+ }
+ break;
+ }
+
+ if (!rc) {
+ ss << "error at offset: " << field.getOffsetStart() << " - '" << name << "' is '" << json_type_to_name(field) << "', expecting '" << type_to_str(type) << "'";
+ generate_err(result, ss.str());
+ throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR));
+ }
+
+}
+
+void
+TrexRpcCommand::generate_err(Json::Value &result, const std::string &msg) {
+ result["specific_err"] = msg;
+}
diff --git a/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp b/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp
index be1eb2f8..bf6056d5 100644
--- a/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp
+++ b/src/rpc-server/src/trex_rpc_jsonrpc_v2_parser.cpp
@@ -71,21 +71,21 @@ public:
virtual void _execute(Json::Value &response) {
Json::Value result;
- TrexRpcCommand::rpc_cmd_rc_e rc = m_cmd->run(m_params, result);
+ trex_rpc_cmd_rc_e rc = m_cmd->run(m_params, result);
switch (rc) {
- case TrexRpcCommand::RPC_CMD_OK:
+ case TREX_RPC_CMD_OK:
response["result"] = result["result"];
break;
- case TrexRpcCommand::RPC_CMD_PARAM_COUNT_ERR:
- case TrexRpcCommand::RPC_CMD_PARAM_PARSE_ERR:
+ case TREX_RPC_CMD_PARAM_COUNT_ERR:
+ case TREX_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:
+ case TREX_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"];
diff --git a/src/rpc-server/src/trex_rpc_server_mock.cpp b/src/rpc-server/src/trex_rpc_server_mock.cpp
index fd4f051c..98d1f35d 100644
--- a/src/rpc-server/src/trex_rpc_server_mock.cpp
+++ b/src/rpc-server/src/trex_rpc_server_mock.cpp
@@ -44,7 +44,7 @@ int main(int argc, char *argv[]) {
// gtest ?
if (argc > 1) {
- if ( (string(argv[1]) != "--ut") || (argc != 2) ) {
+ if (string(argv[1]) != "--ut") {
cout << "\n[Usage] " << argv[0] << ": " << " [--ut]\n\n";
exit(-1);
}