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