diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-05-08 20:40:48 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-05-09 11:07:13 -0700 |
commit | 770d94d3065bb42308be95beb2b3911164f3ace7 (patch) | |
tree | 0f9864988dbdd4236e342ea87ce308f72afe8451 | |
parent | 46c3e48ef3b411e8aa2c182c950478957c501a70 (diff) | |
download | ceph-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.cc | 23 | ||||
-rw-r--r-- | src/common/ceph_json.h | 32 | ||||
-rw-r--r-- | src/rgw/rgw_admin.cc | 1 | ||||
-rw-r--r-- | src/rgw/rgw_bucket.cc | 150 | ||||
-rw-r--r-- | src/rgw/rgw_bucket.h | 3 | ||||
-rw-r--r-- | src/rgw/rgw_common.h | 3 | ||||
-rw-r--r-- | src/rgw/rgw_json_enc.cc | 14 |
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); |