]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implement metadata hander for buckets data
authorYehuda Sadeh <yehuda@inktank.com>
Thu, 9 May 2013 03:40:48 +0000 (20:40 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Thu, 9 May 2013 18:07:13 +0000 (11:07 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/common/ceph_json.cc
src/common/ceph_json.h
src/rgw/rgw_admin.cc
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h
src/rgw/rgw_common.h
src/rgw/rgw_json_enc.cc

index e5fc48a74f8b5905762910dbfe7ba334b0bf3c2b..37b4ccdee7a8ed450ba8d37868134acd4d16068b 100644 (file)
@@ -422,6 +422,19 @@ void decode_json_obj(bool& val, JSONObj *obj)
   val = (bool)i;
 }
 
+void decode_json_obj(bufferlist& val, JSONObj *obj)
+{
+  string s = obj->get_data();
+
+  bufferlist bl;
+  bl.append(s.c_str(), s.size());
+  try {
+    val.decode_base64(bl);
+  } catch (buffer::error& err) {
+   throw JSONDecoder::err("failed to decode base64");
+  }
+}
+
 void encode_json(const char *name, const string& val, Formatter *f)
 {
   f->dump_string(name, val);
@@ -480,6 +493,14 @@ void encode_json(const char *name, const utime_t& val, Formatter *f)
 
 void encode_json(const char *name, const bufferlist& bl, Formatter *f)
 {
-  encode_json(name, bl.length(), f);
+  /* need to copy data from bl, as it is const bufferlist */
+  bufferlist src = bl;
+
+  bufferlist b64;
+  src.encode_base64(b64);
+
+  string s(b64.c_str(), b64.length());
+
+  encode_json(name, s, f);
 }
 
index 04ca4c1e4a12bebfdb95cd2dff21ad8304a3ad60..8085a7ca6cceb9cdd821c0b9986cc3d28780691e 100644 (file)
@@ -134,6 +134,7 @@ void decode_json_obj(long& val, JSONObj *obj);
 void decode_json_obj(unsigned& val, JSONObj *obj);
 void decode_json_obj(int& val, JSONObj *obj);
 void decode_json_obj(bool& val, JSONObj *obj);
+void decode_json_obj(bufferlist& val, JSONObj *obj);
 
 template<class T>
 void decode_json_obj(list<T>& l, JSONObj *obj)
@@ -148,6 +149,21 @@ void decode_json_obj(list<T>& l, JSONObj *obj)
   }
 }
 
