1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.rest.client;
22
23 import java.io.IOException;
24 import java.util.Collections;
25 import java.util.Map;
26 import java.util.concurrent.ConcurrentHashMap;
27
28 import org.apache.commons.httpclient.Header;
29 import org.apache.commons.httpclient.HttpClient;
30 import org.apache.commons.httpclient.HttpMethod;
31 import org.apache.commons.httpclient.HttpVersion;
32 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
33 import org.apache.commons.httpclient.URI;
34 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
35 import org.apache.commons.httpclient.methods.DeleteMethod;
36 import org.apache.commons.httpclient.methods.GetMethod;
37 import org.apache.commons.httpclient.methods.HeadMethod;
38 import org.apache.commons.httpclient.methods.PostMethod;
39 import org.apache.commons.httpclient.methods.PutMethod;
40 import org.apache.commons.httpclient.params.HttpClientParams;
41 import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44
45
46
47
48
49 public class Client {
50 public static final Header[] EMPTY_HEADER_ARRAY = new Header[0];
51
52 private static final Log LOG = LogFactory.getLog(Client.class);
53
54 private HttpClient httpClient;
55 private Cluster cluster;
56
57 private Map<String, String> extraHeaders;
58
59
60
61
62 public Client() {
63 this(null);
64 }
65
66
67
68
69
70 public Client(Cluster cluster) {
71 this.cluster = cluster;
72 MultiThreadedHttpConnectionManager manager =
73 new MultiThreadedHttpConnectionManager();
74 HttpConnectionManagerParams managerParams = manager.getParams();
75 managerParams.setConnectionTimeout(2000);
76 managerParams.setDefaultMaxConnectionsPerHost(10);
77 managerParams.setMaxTotalConnections(100);
78 extraHeaders = new ConcurrentHashMap<String, String>();
79 this.httpClient = new HttpClient(manager);
80 HttpClientParams clientParams = httpClient.getParams();
81 clientParams.setVersion(HttpVersion.HTTP_1_1);
82 }
83
84
85
86
87 public void shutdown() {
88 MultiThreadedHttpConnectionManager manager =
89 (MultiThreadedHttpConnectionManager) httpClient.getHttpConnectionManager();
90 manager.shutdown();
91 }
92
93
94
95
96 public HttpClient getHttpClient() {
97 return httpClient;
98 }
99
100
101
102
103
104
105 public void addExtraHeader(final String name, final String value) {
106 extraHeaders.put(name, value);
107 }
108
109
110
111
112 public String getExtraHeader(final String name) {
113 return extraHeaders.get(name);
114 }
115
116
117
118
119 public Map<String, String> getExtraHeaders() {
120 return Collections.unmodifiableMap(extraHeaders);
121 }
122
123
124
125
126 public void removeExtraHeader(final String name) {
127 extraHeaders.remove(name);
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public int executePathOnly(Cluster cluster, HttpMethod method,
144 Header[] headers, String path) throws IOException {
145 IOException lastException;
146 if (cluster.nodes.size() < 1) {
147 throw new IOException("Cluster is empty");
148 }
149 int start = (int)Math.round((cluster.nodes.size() - 1) * Math.random());
150 int i = start;
151 do {
152 cluster.lastHost = cluster.nodes.get(i);
153 try {
154 StringBuilder sb = new StringBuilder();
155 sb.append("http://");
156 sb.append(cluster.lastHost);
157 sb.append(path);
158 URI uri = new URI(sb.toString(), true);
159 return executeURI(method, headers, uri.toString());
160 } catch (IOException e) {
161 lastException = e;
162 }
163 } while (++i != start && i < cluster.nodes.size());
164 throw lastException;
165 }
166
167
168
169
170
171
172
173
174
175 public int executeURI(HttpMethod method, Header[] headers, String uri)
176 throws IOException {
177 method.setURI(new URI(uri, true));
178 for (Map.Entry<String, String> e: extraHeaders.entrySet()) {
179 method.addRequestHeader(e.getKey(), e.getValue());
180 }
181 if (headers != null) {
182 for (Header header: headers) {
183 method.addRequestHeader(header);
184 }
185 }
186 long startTime = System.currentTimeMillis();
187 int code = httpClient.executeMethod(method);
188 long endTime = System.currentTimeMillis();
189 if (LOG.isDebugEnabled()) {
190 LOG.debug(method.getName() + " " + uri + " " + code + " " +
191 method.getStatusText() + " in " + (endTime - startTime) + " ms");
192 }
193 return code;
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207 public int execute(Cluster cluster, HttpMethod method, Header[] headers,
208 String path) throws IOException {
209 if (path.startsWith("/")) {
210 return executePathOnly(cluster, method, headers, path);
211 }
212 return executeURI(method, headers, path);
213 }
214
215
216
217
218 public Cluster getCluster() {
219 return cluster;
220 }
221
222
223
224
225 public void setCluster(Cluster cluster) {
226 this.cluster = cluster;
227 }
228
229
230
231
232
233
234
235 public Response head(String path) throws IOException {
236 return head(cluster, path, null);
237 }
238
239
240
241
242
243
244
245
246
247 public Response head(Cluster cluster, String path, Header[] headers)
248 throws IOException {
249 HeadMethod method = new HeadMethod();
250 try {
251 int code = execute(cluster, method, null, path);
252 headers = method.getResponseHeaders();
253 return new Response(code, headers, null);
254 } finally {
255 method.releaseConnection();
256 }
257 }
258
259
260
261
262
263
264
265 public Response get(String path) throws IOException {
266 return get(cluster, path);
267 }
268
269
270
271
272
273
274
275
276 public Response get(Cluster cluster, String path) throws IOException {
277 return get(cluster, path, EMPTY_HEADER_ARRAY);
278 }
279
280
281
282
283
284
285
286
287 public Response get(String path, String accept) throws IOException {
288 return get(cluster, path, accept);
289 }
290
291
292
293
294
295
296
297
298
299 public Response get(Cluster cluster, String path, String accept)
300 throws IOException {
301 Header[] headers = new Header[1];
302 headers[0] = new Header("Accept", accept);
303 return get(cluster, path, headers);
304 }
305
306
307
308
309
310
311
312
313
314 public Response get(String path, Header[] headers) throws IOException {
315 return get(cluster, path, headers);
316 }
317
318
319
320
321
322
323
324
325
326 public Response get(Cluster c, String path, Header[] headers)
327 throws IOException {
328 GetMethod method = new GetMethod();
329 try {
330 int code = execute(c, method, headers, path);
331 headers = method.getResponseHeaders();
332 byte[] body = method.getResponseBody();
333 return new Response(code, headers, body);
334 } finally {
335 method.releaseConnection();
336 }
337 }
338
339
340
341
342
343
344
345
346
347 public Response put(String path, String contentType, byte[] content)
348 throws IOException {
349 return put(cluster, path, contentType, content);
350 }
351
352
353
354
355
356
357
358
359
360
361 public Response put(Cluster cluster, String path, String contentType,
362 byte[] content) throws IOException {
363 Header[] headers = new Header[1];
364 headers[0] = new Header("Content-Type", contentType);
365 return put(cluster, path, headers, content);
366 }
367
368
369
370
371
372
373
374
375
376
377 public Response put(String path, Header[] headers, byte[] content)
378 throws IOException {
379 return put(cluster, path, headers, content);
380 }
381
382
383
384
385
386
387
388
389
390
391
392 public Response put(Cluster cluster, String path, Header[] headers,
393 byte[] content) throws IOException {
394 PutMethod method = new PutMethod();
395 try {
396 method.setRequestEntity(new ByteArrayRequestEntity(content));
397 int code = execute(cluster, method, headers, path);
398 headers = method.getResponseHeaders();
399 content = method.getResponseBody();
400 return new Response(code, headers, content);
401 } finally {
402 method.releaseConnection();
403 }
404 }
405
406
407
408
409
410
411
412
413
414 public Response post(String path, String contentType, byte[] content)
415 throws IOException {
416 return post(cluster, path, contentType, content);
417 }
418
419
420
421
422
423
424
425
426
427
428 public Response post(Cluster cluster, String path, String contentType,
429 byte[] content) throws IOException {
430 Header[] headers = new Header[1];
431 headers[0] = new Header("Content-Type", contentType);
432 return post(cluster, path, headers, content);
433 }
434
435
436
437
438
439
440
441
442
443
444 public Response post(String path, Header[] headers, byte[] content)
445 throws IOException {
446 return post(cluster, path, headers, content);
447 }
448
449
450
451
452
453
454
455
456
457
458
459 public Response post(Cluster cluster, String path, Header[] headers,
460 byte[] content) throws IOException {
461 PostMethod method = new PostMethod();
462 try {
463 method.setRequestEntity(new ByteArrayRequestEntity(content));
464 int code = execute(cluster, method, headers, path);
465 headers = method.getResponseHeaders();
466 content = method.getResponseBody();
467 return new Response(code, headers, content);
468 } finally {
469 method.releaseConnection();
470 }
471 }
472
473
474
475
476
477
478
479 public Response delete(String path) throws IOException {
480 return delete(cluster, path);
481 }
482
483
484
485
486
487
488
489
490 public Response delete(Cluster cluster, String path) throws IOException {
491 DeleteMethod method = new DeleteMethod();
492 try {
493 int code = execute(cluster, method, null, path);
494 Header[] headers = method.getResponseHeaders();
495 byte[] content = method.getResponseBody();
496 return new Response(code, headers, content);
497 } finally {
498 method.releaseConnection();
499 }
500 }
501 }