/* * Copyright 2018-present ScyllaDB */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #include "api/api.hh" #include "api/config.hh" #include "api/api-doc/config.json.hh" #include "api/api-doc/storage_proxy.json.hh" #include "api/api-doc/storage_service.json.hh" #include "replica/database.hh" #include "db/config.hh" #include #include #include #include namespace api { using namespace seastar::httpd; namespace sp = httpd::storage_proxy_json; namespace ss = httpd::storage_service_json; std::string_view format_type(std::string_view type) { if (type == "int") { return "integer"; } return type; } future<> get_config_swagger_entry(std::string_view name, const std::string& description, std::string_view type, bool& first, output_stream& os) { std::stringstream ss; if (first) { first=false; } else { ss <<','; }; ss << "\"/v2/config/" << name <<"\": {" "\"get\": {" "\"description\": \"" << boost::replace_all_copy(boost::replace_all_copy(boost::replace_all_copy(description,"\n","\\n"),"\"", "''"), "\t", " ") <<"\"," "\"operationId\": \"find_config_"<< name <<"\"," "\"produces\": [" "\"application/json\"" "]," "\"tags\": [\"config\"]," "\"parameters\": [" "]," "\"responses\": {" "\"200\": {" "\"description\": \"Config value\"," "\"schema\": {" "\"type\": \"" << format_type(type) << "\"" "}" "}," "\"default\": {" "\"description\": \"unexpected error\"," "\"schema\": {" "\"$ref\": \"#/definitions/ErrorModel\"" "}" "}" "}" "}" "}"; return os.write(ss.str()); } namespace cs = httpd::config_json; void set_config(std::shared_ptr < api_registry_builder20 > rb, http_context& ctx, routes& r, db::config& cfg, bool first) { rb->register_function(r, [&cfg, first] (output_stream& os) { return do_with(first, [&os, &cfg] (bool& first) { auto f = make_ready_future(); for (auto&& cfg_ref : cfg.values()) { auto&& cfg = cfg_ref.get(); f = f.then([&os, &first, &cfg] { return get_config_swagger_entry(cfg.name(), std::string(cfg.desc()), cfg.type_name(), first, os); }); } return f; }); }); cs::find_config_id.set(r, [&cfg] (const_req r) { auto id = r.get_path_param("id"); for (auto&& cfg_ref : cfg.values()) { auto&& cfg = cfg_ref.get(); if (id == cfg.name()) { return cfg.value_as_json(); } } throw bad_param_exception(sstring("No such config entry: ") + id); }); sp::get_rpc_timeout.set(r, [&cfg](const_req req) { return cfg.request_timeout_in_ms()/1000.0; }); sp::set_rpc_timeout.set(r, [](std::unique_ptr req) { //TBD unimplemented(); auto enable = req->get_query_param("timeout"); return make_ready_future(seastar::json::json_void()); }); sp::get_read_rpc_timeout.set(r, [&cfg](const_req req) { return cfg.read_request_timeout_in_ms()/1000.0; }); sp::set_read_rpc_timeout.set(r, [](std::unique_ptr req) { //TBD unimplemented(); auto enable = req->get_query_param("timeout"); return make_ready_future(seastar::json::json_void()); }); sp::get_write_rpc_timeout.set(r, [&cfg](const_req req) { return cfg.write_request_timeout_in_ms()/1000.0; }); sp::set_write_rpc_timeout.set(r, [](std::unique_ptr req) { //TBD unimplemented(); auto enable = req->get_query_param("timeout"); return make_ready_future(seastar::json::json_void()); }); sp::get_counter_write_rpc_timeout.set(r, [&cfg](const_req req) { return cfg.counter_write_request_timeout_in_ms()/1000.0; }); sp::set_counter_write_rpc_timeout.set(r, [](std::unique_ptr req) { //TBD unimplemented(); auto enable = req->get_query_param("timeout"); return make_ready_future(seastar::json::json_void()); }); sp::get_cas_contention_timeout.set(r, [&cfg](const_req req) { return cfg.cas_contention_timeout_in_ms()/1000.0; }); sp::set_cas_contention_timeout.set(r, [](std::unique_ptr req) { //TBD unimplemented(); auto enable = req->get_query_param("timeout"); return make_ready_future(seastar::json::json_void()); }); sp::get_range_rpc_timeout.set(r, [&cfg](const_req req) { return cfg.range_request_timeout_in_ms()/1000.0; }); sp::set_range_rpc_timeout.set(r, [](std::unique_ptr req) { //TBD unimplemented(); auto enable = req->get_query_param("timeout"); return make_ready_future(seastar::json::json_void()); }); sp::get_truncate_rpc_timeout.set(r, [&cfg](const_req req) { return cfg.truncate_request_timeout_in_ms()/1000.0; }); sp::set_truncate_rpc_timeout.set(r, [](std::unique_ptr req) { //TBD unimplemented(); auto enable = req->get_query_param("timeout"); return make_ready_future(seastar::json::json_void()); }); ss::get_all_data_file_locations.set(r, [&cfg](const_req req) { return cfg.data_file_directories(); }); ss::get_saved_caches_location.set(r, [&cfg](const_req req) { return cfg.saved_caches_directory(); }); ss::set_compaction_throughput_mb_per_sec.set(r, [&cfg](std::unique_ptr req) mutable { api::req_param value(*req, "value", 0); cfg.compaction_throughput_mb_per_sec(value.value, utils::config_file::config_source::API); return make_ready_future(json::json_void()); }); ss::set_stream_throughput_mb_per_sec.set(r, [&cfg](std::unique_ptr req) mutable { api::req_param value(*req, "value", 0); cfg.stream_io_throughput_mb_per_sec(value.value, utils::config_file::config_source::API); return make_ready_future(json::json_void()); }); } void unset_config(http_context& ctx, routes& r) { cs::find_config_id.unset(r); sp::get_rpc_timeout.unset(r); sp::set_rpc_timeout.unset(r); sp::get_read_rpc_timeout.unset(r); sp::set_read_rpc_timeout.unset(r); sp::get_write_rpc_timeout.unset(r); sp::set_write_rpc_timeout.unset(r); sp::get_counter_write_rpc_timeout.unset(r); sp::set_counter_write_rpc_timeout.unset(r); sp::get_cas_contention_timeout.unset(r); sp::set_cas_contention_timeout.unset(r); sp::get_range_rpc_timeout.unset(r); sp::set_range_rpc_timeout.unset(r); sp::get_truncate_rpc_timeout.unset(r); sp::set_truncate_rpc_timeout.unset(r); ss::get_all_data_file_locations.unset(r); ss::get_saved_caches_location.unset(r); ss::set_compaction_throughput_mb_per_sec.unset(r); ss::set_stream_throughput_mb_per_sec.unset(r); } }