1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.rest;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.DataInputStream;
26 import java.io.EOFException;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.Serializable;
30 import java.net.URLEncoder;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.List;
34
35 import javax.ws.rs.core.MediaType;
36 import javax.xml.bind.JAXBContext;
37 import javax.xml.bind.JAXBException;
38 import javax.xml.bind.Unmarshaller;
39 import javax.xml.bind.annotation.XmlAccessType;
40 import javax.xml.bind.annotation.XmlAccessorType;
41 import javax.xml.bind.annotation.XmlElement;
42 import javax.xml.bind.annotation.XmlRootElement;
43 import javax.xml.parsers.SAXParserFactory;
44 import javax.xml.stream.XMLStreamException;
45
46 import org.apache.hadoop.conf.Configuration;
47 import org.apache.hadoop.hbase.HBaseTestingUtility;
48 import org.apache.hadoop.hbase.HColumnDescriptor;
49 import org.apache.hadoop.hbase.HTableDescriptor;
50 import org.apache.hadoop.hbase.testclassification.MediumTests;
51 import org.apache.hadoop.hbase.TableName;
52 import org.apache.hadoop.hbase.client.Admin;
53 import org.apache.hadoop.hbase.filter.Filter;
54 import org.apache.hadoop.hbase.filter.ParseFilter;
55 import org.apache.hadoop.hbase.filter.PrefixFilter;
56 import org.apache.hadoop.hbase.rest.client.Client;
57 import org.apache.hadoop.hbase.rest.client.Cluster;
58 import org.apache.hadoop.hbase.rest.client.Response;
59 import org.apache.hadoop.hbase.rest.model.CellModel;
60 import org.apache.hadoop.hbase.rest.model.CellSetModel;
61 import org.apache.hadoop.hbase.rest.model.RowModel;
62 import org.apache.hadoop.hbase.rest.provider.JacksonProvider;
63 import org.apache.hadoop.hbase.util.Bytes;
64 import org.codehaus.jackson.JsonFactory;
65 import org.codehaus.jackson.JsonParser;
66 import org.codehaus.jackson.JsonToken;
67 import org.codehaus.jackson.map.ObjectMapper;
68 import org.junit.AfterClass;
69 import org.junit.BeforeClass;
70 import org.junit.Test;
71 import org.junit.experimental.categories.Category;
72 import org.xml.sax.InputSource;
73 import org.xml.sax.XMLReader;
74
75 @Category(MediumTests.class)
76 public class TestTableScan {
77
78 private static final TableName TABLE = TableName.valueOf("TestScanResource");
79 private static final String CFA = "a";
80 private static final String CFB = "b";
81 private static final String COLUMN_1 = CFA + ":1";
82 private static final String COLUMN_2 = CFB + ":2";
83 private static Client client;
84 private static int expectedRows1;
85 private static int expectedRows2;
86 private static Configuration conf;
87
88 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
89 private static final HBaseRESTTestingUtility REST_TEST_UTIL =
90 new HBaseRESTTestingUtility();
91
92 @BeforeClass
93 public static void setUpBeforeClass() throws Exception {
94 conf = TEST_UTIL.getConfiguration();
95 conf.set(Constants.CUSTOM_FILTERS, "CustomFilter:" + CustomFilter.class.getName());
96 TEST_UTIL.startMiniCluster();
97 REST_TEST_UTIL.startServletContainer(conf);
98 client = new Client(new Cluster().add("localhost",
99 REST_TEST_UTIL.getServletPort()));
100 Admin admin = TEST_UTIL.getHBaseAdmin();
101 if (!admin.tableExists(TABLE)) {
102 HTableDescriptor htd = new HTableDescriptor(TABLE);
103 htd.addFamily(new HColumnDescriptor(CFA));
104 htd.addFamily(new HColumnDescriptor(CFB));
105 admin.createTable(htd);
106 expectedRows1 = TestScannerResource.insertData(conf, TABLE, COLUMN_1, 1.0);
107 expectedRows2 = TestScannerResource.insertData(conf, TABLE, COLUMN_2, 0.5);
108 }
109 }
110
111 @AfterClass
112 public static void tearDownAfterClass() throws Exception {
113 TEST_UTIL.getHBaseAdmin().disableTable(TABLE);
114 TEST_UTIL.getHBaseAdmin().deleteTable(TABLE);
115 REST_TEST_UTIL.shutdownServletContainer();
116 TEST_UTIL.shutdownMiniCluster();
117 }
118
119 @Test
120 public void testSimpleScannerXML() throws IOException, JAXBException, XMLStreamException {
121
122 StringBuilder builder = new StringBuilder();
123 builder.append("/*");
124 builder.append("?");
125 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
126 builder.append("&");
127 builder.append(Constants.SCAN_LIMIT + "=10");
128 Response response = client.get("/" + TABLE + builder.toString(),
129 Constants.MIMETYPE_XML);
130 assertEquals(200, response.getCode());
131 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
132 JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class);
133 Unmarshaller ush = ctx.createUnmarshaller();
134 CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream());
135 int count = TestScannerResource.countCellSet(model);
136 assertEquals(10, count);
137 checkRowsNotNull(model);
138
139
140 builder = new StringBuilder();
141 builder.append("/*");
142 builder.append("?");
143 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
144 response = client.get("/" + TABLE + builder.toString(),
145 Constants.MIMETYPE_XML);
146 assertEquals(200, response.getCode());
147 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
148 model = (CellSetModel) ush.unmarshal(response.getStream());
149 count = TestScannerResource.countCellSet(model);
150 assertEquals(expectedRows1, count);
151 checkRowsNotNull(model);
152
153
154 builder = new StringBuilder();
155 builder.append("/*");
156 builder.append("?");
157 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
158 builder.append("&");
159 builder.append(Constants.SCAN_START_ROW + "=aaa");
160 builder.append("&");
161 builder.append(Constants.SCAN_END_ROW + "=aay");
162 response = client.get("/" + TABLE + builder.toString(),
163 Constants.MIMETYPE_XML);
164 assertEquals(200, response.getCode());
165 model = (CellSetModel) ush.unmarshal(response.getStream());
166 count = TestScannerResource.countCellSet(model);
167 RowModel startRow = model.getRows().get(0);
168 assertEquals("aaa", Bytes.toString(startRow.getKey()));
169 RowModel endRow = model.getRows().get(model.getRows().size() - 1);
170 assertEquals("aax", Bytes.toString(endRow.getKey()));
171 assertEquals(24, count);
172 checkRowsNotNull(model);
173
174
175 builder = new StringBuilder();
176 builder.append("/*");
177 builder.append("?");
178 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
179 builder.append("&");
180 builder.append(Constants.SCAN_START_ROW + "=aaa");
181 builder.append("&");
182 builder.append(Constants.SCAN_LIMIT + "=15");
183 response = client.get("/" + TABLE + builder.toString(),
184 Constants.MIMETYPE_XML);
185 assertEquals(200, response.getCode());
186 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
187 model = (CellSetModel) ush.unmarshal(response.getStream());
188 startRow = model.getRows().get(0);
189 assertEquals("aaa", Bytes.toString(startRow.getKey()));
190 count = TestScannerResource.countCellSet(model);
191 assertEquals(15, count);
192 checkRowsNotNull(model);
193 }
194
195 @Test
196 public void testSimpleScannerJson() throws IOException, JAXBException {
197
198 StringBuilder builder = new StringBuilder();
199 builder.append("/*");
200 builder.append("?");
201 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
202 builder.append("&");
203 builder.append(Constants.SCAN_LIMIT + "=20");
204 Response response = client.get("/" + TABLE + builder.toString(),
205 Constants.MIMETYPE_JSON);
206 assertEquals(200, response.getCode());
207 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
208 ObjectMapper mapper = new JacksonProvider()
209 .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
210 CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class);
211 int count = TestScannerResource.countCellSet(model);
212 assertEquals(20, count);
213 checkRowsNotNull(model);
214
215
216 builder = new StringBuilder();
217 builder.append("/*");
218 builder.append("?");
219 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_2);
220 response = client.get("/" + TABLE + builder.toString(),
221 Constants.MIMETYPE_JSON);
222 assertEquals(200, response.getCode());
223 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
224 model = mapper.readValue(response.getStream(), CellSetModel.class);
225 count = TestScannerResource.countCellSet(model);
226 assertEquals(expectedRows2, count);
227 checkRowsNotNull(model);
228
229
230 builder = new StringBuilder();
231 builder.append("/*");
232 builder.append("?");
233 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
234 builder.append("&");
235 builder.append(Constants.SCAN_START_ROW + "=aaa");
236 builder.append("&");
237 builder.append(Constants.SCAN_END_ROW + "=aay");
238 response = client.get("/" + TABLE + builder.toString(),
239 Constants.MIMETYPE_JSON);
240 assertEquals(200, response.getCode());
241 model = mapper.readValue(response.getStream(), CellSetModel.class);
242 RowModel startRow = model.getRows().get(0);
243 assertEquals("aaa", Bytes.toString(startRow.getKey()));
244 RowModel endRow = model.getRows().get(model.getRows().size() - 1);
245 assertEquals("aax", Bytes.toString(endRow.getKey()));
246 count = TestScannerResource.countCellSet(model);
247 assertEquals(24, count);
248 checkRowsNotNull(model);
249 }
250
251
252
253
254
255 @Test
256 public void testScanUsingListenerUnmarshallerXML() throws Exception {
257 StringBuilder builder = new StringBuilder();
258 builder.append("/*");
259 builder.append("?");
260 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
261 builder.append("&");
262 builder.append(Constants.SCAN_LIMIT + "=10");
263 Response response = client.get("/" + TABLE + builder.toString(),
264 Constants.MIMETYPE_XML);
265 assertEquals(200, response.getCode());
266 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
267 JAXBContext context = JAXBContext.newInstance(ClientSideCellSetModel.class, RowModel.class,
268 CellModel.class);
269 Unmarshaller unmarshaller = context.createUnmarshaller();
270
271 final ClientSideCellSetModel.Listener listener = new ClientSideCellSetModel.Listener() {
272 @Override
273 public void handleRowModel(ClientSideCellSetModel helper, RowModel row) {
274 assertTrue(row.getKey() != null);
275 assertTrue(row.getCells().size() > 0);
276 }
277 };
278
279
280 unmarshaller.setListener(new Unmarshaller.Listener() {
281 public void beforeUnmarshal(Object target, Object parent) {
282 if (target instanceof ClientSideCellSetModel) {
283 ((ClientSideCellSetModel) target).setCellSetModelListener(listener);
284 }
285 }
286
287 public void afterUnmarshal(Object target, Object parent) {
288 if (target instanceof ClientSideCellSetModel) {
289 ((ClientSideCellSetModel) target).setCellSetModelListener(null);
290 }
291 }
292 });
293
294
295 SAXParserFactory factory = SAXParserFactory.newInstance();
296 factory.setNamespaceAware(true);
297 XMLReader reader = factory.newSAXParser().getXMLReader();
298 reader.setContentHandler(unmarshaller.getUnmarshallerHandler());
299 assertFalse(ClientSideCellSetModel.listenerInvoked);
300 reader.parse(new InputSource(response.getStream()));
301 assertTrue(ClientSideCellSetModel.listenerInvoked);
302
303 }
304
305 @Test
306 public void testStreamingJSON() throws Exception {
307
308 StringBuilder builder = new StringBuilder();
309 builder.append("/*");
310 builder.append("?");
311 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
312 builder.append("&");
313 builder.append(Constants.SCAN_LIMIT + "=20");
314 Response response = client.get("/" + TABLE + builder.toString(),
315 Constants.MIMETYPE_JSON);
316 assertEquals(200, response.getCode());
317 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
318 ObjectMapper mapper = new JacksonProvider()
319 .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
320 CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class);
321 int count = TestScannerResource.countCellSet(model);
322 assertEquals(20, count);
323 checkRowsNotNull(model);
324
325
326 builder = new StringBuilder();
327 builder.append("/*");
328 builder.append("?");
329 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_2);
330 response = client.get("/" + TABLE + builder.toString(),
331 Constants.MIMETYPE_JSON);
332 assertEquals(200, response.getCode());
333 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
334 model = mapper.readValue(response.getStream(), CellSetModel.class);
335 count = TestScannerResource.countCellSet(model);
336 assertEquals(expectedRows2, count);
337 checkRowsNotNull(model);
338
339
340 builder = new StringBuilder();
341 builder.append("/*");
342 builder.append("?");
343 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
344 builder.append("&");
345 builder.append(Constants.SCAN_START_ROW + "=aaa");
346 builder.append("&");
347 builder.append(Constants.SCAN_END_ROW + "=aay");
348 response = client.get("/" + TABLE + builder.toString(),
349 Constants.MIMETYPE_JSON);
350 assertEquals(200, response.getCode());
351
352 count = 0;
353 JsonFactory jfactory = new JsonFactory(mapper);
354 JsonParser jParser = jfactory.createJsonParser(response.getStream());
355 boolean found = false;
356 while (jParser.nextToken() != JsonToken.END_OBJECT) {
357 if(jParser.getCurrentToken() == JsonToken.START_OBJECT && found) {
358 RowModel row = jParser.readValueAs(RowModel.class);
359 assertNotNull(row.getKey());
360 for (int i = 0; i < row.getCells().size(); i++) {
361 if (count == 0) {
362 assertEquals("aaa", Bytes.toString(row.getKey()));
363 }
364 if (count == 23) {
365 assertEquals("aax", Bytes.toString(row.getKey()));
366 }
367 count++;
368 }
369 jParser.skipChildren();
370 } else {
371 found = jParser.getCurrentToken() == JsonToken.START_ARRAY;
372 }
373 }
374 assertEquals(24, count);
375 }
376
377 @Test
378 public void testSimpleScannerProtobuf() throws Exception {
379 StringBuilder builder = new StringBuilder();
380 builder.append("/*");
381 builder.append("?");
382 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
383 builder.append("&");
384 builder.append(Constants.SCAN_LIMIT + "=15");
385 Response response = client.get("/" + TABLE + builder.toString(),
386 Constants.MIMETYPE_PROTOBUF);
387 assertEquals(200, response.getCode());
388 assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
389 int rowCount = readProtobufStream(response.getStream());
390 assertEquals(15, rowCount);
391
392
393 builder = new StringBuilder();
394 builder.append("/*");
395 builder.append("?");
396 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
397 builder.append("&");
398 builder.append(Constants.SCAN_START_ROW + "=aaa");
399 builder.append("&");
400 builder.append(Constants.SCAN_END_ROW + "=aay");
401 response = client.get("/" + TABLE + builder.toString(),
402 Constants.MIMETYPE_PROTOBUF);
403 assertEquals(200, response.getCode());
404 assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
405 rowCount = readProtobufStream(response.getStream());
406 assertEquals(24, rowCount);
407 }
408
409 private void checkRowsNotNull(CellSetModel model) {
410 for (RowModel row: model.getRows()) {
411 assertTrue(row.getKey() != null);
412 assertTrue(row.getCells().size() > 0);
413 }
414 }
415
416
417
418
419
420
421
422 public int readProtobufStream(InputStream inputStream) throws IOException{
423 DataInputStream stream = new DataInputStream(inputStream);
424 CellSetModel model = null;
425 int rowCount = 0;
426 try {
427 while (true) {
428 byte[] lengthBytes = new byte[2];
429 int readBytes = stream.read(lengthBytes);
430 if (readBytes == -1) {
431 break;
432 }
433 assertEquals(2, readBytes);
434 int length = Bytes.toShort(lengthBytes);
435 byte[] cellset = new byte[length];
436 stream.read(cellset);
437 model = new CellSetModel();
438 model.getObjectFromMessage(cellset);
439 checkRowsNotNull(model);
440 rowCount = rowCount + TestScannerResource.countCellSet(model);
441 }
442 } catch (EOFException exp) {
443 exp.printStackTrace();
444 } finally {
445 stream.close();
446 }
447 return rowCount;
448 }
449
450 @Test
451 public void testScanningUnknownColumnJson() throws IOException, JAXBException {
452
453 StringBuilder builder = new StringBuilder();
454 builder.append("/*");
455 builder.append("?");
456 builder.append(Constants.SCAN_COLUMN + "=a:test");
457 Response response = client.get("/" + TABLE + builder.toString(),
458 Constants.MIMETYPE_JSON);
459 assertEquals(200, response.getCode());
460 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
461 ObjectMapper mapper = new JacksonProvider().locateMapper(CellSetModel.class,
462 MediaType.APPLICATION_JSON_TYPE);
463 CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class);
464 int count = TestScannerResource.countCellSet(model);
465 assertEquals(0, count);
466 }
467
468 @Test
469 public void testSimpleFilter() throws IOException, JAXBException {
470 StringBuilder builder = new StringBuilder();
471 builder = new StringBuilder();
472 builder.append("/*");
473 builder.append("?");
474 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
475 builder.append("&");
476 builder.append(Constants.SCAN_START_ROW + "=aaa");
477 builder.append("&");
478 builder.append(Constants.SCAN_END_ROW + "=aay");
479 builder.append("&");
480 builder.append(Constants.SCAN_FILTER + "=" + URLEncoder.encode("PrefixFilter('aab')", "UTF-8"));
481 Response response =
482 client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML);
483 assertEquals(200, response.getCode());
484 JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class);
485 Unmarshaller ush = ctx.createUnmarshaller();
486 CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream());
487 int count = TestScannerResource.countCellSet(model);
488 assertEquals(1, count);
489 assertEquals("aab", new String(model.getRows().get(0).getCells().get(0).getValue()));
490 }
491
492 @Test
493 public void testCompoundFilter() throws IOException, JAXBException {
494 StringBuilder builder = new StringBuilder();
495 builder = new StringBuilder();
496 builder.append("/*");
497 builder.append("?");
498 builder.append(Constants.SCAN_FILTER + "="
499 + URLEncoder.encode("PrefixFilter('abc') AND QualifierFilter(=,'binary:1')", "UTF-8"));
500 Response response =
501 client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML);
502 assertEquals(200, response.getCode());
503 JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class);
504 Unmarshaller ush = ctx.createUnmarshaller();
505 CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream());
506 int count = TestScannerResource.countCellSet(model);
507 assertEquals(1, count);
508 assertEquals("abc", new String(model.getRows().get(0).getCells().get(0).getValue()));
509 }
510
511 @Test
512 public void testCustomFilter() throws IOException, JAXBException {
513 StringBuilder builder = new StringBuilder();
514 builder = new StringBuilder();
515 builder.append("/a*");
516 builder.append("?");
517 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
518 builder.append("&");
519 builder.append(Constants.SCAN_FILTER + "=" + URLEncoder.encode("CustomFilter('abc')", "UTF-8"));
520 Response response =
521 client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML);
522 assertEquals(200, response.getCode());
523 JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class);
524 Unmarshaller ush = ctx.createUnmarshaller();
525 CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream());
526 int count = TestScannerResource.countCellSet(model);
527 assertEquals(1, count);
528 assertEquals("abc", new String(model.getRows().get(0).getCells().get(0).getValue()));
529 }
530
531 @Test
532 public void testNegativeCustomFilter() throws IOException, JAXBException {
533 StringBuilder builder = new StringBuilder();
534 builder = new StringBuilder();
535 builder.append("/b*");
536 builder.append("?");
537 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
538 builder.append("&");
539 builder.append(Constants.SCAN_FILTER + "=" + URLEncoder.encode("CustomFilter('abc')", "UTF-8"));
540 Response response =
541 client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML);
542 assertEquals(200, response.getCode());
543 JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class);
544 Unmarshaller ush = ctx.createUnmarshaller();
545 CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream());
546 int count = TestScannerResource.countCellSet(model);
547
548 assertEquals(0, count);
549 }
550
551 @Test
552 public void testReversed() throws IOException, JAXBException {
553 StringBuilder builder = new StringBuilder();
554 builder.append("/*");
555 builder.append("?");
556 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
557 builder.append("&");
558 builder.append(Constants.SCAN_START_ROW + "=aaa");
559 builder.append("&");
560 builder.append(Constants.SCAN_END_ROW + "=aay");
561 Response response = client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML);
562 assertEquals(200, response.getCode());
563 JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class);
564 Unmarshaller ush = ctx.createUnmarshaller();
565 CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream());
566 int count = TestScannerResource.countCellSet(model);
567 assertEquals(24, count);
568 List<RowModel> rowModels = model.getRows().subList(1, count);
569
570
571 builder = new StringBuilder();
572 builder.append("/*");
573 builder.append("?");
574 builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1);
575 builder.append("&");
576 builder.append(Constants.SCAN_START_ROW + "=aay");
577 builder.append("&");
578 builder.append(Constants.SCAN_END_ROW + "=aaa");
579 builder.append("&");
580 builder.append(Constants.SCAN_REVERSED + "=true");
581 response = client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML);
582 assertEquals(200, response.getCode());
583 model = (CellSetModel) ush.unmarshal(response.getStream());
584 count = TestScannerResource.countCellSet(model);
585 assertEquals(24, count);
586 List<RowModel> reversedRowModels = model.getRows().subList(1, count);
587
588 Collections.reverse(reversedRowModels);
589 assertEquals(rowModels.size(), reversedRowModels.size());
590 for (int i = 0; i < rowModels.size(); i++) {
591 RowModel rowModel = rowModels.get(i);
592 RowModel reversedRowModel = reversedRowModels.get(i);
593
594 assertEquals(new String(rowModel.getKey(), "UTF-8"),
595 new String(reversedRowModel.getKey(), "UTF-8"));
596 assertEquals(new String(rowModel.getCells().get(0).getValue(), "UTF-8"),
597 new String(reversedRowModel.getCells().get(0).getValue(), "UTF-8"));
598 }
599 }
600
601 public static class CustomFilter extends PrefixFilter {
602 private byte[] key = null;
603
604 public CustomFilter(byte[] key) {
605 super(key);
606 }
607
608 @Override
609 public boolean filterRowKey(byte[] buffer, int offset, int length) {
610 int cmp = Bytes.compareTo(buffer, offset, length, this.key, 0, this.key.length);
611 return cmp != 0;
612 }
613
614 public static Filter createFilterFromArguments(ArrayList<byte[]> filterArguments) {
615 byte[] prefix = ParseFilter.removeQuotesFromByteArray(filterArguments.get(0));
616 return new CustomFilter(prefix);
617 }
618 }
619
620
621
622
623
624 @XmlRootElement(name = "CellSet")
625 @XmlAccessorType(XmlAccessType.FIELD)
626 public static class ClientSideCellSetModel implements Serializable {
627
628 private static final long serialVersionUID = 1L;
629
630
631
632
633
634 @XmlElement(name="Row")
635 private List<RowModel> row;
636
637 static boolean listenerInvoked = false;
638
639
640
641
642
643 public void setCellSetModelListener(final Listener l) {
644 row = (l == null) ? null : new ArrayList<RowModel>() {
645 private static final long serialVersionUID = 1L;
646
647 public boolean add(RowModel o) {
648 l.handleRowModel(ClientSideCellSetModel.this, o);
649 listenerInvoked = true;
650 return false;
651 }
652 };
653 }
654
655
656
657
658 public static interface Listener {
659 void handleRowModel(ClientSideCellSetModel helper, RowModel rowModel);
660 }
661 }
662 }
663
664
665