diff --git a/utils/gcp/object_storage.cc b/utils/gcp/object_storage.cc index 2a34921c2a..147ad376bd 100644 --- a/utils/gcp/object_storage.cc +++ b/utils/gcp/object_storage.cc @@ -1156,6 +1156,25 @@ seekable_data_source utils::gcp::storage::client::create_download_source(std::st return seekable_data_source(std::make_unique(_impl, bucket, object_name, as)); } +future storage::client::object_exists(std::string_view bucket, std::string_view object_name, seastar::abort_source* as) const { + gcp_storage.debug("Get object metadata {}:{}", bucket, object_name); + + auto path = fmt::format("/storage/v1/b/{}/o/{}", bucket, seastar::http::internal::url_encode(object_name)); + try { + auto res = co_await _impl->send_with_retry(path, GCP_OBJECT_SCOPE_READ_ONLY, ""s, ""s, httpclient::method_type::GET, {}, as); + if (res.result() != status_type::ok) { + throw failed_operation( + fmt::format("Could not retrieve object metadata {}:{}: {} ({})", bucket, object_name, res.result(), get_gcp_error_message(res.body()))); + } + } catch (const storage_io_error& e) { + if (e.code().value() == ENOENT) { + co_return false; + } + throw; + } + co_return true; +} + future<> utils::gcp::storage::client::close() { return _impl->close(); } diff --git a/utils/gcp/object_storage.hh b/utils/gcp/object_storage.hh index 1f62ea5d23..86b20774b0 100644 --- a/utils/gcp/object_storage.hh +++ b/utils/gcp/object_storage.hh @@ -154,7 +154,10 @@ namespace utils::gcp::storage { * Creates a data_source for reading from a named object. */ seekable_data_source create_download_source(std::string_view bucket, std::string_view object_name, seastar::abort_source* = nullptr) const; - + /** + * Checks if an object exists. + */ + future object_exists(std::string_view bucket, std::string_view object_name, seastar::abort_source* as = nullptr) const; /** * Destroys resources. Must be called before releasing object */