+template<class K, class V>
+void decode_json_obj(map<K, V>& m, JSONObj *obj)
+{
+  JSONObjIter iter = obj->find_first();
+
+  for (; !iter.end(); ++iter) {
+    K key;
+    V val;
+    JSONObj *o = *iter;
+    JSONDecoder::decode_json("key", key, o);
+    JSONDecoder::decode_json("val", val, o);
+    m[key] = val;
+  }
+}
+
 template<class C>
 void decode_json_obj(C& container, void (*cb)(C&, JSONObj *obj), JSONObj *obj)
 {
@@ -246,6 +262,19 @@ void encode_json(const char *name, const bufferlist& bl, Formatter *f);
 void encode_json(const char *name, long long val, Formatter *f);
 void encode_json(const char *name, long long unsigned val, Formatter *f);
 
+template<class K, class V>
+static void encode_json(const char *name, const std::map<K, V>& m, Formatter *f)
+{
+  f->open_array_section(name);
+  for (typename std::map<K, V>::const_iterator i = m.begin(); i != m.end(); ++i) {
+    f->open_object_section("entry");
+    encode_json("key", i->first, f);
+    encode_json("val", i->second, f);
+    f->close_section();
+  }
+  f->close_section();
+}
+
 template<class T>
 static void encode_json(const char *name, const std::list<T>& l, Formatter *f)
 {
@@ -257,7 +286,7 @@ static void encode_json(const char *name, const std::list<T>& l, Formatter *f)
 }
 
 template<class K, class V>
-void encode_json(const char *name, const map<K, V>& m, Formatter *f)
+void encode_json_map(const char *name, const map<K, V>& m, Formatter *f)
 {
   f->open_array_section(name);
   typename map<K,V>::const_iterator iter;
@@ -267,6 +296,7 @@ void encode_json(const char *name, const map<K, V>& m, Formatter *f)
   f->close_section(); 
 }
 
+
 template<class K, class V>
 void encode_json_map(const char *name, const char *index_name,
                      const char *object_name, const char *value_name,
index 9ea6c2b790cbaf4d55de41e42f813cd17f4643a5..678aed5b3735a6a67b336ff5117c1f587539c8f4 100644 (file)
@@ -831,6 +831,7 @@ int main(int argc, char **argv)
   }
 
   rgw_user_init(store->meta_mgr);
+  rgw_bucket_init(store->meta_mgr);
 
   StoreDestructor store_destructor(store);
 
index 809c653de1404029e2306badeaddf5f027be6eb1..95be53fa7595c1bff8cd3d618306cdea45e252d1 100644 (file)
@@ -23,6 +23,8 @@
 
 using namespace std;
 
+static RGWMetadataHandler *bucket_meta_handler = NULL;
+
 // define as static when RGWBucket implementation compete
 void rgw_get_buckets_obj(string& user_id, string& buckets_obj_id)
 {
@@ -1235,3 +1237,151 @@ void RGWDataChangesLog::ChangesRenewThread::stop()
   cond.Signal();
 }
 
+struct RGWBucketCompleteInfo {
+  RGWBucketInfo info;
+  map<string, bufferlist> attrs;
+
+ void dump(Formatter *f) const {
+    encode_json("bucket_info", info, f);
+    encode_json("attrs", attrs, f);
+  }
+
+  void decode_json(JSONObj *obj) {
+    JSONDecoder::decode_json("bucket_info", info, obj);
+    JSONDecoder::decode_json("attrs", attrs, obj);
+  }
+};
+
+class RGWBucketMetadataObject : public RGWMetadataObject {
+  RGWBucketCompleteInfo info;
+public:
+  RGWBucketMetadataObject(RGWBucketCompleteInfo& i, obj_version& v) : info(i) {
+    objv = v;
+  }
+
+  void dump(Formatter *f) const {
+    info.dump(f);
+  }
+};
+
+class RGWBucketMetadataHandler : public RGWMetadataHandler {
+
+  int init_bucket(RGWRados *store, string& bucket_name, rgw_bucket& bucket) {
+    RGWBucketInfo bucket_info;
+    int r = store->get_bucket_info(NULL, bucket_name, bucket_info);
+    if (r < 0) {
+      cerr << "could not get bucket info for bucket=" << bucket_name << std::endl;
+      return r;
+    }
+    bucket = bucket_info.bucket;
+
+    return 0;
+  }
+
+public:
+  string get_type() { return "bucket"; }
+
+  int get(RGWRados *store, string& entry, RGWMetadataObject **obj) {
+    RGWBucketCompleteInfo bci;
+
+    RGWObjVersionTracker objv_tracker;
+
+
+    int ret = store->get_bucket_info(NULL, entry, bci.info, &bci.attrs);
+    if (ret < 0)
+      return ret;
+
+    RGWBucketMetadataObject *mdo = new RGWBucketMetadataObject(bci, objv_tracker.read_version);
+
+    *obj = mdo;
+
+    return 0;
+  }
+
+  int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker, JSONObj *obj) {
+    RGWBucketCompleteInfo bci;
+
+    decode_json_obj(bci, obj);
+
+    int ret = store->put_bucket_info(entry, bci.info, false, &bci.attrs);
+    if (ret < 0)
+      return ret;
+
+    return 0;
+  }
+
+  struct list_keys_info {
+    RGWRados *store;
+    RGWListRawObjsCtx ctx;
+  };
+
+  int remove(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker) {
+#warning FIXME: use objv_tracker
+    rgw_bucket bucket;
+    int r = init_bucket(store, entry, bucket);
+    if (r < 0) {
+      cerr << "could not init bucket=" << entry << std::endl;
+      return r;
+    }
+
+    return store->delete_bucket(bucket);
+  }
+
+  int put_entry(RGWRados *store, string& key, bufferlist& bl, bool exclusive,
+                RGWObjVersionTracker *objv_tracker, map<string, bufferlist> *pattrs) {
+    return rgw_put_system_obj(store, store->zone.domain_root, key,
+                              bl.c_str(), bl.length(), exclusive,
+                              objv_tracker, pattrs);
+  }
+
+  int list_keys_init(RGWRados *store, void **phandle)
+  {
+    list_keys_info *info = new list_keys_info;
+
+    info->store = store;
+
+    *phandle = (void *)info;
+
+    return 0;
+  }
+
+  int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) {
+    list_keys_info *info = (list_keys_info *)handle;
+
+    string no_filter;
+
+    keys.clear();
+
+    RGWRados *store = info->store;
+
+    list<string> unfiltered_keys;
+
+    int ret = store->list_raw_objects(store->zone.domain_root, no_filter,
+                                      max, info->ctx, unfiltered_keys, truncated);
+    if (ret < 0)
+      return ret;
+
+    // now filter out the system entries
+    list<string>::iterator iter;
+    for (iter = unfiltered_keys.begin(); iter != unfiltered_keys.end(); ++iter) {
+      string& k = *iter;
+
+      if (k[0] != '.') {
+        keys.push_back(k);
+      }
+    }
+
+    return 0;
+  }
+
+  void list_keys_complete(void *handle) {
+    list_keys_info *info = (list_keys_info *)handle;
+    delete info;
+  }
+};
+
+void rgw_bucket_init(RGWMetadataManager *mm)
+{
+  bucket_meta_handler = new RGWBucketMetadataHandler;
+  mm->register_handler(bucket_meta_handler);
+}
index a6ac836ace73af927f99d2059e11d9029ef0d1de..0994baba488a950cc6bac82ea6018fa42d49907b 100644 (file)
@@ -79,6 +79,9 @@ public:
 };
 WRITE_CLASS_ENCODER(RGWUserBuckets)
 
