Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_rest_conn.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_RGW_REST_CONN_H
5 #define CEPH_RGW_REST_CONN_H
6
7 #include "rgw_rados.h"
8 #include "rgw_rest_client.h"
9 #include "common/ceph_json.h"
10 #include "common/RefCountedObj.h"
11
12 #include <atomic>
13
14 class CephContext;
15 class RGWRados;
16
17 template <class T>
18 static int parse_decode_json(CephContext *cct, T& t, bufferlist& bl)
19 {
20   JSONParser p;
21   int ret = p.parse(bl.c_str(), bl.length());
22   if (ret < 0) {
23     return ret;
24   }
25
26   try {
27     decode_json_obj(t, &p);
28   } catch (JSONDecoder::err& e) {
29     return -EINVAL;
30   }
31   return 0;
32 }
33
34 struct rgw_http_param_pair {
35   const char *key;
36   const char *val;
37 };
38
39 // copy a null-terminated rgw_http_param_pair list into a list of string pairs
40 inline param_vec_t make_param_list(const rgw_http_param_pair* pp)
41 {
42   param_vec_t params;
43   while (pp && pp->key) {
44     string k = pp->key;
45     string v = (pp->val ? pp->val : "");
46     params.emplace_back(make_pair(std::move(k), std::move(v)));
47     ++pp;
48   }
49   return params;
50 }
51
52 class RGWRESTConn
53 {
54   CephContext *cct;
55   vector<string> endpoints;
56   RGWAccessKey key;
57   string self_zone_group;
58   string remote_id;
59   std::atomic<int64_t> counter = { 0 };
60
61 public:
62
63   RGWRESTConn(CephContext *_cct, RGWRados *store, const string& _remote_id, const list<string>& endpoints);
64   // custom move needed for atomic
65   RGWRESTConn(RGWRESTConn&& other);
66   RGWRESTConn& operator=(RGWRESTConn&& other);
67
68   int get_url(string& endpoint);
69   string get_url();
70   const string& get_self_zonegroup() {
71     return self_zone_group;
72   }
73   const string& get_remote_id() {
74     return remote_id;
75   }
76   RGWAccessKey& get_key() {
77     return key;
78   }
79
80   CephContext *get_ctx() {
81     return cct;
82   }
83   size_t get_endpoint_count() const { return endpoints.size(); }
84
85   /* sync request */
86   int forward(const rgw_user& uid, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl);
87
88   /* async request */
89   int put_obj_init(const rgw_user& uid, rgw_obj& obj, uint64_t obj_size,
90                    map<string, bufferlist>& attrs, RGWRESTStreamWriteRequest **req);
91   int complete_request(RGWRESTStreamWriteRequest *req, string& etag, ceph::real_time *mtime);
92
93   int get_obj(const rgw_user& uid, req_info *info /* optional */, rgw_obj& obj,
94               const ceph::real_time *mod_ptr, const ceph::real_time *unmod_ptr,
95               uint32_t mod_zone_id, uint64_t mod_pg_ver,
96               bool prepend_metadata, bool get_op, bool rgwx_stat, bool sync_manifest,
97               bool skip_decrypt, RGWGetDataCB *cb, RGWRESTStreamRWRequest **req);
98   int complete_request(RGWRESTStreamRWRequest *req, string& etag, ceph::real_time *mtime, uint64_t *psize, map<string, string>& attrs);
99
100   int get_resource(const string& resource,
101                    param_vec_t *extra_params,
102                    map<string, string>* extra_headers,
103                    bufferlist& bl,
104                    bufferlist *send_data = nullptr,
105                    RGWHTTPManager *mgr = nullptr);
106
107   template <class T>
108   int get_json_resource(const string& resource, param_vec_t *params, bufferlist *in_data, T& t);
109   template <class T>
110   int get_json_resource(const string& resource, param_vec_t *params, T& t);
111   template <class T>
112   int get_json_resource(const string& resource, const rgw_http_param_pair *pp, T& t);
113 };
114
115
116 template<class T>
117 int RGWRESTConn::get_json_resource(const string& resource, param_vec_t *params, bufferlist *in_data, T& t)
118 {
119   bufferlist bl;
120   int ret = get_resource(resource, params, nullptr, bl, in_data);
121   if (ret < 0) {
122     return ret;
123   }
124
125   ret = parse_decode_json(cct, t, bl);
126   if (ret < 0) {
127     return ret;
128   }
129
130   return 0;
131 }
132
133 template<class T>
134 int RGWRESTConn::get_json_resource(const string& resource, param_vec_t *params, T& t)
135 {
136   return get_json_resource(resource, params, nullptr, t);
137 }
138
139 template<class T>
140 int RGWRESTConn::get_json_resource(const string& resource,  const rgw_http_param_pair *pp, T& t)
141 {
142   param_vec_t params = make_param_list(pp);
143   return get_json_resource(resource, &params, t);
144 }
145
146 class RGWStreamIntoBufferlist : public RGWGetDataCB {
147   bufferlist& bl;
148 public:
149   RGWStreamIntoBufferlist(bufferlist& _bl) : bl(_bl) {}
150   int handle_data(bufferlist& inbl, off_t bl_ofs, off_t bl_len) override {
151     bl.claim_append(inbl);
152     return bl_len;
153   }
154 };
155
156 class RGWRESTReadResource : public RefCountedObject {
157   CephContext *cct;
158   RGWRESTConn *conn;
159   string resource;
160   param_vec_t params;
161   map<string, string> headers;
162   bufferlist bl;
163   RGWStreamIntoBufferlist cb;
164
165   RGWHTTPManager *mgr;
166   RGWRESTStreamReadRequest req;
167
168   void init_common(param_vec_t *extra_headers);
169
170 public:
171   RGWRESTReadResource(RGWRESTConn *_conn,
172                       const string& _resource,
173                       const rgw_http_param_pair *pp,
174                       param_vec_t *extra_headers,
175                       RGWHTTPManager *_mgr);
176
177   RGWRESTReadResource(RGWRESTConn *_conn,
178                       const string& _resource,
179                       param_vec_t& _params,
180                       param_vec_t *extra_headers,
181                       RGWHTTPManager *_mgr);
182
183   void set_user_info(void *user_info) {
184     req.set_user_info(user_info);
185   }
186   void *get_user_info() {
187     return req.get_user_info();
188   }
189
190   template <class T>
191   int decode_resource(T *dest);
192
193   int read();
194
195   int aio_read();
196
197   string to_str() {
198     return req.to_str();
199   }
200
201   int get_http_status() {
202     return req.get_http_status();
203   }
204
205   int wait_bl(bufferlist *pbl) {
206     int ret = req.wait();
207     if (ret < 0) {
208       return ret;
209     }
210
211     if (req.get_status() < 0) {
212       return req.get_status();
213     }
214     *pbl = bl;
215     return 0;
216   }
217
218   template <class T>
219   int wait(T *dest);
220
221   template <class T>
222   int fetch(T *dest);
223 };
224
225
226 template <class T>
227 int RGWRESTReadResource::decode_resource(T *dest)
228 {
229   int ret = req.get_status();
230   if (ret < 0) {
231     return ret;
232   }
233   ret = parse_decode_json(cct, *dest, bl);
234   if (ret < 0) {
235     return ret;
236   }
237   return 0;
238 }
239
240 template <class T>
241 int RGWRESTReadResource::fetch(T *dest)
242 {
243   int ret = read();
244   if (ret < 0) {
245     return ret;
246   }
247
248   ret = decode_resource(dest);
249   if (ret < 0) {
250     return ret;
251   }
252   return 0;
253 }
254
255 template <class T>
256 int RGWRESTReadResource::wait(T *dest)
257 {
258   int ret = req.wait();
259   if (ret < 0) {
260     return ret;
261   }
262
263   ret = decode_resource(dest);
264   if (ret < 0) {
265     return ret;
266   }
267   return 0;
268 }
269
270 class RGWRESTSendResource : public RefCountedObject {
271   CephContext *cct;
272   RGWRESTConn *conn;
273   string method;
274   string resource;
275   param_vec_t params;
276   map<string, string> headers;
277   bufferlist bl;
278   RGWStreamIntoBufferlist cb;
279
280   RGWHTTPManager *mgr;
281   RGWRESTStreamRWRequest req;
282
283   void init_common(param_vec_t *extra_headers);
284
285 public:
286   RGWRESTSendResource(RGWRESTConn *_conn,
287                       const string& _method,
288                       const string& _resource,
289                       const rgw_http_param_pair *pp,
290                       param_vec_t *extra_headers,
291                       RGWHTTPManager *_mgr);
292
293   RGWRESTSendResource(RGWRESTConn *_conn,
294                       const string& _method,
295                       const string& _resource,
296                       param_vec_t& params,
297                       param_vec_t *extra_headers,
298                       RGWHTTPManager *_mgr);
299
300   void set_user_info(void *user_info) {
301     req.set_user_info(user_info);
302   }
303   void *get_user_info() {
304     return req.get_user_info();
305   }
306
307   template <class T>
308   int decode_resource(T *dest);
309
310   int send(bufferlist& bl);
311
312   int aio_send(bufferlist& bl);
313
314   string to_str() {
315     return req.to_str();
316   }
317
318   int get_http_status() {
319     return req.get_http_status();
320   }
321
322   int wait_bl(bufferlist *pbl) {
323     int ret = req.wait();
324     if (ret < 0) {
325       return ret;
326     }
327
328     if (req.get_status() < 0) {
329       return req.get_status();
330     }
331     *pbl = bl;
332     return 0;
333   }
334
335   template <class T>
336   int wait(T *dest);
337 };
338
339 template <class T>
340 int RGWRESTSendResource::decode_resource(T *dest)
341 {
342   int ret = req.get_status();
343   if (ret < 0) {
344     return ret;
345   }
346   ret = parse_decode_json(cct, *dest, bl);
347   if (ret < 0) {
348     return ret;
349   }
350   return 0;
351 }
352
353 template <class T>
354 int RGWRESTSendResource::wait(T *dest)
355 {
356   int ret = req.wait();
357   if (ret < 0) {
358     return ret;
359   }
360
361   ret = decode_resource(dest);
362   if (ret < 0) {
363     return ret;
364   }
365   return 0;
366 }
367
368 class RGWRESTPostResource : public RGWRESTSendResource {
369 public:
370   RGWRESTPostResource(RGWRESTConn *_conn,
371                       const string& _resource,
372                       const rgw_http_param_pair *pp,
373                       param_vec_t *extra_headers,
374                       RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "POST", _resource,
375                                                                   pp, extra_headers, _mgr) {}
376
377   RGWRESTPostResource(RGWRESTConn *_conn,
378                       const string& _resource,
379                       param_vec_t& params,
380                       param_vec_t *extra_headers,
381                       RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "POST", _resource,
382                                                                   params, extra_headers, _mgr) {}
383
384 };
385
386 class RGWRESTPutResource : public RGWRESTSendResource {
387 public:
388   RGWRESTPutResource(RGWRESTConn *_conn,
389                      const string& _resource,
390                      const rgw_http_param_pair *pp,
391                      param_vec_t *extra_headers,
392                      RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "PUT", _resource,
393                                                                   pp, extra_headers, _mgr) {}
394
395   RGWRESTPutResource(RGWRESTConn *_conn,
396                      const string& _resource,
397                      param_vec_t& params,
398                      param_vec_t *extra_headers,
399                      RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "PUT", _resource,
400                                                                   params, extra_headers, _mgr) {}
401
402 };
403
404 class RGWRESTDeleteResource : public RGWRESTSendResource {
405 public:
406   RGWRESTDeleteResource(RGWRESTConn *_conn,
407                      const string& _resource,
408                      const rgw_http_param_pair *pp,
409                      param_vec_t *extra_headers,
410                      RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "DELETE", _resource,
411                                                                   pp, extra_headers, _mgr) {}
412
413   RGWRESTDeleteResource(RGWRESTConn *_conn,
414                      const string& _resource,
415                      param_vec_t& params,
416                      param_vec_t *extra_headers,
417                      RGWHTTPManager *_mgr) : RGWRESTSendResource(_conn, "DELETE", _resource,
418                                                                   params, extra_headers, _mgr) {}
419
420 };
421
422
423
424 #endif