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.thrift2;
21
22 import java.io.IOException;
23 import java.nio.ByteBuffer;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.HashMap;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.HBaseTestingUtility;
35 import org.apache.hadoop.hbase.HColumnDescriptor;
36 import org.apache.hadoop.hbase.HTableDescriptor;
37 import org.apache.hadoop.hbase.MediumTests;
38 import org.apache.hadoop.hbase.client.HBaseAdmin;
39 import org.apache.hadoop.hbase.client.Get;
40 import org.apache.hadoop.hbase.client.Put;
41 import org.apache.hadoop.hbase.client.Scan;
42 import org.apache.hadoop.hbase.client.Delete;
43 import org.apache.hadoop.hbase.filter.ParseFilter;
44 import org.apache.hadoop.hbase.thrift.ThriftMetrics;
45 import org.apache.hadoop.hbase.thrift2.generated.TColumn;
46 import org.apache.hadoop.hbase.thrift2.generated.TColumnIncrement;
47 import org.apache.hadoop.hbase.thrift2.generated.TColumnValue;
48 import org.apache.hadoop.hbase.thrift2.generated.TDelete;
49 import org.apache.hadoop.hbase.thrift2.generated.TDeleteType;
50 import org.apache.hadoop.hbase.thrift2.generated.TGet;
51 import org.apache.hadoop.hbase.thrift2.generated.THBaseService;
52 import org.apache.hadoop.hbase.thrift2.generated.TIOError;
53 import org.apache.hadoop.hbase.thrift2.generated.TIllegalArgument;
54 import org.apache.hadoop.hbase.thrift2.generated.TIncrement;
55 import org.apache.hadoop.hbase.thrift2.generated.TPut;
56 import org.apache.hadoop.hbase.thrift2.generated.TResult;
57 import org.apache.hadoop.hbase.thrift2.generated.TScan;
58 import org.apache.hadoop.hbase.thrift2.generated.TMutation;
59 import org.apache.hadoop.hbase.thrift2.generated.TRowMutations;
60 import org.apache.hadoop.hbase.util.Bytes;
61 import org.apache.hadoop.metrics.ContextFactory;
62 import org.apache.hadoop.metrics.MetricsContext;
63 import org.apache.hadoop.metrics.MetricsUtil;
64 import org.apache.hadoop.metrics.spi.NoEmitMetricsContext;
65 import org.apache.hadoop.metrics.spi.OutputRecord;
66 import org.apache.thrift.TException;
67 import org.junit.AfterClass;
68 import org.junit.Before;
69 import org.junit.BeforeClass;
70 import org.junit.Test;
71 import org.junit.experimental.categories.Category;
72
73 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.getFromThrift;
74 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.putFromThrift;
75 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.scanFromThrift;
76 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.deleteFromThrift;
77 import static org.junit.Assert.*;
78 import static java.nio.ByteBuffer.wrap;
79
80
81
82
83
84 @Category(MediumTests.class)
85 public class TestThriftHBaseServiceHandler {
86
87 public static final Log LOG = LogFactory.getLog(TestThriftHBaseServiceHandler.class);
88 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
89
90
91 private static byte[] tableAname = Bytes.toBytes("tableA");
92 private static byte[] familyAname = Bytes.toBytes("familyA");
93 private static byte[] familyBname = Bytes.toBytes("familyB");
94 private static byte[] qualifierAname = Bytes.toBytes("qualifierA");
95 private static byte[] qualifierBname = Bytes.toBytes("qualifierB");
96 private static byte[] valueAname = Bytes.toBytes("valueA");
97 private static byte[] valueBname = Bytes.toBytes("valueB");
98 private static HColumnDescriptor[] families = new HColumnDescriptor[] {
99 new HColumnDescriptor(familyAname),
100 new HColumnDescriptor(familyBname)
101 .setMaxVersions(2)
102 };
103
104 public void assertTColumnValuesEqual(List<TColumnValue> columnValuesA,
105 List<TColumnValue> columnValuesB) {
106 assertEquals(columnValuesA.size(), columnValuesB.size());
107 Comparator<TColumnValue> comparator = new Comparator<TColumnValue>() {
108 @Override
109 public int compare(TColumnValue o1, TColumnValue o2) {
110 return Bytes.compareTo(Bytes.add(o1.getFamily(), o1.getQualifier()),
111 Bytes.add(o2.getFamily(), o2.getQualifier()));
112 }
113 };
114 Collections.sort(columnValuesA, comparator);
115 Collections.sort(columnValuesB, comparator);
116
117 for (int i = 0; i < columnValuesA.size(); i++) {
118 TColumnValue a = columnValuesA.get(i);
119 TColumnValue b = columnValuesB.get(i);
120 assertArrayEquals(a.getFamily(), b.getFamily());
121 assertArrayEquals(a.getQualifier(), b.getQualifier());
122 assertArrayEquals(a.getValue(), b.getValue());
123 }
124 }
125
126 @BeforeClass
127 public static void beforeClass() throws Exception {
128 UTIL.startMiniCluster();
129 HBaseAdmin admin = new HBaseAdmin(UTIL.getConfiguration());
130 HTableDescriptor tableDescriptor = new HTableDescriptor(tableAname);
131 for (HColumnDescriptor family : families) {
132 tableDescriptor.addFamily(family);
133 }
134 admin.createTable(tableDescriptor);
135 }
136
137 @AfterClass
138 public static void afterClass() throws Exception {
139 UTIL.shutdownMiniCluster();
140 }
141
142 @Before
143 public void setup() throws Exception {
144
145 }
146
147 private ThriftHBaseServiceHandler createHandler() {
148 return new ThriftHBaseServiceHandler(UTIL.getConfiguration());
149 }
150
151 @Test
152 public void testExists() throws TIOError, TException {
153 ThriftHBaseServiceHandler handler = createHandler();
154 byte[] rowName = "testExists".getBytes();
155 ByteBuffer table = wrap(tableAname);
156
157 TGet get = new TGet(wrap(rowName));
158 assertFalse(handler.exists(table, get));
159
160 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
161 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
162 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
163 TPut put = new TPut(wrap(rowName), columnValues);
164 put.setColumnValues(columnValues);
165
166 handler.put(table, put);
167
168 assertTrue(handler.exists(table, get));
169 }
170
171 @Test
172 public void testPutGet() throws Exception {
173 ThriftHBaseServiceHandler handler = createHandler();
174 byte[] rowName = "testPutGet".getBytes();
175 ByteBuffer table = wrap(tableAname);
176
177 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
178 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
179 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
180 TPut put = new TPut(wrap(rowName), columnValues);
181
182 put.setColumnValues(columnValues);
183
184 handler.put(table, put);
185
186 TGet get = new TGet(wrap(rowName));
187
188 TResult result = handler.get(table, get);
189 assertArrayEquals(rowName, result.getRow());
190 List<TColumnValue> returnedColumnValues = result.getColumnValues();
191 assertTColumnValuesEqual(columnValues, returnedColumnValues);
192 }
193
194 @Test
195 public void testPutGetMultiple() throws Exception {
196 ThriftHBaseServiceHandler handler = createHandler();
197 ByteBuffer table = wrap(tableAname);
198 byte[] rowName1 = "testPutGetMultiple1".getBytes();
199 byte[] rowName2 = "testPutGetMultiple2".getBytes();
200
201 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
202 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
203 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
204 List<TPut> puts = new ArrayList<TPut>();
205 puts.add(new TPut(wrap(rowName1), columnValues));
206 puts.add(new TPut(wrap(rowName2), columnValues));
207
208 handler.putMultiple(table, puts);
209
210 List<TGet> gets = new ArrayList<TGet>();
211 gets.add(new TGet(wrap(rowName1)));
212 gets.add(new TGet(wrap(rowName2)));
213
214 List<TResult> results = handler.getMultiple(table, gets);
215 assertEquals(2, results.size());
216
217 assertArrayEquals(rowName1, results.get(0).getRow());
218 assertTColumnValuesEqual(columnValues, results.get(0).getColumnValues());
219
220 assertArrayEquals(rowName2, results.get(1).getRow());
221 assertTColumnValuesEqual(columnValues, results.get(1).getColumnValues());
222 }
223
224 @Test
225 public void testDeleteMultiple() throws Exception {
226 ThriftHBaseServiceHandler handler = createHandler();
227 ByteBuffer table = wrap(tableAname);
228 byte[] rowName1 = "testDeleteMultiple1".getBytes();
229 byte[] rowName2 = "testDeleteMultiple2".getBytes();
230
231 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
232 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
233 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
234 List<TPut> puts = new ArrayList<TPut>();
235 puts.add(new TPut(wrap(rowName1), columnValues));
236 puts.add(new TPut(wrap(rowName2), columnValues));
237
238 handler.putMultiple(table, puts);
239
240 List<TDelete> deletes = new ArrayList<TDelete>();
241 deletes.add(new TDelete(wrap(rowName1)));
242 deletes.add(new TDelete(wrap(rowName2)));
243
244 List<TDelete> deleteResults = handler.deleteMultiple(table, deletes);
245
246 assertEquals(0, deleteResults.size());
247
248 assertFalse(handler.exists(table, new TGet(wrap(rowName1))));
249 assertFalse(handler.exists(table, new TGet(wrap(rowName2))));
250 }
251
252 @Test
253 public void testDelete() throws Exception {
254 ThriftHBaseServiceHandler handler = createHandler();
255 byte[] rowName = "testDelete".getBytes();
256 ByteBuffer table = wrap(tableAname);
257
258 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
259 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
260 wrap(valueAname));
261 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname),
262 wrap(valueBname));
263 columnValues.add(columnValueA);
264 columnValues.add(columnValueB);
265 TPut put = new TPut(wrap(rowName), columnValues);
266
267 put.setColumnValues(columnValues);
268
269 handler.put(table, put);
270
271 TDelete delete = new TDelete(wrap(rowName));
272 List<TColumn> deleteColumns = new ArrayList<TColumn>();
273 TColumn deleteColumn = new TColumn(wrap(familyAname));
274 deleteColumn.setQualifier(qualifierAname);
275 deleteColumns.add(deleteColumn);
276 delete.setColumns(deleteColumns);
277
278 handler.deleteSingle(table, delete);
279
280 TGet get = new TGet(wrap(rowName));
281 TResult result = handler.get(table, get);
282 assertArrayEquals(rowName, result.getRow());
283 List<TColumnValue> returnedColumnValues = result.getColumnValues();
284 List<TColumnValue> expectedColumnValues = new ArrayList<TColumnValue>();
285 expectedColumnValues.add(columnValueB);
286 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
287 }
288
289 @Test
290 public void testDeleteAllTimestamps() throws Exception {
291 ThriftHBaseServiceHandler handler = createHandler();
292 byte[] rowName = "testDeleteAllTimestamps".getBytes();
293 ByteBuffer table = wrap(tableAname);
294
295 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
296 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
297 wrap(valueAname));
298 columnValueA.setTimestamp(System.currentTimeMillis() - 10);
299 columnValues.add(columnValueA);
300 TPut put = new TPut(wrap(rowName), columnValues);
301
302 put.setColumnValues(columnValues);
303
304 handler.put(table, put);
305 columnValueA.setTimestamp(System.currentTimeMillis());
306 handler.put(table, put);
307
308 TGet get = new TGet(wrap(rowName));
309 get.setMaxVersions(2);
310 TResult result = handler.get(table, get);
311 assertEquals(2, result.getColumnValuesSize());
312
313 TDelete delete = new TDelete(wrap(rowName));
314 List<TColumn> deleteColumns = new ArrayList<TColumn>();
315 TColumn deleteColumn = new TColumn(wrap(familyAname));
316 deleteColumn.setQualifier(qualifierAname);
317 deleteColumns.add(deleteColumn);
318 delete.setColumns(deleteColumns);
319 delete.setDeleteType(TDeleteType.DELETE_COLUMNS);
320
321 handler.deleteSingle(table, delete);
322
323 get = new TGet(wrap(rowName));
324 result = handler.get(table, get);
325 assertNull(result.getRow());
326 assertEquals(0, result.getColumnValuesSize());
327 }
328
329 @Test
330 public void testDeleteSingleTimestamp() throws Exception {
331 ThriftHBaseServiceHandler handler = createHandler();
332 byte[] rowName = "testDeleteSingleTimestamp".getBytes();
333 ByteBuffer table = wrap(tableAname);
334
335 long timestamp1 = System.currentTimeMillis() - 10;
336 long timestamp2 = System.currentTimeMillis();
337
338 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
339 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
340 wrap(valueAname));
341 columnValueA.setTimestamp(timestamp1);
342 columnValues.add(columnValueA);
343 TPut put = new TPut(wrap(rowName), columnValues);
344
345 put.setColumnValues(columnValues);
346
347 handler.put(table, put);
348 columnValueA.setTimestamp(timestamp2);
349 handler.put(table, put);
350
351 TGet get = new TGet(wrap(rowName));
352 get.setMaxVersions(2);
353 TResult result = handler.get(table, get);
354 assertEquals(2, result.getColumnValuesSize());
355
356 TDelete delete = new TDelete(wrap(rowName));
357 List<TColumn> deleteColumns = new ArrayList<TColumn>();
358 TColumn deleteColumn = new TColumn(wrap(familyAname));
359 deleteColumn.setQualifier(qualifierAname);
360 deleteColumns.add(deleteColumn);
361 delete.setColumns(deleteColumns);
362 delete.setDeleteType(TDeleteType.DELETE_COLUMN);
363
364 handler.deleteSingle(table, delete);
365
366 get = new TGet(wrap(rowName));
367 result = handler.get(table, get);
368 assertArrayEquals(rowName, result.getRow());
369 assertEquals(1, result.getColumnValuesSize());
370
371 assertEquals(timestamp1, result.getColumnValues().get(0).getTimestamp());
372 }
373
374 @Test
375 public void testIncrement() throws Exception {
376 ThriftHBaseServiceHandler handler = createHandler();
377 byte[] rowName = "testIncrement".getBytes();
378 ByteBuffer table = wrap(tableAname);
379
380 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
381 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
382 wrap(Bytes.toBytes(1L))));
383 TPut put = new TPut(wrap(rowName), columnValues);
384 put.setColumnValues(columnValues);
385 handler.put(table, put);
386
387 List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
388 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname)));
389 TIncrement increment = new TIncrement(wrap(rowName), incrementColumns);
390 handler.increment(table, increment);
391
392 TGet get = new TGet(wrap(rowName));
393 TResult result = handler.get(table, get);
394
395 assertArrayEquals(rowName, result.getRow());
396 assertEquals(1, result.getColumnValuesSize());
397 TColumnValue columnValue = result.getColumnValues().get(0);
398 assertArrayEquals(Bytes.toBytes(2L), columnValue.getValue());
399 }
400
401
402
403
404
405
406
407 @Test
408 public void testCheckAndPut() throws Exception {
409 ThriftHBaseServiceHandler handler = createHandler();
410 byte[] rowName = "testCheckAndPut".getBytes();
411 ByteBuffer table = wrap(tableAname);
412
413 List<TColumnValue> columnValuesA = new ArrayList<TColumnValue>();
414 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
415 wrap(valueAname));
416 columnValuesA.add(columnValueA);
417 TPut putA = new TPut(wrap(rowName), columnValuesA);
418 putA.setColumnValues(columnValuesA);
419
420 List<TColumnValue> columnValuesB = new ArrayList<TColumnValue>();
421 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname),
422 wrap(valueBname));
423 columnValuesB.add(columnValueB);
424 TPut putB = new TPut(wrap(rowName), columnValuesB);
425 putB.setColumnValues(columnValuesB);
426
427 assertFalse(handler.checkAndPut(table, wrap(rowName), wrap(familyAname),
428 wrap(qualifierAname), wrap(valueAname), putB));
429
430 TGet get = new TGet(wrap(rowName));
431 TResult result = handler.get(table, get);
432 assertEquals(0, result.getColumnValuesSize());
433
434 handler.put(table, putA);
435
436 assertTrue(handler.checkAndPut(table, wrap(rowName), wrap(familyAname),
437 wrap(qualifierAname), wrap(valueAname), putB));
438
439 result = handler.get(table, get);
440 assertArrayEquals(rowName, result.getRow());
441 List<TColumnValue> returnedColumnValues = result.getColumnValues();
442 List<TColumnValue> expectedColumnValues = new ArrayList<TColumnValue>();
443 expectedColumnValues.add(columnValueA);
444 expectedColumnValues.add(columnValueB);
445 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
446 }
447
448
449
450
451
452
453
454 @Test
455 public void testCheckAndDelete() throws Exception {
456 ThriftHBaseServiceHandler handler = createHandler();
457 byte[] rowName = "testCheckAndDelete".getBytes();
458 ByteBuffer table = wrap(tableAname);
459
460 List<TColumnValue> columnValuesA = new ArrayList<TColumnValue>();
461 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
462 wrap(valueAname));
463 columnValuesA.add(columnValueA);
464 TPut putA = new TPut(wrap(rowName), columnValuesA);
465 putA.setColumnValues(columnValuesA);
466
467 List<TColumnValue> columnValuesB = new ArrayList<TColumnValue>();
468 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname),
469 wrap(valueBname));
470 columnValuesB.add(columnValueB);
471 TPut putB = new TPut(wrap(rowName), columnValuesB);
472 putB.setColumnValues(columnValuesB);
473
474
475 handler.put(table, putB);
476
477 TDelete delete = new TDelete(wrap(rowName));
478
479 assertFalse(handler.checkAndDelete(table, wrap(rowName), wrap(familyAname),
480 wrap(qualifierAname), wrap(valueAname), delete));
481
482 TGet get = new TGet(wrap(rowName));
483 TResult result = handler.get(table, get);
484 assertArrayEquals(rowName, result.getRow());
485 assertTColumnValuesEqual(columnValuesB, result.getColumnValues());
486
487 handler.put(table, putA);
488
489 assertTrue(handler.checkAndDelete(table, wrap(rowName), wrap(familyAname),
490 wrap(qualifierAname), wrap(valueAname), delete));
491
492 result = handler.get(table, get);
493 assertFalse(result.isSetRow());
494 assertEquals(0, result.getColumnValuesSize());
495 }
496
497 @Test
498 public void testScan() throws Exception {
499 ThriftHBaseServiceHandler handler = createHandler();
500 ByteBuffer table = wrap(tableAname);
501
502
503 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
504 wrap(valueAname));
505 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
506 columnValues.add(columnValue);
507 for (int i = 0; i < 10; i++) {
508 TPut put = new TPut(wrap(("testScan" + i).getBytes()), columnValues);
509 handler.put(table, put);
510 }
511
512
513 TScan scan = new TScan();
514 List<TColumn> columns = new ArrayList<TColumn>();
515 TColumn column = new TColumn();
516 column.setFamily(familyAname);
517 column.setQualifier(qualifierAname);
518 columns.add(column);
519 scan.setColumns(columns);
520 scan.setStartRow("testScan".getBytes());
521 scan.setStopRow("testScan\uffff".getBytes());
522
523
524 int scanId = handler.openScanner(table, scan);
525 List<TResult> results = handler.getScannerRows(scanId, 10);
526 assertEquals(10, results.size());
527 for (int i = 0; i < 10; i++) {
528
529 assertArrayEquals(("testScan" + i).getBytes(), results.get(i).getRow());
530 }
531
532
533 results = handler.getScannerRows(scanId, 10);
534 assertEquals(0, results.size());
535
536
537 handler.closeScanner(scanId);
538 try {
539 handler.getScannerRows(scanId, 10);
540 fail("Scanner id should be invalid");
541 } catch (TIllegalArgument e) {
542 }
543 }
544
545 @Test
546 public void testScanWithFilter() throws Exception {
547 ThriftHBaseServiceHandler handler = createHandler();
548 ByteBuffer table = wrap(tableAname);
549
550
551 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
552 wrap(valueAname));
553 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
554 columnValues.add(columnValue);
555 for (int i = 0; i < 10; i++) {
556 TPut put = new TPut(wrap(("testScanWithFilter" + i).getBytes()), columnValues);
557 handler.put(table, put);
558 }
559
560
561 TScan scan = new TScan();
562 List<TColumn> columns = new ArrayList<TColumn>();
563 TColumn column = new TColumn();
564 column.setFamily(familyAname);
565 column.setQualifier(qualifierAname);
566 columns.add(column);
567 scan.setColumns(columns);
568 scan.setStartRow("testScanWithFilter".getBytes());
569 scan.setStopRow("testScanWithFilter\uffff".getBytes());
570
571 scan.setFilterString(wrap(("KeyOnlyFilter()").getBytes()));
572
573
574 int scanId = handler.openScanner(table, scan);
575 List<TResult> results = handler.getScannerRows(scanId, 10);
576 assertEquals(10, results.size());
577 for (int i = 0; i < 10; i++) {
578
579 assertArrayEquals(("testScanWithFilter" + i).getBytes(), results.get(i).getRow());
580
581 assertEquals(0, results.get(i).getColumnValues().get(0).getValue().length);
582 }
583
584
585 results = handler.getScannerRows(scanId, 10);
586 assertEquals(0, results.size());
587
588
589 handler.closeScanner(scanId);
590 try {
591 handler.getScannerRows(scanId, 10);
592 fail("Scanner id should be invalid");
593 } catch (TIllegalArgument e) {
594 }
595 }
596
597
598
599
600
601
602
603
604 private String pad(int n, byte pad) {
605 String res = Integer.toString(n);
606 while (res.length() < pad) res = "0" + res;
607 return res;
608 }
609
610 @Test
611 public void testScanWithBatchSize() throws Exception {
612 ThriftHBaseServiceHandler handler = createHandler();
613 ByteBuffer table = wrap(tableAname);
614
615
616 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
617 for (int i = 0; i < 100; i++) {
618 String colNum = pad(i, (byte) 3);
619 TColumnValue columnValue = new TColumnValue(wrap(familyAname),
620 wrap(("col" + colNum).getBytes()), wrap(("val" + colNum).getBytes()));
621 columnValues.add(columnValue);
622 }
623 TPut put = new TPut(wrap(("testScanWithBatchSize").getBytes()), columnValues);
624 handler.put(table, put);
625
626
627 TScan scan = new TScan();
628 List<TColumn> columns = new ArrayList<TColumn>();
629 TColumn column = new TColumn();
630 column.setFamily(familyAname);
631 columns.add(column);
632 scan.setColumns(columns);
633 scan.setStartRow("testScanWithBatchSize".getBytes());
634 scan.setStopRow("testScanWithBatchSize\uffff".getBytes());
635
636 scan.setBatchSize(10);
637
638
639 int scanId = handler.openScanner(table, scan);
640 List<TResult> results = null;
641 for (int i = 0; i < 10; i++) {
642
643 results = handler.getScannerRows(scanId, 1);
644 assertEquals(1, results.size());
645
646 List<TColumnValue> cols = results.get(0).getColumnValues();
647 assertEquals(10, cols.size());
648
649 for (int y = 0; y < 10; y++) {
650 int colNum = y + (10 * i);
651 String colNumPad = pad(colNum, (byte) 3);
652 assertArrayEquals(("col" + colNumPad).getBytes(), cols.get(y).getQualifier());
653 }
654 }
655
656
657 results = handler.getScannerRows(scanId, 1);
658 assertEquals(0, results.size());
659
660
661 handler.closeScanner(scanId);
662 try {
663 handler.getScannerRows(scanId, 1);
664 fail("Scanner id should be invalid");
665 } catch (TIllegalArgument e) {
666 }
667 }
668
669 @Test
670 public void testFilterRegistration() throws Exception {
671 Configuration conf = UTIL.getConfiguration();
672 conf.set("hbase.thrift.filters", "MyFilter:filterclass");
673 ThriftServer.registerFilters(conf);
674 Map<String, String> registeredFilters = ParseFilter.getAllFilters();
675 assertEquals("filterclass", registeredFilters.get("MyFilter"));
676 }
677
678 @Test
679 public void testMetrics() throws Exception {
680 Configuration conf = UTIL.getConfiguration();
681 ThriftMetrics metrics = getMetrics(conf);
682 THBaseService.Iface handler =
683 ThriftHBaseServiceHandler.newInstance(conf, metrics);
684 byte[] rowName = "testMetrics".getBytes();
685 ByteBuffer table = wrap(tableAname);
686
687 TGet get = new TGet(wrap(rowName));
688 assertFalse(handler.exists(table, get));
689
690 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
691 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
692 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
693 TPut put = new TPut(wrap(rowName), columnValues);
694 put.setColumnValues(columnValues);
695
696 handler.put(table, put);
697
698 assertTrue(handler.exists(table, get));
699 logMetrics(metrics);
700 verifyMetrics(metrics, "put_num_ops", 1);
701 verifyMetrics(metrics, "exists_num_ops", 2);
702 }
703
704 @Test
705 public void testAttribute() throws Exception {
706 byte[] rowName = "testAttribute".getBytes();
707 byte[] attributeKey = "attribute1".getBytes();
708 byte[] attributeValue = "value1".getBytes();
709 Map<ByteBuffer, ByteBuffer> attributes = new HashMap<ByteBuffer, ByteBuffer>();
710 attributes.put(wrap(attributeKey), wrap(attributeValue));
711
712 TGet tGet = new TGet(wrap(rowName));
713 tGet.setAttributes(attributes);
714 Get get = getFromThrift(tGet);
715 assertArrayEquals(get.getAttribute("attribute1"), attributeValue);
716
717 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
718 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
719 TPut tPut = new TPut(wrap(rowName) , columnValues);
720 tPut.setAttributes(attributes);
721 Put put = putFromThrift(tPut);
722 assertArrayEquals(put.getAttribute("attribute1"), attributeValue);
723
724 TScan tScan = new TScan();
725 tScan.setAttributes(attributes);
726 Scan scan = scanFromThrift(tScan);
727 assertArrayEquals(scan.getAttribute("attribute1"), attributeValue);
728
729 TDelete tDelete = new TDelete(wrap(rowName));
730 tDelete.setAttributes(attributes);
731 Delete delete = deleteFromThrift(tDelete);
732 assertArrayEquals(delete.getAttribute("attribute1"), attributeValue);
733 }
734
735
736
737
738
739
740
741 @Test
742 public void testMutateRow() throws Exception {
743 ThriftHBaseServiceHandler handler = createHandler();
744 byte[] rowName = "testMutateRow".getBytes();
745 ByteBuffer table = wrap(tableAname);
746
747 List<TColumnValue> columnValuesA = new ArrayList<TColumnValue>();
748 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
749 wrap(valueAname));
750 columnValuesA.add(columnValueA);
751 TPut putA = new TPut(wrap(rowName), columnValuesA);
752 putA.setColumnValues(columnValuesA);
753
754 handler.put(table,putA);
755
756 TGet get = new TGet(wrap(rowName));
757 TResult result = handler.get(table, get);
758 assertArrayEquals(rowName, result.getRow());
759 List<TColumnValue> returnedColumnValues = result.getColumnValues();
760
761 List<TColumnValue> expectedColumnValues = new ArrayList<TColumnValue>();
762 expectedColumnValues.add(columnValueA);
763 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
764
765 List<TColumnValue> columnValuesB = new ArrayList<TColumnValue>();
766 TColumnValue columnValueB = new TColumnValue(wrap(familyAname), wrap(qualifierBname),
767 wrap(valueBname));
768 columnValuesB.add(columnValueB);
769 TPut putB = new TPut(wrap(rowName), columnValuesB);
770 putB.setColumnValues(columnValuesB);
771
772 TDelete delete = new TDelete(wrap(rowName));
773 List<TColumn> deleteColumns = new ArrayList<TColumn>();
774 TColumn deleteColumn = new TColumn(wrap(familyAname));
775 deleteColumn.setQualifier(qualifierAname);
776 deleteColumns.add(deleteColumn);
777 delete.setColumns(deleteColumns);
778
779 List<TMutation> mutations = new ArrayList<TMutation>();
780 TMutation mutationA = TMutation.put(putB);
781 mutations.add(mutationA);
782
783 TMutation mutationB = TMutation.deleteSingle(delete);
784 mutations.add(mutationB);
785
786 TRowMutations tRowMutations = new TRowMutations(wrap(rowName),mutations);
787 handler.mutateRow(table,tRowMutations);
788
789 result = handler.get(table, get);
790 assertArrayEquals(rowName, result.getRow());
791 returnedColumnValues = result.getColumnValues();
792
793 expectedColumnValues = new ArrayList<TColumnValue>();
794 expectedColumnValues.add(columnValueB);
795 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
796 }
797
798 private static ThriftMetrics getMetrics(Configuration conf) throws Exception {
799 setupMetricsContext();
800 return new ThriftMetrics(Integer.parseInt(ThriftServer.DEFAULT_LISTEN_PORT),
801 conf, THBaseService.Iface.class);
802 }
803
804 private static void setupMetricsContext() throws IOException {
805 ContextFactory factory = ContextFactory.getFactory();
806 factory.setAttribute(ThriftMetrics.CONTEXT_NAME + ".class",
807 NoEmitMetricsContext.class.getName());
808 MetricsUtil.getContext(ThriftMetrics.CONTEXT_NAME)
809 .createRecord(ThriftMetrics.CONTEXT_NAME).remove();
810 }
811
812 private static void logMetrics(ThriftMetrics metrics) throws Exception {
813 if (LOG.isDebugEnabled()) {
814 return;
815 }
816 MetricsContext context = MetricsUtil.getContext(
817 ThriftMetrics.CONTEXT_NAME);
818 metrics.doUpdates(context);
819 for (String key : context.getAllRecords().keySet()) {
820 for (OutputRecord record : context.getAllRecords().get(key)) {
821 for (String name : record.getMetricNames()) {
822 LOG.debug("metrics:" + name + " value:" +
823 record.getMetric(name).intValue());
824 }
825 }
826 }
827 }
828
829 private static void verifyMetrics(ThriftMetrics metrics, String name, int expectValue)
830 throws Exception {
831 MetricsContext context = MetricsUtil.getContext(
832 ThriftMetrics.CONTEXT_NAME);
833 metrics.doUpdates(context);
834 OutputRecord record = context.getAllRecords().get(
835 ThriftMetrics.CONTEXT_NAME).iterator().next();
836 assertEquals(expectValue, record.getMetric(name).intValue());
837 }
838
839 @org.junit.Rule
840 public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
841 new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
842 }
843