diff --git a/golang/pkg/client/client.go b/golang/pkg/client/client.go index a930a3ef6..4f13311a9 100644 --- a/golang/pkg/client/client.go +++ b/golang/pkg/client/client.go @@ -50,6 +50,7 @@ func (c *client) GetServerVersion() string { err := c.getMetrics(URL, &appMetrics) if err != nil { log.Println(err) + return "unknown" } c.serverVersion = appMetrics.App.Version if c.serverVersion[0:3] != wantServerVersion { @@ -66,7 +67,7 @@ func New(config ClientConfig) (Client, error) { func (c *client) getMetrics(url string, payload interface{}) error { spaceClient := http.Client{ - Timeout: time.Second * 30, + Timeout: time.Second * 5, } req, err := http.NewRequest(http.MethodGet, url, nil) diff --git a/src/CoreServer.cpp b/src/CoreServer.cpp index 1ec775483..88343406b 100644 --- a/src/CoreServer.cpp +++ b/src/CoreServer.cpp @@ -265,6 +265,28 @@ void CoreServer::_setup_routes(const PrometheusConfig &prom_config) res.set_content(j.dump(), "text/json"); } }); + _svr.Delete(fmt::format("/api/v1/policies/({})", AbstractModule::MODULE_ID_REGEX).c_str(), [&](const httplib::Request &req, httplib::Response &res) { + json j; + auto name = req.matches[1]; + if (!_registry.policy_manager()->module_exists(name)) { + res.status = 404; + j["error"] = "policy does not exists"; + res.set_content(j.dump(), "text/json"); + return; + } + try { + auto [policy, lock] = _registry.policy_manager()->module_get_locked(name); + policy->stop(); + lock.unlock(); + // TODO chance of race here + _registry.policy_manager()->module_remove(name); + res.set_content(j.dump(), "text/json"); + } catch (const std::exception &e) { + res.status = 500; + j["error"] = e.what(); + res.set_content(j.dump(), "text/json"); + } + }); _svr.Get(fmt::format("/api/v1/policies/({})/metrics/bucket/(\\d+)", AbstractModule::MODULE_ID_REGEX).c_str(), [&](const httplib::Request &req, httplib::Response &res) { json j; auto name = req.matches[1]; diff --git a/src/tests/test_policies.cpp b/src/tests/test_policies.cpp index 79b0a93c4..67980944a 100644 --- a/src/tests/test_policies.cpp +++ b/src/tests/test_policies.cpp @@ -272,4 +272,30 @@ TEST_CASE("Policies", "[policies]") REQUIRE(!registry.policy_manager()->module_exists("default_view")); REQUIRE(!registry.input_manager()->module_exists("anycast-default_view")); } + SECTION("Good Config, test stop()") + { + CoreRegistry registry(nullptr); + YAML::Node config_file = YAML::Load(policies_config); + + CHECK(config_file["visor"]["policies"]); + CHECK(config_file["visor"]["policies"].IsMap()); + + REQUIRE_NOTHROW(registry.tap_manager()->load(config_file["visor"]["taps"], true)); + REQUIRE_NOTHROW(registry.policy_manager()->load(config_file["visor"]["policies"])); + + REQUIRE(registry.policy_manager()->module_exists("default_view")); + auto [policy, lock] = registry.policy_manager()->module_get_locked("default_view"); + CHECK(policy->name() == "default_view"); + CHECK(policy->input_stream()->running()); + CHECK(policy->modules()[0]->running()); + CHECK(policy->modules()[1]->running()); + CHECK(policy->modules()[2]->running()); + policy->stop(); + CHECK(!policy->input_stream()->running()); + CHECK(!policy->modules()[0]->running()); + CHECK(!policy->modules()[1]->running()); + CHECK(!policy->modules()[2]->running()); + lock.unlock(); + REQUIRE_NOTHROW(registry.policy_manager()->module_remove("default_view")); + } }