diff --git a/locator/token_metadata.cc b/locator/token_metadata.cc index 461e33978f..b1533c6a17 100644 --- a/locator/token_metadata.cc +++ b/locator/token_metadata.cc @@ -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& 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 diff --git a/locator/token_metadata.hh b/locator/token_metadata.hh index 433b9a840b..a3cfc43064 100644 --- a/locator/token_metadata.hh +++ b/locator/token_metadata.hh @@ -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; @@ -241,6 +247,10 @@ public: /** Return the end-point for a unique host ID */ std::optional 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& get_endpoint_to_host_id_map_for_reading() const;