Skip to content

Commit c3a992c

Browse files
committed
fix2
1 parent fa9c60f commit c3a992c

9 files changed

Lines changed: 82 additions & 82 deletions

File tree

src/iceberg/catalog/rest/catalog_properties.cc

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

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

22-
#include "iceberg/catalog/rest/constant.h"
23-
2422
namespace iceberg::rest {
2523

2624
std::unique_ptr<RestCatalogConfig> RestCatalogConfig::default_properties() {
@@ -34,11 +32,8 @@ std::unique_ptr<RestCatalogConfig> RestCatalogConfig::FromMap(
3432
return rest_catalog_config;
3533
}
3634

37-
std::unordered_map<std::string, std::string> RestCatalogConfig::GetExtraHeaders() const {
35+
std::unordered_map<std::string, std::string> RestCatalogConfig::ExtractHeaders() const {
3836
std::unordered_map<std::string, std::string> headers;
39-
headers[kHeaderContentType] = kMimeTypeApplicationJson;
40-
headers[kHeaderUserAgent] = kUserAgent;
41-
4237
constexpr std::string_view prefix = "header.";
4338
for (const auto& [key, value] : configs_) {
4439
if (key.starts_with(prefix)) {

src/iceberg/catalog/rest/catalog_properties.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ class ICEBERG_REST_EXPORT RestCatalogConfig : public ConfigBase<RestCatalogConfi
4141
using Entry = const ConfigBase<RestCatalogConfig>::Entry<T>;
4242

4343
/// \brief The URI of the REST catalog server.
44-
inline static std::string_view kUri{"uri"};
44+
inline static Entry<std::string> kUri{"uri", ""};
4545

4646
/// \brief The name of the catalog.
47-
inline static std::string_view kName{"name"};
47+
inline static Entry<std::string> kName{"name", ""};
4848

4949
/// \brief The warehouse path.
50-
inline static std::string_view kWarehouse{"warehouse"};
50+
inline static Entry<std::string> kWarehouse{"warehouse", ""};
5151

5252
/// \brief Create a default RestCatalogConfig instance.
5353
static std::unique_ptr<RestCatalogConfig> default_properties();
@@ -56,13 +56,11 @@ class ICEBERG_REST_EXPORT RestCatalogConfig : public ConfigBase<RestCatalogConfi
5656
static std::unique_ptr<RestCatalogConfig> FromMap(
5757
const std::unordered_map<std::string, std::string>& properties);
5858

59-
/// \brief Generates extra HTTP headers to be added to every request from the
60-
/// configuration.
59+
/// \brief Returns HTTP headers to be added to every request.
6160
///
62-
/// This includes default headers like Content-Type, User-Agent, X-Client-Version and
63-
/// any custom headers prefixed with "header." in the properties.
64-
/// \return A map of header names to values.
65-
std::unordered_map<std::string, std::string> GetExtraHeaders() const;
61+
/// This includes any key prefixed with "header." in the properties.
62+
/// \return A map of headers with the prefix removed from the keys.
63+
std::unordered_map<std::string, std::string> ExtractHeaders() const;
6664
};
6765

6866
} // namespace iceberg::rest

src/iceberg/catalog/rest/http_client.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "cpr/body.h"
2525
#include "cpr/cprtypes.h"
2626
#include "iceberg/catalog/rest/catalog_properties.h"
27+
#include "iceberg/catalog/rest/constant.h"
2728
#include "iceberg/catalog/rest/json_internal.h"
2829
#include "iceberg/json_internal.h"
2930
#include "iceberg/util/macros.h"
@@ -88,8 +89,11 @@ void HttpClient::PrepareSession(
8889
}
8990

9091
HttpClient::HttpClient(const RestCatalogConfig& config)
91-
: default_headers_{config.GetExtraHeaders()},
92-
session_{std::make_unique<cpr::Session>()} {}
92+
: default_headers_{config.ExtractHeaders()},
93+
session_{std::make_unique<cpr::Session>()} {
94+
default_headers_[kHeaderContentType] = kMimeTypeApplicationJson;
95+
default_headers_[kHeaderUserAgent] = kUserAgent;
96+
}
9397

9498
Result<HttpResponse> HttpClient::Get(
9599
const std::string& path, const std::unordered_map<std::string, std::string>& params,

src/iceberg/catalog/rest/resource_paths.cc

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace iceberg::rest {
3030
Result<std::unique_ptr<ResourcePaths>> ResourcePaths::Make(
3131
const RestCatalogConfig& config) {
3232
// Validate and extract URI
33-
auto it = config.configs().find(std::string(RestCatalogConfig::kUri));
33+
auto it = config.configs().find(RestCatalogConfig::kUri.key());
3434
if (it == config.configs().end() || it->second.empty()) {
3535
return InvalidArgument("Rest catalog configuration property 'uri' is required.");
3636
}
@@ -117,15 +117,4 @@ std::string ResourcePaths::CommitTransaction() const {
117117
return BuildPath("transactions/commit");
118118
}
119119

120-
std::string ResourcePaths::Views(const Namespace& ns) const {
121-
return BuildPath(std::format("namespaces/{}/views", EncodeNamespaceForUrl(ns)));
122-
}
123-
124-
std::string ResourcePaths::View(const TableIdentifier& ident) const {
125-
return BuildPath(
126-
std::format("namespaces/{}/views/{}", EncodeNamespaceForUrl(ident.ns), ident.name));
127-
}
128-
129-
std::string ResourcePaths::RenameView() const { return BuildPath("views/rename"); }
130-
131120
} // namespace iceberg::rest

src/iceberg/catalog/rest/resource_paths.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,6 @@ class ICEBERG_REST_EXPORT ResourcePaths {
9292
/// \brief Get the /v1/{prefix}/transactions/commit endpoint path.
9393
std::string CommitTransaction() const;
9494

95-
/// \brief Get the /v1/{prefix}/namespaces/{namespace}/views endpoint path.
96-
std::string Views(const Namespace& ns) const;
97-
98-
/// \brief Get the /v1/{prefix}/namespaces/{namespace}/views/{view} endpoint path.
99-
std::string View(const TableIdentifier& ident) const;
100-
101-
/// \brief Get the /v1/{prefix}/views/rename endpoint path.
102-
std::string RenameView() const;
103-
10495
private:
10596
explicit ResourcePaths(std::string base_uri, std::string prefix);
10697

src/iceberg/catalog/rest/rest_catalog.cc

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,44 +41,46 @@
4141

4242
namespace iceberg::rest {
4343

44-
Result<std::unique_ptr<RestCatalog>> RestCatalog::Make(const RestCatalogConfig& config) {
45-
// Create ResourcePaths and validate URI
46-
ICEBERG_ASSIGN_OR_RAISE(auto paths, ResourcePaths::Make(config));
47-
44+
Result<std::unique_ptr<RestCatalogConfig>> RestCatalog::FetchAndMergeConfig(
45+
const RestCatalogConfig& config, const ResourcePaths& paths) {
46+
// Fetch server configuration
4847
auto tmp_client = std::make_unique<HttpClient>(config);
49-
const std::string endpoint = paths->Config();
50-
ICEBERG_ASSIGN_OR_RAISE(const HttpResponse& response,
48+
const std::string endpoint = paths.Config();
49+
ICEBERG_ASSIGN_OR_RAISE(const auto response,
5150
tmp_client->Get(endpoint, {}, {}, DefaultErrorHandler()));
5251
ICEBERG_ASSIGN_OR_RAISE(auto json, FromJsonString(response.body()));
5352
ICEBERG_ASSIGN_OR_RAISE(auto server_config, CatalogConfigFromJson(json));
53+
5454
// Merge server config into client config, server config overrides > client config
5555
// properties > server config defaults
56-
auto final_props = std::move(server_config.defaults);
57-
for (const auto& kv : config.configs()) {
58-
final_props.insert_or_assign(kv.first, kv.second);
59-
}
56+
auto final_props =
57+
MergeConfigs(server_config.defaults, config.configs(), server_config.overrides);
58+
return RestCatalogConfig::FromMap(final_props);
59+
}
60+
61+
Result<std::unique_ptr<RestCatalog>> RestCatalog::Make(const RestCatalogConfig& config) {
62+
ICEBERG_ASSIGN_OR_RAISE(auto paths, ResourcePaths::Make(config));
63+
// Fetch and merge server configuration
64+
ICEBERG_ASSIGN_OR_RAISE(auto final_config, FetchAndMergeConfig(config, *paths));
6065

61-
for (const auto& kv : server_config.overrides) {
62-
final_props.insert_or_assign(kv.first, kv.second);
63-
}
64-
auto final_config = RestCatalogConfig::FromMap(final_props);
6566
auto client = std::make_unique<HttpClient>(*final_config);
6667
ICEBERG_ASSIGN_OR_RAISE(auto final_paths, ResourcePaths::Make(*final_config));
67-
return std::unique_ptr<RestCatalog>(new RestCatalog(
68-
std::move(final_config), std::move(client), std::move(*final_paths)));
68+
69+
std::string catalog_name = final_config->Get(RestCatalogConfig::kName);
70+
return std::unique_ptr<RestCatalog>(
71+
new RestCatalog(std::move(final_config), std::move(client), std::move(*final_paths),
72+
std::move(catalog_name)));
6973
}
7074

7175
RestCatalog::RestCatalog(std::unique_ptr<RestCatalogConfig> config,
72-
std::unique_ptr<HttpClient> client, ResourcePaths paths)
73-
: config_(std::move(config)), client_(std::move(client)), paths_(std::move(paths)) {}
74-
75-
std::string_view RestCatalog::name() const {
76-
auto it = config_->configs().find(std::string(RestCatalogConfig::kName));
77-
if (it == config_->configs().end() || it->second.empty()) {
78-
return {""};
79-
}
80-
return std::string_view(it->second);
81-
}
76+
std::unique_ptr<HttpClient> client, ResourcePaths paths,
77+
std::string name)
78+
: config_(std::move(config)),
79+
client_(std::move(client)),
80+
paths_(std::move(paths)),
81+
name_(std::move(name)) {}
82+
83+
std::string_view RestCatalog::name() const { return name_; }
8284

8385
Result<std::vector<Namespace>> RestCatalog::ListNamespaces(const Namespace& ns) const {
8486
const std::string endpoint = paths_.Namespaces();

src/iceberg/catalog/rest/rest_catalog.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,20 @@ class ICEBERG_REST_EXPORT RestCatalog : public Catalog {
100100

101101
private:
102102
RestCatalog(std::unique_ptr<RestCatalogConfig> config,
103-
std::unique_ptr<HttpClient> client, ResourcePaths paths);
103+
std::unique_ptr<HttpClient> client, ResourcePaths paths, std::string name);
104+
105+
/// \brief Fetch server configuration and merge with client config
106+
///
107+
/// \param config the initial client configuration
108+
/// \param paths the resource paths for REST endpoints
109+
/// \return the final merged configuration
110+
static Result<std::unique_ptr<RestCatalogConfig>> FetchAndMergeConfig(
111+
const RestCatalogConfig& config, const ResourcePaths& paths);
104112

105113
std::unique_ptr<RestCatalogConfig> config_;
106114
std::unique_ptr<HttpClient> client_;
107115
ResourcePaths paths_;
116+
std::string name_; // Cached catalog name
108117
};
109118

110119
} // namespace iceberg::rest

src/iceberg/catalog/rest/rest_util.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <format>
2424
#include <string>
2525
#include <string_view>
26+
#include <unordered_map>
2627

2728
#include "iceberg/table_identifier.h"
2829

@@ -78,4 +79,25 @@ inline std::string EncodeNamespaceForUrl(const Namespace& ns) {
7879
return EncodeUriComponent(joined_string);
7980
}
8081

82+
/// \brief Merge catalog configuration properties.
83+
/// \details Merges three sets of configuration properties following the precedence order:
84+
/// server overrides > client configs > server defaults.
85+
/// \param server_defaults Default properties provided by the server.
86+
/// \param client_configs Configuration properties from the client.
87+
/// \param server_overrides Override properties enforced by the server.
88+
/// \return A merged map containing all properties with correct precedence.
89+
inline std::unordered_map<std::string, std::string> MergeConfigs(
90+
const std::unordered_map<std::string, std::string>& server_defaults,
91+
const std::unordered_map<std::string, std::string>& client_configs,
92+
const std::unordered_map<std::string, std::string>& server_overrides) {
93+
auto merged = server_defaults;
94+
for (const auto& kv : client_configs) {
95+
merged.insert_or_assign(kv.first, kv.second);
96+
}
97+
for (const auto& kv : server_overrides) {
98+
merged.insert_or_assign(kv.first, kv.second);
99+
}
100+
return merged;
101+
}
102+
81103
} // namespace iceberg::rest

src/iceberg/test/rest_catalog_test.cc

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,17 @@ class RestCatalogTest : public ::testing::Test {
4444
std::string uri = uri_env ? uri_env : "http://localhost:8181";
4545
std::string warehouse = warehouse_env ? warehouse_env : "default";
4646

47-
config_
48-
.Set(RestCatalogConfig::Entry<std::string>{std::string(RestCatalogConfig::kUri),
49-
""},
50-
uri)
51-
.Set(RestCatalogConfig::Entry<std::string>{std::string(RestCatalogConfig::kName),
52-
""},
53-
std::string("test_catalog"))
54-
.Set(
55-
RestCatalogConfig::Entry<std::string>{
56-
std::string(RestCatalogConfig::kWarehouse), ""},
57-
warehouse);
47+
config_.Set(RestCatalogConfig::kUri, uri)
48+
.Set(RestCatalogConfig::kName, std::string("test_catalog"))
49+
.Set(RestCatalogConfig::kWarehouse, warehouse);
5850
}
5951

6052
void TearDown() override {}
6153

6254
RestCatalogConfig config_;
6355
};
6456

65-
TEST_F(RestCatalogTest, DISABLED_MakeCatalogSuccess) {
57+
TEST_F(RestCatalogTest, MakeCatalogSuccess) {
6658
auto catalog_result = RestCatalog::Make(config_);
6759
EXPECT_THAT(catalog_result, IsOk());
6860

@@ -74,16 +66,14 @@ TEST_F(RestCatalogTest, DISABLED_MakeCatalogSuccess) {
7466

7567
TEST_F(RestCatalogTest, DISABLED_MakeCatalogEmptyUri) {
7668
RestCatalogConfig invalid_config = config_;
77-
invalid_config.Set(
78-
RestCatalogConfig::Entry<std::string>{std::string(RestCatalogConfig::kUri), ""},
79-
std::string(""));
69+
invalid_config.Set(RestCatalogConfig::kUri, std::string(""));
8070

8171
auto catalog_result = RestCatalog::Make(invalid_config);
8272
EXPECT_THAT(catalog_result, IsError(ErrorKind::kInvalidArgument));
8373
EXPECT_THAT(catalog_result, HasErrorMessage("uri"));
8474
}
8575

86-
TEST_F(RestCatalogTest, DISABLED_MakeCatalogWithCustomProperties) {
76+
TEST_F(RestCatalogTest, MakeCatalogWithCustomProperties) {
8777
RestCatalogConfig custom_config = config_;
8878
custom_config
8979
.Set(RestCatalogConfig::Entry<std::string>{"custom_prop", ""},
@@ -94,7 +84,7 @@ TEST_F(RestCatalogTest, DISABLED_MakeCatalogWithCustomProperties) {
9484
EXPECT_THAT(catalog_result, IsOk());
9585
}
9686

97-
TEST_F(RestCatalogTest, DISABLED_ListNamespaces) {
87+
TEST_F(RestCatalogTest, ListNamespaces) {
9888
auto catalog_result = RestCatalog::Make(config_);
9989
ASSERT_THAT(catalog_result, IsOk());
10090
auto& catalog = catalog_result.value();

0 commit comments

Comments
 (0)