Skip to content

Commit

Permalink
cloud_storage_clients: Use get_optional to find error code
Browse files Browse the repository at this point in the history
When searching for error codes in an XML tree, ptree::count does not
honor dot paths. The change uses get_optional and adds some tests for
the method.
  • Loading branch information
abhijat committed Nov 9, 2023
1 parent 6849a18 commit 1ec6cfe
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/v/cloud_storage_clients/s3_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -861,12 +861,13 @@ ss::future<> s3_client::do_delete_object(
});
}

static std::variant<client::delete_objects_result, rest_error_response>
std::variant<client::delete_objects_result, rest_error_response>
iobuf_to_delete_objects_result(iobuf&& buf) {
auto root = util::iobuf_to_ptree(std::move(buf), s3_log);
auto result = client::delete_objects_result{};
try {
if (root.count("Error.Code") > 0) {
if (auto error_code = root.get_optional<ss::sstring>("Error.Code");
error_code) {
// This is an error response. S3 can reply with 200 error code and
// error response in the body.
constexpr const char* empty = "";
Expand Down
53 changes: 53 additions & 0 deletions src/v/cloud_storage_clients/tests/s3_client_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -833,3 +833,56 @@ FIXTURE_TEST(test_client_pool_reconnect, client_pool_fixture) {
auto count = std::count(result.begin(), result.end(), true);
BOOST_REQUIRE(count == 20);
}

SEASTAR_THREAD_TEST_CASE(test_parse_delete_object_response_infra_error) {
const ss::sstring xml_response
= "<Error><Code>SlowDown</Code><Message>Please reduce your request "
"rate.</Message><RequestId>R123</RequestId><HostId>H123</HostId></"
"Error>";

iobuf b;
b.append(xml_response.data(), xml_response.size());
const auto result = cloud_storage_clients::iobuf_to_delete_objects_result(
std::move(b));
const auto* error = std::get_if<cloud_storage_clients::rest_error_response>(
&result);
BOOST_REQUIRE_NE(error, nullptr);
BOOST_REQUIRE_EQUAL(error->code_string(), "SlowDown");
}

SEASTAR_THREAD_TEST_CASE(test_parse_delete_object_response_key_error) {
const ss::sstring xml_response
= R"XML(<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Error>
<Key>0</Key>
<Code>TestFailure</Code>
</Error>
</DeleteResult>)XML";

iobuf b;
b.append(xml_response.data(), xml_response.size());
const auto result = cloud_storage_clients::iobuf_to_delete_objects_result(
std::move(b));
const auto* response
= std::get_if<cloud_storage_clients::client::delete_objects_result>(
&result);
BOOST_REQUIRE_NE(response, nullptr);
BOOST_REQUIRE_EQUAL(response->undeleted_keys.size(), 1);
BOOST_REQUIRE_EQUAL(response->undeleted_keys.front().reason, "TestFailure");
}

SEASTAR_THREAD_TEST_CASE(test_parse_delete_object_response_no_error) {
const ss::sstring xml_response
= R"XML(<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
</DeleteResult>)XML";

iobuf b;
b.append(xml_response.data(), xml_response.size());
const auto result = cloud_storage_clients::iobuf_to_delete_objects_result(
std::move(b));
const auto* response
= std::get_if<cloud_storage_clients::client::delete_objects_result>(
&result);
BOOST_REQUIRE_NE(response, nullptr);
BOOST_REQUIRE(response->undeleted_keys.empty());
}

0 comments on commit 1ec6cfe

Please sign in to comment.