From 2768583dc486109e49d209243675b99fdd39e92c Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 9 Jan 2017 13:04:43 -0800 Subject: [PATCH] rgw: new rest api to retrieve object layout Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_common.h | 3 ++- src/rgw/rgw_op.cc | 23 +++++++++++++++++++++++ src/rgw/rgw_op.h | 28 ++++++++++++++++++++++++++++ src/rgw/rgw_rados.cc | 13 +++++++++++++ src/rgw/rgw_rados.h | 1 + src/rgw/rgw_rest_s3.cc | 34 ++++++++++++++++++++++++++++++++++ src/rgw/rgw_rest_s3.h | 8 ++++++++ 7 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index b852520e4c6e..112dc09903b5 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -446,7 +446,8 @@ enum RGWOpType { RGW_OP_GET_INFO, /* rgw specific */ - RGW_OP_ADMIN_SET_METADATA + RGW_OP_ADMIN_SET_METADATA, + RGW_OP_GET_OBJ_LAYOUT, }; class RGWAccessControlPolicy; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 29a272184ebc..c3f08d06f2a0 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -5515,6 +5515,29 @@ void RGWSetAttrs::execute() } } +void RGWGetObjLayout::pre_exec() +{ + rgw_bucket_object_pre_exec(s); +} + +void RGWGetObjLayout::execute() +{ + rgw_obj obj(s->bucket, s->object.name); + obj.set_instance(s->object.instance); + target = new RGWRados::Object(store, s->bucket_info, *static_cast(s->obj_ctx), obj); + RGWRados::Object::Read stat_op(target); + + op_ret = stat_op.prepare(); + if (op_ret < 0) { + return; + } + + head_obj = stat_op.state.obj; + + op_ret = target->get_manifest(&manifest); +} + + RGWHandler::~RGWHandler() { } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 44a693c10bb8..62f4e3b838ab 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1764,4 +1764,32 @@ public: virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; } }; +class RGWGetObjLayout : public RGWOp { +protected: + RGWRados::Object *target{nullptr}; + RGWObjManifest *manifest{nullptr}; + rgw_obj head_obj; + +public: + RGWGetObjLayout() { + delete target; + } + + int check_caps(RGWUserCaps& caps) { + return caps.check_cap("admin", RGW_CAP_READ); + } + int verify_permission() { + return check_caps(s->user->caps); + } + void pre_exec(); + void execute(); + + virtual void send_response() = 0; + virtual const string name() { return "get_obj_layout"; } + virtual RGWOpType get_type() { return RGW_OP_GET_OBJ_LAYOUT; } + virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; } +}; + + + #endif /* CEPH_RGW_OP_H */ diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 8757baf1c578..cd36f89069ed 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -8638,6 +8638,19 @@ int RGWRados::get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **stat return ret; } +int RGWRados::Object::get_manifest(RGWObjManifest **pmanifest) +{ + RGWObjState *astate; + int r = get_state(&astate, true); + if (r < 0) { + return r; + } + + *pmanifest = &astate->manifest; + + return 0; +} + int RGWRados::Object::Read::get_attr(const char *name, bufferlist& dest) { RGWObjState *state; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 9d820ff7f00d..b1671fdf0aac 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -2371,6 +2371,7 @@ public: rgw_obj& get_obj() { return obj; } RGWObjectCtx& get_ctx() { return ctx; } RGWBucketInfo& get_bucket_info() { return bucket_info; } + int get_manifest(RGWObjManifest **pmanifest); int get_bucket_shard(BucketShard **pbs) { if (!bs_initialized) { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index d238461d7cfd..1e08a584b570 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -2899,6 +2899,38 @@ void RGWDeleteMultiObj_ObjStore_S3::end_response() rgw_flush_formatter_and_reset(s, s->formatter); } +void RGWGetObjLayout_ObjStore_S3::send_response() +{ + if (op_ret) + set_req_state_err(s, op_ret); + dump_errno(s); + end_header(s, this, "application/json"); + + JSONFormatter f; + + if (op_ret < 0) { + return; + } + + f.open_object_section("result"); + ::encode_json("head", head_obj, &f); + ::encode_json("manifest", *manifest, &f); + f.open_array_section("data_location"); + for (auto miter = manifest->obj_begin(); miter != manifest->obj_end(); ++miter) { + f.open_object_section("obj"); + rgw_obj loc = miter.get_location(); + ::encode_json("ofs", miter.get_ofs(), &f); + ::encode_json("loc", loc, &f); + ::encode_json("loc_ofs", miter.location_ofs(), &f); + ::encode_json("loc_size", miter.get_stripe_size(), &f); + f.close_section(); + rgw_flush_formatter(s, &f); + } + f.close_section(); + f.close_section(); + rgw_flush_formatter(s, &f); +} + RGWOp *RGWHandler_REST_Service_S3::op_get() { if (is_usage_op()) { @@ -3036,6 +3068,8 @@ RGWOp *RGWHandler_REST_Obj_S3::op_get() return new RGWGetACLs_ObjStore_S3; } else if (s->info.args.exists("uploadId")) { return new RGWListMultipart_ObjStore_S3; + } else if (s->info.args.exists("layout")) { + return new RGWGetObjLayout_ObjStore_S3; } return get_obj_op(true); } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 91c73613ab67..edc7649090cf 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -398,6 +398,14 @@ public: void end_response(); }; +class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout { +public: + RGWGetObjLayout_ObjStore_S3() {} + ~RGWGetObjLayout_ObjStore_S3() {} + + void send_response(); +}; + class RGW_Auth_S3_Keystone_ValidateToken : public RGWHTTPClient { private: bufferlist rx_buffer; -- 2.47.3