]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add a flusher to handle output data, simplify client api
authorYehuda Sadeh <yehuda@inktank.com>
Sat, 22 Sep 2012 00:26:05 +0000 (17:26 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Mon, 8 Oct 2012 18:12:24 +0000 (11:12 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_admin.cc
src/rgw/rgw_formats.h
src/rgw/rgw_html_errors.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h
src/rgw/rgw_rest_usage.cc
src/rgw/rgw_rest_usage.h
src/rgw/rgw_usage.cc
src/rgw/rgw_usage.h

index 339f044bcea7830fc072f1470d9e3bb25bcfdbac..a545b82342feecf1d49f7542667825650f05d275 100644 (file)
@@ -1535,9 +1535,11 @@ next:
     parse_date(start_date, &start_epoch);
     parse_date(end_date, &end_epoch);
 
+    RGWStreamFlusher f(formatter, cout);
+
     int ret = RGWUsage::show(rgwstore, user_id, start_epoch, end_epoch,
                             show_log_entries, show_log_sum, &categories,
-                            formatter);
+                            f);
     if (ret < 0) {
       cerr << "ERROR: failed to show usage" << std::endl;
       return 1;
index c43b24b050df10d2074bf876e8fda831ae0214a2..29767851d5f2785ced5b5dbcc77340ff1bb9ced7 100644 (file)
@@ -50,4 +50,44 @@ private:
   size_t min_stack_level;
 };
 
+class RGWFormatterFlusher {
+protected:
+  Formatter *formatter;
+  bool flushed;
+  bool started;
+  virtual void do_flush() = 0;
+  virtual void do_start(int ret) {}
+  void set_formatter(Formatter *f) {
+    formatter = f;
+  }
+public:
+  RGWFormatterFlusher(Formatter *f) : formatter(f), flushed(false), started(false) {}
+  virtual ~RGWFormatterFlusher() {}
+
+  void flush() {
+    do_flush();
+    flushed = true;
+  }
+
+  virtual void start(int client_ret) {
+    if (!started)
+      do_start(client_ret);
+    started = true;
+  }
+
+  Formatter *get_formatter() { return formatter; }
+  bool did_flush() { return flushed; }
+  bool did_start() { return started; }
+};
+
+class RGWStreamFlusher : public RGWFormatterFlusher {
+  ostream& os;
+protected:
+  virtual void do_flush() {
+    formatter->flush(os);
+  }
+public:
+  RGWStreamFlusher(Formatter *f, ostream& _os) : RGWFormatterFlusher(f), os(_os) {}
+};
+
 #endif
index 4202216ac97d6b4776f97b35e54b7fd112a4a79e..c4335bcaf0a6cfde136c436e3ab957d64376ad6e 100644 (file)
@@ -56,7 +56,7 @@ const static struct rgw_html_errors RGW_HTML_SWIFT_ERRORS[] = {
 
 #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
 
-static const struct rgw_html_errors *search_err(int err_no, const struct rgw_html_errors *errs, int len)
+static inline const struct rgw_html_errors *search_err(int err_no, const struct rgw_html_errors *errs, int len)
 {
   for (int i = 0; i < len; ++i, ++errs) {
     if (err_no == errs->err_no)
index fb2dec0458cd59dcc1746d90b9b1aa7c8ecf55ee..8885f72d31252c6eb74d81011b75f18d6cc3e763 100644 (file)
@@ -240,6 +240,19 @@ int RGWGetObj_ObjStore::get_params()
   return 0;
 }
 
+void RGWRESTFlusher::do_start(int ret)
+{
+  set_req_state_err(s, ret); /* no going back from here */
+  dump_errno(s);
+  dump_start(s);
+  end_header(s);
+  rgw_flush_formatter_and_reset(s, s->formatter);
+}
+
+void RGWRESTFlusher::do_flush()
+{
+  rgw_flush_formatter(s, s->formatter);
+}
 
 int RGWPutObj_ObjStore::verify_params()
 {
@@ -475,6 +488,17 @@ int RGWDeleteMultiObj_ObjStore::get_params()
   return ret;
 }
 
+
+void RGWRESTOp::send_response()
+{
+  if (!flusher.did_start()) {
+    set_req_state_err(s, http_ret);
+    dump_errno(s);
+    end_header(s);
+  }
+  flusher.flush();
+}
+
 static void line_unfold(const char *line, string& sdest)
 {
   char dest[strlen(line) + 1];
index 527db72a616ac81789fa052018d128bde80bef68..a4ffa2fca692c01ceccb9e3df1ccd56a58602325 100644 (file)
@@ -3,6 +3,7 @@
 #define TIME_BUF_SIZE 128
 
 #include "rgw_op.h"
+#include "rgw_formats.h"
 
 extern void rgw_flush_formatter_and_reset(struct req_state *s,
                                         ceph::Formatter *formatter);
@@ -10,6 +11,22 @@ extern void rgw_flush_formatter_and_reset(struct req_state *s,
 extern void rgw_flush_formatter(struct req_state *s,
                                          ceph::Formatter *formatter);
 
+
+class RGWRESTFlusher : public RGWFormatterFlusher {
+  struct req_state *s;
+protected:
+  virtual void do_flush();
+  virtual void do_start(int ret);
+public:
+  RGWRESTFlusher(struct req_state *_s) : RGWFormatterFlusher(_s->formatter), s(_s) {}
+  RGWRESTFlusher() : RGWFormatterFlusher(NULL), s(NULL) {}
+
+  void init(struct req_state *_s) {
+    s = _s;
+    set_formatter(s->formatter);
+  }
+};
+
 class RGWClientIO;
 
 class RGWGetObj_ObjStore : public RGWGetObj
@@ -153,6 +170,19 @@ public:
   int get_params();
 };
 
+class RGWRESTOp : public RGWOp {
+protected:
+  int http_ret;
+  RGWRESTFlusher flusher;
+public:
+  RGWRESTOp() : http_ret(0) {}
+  virtual void init(struct req_state *s, RGWHandler *dialect_handler) {
+    RGWOp::init(s, dialect_handler);
+    flusher.init(s);
+  }
+  virtual void send_response();
+};
+
 class RGWHandler_ObjStore : public RGWHandler {
 protected:
   virtual bool is_obj_update_op() { return false; }
index 4d0614d86a7a68c6164fd150010f191b1175665c..27745ff4a492a56d09c1ed6555297ce98abb47d8 100644 (file)
@@ -1041,7 +1041,7 @@ static bool get_auth_header(struct req_state *s, string& dest, bool qsr)
  * verify that a signed request comes from the keyholder
  * by checking the signature against our locally-computed version
  */
-int RGWHandler_ObjStore_S3::authorize()
+int RGW_Auth_S3::authorize(struct req_state *s)
 {
   bool qsr = false;
   string auth_id;
@@ -1144,6 +1144,15 @@ int RGWHandler_ObjStore_S3::authorize()
   return  0;
 }
 
+int RGWHandler_Auth_S3::init(struct req_state *state, RGWClientIO *cio)
+{
+  int ret = RGWHandler_ObjStore_S3::init_from_header(state);
+  if (ret < 0)
+    return ret;
+
+  return RGWHandler_ObjStore::init(state, cio);
+}
+
 RGWHandler *RGWRESTMgr_S3::get_handler(struct req_state *s)
 {
   int ret = RGWHandler_ObjStore_S3::init_from_header(s);
index 11415cf132951816c7ef04134f3c8f2f9d63820f..42a77a08c9460ac78cca72fa118859341bfdf187 100644 (file)
@@ -163,6 +163,26 @@ public:
   void end_response();
 };
 
+class RGW_Auth_S3 {
+public:
+  static int authorize(struct req_state *s);
+};
+
+class RGWHandler_Auth_S3 : public RGWHandler_ObjStore {
+  friend class RGWRESTMgr_S3;
+public:
+  RGWHandler_Auth_S3() : RGWHandler_ObjStore() {}
+  virtual ~RGWHandler_Auth_S3() {}
+
+  virtual int validate_bucket_name(const string& bucket) { return 0; }
+  virtual int validate_object_name(const string& bucket) { return 0; }
+
+  virtual int init(struct req_state *state, RGWClientIO *cio);
+  virtual int authorize() {
+    return RGW_Auth_S3::authorize(s);
+  }
+};
+
 class RGWHandler_ObjStore_S3 : public RGWHandler_ObjStore {
   friend class RGWRESTMgr_S3;
 public:
@@ -174,7 +194,9 @@ public:
   int validate_bucket_name(const string& bucket);
 
   virtual int init(struct req_state *state, RGWClientIO *cio);
-  int authorize();
+  virtual int authorize() {
+    return RGW_Auth_S3::authorize(s);
+  }
 };
 
 class RGWHandler_ObjStore_Service_S3 : public RGWHandler_ObjStore_S3 {
index 1057c5d6d351872b7d1bdd15ec66f88b722533c0..47f5b58082598dfc29cc52a9db7a30138f03bec1 100644 (file)
@@ -2,7 +2,7 @@
 #include "rgw_usage.h"
 #include "rgw_rest_usage.h"
 
-class RGWOp_Usage : public RGWOp {
+class RGWOp_Usage : public RGWRESTOp {
 
 public:
   RGWOp_Usage() {}
@@ -15,13 +15,7 @@ public:
 
 void RGWOp_Usage::execute() {
   map<std::string, bool> categories;
-  int ret = RGWUsage::show(rgwstore, s->user.user_id, 0, (uint64_t)-1, true, true, &categories, s->formatter);
-  if (ret)
-    set_req_state_err(s, ret);
-  dump_errno(s);
-  dump_start(s);
-
-  rgw_flush_formatter_and_reset(s, s->formatter);
+  http_ret = RGWUsage::show(rgwstore, s->user.user_id, 0, (uint64_t)-1, true, true, &categories, flusher);
 }
 
 RGWOp *RGWHandler_Usage::op_get()
index 779c78157d830d1ca6c364eae4eb9680b23bddc5..ae975f3529db0bf9d5196fe4235ad5bbea6375cc 100644 (file)
@@ -5,7 +5,7 @@
 #include "rgw_rest_s3.h"
 
 
-class RGWHandler_Usage : public RGWHandler_ObjStore_S3 {
+class RGWHandler_Usage : public RGWHandler_Auth_S3 {
 protected:
   RGWOp *op_get();
 //  RGWOp *op_delete();
@@ -27,9 +27,6 @@ public:
   virtual ~RGWRESTMgr_Usage() {}
 
   RGWHandler *get_handler(struct req_state *s) {
-    int ret = RGWHandler_ObjStore_S3::init_from_header(s);
-    if (ret < 0)
-      return NULL;
     return new RGWHandler_Usage;
   }
 };
index 64cfe6bbb8a5a4a0f460a5c2e69f75e6bff3a54c..38565457db1c1503d374f4bf5d8c9f6ba7df84da 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "rgw_rados.h"
 #include "rgw_usage.h"
+#include "rgw_formats.h"
 
 using namespace std;
 
@@ -30,16 +31,19 @@ static void dump_usage_categories_info(Formatter *formatter, const rgw_usage_log
 int RGWUsage::show(RGWRados *store, string& uid, uint64_t start_epoch,
                   uint64_t end_epoch, bool show_log_entries, bool show_log_sum,
                   map<string, bool> *categories,
-                  ceph::Formatter *formatter)
+                  RGWFormatterFlusher& flusher)
 {
   uint32_t max_entries = 1000;
 
   bool is_truncated = true;
 
   RGWUsageIter usage_iter;
+  Formatter *formatter = flusher.get_formatter();
 
   map<rgw_user_bucket, rgw_usage_log_entry> usage;
 
+  flusher.start(0);
+
   formatter->open_object_section("usage");
   if (show_log_entries) {
     formatter->open_array_section("entries");
@@ -84,7 +88,7 @@ int RGWUsage::show(RGWRados *store, string& uid, uint64_t start_epoch,
         formatter->dump_int("epoch", entry.epoch);
         dump_usage_categories_info(formatter, entry, categories);
         formatter->close_section(); // bucket
-        formatter->flush(cout);
+        flusher.flush();
       }
 
       summary_map[ub.user].aggregate(entry, categories);
@@ -117,14 +121,14 @@ int RGWUsage::show(RGWRados *store, string& uid, uint64_t start_epoch,
 
       formatter->close_section(); // user
 
-      formatter->flush(cout);
+      flusher.flush();
     }
 
     formatter->close_section(); // summary
   }
 
   formatter->close_section(); // usage
-  formatter->flush(cout);
+  flusher.flush();
 
   return 0;
 }
index 1cf9ab8b6ba94ad96dae05381a3b643a3eebe907..76ae0f54458418c2d900a11b21fec6e1c849e9c7 100644 (file)
@@ -5,6 +5,7 @@
 #include <map>
 
 #include "common/Formatter.h"
+#include "rgw_formats.h"
 
 class RGWRados;
 
@@ -15,7 +16,7 @@ public:
   static int show(RGWRados *store, std::string& uid, uint64_t start_epoch,
                  uint64_t end_epoch, bool show_log_entries, bool show_log_sum,
                  std::map<std::string, bool> *categories,
-                 ceph::Formatter *formatter);
+                 RGWFormatterFlusher& flusher);
 
   static int trim(RGWRados *store, std::string& uid, uint64_t start_epoch,
                  uint64_t end_epoch);