Skip to content

Commit b1d852e

Browse files
committed
1
1 parent 1630d69 commit b1d852e

File tree

11 files changed

+385
-297
lines changed

11 files changed

+385
-297
lines changed

src/iceberg/catalog/rest/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ set(ICEBERG_REST_SOURCES
1919
catalog.cc
2020
json_internal.cc
2121
config.cc
22-
http_client_internal.cc)
22+
http_client_internal.cc
23+
resource_paths.cc)
2324

2425
set(ICEBERG_REST_STATIC_BUILD_INTERFACE_LIBS)
2526
set(ICEBERG_REST_SHARED_BUILD_INTERFACE_LIBS)

src/iceberg/catalog/rest/catalog.cc

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,28 @@
2525
#include <cpr/cpr.h>
2626

2727
#include "iceberg/catalog/rest/config.h"
28+
#include "iceberg/catalog/rest/endpoint_util.h"
2829
#include "iceberg/catalog/rest/http_client_interal.h"
2930
#include "iceberg/catalog/rest/json_internal.h"
3031
#include "iceberg/catalog/rest/types.h"
31-
#include "iceberg/catalog/rest/util.h"
3232
#include "iceberg/json_internal.h"
3333
#include "iceberg/result.h"
3434
#include "iceberg/table.h"
3535
#include "iceberg/util/macros.h"
3636

