summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-05-08 20:40:48 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-05-09 11:07:13 -0700
commit770d94d3065bb42308be95beb2b3911164f3ace7 (patch)
tree0f9864988dbdd4236e342ea87ce308f72afe8451
parent46c3e48ef3b411e8aa2c182c950478957c501a70 (diff)
downloadceph-770d94d3065bb42308be95beb2b3911164f3ace7.tar.gz
rgw: implement metadata hander for buckets data
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/common/ceph_json.cc23
-rw-r--r--src/common/ceph_json.h32
-rw-r--r--src/rgw/rgw_admin.cc1
-rw-r--r--src/rgw/rgw_bucket.cc150
-rw-r--r--src/rgw/rgw_bucket.h3
-rw-r--r--src/rgw/rgw_common.h3
-rw-r--r--src/rgw/rgw_json_enc.cc14
7 files changed, 224 insertions, 2 deletions
diff --git a/src/common/ceph_json.cc b/src/common/ceph_json.cc
index e5fc48a74f8..37b4ccdee7a 100644
--- a/src/common/ceph_json.cc
+++ b/src/common/ceph_json.cc
@@ -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);
}
diff --git a/src/common/ceph_json.h b/src/common/ceph_json.h
index 04ca4c1e4a1..8085a7ca6cc 100644
--- a/src/common/ceph_json.h
+++ b/src/common/ceph_json.h
@@ -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,
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc
index 9ea6c2b790c..678aed5b373 100644
--- a/src/rgw/rgw_admin.cc
+++ b/src/rgw/rgw_admin.cc
@@ -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);
diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc
index 809c653de14..95be53fa759 100644
--- a/src/rgw/rgw_bucket.cc
+++ b/src/rgw/rgw_bucket.cc
@@ -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);
+}
diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h
index a6ac836ace7..0994baba488 100644
--- a/src/rgw/rgw_bucket.h
+++ b/src/rgw/rgw_bucket.h
@@ -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.
diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h
index 1a72b35eb28..67b1074d64a 100644
--- a/src/rgw/rgw_common.h
+++ b/src/rgw/rgw_common.h
@@ -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)
diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc
index 60948619076..2094b5cb372 100644
--- a/src/rgw/rgw_json_enc.cc
+++ b/src/rgw/rgw_json_enc.cc
@@ -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);