2023-04-20 13:26:02 +00:00
|
|
|
#include "RaftServerConfig.h"
|
|
|
|
#include <unordered_set>
|
2023-07-06 15:18:49 +00:00
|
|
|
#include <IO/ReadHelpers.h>
|
2023-04-20 13:26:02 +00:00
|
|
|
#include <base/find_symbols.h>
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
RaftServerConfig::RaftServerConfig(const nuraft::srv_config & cfg) noexcept
|
|
|
|
: id(cfg.get_id()), endpoint(cfg.get_endpoint()), learner(cfg.is_learner()), priority(cfg.get_priority())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
RaftServerConfig::operator nuraft::srv_config() const noexcept
|
|
|
|
{
|
|
|
|
return {id, 0, endpoint, "", learner, priority};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<RaftServerConfig> RaftServerConfig::parse(std::string_view server) noexcept
|
|
|
|
{
|
|
|
|
std::vector<std::string_view> parts;
|
|
|
|
splitInto<';', '='>(parts, server);
|
|
|
|
|
|
|
|
const bool with_id_endpoint = parts.size() == 2;
|
|
|
|
const bool with_server_type = parts.size() == 3;
|
|
|
|
const bool with_priority = parts.size() == 4;
|
|
|
|
if (!with_id_endpoint && !with_server_type && !with_priority)
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
const std::string_view id_str = parts[0];
|
|
|
|
if (!id_str.starts_with("server."))
|
|
|
|
return std::nullopt;
|
|
|
|
|
2023-07-03 10:11:44 +00:00
|
|
|
Int32 id;
|
2023-07-06 15:18:49 +00:00
|
|
|
if (!tryParse(id, std::next(id_str.begin(), 7)))
|
2023-04-20 13:26:02 +00:00
|
|
|
return std::nullopt;
|
|
|
|
if (id <= 0)
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
const std::string_view endpoint = parts[1];
|
|
|
|
const size_t port_delimiter = endpoint.find_last_of(':');
|
|
|
|
if (port_delimiter == std::string::npos)
|
|
|
|
return {};
|
|
|
|
const std::string_view port = endpoint.substr(port_delimiter + 1);
|
|
|
|
|
|
|
|
uint16_t port_tmp;
|
2023-07-06 15:18:49 +00:00
|
|
|
if (!tryParse(port_tmp, port))
|
2023-04-20 13:26:02 +00:00
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
RaftServerConfig out{id, endpoint};
|
|
|
|
|
|
|
|
if (with_id_endpoint)
|
|
|
|
return out;
|
|
|
|
|
|
|
|
if (parts[2] != "learner" && parts[2] != "participant")
|
|
|
|
return std::nullopt;
|
|
|
|
out.learner = parts[2] == "learner";
|
|
|
|
if (with_server_type)
|
|
|
|
return out;
|
|
|
|
|
|
|
|
const std::string_view priority = parts[3];
|
2023-07-06 15:18:49 +00:00
|
|
|
if (!tryParse(out.priority, priority))
|
2023-04-20 13:26:02 +00:00
|
|
|
return std::nullopt;
|
|
|
|
if (out.priority < 0)
|
|
|
|
return std::nullopt;
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
RaftServers parseRaftServers(std::string_view servers)
|
|
|
|
{
|
|
|
|
std::vector<std::string_view> server_arr;
|
2023-07-17 10:50:02 +00:00
|
|
|
std::unordered_set<int32_t> ids;
|
2023-04-20 13:26:02 +00:00
|
|
|
std::unordered_set<String> endpoints;
|
|
|
|
RaftServers out;
|
|
|
|
|
|
|
|
for (auto & server : splitInto<','>(server_arr, servers))
|
2023-07-17 10:50:02 +00:00
|
|
|
{
|
2023-04-20 13:26:02 +00:00
|
|
|
if (auto maybe_server = RaftServerConfig::parse(server))
|
|
|
|
{
|
|
|
|
String endpoint = maybe_server->endpoint;
|
|
|
|
if (endpoints.contains(endpoint))
|
|
|
|
return {};
|
|
|
|
const int id = maybe_server->id;
|
|
|
|
if (ids.contains(id))
|
|
|
|
return {};
|
|
|
|
|
|
|
|
out.emplace_back(std::move(*maybe_server));
|
|
|
|
endpoints.emplace(std::move(endpoint));
|
|
|
|
ids.emplace(id);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return {};
|
2023-07-17 10:50:02 +00:00
|
|
|
}
|
2023-04-20 13:26:02 +00:00
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|