]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
RGW|Bucket notification: fix for v2 topics rgw-admin list operation
authorAli Masarwa <amasarwa@redhat.com>
Sun, 29 Sep 2024 12:00:13 +0000 (15:00 +0300)
committerYuval Lifshitz <ylifshit@ibm.com>
Tue, 19 Nov 2024 16:49:12 +0000 (16:49 +0000)
Signed-off-by: Ali Masarwa <amasarwa@redhat.com>
(cherry picked from commit 575a19d2a81e959d21f64d1a9ed39a5db3b92957)

src/rgw/rgw_admin.cc
src/rgw/rgw_pubsub.cc
src/rgw/rgw_pubsub.h
src/rgw/rgw_rest_pubsub.cc
src/test/rgw/bucket_notification/test_bn.py

index 0ce00d993e962a2c7f0a3cedcec67fa762e8a821..7bdd0544899ac3ea6a8fc03ebc10ab40e3933727 100644 (file)
@@ -11082,22 +11082,22 @@ next:
     }
 
     formatter->open_object_section("result");
-    formatter->open_array_section("topics");
-    do {
-      rgw_pubsub_topics result;
-      int ret = ps.get_topics(dpp(), next_token, max_entries,
-                              result, next_token, null_yield);
-      if (ret < 0 && ret != -ENOENT) {
-        cerr << "ERROR: could not get topics: " << cpp_strerror(-ret) << std::endl;
-        return -ret;
-      }
-      for (const auto& [_, topic] : result.topics) {
-        if (owner && *owner != topic.owner) {
-          continue;
+    rgw_pubsub_topics result;
+    if (rgw::all_zonegroups_support(*site, rgw::zone_features::notification_v2) &&
+        driver->stat_topics_v1(tenant, null_yield, dpp()) == -ENOENT) {
+      formatter->open_array_section("topics");
+      do {
+        int ret = ps.get_topics_v2(dpp(), next_token, max_entries,
+                                   result, next_token, null_yield);
+        if (ret < 0 && ret != -ENOENT) {
+          cerr << "ERROR: could not get topics: " << cpp_strerror(-ret) << std::endl;
+          return -ret;
         }
-        std::set<std::string> subscribed_buckets;
-        if (rgw::all_zonegroups_support(*site, rgw::zone_features::notification_v2) &&
-            driver->stat_topics_v1(tenant, null_yield, dpp()) == -ENOENT) {
+        for (const auto& [_, topic] : result.topics) {
+          if (owner && *owner != topic.owner) {
+            continue;
+          }
+          std::set<std::string> subscribed_buckets;
           ret = driver->get_bucket_topic_mapping(topic, subscribed_buckets,
                                                  null_yield, dpp());
           if (ret < 0) {
@@ -11105,15 +11105,21 @@ next:
                  << topic.name << ", ret=" << ret << std::endl;
           }
           show_topics_info_v2(topic, subscribed_buckets, formatter.get());
-        } else {
-          encode_json("result", result, formatter.get());
-        }
-        if (max_entries_specified) {
-          --max_entries;
+          if (max_entries_specified) {
+            --max_entries;
+          }
         }
+        result.topics.clear();
+      } while (!next_token.empty() && max_entries > 0);
+      formatter->close_section(); // topics
+    } else { // v1, list all topics
+      int ret = ps.get_topics_v1(dpp(), result, null_yield);
+      if (ret < 0 && ret != -ENOENT) {
+        cerr << "ERROR: could not get topics: " << cpp_strerror(-ret) << std::endl;
+        return -ret;
       }
-    } while (!next_token.empty() && max_entries > 0);
-    formatter->close_section(); // topics
+      encode_json("result", result, formatter.get());
+    }
     if (max_entries_specified) {
       encode_json("truncated", !next_token.empty(), formatter.get());
       if (!next_token.empty()) {
index 7eca57e4308666c2942f18fcc162bdd53b43bd23..20ee4f8c17dfd83710948050b47b3dc1558ba2ea 100644 (file)
@@ -570,22 +570,16 @@ RGWPubSub::RGWPubSub(rgw::sal::Driver* _driver,
 {
 }
 
-int RGWPubSub::get_topics(const DoutPrefixProvider* dpp,
-                          const std::string& start_marker, int max_items,
-                          rgw_pubsub_topics& result, std::string& next_marker,
-                          optional_yield y) const
+int RGWPubSub::get_topics_v2(const DoutPrefixProvider* dpp,
+                             const std::string& start_marker, int max_items,
+                             rgw_pubsub_topics& result, std::string& next_marker,
+                             optional_yield y) const
 {
   if (rgw::account::validate_id(tenant)) {
     // if our tenant is an account, return the account listing
     return list_account_topics(dpp, start_marker, max_items,
                                result, next_marker, y);
   }
-
-  if (!use_notification_v2 || driver->stat_topics_v1(tenant, y, dpp) != -ENOENT) {
-    // in case of v1 or during migration we use v1 topics
-    // v1 returns all topics, ignoring marker/max_items
-    return read_topics_v1(dpp, result, nullptr, y);
-  }
  
   // TODO: prefix filter on 'tenant:'
   void* handle = NULL;
@@ -629,6 +623,13 @@ int RGWPubSub::get_topics(const DoutPrefixProvider* dpp,
   return ret;
 }
 
+int RGWPubSub::get_topics_v1(const DoutPrefixProvider* dpp,
+                             rgw_pubsub_topics& result,
+                             optional_yield y) const
+{
+  return read_topics_v1(dpp, result, nullptr, y);
+}
+
 int RGWPubSub::list_account_topics(const DoutPrefixProvider* dpp,
                                    const std::string& start_marker,
                                    int max_items, rgw_pubsub_topics& result,
index b7ce443af037ec618146a8bb1d74c5410fb45733..8a6b290cb85684e91d216eaaad49e88772e29cae 100644 (file)
@@ -643,9 +643,14 @@ public:
 
   // get a paginated list of topics
   // return 0 on success, error code otherwise
-  int get_topics(const DoutPrefixProvider* dpp,
-                 const std::string& start_marker, int max_items,
-                 rgw_pubsub_topics& result, std::string& next_marker,
+  int get_topics_v2(const DoutPrefixProvider* dpp,
+                    const std::string& start_marker, int max_items,
+                    rgw_pubsub_topics& result, std::string& next_marker,
+                    optional_yield y) const;
+
+  // return 0 on success, error code otherwise
+  int get_topics_v1(const DoutPrefixProvider* dpp,
+                 rgw_pubsub_topics& result,
                  optional_yield y) const;
 
   // get a topic with by its name and populate it into "result"
index 7a93c7114e2cad67d226460e65282f9c4287259c..01fdcceb54510d2d070c84150556df79d1ae17b6 100644 (file)
@@ -473,8 +473,13 @@ void RGWPSListTopicsOp::execute(optional_yield y) {
   const std::string start_token = s->info.args.get("NextToken");
 
   const RGWPubSub ps(driver, get_account_or_tenant(s->owner.id), *s->penv.site);
-  constexpr int max_items = 100;
-  op_ret = ps.get_topics(this, start_token, max_items, result, next_token, y);
+  if (rgw::all_zonegroups_support(*s->penv.site, rgw::zone_features::notification_v2) &&
+      driver->stat_topics_v1(s->bucket->get_tenant(), null_yield, this) == -ENOENT) {
+    op_ret = ps.get_topics_v1(this, result, y);
+  } else {
+    constexpr int max_items = 100;
+    op_ret = ps.get_topics_v2(this, start_token, max_items, result, next_token, y);
+  }
   // if there are no topics it is not considered an error
   op_ret = op_ret == -ENOENT ? 0 : op_ret;
   if (op_ret < 0) {
index f03be32d01b4c71823d7dcec5400c1ba6ec67f0d..8f93dd5d2f3a5854cbb8eba5f79fd08c0c3fa71c 100644 (file)
@@ -611,19 +611,16 @@ def test_ps_s3_topic_on_master():
     assert_equal(status, 404)
 
     # get the remaining 2 topics
-    result, status = topic_conf1.get_list()
-    assert_equal(status, 200)
-    assert_equal(len(result['ListTopicsResponse']['ListTopicsResult']['Topics']['member']), 2)
+    list_topics(2, tenant)
 
     # delete topics
-    result = topic_conf2.del_config()
+    status = topic_conf2.del_config()
     assert_equal(status, 200)
-    result = topic_conf3.del_config()
+    status = topic_conf3.del_config()
     assert_equal(status, 200)
 
     # get topic list, make sure it is empty
-    result, status = topic_conf1.get_list()
-    assert_equal(result['ListTopicsResponse']['ListTopicsResult']['Topics'], None)
+    list_topics(0, tenant)
 
 
 @attr('basic_test')