diff options
-rw-r--r-- | src/gtest/rpc_test.cpp | 13 | ||||
-rw-r--r-- | src/rpc-server/include/trex_rpc_exception_api.h | 39 | ||||
-rw-r--r-- | src/rpc-server/include/trex_rpc_jsonrpc_v2.h | 67 | ||||
-rw-r--r-- | src/rpc-server/include/trex_rpc_req_resp.h | 2 | ||||
-rw-r--r-- | src/rpc-server/include/trex_rpc_server_api.h | 11 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp | 102 | ||||
-rw-r--r-- | src/rpc-server/src/trex_rpc_req_resp.cpp | 27 |
7 files changed, 226 insertions, 35 deletions
diff --git a/src/gtest/rpc_test.cpp b/src/gtest/rpc_test.cpp index 7f78efd0..59b4b189 100644 --- a/src/gtest/rpc_test.cpp +++ b/src/gtest/rpc_test.cpp @@ -47,19 +47,19 @@ TEST_F(RpcTest, basic_rpc_test) { zmq_connect (requester, "tcp://localhost:5050"); - char buffer[50]; + char buffer[250]; Json::Value request; int id = 1; request["jsonrpc"] = "2.0"; - request["method"] = "test_func"; + //request["method"] = "test_func"; Json::Value ¶ms = request["params"]; params["num"] = 12; params["msg"] = "hello, method test_func"; - for (int request_nbr = 0; request_nbr != 10; request_nbr++) { - request["id"] = id++; + for (int request_nbr = 0; request_nbr != 1; request_nbr++) { + //request["id"] = "itay_id"; std::stringstream ss; ss << request; @@ -68,8 +68,9 @@ TEST_F(RpcTest, basic_rpc_test) { zmq_send (requester, ss.str().c_str(), ss.str().size(), 0); - zmq_recv (requester, buffer, 50, 0); - printf ("Received ACK\n"); + int len = zmq_recv (requester, buffer, 250, 0); + std::string resp(buffer, buffer + len); + std::cout << "Got: " << resp << "\n"; } zmq_close (requester); zmq_ctx_destroy (context); diff --git a/src/rpc-server/include/trex_rpc_exception_api.h b/src/rpc-server/include/trex_rpc_exception_api.h new file mode 100644 index 00000000..8783c219 --- /dev/null +++ b/src/rpc-server/include/trex_rpc_exception_api.h @@ -0,0 +1,39 @@ +/* + 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_EXCEPTION_API_H__ +#define __TREX_RPC_EXCEPTION_API_H__ + +#include <string> +#include <stdexcept> + +/** + * generic exception for RPC errors + * + */ +class TrexRpcException : public std::runtime_error +{ +public: + TrexRpcException(const std::string &what) : std::runtime_error(what) { + } +}; + +#endif /* __TREX_RPC_EXCEPTION_API_H__ */ diff --git a/src/rpc-server/include/trex_rpc_jsonrpc_v2.h b/src/rpc-server/include/trex_rpc_jsonrpc_v2.h new file mode 100644 index 00000000..5a88f756 --- /dev/null +++ b/src/rpc-server/include/trex_rpc_jsonrpc_v2.h @@ -0,0 +1,67 @@ +/* + 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_JSONRPC_V2_H__ +#define __TREX_RPC_JSONRPC_V2_H__ + +#include <string> + +/** + * JSON RPC V2 command + * + * @author imarom (12-Aug-15) + */ +class TrexJsonRpcV2Command { +public: + virtual void execute(std::string &response) = 0; +}; + +/** + * JSON RPC V2 parser + * + * @author imarom (12-Aug-15) + */ +class TrexJsonRpcV2Parser { + +public: + + /** + * creates a JSON-RPC object from a string + * + * @author imarom (12-Aug-15) + * + * @param msg + */ + TrexJsonRpcV2Parser(const std::string &msg); + + /** + * parses the string to a executable command + * + * @author imarom (12-Aug-15) + */ + TrexJsonRpcV2Command * parse(); + +private: + std::string m_msg; +}; + +#endif /* __TREX_RPC_JSONRPC_V2_H__ */ + diff --git a/src/rpc-server/include/trex_rpc_req_resp.h b/src/rpc-server/include/trex_rpc_req_resp.h index 46d01579..511afc02 100644 --- a/src/rpc-server/include/trex_rpc_req_resp.h +++ b/src/rpc-server/include/trex_rpc_req_resp.h @@ -39,7 +39,7 @@ protected: void _stop_rpc_thread(); private: - void handle_request(const uint8_t *msg, uint32_t size); + void handle_request(const std::string &request); static const int RPC_MAX_MSG_SIZE = 2048; void *m_context; diff --git a/src/rpc-server/include/trex_rpc_server_api.h b/src/rpc-server/include/trex_rpc_server_api.h index 98e5f977..f9860e14 100644 --- a/src/rpc-server/include/trex_rpc_server_api.h +++ b/src/rpc-server/include/trex_rpc_server_api.h @@ -28,16 +28,7 @@ limitations under the License. #include <string> #include <stdexcept> -/** - * generic exception for RPC errors - * - */ -class TrexRpcException : public std::runtime_error -{ -public: - TrexRpcException(const std::string &what) : std::runtime_error(what) { - } -}; +#include <trex_rpc_exception_api.h> /* forward decl. of class */ class TrexRpcServerInterface; diff --git a/src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp b/src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp new file mode 100644 index 00000000..d4895557 --- /dev/null +++ b/src/rpc-server/src/trex_rpc_jsonrpc_v2.cpp @@ -0,0 +1,102 @@ +/* + 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.h> + +#include <json/json.h> + +#include <iostream> + +/* dummy command */ +class DumymCommand : public TrexJsonRpcV2Command { +public: + virtual void execute(std::string &response) { + std::cout << "dummy here\n"; + } +}; + +/** + * describes the parser error + * + */ +class JsonRpcError : public TrexJsonRpcV2Command { +public: + + JsonRpcError(const Json::Value &msg_id, int code, const std::string &msg) : m_msg_id(msg_id), m_code(code), m_msg(msg) { + + } + + virtual void execute(std::string &response) { + Json::Value response_json; + Json::FastWriter writer; + + response_json["jsonrpc"] = "2.0"; + response_json["id"] = m_msg_id; + + response_json["error"]["code"] = m_code; + response_json["error"]["message"] = m_msg; + + /* encode to string */ + response = writer.write(response_json); + + } + +private: + Json::Value m_msg_id; + int m_code; + std::string m_msg; +}; + + +TrexJsonRpcV2Parser::TrexJsonRpcV2Parser(const std::string &msg) : m_msg(msg) { + +} + +TrexJsonRpcV2Command * TrexJsonRpcV2Parser::parse() { + Json::Reader reader; + Json::Value request; + + /* basic JSON parsing */ + bool rc = reader.parse(m_msg, request, false); + if (!rc) { + return new JsonRpcError(Json::Value::null, -32700, "Bad JSON Format"); + } + + Json::Value msg_id = request["id"]; + + /* check version */ + if (request["jsonrpc"] != "2.0") { + return new JsonRpcError(msg_id, -32600, "Invalid JSONRPC Version"); + } + + /* check method name */ + std::string method_name = request["method"].asString(); + if (method_name == "") { + return new JsonRpcError(msg_id, -32600, "Missing Method Name"); + } + + std::cout << "method name: " << method_name << "\n"; + + TrexJsonRpcV2Command *command = new DumymCommand(); + + return (command); +} + diff --git a/src/rpc-server/src/trex_rpc_req_resp.cpp b/src/rpc-server/src/trex_rpc_req_resp.cpp index a64129aa..5c28d90d 100644 --- a/src/rpc-server/src/trex_rpc_req_resp.cpp +++ b/src/rpc-server/src/trex_rpc_req_resp.cpp @@ -21,6 +21,7 @@ limitations under the License. #include <trex_rpc_server_api.h> #include <trex_rpc_req_resp.h> +#include <trex_rpc_jsonrpc_v2.h> #include <unistd.h> #include <sstream> @@ -71,7 +72,8 @@ void TrexRpcServerReqRes::_rpc_thread_cb() { } } - handle_request(m_msg_buffer, msg_size); + std::string request((const char *)m_msg_buffer, msg_size); + handle_request(request); } /* must be done from the same thread */ @@ -84,29 +86,18 @@ void TrexRpcServerReqRes::_stop_rpc_thread() { } -void TrexRpcServerReqRes::handle_request(const uint8_t *msg, uint32_t msg_size) { - Json::Reader reader; - Json::Value request; +void TrexRpcServerReqRes::handle_request(const std::string &request) { std::string response; - /* parse the json request */ - bool rc = reader.parse( (const char *)msg, (const char *)msg + msg_size, request, false); - if (!rc) { - throw TrexRpcException("Unable to decode JSON RPC request: " + std::string( (const char *)msg, msg_size)); - } + /* debug */ std::cout << request << std::endl; - #if 0 - TrexJsonRpcRequest rpc_request(msg, msg_size); - - rpc_request->parse(); - rpc_request->execute(); + TrexJsonRpcV2Parser rpc_request(request); - rpc_request->get_response(response); + TrexJsonRpcV2Command *rpc_command = rpc_request.parse(); - zmq_send(m_socket, response, response.size(), 0); - #endif + rpc_command->execute(response); - zmq_send(m_socket, "ACK", 3 ,0); + zmq_send(m_socket, response.c_str(), response.size(), 0); } |