1extern crate clap;
2extern crate hyper;
3extern crate iron;
4extern crate params;
5extern crate router;
6extern crate serde;
7extern crate serde_json;
8
9use hyper::header::{ContentType, Headers, ETag, EntityTag};
10use hyper::mime::{Attr, Mime, TopLevel, SubLevel, Value};
11
12use iron::prelude::*;
13use iron::request::Request;
14use iron::response::Response;
15use iron::status;
16use iron::IronResult;
18
19use router::Router;
20use serde_json::Map;
21
22use std::io::Read;
23use std::sync::{Arc, Mutex};
24
25use super::client::Client;
26use super::couchbase::types::error_type;
27use super::couchbase::types::instance;
28use super::couchbase::types::response;
29use super::couchbase::types::operation::Operation;
30
31pub fn get_meta(cas: &str, version: u16) -> serde_json::Value {
47 json!({
48 "cas": cas.to_string(),
49 "version": u64::from(version)
50 })
51}
52
53pub fn get_error(client: instance::InstancePtr, rc: &error_type::ErrorType) -> Map<String, serde_json::Value> {
54 let error = response::format_error(client, rc);
55
56 let mut res: Map<String, serde_json::Value> = Map::new();
57 res.insert("error".to_string(), serde_json::value::Value::String(error.to_string()));
58
59 res
60}
61
62pub fn handler_get(safe_client: &Arc<Mutex<Client>>, req: &mut iron::request::Request) -> IronResult<Response> {
63 println!("{:?}", &req);
64
65 let docid = req.extensions.get::<Router>().unwrap().find("docid").unwrap_or("");
68 let mut client = safe_client.lock().unwrap();
69
70 let response = client.get_sync(docid);
71 match response {
72 Ok(result) => {
73 let cas = result.cas.to_string();
74 let value = result.value.unwrap();
75
76 let mut headers = Headers::new();
77 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
78 headers.set(ETag(EntityTag::new(false, cas.to_owned())));
79
80 let doc: serde_json::Value = match serde_json::from_str(&value[..]) {
81 Ok(value) => value,
82 Err(_e) => json!(value)
83 };
84
85 let json = json!({
86 "meta": get_meta(&cas, result.version),
87 "doc": doc
88 });
89
90 let mut response = Response::with((status::Ok, json.to_string()));
91 response.headers = headers;
92 Ok(response)
93 },
94 Err(res) => {
95 let mut headers = Headers::new();
96 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
97
98 let json = serde_json::to_string(
99 &get_error(
100 client.instance,
101 &res.0.unwrap().rc
102 )
103 ).unwrap();
104
105 let mut response = Response::with((status::BadRequest, json));
106 response.headers = headers;
107 Ok(response)
108 }
109 }
110}
111
112pub fn handler_remove(safe_client: &Arc<Mutex<Client>>, req: &mut Request) -> IronResult<Response> {
113 debug!("handler_remove() called");
114 let docid = req.extensions.get::<Router>().unwrap().find("docid").unwrap_or("");
115 let mut client = safe_client.lock().unwrap();
116
117 let mut payload = String::new();
118 let _ = req.body.read_to_string(&mut payload).unwrap();
119 let response = client.remove_sync(docid);
120 match response {
121 Ok(result) => {
122 let cas = result.cas.to_string();
123
124 let mut headers = Headers::new();
125 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
126 headers.set(ETag(EntityTag::new(false, cas.to_owned())));
127
128 let mut map = Map::new();
129 map.insert("meta".to_string(), get_meta(&cas, result.version));
130
131 let json = serde_json::to_string(&map).unwrap();
132
133 let mut response = Response::with((status::Ok, json));
134 response.headers = headers;
135 Ok(response)
136 },
137 Err(res) => {
138 let mut headers = Headers::new();
139 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
140
141 let json = serde_json::to_string(
142 &get_error(
143 client.instance,
144 &res.0.unwrap().rc
145 )
146 ).unwrap();
147
148 let mut response = Response::with((status::BadRequest, json));
149 response.headers = headers;
150 Ok(response)
151 }
152 }
153}
154
155pub fn handler_store(safe_client: &Arc<Mutex<Client>>, operation: Operation, req: &mut Request) -> IronResult<Response> {
156 let mut cas: u64 = 0;
157 let mut exptime: u32 = 0;
158
159let docid = req.extensions.get::<Router>().unwrap().find("docid").unwrap_or("");
179 let mut client = safe_client.lock().unwrap();
180
181 let mut payload = String::new();
182 let _ = req.body.read_to_string(&mut payload).unwrap();
183 let response = client.store_sync(docid, &payload[..], operation, cas, exptime);
184
185 match response {
186 Ok(result) => {
187 let cas = result.cas.to_string();
188
189 let mut headers = Headers::new();
190 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
191 headers.set(ETag(EntityTag::new(false, cas.to_owned())));
192
193 let mut map = Map::new();
194 map.insert("meta".to_string(), get_meta(&cas, result.version));
195
196 let json = serde_json::to_string(&map).unwrap();
197
198 let mut response = Response::with((status::Ok, json));
199 response.headers = headers;
200 Ok(response)
201 },
202 Err(res) => {
203 let mut headers = Headers::new();
204 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
205
206 let json = serde_json::to_string(
207 &get_error(
208 client.instance,
209 &res.0.unwrap().rc
210 )
211 ).unwrap();
212
213 let mut response = Response::with((status::BadRequest, json));
214 response.headers = headers;
215 Ok(response)
216 }
217 }
218}
219
220pub fn handler_query_view(safe_client: &Arc<Mutex<Client>>, req: &mut Request) -> IronResult<Response> {
221 let ddoc = req.extensions.get::<Router>().unwrap().find("ddoc").unwrap_or("");
222 let view = req.extensions.get::<Router>().unwrap().find("view").unwrap_or("");
223 let mut client = safe_client.lock().unwrap();
224
225 let response = client.query_view_sync(ddoc, view);
226 match response {
227 Err(res) => {
228 let mut headers = Headers::new();
229 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
230
231 let json = serde_json::to_string(
232 &get_error(
233 client.instance,
234 &res.0.unwrap().rc
235 )
236 ).unwrap();
237
238 let mut response = Response::with((status::BadRequest, json));
239 response.headers = headers;
240 Ok(response)
241 },
242 Ok(res) => {
243 let cas = res.cas.to_string();
244 let value = res.value.unwrap();
245
246 let mut headers = Headers::new();
247 headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![(Attr::Charset, Value::Utf8)])));
248 headers.set(ETag(EntityTag::new(false, cas.to_owned())));
249
250 let map = json!({
251 "meta": get_meta(&cas, res.version),
252 "doc": &value
253 });
254
255 let json = serde_json::to_string(&map).unwrap();
257
258 let mut response = Response::with((status::Ok, json));
259 response.headers = headers;
260 Ok(response)
261 }
262 }
263}
264
265#[allow(unused_mut)]
266#[allow(unused_must_use)]
267#[allow(unused_variables)]
268pub fn start_web(c: &Arc<Mutex<Client>>, port: u16) {
269 println!("Starting REST Interface on port {}.", port);
270
271 let mut router = Router::new();
272
273 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
275 let add_handler = move |req: &mut Request| -> IronResult<Response> {
276 handler_store(&handler_client, Operation::Add, req)
277 };
278
279 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
281 let append_handler = move |req: &mut Request| -> IronResult<Response> {
282 handler_store(&handler_client, Operation::Append, req)
283 };
284
285 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
287 let create_handler = move |req: &mut Request| -> IronResult<Response> {
288 handler_store(&handler_client, Operation::Upsert, req)
289 };
290
291 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
293 let get_handler = move |req: &mut Request| -> IronResult<Response> {
294 handler_get(&handler_client, req)
295 };
296
297 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
299 let prepend_handler = move |req: &mut Request| -> IronResult<Response> {
300 handler_store(&handler_client, Operation::Prepend, req)
301 };
302
303 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
305 let remove_handler = move |req: &mut Request| -> IronResult<Response> {
306 handler_remove(&handler_client, req)
307 };
308
309 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
311 let replace_handler = move |req: &mut Request| -> IronResult<Response> {
312 handler_store(&handler_client, Operation::Replace, req)
313 };
314
315 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
317 let set_handler = move |req: &mut Request| -> IronResult<Response> {
318 handler_store(&handler_client, Operation::Set, req)
319 };
320
321 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
323 let upsert_handler = move |req: &mut Request| -> IronResult<Response> {
324 handler_store(&handler_client, Operation::Upsert, req)
325 };
326
327 let handler_client = Arc::new(Mutex::new(c.lock().unwrap().clone()));
329 let query_view_handler = move |req: &mut Request| -> IronResult<Response> {
330 handler_query_view(&handler_client, req)
331 };
332
333 router.get("/bucket/:bucketid/doc/:docid", get_handler, "doc_get");
335 router.post("/bucket/:bucketid/doc/:docid", create_handler, "doc_insert");
336 router.post("/bucket/:bucketid/doc/:docid/add", add_handler, "doc_add");
337 router.post("/bucket/:bucketid/doc/:docid/append", append_handler, "doc_append");
338 router.post("/bucket/:bucketid/doc/:docid/prepend", prepend_handler, "doc_prepend");
339 router.delete("/bucket/:bucketid/doc/:docid", remove_handler, "doc_remove");
340 router.post("/bucket/:bucketid/doc/:docid/replace", replace_handler, "doc_replace");
341 router.post("/bucket/:bucketid/doc/:docid/set", set_handler , "doc_set");
342 router.post("/bucket/:bucketid/doc/:docid/upsert", upsert_handler, "doc_upsert");
343
344 router.get("/bucket/:bucketid/view/:ddoc/:view", query_view_handler, "query_view");
346
347 let address = format!("0.0.0.0:{}", port);
348 match Iron::new(router).http(&address[..]) {
349 Ok(_res) => {
350 },
352 Err(res) => {
353 println!("{:?}", res);
354 }
355 }
356}
357