summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-02-12 09:40:12 -0800
committerYehuda Sadeh <yehuda@inktank.com>2013-03-22 11:23:08 -0700
commitb07f3cda5e79e9345a3132daa416c4b16a8248c5 (patch)
tree287bca862c01665a1b270c103773cc98bbd11068
parent96ad9b149f22c08ad1510833f45d9afcb90d3289 (diff)
downloadceph-b07f3cda5e79e9345a3132daa416c4b16a8248c5.tar.gz
rgw: add encode_json
dump() just dumps the internal content of an object, encode_json() create the object inside its own section. Note that there are cases where we don't want an object to be surrounded by a section, e.g., when an object represents an array. In such a case we'd need to override the encode_json() for this object type. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/common/ceph_json.cc41
-rw-r--r--src/common/ceph_json.h96
-rw-r--r--src/rgw/rgw_admin.cc3
-rw-r--r--src/rgw/rgw_common.cc7
-rw-r--r--src/rgw/rgw_common.h2
-rw-r--r--src/rgw/rgw_json_enc.cc196
6 files changed, 218 insertions, 127 deletions
diff --git a/src/common/ceph_json.cc b/src/common/ceph_json.cc
index 536618aa7d8..8aa0a384eca 100644
--- a/src/common/ceph_json.cc
+++ b/src/common/ceph_json.cc
@@ -3,6 +3,7 @@
#include <errno.h>
#include "common/ceph_json.h"
+#include "include/utime.h"
// for testing DELETE ME
#include <fstream>
@@ -366,3 +367,43 @@ void decode_json_obj(bool& val, JSONObj *obj)
val = (bool)i;
}
+void encode_json(const char *name, const string& val, Formatter *f)
+{
+ f->dump_string(name, val);
+}
+
+void encode_json(const char *name, const char *val, Formatter *f)
+{
+ f->dump_string(name, val);
+}
+
+void encode_json(const char *name, int val, Formatter *f)
+{
+ f->dump_int(name, val);
+}
+
+void encode_json(const char *name, long val, Formatter *f)
+{
+ f->dump_int(name, val);
+}
+
+void encode_json(const char *name, unsigned val, Formatter *f)
+{
+ f->dump_int(name, val);
+}
+
+void encode_json(const char *name, unsigned long val, Formatter *f)
+{
+ f->dump_int(name, val);
+}
+
+void encode_json(const char *name, const utime_t& val, Formatter *f)
+{
+ f->dump_stream(name) << val;
+}
+
+void encode_json(const char *name, const bufferlist& bl, Formatter *f)
+{
+ encode_json(name, bl.length(), f);
+}
+
diff --git a/src/common/ceph_json.h b/src/common/ceph_json.h
index bfbd3fa6c5b..13e6a1b0d77 100644
--- a/src/common/ceph_json.h
+++ b/src/common/ceph_json.h
@@ -3,8 +3,10 @@
#include <iostream>
#include <include/types.h>
+#include <list>
#include "json_spirit/json_spirit.h"
+#include "Formatter.h"
using namespace json_spirit;
@@ -105,10 +107,10 @@ public:
}
template<class T>
- static bool decode_json(const string& name, T& val, JSONObj *obj, bool mandatory = false);
+ static bool decode_json(const char *name, T& val, JSONObj *obj, bool mandatory = false);
template<class T>
- static void decode_json(const string& name, T& val, T& default_val, JSONObj *obj);
+ static void decode_json(const char *name, T& val, T& default_val, JSONObj *obj);
};
template<class T>
@@ -142,12 +144,12 @@ void decode_json_obj(list<T>& l, JSONObj *obj)
}
template<class T>
-bool JSONDecoder::decode_json(const string& name, T& val, JSONObj *obj, bool mandatory)
+bool JSONDecoder::decode_json(const char *name, T& val, JSONObj *obj, bool mandatory)
{
JSONObjIter iter = obj->find_first(name);
if (iter.end()) {
if (mandatory) {
- string s = "missing mandatory field " + name;
+ string s = "missing mandatory field " + string(name);
throw err(s);
}
return false;
@@ -156,7 +158,7 @@ bool JSONDecoder::decode_json(const string& name, T& val, JSONObj *obj, bool man
try {
decode_json_obj(val, *iter);
} catch (err& e) {
- string s = name + ": ";
+ string s = string(name) + ": ";
s.append(e.message);
throw err(s);
}
@@ -165,7 +167,7 @@ bool JSONDecoder::decode_json(const string& name, T& val, JSONObj *obj, bool man
}
template<class T>
-void JSONDecoder::decode_json(const string& name, T& val, T& default_val, JSONObj *obj)
+void JSONDecoder::decode_json(const char *name, T& val, T& default_val, JSONObj *obj)
{
JSONObjIter iter = obj->find_first(name);
if (iter.end()) {
@@ -177,10 +179,90 @@ void JSONDecoder::decode_json(const string& name, T& val, T& default_val, JSONOb
decode_json_obj(val, *iter);
} catch (err& e) {
val = default_val;
- string s = name + ": ";
+ string s = string(name) + ": ";
s.append(e.message);
throw err(s);
}
}
+template<class T>
+static void encode_json(const char *name, const T& val, Formatter *f)
+{
+ f->open_object_section(name);
+ val.dump(f);
+ f->close_section();
+}
+
+template<class T>
+static void encode_json(const char *name, const std::list<T>& l, Formatter *f)
+{
+ f->open_array_section(name);
+ for (typename std::list<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
+ f->open_object_section("obj");
+ encode_json(name, *iter, f);
+ f->close_section();
+ }
+ f->close_section();
+}
+
+class utime_t;
+
+void encode_json(const char *name, const string& val, Formatter *f);
+void encode_json(const char *name, const char *val, Formatter *f);
+void encode_json(const char *name, int val, Formatter *f);
+void encode_json(const char *name, unsigned val, Formatter *f);
+void encode_json(const char *name, long val, Formatter *f);
+void encode_json(const char *name, unsigned long val, Formatter *f);
+void encode_json(const char *name, const utime_t& val, Formatter *f);
+void encode_json(const char *name, const bufferlist& bl, Formatter *f);
+
+template<class K, class V>
+void encode_json_map(const char *name, const char *index_name,
+ const char *object_name, const char *value_name,
+ void (*cb)(const char *, const V&, Formatter *, void *), void *parent,
+ const map<K, V>& m, Formatter *f)
+{
+ f->open_array_section(name);
+ typename map<K,V>::const_iterator iter;
+ for (iter = m.begin(); iter != m.end(); ++iter) {
+ if (index_name) {
+ f->open_object_section("key_value");
+ f->dump_string(index_name, iter->first);
+ }
+
+ if (object_name) {
+ f->open_object_section(object_name);
+ }
+
+ if (cb) {
+ cb(value_name, iter->second, f, parent);
+ } else {
+ encode_json(value_name, iter->second, f);
+ }
+
+ if (object_name) {
+ f->close_section();
+ }
+ if (index_name) {
+ f->close_section();
+ }
+ }
+ 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,
+ const map<K, V>& m, Formatter *f)
+{
+ encode_json_map<K, V>(name, index_name, object_name, value_name, NULL, NULL, m, f);
+}
+
+template<class K, class V>
+void encode_json_map(const char *name, const char *index_name, const char *value_name,
+ const map<K, V>& m, Formatter *f)
+{
+ encode_json_map<K, V>(name, index_name, NULL, value_name, NULL, NULL, m, f);
+}
+
#endif
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc
index 46aa4d449b2..b4838ae5009 100644
--- a/src/rgw/rgw_admin.cc
+++ b/src/rgw/rgw_admin.cc
@@ -9,6 +9,7 @@ using namespace std;
#include "common/config.h"
#include "common/ceph_argparse.h"
#include "common/Formatter.h"
+#include "common/ceph_json.h"
#include "global/global_init.h"
#include "common/errno.h"
#include "include/utime.h"
@@ -320,7 +321,7 @@ string escape_str(string& src, char c)
static void show_user_info(RGWUserInfo& info, Formatter *formatter)
{
- info.dump(formatter);
+ encode_json("user_info", info, formatter);
formatter->flush(cout);
cout << std::endl;
diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc
index 3609992750f..65ff2fe99ed 100644
--- a/src/rgw/rgw_common.cc
+++ b/src/rgw/rgw_common.cc
@@ -729,7 +729,12 @@ int RGWUserCaps::remove_from_string(const string& str)
void RGWUserCaps::dump(Formatter *f) const
{
- f->open_array_section("caps");
+ dump(f, "caps");
+}
+
+void RGWUserCaps::dump(Formatter *f, const char *name) const
+{
+ f->open_array_section(name);
map<string, uint32_t>::const_iterator iter;
for (iter = caps.begin(); iter != caps.end(); ++iter)
{
diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h
index e2b25ebbe2b..bb203ef72bb 100644
--- a/src/rgw/rgw_common.h
+++ b/src/rgw/rgw_common.h
@@ -355,11 +355,13 @@ public:
}
int check_cap(const string& cap, uint32_t perm);
void dump(Formatter *f) const;
+ void dump(Formatter *f, const char *name) const;
void decode_json(JSONObj *obj);
};
WRITE_CLASS_ENCODER(RGWUserCaps);
+void encode_json(const char *name, const RGWUserCaps& val, Formatter *f);
struct RGWUserInfo
{
diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc
index c6465a29e85..4cccadc5ac0 100644
--- a/src/rgw/rgw_json_enc.cc
+++ b/src/rgw/rgw_json_enc.cc
@@ -9,6 +9,11 @@
#include "common/ceph_json.h"
#include "common/Formatter.h"
+void encode_json(const char *name, const RGWUserCaps& val, Formatter *f)
+{
+ val.dump(f, name);
+}
+
void RGWObjManifestPart::dump(Formatter *f) const
{
f->open_object_section("loc");
@@ -128,94 +133,61 @@ void RGWAccessControlList::dump(Formatter *f) const
void ACLOwner::dump(Formatter *f) const
{
- f->dump_string("id", id);
- f->dump_string("display_name", display_name);
+ encode_json("id", id, f);
+ encode_json("display_name", display_name, f);
}
void RGWAccessControlPolicy::dump(Formatter *f) const
{
- f->open_object_section("acl");
- acl.dump(f);
- f->close_section();
- f->open_object_section("owner");
- owner.dump(f);
- f->close_section();
+ encode_json("acl", acl, f);
+ encode_json("owner", owner, f);
}
void ObjectMetaInfo::dump(Formatter *f) const
{
- f->dump_unsigned("size", size);
- f->dump_stream("mtime") << mtime;
+ encode_json("size", size, f);
+ encode_json("mtime", mtime, f);
}
void ObjectCacheInfo::dump(Formatter *f) const
{
- f->dump_int("status", status);
- f->dump_unsigned("flags", flags);
- f->open_object_section("data");
- f->dump_unsigned("length", data.length());
- f->close_section();
-
- map<string, bufferlist>::const_iterator iter = xattrs.begin();
- f->open_array_section("xattrs");
- for (; iter != xattrs.end(); ++iter) {
- f->dump_string("name", iter->first);
- f->open_object_section("value");
- f->dump_unsigned("length", iter->second.length());
- f->close_section();
- }
- f->close_section();
-
- f->open_array_section("rm_xattrs");
- for (iter = rm_xattrs.begin(); iter != rm_xattrs.end(); ++iter) {
- f->dump_string("name", iter->first);
- f->open_object_section("value");
- f->dump_unsigned("length", iter->second.length());
- f->close_section();
- }
- f->close_section();
- f->open_object_section("meta");
- meta.dump(f);
- f->close_section();
+ encode_json("status", status, f);
+ encode_json("flags", flags, f);
+ encode_json("data", data, f);
+ encode_json_map("xattrs", "name", "value", "length", xattrs, f);
+ encode_json_map("rm_xattrs", "name", "value", "length", rm_xattrs, f);
+ encode_json("meta", meta, f);
}
void RGWCacheNotifyInfo::dump(Formatter *f) const
{
- f->dump_unsigned("op", op);
- f->open_object_section("obj");
- obj.dump(f);
- f->close_section();
- f->open_object_section("obj_info");
- obj_info.dump(f);
- f->close_section();
- f->dump_unsigned("ofs", ofs);
- f->dump_string("ns", ns);
+ encode_json("op", op, f);
+ encode_json("obj", obj, f);
+ encode_json("obj_info", obj_info, f);
+ encode_json("ofs", ofs, f);
+ encode_json("ns", ns, f);
}
void RGWAccessKey::dump(Formatter *f) const
{
- f->open_object_section("key");
- f->dump_string("access_key", id);
- f->dump_string("secret_key", key);
- f->dump_string("subuser", subuser);
- f->close_section();
+ encode_json("access_key", id, f);
+ encode_json("secret_key", key, f);
+ encode_json("subuser", subuser, f);
}
void RGWAccessKey::dump(Formatter *f, const string& user, bool swift) const
{
- f->open_object_section("key");
string u = user;
if (!subuser.empty()) {
u.append(":");
u.append(subuser);
}
- f->dump_string("user", u);
+ encode_json("user", u, f);
if (!swift) {
- f->dump_string("access_key", id);
+ encode_json("access_key", id, f);
}
- f->dump_string("secret_key", key);
- f->close_section();
+ encode_json("secret_key", key, f);
}
void RGWAccessKey::decode_json(JSONObj *obj) {
@@ -292,25 +264,21 @@ static void perm_to_str(uint32_t mask, char *buf, int len)
void RGWSubUser::dump(Formatter *f) const
{
- f->open_object_section("subuser");
- f->dump_string("id", name);
+ encode_json("id", name, f);
char buf[256];
perm_to_str(perm_mask, buf, sizeof(buf));
- f->dump_string("permissions", buf);
- f->close_section();
+ encode_json("permissions", (const char *)buf, f);
}
void RGWSubUser::dump(Formatter *f, const string& user) const
{
- f->open_object_section("subuser");
string s = user;
s.append(":");
s.append(name);
- f->dump_string("id", s);
+ encode_json("id", s, f);
char buf[256];
perm_to_str(perm_mask, buf, sizeof(buf));
- f->dump_string("permissions", buf);
- f->close_section();
+ encode_json("permissions", (const char *)buf, f);
}
static uint32_t str_to_perm(const string& s)
@@ -338,42 +306,40 @@ void RGWSubUser::decode_json(JSONObj *obj)
perm_mask = str_to_perm(perm_str);
}
-void RGWUserInfo::dump(Formatter *f) const
+static void user_info_dump_subuser(const char *name, const RGWSubUser& subuser, Formatter *f, void *parent)
{
- f->open_object_section("user_info");
+ RGWUserInfo *info = (RGWUserInfo *)parent;
+ subuser.dump(f, info->user_id);
+}
- f->dump_string("user_id", user_id);
- f->dump_string("display_name", display_name);
- f->dump_string("email", user_email);
- f->dump_int("suspended", (int)suspended);
- f->dump_int("max_buckets", (int)max_buckets);
+static void user_info_dump_key(const char *name, const RGWAccessKey& key, Formatter *f, void *parent)
+{
+ RGWUserInfo *info = (RGWUserInfo *)parent;
+ key.dump(f, info->user_id, false);
+}
- f->dump_unsigned("auid", auid);
+static void user_info_dump_swift_key(const char *name, const RGWAccessKey& key, Formatter *f, void *parent)
+{
+ RGWUserInfo *info = (RGWUserInfo *)parent;
+ key.dump(f, info->user_id, true);
+}
- map<string, RGWSubUser>::const_iterator siter = subusers.begin();
- f->open_array_section("subusers");
- for (; siter != subusers.end(); ++siter) {
- siter->second.dump(f, user_id);
- }
- f->close_section();
+void RGWUserInfo::dump(Formatter *f) const
+{
- map<string, RGWAccessKey>::const_iterator aiter = access_keys.begin();
- f->open_array_section("keys");
- for (; aiter != access_keys.end(); ++aiter) {
- aiter->second.dump(f, user_id, false);
- }
- f->close_section();
+ encode_json("user_id", user_id, f);
+ encode_json("display_name", display_name, f);
+ encode_json("email", user_email, f);
+ encode_json("suspended", (int)suspended, f);
+ encode_json("max_buckets", (int)max_buckets, f);
- aiter = swift_keys.begin();
- f->open_array_section("swift_keys");
- for (; aiter != swift_keys.end(); ++aiter) {
- aiter->second.dump(f, user_id, true);
- }
- f->close_section();
+ encode_json("auid", auid, f);
- caps.dump(f);
+ encode_json_map("subusers", NULL, "subuser", NULL, user_info_dump_subuser,(void *)this, subusers, f);
+ encode_json_map("keys", NULL, "key", NULL, user_info_dump_key,(void *)this, access_keys, f);
+ encode_json_map("swift_keys", NULL, "key", NULL, user_info_dump_swift_key,(void *)this, swift_keys, f);
- f->close_section();
+ encode_json("caps", caps, f);
}
@@ -428,48 +394,42 @@ void RGWUserInfo::decode_json(JSONObj *obj)
void rgw_bucket::dump(Formatter *f) const
{
- f->dump_string("name", name);
- f->dump_string("pool", pool);
- f->dump_string("marker", marker);
- f->dump_string("bucket_id", bucket_id);
+ encode_json("name", name, f);
+ encode_json("pool", pool, f);
+ encode_json("marker", marker, f);
+ encode_json("bucket_id", bucket_id, f);
}
void RGWBucketInfo::dump(Formatter *f) const
{
- f->open_object_section("bucket");
- bucket.dump(f);
- f->close_section();
- f->dump_string("owner", owner);
- f->dump_unsigned("flags", flags);
+ encode_json("bucket", bucket, f);
+ encode_json("owner", owner, f);
+ encode_json("flags", flags, f);
}
void RGWBucketEnt::dump(Formatter *f) const
{
- f->open_object_section("bucket");
- bucket.dump(f);
- f->close_section();
- f->dump_unsigned("size", size);
- f->dump_unsigned("size_rounded", size_rounded);
- f->dump_stream("mtime") << mtime;
- f->dump_unsigned("count", count);
+ encode_json("bucket", bucket, f);
+ encode_json("size", size, f);
+ encode_json("size_rounded", size_rounded, f);
+ encode_json("mtime", mtime, f);
+ encode_json("count", count, f);
}
void RGWUploadPartInfo::dump(Formatter *f) const
{
- f->dump_unsigned("num", num);
- f->dump_unsigned("size", size);
- f->dump_string("etag", etag);
- f->dump_stream("modified") << modified;
+ encode_json("num", num, f);
+ encode_json("size", size, f);
+ encode_json("etag", etag, f);
+ encode_json("modified", modified, f);
}
void rgw_obj::dump(Formatter *f) const
{
- f->open_object_section("bucket");
- bucket.dump(f);
- f->close_section();
- f->dump_string("key", key);
- f->dump_string("ns", ns);
- f->dump_string("object", object);
+ encode_json("bucket", bucket, f);
+ encode_json("key", key, f);
+ encode_json("ns", ns, f);
+ encode_json("object", object, f);
}