1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.thrift2;
20
21 import com.google.common.collect.Lists;
22 import org.apache.commons.collections.CollectionUtils;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.hbase.Cell;
27 import org.apache.hadoop.hbase.CompatibilityFactory;
28 import org.apache.hadoop.hbase.CoprocessorEnvironment;
29 import org.apache.hadoop.hbase.HBaseTestingUtility;
30 import org.apache.hadoop.hbase.HColumnDescriptor;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.client.Admin;
34 import org.apache.hadoop.hbase.client.Get;
35 import org.apache.hadoop.hbase.client.HBaseAdmin;
36 import org.apache.hadoop.hbase.client.Put;
37 import org.apache.hadoop.hbase.client.Scan;
38 import org.apache.hadoop.hbase.client.Increment;
39 import org.apache.hadoop.hbase.client.Delete;
40 import org.apache.hadoop.hbase.client.Durability;
41 import org.apache.hadoop.hbase.client.Table;
42 import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
43 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
44 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
45 import org.apache.hadoop.hbase.filter.ParseFilter;
46 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
47 import org.apache.hadoop.hbase.security.UserProvider;
48 import org.apache.hadoop.hbase.test.MetricsAssertHelper;
49 import org.apache.hadoop.hbase.testclassification.MediumTests;
50 import org.apache.hadoop.hbase.thrift.ErrorThrowingGetObserver;
51 import org.apache.hadoop.hbase.thrift.ThriftMetrics;
52 import org.apache.hadoop.hbase.thrift2.generated.TAppend;
53 import org.apache.hadoop.hbase.thrift2.generated.TColumn;
54 import org.apache.hadoop.hbase.thrift2.generated.TColumnIncrement;
55 import org.apache.hadoop.hbase.thrift2.generated.TColumnValue;
56 import org.apache.hadoop.hbase.thrift2.generated.TCompareOp;
57 import org.apache.hadoop.hbase.thrift2.generated.TDelete;
58 import org.apache.hadoop.hbase.thrift2.generated.TDeleteType;
59 import org.apache.hadoop.hbase.thrift2.generated.TGet;
60 import org.apache.hadoop.hbase.thrift2.generated.THBaseService;
61 import org.apache.hadoop.hbase.thrift2.generated.TIOError;
62 import org.apache.hadoop.hbase.thrift2.generated.TIllegalArgument;
63 import org.apache.hadoop.hbase.thrift2.generated.TIncrement;
64 import org.apache.hadoop.hbase.thrift2.generated.TPut;
65 import org.apache.hadoop.hbase.thrift2.generated.TResult;
66 import org.apache.hadoop.hbase.thrift2.generated.TScan;
67 import org.apache.hadoop.hbase.thrift2.generated.TMutation;
68 import org.apache.hadoop.hbase.thrift2.generated.TRowMutations;
69 import org.apache.hadoop.hbase.thrift2.generated.TDurability;
70 import org.apache.hadoop.hbase.thrift2.generated.TTimeRange;
71 import org.apache.hadoop.hbase.util.Bytes;
72 import org.apache.thrift.TException;
73 import org.junit.AfterClass;
74 import org.junit.Before;
75 import org.junit.BeforeClass;
76 import org.junit.Test;
77 import org.junit.experimental.categories.Category;
78
79 import java.io.IOException;
80 import java.io.InterruptedIOException;
81 import java.nio.ByteBuffer;
82 import java.util.ArrayList;
83 import java.util.Arrays;
84 import java.util.Collections;
85 import java.util.Comparator;
86 import java.util.List;
87 import java.util.Map;
88 import java.util.HashMap;
89 import java.util.concurrent.TimeUnit;
90
91 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.getFromThrift;
92 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.putFromThrift;
93 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.scanFromThrift;
94 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.incrementFromThrift;
95 import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.deleteFromThrift;
96 import static org.junit.Assert.*;
97 import static java.nio.ByteBuffer.wrap;
98
99
100
101
102
103 @Category(MediumTests.class)
104 public class TestThriftHBaseServiceHandler {
105
106 private static final Log LOG = LogFactory.getLog(TestThriftHBaseServiceHandler.class);
107 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
108
109
110 private static byte[] tableAname = Bytes.toBytes("tableA");
111 private static byte[] familyAname = Bytes.toBytes("familyA");
112 private static byte[] familyBname = Bytes.toBytes("familyB");
113 private static byte[] qualifierAname = Bytes.toBytes("qualifierA");
114 private static byte[] qualifierBname = Bytes.toBytes("qualifierB");
115 private static byte[] valueAname = Bytes.toBytes("valueA");
116 private static byte[] valueBname = Bytes.toBytes("valueB");
117 private static HColumnDescriptor[] families = new HColumnDescriptor[] {
118 new HColumnDescriptor(familyAname).setMaxVersions(3),
119 new HColumnDescriptor(familyBname).setMaxVersions(2)
120 };
121
122
123 private static final MetricsAssertHelper metricsHelper =
124 CompatibilityFactory.getInstance(MetricsAssertHelper.class);
125
126
127 public void assertTColumnValuesEqual(List<TColumnValue> columnValuesA,
128 List<TColumnValue> columnValuesB) {
129 assertEquals(columnValuesA.size(), columnValuesB.size());
130 Comparator<TColumnValue> comparator = new Comparator<TColumnValue>() {
131 @Override
132 public int compare(TColumnValue o1, TColumnValue o2) {
133 return Bytes.compareTo(Bytes.add(o1.getFamily(), o1.getQualifier()),
134 Bytes.add(o2.getFamily(), o2.getQualifier()));
135 }
136 };
137 Collections.sort(columnValuesA, comparator);
138 Collections.sort(columnValuesB, comparator);
139
140 for (int i = 0; i < columnValuesA.size(); i++) {
141 TColumnValue a = columnValuesA.get(i);
142 TColumnValue b = columnValuesB.get(i);
143 assertTColumnValueEqual(a, b);
144 }
145 }
146
147 public void assertTColumnValueEqual(TColumnValue a, TColumnValue b) {
148 assertArrayEquals(a.getFamily(), b.getFamily());
149 assertArrayEquals(a.getQualifier(), b.getQualifier());
150 assertArrayEquals(a.getValue(), b.getValue());
151 }
152
153 @BeforeClass
154 public static void beforeClass() throws Exception {
155 UTIL.getConfiguration().set("hbase.client.retries.number", "3");
156 UTIL.startMiniCluster();
157 Admin admin = new HBaseAdmin(UTIL.getConfiguration());
158 HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(tableAname));
159 for (HColumnDescriptor family : families) {
160 tableDescriptor.addFamily(family);
161 }
162 admin.createTable(tableDescriptor);
163 admin.close();
164 }
165
166 @AfterClass
167 public static void afterClass() throws Exception {
168 UTIL.shutdownMiniCluster();
169 }
170
171 @Before
172 public void setup() throws Exception {
173
174 }
175
176 private ThriftHBaseServiceHandler createHandler() throws TException {
177 try {
178 Configuration conf = UTIL.getConfiguration();
179 return new ThriftHBaseServiceHandler(conf, UserProvider.instantiate(conf));
180 } catch (IOException ie) {
181 throw new TException(ie);
182 }
183 }
184
185 @Test
186 public void testExists() throws TIOError, TException {
187 ThriftHBaseServiceHandler handler = createHandler();
188 byte[] rowName = "testExists".getBytes();
189 ByteBuffer table = wrap(tableAname);
190
191 TGet get = new TGet(wrap(rowName));
192 assertFalse(handler.exists(table, get));
193
194 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
195 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
196 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
197 TPut put = new TPut(wrap(rowName), columnValues);
198 put.setColumnValues(columnValues);
199
200 handler.put(table, put);
201
202 assertTrue(handler.exists(table, get));
203 }
204
205 @Test
206 public void testExistsAll() throws TIOError, TException {
207 ThriftHBaseServiceHandler handler = createHandler();
208 byte[] rowName1 = "testExistsAll1".getBytes();
209 byte[] rowName2 = "testExistsAll2".getBytes();
210 ByteBuffer table = wrap(tableAname);
211
212 List<TGet> gets = new ArrayList<>();
213 gets.add(new TGet(wrap(rowName2)));
214 gets.add(new TGet(wrap(rowName2)));
215 List<Boolean> existsResult1 = handler.existsAll(table, gets);
216 assertFalse(existsResult1.get(0));
217 assertFalse(existsResult1.get(1));
218
219 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
220 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
221 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
222 List<TPut> puts = new ArrayList<TPut>();
223 puts.add(new TPut(wrap(rowName1), columnValues));
224 puts.add(new TPut(wrap(rowName2), columnValues));
225
226 handler.putMultiple(table, puts);
227 List<Boolean> existsResult2 = handler.existsAll(table,gets );
228
229 assertTrue(existsResult2.get(0));
230 assertTrue(existsResult2.get(1));
231 }
232
233 @Test
234 public void testPutGet() throws Exception {
235 ThriftHBaseServiceHandler handler = createHandler();
236 byte[] rowName = "testPutGet".getBytes();
237 ByteBuffer table = wrap(tableAname);
238
239 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
240 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
241 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
242 TPut put = new TPut(wrap(rowName), columnValues);
243
244 put.setColumnValues(columnValues);
245
246 handler.put(table, put);
247
248 TGet get = new TGet(wrap(rowName));
249
250 TResult result = handler.get(table, get);
251 assertArrayEquals(rowName, result.getRow());
252 List<TColumnValue> returnedColumnValues = result.getColumnValues();
253 assertTColumnValuesEqual(columnValues, returnedColumnValues);
254 }
255
256 @Test
257 public void testPutGetMultiple() throws Exception {
258 ThriftHBaseServiceHandler handler = createHandler();
259 ByteBuffer table = wrap(tableAname);
260 byte[] rowName1 = "testPutGetMultiple1".getBytes();
261 byte[] rowName2 = "testPutGetMultiple2".getBytes();
262
263 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
264 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
265 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
266 List<TPut> puts = new ArrayList<TPut>();
267 puts.add(new TPut(wrap(rowName1), columnValues));
268 puts.add(new TPut(wrap(rowName2), columnValues));
269
270 handler.putMultiple(table, puts);
271
272 List<TGet> gets = new ArrayList<TGet>();
273 gets.add(new TGet(wrap(rowName1)));
274 gets.add(new TGet(wrap(rowName2)));
275
276 List<TResult> results = handler.getMultiple(table, gets);
277 assertEquals(2, results.size());
278
279 assertArrayEquals(rowName1, results.get(0).getRow());
280 assertTColumnValuesEqual(columnValues, results.get(0).getColumnValues());
281
282 assertArrayEquals(rowName2, results.get(1).getRow());
283 assertTColumnValuesEqual(columnValues, results.get(1).getColumnValues());
284 }
285
286 @Test
287 public void testDeleteMultiple() throws Exception {
288 ThriftHBaseServiceHandler handler = createHandler();
289 ByteBuffer table = wrap(tableAname);
290 byte[] rowName1 = "testDeleteMultiple1".getBytes();
291 byte[] rowName2 = "testDeleteMultiple2".getBytes();
292
293 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
294 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
295 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
296 List<TPut> puts = new ArrayList<TPut>();
297 puts.add(new TPut(wrap(rowName1), columnValues));
298 puts.add(new TPut(wrap(rowName2), columnValues));
299
300 handler.putMultiple(table, puts);
301
302 List<TDelete> deletes = new ArrayList<TDelete>();
303 deletes.add(new TDelete(wrap(rowName1)));
304 deletes.add(new TDelete(wrap(rowName2)));
305
306 List<TDelete> deleteResults = handler.deleteMultiple(table, deletes);
307
308 assertEquals(0, deleteResults.size());
309
310 assertFalse(handler.exists(table, new TGet(wrap(rowName1))));
311 assertFalse(handler.exists(table, new TGet(wrap(rowName2))));
312 }
313
314 @Test
315 public void testDelete() throws Exception {
316 ThriftHBaseServiceHandler handler = createHandler();
317 byte[] rowName = "testDelete".getBytes();
318 ByteBuffer table = wrap(tableAname);
319
320 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
321 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
322 wrap(valueAname));
323 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname),
324 wrap(valueBname));
325 columnValues.add(columnValueA);
326 columnValues.add(columnValueB);
327 TPut put = new TPut(wrap(rowName), columnValues);
328
329 put.setColumnValues(columnValues);
330
331 handler.put(table, put);
332
333 TDelete delete = new TDelete(wrap(rowName));
334 List<TColumn> deleteColumns = new ArrayList<TColumn>();
335 TColumn deleteColumn = new TColumn(wrap(familyAname));
336 deleteColumn.setQualifier(qualifierAname);
337 deleteColumns.add(deleteColumn);
338 delete.setColumns(deleteColumns);
339
340 handler.deleteSingle(table, delete);
341
342 TGet get = new TGet(wrap(rowName));
343 TResult result = handler.get(table, get);
344 assertArrayEquals(rowName, result.getRow());
345 List<TColumnValue> returnedColumnValues = result.getColumnValues();
346 List<TColumnValue> expectedColumnValues = new ArrayList<TColumnValue>();
347 expectedColumnValues.add(columnValueB);
348 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
349 }
350
351 @Test
352 public void testDeleteAllTimestamps() throws Exception {
353 ThriftHBaseServiceHandler handler = createHandler();
354 byte[] rowName = "testDeleteAllTimestamps".getBytes();
355 ByteBuffer table = wrap(tableAname);
356
357 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
358 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
359 wrap(valueAname));
360 columnValueA.setTimestamp(System.currentTimeMillis() - 10);
361 columnValues.add(columnValueA);
362 TPut put = new TPut(wrap(rowName), columnValues);
363
364 put.setColumnValues(columnValues);
365
366 handler.put(table, put);
367 columnValueA.setTimestamp(System.currentTimeMillis());
368 handler.put(table, put);
369
370 TGet get = new TGet(wrap(rowName));
371 get.setMaxVersions(2);
372 TResult result = handler.get(table, get);
373 assertEquals(2, result.getColumnValuesSize());
374
375 TDelete delete = new TDelete(wrap(rowName));
376 List<TColumn> deleteColumns = new ArrayList<TColumn>();
377 TColumn deleteColumn = new TColumn(wrap(familyAname));
378 deleteColumn.setQualifier(qualifierAname);
379 deleteColumns.add(deleteColumn);
380 delete.setColumns(deleteColumns);
381 delete.setDeleteType(TDeleteType.DELETE_COLUMNS);
382
383 handler.deleteSingle(table, delete);
384
385 get = new TGet(wrap(rowName));
386 result = handler.get(table, get);
387 assertNull(result.getRow());
388 assertEquals(0, result.getColumnValuesSize());
389 }
390
391 @Test
392 public void testDeleteSingleTimestamp() throws Exception {
393 ThriftHBaseServiceHandler handler = createHandler();
394 byte[] rowName = "testDeleteSingleTimestamp".getBytes();
395 ByteBuffer table = wrap(tableAname);
396
397 long timestamp1 = System.currentTimeMillis() - 10;
398 long timestamp2 = System.currentTimeMillis();
399
400 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
401 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
402 wrap(valueAname));
403 columnValueA.setTimestamp(timestamp1);
404 columnValues.add(columnValueA);
405 TPut put = new TPut(wrap(rowName), columnValues);
406
407 put.setColumnValues(columnValues);
408
409 handler.put(table, put);
410 columnValueA.setTimestamp(timestamp2);
411 handler.put(table, put);
412
413 TGet get = new TGet(wrap(rowName));
414 get.setMaxVersions(2);
415 TResult result = handler.get(table, get);
416 assertEquals(2, result.getColumnValuesSize());
417
418 TDelete delete = new TDelete(wrap(rowName));
419 List<TColumn> deleteColumns = new ArrayList<TColumn>();
420 TColumn deleteColumn = new TColumn(wrap(familyAname));
421 deleteColumn.setQualifier(qualifierAname);
422 deleteColumns.add(deleteColumn);
423 delete.setColumns(deleteColumns);
424 delete.setDeleteType(TDeleteType.DELETE_COLUMN);
425
426 handler.deleteSingle(table, delete);
427
428 get = new TGet(wrap(rowName));
429 result = handler.get(table, get);
430 assertArrayEquals(rowName, result.getRow());
431 assertEquals(1, result.getColumnValuesSize());
432
433 assertEquals(timestamp1, result.getColumnValues().get(0).getTimestamp());
434 }
435
436 @Test
437 public void testIncrement() throws Exception {
438 ThriftHBaseServiceHandler handler = createHandler();
439 byte[] rowName = "testIncrement".getBytes();
440 ByteBuffer table = wrap(tableAname);
441
442 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
443 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname),
444 wrap(Bytes.toBytes(1L))));
445 TPut put = new TPut(wrap(rowName), columnValues);
446 put.setColumnValues(columnValues);
447 handler.put(table, put);
448
449 List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
450 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname)));
451 TIncrement increment = new TIncrement(wrap(rowName), incrementColumns);
452 handler.increment(table, increment);
453
454 TGet get = new TGet(wrap(rowName));
455 TResult result = handler.get(table, get);
456
457 assertArrayEquals(rowName, result.getRow());
458 assertEquals(1, result.getColumnValuesSize());
459 TColumnValue columnValue = result.getColumnValues().get(0);
460 assertArrayEquals(Bytes.toBytes(2L), columnValue.getValue());
461 }
462
463 @Test
464 public void testAppend() throws Exception {
465 ThriftHBaseServiceHandler handler = createHandler();
466 byte[] rowName = "testAppend".getBytes();
467 ByteBuffer table = wrap(tableAname);
468 byte[] v1 = Bytes.toBytes("42");
469 byte[] v2 = Bytes.toBytes("23");
470 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
471 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(v1)));
472 TPut put = new TPut(wrap(rowName), columnValues);
473 put.setColumnValues(columnValues);
474 handler.put(table, put);
475
476 List<TColumnValue> appendColumns = new ArrayList<TColumnValue>();
477 appendColumns.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(v2)));
478 TAppend append = new TAppend(wrap(rowName), appendColumns);
479 handler.append(table, append);
480
481 TGet get = new TGet(wrap(rowName));
482 TResult result = handler.get(table, get);
483
484 assertArrayEquals(rowName, result.getRow());
485 assertEquals(1, result.getColumnValuesSize());
486 TColumnValue columnValue = result.getColumnValues().get(0);
487 assertArrayEquals(Bytes.add(v1, v2), columnValue.getValue());
488 }
489
490
491
492
493
494
495
496 @Test
497 public void testCheckAndPut() throws Exception {
498 ThriftHBaseServiceHandler handler = createHandler();
499 byte[] rowName = "testCheckAndPut".getBytes();
500 ByteBuffer table = wrap(tableAname);
501
502 List<TColumnValue> columnValuesA = new ArrayList<TColumnValue>();
503 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
504 wrap(valueAname));
505 columnValuesA.add(columnValueA);
506 TPut putA = new TPut(wrap(rowName), columnValuesA);
507 putA.setColumnValues(columnValuesA);
508
509 List<TColumnValue> columnValuesB = new ArrayList<TColumnValue>();
510 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname),
511 wrap(valueBname));
512 columnValuesB.add(columnValueB);
513 TPut putB = new TPut(wrap(rowName), columnValuesB);
514 putB.setColumnValues(columnValuesB);
515
516 assertFalse(handler.checkAndPut(table, wrap(rowName), wrap(familyAname),
517 wrap(qualifierAname), wrap(valueAname), putB));
518
519 TGet get = new TGet(wrap(rowName));
520 TResult result = handler.get(table, get);
521 assertEquals(0, result.getColumnValuesSize());
522
523 handler.put(table, putA);
524
525 assertTrue(handler.checkAndPut(table, wrap(rowName), wrap(familyAname),
526 wrap(qualifierAname), wrap(valueAname), putB));
527
528 result = handler.get(table, get);
529 assertArrayEquals(rowName, result.getRow());
530 List<TColumnValue> returnedColumnValues = result.getColumnValues();
531 List<TColumnValue> expectedColumnValues = new ArrayList<TColumnValue>();
532 expectedColumnValues.add(columnValueA);
533 expectedColumnValues.add(columnValueB);
534 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
535 }
536
537
538
539
540
541
542
543 @Test
544 public void testCheckAndDelete() throws Exception {
545 ThriftHBaseServiceHandler handler = createHandler();
546 byte[] rowName = "testCheckAndDelete".getBytes();
547 ByteBuffer table = wrap(tableAname);
548
549 List<TColumnValue> columnValuesA = new ArrayList<TColumnValue>();
550 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
551 wrap(valueAname));
552 columnValuesA.add(columnValueA);
553 TPut putA = new TPut(wrap(rowName), columnValuesA);
554 putA.setColumnValues(columnValuesA);
555
556 List<TColumnValue> columnValuesB = new ArrayList<TColumnValue>();
557 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname),
558 wrap(valueBname));
559 columnValuesB.add(columnValueB);
560 TPut putB = new TPut(wrap(rowName), columnValuesB);
561 putB.setColumnValues(columnValuesB);
562
563
564 handler.put(table, putB);
565
566 TDelete delete = new TDelete(wrap(rowName));
567
568 assertFalse(handler.checkAndDelete(table, wrap(rowName), wrap(familyAname),
569 wrap(qualifierAname), wrap(valueAname), delete));
570
571 TGet get = new TGet(wrap(rowName));
572 TResult result = handler.get(table, get);
573 assertArrayEquals(rowName, result.getRow());
574 assertTColumnValuesEqual(columnValuesB, result.getColumnValues());
575
576 handler.put(table, putA);
577
578 assertTrue(handler.checkAndDelete(table, wrap(rowName), wrap(familyAname),
579 wrap(qualifierAname), wrap(valueAname), delete));
580
581 result = handler.get(table, get);
582 assertFalse(result.isSetRow());
583 assertEquals(0, result.getColumnValuesSize());
584 }
585
586 @Test
587 public void testScan() throws Exception {
588 ThriftHBaseServiceHandler handler = createHandler();
589 ByteBuffer table = wrap(tableAname);
590
591
592 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
593 wrap(valueAname));
594 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
595 columnValues.add(columnValue);
596 for (int i = 0; i < 10; i++) {
597 TPut put = new TPut(wrap(("testScan" + i).getBytes()), columnValues);
598 handler.put(table, put);
599 }
600
601
602 TScan scan = new TScan();
603 List<TColumn> columns = new ArrayList<TColumn>();
604 TColumn column = new TColumn();
605 column.setFamily(familyAname);
606 column.setQualifier(qualifierAname);
607 columns.add(column);
608 scan.setColumns(columns);
609 scan.setStartRow("testScan".getBytes());
610 scan.setStopRow("testScan\uffff".getBytes());
611
612
613 int scanId = handler.openScanner(table, scan);
614 List<TResult> results = handler.getScannerRows(scanId, 10);
615 assertEquals(10, results.size());
616 for (int i = 0; i < 10; i++) {
617
618 assertArrayEquals(("testScan" + i).getBytes(), results.get(i).getRow());
619 }
620
621
622 results = handler.getScannerRows(scanId, 10);
623 assertEquals(0, results.size());
624
625
626 handler.closeScanner(scanId);
627 try {
628 handler.getScannerRows(scanId, 10);
629 fail("Scanner id should be invalid");
630 } catch (TIllegalArgument e) {
631 }
632 }
633
634
635
636
637
638
639 @Test
640 public void testLongLivedScan() throws Exception {
641 int numTrials = 6;
642 int trialPause = 1000;
643 int cleanUpInterval = 100;
644 Configuration conf = new Configuration(UTIL.getConfiguration());
645
646 conf.setInt(ThriftHBaseServiceHandler.MAX_IDLETIME, (numTrials / 2) * trialPause);
647 conf.setInt(ThriftHBaseServiceHandler.CLEANUP_INTERVAL, cleanUpInterval);
648 ThriftHBaseServiceHandler handler = new ThriftHBaseServiceHandler(conf,
649 UserProvider.instantiate(conf));
650
651 ByteBuffer table = wrap(tableAname);
652
653 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
654 wrap(valueAname));
655 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
656 columnValues.add(columnValue);
657 for (int i = 0; i < numTrials; i++) {
658 TPut put = new TPut(wrap(("testScan" + i).getBytes()), columnValues);
659 handler.put(table, put);
660 }
661
662
663 TScan scan = new TScan();
664 List<TColumn> columns = new ArrayList<TColumn>();
665 TColumn column = new TColumn();
666 column.setFamily(familyAname);
667 column.setQualifier(qualifierAname);
668 columns.add(column);
669 scan.setColumns(columns);
670 scan.setStartRow("testScan".getBytes());
671 scan.setStopRow("testScan\uffff".getBytes());
672
673 scan.setCaching(1);
674
675
676 int scanId = handler.openScanner(table, scan);
677 for (int i = 0; i < numTrials; i++) {
678
679 List<TResult> results = handler.getScannerRows(scanId, 1);
680 assertArrayEquals(("testScan" + i).getBytes(), results.get(0).getRow());
681 Thread.sleep(trialPause);
682 }
683 }
684
685 @Test
686 public void testReverseScan() throws Exception {
687 ThriftHBaseServiceHandler handler = createHandler();
688 ByteBuffer table = wrap(tableAname);
689
690
691 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
692 wrap(valueAname));
693 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
694 columnValues.add(columnValue);
695 for (int i = 0; i < 10; i++) {
696 TPut put = new TPut(wrap(("testReverseScan" + i).getBytes()), columnValues);
697 handler.put(table, put);
698 }
699
700
701 TScan scan = new TScan();
702 scan.setReversed(true);
703 List<TColumn> columns = new ArrayList<TColumn>();
704 TColumn column = new TColumn();
705 column.setFamily(familyAname);
706 column.setQualifier(qualifierAname);
707 columns.add(column);
708 scan.setColumns(columns);
709 scan.setStartRow("testReverseScan\uffff".getBytes());
710 scan.setStopRow("testReverseScan".getBytes());
711
712
713 int scanId = handler.openScanner(table, scan);
714 List<TResult> results = handler.getScannerRows(scanId, 10);
715 assertEquals(10, results.size());
716 for (int i = 0; i < 10; i++) {
717
718 assertArrayEquals(("testReverseScan" + (9 - i)).getBytes(), results.get(i).getRow());
719 }
720
721
722 results = handler.getScannerRows(scanId, 10);
723 assertEquals(0, results.size());
724
725
726 handler.closeScanner(scanId);
727 try {
728 handler.getScannerRows(scanId, 10);
729 fail("Scanner id should be invalid");
730 } catch (TIllegalArgument e) {
731 }
732 }
733
734 @Test
735 public void testScanWithFilter() throws Exception {
736 ThriftHBaseServiceHandler handler = createHandler();
737 ByteBuffer table = wrap(tableAname);
738
739
740 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
741 wrap(valueAname));
742 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
743 columnValues.add(columnValue);
744 for (int i = 0; i < 10; i++) {
745 TPut put = new TPut(wrap(("testScanWithFilter" + i).getBytes()), columnValues);
746 handler.put(table, put);
747 }
748
749
750 TScan scan = new TScan();
751 List<TColumn> columns = new ArrayList<TColumn>();
752 TColumn column = new TColumn();
753 column.setFamily(familyAname);
754 column.setQualifier(qualifierAname);
755 columns.add(column);
756 scan.setColumns(columns);
757 scan.setStartRow("testScanWithFilter".getBytes());
758 scan.setStopRow("testScanWithFilter\uffff".getBytes());
759
760 scan.setFilterString(wrap(("KeyOnlyFilter()").getBytes()));
761
762
763 int scanId = handler.openScanner(table, scan);
764 List<TResult> results = handler.getScannerRows(scanId, 10);
765 assertEquals(10, results.size());
766 for (int i = 0; i < 10; i++) {
767
768 assertArrayEquals(("testScanWithFilter" + i).getBytes(), results.get(i).getRow());
769
770 assertEquals(0, results.get(i).getColumnValues().get(0).getValue().length);
771 }
772
773
774 results = handler.getScannerRows(scanId, 10);
775 assertEquals(0, results.size());
776
777
778 handler.closeScanner(scanId);
779 try {
780 handler.getScannerRows(scanId, 10);
781 fail("Scanner id should be invalid");
782 } catch (TIllegalArgument e) {
783 }
784 }
785
786 @Test
787 public void testScanWithColumnFamilyTimeRange() throws Exception {
788 ThriftHBaseServiceHandler handler = createHandler();
789 ByteBuffer table = wrap(tableAname);
790
791
792 TColumnValue familyAColumnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
793 wrap(valueAname));
794 TColumnValue familyBColumnValue = new TColumnValue(wrap(familyBname), wrap(qualifierBname),
795 wrap(valueBname));
796 long minTimestamp = System.currentTimeMillis();
797 for (int i = 0; i < 10; i++) {
798 familyAColumnValue.setTimestamp(minTimestamp + i);
799 familyBColumnValue.setTimestamp(minTimestamp + i);
800 List<TColumnValue> columnValues = new ArrayList<>(2);
801 columnValues.add(familyAColumnValue);
802 columnValues.add(familyBColumnValue);
803 TPut put = new TPut(wrap(("testScanWithColumnFamilyTimeRange" + i).getBytes()),
804 columnValues);
805 handler.put(table, put);
806 }
807
808
809 TScan scan = new TScan();
810 Map<ByteBuffer,TTimeRange> colFamTimeRangeMap = new HashMap<>(2);
811 colFamTimeRangeMap.put(wrap(familyAname), new TTimeRange(minTimestamp + 3, minTimestamp + 5));
812 colFamTimeRangeMap.put(wrap(familyBname), new TTimeRange(minTimestamp + 6, minTimestamp + 9));
813 scan.setColFamTimeRangeMap(colFamTimeRangeMap);
814
815
816 int scanId = handler.openScanner(table, scan);
817 List<TResult> results = handler.getScannerRows(scanId, 5);
818 assertEquals(5, results.size());
819 int familyACount = 0;
820 int familyBCount = 0;
821 for (TResult result : results) {
822 List<TColumnValue> columnValues = result.getColumnValues();
823 if (CollectionUtils.isNotEmpty(columnValues)) {
824 if (Bytes.equals(familyAname, columnValues.get(0).getFamily())) {
825 familyACount++;
826 } else if (Bytes.equals(familyBname, columnValues.get(0).getFamily())) {
827 familyBCount++;
828 }
829 }
830 }
831 assertEquals(2, familyACount);
832 assertEquals(3, familyBCount);
833
834
835 results = handler.getScannerRows(scanId, 1);
836 assertEquals(0, results.size());
837
838
839 handler.closeScanner(scanId);
840 try {
841 handler.getScannerRows(scanId, 1);
842 fail("Scanner id should be invalid");
843 } catch (TIllegalArgument e) {
844 }
845 }
846
847 @Test
848 public void testSmallScan() throws Exception {
849 ThriftHBaseServiceHandler handler = createHandler();
850 ByteBuffer table = wrap(tableAname);
851
852
853 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
854 wrap(valueAname));
855 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
856 columnValues.add(columnValue);
857 for (int i = 0; i < 10; i++) {
858 TPut put = new TPut(wrap(("testSmallScan" + i).getBytes()), columnValues);
859 handler.put(table, put);
860 }
861
862
863 TScan scan = new TScan();
864 scan.setStartRow("testSmallScan".getBytes());
865 scan.setStopRow("testSmallScan\uffff".getBytes());
866 scan.setSmall(true);
867 scan.setCaching(2);
868
869
870 int scanId = handler.openScanner(table, scan);
871 List<TResult> results = handler.getScannerRows(scanId, 10);
872 assertEquals(10, results.size());
873 for (int i = 0; i < 10; i++) {
874
875 assertArrayEquals(("testSmallScan" + i).getBytes(), results.get(i).getRow());
876 }
877
878
879 results = handler.getScannerRows(scanId, 10);
880 assertEquals(0, results.size());
881
882
883 handler.closeScanner(scanId);
884 try {
885 handler.getScannerRows(scanId, 10);
886 fail("Scanner id should be invalid");
887 } catch (TIllegalArgument e) {
888 }
889 }
890
891 @Test
892 public void testPutTTL() throws Exception {
893 ThriftHBaseServiceHandler handler = createHandler();
894 byte[] rowName = "testPutTTL".getBytes();
895 ByteBuffer table = wrap(tableAname);
896 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
897
898
899 columnValues.add(
900 new TColumnValue(
901 wrap(familyAname),
902 wrap(qualifierAname),
903 wrap(Bytes.toBytes(1L))));
904
905
906 TPut put = new TPut(wrap(rowName), columnValues);
907 put.setColumnValues(columnValues);
908
909 Map<ByteBuffer, ByteBuffer> attributes = new HashMap<>();
910
911
912 long ttlTimeMs = 2000L;
913
914
915 attributes.put(wrap(Bytes.toBytes("_ttl")), wrap(Bytes.toBytes(ttlTimeMs)));
916
917 put.setAttributes(attributes);
918
919 handler.put(table, put);
920
921
922 TGet getOne = new TGet(wrap(rowName));
923 TResult resultOne = handler.get(table, getOne);
924
925
926 assertArrayEquals(rowName, resultOne.getRow());
927 assertEquals(1, resultOne.getColumnValuesSize());
928
929
930 Thread.sleep(ttlTimeMs * 15);
931
932 TGet getTwo = new TGet(wrap(rowName));
933 TResult resultTwo = handler.get(table, getTwo);
934
935
936
937 assertNull(resultTwo.getRow());
938 assertEquals(0, resultTwo.getColumnValuesSize());
939 }
940
941
942
943
944
945
946
947
948 private String pad(int n, byte pad) {
949 String res = Integer.toString(n);
950 while (res.length() < pad) res = "0" + res;
951 return res;
952 }
953
954 @Test
955 public void testScanWithBatchSize() throws Exception {
956 ThriftHBaseServiceHandler handler = createHandler();
957 ByteBuffer table = wrap(tableAname);
958
959
960 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
961 for (int i = 0; i < 100; i++) {
962 String colNum = pad(i, (byte) 3);
963 TColumnValue columnValue = new TColumnValue(wrap(familyAname),
964 wrap(("col" + colNum).getBytes()), wrap(("val" + colNum).getBytes()));
965 columnValues.add(columnValue);
966 }
967 TPut put = new TPut(wrap(("testScanWithBatchSize").getBytes()), columnValues);
968 handler.put(table, put);
969
970
971 TScan scan = new TScan();
972 List<TColumn> columns = new ArrayList<TColumn>();
973 TColumn column = new TColumn();
974 column.setFamily(familyAname);
975 columns.add(column);
976 scan.setColumns(columns);
977 scan.setStartRow("testScanWithBatchSize".getBytes());
978 scan.setStopRow("testScanWithBatchSize\uffff".getBytes());
979
980 scan.setBatchSize(10);
981
982
983 int scanId = handler.openScanner(table, scan);
984 List<TResult> results = null;
985 for (int i = 0; i < 10; i++) {
986
987 results = handler.getScannerRows(scanId, 1);
988 assertEquals(1, results.size());
989
990 List<TColumnValue> cols = results.get(0).getColumnValues();
991 assertEquals(10, cols.size());
992
993 for (int y = 0; y < 10; y++) {
994 int colNum = y + (10 * i);
995 String colNumPad = pad(colNum, (byte) 3);
996 assertArrayEquals(("col" + colNumPad).getBytes(), cols.get(y).getQualifier());
997 }
998 }
999
1000
1001 results = handler.getScannerRows(scanId, 1);
1002 assertEquals(0, results.size());
1003
1004
1005 handler.closeScanner(scanId);
1006 try {
1007 handler.getScannerRows(scanId, 1);
1008 fail("Scanner id should be invalid");
1009 } catch (TIllegalArgument e) {
1010 }
1011 }
1012
1013 @Test
1014 public void testGetScannerResults() throws Exception {
1015 ThriftHBaseServiceHandler handler = createHandler();
1016 ByteBuffer table = wrap(tableAname);
1017
1018
1019 TColumnValue columnValue =
1020 new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname));
1021 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
1022 columnValues.add(columnValue);
1023 for (int i = 0; i < 20; i++) {
1024 TPut put =
1025 new TPut(wrap(("testGetScannerResults" + pad(i, (byte) 2)).getBytes()), columnValues);
1026 handler.put(table, put);
1027 }
1028
1029
1030 TScan scan = new TScan();
1031 List<TColumn> columns = new ArrayList<TColumn>();
1032 TColumn column = new TColumn();
1033 column.setFamily(familyAname);
1034 column.setQualifier(qualifierAname);
1035 columns.add(column);
1036 scan.setColumns(columns);
1037 scan.setStartRow("testGetScannerResults".getBytes());
1038
1039
1040 scan.setStopRow("testGetScannerResults05".getBytes());
1041 List<TResult> results = handler.getScannerResults(table, scan, 5);
1042 assertEquals(5, results.size());
1043 for (int i = 0; i < 5; i++) {
1044
1045 assertArrayEquals(("testGetScannerResults" + pad(i, (byte) 2)).getBytes(), results.get(i)
1046 .getRow());
1047 }
1048
1049
1050 scan.setStopRow("testGetScannerResults10".getBytes());
1051 results = handler.getScannerResults(table, scan, 10);
1052 assertEquals(10, results.size());
1053 for (int i = 0; i < 10; i++) {
1054
1055 assertArrayEquals(("testGetScannerResults" + pad(i, (byte) 2)).getBytes(), results.get(i)
1056 .getRow());
1057 }
1058
1059
1060 scan.setStopRow("testGetScannerResults20".getBytes());
1061 results = handler.getScannerResults(table, scan, 20);
1062 assertEquals(20, results.size());
1063 for (int i = 0; i < 20; i++) {
1064
1065 assertArrayEquals(("testGetScannerResults" + pad(i, (byte) 2)).getBytes(), results.get(i)
1066 .getRow());
1067 }
1068
1069
1070 scan = new TScan();
1071 scan.setColumns(columns);
1072 scan.setReversed(true);
1073 scan.setStartRow("testGetScannerResults20".getBytes());
1074 scan.setStopRow("testGetScannerResults".getBytes());
1075 results = handler.getScannerResults(table, scan, 20);
1076 assertEquals(20, results.size());
1077 for (int i = 0; i < 20; i++) {
1078
1079 assertArrayEquals(("testGetScannerResults" + pad(19 - i, (byte) 2)).getBytes(), results.get(i)
1080 .getRow());
1081 }
1082 }
1083
1084 @Test
1085 public void testFilterRegistration() throws Exception {
1086 Configuration conf = UTIL.getConfiguration();
1087 conf.set("hbase.thrift.filters", "MyFilter:filterclass");
1088 ThriftServer.registerFilters(conf);
1089 Map<String, String> registeredFilters = ParseFilter.getAllFilters();
1090 assertEquals("filterclass", registeredFilters.get("MyFilter"));
1091 }
1092
1093 @Test
1094 public void testMetrics() throws Exception {
1095 Configuration conf = UTIL.getConfiguration();
1096 ThriftMetrics metrics = getMetrics(conf);
1097 ThriftHBaseServiceHandler hbaseHandler = createHandler();
1098 THBaseService.Iface handler =
1099 ThriftHBaseServiceHandler.newInstance(hbaseHandler, metrics);
1100 byte[] rowName = "testMetrics".getBytes();
1101 ByteBuffer table = wrap(tableAname);
1102
1103 TGet get = new TGet(wrap(rowName));
1104 assertFalse(handler.exists(table, get));
1105
1106 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
1107 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
1108 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname)));
1109 TPut put = new TPut(wrap(rowName), columnValues);
1110 put.setColumnValues(columnValues);
1111
1112 handler.put(table, put);
1113
1114 assertTrue(handler.exists(table, get));
1115 metricsHelper.assertCounter("put_num_ops", 1, metrics.getSource());
1116 metricsHelper.assertCounter( "exists_num_ops", 2, metrics.getSource());
1117 }
1118
1119 private static ThriftMetrics getMetrics(Configuration conf) throws Exception {
1120 ThriftMetrics m = new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.TWO);
1121 m.getSource().init();
1122 return m;
1123 }
1124
1125 @Test
1126 public void testMetricsWithException() throws Exception {
1127 byte[] rowkey = Bytes.toBytes("row1");
1128 byte[] family = Bytes.toBytes("f");
1129 byte[] col = Bytes.toBytes("c");
1130
1131 TableName tableName = TableName.valueOf("testMetricsWithException");
1132 HTableDescriptor tableDesc = new HTableDescriptor(tableName);
1133 tableDesc.addCoprocessor(ErrorThrowingGetObserver.class.getName());
1134 tableDesc.addFamily(new HColumnDescriptor(family));
1135
1136 Table table = UTIL.createTable(tableDesc, null);
1137 table.put(new Put(rowkey).addColumn(family, col, Bytes.toBytes("val1")));
1138
1139 ThriftHBaseServiceHandler hbaseHandler = createHandler();
1140 ThriftMetrics metrics = getMetrics(UTIL.getConfiguration());
1141 THBaseService.Iface handler =
1142 ThriftHBaseServiceHandler.newInstance(hbaseHandler, metrics);
1143 ByteBuffer tTableName = wrap(tableName.getName());
1144
1145
1146 long preGetCounter = metricsHelper.checkCounterExists("get_num_ops", metrics.getSource()) ?
1147 metricsHelper.getCounter("get_num_ops", metrics.getSource()) :
1148 0;
1149 TGet tGet = new TGet(wrap(rowkey));
1150 TResult tResult = handler.get(tTableName, tGet);
1151
1152 List<TColumnValue> expectedColumnValues = Lists.newArrayList(
1153 new TColumnValue(wrap(family), wrap(col), wrap(Bytes.toBytes("val1")))
1154 );
1155 assertArrayEquals(rowkey, tResult.getRow());
1156 List<TColumnValue> returnedColumnValues = tResult.getColumnValues();
1157 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
1158
1159 metricsHelper.assertCounter("get_num_ops", preGetCounter + 1, metrics.getSource());
1160
1161
1162 for (ErrorThrowingGetObserver.ErrorType type : ErrorThrowingGetObserver.ErrorType.values()) {
1163 testExceptionType(handler, metrics, tTableName, rowkey, type);
1164 }
1165 }
1166
1167 private void testExceptionType(THBaseService.Iface handler, ThriftMetrics metrics,
1168 ByteBuffer tTableName, byte[] rowkey, ErrorThrowingGetObserver.ErrorType errorType) {
1169 long preGetCounter = metricsHelper.getCounter("get_num_ops", metrics.getSource());
1170 String exceptionKey = errorType.getMetricName();
1171 long preExceptionCounter = metricsHelper.checkCounterExists(exceptionKey, metrics.getSource()) ?
1172 metricsHelper.getCounter(exceptionKey, metrics.getSource()) :
1173 0;
1174 TGet tGet = new TGet(wrap(rowkey));
1175 Map<ByteBuffer, ByteBuffer> attributes = new HashMap<>();
1176 attributes.put(wrap(Bytes.toBytes(ErrorThrowingGetObserver.SHOULD_ERROR_ATTRIBUTE)),
1177 wrap(Bytes.toBytes(errorType.name())));
1178 tGet.setAttributes(attributes);
1179 try {
1180 TResult tResult = handler.get(tTableName, tGet);
1181 fail("Get with error attribute should have thrown an exception");
1182 } catch (TException e) {
1183 LOG.info("Received exception: ", e);
1184 metricsHelper.assertCounter("get_num_ops", preGetCounter + 1, metrics.getSource());
1185 metricsHelper.assertCounter(exceptionKey, preExceptionCounter + 1, metrics.getSource());
1186 }
1187
1188 }
1189
1190
1191
1192
1193
1194
1195
1196 @Test
1197 public void testMetricsPrecision() throws Exception {
1198 byte[] rowkey = Bytes.toBytes("row1");
1199 byte[] family = Bytes.toBytes("f");
1200 byte[] col = Bytes.toBytes("c");
1201
1202 TableName tableName = TableName.valueOf("testMetricsPrecision");
1203 HTableDescriptor tableDesc = new HTableDescriptor(tableName);
1204 tableDesc.addCoprocessor(DelayingRegionObserver.class.getName());
1205 tableDesc.addFamily(new HColumnDescriptor(family));
1206
1207 Table table = null;
1208 try {
1209 table = UTIL.createTable(tableDesc, null);
1210
1211 table.put(new Put(rowkey).addColumn(family, col, Bytes.toBytes("val1")));
1212
1213 ThriftHBaseServiceHandler hbaseHandler = createHandler();
1214 ThriftMetrics metrics = getMetrics(UTIL.getConfiguration());
1215 THBaseService.Iface handler =
1216 ThriftHBaseServiceHandler.newInstance(hbaseHandler, metrics);
1217 ByteBuffer tTableName = wrap(tableName.getName());
1218
1219
1220 TGet tGet = new TGet(wrap(rowkey));
1221 TResult tResult = handler.get(tTableName, tGet);
1222
1223 List<TColumnValue> expectedColumnValues = Lists.newArrayList(
1224 new TColumnValue(wrap(family), wrap(col), wrap(Bytes.toBytes("val1")))
1225 );
1226 assertArrayEquals(rowkey, tResult.getRow());
1227 List<TColumnValue> returnedColumnValues = tResult.getColumnValues();
1228 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
1229
1230 metricsHelper.assertGaugeGt("get_max", 3000L, metrics.getSource());
1231 } finally {
1232 if (table != null) {
1233 try {
1234 table.close();
1235 } catch (IOException ignored) {
1236 }
1237 UTIL.deleteTable(tableName);
1238 }
1239 }
1240 }
1241
1242
1243 @Test
1244 public void testAttribute() throws Exception {
1245 byte[] rowName = "testAttribute".getBytes();
1246 byte[] attributeKey = "attribute1".getBytes();
1247 byte[] attributeValue = "value1".getBytes();
1248 Map<ByteBuffer, ByteBuffer> attributes = new HashMap<ByteBuffer, ByteBuffer>();
1249 attributes.put(wrap(attributeKey), wrap(attributeValue));
1250
1251 TGet tGet = new TGet(wrap(rowName));
1252 tGet.setAttributes(attributes);
1253 Get get = getFromThrift(tGet);
1254 assertArrayEquals(get.getAttribute("attribute1"), attributeValue);
1255
1256 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
1257 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
1258 TPut tPut = new TPut(wrap(rowName) , columnValues);
1259 tPut.setAttributes(attributes);
1260 Put put = putFromThrift(tPut);
1261 assertArrayEquals(put.getAttribute("attribute1"), attributeValue);
1262
1263 TScan tScan = new TScan();
1264 tScan.setAttributes(attributes);
1265 Scan scan = scanFromThrift(tScan);
1266 assertArrayEquals(scan.getAttribute("attribute1"), attributeValue);
1267
1268 List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
1269 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname)));
1270 TIncrement tIncrement = new TIncrement(wrap(rowName), incrementColumns);
1271 tIncrement.setAttributes(attributes);
1272 Increment increment = incrementFromThrift(tIncrement);
1273 assertArrayEquals(increment.getAttribute("attribute1"), attributeValue);
1274
1275 TDelete tDelete = new TDelete(wrap(rowName));
1276 tDelete.setAttributes(attributes);
1277 Delete delete = deleteFromThrift(tDelete);
1278 assertArrayEquals(delete.getAttribute("attribute1"), attributeValue);
1279 }
1280
1281
1282
1283
1284
1285
1286
1287 @Test
1288 public void testMutateRow() throws Exception {
1289 ThriftHBaseServiceHandler handler = createHandler();
1290 byte[] rowName = "testMutateRow".getBytes();
1291 ByteBuffer table = wrap(tableAname);
1292
1293 List<TColumnValue> columnValuesA = new ArrayList<TColumnValue>();
1294 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname),
1295 wrap(valueAname));
1296 columnValuesA.add(columnValueA);
1297 TPut putA = new TPut(wrap(rowName), columnValuesA);
1298 putA.setColumnValues(columnValuesA);
1299
1300 handler.put(table,putA);
1301
1302 TGet get = new TGet(wrap(rowName));
1303 TResult result = handler.get(table, get);
1304 assertArrayEquals(rowName, result.getRow());
1305 List<TColumnValue> returnedColumnValues = result.getColumnValues();
1306
1307 List<TColumnValue> expectedColumnValues = new ArrayList<TColumnValue>();
1308 expectedColumnValues.add(columnValueA);
1309 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
1310
1311 List<TColumnValue> columnValuesB = new ArrayList<TColumnValue>();
1312 TColumnValue columnValueB = new TColumnValue(wrap(familyAname), wrap(qualifierBname),
1313 wrap(valueBname));
1314 columnValuesB.add(columnValueB);
1315 TPut putB = new TPut(wrap(rowName), columnValuesB);
1316 putB.setColumnValues(columnValuesB);
1317
1318 TDelete delete = new TDelete(wrap(rowName));
1319 List<TColumn> deleteColumns = new ArrayList<TColumn>();
1320 TColumn deleteColumn = new TColumn(wrap(familyAname));
1321 deleteColumn.setQualifier(qualifierAname);
1322 deleteColumns.add(deleteColumn);
1323 delete.setColumns(deleteColumns);
1324
1325 List<TMutation> mutations = new ArrayList<TMutation>();
1326 TMutation mutationA = TMutation.put(putB);
1327 mutations.add(mutationA);
1328
1329 TMutation mutationB = TMutation.deleteSingle(delete);
1330 mutations.add(mutationB);
1331
1332 TRowMutations tRowMutations = new TRowMutations(wrap(rowName),mutations);
1333 handler.mutateRow(table,tRowMutations);
1334
1335 result = handler.get(table, get);
1336 assertArrayEquals(rowName, result.getRow());
1337 returnedColumnValues = result.getColumnValues();
1338
1339 expectedColumnValues = new ArrayList<TColumnValue>();
1340 expectedColumnValues.add(columnValueB);
1341 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues);
1342 }
1343
1344
1345
1346
1347
1348
1349
1350
1351 @Test
1352 public void testDurability() throws Exception {
1353 byte[] rowName = "testDurability".getBytes();
1354 List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
1355 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)));
1356
1357 List<TColumnIncrement> incrementColumns = new ArrayList<TColumnIncrement>();
1358 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname)));
1359
1360 TDelete tDelete = new TDelete(wrap(rowName));
1361 tDelete.setDurability(TDurability.SKIP_WAL);
1362 Delete delete = deleteFromThrift(tDelete);
1363 assertEquals(delete.getDurability(), Durability.SKIP_WAL);
1364
1365 tDelete.setDurability(TDurability.ASYNC_WAL);
1366 delete = deleteFromThrift(tDelete);
1367 assertEquals(delete.getDurability(), Durability.ASYNC_WAL);
1368
1369 tDelete.setDurability(TDurability.SYNC_WAL);
1370 delete = deleteFromThrift(tDelete);
1371 assertEquals(delete.getDurability(), Durability.SYNC_WAL);
1372
1373 tDelete.setDurability(TDurability.FSYNC_WAL);
1374 delete = deleteFromThrift(tDelete);
1375 assertEquals(delete.getDurability(), Durability.FSYNC_WAL);
1376
1377 TPut tPut = new TPut(wrap(rowName), columnValues);
1378 tPut.setDurability(TDurability.SKIP_WAL);
1379 Put put = putFromThrift(tPut);
1380 assertEquals(put.getDurability(), Durability.SKIP_WAL);
1381
1382 tPut.setDurability(TDurability.ASYNC_WAL);
1383 put = putFromThrift(tPut);
1384 assertEquals(put.getDurability(), Durability.ASYNC_WAL);
1385
1386 tPut.setDurability(TDurability.SYNC_WAL);
1387 put = putFromThrift(tPut);
1388 assertEquals(put.getDurability(), Durability.SYNC_WAL);
1389
1390 tPut.setDurability(TDurability.FSYNC_WAL);
1391 put = putFromThrift(tPut);
1392 assertEquals(put.getDurability(), Durability.FSYNC_WAL);
1393
1394 TIncrement tIncrement = new TIncrement(wrap(rowName), incrementColumns);
1395
1396 tIncrement.setDurability(TDurability.SKIP_WAL);
1397 Increment increment = incrementFromThrift(tIncrement);
1398 assertEquals(increment.getDurability(), Durability.SKIP_WAL);
1399
1400 tIncrement.setDurability(TDurability.ASYNC_WAL);
1401 increment = incrementFromThrift(tIncrement);
1402 assertEquals(increment.getDurability(), Durability.ASYNC_WAL);
1403
1404 tIncrement.setDurability(TDurability.SYNC_WAL);
1405 increment = incrementFromThrift(tIncrement);
1406 assertEquals(increment.getDurability(), Durability.SYNC_WAL);
1407
1408 tIncrement.setDurability(TDurability.FSYNC_WAL);
1409 increment = incrementFromThrift(tIncrement);
1410 assertEquals(increment.getDurability(), Durability.FSYNC_WAL);
1411 }
1412
1413 @Test
1414 public void testCheckAndMutate() throws Exception {
1415 ThriftHBaseServiceHandler handler = createHandler();
1416 ByteBuffer table = wrap(tableAname);
1417 ByteBuffer row = wrap("row".getBytes());
1418 ByteBuffer family = wrap(familyAname);
1419 ByteBuffer qualifier = wrap(qualifierAname);
1420 ByteBuffer value = wrap(valueAname);
1421
1422
1423 List<TColumnValue> columnValuesB = new ArrayList<TColumnValue>();
1424 TColumnValue columnValueB = new TColumnValue(family, wrap(qualifierBname), wrap(valueBname));
1425 columnValuesB.add(columnValueB);
1426 TPut putB = new TPut(row, columnValuesB);
1427 putB.setColumnValues(columnValuesB);
1428
1429 TRowMutations tRowMutations = new TRowMutations(row,
1430 Arrays.<TMutation> asList(TMutation.put(putB)));
1431
1432
1433 TResult result = handler.get(table, new TGet(row));
1434 assertEquals(0, result.getColumnValuesSize());
1435
1436
1437 assertFalse("Expected condition to not pass",
1438 handler.checkAndMutate(table, row, family, qualifier, TCompareOp.EQUAL, value,
1439 tRowMutations));
1440
1441 List<TColumnValue> columnValuesA = new ArrayList<TColumnValue>();
1442 TColumnValue columnValueA = new TColumnValue(family, qualifier, value);
1443 columnValuesA.add(columnValueA);
1444
1445
1446 handler.put(table, new TPut(row, columnValuesA));
1447
1448
1449 result = handler.get(table, new TGet(row));
1450 assertEquals(1, result.getColumnValuesSize());
1451 assertTColumnValueEqual(columnValueA, result.getColumnValues().get(0));
1452
1453
1454 assertTrue("Expected condition to pass",
1455 handler.checkAndMutate(table, row, family, qualifier, TCompareOp.EQUAL, value,
1456 tRowMutations));
1457
1458 result = handler.get(table, new TGet(row));
1459 assertEquals(2, result.getColumnValuesSize());
1460 assertTColumnValueEqual(columnValueA, result.getColumnValues().get(0));
1461 assertTColumnValueEqual(columnValueB, result.getColumnValues().get(1));
1462 }
1463
1464 public static class DelayingRegionObserver extends BaseRegionObserver {
1465 private static final Log LOG = LogFactory.getLog(DelayingRegionObserver.class);
1466
1467 private long delayMillis;
1468
1469 @Override
1470 public void start(CoprocessorEnvironment e) throws IOException {
1471 this.delayMillis = e.getConfiguration()
1472 .getLong("delayingregionobserver.delay", 3000);
1473 }
1474
1475 @Override
1476 public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> e, Get get,
1477 List<Cell> results) throws IOException {
1478 try {
1479 long start = System.currentTimeMillis();
1480 TimeUnit.MILLISECONDS.sleep(delayMillis);
1481 if (LOG.isTraceEnabled()) {
1482 LOG.trace("Slept for " + (System.currentTimeMillis() - start) + " msec");
1483 }
1484 } catch (InterruptedException ie) {
1485 throw new InterruptedIOException("Interrupted while sleeping");
1486 }
1487 }
1488 }
1489 }
1490