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