001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.thrift2; 019 020import static java.nio.ByteBuffer.wrap; 021import static org.apache.hadoop.hbase.thrift.HBaseServiceHandler.CLEANUP_INTERVAL; 022import static org.apache.hadoop.hbase.thrift.HBaseServiceHandler.MAX_IDLETIME; 023import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.deleteFromThrift; 024import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.getFromThrift; 025import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.incrementFromThrift; 026import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.putFromThrift; 027import static org.apache.hadoop.hbase.thrift2.ThriftUtilities.scanFromThrift; 028import static org.junit.Assert.assertArrayEquals; 029import static org.junit.Assert.assertEquals; 030import static org.junit.Assert.assertFalse; 031import static org.junit.Assert.assertNull; 032import static org.junit.Assert.assertTrue; 033import static org.junit.Assert.fail; 034 035import java.io.IOException; 036import java.io.InterruptedIOException; 037import java.nio.ByteBuffer; 038import java.util.ArrayList; 039import java.util.Arrays; 040import java.util.Collections; 041import java.util.Comparator; 042import java.util.HashMap; 043import java.util.List; 044import java.util.Map; 045import java.util.Optional; 046import java.util.concurrent.TimeUnit; 047import org.apache.hadoop.conf.Configuration; 048import org.apache.hadoop.hbase.Cell; 049import org.apache.hadoop.hbase.CompatibilityFactory; 050import org.apache.hadoop.hbase.CoprocessorEnvironment; 051import org.apache.hadoop.hbase.HBaseClassTestRule; 052import org.apache.hadoop.hbase.HBaseTestingUtility; 053import org.apache.hadoop.hbase.HColumnDescriptor; 054import org.apache.hadoop.hbase.HTableDescriptor; 055import org.apache.hadoop.hbase.TableName; 056import org.apache.hadoop.hbase.client.Admin; 057import org.apache.hadoop.hbase.client.Consistency; 058import org.apache.hadoop.hbase.client.Delete; 059import org.apache.hadoop.hbase.client.Durability; 060import org.apache.hadoop.hbase.client.Get; 061import org.apache.hadoop.hbase.client.Increment; 062import org.apache.hadoop.hbase.client.Put; 063import org.apache.hadoop.hbase.client.Scan; 064import org.apache.hadoop.hbase.client.Table; 065import org.apache.hadoop.hbase.client.TableDescriptor; 066import org.apache.hadoop.hbase.coprocessor.ObserverContext; 067import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor; 068import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; 069import org.apache.hadoop.hbase.coprocessor.RegionObserver; 070import org.apache.hadoop.hbase.filter.ParseFilter; 071import org.apache.hadoop.hbase.security.UserProvider; 072import org.apache.hadoop.hbase.test.MetricsAssertHelper; 073import org.apache.hadoop.hbase.testclassification.ClientTests; 074import org.apache.hadoop.hbase.testclassification.MediumTests; 075import org.apache.hadoop.hbase.thrift.ErrorThrowingGetObserver; 076import org.apache.hadoop.hbase.thrift.HbaseHandlerMetricsProxy; 077import org.apache.hadoop.hbase.thrift.ThriftMetrics; 078import org.apache.hadoop.hbase.thrift2.generated.TAppend; 079import org.apache.hadoop.hbase.thrift2.generated.TColumn; 080import org.apache.hadoop.hbase.thrift2.generated.TColumnFamilyDescriptor; 081import org.apache.hadoop.hbase.thrift2.generated.TColumnIncrement; 082import org.apache.hadoop.hbase.thrift2.generated.TColumnValue; 083import org.apache.hadoop.hbase.thrift2.generated.TCompareOp; 084import org.apache.hadoop.hbase.thrift2.generated.TConsistency; 085import org.apache.hadoop.hbase.thrift2.generated.TDataBlockEncoding; 086import org.apache.hadoop.hbase.thrift2.generated.TDelete; 087import org.apache.hadoop.hbase.thrift2.generated.TDeleteType; 088import org.apache.hadoop.hbase.thrift2.generated.TDurability; 089import org.apache.hadoop.hbase.thrift2.generated.TGet; 090import org.apache.hadoop.hbase.thrift2.generated.THBaseService; 091import org.apache.hadoop.hbase.thrift2.generated.TIOError; 092import org.apache.hadoop.hbase.thrift2.generated.TIllegalArgument; 093import org.apache.hadoop.hbase.thrift2.generated.TIncrement; 094import org.apache.hadoop.hbase.thrift2.generated.TMutation; 095import org.apache.hadoop.hbase.thrift2.generated.TNamespaceDescriptor; 096import org.apache.hadoop.hbase.thrift2.generated.TPut; 097import org.apache.hadoop.hbase.thrift2.generated.TReadType; 098import org.apache.hadoop.hbase.thrift2.generated.TResult; 099import org.apache.hadoop.hbase.thrift2.generated.TRowMutations; 100import org.apache.hadoop.hbase.thrift2.generated.TScan; 101import org.apache.hadoop.hbase.thrift2.generated.TTableDescriptor; 102import org.apache.hadoop.hbase.thrift2.generated.TTableName; 103import org.apache.hadoop.hbase.thrift2.generated.TTimeRange; 104import org.apache.hadoop.hbase.util.Bytes; 105import org.apache.thrift.TException; 106import org.junit.AfterClass; 107import org.junit.Before; 108import org.junit.BeforeClass; 109import org.junit.ClassRule; 110import org.junit.Rule; 111import org.junit.Test; 112import org.junit.experimental.categories.Category; 113import org.junit.rules.TestName; 114import org.slf4j.Logger; 115import org.slf4j.LoggerFactory; 116 117import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 118import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils; 119 120/** 121 * Unit testing for ThriftServer.HBaseServiceHandler, a part of the org.apache.hadoop.hbase.thrift2 122 * package. 123 */ 124@Category({ClientTests.class, MediumTests.class}) 125public class TestThriftHBaseServiceHandler { 126 127 @ClassRule 128 public static final HBaseClassTestRule CLASS_RULE = 129 HBaseClassTestRule.forClass(TestThriftHBaseServiceHandler.class); 130 131 private static final Logger LOG = LoggerFactory.getLogger(TestThriftHBaseServiceHandler.class); 132 private static final HBaseTestingUtility UTIL = new HBaseTestingUtility(); 133 134 // Static names for tables, columns, rows, and values 135 private static byte[] tableAname = Bytes.toBytes("tableA"); 136 private static byte[] familyAname = Bytes.toBytes("familyA"); 137 private static byte[] familyBname = Bytes.toBytes("familyB"); 138 private static byte[] qualifierAname = Bytes.toBytes("qualifierA"); 139 private static byte[] qualifierBname = Bytes.toBytes("qualifierB"); 140 private static byte[] valueAname = Bytes.toBytes("valueA"); 141 private static byte[] valueBname = Bytes.toBytes("valueB"); 142 private static HColumnDescriptor[] families = new HColumnDescriptor[] { 143 new HColumnDescriptor(familyAname).setMaxVersions(3), 144 new HColumnDescriptor(familyBname).setMaxVersions(2) 145 }; 146 147 148 private static final MetricsAssertHelper metricsHelper = 149 CompatibilityFactory.getInstance(MetricsAssertHelper.class); 150 151 @Rule 152 public TestName name = new TestName(); 153 154 155 public void assertTColumnValuesEqual(List<TColumnValue> columnValuesA, 156 List<TColumnValue> columnValuesB) { 157 assertEquals(columnValuesA.size(), columnValuesB.size()); 158 Comparator<TColumnValue> comparator = new Comparator<TColumnValue>() { 159 @Override 160 public int compare(TColumnValue o1, TColumnValue o2) { 161 return Bytes.compareTo(Bytes.add(o1.getFamily(), o1.getQualifier()), 162 Bytes.add(o2.getFamily(), o2.getQualifier())); 163 } 164 }; 165 Collections.sort(columnValuesA, comparator); 166 Collections.sort(columnValuesB, comparator); 167 168 for (int i = 0; i < columnValuesA.size(); i++) { 169 TColumnValue a = columnValuesA.get(i); 170 TColumnValue b = columnValuesB.get(i); 171 assertTColumnValueEqual(a, b); 172 } 173 } 174 175 public void assertTColumnValueEqual(TColumnValue a, TColumnValue b) { 176 assertArrayEquals(a.getFamily(), b.getFamily()); 177 assertArrayEquals(a.getQualifier(), b.getQualifier()); 178 assertArrayEquals(a.getValue(), b.getValue()); 179 } 180 181 @BeforeClass 182 public static void beforeClass() throws Exception { 183 UTIL.getConfiguration().set("hbase.client.retries.number", "3"); 184 UTIL.startMiniCluster(); 185 Admin admin = UTIL.getAdmin(); 186 HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(tableAname)); 187 for (HColumnDescriptor family : families) { 188 tableDescriptor.addFamily(family); 189 } 190 admin.createTable(tableDescriptor); 191 admin.close(); 192 } 193 194 @AfterClass 195 public static void afterClass() throws Exception { 196 UTIL.shutdownMiniCluster(); 197 } 198 199 @Before 200 public void setup() throws Exception { 201 202 } 203 204 private ThriftHBaseServiceHandler createHandler() throws TException { 205 try { 206 Configuration conf = UTIL.getConfiguration(); 207 return new ThriftHBaseServiceHandler(conf, UserProvider.instantiate(conf)); 208 } catch (IOException ie) { 209 throw new TException(ie); 210 } 211 } 212 213 @Test 214 public void testExists() throws TIOError, TException { 215 ThriftHBaseServiceHandler handler = createHandler(); 216 byte[] rowName = Bytes.toBytes("testExists"); 217 ByteBuffer table = wrap(tableAname); 218 219 TGet get = new TGet(wrap(rowName)); 220 assertFalse(handler.exists(table, get)); 221 222 List<TColumnValue> columnValues = new ArrayList<>(2); 223 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 224 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 225 TPut put = new TPut(wrap(rowName), columnValues); 226 put.setColumnValues(columnValues); 227 228 handler.put(table, put); 229 230 assertTrue(handler.exists(table, get)); 231 } 232 233 @Test 234 public void testExistsAll() throws TIOError, TException { 235 ThriftHBaseServiceHandler handler = createHandler(); 236 byte[] rowName1 = Bytes.toBytes("testExistsAll1"); 237 byte[] rowName2 = Bytes.toBytes("testExistsAll2"); 238 ByteBuffer table = wrap(tableAname); 239 240 List<TGet> gets = new ArrayList<>(); 241 gets.add(new TGet(wrap(rowName2))); 242 gets.add(new TGet(wrap(rowName2))); 243 List<Boolean> existsResult1 = handler.existsAll(table, gets); 244 assertFalse(existsResult1.get(0)); 245 assertFalse(existsResult1.get(1)); 246 247 List<TColumnValue> columnValues = new ArrayList<TColumnValue>(); 248 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 249 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 250 List<TPut> puts = new ArrayList<TPut>(); 251 puts.add(new TPut(wrap(rowName1), columnValues)); 252 puts.add(new TPut(wrap(rowName2), columnValues)); 253 254 handler.putMultiple(table, puts); 255 List<Boolean> existsResult2 = handler.existsAll(table,gets ); 256 257 assertTrue(existsResult2.get(0)); 258 assertTrue(existsResult2.get(1)); 259 } 260 261 @Test 262 public void testPutGet() throws Exception { 263 ThriftHBaseServiceHandler handler = createHandler(); 264 byte[] rowName = Bytes.toBytes("testPutGet"); 265 ByteBuffer table = wrap(tableAname); 266 267 List<TColumnValue> columnValues = new ArrayList<>(2); 268 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 269 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 270 TPut put = new TPut(wrap(rowName), columnValues); 271 272 put.setColumnValues(columnValues); 273 274 handler.put(table, put); 275 276 TGet get = new TGet(wrap(rowName)); 277 278 TResult result = handler.get(table, get); 279 assertArrayEquals(rowName, result.getRow()); 280 List<TColumnValue> returnedColumnValues = result.getColumnValues(); 281 assertTColumnValuesEqual(columnValues, returnedColumnValues); 282 } 283 284 @Test 285 public void testPutGetMultiple() throws Exception { 286 ThriftHBaseServiceHandler handler = createHandler(); 287 ByteBuffer table = wrap(tableAname); 288 byte[] rowName1 = Bytes.toBytes("testPutGetMultiple1"); 289 byte[] rowName2 = Bytes.toBytes("testPutGetMultiple2"); 290 291 List<TColumnValue> columnValues = new ArrayList<>(2); 292 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 293 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 294 List<TPut> puts = new ArrayList<>(2); 295 puts.add(new TPut(wrap(rowName1), columnValues)); 296 puts.add(new TPut(wrap(rowName2), columnValues)); 297 298 handler.putMultiple(table, puts); 299 300 List<TGet> gets = new ArrayList<>(2); 301 gets.add(new TGet(wrap(rowName1))); 302 gets.add(new TGet(wrap(rowName2))); 303 304 List<TResult> results = handler.getMultiple(table, gets); 305 assertEquals(2, results.size()); 306 307 assertArrayEquals(rowName1, results.get(0).getRow()); 308 assertTColumnValuesEqual(columnValues, results.get(0).getColumnValues()); 309 310 assertArrayEquals(rowName2, results.get(1).getRow()); 311 assertTColumnValuesEqual(columnValues, results.get(1).getColumnValues()); 312 } 313 314 @Test 315 public void testDeleteMultiple() throws Exception { 316 ThriftHBaseServiceHandler handler = createHandler(); 317 ByteBuffer table = wrap(tableAname); 318 byte[] rowName1 = Bytes.toBytes("testDeleteMultiple1"); 319 byte[] rowName2 = Bytes.toBytes("testDeleteMultiple2"); 320 321 List<TColumnValue> columnValues = new ArrayList<>(2); 322 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 323 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 324 List<TPut> puts = new ArrayList<>(2); 325 puts.add(new TPut(wrap(rowName1), columnValues)); 326 puts.add(new TPut(wrap(rowName2), columnValues)); 327 328 handler.putMultiple(table, puts); 329 330 List<TDelete> deletes = new ArrayList<>(2); 331 deletes.add(new TDelete(wrap(rowName1))); 332 deletes.add(new TDelete(wrap(rowName2))); 333 334 List<TDelete> deleteResults = handler.deleteMultiple(table, deletes); 335 // 0 means they were all successfully applies 336 assertEquals(0, deleteResults.size()); 337 338 assertFalse(handler.exists(table, new TGet(wrap(rowName1)))); 339 assertFalse(handler.exists(table, new TGet(wrap(rowName2)))); 340 } 341 342 @Test 343 public void testDelete() throws Exception { 344 ThriftHBaseServiceHandler handler = createHandler(); 345 byte[] rowName = Bytes.toBytes("testDelete"); 346 ByteBuffer table = wrap(tableAname); 347 348 List<TColumnValue> columnValues = new ArrayList<>(2); 349 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 350 wrap(valueAname)); 351 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname), 352 wrap(valueBname)); 353 columnValues.add(columnValueA); 354 columnValues.add(columnValueB); 355 TPut put = new TPut(wrap(rowName), columnValues); 356 357 put.setColumnValues(columnValues); 358 359 handler.put(table, put); 360 361 TDelete delete = new TDelete(wrap(rowName)); 362 List<TColumn> deleteColumns = new ArrayList<>(1); 363 TColumn deleteColumn = new TColumn(wrap(familyAname)); 364 deleteColumn.setQualifier(qualifierAname); 365 deleteColumns.add(deleteColumn); 366 delete.setColumns(deleteColumns); 367 368 handler.deleteSingle(table, delete); 369 370 TGet get = new TGet(wrap(rowName)); 371 TResult result = handler.get(table, get); 372 assertArrayEquals(rowName, result.getRow()); 373 List<TColumnValue> returnedColumnValues = result.getColumnValues(); 374 List<TColumnValue> expectedColumnValues = new ArrayList<>(1); 375 expectedColumnValues.add(columnValueB); 376 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues); 377 } 378 379 @Test 380 public void testDeleteAllTimestamps() throws Exception { 381 ThriftHBaseServiceHandler handler = createHandler(); 382 byte[] rowName = Bytes.toBytes("testDeleteAllTimestamps"); 383 ByteBuffer table = wrap(tableAname); 384 385 List<TColumnValue> columnValues = new ArrayList<>(1); 386 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 387 wrap(valueAname)); 388 columnValueA.setTimestamp(System.currentTimeMillis() - 10); 389 columnValues.add(columnValueA); 390 TPut put = new TPut(wrap(rowName), columnValues); 391 392 put.setColumnValues(columnValues); 393 394 handler.put(table, put); 395 columnValueA.setTimestamp(System.currentTimeMillis()); 396 handler.put(table, put); 397 398 TGet get = new TGet(wrap(rowName)); 399 get.setMaxVersions(2); 400 TResult result = handler.get(table, get); 401 assertEquals(2, result.getColumnValuesSize()); 402 403 TDelete delete = new TDelete(wrap(rowName)); 404 List<TColumn> deleteColumns = new ArrayList<>(1); 405 TColumn deleteColumn = new TColumn(wrap(familyAname)); 406 deleteColumn.setQualifier(qualifierAname); 407 deleteColumns.add(deleteColumn); 408 delete.setColumns(deleteColumns); 409 delete.setDeleteType(TDeleteType.DELETE_COLUMNS); // This is the default anyway. 410 411 handler.deleteSingle(table, delete); 412 413 get = new TGet(wrap(rowName)); 414 result = handler.get(table, get); 415 assertNull(result.getRow()); 416 assertEquals(0, result.getColumnValuesSize()); 417 } 418 419 @Test 420 public void testDeleteSingleTimestamp() throws Exception { 421 ThriftHBaseServiceHandler handler = createHandler(); 422 byte[] rowName = Bytes.toBytes("testDeleteSingleTimestamp"); 423 ByteBuffer table = wrap(tableAname); 424 425 long timestamp1 = System.currentTimeMillis() - 10; 426 long timestamp2 = System.currentTimeMillis(); 427 428 List<TColumnValue> columnValues = new ArrayList<>(1); 429 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 430 wrap(valueAname)); 431 columnValueA.setTimestamp(timestamp1); 432 columnValues.add(columnValueA); 433 TPut put = new TPut(wrap(rowName), columnValues); 434 435 put.setColumnValues(columnValues); 436 437 handler.put(table, put); 438 columnValueA.setTimestamp(timestamp2); 439 handler.put(table, put); 440 441 TGet get = new TGet(wrap(rowName)); 442 get.setMaxVersions(2); 443 TResult result = handler.get(table, get); 444 assertEquals(2, result.getColumnValuesSize()); 445 446 TDelete delete = new TDelete(wrap(rowName)); 447 List<TColumn> deleteColumns = new ArrayList<>(1); 448 TColumn deleteColumn = new TColumn(wrap(familyAname)); 449 deleteColumn.setQualifier(qualifierAname); 450 deleteColumns.add(deleteColumn); 451 delete.setColumns(deleteColumns); 452 delete.setDeleteType(TDeleteType.DELETE_COLUMN); 453 454 handler.deleteSingle(table, delete); 455 456 get = new TGet(wrap(rowName)); 457 result = handler.get(table, get); 458 assertArrayEquals(rowName, result.getRow()); 459 assertEquals(1, result.getColumnValuesSize()); 460 // the older timestamp should remain. 461 assertEquals(timestamp1, result.getColumnValues().get(0).getTimestamp()); 462 } 463 464 @Test 465 public void testDeleteFamily() throws Exception { 466 ThriftHBaseServiceHandler handler = createHandler(); 467 byte[] rowName = Bytes.toBytes("testDeleteFamily"); 468 ByteBuffer table = wrap(tableAname); 469 470 long timestamp1 = System.currentTimeMillis() - 10; 471 long timestamp2 = System.currentTimeMillis(); 472 473 List<TColumnValue> columnValues = new ArrayList<>(); 474 TColumnValue columnValueA = 475 new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)); 476 columnValueA.setTimestamp(timestamp1); 477 columnValues.add(columnValueA); 478 TPut put = new TPut(wrap(rowName), columnValues); 479 480 put.setColumnValues(columnValues); 481 482 handler.put(table, put); 483 columnValueA.setTimestamp(timestamp2); 484 handler.put(table, put); 485 486 TGet get = new TGet(wrap(rowName)); 487 get.setMaxVersions(2); 488 TResult result = handler.get(table, get); 489 assertEquals(2, result.getColumnValuesSize()); 490 491 TDelete delete = new TDelete(wrap(rowName)); 492 List<TColumn> deleteColumns = new ArrayList<>(); 493 TColumn deleteColumn = new TColumn(wrap(familyAname)); 494 deleteColumns.add(deleteColumn); 495 delete.setColumns(deleteColumns); 496 delete.setDeleteType(TDeleteType.DELETE_FAMILY); 497 498 handler.deleteSingle(table, delete); 499 500 get = new TGet(wrap(rowName)); 501 result = handler.get(table, get); 502 assertArrayEquals(null, result.getRow()); 503 assertEquals(0, result.getColumnValuesSize()); 504 } 505 506 @Test 507 public void testDeleteFamilyVersion() throws Exception { 508 ThriftHBaseServiceHandler handler = createHandler(); 509 byte[] rowName = Bytes.toBytes("testDeleteFamilyVersion"); 510 ByteBuffer table = wrap(tableAname); 511 512 long timestamp1 = System.currentTimeMillis() - 10; 513 long timestamp2 = System.currentTimeMillis(); 514 515 List<TColumnValue> columnValues = new ArrayList<>(); 516 TColumnValue columnValueA = 517 new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)); 518 columnValueA.setTimestamp(timestamp1); 519 columnValues.add(columnValueA); 520 TPut put = new TPut(wrap(rowName), columnValues); 521 522 put.setColumnValues(columnValues); 523 524 handler.put(table, put); 525 columnValueA.setTimestamp(timestamp2); 526 handler.put(table, put); 527 528 TGet get = new TGet(wrap(rowName)); 529 get.setMaxVersions(2); 530 TResult result = handler.get(table, get); 531 assertEquals(2, result.getColumnValuesSize()); 532 533 TDelete delete = new TDelete(wrap(rowName)); 534 List<TColumn> deleteColumns = new ArrayList<>(); 535 TColumn deleteColumn = new TColumn(wrap(familyAname)); 536 deleteColumn.setTimestamp(timestamp1); 537 deleteColumns.add(deleteColumn); 538 delete.setColumns(deleteColumns); 539 delete.setDeleteType(TDeleteType.DELETE_FAMILY_VERSION); 540 541 handler.deleteSingle(table, delete); 542 543 get = new TGet(wrap(rowName)); 544 result = handler.get(table, get); 545 assertArrayEquals(rowName, result.getRow()); 546 assertEquals(1, result.getColumnValuesSize()); 547 assertEquals(timestamp2, result.getColumnValues().get(0).getTimestamp()); 548 } 549 550 @Test 551 public void testIncrement() throws Exception { 552 ThriftHBaseServiceHandler handler = createHandler(); 553 byte[] rowName = Bytes.toBytes("testIncrement"); 554 ByteBuffer table = wrap(tableAname); 555 556 List<TColumnValue> columnValues = new ArrayList<>(1); 557 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), 558 wrap(Bytes.toBytes(1L)))); 559 TPut put = new TPut(wrap(rowName), columnValues); 560 put.setColumnValues(columnValues); 561 handler.put(table, put); 562 563 List<TColumnIncrement> incrementColumns = new ArrayList<>(1); 564 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname))); 565 TIncrement increment = new TIncrement(wrap(rowName), incrementColumns); 566 handler.increment(table, increment); 567 568 TGet get = new TGet(wrap(rowName)); 569 TResult result = handler.get(table, get); 570 571 assertArrayEquals(rowName, result.getRow()); 572 assertEquals(1, result.getColumnValuesSize()); 573 TColumnValue columnValue = result.getColumnValues().get(0); 574 assertArrayEquals(Bytes.toBytes(2L), columnValue.getValue()); 575 } 576 577 @Test 578 public void testAppend() throws Exception { 579 ThriftHBaseServiceHandler handler = createHandler(); 580 byte[] rowName = Bytes.toBytes("testAppend"); 581 ByteBuffer table = wrap(tableAname); 582 byte[] v1 = Bytes.toBytes("42"); 583 byte[] v2 = Bytes.toBytes("23"); 584 List<TColumnValue> columnValues = new ArrayList<>(1); 585 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(v1))); 586 TPut put = new TPut(wrap(rowName), columnValues); 587 put.setColumnValues(columnValues); 588 handler.put(table, put); 589 590 List<TColumnValue> appendColumns = new ArrayList<>(1); 591 appendColumns.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(v2))); 592 TAppend append = new TAppend(wrap(rowName), appendColumns); 593 handler.append(table, append); 594 595 TGet get = new TGet(wrap(rowName)); 596 TResult result = handler.get(table, get); 597 598 assertArrayEquals(rowName, result.getRow()); 599 assertEquals(1, result.getColumnValuesSize()); 600 TColumnValue columnValue = result.getColumnValues().get(0); 601 assertArrayEquals(Bytes.add(v1, v2), columnValue.getValue()); 602 } 603 604 /** 605 * check that checkAndPut fails if the cell does not exist, then put in the cell, then check 606 * that the checkAndPut succeeds. 607 */ 608 @Test 609 public void testCheckAndPut() throws Exception { 610 ThriftHBaseServiceHandler handler = createHandler(); 611 byte[] rowName = Bytes.toBytes("testCheckAndPut"); 612 ByteBuffer table = wrap(tableAname); 613 614 List<TColumnValue> columnValuesA = new ArrayList<>(1); 615 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 616 wrap(valueAname)); 617 columnValuesA.add(columnValueA); 618 TPut putA = new TPut(wrap(rowName), columnValuesA); 619 putA.setColumnValues(columnValuesA); 620 621 List<TColumnValue> columnValuesB = new ArrayList<>(1); 622 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname), 623 wrap(valueBname)); 624 columnValuesB.add(columnValueB); 625 TPut putB = new TPut(wrap(rowName), columnValuesB); 626 putB.setColumnValues(columnValuesB); 627 628 assertFalse(handler.checkAndPut(table, wrap(rowName), wrap(familyAname), 629 wrap(qualifierAname), wrap(valueAname), putB)); 630 631 TGet get = new TGet(wrap(rowName)); 632 TResult result = handler.get(table, get); 633 assertEquals(0, result.getColumnValuesSize()); 634 635 handler.put(table, putA); 636 637 assertTrue(handler.checkAndPut(table, wrap(rowName), wrap(familyAname), 638 wrap(qualifierAname), wrap(valueAname), putB)); 639 640 result = handler.get(table, get); 641 assertArrayEquals(rowName, result.getRow()); 642 List<TColumnValue> returnedColumnValues = result.getColumnValues(); 643 List<TColumnValue> expectedColumnValues = new ArrayList<>(2); 644 expectedColumnValues.add(columnValueA); 645 expectedColumnValues.add(columnValueB); 646 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues); 647 } 648 649 /** 650 * check that checkAndDelete fails if the cell does not exist, then put in the cell, then 651 * check that the checkAndDelete succeeds. 652 */ 653 @Test 654 public void testCheckAndDelete() throws Exception { 655 ThriftHBaseServiceHandler handler = createHandler(); 656 byte[] rowName = Bytes.toBytes("testCheckAndDelete"); 657 ByteBuffer table = wrap(tableAname); 658 659 List<TColumnValue> columnValuesA = new ArrayList<>(1); 660 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 661 wrap(valueAname)); 662 columnValuesA.add(columnValueA); 663 TPut putA = new TPut(wrap(rowName), columnValuesA); 664 putA.setColumnValues(columnValuesA); 665 666 List<TColumnValue> columnValuesB = new ArrayList<>(1); 667 TColumnValue columnValueB = new TColumnValue(wrap(familyBname), wrap(qualifierBname), 668 wrap(valueBname)); 669 columnValuesB.add(columnValueB); 670 TPut putB = new TPut(wrap(rowName), columnValuesB); 671 putB.setColumnValues(columnValuesB); 672 673 // put putB so that we know whether the row has been deleted or not 674 handler.put(table, putB); 675 676 TDelete delete = new TDelete(wrap(rowName)); 677 678 assertFalse(handler.checkAndDelete(table, wrap(rowName), wrap(familyAname), 679 wrap(qualifierAname), wrap(valueAname), delete)); 680 681 TGet get = new TGet(wrap(rowName)); 682 TResult result = handler.get(table, get); 683 assertArrayEquals(rowName, result.getRow()); 684 assertTColumnValuesEqual(columnValuesB, result.getColumnValues()); 685 686 handler.put(table, putA); 687 688 assertTrue(handler.checkAndDelete(table, wrap(rowName), wrap(familyAname), 689 wrap(qualifierAname), wrap(valueAname), delete)); 690 691 result = handler.get(table, get); 692 assertFalse(result.isSetRow()); 693 assertEquals(0, result.getColumnValuesSize()); 694 } 695 696 @Test 697 public void testScan() throws Exception { 698 ThriftHBaseServiceHandler handler = createHandler(); 699 ByteBuffer table = wrap(tableAname); 700 701 // insert data 702 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 703 wrap(valueAname)); 704 List<TColumnValue> columnValues = new ArrayList<>(1); 705 columnValues.add(columnValue); 706 for (int i = 0; i < 10; i++) { 707 TPut put = new TPut(wrap(Bytes.toBytes("testScan" + i)), columnValues); 708 handler.put(table, put); 709 } 710 711 // create scan instance 712 TScan scan = new TScan(); 713 List<TColumn> columns = new ArrayList<>(1); 714 TColumn column = new TColumn(); 715 column.setFamily(familyAname); 716 column.setQualifier(qualifierAname); 717 columns.add(column); 718 scan.setColumns(columns); 719 scan.setStartRow(Bytes.toBytes("testScan")); 720 scan.setStopRow(Bytes.toBytes("testScan\uffff")); 721 722 // get scanner and rows 723 int scanId = handler.openScanner(table, scan); 724 List<TResult> results = handler.getScannerRows(scanId, 10); 725 assertEquals(10, results.size()); 726 for (int i = 0; i < 10; i++) { 727 // check if the rows are returned and in order 728 assertArrayEquals(Bytes.toBytes("testScan" + i), results.get(i).getRow()); 729 } 730 731 // check that we are at the end of the scan 732 results = handler.getScannerRows(scanId, 10); 733 assertEquals(0, results.size()); 734 735 // close scanner and check that it was indeed closed 736 handler.closeScanner(scanId); 737 try { 738 handler.getScannerRows(scanId, 10); 739 fail("Scanner id should be invalid"); 740 } catch (TIllegalArgument e) { 741 } 742 } 743 744 /** 745 * Tests keeping a HBase scanner alive for long periods of time. Each call to getScannerRow() 746 * should reset the ConnectionCache timeout for the scanner's connection 747 */ 748 @Test 749 public void testLongLivedScan() throws Exception { 750 int numTrials = 6; 751 int trialPause = 1000; 752 int cleanUpInterval = 100; 753 Configuration conf = new Configuration(UTIL.getConfiguration()); 754 // Set the ConnectionCache timeout to trigger halfway through the trials 755 conf.setInt(MAX_IDLETIME, (numTrials / 2) * trialPause); 756 conf.setInt(CLEANUP_INTERVAL, cleanUpInterval); 757 ThriftHBaseServiceHandler handler = new ThriftHBaseServiceHandler(conf, 758 UserProvider.instantiate(conf)); 759 760 ByteBuffer table = wrap(tableAname); 761 // insert data 762 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 763 wrap(valueAname)); 764 List<TColumnValue> columnValues = new ArrayList<>(1); 765 columnValues.add(columnValue); 766 for (int i = 0; i < numTrials; i++) { 767 TPut put = new TPut(wrap(Bytes.toBytes("testScan" + i)), columnValues); 768 handler.put(table, put); 769 } 770 771 // create scan instance 772 TScan scan = new TScan(); 773 List<TColumn> columns = new ArrayList<>(1); 774 TColumn column = new TColumn(); 775 column.setFamily(familyAname); 776 column.setQualifier(qualifierAname); 777 columns.add(column); 778 scan.setColumns(columns); 779 scan.setStartRow(Bytes.toBytes("testScan")); 780 scan.setStopRow(Bytes.toBytes("testScan\uffff")); 781 // Prevent the scanner from caching results 782 scan.setCaching(1); 783 784 // get scanner and rows 785 int scanId = handler.openScanner(table, scan); 786 for (int i = 0; i < numTrials; i++) { 787 // Make sure that the Scanner doesn't throw an exception after the ConnectionCache timeout 788 List<TResult> results = handler.getScannerRows(scanId, 1); 789 assertArrayEquals(Bytes.toBytes("testScan" + i), results.get(0).getRow()); 790 Thread.sleep(trialPause); 791 } 792 } 793 794 @Test 795 public void testReverseScan() throws Exception { 796 ThriftHBaseServiceHandler handler = createHandler(); 797 ByteBuffer table = wrap(tableAname); 798 799 // insert data 800 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 801 wrap(valueAname)); 802 List<TColumnValue> columnValues = new ArrayList<>(1); 803 columnValues.add(columnValue); 804 for (int i = 0; i < 10; i++) { 805 TPut put = new TPut(wrap(Bytes.toBytes("testReverseScan" + i)), columnValues); 806 handler.put(table, put); 807 } 808 809 // create reverse scan instance 810 TScan scan = new TScan(); 811 scan.setReversed(true); 812 List<TColumn> columns = new ArrayList<>(1); 813 TColumn column = new TColumn(); 814 column.setFamily(familyAname); 815 column.setQualifier(qualifierAname); 816 columns.add(column); 817 scan.setColumns(columns); 818 scan.setStartRow(Bytes.toBytes("testReverseScan\uffff")); 819 scan.setStopRow(Bytes.toBytes("testReverseScan")); 820 821 // get scanner and rows 822 int scanId = handler.openScanner(table, scan); 823 List<TResult> results = handler.getScannerRows(scanId, 10); 824 assertEquals(10, results.size()); 825 for (int i = 0; i < 10; i++) { 826 // check if the rows are returned and in order 827 assertArrayEquals(Bytes.toBytes("testReverseScan" + (9 - i)), results.get(i).getRow()); 828 } 829 830 // check that we are at the end of the scan 831 results = handler.getScannerRows(scanId, 10); 832 assertEquals(0, results.size()); 833 834 // close scanner and check that it was indeed closed 835 handler.closeScanner(scanId); 836 try { 837 handler.getScannerRows(scanId, 10); 838 fail("Scanner id should be invalid"); 839 } catch (TIllegalArgument e) { 840 } 841 } 842 843 @Test 844 public void testScanWithFilter() throws Exception { 845 ThriftHBaseServiceHandler handler = createHandler(); 846 ByteBuffer table = wrap(tableAname); 847 848 // insert data 849 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 850 wrap(valueAname)); 851 List<TColumnValue> columnValues = new ArrayList<>(1); 852 columnValues.add(columnValue); 853 for (int i = 0; i < 10; i++) { 854 TPut put = new TPut(wrap(Bytes.toBytes("testScanWithFilter" + i)), columnValues); 855 handler.put(table, put); 856 } 857 858 // create scan instance with filter 859 TScan scan = new TScan(); 860 List<TColumn> columns = new ArrayList<>(1); 861 TColumn column = new TColumn(); 862 column.setFamily(familyAname); 863 column.setQualifier(qualifierAname); 864 columns.add(column); 865 scan.setColumns(columns); 866 scan.setStartRow(Bytes.toBytes("testScanWithFilter")); 867 scan.setStopRow(Bytes.toBytes("testScanWithFilter\uffff")); 868 // only get the key part 869 scan.setFilterString(wrap(Bytes.toBytes("KeyOnlyFilter()"))); 870 871 // get scanner and rows 872 int scanId = handler.openScanner(table, scan); 873 List<TResult> results = handler.getScannerRows(scanId, 10); 874 assertEquals(10, results.size()); 875 for (int i = 0; i < 10; i++) { 876 // check if the rows are returned and in order 877 assertArrayEquals(Bytes.toBytes("testScanWithFilter" + i), results.get(i).getRow()); 878 // check that the value is indeed stripped by the filter 879 assertEquals(0, results.get(i).getColumnValues().get(0).getValue().length); 880 } 881 882 // check that we are at the end of the scan 883 results = handler.getScannerRows(scanId, 10); 884 assertEquals(0, results.size()); 885 886 // close scanner and check that it was indeed closed 887 handler.closeScanner(scanId); 888 try { 889 handler.getScannerRows(scanId, 10); 890 fail("Scanner id should be invalid"); 891 } catch (TIllegalArgument e) { 892 } 893 } 894 895 @Test 896 public void testScanWithColumnFamilyTimeRange() throws Exception { 897 ThriftHBaseServiceHandler handler = createHandler(); 898 ByteBuffer table = wrap(tableAname); 899 900 // insert data 901 TColumnValue familyAColumnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 902 wrap(valueAname)); 903 TColumnValue familyBColumnValue = new TColumnValue(wrap(familyBname), wrap(qualifierBname), 904 wrap(valueBname)); 905 long minTimestamp = System.currentTimeMillis(); 906 for (int i = 0; i < 10; i++) { 907 familyAColumnValue.setTimestamp(minTimestamp + i); 908 familyBColumnValue.setTimestamp(minTimestamp + i); 909 List<TColumnValue> columnValues = new ArrayList<>(2); 910 columnValues.add(familyAColumnValue); 911 columnValues.add(familyBColumnValue); 912 TPut put = new TPut(wrap(Bytes.toBytes("testScanWithColumnFamilyTimeRange" + i)), 913 columnValues); 914 handler.put(table, put); 915 } 916 917 // create scan instance with column family time range 918 TScan scan = new TScan(); 919 Map<ByteBuffer,TTimeRange> colFamTimeRangeMap = new HashMap<>(2); 920 colFamTimeRangeMap.put(wrap(familyAname), new TTimeRange(minTimestamp + 3, minTimestamp + 5)); 921 colFamTimeRangeMap.put(wrap(familyBname), new TTimeRange(minTimestamp + 6, minTimestamp + 9)); 922 scan.setColFamTimeRangeMap(colFamTimeRangeMap); 923 924 // get scanner and rows 925 int scanId = handler.openScanner(table, scan); 926 List<TResult> results = handler.getScannerRows(scanId, 5); 927 assertEquals(5, results.size()); 928 int familyACount = 0; 929 int familyBCount = 0; 930 for (TResult result : results) { 931 List<TColumnValue> columnValues = result.getColumnValues(); 932 if (CollectionUtils.isNotEmpty(columnValues)) { 933 if (Bytes.equals(familyAname, columnValues.get(0).getFamily())) { 934 familyACount++; 935 } else if (Bytes.equals(familyBname, columnValues.get(0).getFamily())) { 936 familyBCount++; 937 } 938 } 939 } 940 assertEquals(2, familyACount); 941 assertEquals(3, familyBCount); 942 943 // check that we are at the end of the scan 944 results = handler.getScannerRows(scanId, 1); 945 assertEquals(0, results.size()); 946 947 // close scanner and check that it was indeed closed 948 handler.closeScanner(scanId); 949 try { 950 handler.getScannerRows(scanId, 1); 951 fail("Scanner id should be invalid"); 952 } catch (TIllegalArgument e) { 953 } 954 } 955 956 @Test 957 public void testSmallScan() throws Exception { 958 ThriftHBaseServiceHandler handler = createHandler(); 959 ByteBuffer table = wrap(tableAname); 960 961 // insert data 962 TColumnValue columnValue = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 963 wrap(valueAname)); 964 List<TColumnValue> columnValues = new ArrayList<>(); 965 columnValues.add(columnValue); 966 for (int i = 0; i < 10; i++) { 967 TPut put = new TPut(wrap(Bytes.toBytes("testSmallScan" + i)), columnValues); 968 handler.put(table, put); 969 } 970 971 // small scan instance 972 TScan scan = new TScan(); 973 scan.setStartRow(Bytes.toBytes("testSmallScan")); 974 scan.setStopRow(Bytes.toBytes("testSmallScan\uffff")); 975 scan.setReadType(TReadType.PREAD); 976 scan.setCaching(2); 977 978 // get scanner and rows 979 int scanId = handler.openScanner(table, scan); 980 List<TResult> results = handler.getScannerRows(scanId, 10); 981 assertEquals(10, results.size()); 982 for (int i = 0; i < 10; i++) { 983 // check if the rows are returned and in order 984 assertArrayEquals(Bytes.toBytes("testSmallScan" + i), results.get(i).getRow()); 985 } 986 987 // check that we are at the end of the scan 988 results = handler.getScannerRows(scanId, 10); 989 assertEquals(0, results.size()); 990 991 // close scanner and check that it was indeed closed 992 handler.closeScanner(scanId); 993 try { 994 handler.getScannerRows(scanId, 10); 995 fail("Scanner id should be invalid"); 996 } catch (TIllegalArgument e) { 997 } 998 } 999 1000 @Test 1001 public void testPutTTL() throws Exception { 1002 ThriftHBaseServiceHandler handler = createHandler(); 1003 byte[] rowName = Bytes.toBytes("testPutTTL"); 1004 ByteBuffer table = wrap(tableAname); 1005 List<TColumnValue> columnValues = new ArrayList<>(1); 1006 1007 // Add some dummy data 1008 columnValues.add( 1009 new TColumnValue( 1010 wrap(familyAname), 1011 wrap(qualifierAname), 1012 wrap(Bytes.toBytes(1L)))); 1013 1014 1015 TPut put = new TPut(wrap(rowName), columnValues); 1016 put.setColumnValues(columnValues); 1017 1018 Map<ByteBuffer, ByteBuffer> attributes = new HashMap<>(); 1019 1020 // Time in ms for the kv's to live. 1021 long ttlTimeMs = 2000L; 1022 1023 // the _ttl attribute is a number of ms ttl for key values in this put. 1024 attributes.put(wrap(Bytes.toBytes("_ttl")), wrap(Bytes.toBytes(ttlTimeMs))); 1025 // Attach the attributes 1026 put.setAttributes(attributes); 1027 // Send it. 1028 handler.put(table, put); 1029 1030 // Now get the data back 1031 TGet getOne = new TGet(wrap(rowName)); 1032 TResult resultOne = handler.get(table, getOne); 1033 1034 // It's there. 1035 assertArrayEquals(rowName, resultOne.getRow()); 1036 assertEquals(1, resultOne.getColumnValuesSize()); 1037 1038 // Sleep 30 seconds just to make 100% sure that the key value should be expired. 1039 Thread.sleep(ttlTimeMs * 15); 1040 1041 TGet getTwo = new TGet(wrap(rowName)); 1042 TResult resultTwo = handler.get(table, getTwo); 1043 1044 1045 // Nothing should be there since it's ttl'd out. 1046 assertNull(resultTwo.getRow()); 1047 assertEquals(0, resultTwo.getColumnValuesSize()); 1048 } 1049 1050 /** 1051 * Padding numbers to make comparison of sort order easier in a for loop 1052 * 1053 * @param n The number to pad. 1054 * @param pad The length to pad up to. 1055 * @return The padded number as a string. 1056 */ 1057 private String pad(int n, byte pad) { 1058 String res = Integer.toString(n); 1059 while (res.length() < pad) res = "0" + res; 1060 return res; 1061 } 1062 1063 @Test 1064 public void testScanWithBatchSize() throws Exception { 1065 ThriftHBaseServiceHandler handler = createHandler(); 1066 ByteBuffer table = wrap(tableAname); 1067 1068 // insert data 1069 List<TColumnValue> columnValues = new ArrayList<>(100); 1070 for (int i = 0; i < 100; i++) { 1071 String colNum = pad(i, (byte) 3); 1072 TColumnValue columnValue = new TColumnValue(wrap(familyAname), 1073 wrap(Bytes.toBytes("col" + colNum)), wrap(Bytes.toBytes("val" + colNum))); 1074 columnValues.add(columnValue); 1075 } 1076 TPut put = new TPut(wrap(Bytes.toBytes("testScanWithBatchSize")), columnValues); 1077 handler.put(table, put); 1078 1079 // create scan instance 1080 TScan scan = new TScan(); 1081 List<TColumn> columns = new ArrayList<>(1); 1082 TColumn column = new TColumn(); 1083 column.setFamily(familyAname); 1084 columns.add(column); 1085 scan.setColumns(columns); 1086 scan.setStartRow(Bytes.toBytes("testScanWithBatchSize")); 1087 scan.setStopRow(Bytes.toBytes("testScanWithBatchSize\uffff")); 1088 // set batch size to 10 columns per call 1089 scan.setBatchSize(10); 1090 1091 // get scanner 1092 int scanId = handler.openScanner(table, scan); 1093 List<TResult> results = null; 1094 for (int i = 0; i < 10; i++) { 1095 // get batch for single row (10x10 is what we expect) 1096 results = handler.getScannerRows(scanId, 1); 1097 assertEquals(1, results.size()); 1098 // check length of batch 1099 List<TColumnValue> cols = results.get(0).getColumnValues(); 1100 assertEquals(10, cols.size()); 1101 // check if the columns are returned and in order 1102 for (int y = 0; y < 10; y++) { 1103 int colNum = y + (10 * i); 1104 String colNumPad = pad(colNum, (byte) 3); 1105 assertArrayEquals(Bytes.toBytes("col" + colNumPad), cols.get(y).getQualifier()); 1106 } 1107 } 1108 1109 // check that we are at the end of the scan 1110 results = handler.getScannerRows(scanId, 1); 1111 assertEquals(0, results.size()); 1112 1113 // close scanner and check that it was indeed closed 1114 handler.closeScanner(scanId); 1115 try { 1116 handler.getScannerRows(scanId, 1); 1117 fail("Scanner id should be invalid"); 1118 } catch (TIllegalArgument e) { 1119 } 1120 } 1121 1122 @Test 1123 public void testGetScannerResults() throws Exception { 1124 ThriftHBaseServiceHandler handler = createHandler(); 1125 ByteBuffer table = wrap(tableAname); 1126 1127 // insert data 1128 TColumnValue columnValue = 1129 new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname)); 1130 List<TColumnValue> columnValues = new ArrayList<>(1); 1131 columnValues.add(columnValue); 1132 for (int i = 0; i < 20; i++) { 1133 TPut put = 1134 new TPut(wrap(Bytes.toBytes("testGetScannerResults" + pad(i, (byte) 2))), columnValues); 1135 handler.put(table, put); 1136 } 1137 1138 // create scan instance 1139 TScan scan = new TScan(); 1140 List<TColumn> columns = new ArrayList<>(1); 1141 TColumn column = new TColumn(); 1142 column.setFamily(familyAname); 1143 column.setQualifier(qualifierAname); 1144 columns.add(column); 1145 scan.setColumns(columns); 1146 scan.setStartRow(Bytes.toBytes("testGetScannerResults")); 1147 1148 // get 5 rows and check the returned results 1149 scan.setStopRow(Bytes.toBytes("testGetScannerResults05")); 1150 List<TResult> results = handler.getScannerResults(table, scan, 5); 1151 assertEquals(5, results.size()); 1152 for (int i = 0; i < 5; i++) { 1153 // check if the rows are returned and in order 1154 assertArrayEquals(Bytes.toBytes("testGetScannerResults" + pad(i, (byte) 2)), results.get(i) 1155 .getRow()); 1156 } 1157 1158 // get 10 rows and check the returned results 1159 scan.setStopRow(Bytes.toBytes("testGetScannerResults10")); 1160 results = handler.getScannerResults(table, scan, 10); 1161 assertEquals(10, results.size()); 1162 for (int i = 0; i < 10; i++) { 1163 // check if the rows are returned and in order 1164 assertArrayEquals(Bytes.toBytes("testGetScannerResults" + pad(i, (byte) 2)), results.get(i) 1165 .getRow()); 1166 } 1167 1168 // get 20 rows and check the returned results 1169 scan.setStopRow(Bytes.toBytes("testGetScannerResults20")); 1170 results = handler.getScannerResults(table, scan, 20); 1171 assertEquals(20, results.size()); 1172 for (int i = 0; i < 20; i++) { 1173 // check if the rows are returned and in order 1174 assertArrayEquals(Bytes.toBytes("testGetScannerResults" + pad(i, (byte) 2)), results.get(i) 1175 .getRow()); 1176 } 1177 1178 // reverse scan 1179 scan = new TScan(); 1180 scan.setColumns(columns); 1181 scan.setReversed(true); 1182 scan.setStartRow(Bytes.toBytes("testGetScannerResults20")); 1183 scan.setStopRow(Bytes.toBytes("testGetScannerResults")); 1184 results = handler.getScannerResults(table, scan, 20); 1185 assertEquals(20, results.size()); 1186 for (int i = 0; i < 20; i++) { 1187 // check if the rows are returned and in order 1188 assertArrayEquals(Bytes.toBytes("testGetScannerResults" + pad(19 - i, (byte) 2)), 1189 results.get(i).getRow()); 1190 } 1191 } 1192 1193 @Test 1194 public void testFilterRegistration() throws Exception { 1195 Configuration conf = UTIL.getConfiguration(); 1196 conf.set("hbase.thrift.filters", "MyFilter:filterclass"); 1197 ThriftServer.registerFilters(conf); 1198 Map<String, String> registeredFilters = ParseFilter.getAllFilters(); 1199 assertEquals("filterclass", registeredFilters.get("MyFilter")); 1200 } 1201 1202 @Test 1203 public void testMetrics() throws Exception { 1204 Configuration conf = UTIL.getConfiguration(); 1205 ThriftMetrics metrics = getMetrics(conf); 1206 ThriftHBaseServiceHandler hbaseHandler = createHandler(); 1207 THBaseService.Iface handler = 1208 HbaseHandlerMetricsProxy.newInstance(hbaseHandler, metrics, conf); 1209 byte[] rowName = Bytes.toBytes("testMetrics"); 1210 ByteBuffer table = wrap(tableAname); 1211 1212 TGet get = new TGet(wrap(rowName)); 1213 assertFalse(handler.exists(table, get)); 1214 1215 List<TColumnValue> columnValues = new ArrayList<>(2); 1216 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 1217 columnValues.add(new TColumnValue(wrap(familyBname), wrap(qualifierBname), wrap(valueBname))); 1218 TPut put = new TPut(wrap(rowName), columnValues); 1219 put.setColumnValues(columnValues); 1220 1221 handler.put(table, put); 1222 1223 assertTrue(handler.exists(table, get)); 1224 metricsHelper.assertCounter("put_num_ops", 1, metrics.getSource()); 1225 metricsHelper.assertCounter( "exists_num_ops", 2, metrics.getSource()); 1226 } 1227 1228 private static ThriftMetrics getMetrics(Configuration conf) throws Exception { 1229 ThriftMetrics m = new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.TWO); 1230 m.getSource().init(); //Clear all the metrics 1231 return m; 1232 } 1233 1234 @Test 1235 public void testMetricsWithException() throws Exception { 1236 byte[] rowkey = Bytes.toBytes("row1"); 1237 byte[] family = Bytes.toBytes("f"); 1238 byte[] col = Bytes.toBytes("c"); 1239 // create a table which will throw exceptions for requests 1240 TableName tableName = TableName.valueOf(name.getMethodName()); 1241 HTableDescriptor tableDesc = new HTableDescriptor(tableName); 1242 tableDesc.addCoprocessor(ErrorThrowingGetObserver.class.getName()); 1243 tableDesc.addFamily(new HColumnDescriptor(family)); 1244 1245 Table table = UTIL.createTable(tableDesc, null); 1246 table.put(new Put(rowkey).addColumn(family, col, Bytes.toBytes("val1"))); 1247 1248 ThriftHBaseServiceHandler hbaseHandler = createHandler(); 1249 ThriftMetrics metrics = getMetrics(UTIL.getConfiguration()); 1250 THBaseService.Iface handler = 1251 HbaseHandlerMetricsProxy.newInstance(hbaseHandler, metrics, null); 1252 ByteBuffer tTableName = wrap(tableName.getName()); 1253 1254 // check metrics increment with a successful get 1255 long preGetCounter = metricsHelper.checkCounterExists("get_num_ops", metrics.getSource()) ? 1256 metricsHelper.getCounter("get_num_ops", metrics.getSource()) : 1257 0; 1258 TGet tGet = new TGet(wrap(rowkey)); 1259 TResult tResult = handler.get(tTableName, tGet); 1260 1261 List<TColumnValue> expectedColumnValues = Lists.newArrayList( 1262 new TColumnValue(wrap(family), wrap(col), wrap(Bytes.toBytes("val1"))) 1263 ); 1264 assertArrayEquals(rowkey, tResult.getRow()); 1265 List<TColumnValue> returnedColumnValues = tResult.getColumnValues(); 1266 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues); 1267 1268 metricsHelper.assertCounter("get_num_ops", preGetCounter + 1, metrics.getSource()); 1269 1270 // check metrics increment when the get throws each exception type 1271 for (ErrorThrowingGetObserver.ErrorType type : ErrorThrowingGetObserver.ErrorType.values()) { 1272 testExceptionType(handler, metrics, tTableName, rowkey, type); 1273 } 1274 } 1275 1276 private void testExceptionType(THBaseService.Iface handler, ThriftMetrics metrics, 1277 ByteBuffer tTableName, byte[] rowkey, ErrorThrowingGetObserver.ErrorType errorType) { 1278 long preGetCounter = metricsHelper.getCounter("get_num_ops", metrics.getSource()); 1279 String exceptionKey = errorType.getMetricName(); 1280 long preExceptionCounter = metricsHelper.checkCounterExists(exceptionKey, metrics.getSource()) ? 1281 metricsHelper.getCounter(exceptionKey, metrics.getSource()) : 1282 0; 1283 TGet tGet = new TGet(wrap(rowkey)); 1284 Map<ByteBuffer, ByteBuffer> attributes = new HashMap<>(); 1285 attributes.put(wrap(Bytes.toBytes(ErrorThrowingGetObserver.SHOULD_ERROR_ATTRIBUTE)), 1286 wrap(Bytes.toBytes(errorType.name()))); 1287 tGet.setAttributes(attributes); 1288 try { 1289 TResult tResult = handler.get(tTableName, tGet); 1290 fail("Get with error attribute should have thrown an exception"); 1291 } catch (TException e) { 1292 LOG.info("Received exception: ", e); 1293 metricsHelper.assertCounter("get_num_ops", preGetCounter + 1, metrics.getSource()); 1294 metricsHelper.assertCounter(exceptionKey, preExceptionCounter + 1, metrics.getSource()); 1295 } 1296 1297 } 1298 1299 /** 1300 * See HBASE-17611 1301 * 1302 * Latency metrics were capped at ~ 2 seconds due to the use of an int variable to capture the 1303 * duration. 1304 */ 1305 @Test 1306 public void testMetricsPrecision() throws Exception { 1307 byte[] rowkey = Bytes.toBytes("row1"); 1308 byte[] family = Bytes.toBytes("f"); 1309 byte[] col = Bytes.toBytes("c"); 1310 // create a table which will throw exceptions for requests 1311 TableName tableName = TableName.valueOf("testMetricsPrecision"); 1312 HTableDescriptor tableDesc = new HTableDescriptor(tableName); 1313 tableDesc.addCoprocessor(DelayingRegionObserver.class.getName()); 1314 tableDesc.addFamily(new HColumnDescriptor(family)); 1315 1316 Table table = null; 1317 try { 1318 table = UTIL.createTable(tableDesc, null); 1319 1320 table.put(new Put(rowkey).addColumn(family, col, Bytes.toBytes("val1"))); 1321 1322 ThriftHBaseServiceHandler hbaseHandler = createHandler(); 1323 ThriftMetrics metrics = getMetrics(UTIL.getConfiguration()); 1324 THBaseService.Iface handler = 1325 HbaseHandlerMetricsProxy.newInstance(hbaseHandler, metrics, null); 1326 ByteBuffer tTableName = wrap(tableName.getName()); 1327 1328 // check metrics latency with a successful get 1329 TGet tGet = new TGet(wrap(rowkey)); 1330 TResult tResult = handler.get(tTableName, tGet); 1331 1332 List<TColumnValue> expectedColumnValues = Lists.newArrayList( 1333 new TColumnValue(wrap(family), wrap(col), wrap(Bytes.toBytes("val1"))) 1334 ); 1335 assertArrayEquals(rowkey, tResult.getRow()); 1336 List<TColumnValue> returnedColumnValues = tResult.getColumnValues(); 1337 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues); 1338 1339 metricsHelper.assertGaugeGt("get_max", 3000L, metrics.getSource()); 1340 } finally { 1341 if (table != null) { 1342 try { 1343 table.close(); 1344 } catch (IOException ignored) { 1345 } 1346 UTIL.deleteTable(tableName); 1347 } 1348 } 1349 } 1350 1351 1352 @Test 1353 public void testAttribute() throws Exception { 1354 byte[] rowName = Bytes.toBytes("testAttribute"); 1355 byte[] attributeKey = Bytes.toBytes("attribute1"); 1356 byte[] attributeValue = Bytes.toBytes("value1"); 1357 Map<ByteBuffer, ByteBuffer> attributes = new HashMap<>(); 1358 attributes.put(wrap(attributeKey), wrap(attributeValue)); 1359 1360 TGet tGet = new TGet(wrap(rowName)); 1361 tGet.setAttributes(attributes); 1362 Get get = getFromThrift(tGet); 1363 assertArrayEquals(get.getAttribute("attribute1"), attributeValue); 1364 1365 List<TColumnValue> columnValues = new ArrayList<>(1); 1366 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 1367 TPut tPut = new TPut(wrap(rowName) , columnValues); 1368 tPut.setAttributes(attributes); 1369 Put put = putFromThrift(tPut); 1370 assertArrayEquals(put.getAttribute("attribute1"), attributeValue); 1371 1372 TScan tScan = new TScan(); 1373 tScan.setAttributes(attributes); 1374 Scan scan = scanFromThrift(tScan); 1375 assertArrayEquals(scan.getAttribute("attribute1"), attributeValue); 1376 1377 List<TColumnIncrement> incrementColumns = new ArrayList<>(1); 1378 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname))); 1379 TIncrement tIncrement = new TIncrement(wrap(rowName), incrementColumns); 1380 tIncrement.setAttributes(attributes); 1381 Increment increment = incrementFromThrift(tIncrement); 1382 assertArrayEquals(increment.getAttribute("attribute1"), attributeValue); 1383 1384 TDelete tDelete = new TDelete(wrap(rowName)); 1385 tDelete.setAttributes(attributes); 1386 Delete delete = deleteFromThrift(tDelete); 1387 assertArrayEquals(delete.getAttribute("attribute1"), attributeValue); 1388 } 1389 1390 /** 1391 * Put valueA to a row, make sure put has happened, then create a mutation object to put valueB 1392 * and delete ValueA, then check that the row value is only valueB. 1393 */ 1394 @Test 1395 public void testMutateRow() throws Exception { 1396 ThriftHBaseServiceHandler handler = createHandler(); 1397 byte[] rowName = Bytes.toBytes("testMutateRow"); 1398 ByteBuffer table = wrap(tableAname); 1399 1400 List<TColumnValue> columnValuesA = new ArrayList<>(1); 1401 TColumnValue columnValueA = new TColumnValue(wrap(familyAname), wrap(qualifierAname), 1402 wrap(valueAname)); 1403 columnValuesA.add(columnValueA); 1404 TPut putA = new TPut(wrap(rowName), columnValuesA); 1405 putA.setColumnValues(columnValuesA); 1406 1407 handler.put(table,putA); 1408 1409 TGet get = new TGet(wrap(rowName)); 1410 TResult result = handler.get(table, get); 1411 assertArrayEquals(rowName, result.getRow()); 1412 List<TColumnValue> returnedColumnValues = result.getColumnValues(); 1413 1414 List<TColumnValue> expectedColumnValues = new ArrayList<>(1); 1415 expectedColumnValues.add(columnValueA); 1416 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues); 1417 1418 List<TColumnValue> columnValuesB = new ArrayList<>(1); 1419 TColumnValue columnValueB = new TColumnValue(wrap(familyAname), wrap(qualifierBname), 1420 wrap(valueBname)); 1421 columnValuesB.add(columnValueB); 1422 TPut putB = new TPut(wrap(rowName), columnValuesB); 1423 putB.setColumnValues(columnValuesB); 1424 1425 TDelete delete = new TDelete(wrap(rowName)); 1426 List<TColumn> deleteColumns = new ArrayList<>(1); 1427 TColumn deleteColumn = new TColumn(wrap(familyAname)); 1428 deleteColumn.setQualifier(qualifierAname); 1429 deleteColumns.add(deleteColumn); 1430 delete.setColumns(deleteColumns); 1431 1432 List<TMutation> mutations = new ArrayList<>(2); 1433 TMutation mutationA = TMutation.put(putB); 1434 mutations.add(mutationA); 1435 1436 TMutation mutationB = TMutation.deleteSingle(delete); 1437 mutations.add(mutationB); 1438 1439 TRowMutations tRowMutations = new TRowMutations(wrap(rowName),mutations); 1440 handler.mutateRow(table,tRowMutations); 1441 1442 result = handler.get(table, get); 1443 assertArrayEquals(rowName, result.getRow()); 1444 returnedColumnValues = result.getColumnValues(); 1445 1446 expectedColumnValues = new ArrayList<>(1); 1447 expectedColumnValues.add(columnValueB); 1448 assertTColumnValuesEqual(expectedColumnValues, returnedColumnValues); 1449 } 1450 1451 /** 1452 * Create TPut, TDelete , TIncrement objects, set durability then call ThriftUtility 1453 * functions to get Put , Delete and Increment respectively. Use getDurability to make sure 1454 * the returned objects have the appropriate durability setting. 1455 */ 1456 @Test 1457 public void testDurability() throws Exception { 1458 byte[] rowName = Bytes.toBytes("testDurability"); 1459 List<TColumnValue> columnValues = new ArrayList<>(1); 1460 columnValues.add(new TColumnValue(wrap(familyAname), wrap(qualifierAname), wrap(valueAname))); 1461 1462 List<TColumnIncrement> incrementColumns = new ArrayList<>(1); 1463 incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname))); 1464 1465 TDelete tDelete = new TDelete(wrap(rowName)); 1466 tDelete.setDurability(TDurability.SKIP_WAL); 1467 Delete delete = deleteFromThrift(tDelete); 1468 assertEquals(Durability.SKIP_WAL, delete.getDurability()); 1469 1470 tDelete.setDurability(TDurability.ASYNC_WAL); 1471 delete = deleteFromThrift(tDelete); 1472 assertEquals(Durability.ASYNC_WAL, delete.getDurability()); 1473 1474 tDelete.setDurability(TDurability.SYNC_WAL); 1475 delete = deleteFromThrift(tDelete); 1476 assertEquals(Durability.SYNC_WAL, delete.getDurability()); 1477 1478 tDelete.setDurability(TDurability.FSYNC_WAL); 1479 delete = deleteFromThrift(tDelete); 1480 assertEquals(Durability.FSYNC_WAL, delete.getDurability()); 1481 1482 TPut tPut = new TPut(wrap(rowName), columnValues); 1483 tPut.setDurability(TDurability.SKIP_WAL); 1484 Put put = putFromThrift(tPut); 1485 assertEquals(Durability.SKIP_WAL, put.getDurability()); 1486 1487 tPut.setDurability(TDurability.ASYNC_WAL); 1488 put = putFromThrift(tPut); 1489 assertEquals(Durability.ASYNC_WAL, put.getDurability()); 1490 1491 tPut.setDurability(TDurability.SYNC_WAL); 1492 put = putFromThrift(tPut); 1493 assertEquals(Durability.SYNC_WAL, put.getDurability()); 1494 1495 tPut.setDurability(TDurability.FSYNC_WAL); 1496 put = putFromThrift(tPut); 1497 assertEquals(Durability.FSYNC_WAL, put.getDurability()); 1498 1499 TIncrement tIncrement = new TIncrement(wrap(rowName), incrementColumns); 1500 1501 tIncrement.setDurability(TDurability.SKIP_WAL); 1502 Increment increment = incrementFromThrift(tIncrement); 1503 assertEquals(Durability.SKIP_WAL, increment.getDurability()); 1504 1505 tIncrement.setDurability(TDurability.ASYNC_WAL); 1506 increment = incrementFromThrift(tIncrement); 1507 assertEquals(Durability.ASYNC_WAL, increment.getDurability()); 1508 1509 tIncrement.setDurability(TDurability.SYNC_WAL); 1510 increment = incrementFromThrift(tIncrement); 1511 assertEquals(Durability.SYNC_WAL, increment.getDurability()); 1512 1513 tIncrement.setDurability(TDurability.FSYNC_WAL); 1514 increment = incrementFromThrift(tIncrement); 1515 assertEquals(Durability.FSYNC_WAL, increment.getDurability()); 1516 } 1517 1518 @Test 1519 public void testCheckAndMutate() throws Exception { 1520 ThriftHBaseServiceHandler handler = createHandler(); 1521 ByteBuffer table = wrap(tableAname); 1522 ByteBuffer row = wrap(Bytes.toBytes("row")); 1523 ByteBuffer family = wrap(familyAname); 1524 ByteBuffer qualifier = wrap(qualifierAname); 1525 ByteBuffer value = wrap(valueAname); 1526 1527 // Create a mutation to write to 'B', our "mutate" of "checkAndMutate" 1528 List<TColumnValue> columnValuesB = new ArrayList<>(1); 1529 TColumnValue columnValueB = new TColumnValue(family, wrap(qualifierBname), wrap(valueBname)); 1530 columnValuesB.add(columnValueB); 1531 TPut putB = new TPut(row, columnValuesB); 1532 putB.setColumnValues(columnValuesB); 1533 1534 TRowMutations tRowMutations = new TRowMutations(row, 1535 Arrays.<TMutation> asList(TMutation.put(putB))); 1536 1537 // Empty table when we begin 1538 TResult result = handler.get(table, new TGet(row)); 1539 assertEquals(0, result.getColumnValuesSize()); 1540 1541 // checkAndMutate -- condition should fail because the value doesn't exist. 1542 assertFalse("Expected condition to not pass", 1543 handler.checkAndMutate(table, row, family, qualifier, TCompareOp.EQUAL, value, 1544 tRowMutations)); 1545 1546 List<TColumnValue> columnValuesA = new ArrayList<>(1); 1547 TColumnValue columnValueA = new TColumnValue(family, qualifier, value); 1548 columnValuesA.add(columnValueA); 1549 1550 // Put an update 'A' 1551 handler.put(table, new TPut(row, columnValuesA)); 1552 1553 // Verify that the update is there 1554 result = handler.get(table, new TGet(row)); 1555 assertEquals(1, result.getColumnValuesSize()); 1556 assertTColumnValueEqual(columnValueA, result.getColumnValues().get(0)); 1557 1558 // checkAndMutate -- condition should pass since we added the value 1559 assertTrue("Expected condition to pass", 1560 handler.checkAndMutate(table, row, family, qualifier, TCompareOp.EQUAL, value, 1561 tRowMutations)); 1562 1563 result = handler.get(table, new TGet(row)); 1564 assertEquals(2, result.getColumnValuesSize()); 1565 assertTColumnValueEqual(columnValueA, result.getColumnValues().get(0)); 1566 assertTColumnValueEqual(columnValueB, result.getColumnValues().get(1)); 1567 } 1568 1569 @Test 1570 public void testConsistency() throws Exception { 1571 byte[] rowName = Bytes.toBytes("testConsistency"); 1572 TGet tGet = new TGet(wrap(rowName)); 1573 tGet.setConsistency(TConsistency.STRONG); 1574 Get get = getFromThrift(tGet); 1575 assertEquals(Consistency.STRONG, get.getConsistency()); 1576 1577 tGet.setConsistency(TConsistency.TIMELINE); 1578 tGet.setTargetReplicaId(1); 1579 get = getFromThrift(tGet); 1580 assertEquals(Consistency.TIMELINE, get.getConsistency()); 1581 assertEquals(1, get.getReplicaId()); 1582 1583 TScan tScan = new TScan(); 1584 tScan.setConsistency(TConsistency.STRONG); 1585 Scan scan = scanFromThrift(tScan); 1586 assertEquals(Consistency.STRONG, scan.getConsistency()); 1587 1588 tScan.setConsistency(TConsistency.TIMELINE); 1589 tScan.setTargetReplicaId(1); 1590 scan = scanFromThrift(tScan); 1591 assertEquals(Consistency.TIMELINE, scan.getConsistency()); 1592 assertEquals(1, scan.getReplicaId()); 1593 1594 TResult tResult = new TResult(); 1595 assertFalse(tResult.isSetStale()); 1596 tResult.setStale(true); 1597 assertTrue(tResult.isSetStale()); 1598 } 1599 1600 @Test 1601 public void testDDLOpertions() throws Exception { 1602 String namespace = "testDDLOpertionsNamespace"; 1603 String table = "testDDLOpertionsTable"; 1604 TTableName tTableName = new TTableName(); 1605 tTableName.setNs(Bytes.toBytes(namespace)); 1606 tTableName.setQualifier(Bytes.toBytes(table)); 1607 ThriftHBaseServiceHandler handler = createHandler(); 1608 //create name space 1609 TNamespaceDescriptor namespaceDescriptor = new TNamespaceDescriptor(); 1610 namespaceDescriptor.setName(namespace); 1611 namespaceDescriptor.putToConfiguration("key1", "value1"); 1612 namespaceDescriptor.putToConfiguration("key2", "value2"); 1613 handler.createNamespace(namespaceDescriptor); 1614 //list namespace 1615 List<TNamespaceDescriptor> namespaceDescriptors = handler.listNamespaceDescriptors(); 1616 // should have 3 namespace, default hbase and testDDLOpertionsNamespace 1617 assertTrue(namespaceDescriptors.size() == 3); 1618 //modify namesapce 1619 namespaceDescriptor.putToConfiguration("kye3", "value3"); 1620 handler.modifyNamespace(namespaceDescriptor); 1621 //get namespace 1622 TNamespaceDescriptor namespaceDescriptorReturned = handler.getNamespaceDescriptor(namespace); 1623 assertTrue(namespaceDescriptorReturned.getConfiguration().size() == 3); 1624 //create table 1625 TTableDescriptor tableDescriptor = new TTableDescriptor(); 1626 tableDescriptor.setTableName(tTableName); 1627 TColumnFamilyDescriptor columnFamilyDescriptor1 = new TColumnFamilyDescriptor(); 1628 columnFamilyDescriptor1.setName(familyAname); 1629 columnFamilyDescriptor1.setDataBlockEncoding(TDataBlockEncoding.DIFF); 1630 tableDescriptor.addToColumns(columnFamilyDescriptor1); 1631 List<ByteBuffer> splitKeys = new ArrayList<>(); 1632 splitKeys.add(ByteBuffer.wrap(Bytes.toBytes(5))); 1633 handler.createTable(tableDescriptor, splitKeys); 1634 //modify table 1635 tableDescriptor.setDurability(TDurability.ASYNC_WAL); 1636 handler.modifyTable(tableDescriptor); 1637 //modify column family 1638 columnFamilyDescriptor1.setInMemory(true); 1639 handler.modifyColumnFamily(tTableName, columnFamilyDescriptor1); 1640 //add column family 1641 TColumnFamilyDescriptor columnFamilyDescriptor2 = new TColumnFamilyDescriptor(); 1642 columnFamilyDescriptor2.setName(familyBname); 1643 columnFamilyDescriptor2.setDataBlockEncoding(TDataBlockEncoding.PREFIX); 1644 handler.addColumnFamily(tTableName, columnFamilyDescriptor2); 1645 //get table descriptor 1646 TTableDescriptor tableDescriptorReturned = handler.getTableDescriptor(tTableName); 1647 assertTrue(tableDescriptorReturned.getColumns().size() == 2); 1648 assertTrue(tableDescriptorReturned.getDurability() == TDurability.ASYNC_WAL); 1649 TColumnFamilyDescriptor columnFamilyDescriptor1Returned = tableDescriptorReturned.getColumns() 1650 .stream().filter(desc -> Bytes.equals(desc.getName(), familyAname)).findFirst().get(); 1651 assertTrue(columnFamilyDescriptor1Returned.isInMemory() == true); 1652 //delete column family 1653 handler.deleteColumnFamily(tTableName, ByteBuffer.wrap(familyBname)); 1654 tableDescriptorReturned = handler.getTableDescriptor(tTableName); 1655 assertTrue(tableDescriptorReturned.getColumns().size() == 1); 1656 //disable table 1657 handler.disableTable(tTableName); 1658 assertTrue(handler.isTableDisabled(tTableName)); 1659 //enable table 1660 handler.enableTable(tTableName); 1661 assertTrue(handler.isTableEnabled(tTableName)); 1662 assertTrue(handler.isTableAvailable(tTableName)); 1663 //truncate table 1664 handler.disableTable(tTableName); 1665 handler.truncateTable(tTableName, true); 1666 assertTrue(handler.isTableAvailable(tTableName)); 1667 //delete table 1668 handler.disableTable(tTableName); 1669 handler.deleteTable(tTableName); 1670 assertFalse(handler.tableExists(tTableName)); 1671 //delete namespace 1672 handler.deleteNamespace(namespace); 1673 namespaceDescriptors = handler.listNamespaceDescriptors(); 1674 // should have 2 namespace, default and hbase 1675 assertTrue(namespaceDescriptors.size() == 2); 1676 } 1677 1678 @Test 1679 public void testGetTableDescriptor() throws Exception { 1680 ThriftHBaseServiceHandler handler = createHandler(); 1681 TTableDescriptor tableDescriptor = handler 1682 .getTableDescriptor(ThriftUtilities.tableNameFromHBase(TableName.valueOf(tableAname))); 1683 TableDescriptor table = ThriftUtilities.tableDescriptorFromThrift(tableDescriptor); 1684 assertTrue(table.getTableName().equals(TableName.valueOf(tableAname))); 1685 assertTrue(table.getColumnFamilies().length == 2); 1686 assertTrue(table.getColumnFamily(familyAname).getMaxVersions() == 3); 1687 assertTrue(table.getColumnFamily(familyBname).getMaxVersions() == 2); 1688 } 1689 1690 public static class DelayingRegionObserver implements RegionCoprocessor, RegionObserver { 1691 private static final Logger LOG = LoggerFactory.getLogger(DelayingRegionObserver.class); 1692 // sleep time in msec 1693 private long delayMillis; 1694 1695 @Override 1696 public Optional<RegionObserver> getRegionObserver() { 1697 return Optional.of(this); 1698 } 1699 1700 @Override 1701 public void start(CoprocessorEnvironment e) throws IOException { 1702 this.delayMillis = e.getConfiguration() 1703 .getLong("delayingregionobserver.delay", 3000); 1704 } 1705 1706 @Override 1707 public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> e, Get get, 1708 List<Cell> results) throws IOException { 1709 try { 1710 long start = System.currentTimeMillis(); 1711 TimeUnit.MILLISECONDS.sleep(delayMillis); 1712 if (LOG.isTraceEnabled()) { 1713 LOG.trace("Slept for " + (System.currentTimeMillis() - start) + " msec"); 1714 } 1715 } catch (InterruptedException ie) { 1716 throw new InterruptedIOException("Interrupted while sleeping"); 1717 } 1718 } 1719 } 1720} 1721