diff --git a/api/api-doc/storage_service.json b/api/api-doc/storage_service.json index 3a5d5b1c1e..d63d45abe1 100644 --- a/api/api-doc/storage_service.json +++ b/api/api-doc/storage_service.json @@ -715,8 +715,8 @@ "path":"/storage_service/repair_async/{keyspace}", "operations":[ { - "method":"GET", - "summary":"Invoke repair asynchronously. You can track repair progress by supplying id", + "method":"POST", + "summary":"Invoke repair asynchronously. You can track repair progress by using the get supplying id", "type":"int", "nickname":"repair_async", "produces":[ @@ -725,7 +725,7 @@ "parameters":[ { "name":"keyspace", - "description":"The keyspace to flush", + "description":"The keyspace to repair", "required":true, "allowMultiple":false, "type":"string", @@ -738,11 +738,35 @@ "allowMultiple":false, "type":"string", "paramType":"query" + } + ] + }, + { + "method":"GET", + "summary":"Track already running repair progress", + "type":"string", + "enum":[ + "RUNNING", + "SUCCESSFUL", + "FAILED" + ], + "nickname":"repair_async_status", + "produces":[ + "application/json" + ], + "parameters":[ + { + "name":"keyspace", + "description":"The keyspace repair is running on", + "required":true, + "allowMultiple":false, + "type":"string", + "paramType":"path" }, { "name":"id", - "description":"Check for the status of the repair", - "required":false, + "description":"The repair ID to check for status", + "required":true, "allowMultiple":false, "type":"int", "paramType":"query" diff --git a/api/storage_service.cc b/api/storage_service.cc index 439687c5ed..4cea70f650 100644 --- a/api/storage_service.cc +++ b/api/storage_service.cc @@ -228,39 +228,14 @@ void set_storage_service(http_context& ctx, routes& r) { }); }); - ss::repair_async.set(r, [&ctx](std::unique_ptr req) { - auto keyspace = req->param["keyspace"]; - // FIXME: the "id" and "options" parameters are mutually exclusive, - // and lead to different operations. It would have made sense to make - // these separate requests (with a different method and/or url). - auto options = req->get_query_param("options"); - auto id = req->get_query_param("id"); - - if (!id.empty()) { - return repair_get_status(ctx.db, boost::lexical_cast(id)) - .then_wrapped([] (future&& fut) { - try { - repair_status s = fut.get0(); - sstring ret; - switch(s) { - case repair_status::RUNNING: ret="RUNNING"; break; - case repair_status::SUCCESSFUL: ret="SUCCESSFUL"; break; - case repair_status::FAILED: ret="FAILED"; break; - } - return make_ready_future(ret); - } catch(std::runtime_error& e) { - throw httpd::bad_param_exception(e.what()); - } - }); - } - + ss::repair_async.set(r, [&ctx](const_req req) { // Currently, we get all the repair options encoded in a single // "options" option, and split it to a map using the "," and ":" // delimiters. TODO: consider if it doesn't make more sense to just // take all the query parameters as this map and pass it to the repair // function. std::unordered_map options_map; - for (auto s : split(options, ",")) { + for (auto s : split(req.get_query_param("options"), ",")) { auto kv = split(s, ":"); if (kv.size() != 2) { throw httpd::bad_param_exception("malformed async repair options"); @@ -272,8 +247,20 @@ void set_storage_service(http_context& ctx, routes& r) { // returns immediately, not waiting for the repair to finish. The user // then has other mechanisms to track the ongoing repair's progress, // or stop it. - int i = repair_start(ctx.db, keyspace, options_map); - return make_ready_future(i); + return repair_start(ctx.db, req.param["keyspace"], options_map); + }); + + ss::repair_async_status.set(r, [&ctx](std::unique_ptr req) { + return repair_get_status(ctx.db, boost::lexical_cast( req->get_query_param("id"))) + .then_wrapped([] (future&& fut) { + ss::ns_repair_async_status::return_type_wrapper res; + try { + res = fut.get0(); + } catch(std::runtime_error& e) { + return make_ready_future(json_exception(httpd::bad_param_exception(e.what()))); + } + return make_ready_future(json::json_return_type(res)); + }); }); ss::force_terminate_all_repair_sessions.set(r, [](std::unique_ptr req) {