1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.rest;
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.ByteArrayInputStream;
26 import java.io.IOException;
27 import java.io.StringWriter;
28 import java.net.URLEncoder;
29 import java.util.List;
30
31 import javax.xml.bind.JAXBContext;
32 import javax.xml.bind.JAXBException;
33 import javax.xml.bind.Marshaller;
34 import javax.xml.bind.Unmarshaller;
35
36 import org.apache.commons.httpclient.Header;
37 import org.apache.hadoop.conf.Configuration;
38 import org.apache.hadoop.hbase.CompatibilityFactory;
39 import org.apache.hadoop.hbase.HBaseTestingUtility;
40 import org.apache.hadoop.hbase.HColumnDescriptor;
41 import org.apache.hadoop.hbase.HConstants;
42 import org.apache.hadoop.hbase.HTableDescriptor;
43 import org.apache.hadoop.hbase.MediumTests;
44 import org.apache.hadoop.hbase.TableName;
45 import org.apache.hadoop.hbase.client.HBaseAdmin;
46 import org.apache.hadoop.hbase.rest.client.Client;
47 import org.apache.hadoop.hbase.rest.client.Cluster;
48 import org.apache.hadoop.hbase.rest.client.Response;
49 import org.apache.hadoop.hbase.rest.model.CellModel;
50 import org.apache.hadoop.hbase.rest.model.CellSetModel;
51 import org.apache.hadoop.hbase.rest.model.RowModel;
52 import org.apache.hadoop.hbase.security.User;
53 import org.apache.hadoop.hbase.test.MetricsAssertHelper;
54 import org.apache.hadoop.hbase.util.Bytes;
55 import org.apache.hadoop.security.UserGroupInformation;
56 import org.junit.After;
57 import org.junit.AfterClass;
58 import org.junit.Before;
59 import org.junit.BeforeClass;
60 import org.junit.Test;
61 import org.junit.experimental.categories.Category;
62
63 @Category(MediumTests.class)
64 public class TestRowResource {
65 private static final String TABLE = "TestRowResource";
66 private static final String CFA = "a";
67 private static final String CFB = "b";
68 private static final String COLUMN_1 = CFA + ":1";
69 private static final String COLUMN_2 = CFB + ":2";
70 private static final String COLUMN_3 = CFA + ":";
71 private static final String ROW_1 = "testrow1";
72 private static final String VALUE_1 = "testvalue1";
73 private static final String ROW_2 = "testrow2";
74 private static final String VALUE_2 = "testvalue2";
75 private static final String ROW_3 = "testrow3";
76 private static final String VALUE_3 = "testvalue3";
77 private static final String ROW_4 = "testrow4";
78 private static final String VALUE_4 = "testvalue4";
79
80 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
81 private static final HBaseRESTTestingUtility REST_TEST_UTIL =
82 new HBaseRESTTestingUtility();
83 private static final MetricsAssertHelper METRICS_ASSERT =
84 CompatibilityFactory.getInstance(MetricsAssertHelper.class);
85 private static Client client;
86 private static JAXBContext context;
87 private static Marshaller marshaller;
88 private static Unmarshaller unmarshaller;
89 private static Configuration conf;
90
91 @BeforeClass
92 public static void setUpBeforeClass() throws Exception {
93 conf = TEST_UTIL.getConfiguration();
94 TEST_UTIL.startMiniCluster(3);
95 REST_TEST_UTIL.startServletContainer(conf);
96 context = JAXBContext.newInstance(
97 CellModel.class,
98 CellSetModel.class,
99 RowModel.class);
100 marshaller = context.createMarshaller();
101 unmarshaller = context.createUnmarshaller();
102 client = new Client(new Cluster().add("localhost",
103 REST_TEST_UTIL.getServletPort()));
104 }
105
106 @Before
107 public void beforeMethod() throws Exception {
108 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
109 if (admin.tableExists(TABLE)) {
110 return;
111 }
112 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLE));
113 htd.addFamily(new HColumnDescriptor(CFA));
114 htd.addFamily(new HColumnDescriptor(CFB));
115 admin.createTable(htd);
116 }
117
118 @After
119 public void afterMethod() throws Exception {
120 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
121 if (admin.tableExists(TABLE)) {
122 admin.disableTable(TABLE);
123 admin.deleteTable(TABLE);
124 }
125 }
126
127 @AfterClass
128 public static void tearDownAfterClass() throws Exception {
129 REST_TEST_UTIL.shutdownServletContainer();
130 TEST_UTIL.shutdownMiniCluster();
131 }
132
133 private static Response deleteRow(String table, String row)
134 throws IOException {
135 StringBuilder path = new StringBuilder();
136 path.append('/');
137 path.append(table);
138 path.append('/');
139 path.append(row);
140 Response response = client.delete(path.toString());
141 Thread.yield();
142 return response;
143 }
144
145 private static Response deleteValue(String table, String row, String column)
146 throws IOException {
147 StringBuilder path = new StringBuilder();
148 path.append('/');
149 path.append(table);
150 path.append('/');
151 path.append(row);
152 path.append('/');
153 path.append(column);
154 Response response = client.delete(path.toString());
155 Thread.yield();
156 return response;
157 }
158
159 private static Response getValueXML(String table, String row, String column)
160 throws IOException {
161 StringBuilder path = new StringBuilder();
162 path.append('/');
163 path.append(table);
164 path.append('/');
165 path.append(row);
166 path.append('/');
167 path.append(column);
168 return getValueXML(path.toString());
169 }
170
171 private static Response getValueXML(String table, String startRow,
172 String endRow, String column) throws IOException {
173 StringBuilder path = new StringBuilder();
174 path.append('/');
175 path.append(table);
176 path.append('/');
177 path.append(startRow);
178 path.append(",");
179 path.append(endRow);
180 path.append('/');
181 path.append(column);
182 return getValueXML(path.toString());
183 }
184
185 private static Response getValueXML(String url) throws IOException {
186 Response response = client.get(url, Constants.MIMETYPE_XML);
187 return response;
188 }
189
190 private static Response getValuePB(String table, String row, String column)
191 throws IOException {
192 StringBuilder path = new StringBuilder();
193 path.append('/');
194 path.append(table);
195 path.append('/');
196 path.append(row);
197 path.append('/');
198 path.append(column);
199 return getValuePB(path.toString());
200 }
201
202 private static Response getValuePB(String url) throws IOException {
203 Response response = client.get(url, Constants.MIMETYPE_PROTOBUF);
204 return response;
205 }
206
207 private static Response putValueXML(String table, String row, String column,
208 String value) throws IOException, JAXBException {
209 StringBuilder path = new StringBuilder();
210 path.append('/');
211 path.append(table);
212 path.append('/');
213 path.append(row);
214 path.append('/');
215 path.append(column);
216 return putValueXML(path.toString(), table, row, column, value);
217 }
218
219 private static Response putValueXML(String url, String table, String row,
220 String column, String value) throws IOException, JAXBException {
221 RowModel rowModel = new RowModel(row);
222 rowModel.addCell(new CellModel(Bytes.toBytes(column),
223 Bytes.toBytes(value)));
224 CellSetModel cellSetModel = new CellSetModel();
225 cellSetModel.addRow(rowModel);
226 StringWriter writer = new StringWriter();
227 marshaller.marshal(cellSetModel, writer);
228 Response response = client.put(url, Constants.MIMETYPE_XML,
229 Bytes.toBytes(writer.toString()));
230 Thread.yield();
231 return response;
232 }
233
234 private static void checkValueXML(String table, String row, String column,
235 String value) throws IOException, JAXBException {
236 Response response = getValueXML(table, row, column);
237 assertEquals(response.getCode(), 200);
238 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
239 CellSetModel cellSet = (CellSetModel)
240 unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
241 RowModel rowModel = cellSet.getRows().get(0);
242 CellModel cell = rowModel.getCells().get(0);
243 assertEquals(Bytes.toString(cell.getColumn()), column);
244 assertEquals(Bytes.toString(cell.getValue()), value);
245 }
246
247 private static void checkValueXML(String url, String table, String row,
248 String column, String value) throws IOException, JAXBException {
249 Response response = getValueXML(url);
250 assertEquals(response.getCode(), 200);
251 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
252 CellSetModel cellSet = (CellSetModel)
253 unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
254 RowModel rowModel = cellSet.getRows().get(0);
255 CellModel cell = rowModel.getCells().get(0);
256 assertEquals(Bytes.toString(cell.getColumn()), column);
257 assertEquals(Bytes.toString(cell.getValue()), value);
258 }
259
260 private static Response putValuePB(String table, String row, String column,
261 String value) throws IOException {
262 StringBuilder path = new StringBuilder();
263 path.append('/');
264 path.append(table);
265 path.append('/');
266 path.append(row);
267 path.append('/');
268 path.append(column);
269 return putValuePB(path.toString(), table, row, column, value);
270 }
271
272 private static Response putValuePB(String url, String table, String row,
273 String column, String value) throws IOException {
274 RowModel rowModel = new RowModel(row);
275 rowModel.addCell(new CellModel(Bytes.toBytes(column),
276 Bytes.toBytes(value)));
277 CellSetModel cellSetModel = new CellSetModel();
278 cellSetModel.addRow(rowModel);
279 Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
280 cellSetModel.createProtobufOutput());
281 Thread.yield();
282 return response;
283 }
284
285 private static void checkValuePB(String table, String row, String column,
286 String value) throws IOException {
287 Response response = getValuePB(table, row, column);
288 assertEquals(response.getCode(), 200);
289 assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
290 CellSetModel cellSet = new CellSetModel();
291 cellSet.getObjectFromMessage(response.getBody());
292 RowModel rowModel = cellSet.getRows().get(0);
293 CellModel cell = rowModel.getCells().get(0);
294 assertEquals(Bytes.toString(cell.getColumn()), column);
295 assertEquals(Bytes.toString(cell.getValue()), value);
296 }
297
298 private static Response checkAndPutValuePB(String url, String table,
299 String row, String column, String valueToCheck, String valueToPut)
300 throws IOException {
301 RowModel rowModel = new RowModel(row);
302 rowModel.addCell(new CellModel(Bytes.toBytes(column),
303 Bytes.toBytes(valueToPut)));
304 rowModel.addCell(new CellModel(Bytes.toBytes(column),
305 Bytes.toBytes(valueToCheck)));
306 CellSetModel cellSetModel = new CellSetModel();
307 cellSetModel.addRow(rowModel);
308 Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
309 cellSetModel.createProtobufOutput());
310 Thread.yield();
311 return response;
312 }
313
314 private static Response checkAndPutValuePB(String table, String row,
315 String column, String valueToCheck, String valueToPut) throws IOException {
316 StringBuilder path = new StringBuilder();
317 path.append('/');
318 path.append(table);
319 path.append('/');
320 path.append(row);
321 path.append("?check=put");
322 return checkAndPutValuePB(path.toString(), table, row, column,
323 valueToCheck, valueToPut);
324 }
325
326 private static Response checkAndPutValueXML(String url, String table,
327 String row, String column, String valueToCheck, String valueToPut)
328 throws IOException, JAXBException {
329 RowModel rowModel = new RowModel(row);
330 rowModel.addCell(new CellModel(Bytes.toBytes(column),
331 Bytes.toBytes(valueToPut)));
332 rowModel.addCell(new CellModel(Bytes.toBytes(column),
333 Bytes.toBytes(valueToCheck)));
334 CellSetModel cellSetModel = new CellSetModel();
335 cellSetModel.addRow(rowModel);
336 StringWriter writer = new StringWriter();
337 marshaller.marshal(cellSetModel, writer);
338 Response response = client.put(url, Constants.MIMETYPE_XML,
339 Bytes.toBytes(writer.toString()));
340 Thread.yield();
341 return response;
342 }
343
344 private static Response checkAndPutValueXML(String table, String row,
345 String column, String valueToCheck, String valueToPut)
346 throws IOException, JAXBException {
347 StringBuilder path = new StringBuilder();
348 path.append('/');
349 path.append(table);
350 path.append('/');
351 path.append(row);
352 path.append("?check=put");
353 return checkAndPutValueXML(path.toString(), table, row, column,
354 valueToCheck, valueToPut);
355 }
356
357 private static Response checkAndDeleteXML(String url, String table,
358 String row, String column, String valueToCheck)
359 throws IOException, JAXBException {
360 RowModel rowModel = new RowModel(row);
361 rowModel.addCell(new CellModel(Bytes.toBytes(column),
362 Bytes.toBytes(valueToCheck)));
363 CellSetModel cellSetModel = new CellSetModel();
364 cellSetModel.addRow(rowModel);
365 StringWriter writer = new StringWriter();
366 marshaller.marshal(cellSetModel, writer);
367 Response response = client.put(url, Constants.MIMETYPE_XML,
368 Bytes.toBytes(writer.toString()));
369 Thread.yield();
370 return response;
371 }
372
373 private static Response checkAndDeleteXML(String table, String row,
374 String column, String valueToCheck) throws IOException, JAXBException {
375 StringBuilder path = new StringBuilder();
376 path.append('/');
377 path.append(table);
378 path.append('/');
379 path.append(row);
380 path.append("?check=delete");
381 return checkAndDeleteXML(path.toString(), table, row, column, valueToCheck);
382 }
383
384 private static Response checkAndDeletePB(String table, String row,
385 String column, String value) throws IOException {
386 StringBuilder path = new StringBuilder();
387 path.append('/');
388 path.append(table);
389 path.append('/');
390 path.append(row);
391 path.append("?check=delete");
392 return checkAndDeleteValuePB(path.toString(), table, row, column, value);
393 }
394
395 private static Response checkAndDeleteValuePB(String url, String table,
396 String row, String column, String valueToCheck)
397 throws IOException {
398 RowModel rowModel = new RowModel(row);
399 rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes
400 .toBytes(valueToCheck)));
401 CellSetModel cellSetModel = new CellSetModel();
402 cellSetModel.addRow(rowModel);
403 Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
404 cellSetModel.createProtobufOutput());
405 Thread.yield();
406 return response;
407 }
408
409 @Test
410 public void testDelete() throws IOException, JAXBException {
411 Response response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
412 assertEquals(response.getCode(), 200);
413 response = putValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
414 assertEquals(response.getCode(), 200);
415 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
416 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
417
418 response = deleteValue(TABLE, ROW_1, COLUMN_1);
419 assertEquals(response.getCode(), 200);
420 response = getValueXML(TABLE, ROW_1, COLUMN_1);
421 assertEquals(response.getCode(), 404);
422 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
423
424 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
425 assertEquals(response.getCode(), 200);
426 response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
427 assertEquals(response.getCode(), 200);
428 response = getValueXML(TABLE, ROW_1, COLUMN_1);
429 assertEquals(response.getCode(), 404);
430
431 response = deleteRow(TABLE, ROW_1);
432 assertEquals(response.getCode(), 200);
433 response = getValueXML(TABLE, ROW_1, COLUMN_1);
434 assertEquals(response.getCode(), 404);
435 response = getValueXML(TABLE, ROW_1, COLUMN_2);
436 assertEquals(response.getCode(), 404);
437 }
438
439 @Test
440 public void testForbidden() throws IOException, JAXBException {
441 conf.set("hbase.rest.readonly", "true");
442
443 Response response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
444 assertEquals(response.getCode(), 403);
445 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
446 assertEquals(response.getCode(), 403);
447 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2);
448 assertEquals(response.getCode(), 403);
449 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2);
450 assertEquals(response.getCode(), 403);
451 response = deleteValue(TABLE, ROW_1, COLUMN_1);
452 assertEquals(response.getCode(), 403);
453 response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
454 assertEquals(response.getCode(), 403);
455 response = deleteRow(TABLE, ROW_1);
456 assertEquals(response.getCode(), 403);
457
458 conf.set("hbase.rest.readonly", "false");
459
460 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
461 assertEquals(response.getCode(), 200);
462 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
463 assertEquals(response.getCode(), 200);
464 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2);
465 assertEquals(response.getCode(), 200);
466 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2, VALUE_3);
467 assertEquals(response.getCode(), 200);
468 response = deleteValue(TABLE, ROW_1, COLUMN_1);
469 assertEquals(response.getCode(), 200);
470 response = deleteRow(TABLE, ROW_1);
471 assertEquals(response.getCode(), 200);
472 }
473
474 @Test
475 public void testSingleCellGetPutXML() throws IOException, JAXBException {
476 Response response = getValueXML(TABLE, ROW_1, COLUMN_1);
477 assertEquals(response.getCode(), 404);
478
479 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
480 assertEquals(response.getCode(), 200);
481 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
482 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2);
483 assertEquals(response.getCode(), 200);
484 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2);
485 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2, VALUE_3);
486 assertEquals(response.getCode(), 200);
487 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3);
488 response = checkAndDeleteXML(TABLE, ROW_1, COLUMN_1, VALUE_3);
489 assertEquals(response.getCode(), 200);
490
491 response = deleteRow(TABLE, ROW_1);
492 assertEquals(response.getCode(), 200);
493 }
494
495 @Test
496 public void testSingleCellGetPutPB() throws IOException, JAXBException {
497 Response response = getValuePB(TABLE, ROW_1, COLUMN_1);
498 assertEquals(response.getCode(), 404);
499
500 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
501 assertEquals(response.getCode(), 200);
502 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
503
504 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
505 assertEquals(response.getCode(), 200);
506 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
507 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2);
508 assertEquals(response.getCode(), 200);
509 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2);
510
511 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2, VALUE_3);
512 assertEquals(response.getCode(), 200);
513 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_3);
514 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3, VALUE_4);
515 assertEquals(response.getCode(), 200);
516 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_4);
517
518 response = deleteRow(TABLE, ROW_1);
519 assertEquals(response.getCode(), 200);
520 }
521
522 @Test
523 public void testSingleCellGetPutBinary() throws IOException {
524 final String path = "/" + TABLE + "/" + ROW_3 + "/" + COLUMN_1;
525 final byte[] body = Bytes.toBytes(VALUE_3);
526 Response response = client.put(path, Constants.MIMETYPE_BINARY, body);
527 assertEquals(response.getCode(), 200);
528 Thread.yield();
529
530 response = client.get(path, Constants.MIMETYPE_BINARY);
531 assertEquals(response.getCode(), 200);
532 assertEquals(Constants.MIMETYPE_BINARY, response.getHeader("content-type"));
533 assertTrue(Bytes.equals(response.getBody(), body));
534 boolean foundTimestampHeader = false;
535 for (Header header: response.getHeaders()) {
536 if (header.getName().equals("X-Timestamp")) {
537 foundTimestampHeader = true;
538 break;
539 }
540 }
541 assertTrue(foundTimestampHeader);
542
543 response = deleteRow(TABLE, ROW_3);
544 assertEquals(response.getCode(), 200);
545 }
546
547 @Test
548 public void testSingleCellGetJSON() throws IOException, JAXBException {
549 final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1;
550 Response response = client.put(path, Constants.MIMETYPE_BINARY,
551 Bytes.toBytes(VALUE_4));
552 assertEquals(response.getCode(), 200);
553 Thread.yield();
554 response = client.get(path, Constants.MIMETYPE_JSON);
555 assertEquals(response.getCode(), 200);
556 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
557 response = deleteRow(TABLE, ROW_4);
558 assertEquals(response.getCode(), 200);
559 }
560
561 @Test
562 public void testMetrics() throws IOException, JAXBException {
563 final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1;
564 Response response = client.put(path, Constants.MIMETYPE_BINARY,
565 Bytes.toBytes(VALUE_4));
566 assertEquals(response.getCode(), 200);
567 Thread.yield();
568 response = client.get(path, Constants.MIMETYPE_JSON);
569 assertEquals(response.getCode(), 200);
570 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
571 response = deleteRow(TABLE, ROW_4);
572 assertEquals(response.getCode(), 200);
573
574 UserGroupInformation ugi = User.getCurrent().getUGI();
575 METRICS_ASSERT.assertCounterGt("requests", 2l,
576 RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
577
578 METRICS_ASSERT.assertCounterGt("successfulGet", 0l,
579 RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
580
581 METRICS_ASSERT.assertCounterGt("successfulPut", 0l,
582 RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
583
584 METRICS_ASSERT.assertCounterGt("successfulDelete", 0l,
585 RESTServlet.getInstance(conf, ugi).getMetrics().getSource());
586 }
587
588 @Test
589 public void testURLEncodedKey() throws IOException, JAXBException {
590 String urlKey = "http://example.com/foo";
591 StringBuilder path = new StringBuilder();
592 path.append('/');
593 path.append(TABLE);
594 path.append('/');
595 path.append(URLEncoder.encode(urlKey, HConstants.UTF8_ENCODING));
596 path.append('/');
597 path.append(COLUMN_1);
598 Response response;
599 response = putValueXML(path.toString(), TABLE, urlKey, COLUMN_1,
600 VALUE_1);
601 assertEquals(response.getCode(), 200);
602 checkValueXML(path.toString(), TABLE, urlKey, COLUMN_1, VALUE_1);
603 }
604
605 @Test
606 public void testNoSuchCF() throws IOException, JAXBException {
607 final String goodPath = "/" + TABLE + "/" + ROW_1 + "/" + CFA+":";
608 final String badPath = "/" + TABLE + "/" + ROW_1 + "/" + "BAD";
609 Response response = client.post(goodPath, Constants.MIMETYPE_BINARY,
610 Bytes.toBytes(VALUE_1));
611 assertEquals(response.getCode(), 200);
612 assertEquals(client.get(goodPath, Constants.MIMETYPE_BINARY).getCode(),
613 200);
614 assertEquals(client.get(badPath, Constants.MIMETYPE_BINARY).getCode(),
615 404);
616 assertEquals(client.get(goodPath, Constants.MIMETYPE_BINARY).getCode(),
617 200);
618 }
619
620 @Test
621 public void testMultiCellGetPutXML() throws IOException, JAXBException {
622 String path = "/" + TABLE + "/fakerow";
623
624 CellSetModel cellSetModel = new CellSetModel();
625 RowModel rowModel = new RowModel(ROW_1);
626 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1),
627 Bytes.toBytes(VALUE_1)));
628 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2),
629 Bytes.toBytes(VALUE_2)));
630 cellSetModel.addRow(rowModel);
631 rowModel = new RowModel(ROW_2);
632 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1),
633 Bytes.toBytes(VALUE_3)));
634 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2),
635 Bytes.toBytes(VALUE_4)));
636 cellSetModel.addRow(rowModel);
637 StringWriter writer = new StringWriter();
638 marshaller.marshal(cellSetModel, writer);
639 Response response = client.put(path, Constants.MIMETYPE_XML,
640 Bytes.toBytes(writer.toString()));
641 Thread.yield();
642
643
644 response = client.get(path, Constants.MIMETYPE_XML);
645 assertEquals(response.getCode(), 404);
646
647
648 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1);
649 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2);
650 checkValueXML(TABLE, ROW_2, COLUMN_1, VALUE_3);
651 checkValueXML(TABLE, ROW_2, COLUMN_2, VALUE_4);
652
653 response = deleteRow(TABLE, ROW_1);
654 assertEquals(response.getCode(), 200);
655 response = deleteRow(TABLE, ROW_2);
656 assertEquals(response.getCode(), 200);
657 }
658
659 @Test
660 public void testMultiCellGetPutPB() throws IOException {
661 String path = "/" + TABLE + "/fakerow";
662
663 CellSetModel cellSetModel = new CellSetModel();
664 RowModel rowModel = new RowModel(ROW_1);
665 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1),
666 Bytes.toBytes(VALUE_1)));
667 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2),
668 Bytes.toBytes(VALUE_2)));
669 cellSetModel.addRow(rowModel);
670 rowModel = new RowModel(ROW_2);
671 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1),
672 Bytes.toBytes(VALUE_3)));
673 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2),
674 Bytes.toBytes(VALUE_4)));
675 cellSetModel.addRow(rowModel);
676 Response response = client.put(path, Constants.MIMETYPE_PROTOBUF,
677 cellSetModel.createProtobufOutput());
678 Thread.yield();
679
680
681 response = client.get(path, Constants.MIMETYPE_PROTOBUF);
682 assertEquals(response.getCode(), 404);
683
684
685 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1);
686 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2);
687 checkValuePB(TABLE, ROW_2, COLUMN_1, VALUE_3);
688 checkValuePB(TABLE, ROW_2, COLUMN_2, VALUE_4);
689
690 response = deleteRow(TABLE, ROW_1);
691 assertEquals(response.getCode(), 200);
692 response = deleteRow(TABLE, ROW_2);
693 assertEquals(response.getCode(), 200);
694 }
695
696 @Test
697 public void testStartEndRowGetPutXML() throws IOException, JAXBException {
698 String[] rows = { ROW_1, ROW_2, ROW_3 };
699 String[] values = { VALUE_1, VALUE_2, VALUE_3 };
700 Response response = null;
701 for (int i = 0; i < rows.length; i++) {
702 response = putValueXML(TABLE, rows[i], COLUMN_1, values[i]);
703 assertEquals(200, response.getCode());
704 checkValueXML(TABLE, rows[i], COLUMN_1, values[i]);
705 }
706 response = getValueXML(TABLE, rows[0], rows[2], COLUMN_1);
707 assertEquals(200, response.getCode());
708 CellSetModel cellSet = (CellSetModel)
709 unmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
710 assertEquals(2, cellSet.getRows().size());
711 for (int i = 0; i < cellSet.getRows().size()-1; i++) {
712 RowModel rowModel = cellSet.getRows().get(i);
713 for (CellModel cell: rowModel.getCells()) {
714 assertEquals(COLUMN_1, Bytes.toString(cell.getColumn()));
715 assertEquals(values[i], Bytes.toString(cell.getValue()));
716 }
717 }
718 for (String row : rows) {
719 response = deleteRow(TABLE, row);
720 assertEquals(200, response.getCode());
721 }
722 }
723
724 @Test
725 public void testInvalidCheckParam() throws IOException, JAXBException {
726 CellSetModel cellSetModel = new CellSetModel();
727 RowModel rowModel = new RowModel(ROW_1);
728 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1),
729 Bytes.toBytes(VALUE_1)));
730 cellSetModel.addRow(rowModel);
731 StringWriter writer = new StringWriter();
732 marshaller.marshal(cellSetModel, writer);
733
734 final String path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "?check=blah";
735
736 Response response = client.put(path, Constants.MIMETYPE_XML,
737 Bytes.toBytes(writer.toString()));
738 assertEquals(response.getCode(), 400);
739 }
740
741 @Test
742 public void testLatestCellGetXML() throws IOException, JAXBException {
743 final String path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
744 CellSetModel cellSetModel = new CellSetModel();
745 RowModel rowModel = new RowModel(ROW_1);
746 CellModel cellOne = new CellModel(Bytes.toBytes(COLUMN_1), 1L, Bytes.toBytes(VALUE_1));
747 CellModel cellTwo = new CellModel(Bytes.toBytes(COLUMN_1), 2L, Bytes.toBytes(VALUE_2));
748 rowModel.addCell(cellOne);
749 rowModel.addCell(cellTwo);
750 cellSetModel.addRow(rowModel);
751 StringWriter writer = new StringWriter();
752 marshaller.marshal(cellSetModel, writer);
753 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
754 assertEquals(response.getCode(), 200);
755 response = getValueXML(TABLE, ROW_1, COLUMN_1);
756 assertEquals(response.getCode(), 200);
757 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
758 CellSetModel cellSet = (CellSetModel) unmarshaller.unmarshal(new ByteArrayInputStream(response
759 .getBody()));
760 assertTrue(cellSet.getRows().size() == 1);
761 assertTrue(cellSet.getRows().get(0).getCells().size() == 1);
762 CellModel cell = cellSet.getRows().get(0).getCells().get(0);
763 assertEquals(VALUE_2, Bytes.toString(cell.getValue()));
764 assertEquals(2L, cell.getTimestamp());
765 response = deleteRow(TABLE, ROW_1);
766 assertEquals(response.getCode(), 200);
767 }
768
769 @Test
770 public void testMultiColumnGetXML() throws Exception {
771 String path = "/" + TABLE + "/fakerow";
772 CellSetModel cellSetModel = new CellSetModel();
773 RowModel rowModel = new RowModel(ROW_1);
774 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1)));
775 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_2)));
776 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_3), Bytes.toBytes(VALUE_2)));
777 cellSetModel.addRow(rowModel);
778 StringWriter writer = new StringWriter();
779 marshaller.marshal(cellSetModel, writer);
780
781 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
782 Thread.yield();
783
784
785 response = client.get(path, Constants.MIMETYPE_XML);
786 assertEquals(response.getCode(), 404);
787
788
789 path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "," + COLUMN_2 + "," + COLUMN_3;
790 response = client.get(path, Constants.MIMETYPE_XML);
791 assertEquals(200, response.getCode());
792 CellSetModel cellSet = (CellSetModel) unmarshaller.unmarshal(new ByteArrayInputStream(response
793 .getBody()));
794 assertTrue(cellSet.getRows().size() == 1);
795 assertTrue(cellSet.getRows().get(0).getCells().size() == 3);
796 List<CellModel> cells = cellSet.getRows().get(0).getCells();
797
798 assertTrue(containsCellModel(cells, COLUMN_1, VALUE_1));
799 assertTrue(containsCellModel(cells, COLUMN_2, VALUE_2));
800 assertTrue(containsCellModel(cells, COLUMN_3, VALUE_2));
801 response = deleteRow(TABLE, ROW_1);
802 assertEquals(response.getCode(), 200);
803 }
804
805 private boolean containsCellModel(List<CellModel> cells, String column, String value) {
806 boolean contains = false;
807 for (CellModel cell : cells) {
808 if (Bytes.toString(cell.getColumn()).equals(column)
809 && Bytes.toString(cell.getValue()).equals(value)) {
810 contains = true;
811 return contains;
812 }
813 }
814 return contains;
815 }
816 }
817