From 4343dd13e7cee44f9e5e0f1d1272541587d85ba4 Mon Sep 17 00:00:00 2001 From: Artur Mukhamadiev Date: Thu, 19 Mar 2026 20:57:52 +0300 Subject: [PATCH] [rpc] new methods in api :Release Notes: added new implicit rpc method: "get-available-methods" get_count get_method_name_by_id get_method_names :Detailed Notes: - :Testing Performed: weak coverage :QA Notes: - :Issues Addressed: TG-4 #done --- include/cloud_point_rpc/rpc_server.hpp | 10 ++++++ include/server_api.h | 2 ++ src/rpc_server.cpp | 25 ++++++++++++++ src/server_api.cpp | 48 +++++++++++++++----------- tests/test_rpc.cpp | 13 +++++++ 5 files changed, 77 insertions(+), 21 deletions(-) diff --git a/include/cloud_point_rpc/rpc_server.hpp b/include/cloud_point_rpc/rpc_server.hpp index 698d9cb..a8f85c6 100644 --- a/include/cloud_point_rpc/rpc_server.hpp +++ b/include/cloud_point_rpc/rpc_server.hpp @@ -23,12 +23,22 @@ class CRPC_EXPORT RpcServer { using Handler = std::function; using callback_t = rpc_string *(*)(rpc_string *); + public: + /// @note +1 method implicitly added: get-available-methods + RpcServer(); + void register_method(const std::string &name, Handler handler); void register_method(const std::string &name, callback_t handler); + + uint64_t get_count() noexcept; + std::span get_method_names() noexcept; + std::string_view get_method_name_by_id(uint64_t id) noexcept; + ///@param request_str json rpc 2.0 formatted string [[nodiscard]] std::string process(const std::string &request_str); private: + std::vector handler_names_; std::map handlers_; }; diff --git a/include/server_api.h b/include/server_api.h index 2dde8e1..5846c1b 100644 --- a/include/server_api.h +++ b/include/server_api.h @@ -29,6 +29,8 @@ typedef rpc_string*(*callback_t)(rpc_string*); CRPC_EXPORT void crpc_init(const char* config_path); CRPC_EXPORT void crpc_deinit(); +CRPC_EXPORT rpc_string* crpc_get_method_name_by_id(uint64_t id); +CRPC_EXPORT uint64_t crpc_get_methods_count(); CRPC_EXPORT void crpc_add_method(callback_t cb, rpc_string* name); #ifdef __cplusplus diff --git a/src/rpc_server.cpp b/src/rpc_server.cpp index 98a1dee..7561ed8 100644 --- a/src/rpc_server.cpp +++ b/src/rpc_server.cpp @@ -1,4 +1,5 @@ #include "cloud_point_rpc/rpc_server.hpp" +#include #include using json = nlohmann::json; @@ -17,8 +18,15 @@ json create_success(const json &result, const json &id) { } } // namespace +RpcServer::RpcServer() { + register_method("get-available-methods", [&](const json&) { + return get_method_names(); + }); +} + void RpcServer::register_method(const std::string &name, Handler handler) { handlers_[name] = std::move(handler); + handler_names_.push_back(handlers_.find(name)->first); } void RpcServer::register_method(const std::string &name, callback_t handler) { @@ -28,6 +36,23 @@ void RpcServer::register_method(const std::string &name, callback_t handler) { rpc_string *res = handler(&tmp); return {res->s}; }; + handler_names_.push_back(handlers_.find(name)->first); +} + +std::span RpcServer::get_method_names() noexcept { + return this->handler_names_; +} + +uint64_t RpcServer::get_count() noexcept { + return this->handler_names_.size(); +} + +std::string_view RpcServer::get_method_name_by_id(uint64_t id) noexcept { + if(id >= handler_names_.size()) { + LOG(ERROR) << __func__ << std::format(": called with id = {} which is bigger, than size={}", id, handler_names_.size()); + return {}; + } + return handler_names_.at(id); } std::string RpcServer::process(const std::string &request_str) { diff --git a/src/server_api.cpp b/src/server_api.cpp index 84a7d56..556c407 100644 --- a/src/server_api.cpp +++ b/src/server_api.cpp @@ -1,53 +1,50 @@ +#include "server_api.h" #include "cloud_point_rpc/config.hpp" #include "cloud_point_rpc/rpc_server.hpp" #include "cloud_point_rpc/tcp_server.hpp" -#include -#include "server_api.h" #include +#include +#include #include #include -#include -static std::list> gc; +static std::list> gc; score::RpcServer rpc_server; std::unique_ptr server = nullptr; extern "C" { -const char* crpc_str_get_data(const rpc_string* that) { +const char *crpc_str_get_data(const rpc_string *that) { return that->s.c_str(); } -uint64_t crpc_str_get_size(const rpc_string* that){ - return that->s.size(); -} +uint64_t crpc_str_get_size(const rpc_string *that) { return that->s.size(); } -rpc_string* crpc_str_create(const char* data, uint64_t size){ +rpc_string *crpc_str_create(const char *data, uint64_t size) { gc.push_back(std::make_unique(data, size)); return gc.back().get(); } -void crpc_str_destroy(rpc_string* that){ +void crpc_str_destroy(rpc_string *that) { auto it = std::ranges::find(gc, that, &std::unique_ptr::get); - if(it != gc.end()) + if (it != gc.end()) gc.erase(it); } - -void crpc_init(const char* config_path) { +void crpc_init(const char *config_path) { google::InitGoogleLogging("CloudPointRPC"); - if(config_path == nullptr) { + if (config_path == nullptr) { LOG(INFO) << "config_path was not provided"; } try { auto config = score::ConfigLoader::load(config_path); LOG(INFO) << "Loaded config from " << config_path; - server = std::make_unique(config.server.ip, config.server.port, - [&](const std::string &request) { - return rpc_server.process( - request); - }); + server = std::make_unique( + config.server.ip, config.server.port, + [&](const std::string &request) { + return rpc_server.process(request); + }); server->start(); } catch (const std::exception &e) { LOG(ERROR) << "Fatal error: " << e.what(); @@ -55,14 +52,23 @@ void crpc_init(const char* config_path) { } void crpc_deinit() { - if(server) + if (server) server->join(); server.reset(); gc.clear(); } -void crpc_add_method(callback_t cb, rpc_string* name) { +void crpc_add_method(callback_t cb, rpc_string *name) { rpc_server.register_method(name->s, cb); } + +rpc_string *crpc_get_method_name_by_id(uint64_t id) { + auto value = rpc_server.get_method_name_by_id(id); + + return crpc_str_create(value.data(), value.size()); } +uint64_t crpc_get_methods_count() { + return rpc_server.get_count(); +} +} diff --git a/tests/test_rpc.cpp b/tests/test_rpc.cpp index 3d2798e..80a0ba2 100644 --- a/tests/test_rpc.cpp +++ b/tests/test_rpc.cpp @@ -61,3 +61,16 @@ TEST_F(RpcServerTest, InvalidJsonReturnsParseError) { ASSERT_TRUE(response.contains("error")); EXPECT_EQ(response["error"]["code"], -32700); } + +TEST_F(RpcServerTest, GetMethod) { + EXPECT_EQ(server.get_count(), 2); + EXPECT_EQ(server.get_method_name_by_id(1), "get-intrinsic-params"); + EXPECT_EQ(server.get_method_names()[1], "get-intrinsic-params"); + + server.register_method("get-test-2", [&](const json&){ + return "test"; + }); + EXPECT_EQ(server.get_count(), 3); + EXPECT_EQ(server.get_method_name_by_id(2), "get-test-2"); + EXPECT_EQ(server.get_method_names()[2], "get-test-2"); +}