Skip to content

Commit

Permalink
rgw: add basic support for Swift's reversed account listings.
Browse files Browse the repository at this point in the history
Fixes: http://tracker.ceph.com/issues/21148
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
  • Loading branch information
rzarzynski committed Aug 28, 2017
1 parent a842dd0 commit 870f548
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 13 deletions.
74 changes: 62 additions & 12 deletions src/rgw/rgw_rest_swift.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ int RGWListBuckets_ObjStore_SWIFT::get_params()
prefix = s->info.args.get("prefix");
marker = s->info.args.get("marker");
end_marker = s->info.args.get("end_marker");
wants_reversed = s->info.args.exists("reverse");

string limit_str = s->info.args.get("limit");
if (!limit_str.empty()) {
Expand Down Expand Up @@ -170,6 +171,17 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_begin(bool has_buckets)
}
}

void RGWListBuckets_ObjStore_SWIFT::handle_listing_chunk(RGWUserBuckets& buckets)
{
if (wants_reversed) {
/* Just store in the reversal buffer. Its content will be handled later,
* in send_response_end(). */
reverse_buffer.emplace(std::begin(reverse_buffer), std::move(buckets));
} else {
return send_response_data(buckets);
}
}

void RGWListBuckets_ObjStore_SWIFT::send_response_data(RGWUserBuckets& buckets)
{
if (! sent_data) {
Expand All @@ -184,23 +196,61 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_data(RGWUserBuckets& buckets)
for (auto iter = m.lower_bound(prefix);
iter != m.end() && boost::algorithm::starts_with(iter->first, prefix);
++iter) {
const RGWBucketEnt& obj = iter->second;
dump_bucket_entry(iter->second);
}
}

s->formatter->open_object_section("container");
s->formatter->dump_string("name", obj.bucket.name);
if (need_stats) {
s->formatter->dump_int("count", obj.count);
s->formatter->dump_int("bytes", obj.size);
}
s->formatter->close_section();
if (! s->cct->_conf->rgw_swift_enforce_content_length) {
rgw_flush_formatter(s, s->formatter);
}
void RGWListBuckets_ObjStore_SWIFT::dump_bucket_entry(const RGWBucketEnt& obj)
{
s->formatter->open_object_section("container");
s->formatter->dump_string("name", obj.bucket.name);

if (need_stats) {
s->formatter->dump_int("count", obj.count);
s->formatter->dump_int("bytes", obj.size);
}

s->formatter->close_section();

if (! s->cct->_conf->rgw_swift_enforce_content_length) {
rgw_flush_formatter(s, s->formatter);
}
}

void RGWListBuckets_ObjStore_SWIFT::send_response_data_reversed(RGWUserBuckets& buckets)
{
if (! sent_data) {
return;
}

/* Take care of the prefix parameter of Swift API. There is no business
* in applying the filter earlier as we really need to go through all
* entries regardless of it (the headers like X-Account-Container-Count
* aren't affected by specifying prefix). */
std::map<std::string, RGWBucketEnt>& m = buckets.get_buckets();

auto iter = m.rbegin();
for (/* initialized above */;
iter != m.rend() && !boost::algorithm::starts_with(iter->first, prefix);
++iter) {
/* NOP */;
}

for (/* iter carried */;
iter != m.rend() && boost::algorithm::starts_with(iter->first, prefix);
++iter) {
dump_bucket_entry(iter->second);
}
}

void RGWListBuckets_ObjStore_SWIFT::send_response_end()
{
if (wants_reversed) {
for (auto& buckets : reverse_buffer) {
send_response_data_reversed(buckets);
}
}

if (sent_data) {
s->formatter->close_section();
}
Expand All @@ -216,7 +266,7 @@ void RGWListBuckets_ObjStore_SWIFT::send_response_end()
user_quota,
static_cast<RGWAccessControlPolicy_SWIFTAcct&>(*s->user_acl));
dump_errno(s);
end_header(s, NULL, NULL, s->formatter->get_len(), true);
end_header(s, nullptr, nullptr, s->formatter->get_len(), true);
}

if (sent_data || s->cct->_conf->rgw_swift_enforce_content_length) {
Expand Down
11 changes: 10 additions & 1 deletion src/rgw/rgw_rest_swift.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,27 @@ class RGWGetObj_ObjStore_SWIFT : public RGWGetObj_ObjStore {

class RGWListBuckets_ObjStore_SWIFT : public RGWListBuckets_ObjStore {
bool need_stats;
bool wants_reversed;
std::string prefix;
std::vector<RGWUserBuckets> reverse_buffer;

uint64_t get_default_max() const override {
return 0;
}

public:
RGWListBuckets_ObjStore_SWIFT() : need_stats(true) {}
RGWListBuckets_ObjStore_SWIFT()
: need_stats(true),
wants_reversed(false) {
}
~RGWListBuckets_ObjStore_SWIFT() override {}

int get_params() override;
void handle_listing_chunk(RGWUserBuckets& buckets) override;
void send_response_begin(bool has_buckets) override;
void send_response_data(RGWUserBuckets& buckets) override;
void send_response_data_reversed(RGWUserBuckets& buckets);
void dump_bucket_entry(const RGWBucketEnt& obj);
void send_response_end() override;

bool should_get_stats() override { return need_stats; }
Expand Down

0 comments on commit 870f548

Please sign in to comment.