locator: token_metadata: add parse_host_id_and_endpoint

To be used for specifying nodes either by their
host_id or ip address and using the token_metadata
to resolve the mapping.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
This commit is contained in:
Benny Halevy
2022-10-25 09:12:05 +03:00
parent 340a5a0c94
commit b74807cb8a
2 changed files with 32 additions and 0 deletions

View File

@@ -1087,6 +1087,12 @@ token_metadata::get_endpoint_for_host_id(host_id host_id) const {
return _impl->get_endpoint_for_host_id(host_id);
}
host_id_or_endpoint token_metadata::parse_host_id_and_endpoint(const sstring& host_id_string) const {
auto res = host_id_or_endpoint(host_id_string);
res.resolve(*this);
return res;
}
const std::unordered_map<inet_address, host_id>&
token_metadata::get_endpoint_to_host_id_map_for_reading() const {
return _impl->get_endpoint_to_host_id_map_for_reading();
@@ -1461,4 +1467,20 @@ host_id_or_endpoint::host_id_or_endpoint(const sstring& s, param_type restrict)
}
}
void host_id_or_endpoint::resolve(const token_metadata& tm) {
if (id) {
auto endpoint_opt = tm.get_endpoint_for_host_id(id);
if (!endpoint_opt) {
throw std::runtime_error(format("Host ID {} not found in the cluster", id));
}
endpoint = *endpoint_opt;
} else {
auto opt_id = tm.get_host_id_if_known(endpoint);
if (!opt_id) {
throw std::runtime_error(format("Host inet address {} not found in the cluster", endpoint));
}
id = *opt_id;
}
}
} // namespace locator

View File

@@ -133,6 +133,8 @@ private:
bool _sort_by_proximity = true;
};
class token_metadata;
struct host_id_or_endpoint {
host_id id;
gms::inet_address endpoint;
@@ -152,6 +154,10 @@ struct host_id_or_endpoint {
bool has_endpoint() const noexcept {
return endpoint != gms::inet_address();
}
// Map the host_id to endpoint based on whichever of them is set,
// using the token_metadata
void resolve(const token_metadata& tm);
};
using dc_rack_fn = seastar::noncopyable_function<endpoint_dc_rack(inet_address)>;
@@ -241,6 +247,10 @@ public:
/** Return the end-point for a unique host ID */
std::optional<inet_address> get_endpoint_for_host_id(locator::host_id host_id) const;
/// Parses the \c host_id_string either as a host uuid or as an ip address and returns the mapping.
/// Throws std::invalid_argument on parse error or std::runtime_error if the host_id wasn't found.
host_id_or_endpoint parse_host_id_and_endpoint(const sstring& host_id_string) const;
/** @return a copy of the endpoint-to-id map for read-only operations */
const std::unordered_map<inet_address, host_id>& get_endpoint_to_host_id_map_for_reading() const;