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