diff --git a/api/api-doc/storage_service.json b/api/api-doc/storage_service.json index e45d6de89c..190b31f549 100644 --- a/api/api-doc/storage_service.json +++ b/api/api-doc/storage_service.json @@ -24,6 +24,109 @@ ] } ] + }, + { + "path":"/storage_service/tokens", + "operations":[ + { + "method":"GET", + "summary":"Returns a list of the tokens for this node", + "type":"array", + "items":{ + "type":"string" + }, + "nickname":"get_tokens", + "produces":[ + "application/json" + ], + "parameters":[ + { + } + ] + } + ] + }, + { + "path":"/storage_service/tokens/{endpoint}", + "operations":[ + { + "method":"GET", + "summary":"Returns a list of the tokens for or a specified node", + "type":"array", + "items":{ + "type":"string" + }, + "nickname":"get_node_tokens", + "produces":[ + "application/json" + ], + "parameters":[ + { + "name":"endpoint", + "description":"The endpoint", + "required":true, + "allowMultiple":false, + "type":"string", + "paramType":"path" + } + ] + } + ] + }, + { + "path":"/storage_service/commitlog", + "operations":[ + { + "method":"GET", + "summary":"Returns the location of the commit log files", + "type":"string", + "nickname":"get_commitlog", + "produces":[ + "application/json" + ], + "parameters":[ + { + } + ] + } + ] + }, + { + "path":"/storage_service/tokens_endpoint", + "operations":[ + { + "method":"GET", + "summary":"Returns a list of the tokens endpoint mapping", + "type":"array", + "items":{ + "type":"mapper" + }, + "nickname":"get_token_endpoint", + "produces":[ + "application/json" + ], + "parameters":[ + { + } + ] + } + ] } - ] -} \ No newline at end of file + ], + "models" : { + "mapper": { + "id": "mapper", + "description": "A key value mapping", + "properties": { + "key": { + "type": "string", + "description": "The key" + }, + "value": { + "type": "string", + "description": "The value" + } + } + } + } +} diff --git a/api/api.hh b/api/api.hh index 4922951946..9c56bd0e24 100644 --- a/api/api.hh +++ b/api/api.hh @@ -7,7 +7,7 @@ #include "http/httpd.hh" #include "database.hh" - +#include namespace api { struct http_context { @@ -18,6 +18,15 @@ struct http_context { future<> set_server(http_context& ctx); +template +std::vector container_to_vec(const T& container) { + std::vector res; + for (auto i : container) { + res.push_back(boost::lexical_cast(i)); + } + return res; +} + } #endif /* API_API_HH_ */ diff --git a/api/storage_service.cc b/api/storage_service.cc index 325f222ee2..aa2544fcb2 100644 --- a/api/storage_service.cc +++ b/api/storage_service.cc @@ -4,6 +4,8 @@ #include "storage_service.hh" #include "api/api-doc/storage_service.json.hh" +#include +#include namespace api { @@ -11,6 +13,35 @@ void set_storage_service(http_context& ctx, routes& r) { httpd::storage_service_json::local_hostid.set(r, [](const_req req) { return ""; }); + + httpd::storage_service_json::get_tokens.set(r, [](std::unique_ptr req) { + return service::sorted_tokens().then([](const std::vector& tokens) { + return make_ready_future(container_to_vec(tokens)); + }); + }); + + httpd::storage_service_json::get_node_tokens.set(r, [](std::unique_ptr req) { + gms::inet_address addr(req->param["endpoint"]); + return service::get_tokens(addr).then([](const std::vector& tokens) { + return make_ready_future(container_to_vec(tokens)); + }); + }); + + httpd::storage_service_json::get_commitlog.set(r, [&ctx](const_req req) { + return ctx.db.local().commitlog()->active_config().commit_log_location; + }); + + httpd::storage_service_json::get_token_endpoint.set(r, [](std::unique_ptr req) { + return service::get_token_to_endpoint().then([] (const std::map& tokens){ + std::vector res(tokens.size()); + for (auto i : tokens) { + res.push_back(storage_service_json::mapper()); + res.back().key = boost::lexical_cast(i.first); + res.back().value = boost::lexical_cast(i.second); + } + return make_ready_future(res); + }); + }); } } diff --git a/locator/token_metadata.cc b/locator/token_metadata.cc index 1fb61c939a..923910a876 100644 --- a/locator/token_metadata.cc +++ b/locator/token_metadata.cc @@ -27,6 +27,15 @@ const std::vector& token_metadata::sorted_tokens() const { return _sorted_tokens; } +std::vector token_metadata::get_tokens(const inet_address& addr) const { + std::vector res; + for (auto&& i : _token_to_endpoint_map) { + if (i.second == addr) { + res.push_back(i.first); + } + } + return res; +} /** * Update token map with a single token/endpoint pair in normal state. */ diff --git a/locator/token_metadata.hh b/locator/token_metadata.hh index 49f766b403..e86539305d 100644 --- a/locator/token_metadata.hh +++ b/locator/token_metadata.hh @@ -49,6 +49,10 @@ public: const token& first_token(const token& start); size_t first_token_index(const token& start); std::experimental::optional get_endpoint(const token& token) const; + std::vector get_tokens(const inet_address& addr) const; + const std::map& get_token_to_endpoint() const { + return _token_to_endpoint_map; + } }; } diff --git a/service/storage_service.hh b/service/storage_service.hh index 23d3addf53..5513a0324c 100644 --- a/service/storage_service.hh +++ b/service/storage_service.hh @@ -51,6 +51,9 @@ class storage_service : public gms::i_endpoint_state_change_subscriber public: static int RING_DELAY; // delay after which we assume ring has stablized + const locator::token_metadata& get_token_metadata() const { + return tokenMetadata; + } private: static int getRingDelay() { @@ -4216,4 +4219,22 @@ inline distributed& get_storage_service() { inline storage_service& get_local_storage_service() { return _the_storage_service.local(); } + +inline future> sorted_tokens() { + return smp::submit_to(0, [] { + return get_local_storage_service().get_token_metadata().sorted_tokens(); + }); +} +inline future> get_tokens(const gms::inet_address& addr) { + return smp::submit_to(0, [addr] { + return get_local_storage_service().get_token_metadata().get_tokens(addr); + }); +} + +inline future> get_token_to_endpoint() { + return smp::submit_to(0, [] { + return get_local_storage_service().get_token_metadata().get_token_to_endpoint(); + }); +} + }