+class RGWMetadataManager;
+
+extern void rgw_bucket_init(RGWMetadataManager *mm);
 /**
  * Get all the buckets owned by a user and fill up an RGWUserBuckets with them.
  * Returns: 0 on success, -ERR# on failure.
index 1a72b35eb28c7bdabe5a6217b416c90932a0b9b9..67b1074d64a61befdf0809e1e28f6281b973c34f 100644 (file)
@@ -537,6 +537,7 @@ struct rgw_bucket {
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
   static void generate_test_instances(list<rgw_bucket*>& o);
 };
 WRITE_CLASS_ENCODER(rgw_bucket)
@@ -581,6 +582,8 @@ struct RGWBucketInfo
   void dump(Formatter *f) const;
   static void generate_test_instances(list<RGWBucketInfo*>& o);
 
+  void decode_json(JSONObj *obj);
+
   RGWBucketInfo() : flags(0) {}
 };
 WRITE_CLASS_ENCODER(RGWBucketInfo)
index 6094861907671157448c70a32b9c3cbd444b3747..2094b5cb3727aa2de8d493e3e3a24addb818ca84 100644 (file)
@@ -391,6 +391,14 @@ void rgw_bucket::dump(Formatter *f) const
   encode_json("bucket_id", bucket_id, f);
 }
 
+void rgw_bucket::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("name", name, obj);
+  JSONDecoder::decode_json("pool", data_pool, obj);
+  JSONDecoder::decode_json("index_pool", index_pool, obj);
+  JSONDecoder::decode_json("marker", marker, obj);
+  JSONDecoder::decode_json("bucket_id", bucket_id, obj);
+}
+
 void RGWBucketInfo::dump(Formatter *f) const
 {
   encode_json("bucket", bucket, f);
@@ -398,6 +406,12 @@ void RGWBucketInfo::dump(Formatter *f) const
   encode_json("flags", flags, f);
 }
 
+void RGWBucketInfo::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("bucket", bucket, obj);
+  JSONDecoder::decode_json("owner", owner, obj);
+  JSONDecoder::decode_json("flags", flags, obj);
+}
+
 void RGWObjEnt::dump(Formatter *f) const
 {
   encode_json("name", name, f);