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.ByteArrayInputStream;
24 import java.io.IOException;
25
26 import javax.xml.bind.JAXBContext;
27 import javax.xml.bind.JAXBException;
28 import javax.xml.bind.Unmarshaller;
29
30 import org.apache.hadoop.conf.Configuration;
31
32 import org.apache.hadoop.hbase.ClusterStatus;
33 import org.apache.hadoop.hbase.HTableDescriptor;
34 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
35 import org.apache.hadoop.hbase.rest.Constants;
36 import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
37 import org.apache.hadoop.hbase.rest.VersionResource;
38 import org.apache.hadoop.hbase.rest.model.StorageClusterStatusModel;
39 import org.apache.hadoop.hbase.rest.model.StorageClusterVersionModel;
40 import org.apache.hadoop.hbase.rest.model.TableListModel;
41 import org.apache.hadoop.hbase.rest.model.TableSchemaModel;
42 import org.apache.hadoop.hbase.rest.model.VersionModel;
43 import org.apache.hadoop.hbase.rest.protobuf.generated.StorageClusterStatusMessage.StorageClusterStatus;
44 import org.apache.hadoop.hbase.rest.protobuf.generated.TableListMessage;
45 import org.apache.hadoop.hbase.util.Bytes;
46 import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
47 import org.mortbay.jetty.MimeTypes;
48 import org.xml.sax.InputSource;
49
50 public class RemoteAdmin {
51
52 final Client client;
53 final Configuration conf;
54 final String accessToken;
55 final int maxRetries;
56 final long sleepTime;
57
58
59
60
61 private static volatile Unmarshaller versionClusterUnmarshaller;
62
63
64
65
66
67
68
69 public RemoteAdmin(Client client, Configuration conf) {
70 this(client, conf, null);
71 }
72
73 static Unmarshaller getUnmarsheller() throws JAXBException {
74
75 if (versionClusterUnmarshaller == null) {
76
77 RemoteAdmin.versionClusterUnmarshaller = JAXBContext.newInstance(
78 StorageClusterVersionModel.class).createUnmarshaller();
79 }
80 return RemoteAdmin.versionClusterUnmarshaller;
81 }
82
83
84
85
86
87
88
89 public RemoteAdmin(Client client, Configuration conf, String accessToken) {
90 this.client = client;
91 this.conf = conf;
92 this.accessToken = accessToken;
93 this.maxRetries = conf.getInt("hbase.rest.client.max.retries", 10);
94 this.sleepTime = conf.getLong("hbase.rest.client.sleep", 1000);
95 }
96
97
98
99
100
101
102 public boolean isTableAvailable(String tableName) throws IOException {
103 return isTableAvailable(Bytes.toBytes(tableName));
104 }
105
106
107
108
109
110
111
112 public VersionModel getRestVersion() throws IOException {
113
114 StringBuilder path = new StringBuilder();
115 path.append('/');
116 if (accessToken != null) {
117 path.append(accessToken);
118 path.append('/');
119 }
120
121 path.append("version/rest");
122
123 int code = 0;
124 for (int i = 0; i < maxRetries; i++) {
125 Response response = client.get(path.toString(),
126 Constants.MIMETYPE_PROTOBUF);
127 code = response.getCode();
128 switch (code) {
129 case 200:
130
131 VersionModel v = new VersionModel();
132 return (VersionModel) v.getObjectFromMessage(response.getBody());
133 case 404:
134 throw new IOException("REST version not found");
135 case 509:
136 try {
137 Thread.sleep(sleepTime);
138 } catch (InterruptedException e) {
139 }
140 break;
141 default:
142 throw new IOException("get request to " + path.toString()
143 + " returned " + code);
144 }
145 }
146 throw new IOException("get request to " + path.toString() + " timed out");
147 }
148
149
150
151
152
153 public StorageClusterStatusModel getClusterStatus() throws IOException {
154
155 StringBuilder path = new StringBuilder();
156 path.append('/');
157 if (accessToken !=null) {
158 path.append(accessToken);
159 path.append('/');
160 }
161
162 path.append("status/cluster");
163
164 int code = 0;
165 for (int i = 0; i < maxRetries; i++) {
166 Response response = client.get(path.toString(),
167 Constants.MIMETYPE_PROTOBUF);
168 code = response.getCode();
169 switch (code) {
170 case 200:
171 StorageClusterStatusModel s = new StorageClusterStatusModel();
172 return (StorageClusterStatusModel) s.getObjectFromMessage(response
173 .getBody());
174 case 404:
175 throw new IOException("Cluster version not found");
176 case 509:
177 try {
178 Thread.sleep(sleepTime);
179 } catch (InterruptedException e) {
180 }
181 break;
182 default:
183 throw new IOException("get request to " + path + " returned " + code);
184 }
185 }
186 throw new IOException("get request to " + path + " timed out");
187 }
188
189
190
191
192
193
194
195 public StorageClusterVersionModel getClusterVersion() throws IOException {
196
197 StringBuilder path = new StringBuilder();
198 path.append('/');
199 if (accessToken != null) {
200 path.append(accessToken);
201 path.append('/');
202 }
203
204 path.append("version/cluster");
205
206 int code = 0;
207 for (int i = 0; i < maxRetries; i++) {
208 Response response = client.get(path.toString(), Constants.MIMETYPE_XML);
209 code = response.getCode();
210 switch (code) {
211 case 200:
212 try {
213
214 return (StorageClusterVersionModel) getUnmarsheller().unmarshal(
215 new ByteArrayInputStream(response.getBody()));
216 } catch (JAXBException jaxbe) {
217
218 throw new IOException(
219 "Issue parsing StorageClusterVersionModel object in XML form: "
220 + jaxbe.getLocalizedMessage());
221 }
222 case 404:
223 throw new IOException("Cluster version not found");
224 case 509:
225 try {
226 Thread.sleep(sleepTime);
227 } catch (InterruptedException e) {
228 }
229 break;
230 default:
231 throw new IOException(path.toString() + " request returned " + code);
232 }
233 }
234 throw new IOException("get request to " + path.toString()
235 + " request timed out");
236 }
237
238
239
240
241
242
243 public boolean isTableAvailable(byte[] tableName) throws IOException {
244 StringBuilder path = new StringBuilder();
245 path.append('/');
246 if (accessToken != null) {
247 path.append(accessToken);
248 path.append('/');
249 }
250 path.append(Bytes.toStringBinary(tableName));
251 path.append('/');
252 path.append("exists");
253 int code = 0;
254 for (int i = 0; i < maxRetries; i++) {
255 Response response = client.get(path.toString(), Constants.MIMETYPE_PROTOBUF);
256 code = response.getCode();
257 switch (code) {
258 case 200:
259 return true;
260 case 404:
261 return false;
262 case 509:
263 try {
264 Thread.sleep(sleepTime);
265 } catch (InterruptedException e) { }
266 break;
267 default:
268 throw new IOException("get request to " + path.toString() + " returned " + code);
269 }
270 }
271 throw new IOException("get request to " + path.toString() + " timed out");
272 }
273
274
275
276
277
278
279 public void createTable(HTableDescriptor desc)
280 throws IOException {
281 TableSchemaModel model = new TableSchemaModel(desc);
282 StringBuilder path = new StringBuilder();
283 path.append('/');
284 if (accessToken != null) {
285 path.append(accessToken);
286 path.append('/');
287 }
288 path.append(Bytes.toStringBinary(desc.getName()));
289 path.append('/');
290 path.append("schema");
291 int code = 0;
292 for (int i = 0; i < maxRetries; i++) {
293 Response response = client.put(path.toString(), Constants.MIMETYPE_PROTOBUF,
294 model.createProtobufOutput());
295 code = response.getCode();
296 switch (code) {
297 case 201:
298 return;
299 case 509:
300 try {
301 Thread.sleep(sleepTime);
302 } catch (InterruptedException e) { }
303 break;
304 default:
305 throw new IOException("create request to " + path.toString() + " returned " + code);
306 }
307 }
308 throw new IOException("create request to " + path.toString() + " timed out");
309 }
310
311
312
313
314
315
316 public void deleteTable(final String tableName) throws IOException {
317 deleteTable(Bytes.toBytes(tableName));
318 }
319
320
321
322
323
324
325 public void deleteTable(final byte [] tableName) throws IOException {
326 StringBuilder path = new StringBuilder();
327 path.append('/');
328 if (accessToken != null) {
329 path.append(accessToken);
330 path.append('/');
331 }
332 path.append(Bytes.toStringBinary(tableName));
333 path.append('/');
334 path.append("schema");
335 int code = 0;
336 for (int i = 0; i < maxRetries; i++) {
337 Response response = client.delete(path.toString());
338 code = response.getCode();
339 switch (code) {
340 case 200:
341 return;
342 case 509:
343 try {
344 Thread.sleep(sleepTime);
345 } catch (InterruptedException e) { }
346 break;
347 default:
348 throw new IOException("delete request to " + path.toString() + " returned " + code);
349 }
350 }
351 throw new IOException("delete request to " + path.toString() + " timed out");
352 }
353
354
355
356
357
358
359
360 public TableListModel getTableList() throws IOException {
361
362 StringBuilder path = new StringBuilder();
363 path.append('/');
364 if (accessToken != null) {
365 path.append(accessToken);
366 path.append('/');
367 }
368
369 int code = 0;
370 for (int i = 0; i < maxRetries; i++) {
371
372
373 Response response = client.get(path.toString(),
374 Constants.MIMETYPE_PROTOBUF);
375 code = response.getCode();
376 switch (code) {
377 case 200:
378 TableListModel t = new TableListModel();
379 return (TableListModel) t.getObjectFromMessage(response.getBody());
380 case 404:
381 throw new IOException("Table list not found");
382 case 509:
383 try {
384 Thread.sleep(sleepTime);
385 } catch (InterruptedException e) {
386 }
387 break;
388 default:
389 throw new IOException("get request to " + path.toString()
390 + " request returned " + code);
391 }
392 }
393 throw new IOException("get request to " + path.toString()
394 + " request timed out");
395 }
396 }