diff --git a/api/api-doc/failure_detector.json b/api/api-doc/failure_detector.json index c59e7630b4..dd3408c570 100644 --- a/api/api-doc/failure_detector.json +++ b/api/api-doc/failure_detector.json @@ -7,6 +7,30 @@ "application/json" ], "apis":[ + { + "path":"/failure_detector/convict/{host}", + "operations":[ + { + "method":"POST", + "summary":"Forces failure detection of a given host locally, marks the node as DOWN, drops connections", + "type":"string", + "nickname":"convict", + "produces":[ + "application/json" + ], + "parameters":[ + { + "name":"host", + "description":"Host ID of the node to convict", + "required":true, + "allowMultiple":false, + "type":"string", + "paramType":"path" + } + ] + } + ] + }, { "path":"/failure_detector/phi", "operations":[ diff --git a/api/failure_detector.cc b/api/failure_detector.cc index 76a8626341..9076ceac7c 100644 --- a/api/failure_detector.cc +++ b/api/failure_detector.cc @@ -9,9 +9,12 @@ #include "failure_detector.hh" #include "api/api.hh" #include "api/api-doc/failure_detector.json.hh" +#include "api/validate.hh" #include "gms/application_state.hh" #include "gms/gossiper.hh" +extern logging::logger apilog; + namespace api { using namespace seastar::httpd; @@ -64,6 +67,15 @@ void set_failure_detector(http_context& ctx, routes& r, gms::gossiper& g) { return make_ready_future(8); }); + fd::convict.set(r, [&g] (std::unique_ptr req) -> future { + return g.container().invoke_on(0, [req = std::move(req)] (gms::gossiper& g) -> future { + auto host_id = validate_host_id(req->get_path_param("host")); + apilog.info("Convict {}", host_id); + co_await g.convict(host_id); + co_return seastar::json::json_void(); + }); + }); + fd::get_simple_states.set(r, [&g] (std::unique_ptr req) { return g.container().invoke_on(0, [] (gms::gossiper& g) { std::vector nodes_status; @@ -114,6 +126,7 @@ void unset_failure_detector(http_context& ctx, routes& r) { fd::set_phi_convict_threshold.unset(r); fd::get_endpoint_state.unset(r); fd::get_endpoint_phi_values.unset(r); + fd::convict.unset(r); } }