2020#include " iceberg/catalog/rest/json_internal.h"
2121
2222#include < string>
23- #include < unordered_map>
2423#include < utility>
2524#include < vector>
2625
2726#include < nlohmann/json.hpp>
2827
2928#include " iceberg/catalog/rest/types.h"
29+ #include " iceberg/catalog/rest/validator.h"
3030#include " iceberg/json_internal.h"
3131#include " iceberg/table_identifier.h"
3232#include " iceberg/util/json_util_internal.h"
@@ -59,9 +59,76 @@ constexpr std::string_view kDestination = "destination";
5959constexpr std::string_view kMetadata = " metadata" ;
6060constexpr std::string_view kConfig = " config" ;
6161constexpr std::string_view kIdentifiers = " identifiers" ;
62+ constexpr std::string_view kOverrides = " overrides" ;
63+ constexpr std::string_view kDefaults = " defaults" ;
64+ constexpr std::string_view kEndpoints = " endpoints" ;
65+ constexpr std::string_view kMessage = " message" ;
66+ constexpr std::string_view kType = " type" ;
67+ constexpr std::string_view kCode = " code" ;
68+ constexpr std::string_view kStack = " stack" ;
69+ constexpr std::string_view kError = " error" ;
6270
6371} // namespace
6472
73+ nlohmann::json ToJson (const CatalogConfig& config) {
74+ nlohmann::json json;
75+ json[kOverrides ] = config.overrides ;
76+ json[kDefaults ] = config.defaults ;
77+ SetContainerField (json, kEndpoints , config.endpoints );
78+ return json;
79+ }
80+
81+ Result<CatalogConfig> CatalogConfigFromJson (const nlohmann::json& json) {
82+ CatalogConfig config;
83+ ICEBERG_ASSIGN_OR_RAISE (
84+ config.overrides ,
85+ GetJsonValueOrDefault<decltype (config.overrides )>(json, kOverrides ));
86+ ICEBERG_ASSIGN_OR_RAISE (
87+ config.defaults , GetJsonValueOrDefault<decltype (config.defaults )>(json, kDefaults ));
88+ ICEBERG_ASSIGN_OR_RAISE (
89+ config.endpoints ,
90+ GetJsonValueOrDefault<std::vector<std::string>>(json, kEndpoints ));
91+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (config));
92+ return config;
93+ }
94+
95+ nlohmann::json ToJson (const ErrorModel& error) {
96+ nlohmann::json json;
97+ json[kMessage ] = error.message ;
98+ json[kType ] = error.type ;
99+ json[kCode ] = error.code ;
100+ SetContainerField (json, kStack , error.stack );
101+ return json;
102+ }
103+
104+ Result<ErrorModel> ErrorModelFromJson (const nlohmann::json& json) {
105+ ErrorModel error;
106+ // NOTE: Iceberg's Java implementation allows missing required fields (message, type,
107+ // code) during deserialization, which deviates from the REST spec. We enforce strict
108+ // validation here.
109+ ICEBERG_ASSIGN_OR_RAISE (error.message , GetJsonValue<std::string>(json, kMessage ));
110+ ICEBERG_ASSIGN_OR_RAISE (error.type , GetJsonValue<std::string>(json, kType ));
111+ ICEBERG_ASSIGN_OR_RAISE (error.code , GetJsonValue<uint32_t >(json, kCode ));
112+ ICEBERG_ASSIGN_OR_RAISE (error.stack ,
113+ GetJsonValueOrDefault<std::vector<std::string>>(json, kStack ));
114+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (error));
115+ return error;
116+ }
117+
118+ nlohmann::json ToJson (const ErrorResponse& response) {
119+ nlohmann::json json;
120+ json[kError ] = ToJson (response.error );
121+ return json;
122+ }
123+
124+ Result<ErrorResponse> ErrorResponseFromJson (const nlohmann::json& json) {
125+ ErrorResponse response;
126+ ICEBERG_ASSIGN_OR_RAISE (auto error_json, GetJsonValue<nlohmann::json>(json, kError ));
127+ ICEBERG_ASSIGN_OR_RAISE (response.error , ErrorModelFromJson (error_json));
128+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (response));
129+ return response;
130+ }
131+
65132nlohmann::json ToJson (const CreateNamespaceRequest& request) {
66133 nlohmann::json json;
67134 json[kNamespace ] = request.namespace_ .levels ;
@@ -77,6 +144,7 @@ Result<CreateNamespaceRequest> CreateNamespaceRequestFromJson(
77144 ICEBERG_ASSIGN_OR_RAISE (
78145 request.properties ,
79146 GetJsonValueOrDefault<decltype (request.properties )>(json, kProperties ));
147+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (request));
80148 return request;
81149}
82150
@@ -94,6 +162,7 @@ Result<UpdateNamespacePropertiesRequest> UpdateNamespacePropertiesRequestFromJso
94162 request.removals , GetJsonValueOrDefault<std::vector<std::string>>(json, kRemovals ));
95163 ICEBERG_ASSIGN_OR_RAISE (
96164 request.updates , GetJsonValueOrDefault<decltype (request.updates )>(json, kUpdates ));
165+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (request));
97166 return request;
98167}
99168
@@ -114,6 +183,7 @@ Result<RegisterTableRequest> RegisterTableRequestFromJson(const nlohmann::json&
114183 GetJsonValue<std::string>(json, kMetadataLocation ));
115184 ICEBERG_ASSIGN_OR_RAISE (request.overwrite ,
116185 GetJsonValueOrDefault<bool >(json, kOverwrite , false ));
186+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (request));
117187 return request;
118188}
119189
@@ -131,6 +201,7 @@ Result<RenameTableRequest> RenameTableRequestFromJson(const nlohmann::json& json
131201 ICEBERG_ASSIGN_OR_RAISE (auto dest_json,
132202 GetJsonValue<nlohmann::json>(json, kDestination ));
133203 ICEBERG_ASSIGN_OR_RAISE (request.destination , TableIdentifierFromJson (dest_json));
204+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (request));
134205 return request;
135206}
136207
@@ -177,6 +248,7 @@ Result<ListNamespacesResponse> ListNamespacesResponseFromJson(
177248 ICEBERG_ASSIGN_OR_RAISE (auto ns, NamespaceFromJson (ns_json));
178249 response.namespaces .push_back (std::move (ns));
179250 }
251+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (response));
180252 return response;
181253}
182254
@@ -232,6 +304,7 @@ Result<UpdateNamespacePropertiesResponse> UpdateNamespacePropertiesResponseFromJ
232304 response.removed , GetJsonValueOrDefault<std::vector<std::string>>(json, kRemoved ));
233305 ICEBERG_ASSIGN_OR_RAISE (
234306 response.missing , GetJsonValueOrDefault<std::vector<std::string>>(json, kMissing ));
307+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (response));
235308 return response;
236309}
237310
@@ -256,6 +329,7 @@ Result<ListTablesResponse> ListTablesResponseFromJson(const nlohmann::json& json
256329 ICEBERG_ASSIGN_OR_RAISE (auto identifier, TableIdentifierFromJson (id_json));
257330 response.identifiers .push_back (std::move (identifier));
258331 }
332+ ICEBERG_RETURN_UNEXPECTED (Validator::Validate (response));
259333 return response;
260334}
261335
@@ -265,6 +339,9 @@ Result<ListTablesResponse> ListTablesResponseFromJson(const nlohmann::json& json
265339 return Model##FromJson (json); \
266340 }
267341
342+ ICEBERG_DEFINE_FROM_JSON (CatalogConfig)
343+ ICEBERG_DEFINE_FROM_JSON (ErrorModel)
344+ ICEBERG_DEFINE_FROM_JSON (ErrorResponse)
268345ICEBERG_DEFINE_FROM_JSON (ListNamespacesResponse)
269346ICEBERG_DEFINE_FROM_JSON (CreateNamespaceRequest)
270347ICEBERG_DEFINE_FROM_JSON (CreateNamespaceResponse)
0 commit comments