3737
namespace iceberg::rest {
3838

39-
Result<RestCatalog> RestCatalog::Make(RestCatalogConfig config) {
39+
Result<std::unique_ptr<RestCatalog>> RestCatalog::Make(const RestCatalogConfig& config) {
4040
// Validate that uri is not empty
41-
if (config.uri.empty()) {
41+
auto it = config.configs().find(std::string(RestCatalogConfig::kUri));
42+
if (it == config.configs().end() || it->second.empty()) {
4243
return InvalidArgument("Rest catalog configuration property 'uri' is required.");
4344
}
4445
ICEBERG_ASSIGN_OR_RAISE(auto tmp_client, HttpClient::Make(config));
45-
const std::string endpoint = config.GetConfigEndpoint();
46+
47+
ResourcePaths paths(config);
48+
ICEBERG_ASSIGN_OR_RAISE(const std::string endpoint, paths.V1Config());
4649
cpr::Parameters params;
47-
if (config.warehouse.has_value()) {
48-
params.Add({"warehouse", config.warehouse.value()});
49-
}
5050
ICEBERG_ASSIGN_OR_RAISE(const auto& response, tmp_client->Get(endpoint, params));
5151
switch (response.status_code) {
5252
case cpr::status::HTTP_OK: {
@@ -55,22 +55,17 @@ Result<RestCatalog> RestCatalog::Make(RestCatalogConfig config) {
5555
// Merge server config into client config, server config overrides > client config
5656
// properties > server config defaults
5757
auto final_props = std::move(server_config.defaults);
58-
for (const auto& kv : config.properties_) {
58+
for (const auto& kv : config.configs()) {
5959
final_props.insert_or_assign(kv.first, kv.second);
6060
}
6161

6262
for (const auto& kv : server_config.overrides) {
6363
final_props.insert_or_assign(kv.first, kv.second);
6464
}
65-
RestCatalogConfig final_config = {
66-
.uri = config.uri,
67-
.name = config.name,
68-
.warehouse = config.warehouse,
69-
.properties_ = std::move(final_props),
70-
};
71-
ICEBERG_ASSIGN_OR_RAISE(auto client, HttpClient::Make(final_config));
72-
return RestCatalog(std::make_shared<RestCatalogConfig>(std::move(final_config)),
73-
std::move(client));
65+
auto final_config = RestCatalogConfig::FromMap(final_props);
66+
ICEBERG_ASSIGN_OR_RAISE(auto client, HttpClient::Make(*final_config));
67+
return std::unique_ptr<RestCatalog>(new RestCatalog(
68+
std::move(final_config), std::move(client), ResourcePaths(*final_config)));
7469
};
7570
default: {
7671
ICEBERG_ASSIGN_OR_RAISE(auto json, FromJsonString(response.text));
@@ -80,17 +75,20 @@ Result<RestCatalog> RestCatalog::Make(RestCatalogConfig config) {
8075
}
8176
}
8277

83-
RestCatalog::RestCatalog(std::shared_ptr<RestCatalogConfig> config,
84-
std::unique_ptr<HttpClient> client)
85-
: config_(std::move(config)), client_(std::move(client)) {}
78+
RestCatalog::RestCatalog(std::unique_ptr<RestCatalogConfig> config,
79+
std::unique_ptr<HttpClient> client, ResourcePaths paths)
80+
: config_(std::move(config)), client_(std::move(client)), paths_(std::move(paths)) {}
8681

8782
std::string_view RestCatalog::name() const {
88-
return config_->name.has_value() ? std::string_view(*config_->name)
89-
: std::string_view("");
83+
auto it = config_->configs().find(std::string(RestCatalogConfig::kName));
84+
if (it == config_->configs().end() || it->second.empty()) {
85+
return {""};
86+
}
87+
return std::string_view(it->second);
9088
}
9189

9290
Result<std::vector<Namespace>> RestCatalog::ListNamespaces(const Namespace& ns) const {
93-
const std::string endpoint = config_->GetNamespacesEndpoint();
91+
ICEBERG_ASSIGN_OR_RAISE(const std::string endpoint, paths_.V1Namespaces());
9492
std::vector<Namespace> result;
9593
std::string next_token;
9694
while (true) {
@@ -182,6 +180,10 @@ Result<bool> RestCatalog::TableExists(const TableIdentifier& identifier) const {
182180
return NotImplemented("Not implemented");
183181
}
184182

183+
Status RestCatalog::RenameTable(const TableIdentifier& from, const TableIdentifier& to) {
184+
return NotImplemented("Not implemented");
185+
}
186+
185187
Result<std::unique_ptr<Table>> RestCatalog::LoadTable(const TableIdentifier& identifier) {
186188
return NotImplemented("Not implemented");
187189
}

src/iceberg/catalog/rest/catalog.h

Lines changed: 11 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@
2222
#include <memory>
2323
#include <string>
2424

25-
#include <cpr/cpr.h>
26-
2725
#include "iceberg/catalog.h"
2826
#include "iceberg/catalog/rest/config.h"
2927
#include "iceberg/catalog/rest/http_client_interal.h"
3028
#include "iceberg/catalog/rest/iceberg_rest_export.h"
31-
#include "iceberg/catalog/rest/types.h"
29+
#include "iceberg/catalog/rest/resource_paths.h"
3230
#include "iceberg/result.h"
3331

3432
/// \file iceberg/catalog/rest/catalog.h
@@ -40,126 +38,73 @@ class ICEBERG_REST_EXPORT RestCatalog : public Catalog {
4038
public:
4139
RestCatalog(const RestCatalog&) = delete;
4240
RestCatalog& operator=(const RestCatalog&) = delete;
43-
RestCatalog(RestCatalog&&) = default;
44-
RestCatalog& operator=(RestCatalog&&) = default;
41+
RestCatalog(RestCatalog&&) = delete;
42+
RestCatalog& operator=(RestCatalog&&) = delete;
4543

4644
/// \brief Create a RestCatalog instance
4745
///
4846
/// \param config the configuration for the RestCatalog
49-
/// \return a RestCatalog instance
50-
static Result<RestCatalog> Make(RestCatalogConfig config);
47+
/// \return a unique_ptr to RestCatalog instance
48+
static Result<std::unique_ptr<RestCatalog>> Make(const RestCatalogConfig& config);
5149

52-
/// \brief Return the name for this catalog
5350
std::string_view name() const override;
5451

55-
/// \brief List child namespaces from the given namespace.
5652
Result<std::vector<Namespace>> ListNamespaces(const Namespace& ns) const override;
5753

58-
/// \brief Create a namespace with associated properties.
5954
Status CreateNamespace(
6055
const Namespace& ns,
6156
const std::unordered_map<std::string, std::string>& properties) override;
6257

63-
/// \brief Get metadata properties for a namespace.
6458
Result<std::unordered_map<std::string, std::string>> GetNamespaceProperties(
6559
const Namespace& ns) const override;
6660

67-
/// \brief Drop a namespace.
6861
Status DropNamespace(const Namespace& ns) override;
6962

70-
/// \brief Check whether the namespace exists.
7163
Result<bool> NamespaceExists(const Namespace& ns) const override;
7264

73-
/// \brief Update a namespace's properties by applying additions and removals.
7465
Status UpdateNamespaceProperties(
7566
const Namespace& ns, const std::unordered_map<std::string, std::string>& updates,
7667
const std::unordered_set<std::string>& removals) override;
7768

78-
/// \brief Return all the identifiers under this namespace
7969
Result<std::vector<TableIdentifier>> ListTables(const Namespace& ns) const override;
8070

81-
/// \brief Create a table
8271
Result<std::unique_ptr<Table>> CreateTable(
8372
const TableIdentifier& identifier, const Schema& schema, const PartitionSpec& spec,
8473
const std::string& location,
8574
const std::unordered_map<std::string, std::string>& properties) override;
8675

87-
/// \brief Update a table
88-
///
89-
/// \param identifier a table identifier
90-
/// \param requirements a list of table requirements
91-
/// \param updates a list of table updates
92-
/// \return a Table instance or ErrorKind::kAlreadyExists if the table already exists
9376
Result<std::unique_ptr<Table>> UpdateTable(
9477
const TableIdentifier& identifier,
9578
const std::vector<std::unique_ptr<TableRequirement>>& requirements,
9679
const std::vector<std::unique_ptr<TableUpdate>>& updates) override;
9780

98-
/// \brief Start a transaction to create a table
99-
///
100-
/// \param identifier a table identifier
101-
/// \param schema a schema
102-
/// \param spec a partition spec
103-
/// \param location a location for the table; leave empty if unspecified
104-
/// \param properties a string map of table properties
105-
/// \return a Transaction to create the table or ErrorKind::kAlreadyExists if the
106-
/// table already exists
10781
Result<std::shared_ptr<Transaction>> StageCreateTable(
10882
const TableIdentifier& identifier, const Schema& schema, const PartitionSpec& spec,
10983
const std::string& location,
11084
const std::unordered_map<std::string, std::string>& properties) override;
11185

112-
/// \brief Check whether table exists
113-
///
114-
/// \param identifier a table identifier
115-
/// \return Result<bool> indicating table exists or not.
116-
/// - On success, the table existence was successfully checked (actual
117-
/// existence may be inferred elsewhere).
118-
/// - On failure, contains error information.
11986
Result<bool> TableExists(const TableIdentifier& identifier) const override;
12087

121-
/// \brief Drop a table; optionally delete data and metadata files
122-
///
123-
/// If purge is set to true the implementation should delete all data and metadata
124-
/// files.
125-
///
126-
/// \param identifier a table identifier
127-
/// \param purge if true, delete all data and metadata files in the table
128-
/// \return Status indicating the outcome of the operation.
129-
/// - On success, the table was dropped (or did not exist).
130-
/// - On failure, contains error information.
88+
Status RenameTable(const TableIdentifier& from, const TableIdentifier& to) override;
89+
13190
Status DropTable(const TableIdentifier& identifier, bool purge) override;
13291

133-
/// \brief Load a table
134-
///
135-
/// \param identifier a table identifier
136-
/// \return instance of Table implementation referred to by identifier or
137-
/// ErrorKind::kNoSuchTable if the table does not exist
13892
Result<std::unique_ptr<Table>> LoadTable(const TableIdentifier& identifier) override;
13993

140-
/// \brief Register a table with the catalog if it does not exist
141-
///
142-
/// \param identifier a table identifier
143-
/// \param metadata_file_location the location of a metadata file
144-
/// \return a Table instance or ErrorKind::kAlreadyExists if the table already exists
14594
Result<std::shared_ptr<Table>> RegisterTable(
14695
const TableIdentifier& identifier,
14796
const std::string& metadata_file_location) override;
14897

149-
/// \brief A builder used to create valid tables or start create/replace transactions
150-
///
151-
/// \param identifier a table identifier
152-
/// \param schema a schema
153-
/// \return the builder to create a table or start a create/replace transaction
15498
std::unique_ptr<RestCatalog::TableBuilder> BuildTable(
15599
const TableIdentifier& identifier, const Schema& schema) const override;
156100

157101
private:
158-
RestCatalog(std::shared_ptr<RestCatalogConfig> config,
159-
std::unique_ptr<HttpClient> client);
102+
RestCatalog(std::unique_ptr<RestCatalogConfig> config,
103+
std::unique_ptr<HttpClient> client, ResourcePaths paths);
160104

161-
std::shared_ptr<RestCatalogConfig> config_;
105+
std::unique_ptr<RestCatalogConfig> config_;
162106
std::unique_ptr<HttpClient> client_;
107+
ResourcePaths paths_;
163108
};
164109

165110
} // namespace iceberg::rest

src/iceberg/catalog/rest/config.cc

Lines changed: 8 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -19,99 +19,19 @@
1919

2020
#include "iceberg/catalog/rest/config.h"
2121

22-
#include <cctype>
23-
#include <ranges>
24-
2522
#include "iceberg/catalog/rest/constant.h"
2623

2724
namespace iceberg::rest {
2825

29-
std::string RestCatalogConfig::GetConfigEndpoint() const {
30-
return std::format("{}/{}/config", TrimTrailingSlash(uri), kPathV1);
31-
}
32-
33-
std::string RestCatalogConfig::GetOAuth2TokensEndpoint() const {
34-
return std::format("{}/{}/oauth/tokens", TrimTrailingSlash(uri), kPathV1);
35-
}
36-
37-
std::string RestCatalogConfig::GetNamespacesEndpoint() const {
38-
return std::format("{}/{}/namespaces", TrimTrailingSlash(uri), kPathV1);
39-
}
40-
41-
std::string RestCatalogConfig::GetNamespaceEndpoint(const Namespace& ns) const {
42-
return std::format("{}/{}/namespaces/{}", TrimTrailingSlash(uri), kPathV1,
43-
EncodeNamespaceForUrl(ns));
44-
}
45-
46-
std::string RestCatalogConfig::GetNamespacePropertiesEndpoint(const Namespace& ns) const {
47-
return std::format("{}/{}/namespaces/{}/properties", TrimTrailingSlash(uri), kPathV1,
48-
EncodeNamespaceForUrl(ns));
49-
}
50-
51-
std::string RestCatalogConfig::GetTablesEndpoint(const Namespace& ns) const {
52-
return std::format("{}/{}/namespaces/{}/tables", TrimTrailingSlash(uri), kPathV1,
53-
EncodeNamespaceForUrl(ns));
54-
}
55-
56-
std::string RestCatalogConfig::GetTableScanPlanEndpoint(
57-
const TableIdentifier& table) const {
58-
return std::format("{}/{}/namespaces/{}/tables/{}/plan", TrimTrailingSlash(uri),
59-
kPathV1, EncodeNamespaceForUrl(table.ns), table.name);
60-
}
61-
62-
std::string RestCatalogConfig::GetTableScanPlanResultEndpoint(
63-
const TableIdentifier& table, const std::string& plan_id) const {
64-
return std::format("{}/{}/namespaces/{}/tables/{}/plan/{}", TrimTrailingSlash(uri),
65-
kPathV1, EncodeNamespaceForUrl(table.ns), table.name, plan_id);
66-
}
67-
68-
std::string RestCatalogConfig::GetTableTasksEndpoint(const TableIdentifier& table) const {
69-
return std::format("{}/{}/namespaces/{}/tables/{}/tasks", TrimTrailingSlash(uri),
70-
kPathV1, EncodeNamespaceForUrl(table.ns), table.name);
71-
}
72-
73-
std::string RestCatalogConfig::GetRegisterTableEndpoint(const Namespace& ns) const {
74-
return std::format("{}/{}/namespaces/{}/register", TrimTrailingSlash(uri), kPathV1,
75-
EncodeNamespaceForUrl(ns));
76-
}
77-
78-
std::string RestCatalogConfig::GetTableEndpoint(const TableIdentifier& table) const {
79-
return std::format("{}/{}/namespaces/{}/tables/{}", TrimTrailingSlash(uri), kPathV1,
80-
EncodeNamespaceForUrl(table.ns), table.name);
81-
}
82-
83-
std::string RestCatalogConfig::GetTableCredentialsEndpoint(
84-
const TableIdentifier& table) const {
85-
return std::format("{}/{}/namespaces/{}/tables/{}/credentials", TrimTrailingSlash(uri),
86-
kPathV1, EncodeNamespaceForUrl(table.ns), table.name);
87-
}
88-
89-
std::string RestCatalogConfig::GetRenameTableEndpoint() const {
90-
return std::format("{}/{}/tables/rename", TrimTrailingSlash(uri), kPathV1);
91-
}
92-
93-
std::string RestCatalogConfig::GetTableMetricsEndpoint(
94-
const TableIdentifier& table) const {
95-
return std::format("{}/{}/namespaces/{}/tables/{}/metrics", TrimTrailingSlash(uri),
96-
kPathV1, EncodeNamespaceForUrl(table.ns), table.name);
97-
}
98-
99-
std::string RestCatalogConfig::GetTransactionCommitEndpoint() const {
100-
return std::format("{}/{}/transactions/commit", TrimTrailingSlash(uri), kPathV1);
101-
}
102-
103-
std::string RestCatalogConfig::GetViewsEndpoint(const Namespace& ns) const {
104-
return std::format("{}/{}/namespaces/{}/views", TrimTrailingSlash(uri), kPathV1,
105-
EncodeNamespaceForUrl(ns));
106-
}
107-
108-
std::string RestCatalogConfig::GetViewEndpoint(const TableIdentifier& view) const {
109-
return std::format("{}/{}/namespaces/{}/views/{}", TrimTrailingSlash(uri), kPathV1,
110-
EncodeNamespaceForUrl(view.ns), view.name);
26+
std::unique_ptr<RestCatalogConfig> RestCatalogConfig::default_properties() {
27+
return std::make_unique<RestCatalogConfig>();
11128
}
11229

113-
std::string RestCatalogConfig::GetRenameViewEndpoint() const {
114-
return std::format("{}/{}/views/rename", TrimTrailingSlash(uri), kPathV1);
30+
std::unique_ptr<RestCatalogConfig> RestCatalogConfig::FromMap(
31+
const std::unordered_map<std::string, std::string>& properties) {
32+
auto rest_catalog_config = std::make_unique<RestCatalogConfig>();
33+
rest_catalog_config->configs_ = properties;
34+
return rest_catalog_config;
11535
}
11636

11737
Result<cpr::Header> RestCatalogConfig::GetExtraHeaders() const {
@@ -122,7 +42,7 @@ Result<cpr::Header> RestCatalogConfig::GetExtraHeaders() const {
12242
headers[std::string(kHeaderXClientVersion)] = std::string(kClientVersion);
12343

12444
constexpr std::string_view prefix = "header.";
125-
for (const auto& [key, value] : properties_) {
45+
for (const auto& [key, value] : configs_) {
12646
if (key.starts_with(prefix)) {
12747
std::string_view header_name = std::string_view(key).substr(prefix.length());
12848

0 commit comments

Comments
 (0)