]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef CEPH_RGW_CR_REST_H |
2 | #define CEPH_RGW_CR_REST_H | |
3 | ||
4 | #include <boost/intrusive_ptr.hpp> | |
5 | #include "include/assert.h" // boost header clobbers our assert.h | |
6 | ||
7 | #include "rgw_coroutine.h" | |
8 | #include "rgw_rest_conn.h" | |
9 | ||
10 | template <class T> | |
11 | class RGWReadRESTResourceCR : public RGWSimpleCoroutine { | |
12 | RGWRESTConn *conn; | |
13 | RGWHTTPManager *http_manager; | |
14 | string path; | |
15 | param_vec_t params; | |
16 | T *result; | |
17 | ||
18 | boost::intrusive_ptr<RGWRESTReadResource> http_op; | |
19 | ||
20 | public: | |
21 | RGWReadRESTResourceCR(CephContext *_cct, RGWRESTConn *_conn, | |
22 | RGWHTTPManager *_http_manager, const string& _path, | |
23 | rgw_http_param_pair *params, T *_result) | |
24 | : RGWSimpleCoroutine(_cct), conn(_conn), http_manager(_http_manager), | |
25 | path(_path), params(make_param_list(params)), result(_result) | |
26 | {} | |
27 | ||
28 | ~RGWReadRESTResourceCR() override { | |
29 | request_cleanup(); | |
30 | } | |
31 | ||
32 | int send_request() override { | |
33 | auto op = boost::intrusive_ptr<RGWRESTReadResource>( | |
34 | new RGWRESTReadResource(conn, path, params, NULL, http_manager)); | |
35 | ||
36 | op->set_user_info((void *)stack); | |
37 | ||
38 | int ret = op->aio_read(); | |
39 | if (ret < 0) { | |
40 | log_error() << "failed to send http operation: " << op->to_str() | |
41 | << " ret=" << ret << std::endl; | |
42 | op->put(); | |
43 | return ret; | |
44 | } | |
45 | std::swap(http_op, op); // store reference in http_op on success | |
46 | return 0; | |
47 | } | |
48 | ||
49 | int request_complete() override { | |
50 | int ret = http_op->wait(result); | |
51 | auto op = std::move(http_op); // release ref on return | |
52 | if (ret < 0) { | |
53 | error_stream << "http operation failed: " << op->to_str() | |
54 | << " status=" << op->get_http_status() << std::endl; | |
55 | op->put(); | |
56 | return ret; | |
57 | } | |
58 | op->put(); | |
59 | return 0; | |
60 | } | |
61 | ||
62 | void request_cleanup() override { | |
63 | if (http_op) { | |
64 | http_op->put(); | |
65 | http_op = NULL; | |
66 | } | |
67 | } | |
68 | }; | |
69 | ||
70 | template <class S, class T> | |
71 | class RGWSendRESTResourceCR : public RGWSimpleCoroutine { | |
72 | RGWRESTConn *conn; | |
73 | RGWHTTPManager *http_manager; | |
74 | string method; | |
75 | string path; | |
76 | param_vec_t params; | |
77 | T *result; | |
78 | S input; | |
79 | ||
80 | boost::intrusive_ptr<RGWRESTSendResource> http_op; | |
81 | ||
82 | public: | |
83 | RGWSendRESTResourceCR(CephContext *_cct, RGWRESTConn *_conn, | |
84 | RGWHTTPManager *_http_manager, | |
85 | const string& _method, const string& _path, | |
86 | rgw_http_param_pair *_params, S& _input, T *_result) | |
87 | : RGWSimpleCoroutine(_cct), conn(_conn), http_manager(_http_manager), | |
88 | method(_method), path(_path), params(make_param_list(_params)), result(_result), | |
89 | input(_input) | |
90 | {} | |
91 | ||
92 | ~RGWSendRESTResourceCR() override { | |
93 | request_cleanup(); | |
94 | } | |
95 | ||
96 | int send_request() override { | |
97 | auto op = boost::intrusive_ptr<RGWRESTSendResource>( | |
98 | new RGWRESTSendResource(conn, method, path, params, NULL, http_manager)); | |
99 | ||
100 | op->set_user_info((void *)stack); | |
101 | ||
102 | JSONFormatter jf; | |
103 | encode_json("data", input, &jf); | |
104 | std::stringstream ss; | |
105 | jf.flush(ss); | |
106 | bufferlist bl; | |
107 | bl.append(ss.str()); | |
108 | ||
109 | int ret = op->aio_send(bl); | |
110 | if (ret < 0) { | |
111 | lsubdout(cct, rgw, 0) << "ERROR: failed to send request" << dendl; | |
112 | op->put(); | |
113 | return ret; | |
114 | } | |
115 | std::swap(http_op, op); // store reference in http_op on success | |
116 | return 0; | |
117 | } | |
118 | ||
119 | int request_complete() override { | |
120 | int ret; | |
121 | if (result) { | |
122 | ret = http_op->wait(result); | |
123 | } else { | |
124 | bufferlist bl; | |
125 | ret = http_op->wait_bl(&bl); | |
126 | } | |
127 | auto op = std::move(http_op); // release ref on return | |
128 | if (ret < 0) { | |
129 | error_stream << "http operation failed: " << op->to_str() | |
130 | << " status=" << op->get_http_status() << std::endl; | |
131 | lsubdout(cct, rgw, 5) << "failed to wait for op, ret=" << ret | |
132 | << ": " << op->to_str() << dendl; | |
133 | op->put(); | |
134 | return ret; | |
135 | } | |
136 | op->put(); | |
137 | return 0; | |
138 | } | |
139 | ||
140 | void request_cleanup() override { | |
141 | if (http_op) { | |
142 | http_op->put(); | |
143 | http_op = NULL; | |
144 | } | |
145 | } | |
146 | }; | |
147 | ||
148 | template <class S, class T> | |
149 | class RGWPostRESTResourceCR : public RGWSendRESTResourceCR<S, T> { | |
150 | public: | |
151 | RGWPostRESTResourceCR(CephContext *_cct, RGWRESTConn *_conn, | |
152 | RGWHTTPManager *_http_manager, | |
153 | const string& _path, | |
154 | rgw_http_param_pair *_params, S& _input, T *_result) | |
155 | : RGWSendRESTResourceCR<S, T>(_cct, _conn, _http_manager, | |
156 | "POST", _path, | |
157 | _params, _input, _result) {} | |
158 | }; | |
159 | ||
160 | template <class S, class T> | |
161 | class RGWPutRESTResourceCR : public RGWSendRESTResourceCR<S, T> { | |
162 | public: | |
163 | RGWPutRESTResourceCR(CephContext *_cct, RGWRESTConn *_conn, | |
164 | RGWHTTPManager *_http_manager, | |
165 | const string& _path, | |
166 | rgw_http_param_pair *_params, S& _input, T *_result) | |
167 | : RGWSendRESTResourceCR<S, T>(_cct, _conn, _http_manager, | |
168 | "PUT", _path, | |
169 | _params, _input, _result) {} | |
170 | }; | |
171 | ||
172 | class RGWDeleteRESTResourceCR : public RGWSimpleCoroutine { | |
173 | RGWRESTConn *conn; | |
174 | RGWHTTPManager *http_manager; | |
175 | string path; | |
176 | param_vec_t params; | |
177 | ||
178 | boost::intrusive_ptr<RGWRESTDeleteResource> http_op; | |
179 | ||
180 | public: | |
181 | RGWDeleteRESTResourceCR(CephContext *_cct, RGWRESTConn *_conn, | |
182 | RGWHTTPManager *_http_manager, | |
183 | const string& _path, | |
184 | rgw_http_param_pair *_params) | |
185 | : RGWSimpleCoroutine(_cct), conn(_conn), http_manager(_http_manager), | |
186 | path(_path), params(make_param_list(_params)) | |
187 | {} | |
188 | ||
189 | ~RGWDeleteRESTResourceCR() override { | |
190 | request_cleanup(); | |
191 | } | |
192 | ||
193 | int send_request() override { | |
194 | auto op = boost::intrusive_ptr<RGWRESTDeleteResource>( | |
195 | new RGWRESTDeleteResource(conn, path, params, nullptr, http_manager)); | |
196 | ||
197 | op->set_user_info((void *)stack); | |
198 | ||
199 | bufferlist bl; | |
200 | ||
201 | int ret = op->aio_send(bl); | |
202 | if (ret < 0) { | |
203 | lsubdout(cct, rgw, 0) << "ERROR: failed to send DELETE request" << dendl; | |
204 | op->put(); | |
205 | return ret; | |
206 | } | |
207 | std::swap(http_op, op); // store reference in http_op on success | |
208 | return 0; | |
209 | } | |
210 | ||
211 | int request_complete() override { | |
212 | int ret; | |
213 | bufferlist bl; | |
214 | ret = http_op->wait_bl(&bl); | |
215 | auto op = std::move(http_op); // release ref on return | |
216 | if (ret < 0) { | |
217 | error_stream << "http operation failed: " << op->to_str() | |
218 | << " status=" << op->get_http_status() << std::endl; | |
219 | lsubdout(cct, rgw, 5) << "failed to wait for op, ret=" << ret | |
220 | << ": " << op->to_str() << dendl; | |
221 | op->put(); | |
222 | return ret; | |
223 | } | |
224 | op->put(); | |
225 | return 0; | |
226 | } | |
227 | ||
228 | void request_cleanup() override { | |
229 | if (http_op) { | |
230 | http_op->put(); | |
231 | http_op = NULL; | |
232 | } | |
233 | } | |
234 | }; | |
235 | ||
236 | #endif |