Merge "Extend storage_service API support"

From Amnon:

"This seriese adds functionality to the storage_service API. It focus on tokens
information, that are partially supported in the storage_service and the call
to the API will return an empty list."
This commit is contained in:
Avi Kivity
2015-05-31 17:57:30 +03:00
6 changed files with 180 additions and 3 deletions

View File

@@ -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":[
{
}
]
}
]
}
]
}
],
"models" : {
"mapper": {
"id": "mapper",
"description": "A key value mapping",
"properties": {
"key": {
"type": "string",
"description": "The key"
},
"value": {
"type": "string",
"description": "The value"
}
}
}
}
}

View File

@@ -7,7 +7,7 @@
#include "http/httpd.hh"
#include "database.hh"
#include <boost/lexical_cast.hpp>
namespace api {
struct http_context {
@@ -18,6 +18,15 @@ struct http_context {
future<> set_server(http_context& ctx);
template<class T>
std::vector<sstring> container_to_vec(const T& container) {
std::vector<sstring> res;
for (auto i : container) {
res.push_back(boost::lexical_cast<sstring>(i));
}
return res;
}
}
#endif /* API_API_HH_ */

View File

@@ -4,6 +4,8 @@
#include "storage_service.hh"
#include "api/api-doc/storage_service.json.hh"
#include <service/storage_service.hh>
#include <db/commitlog/commitlog.hh>
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<request> req) {
return service::sorted_tokens().then([](const std::vector<dht::token>& tokens) {
return make_ready_future<json::json_return_type>(container_to_vec(tokens));
});
});
httpd::storage_service_json::get_node_tokens.set(r, [](std::unique_ptr<request> req) {
gms::inet_address addr(req->param["endpoint"]);
return service::get_tokens(addr).then([](const std::vector<dht::token>& tokens) {
return make_ready_future<json::json_return_type>(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<request> req) {
return service::get_token_to_endpoint().then([] (const std::map<dht::token, gms::inet_address>& tokens){
std::vector<storage_service_json::mapper> res(tokens.size());
for (auto i : tokens) {
res.push_back(storage_service_json::mapper());
res.back().key = boost::lexical_cast<sstring>(i.first);
res.back().value = boost::lexical_cast<sstring>(i.second);
}
return make_ready_future<json::json_return_type>(res);
});
});
}
}

View File

@@ -27,6 +27,15 @@ const std::vector<token>& token_metadata::sorted_tokens() const {
return _sorted_tokens;
}
std::vector<token> token_metadata::get_tokens(const inet_address& addr) const {
std::vector<token> 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.
*/

View File

@@ -49,6 +49,10 @@ public:
const token& first_token(const token& start);
size_t first_token_index(const token& start);
std::experimental::optional<inet_address> get_endpoint(const token& token) const;
std::vector<token> get_tokens(const inet_address& addr) const;
const std::map<token, inet_address>& get_token_to_endpoint() const {
return _token_to_endpoint_map;
}
};
}

View File

@@ -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<storage_service>& get_storage_service() {
inline storage_service& get_local_storage_service() {
return _the_storage_service.local();
}
inline future<std::vector<dht::token>> sorted_tokens() {
return smp::submit_to(0, [] {
return get_local_storage_service().get_token_metadata().sorted_tokens();
});
}
inline future<std::vector<dht::token>> 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<std::map<dht::token, gms::inet_address>> get_token_to_endpoint() {
return smp::submit_to(0, [] {
return get_local_storage_service().get_token_metadata().get_token_to_endpoint();
});
}
}