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.rest.client; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertNull; 024import static org.junit.Assert.assertTrue; 025 026import java.io.IOException; 027import java.util.ArrayList; 028import java.util.Collections; 029import java.util.Iterator; 030import java.util.List; 031import org.apache.hadoop.hbase.Cell; 032import org.apache.hadoop.hbase.CellUtil; 033import org.apache.hadoop.hbase.HBaseClassTestRule; 034import org.apache.hadoop.hbase.HBaseTestingUtil; 035import org.apache.hadoop.hbase.TableName; 036import org.apache.hadoop.hbase.client.Admin; 037import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 038import org.apache.hadoop.hbase.client.Delete; 039import org.apache.hadoop.hbase.client.Get; 040import org.apache.hadoop.hbase.client.Put; 041import org.apache.hadoop.hbase.client.Result; 042import org.apache.hadoop.hbase.client.ResultScanner; 043import org.apache.hadoop.hbase.client.Scan; 044import org.apache.hadoop.hbase.client.Table; 045import org.apache.hadoop.hbase.client.TableDescriptor; 046import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 047import org.apache.hadoop.hbase.rest.HBaseRESTTestingUtility; 048import org.apache.hadoop.hbase.rest.RESTServlet; 049import org.apache.hadoop.hbase.testclassification.MediumTests; 050import org.apache.hadoop.hbase.testclassification.RestTests; 051import org.apache.hadoop.hbase.util.Bytes; 052import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 053import org.apache.http.Header; 054import org.apache.http.message.BasicHeader; 055import org.junit.After; 056import org.junit.AfterClass; 057import org.junit.Before; 058import org.junit.BeforeClass; 059import org.junit.ClassRule; 060import org.junit.Test; 061import org.junit.experimental.categories.Category; 062 063@Category({ RestTests.class, MediumTests.class }) 064public class TestRemoteTable { 065 @ClassRule 066 public static final HBaseClassTestRule CLASS_RULE = 067 HBaseClassTestRule.forClass(TestRemoteTable.class); 068 069 // Verify that invalid URL characters and arbitrary bytes are escaped when 070 // constructing REST URLs per HBASE-7621. RemoteHTable should support row keys 071 // and qualifiers containing any byte for all table operations. 072 private static final String INVALID_URL_CHARS_1 = 073 "|\"\\^{}\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000B\u000C"; 074 075 // HColumnDescriptor prevents certain characters in column names. The following 076 // are examples of characters are allowed in column names but are not valid in 077 // URLs. 078 private static final String INVALID_URL_CHARS_2 = "|^{}\u0242"; 079 080 // Besides alphanumeric these characters can also be present in table names. 081 private static final String VALID_TABLE_NAME_CHARS = "_-."; 082 083 private static final TableName TABLE = 084 TableName.valueOf("TestRemoteTable" + VALID_TABLE_NAME_CHARS); 085 086 private static final byte[] ROW_1 = Bytes.toBytes("testrow1" + INVALID_URL_CHARS_1); 087 private static final byte[] ROW_2 = Bytes.toBytes("testrow2" + INVALID_URL_CHARS_1); 088 private static final byte[] ROW_3 = Bytes.toBytes("testrow3" + INVALID_URL_CHARS_1); 089 private static final byte[] ROW_4 = Bytes.toBytes("testrow4" + INVALID_URL_CHARS_1); 090 091 private static final byte[] COLUMN_1 = Bytes.toBytes("a" + INVALID_URL_CHARS_2); 092 private static final byte[] COLUMN_2 = Bytes.toBytes("b" + INVALID_URL_CHARS_2); 093 private static final byte[] COLUMN_3 = Bytes.toBytes("c" + INVALID_URL_CHARS_2); 094 095 private static final byte[] QUALIFIER_1 = Bytes.toBytes("1" + INVALID_URL_CHARS_1); 096 private static final byte[] QUALIFIER_2 = Bytes.toBytes("2" + INVALID_URL_CHARS_1); 097 private static final byte[] VALUE_1 = Bytes.toBytes("testvalue1"); 098 private static final byte[] VALUE_2 = Bytes.toBytes("testvalue2"); 099 100 private static final long ONE_HOUR = 60 * 60 * 1000; 101 private static final long TS_2 = EnvironmentEdgeManager.currentTime(); 102 private static final long TS_1 = TS_2 - ONE_HOUR; 103 104 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 105 private static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility(); 106 private RemoteHTable remoteTable; 107 108 @BeforeClass 109 public static void setUpBeforeClass() throws Exception { 110 TEST_UTIL.startMiniCluster(); 111 REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); 112 } 113 114 @Before 115 public void before() throws Exception { 116 Admin admin = TEST_UTIL.getAdmin(); 117 if (admin.tableExists(TABLE)) { 118 if (admin.isTableEnabled(TABLE)) { 119 admin.disableTable(TABLE); 120 } 121 122 admin.deleteTable(TABLE); 123 } 124 125 TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TABLE) 126 .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(COLUMN_1).setMaxVersions(3).build()) 127 .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(COLUMN_2).setMaxVersions(3).build()) 128 .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(COLUMN_3).setMaxVersions(3).build()) 129 .build(); 130 admin.createTable(tableDescriptor); 131 try (Table table = TEST_UTIL.getConnection().getTable(TABLE)) { 132 Put put = new Put(ROW_1); 133 put.addColumn(COLUMN_1, QUALIFIER_1, TS_2, VALUE_1); 134 table.put(put); 135 put = new Put(ROW_2); 136 put.addColumn(COLUMN_1, QUALIFIER_1, TS_1, VALUE_1); 137 put.addColumn(COLUMN_1, QUALIFIER_1, TS_2, VALUE_2); 138 put.addColumn(COLUMN_2, QUALIFIER_2, TS_2, VALUE_2); 139 table.put(put); 140 } 141 remoteTable = 142 new RemoteHTable(new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort())), 143 TEST_UTIL.getConfiguration(), TABLE.toBytes()); 144 } 145 146 @After 147 public void after() throws Exception { 148 remoteTable.close(); 149 } 150 151 @AfterClass 152 public static void tearDownAfterClass() throws Exception { 153 REST_TEST_UTIL.shutdownServletContainer(); 154 TEST_UTIL.shutdownMiniCluster(); 155 } 156 157 @Test 158 public void testGetTableDescriptor() throws IOException { 159 try (Table table = TEST_UTIL.getConnection().getTable(TABLE)) { 160 TableDescriptor local = table.getDescriptor(); 161 assertEquals(remoteTable.getDescriptor(), local); 162 } 163 } 164 165 @Test 166 public void testGet() throws IOException { 167 Get get = new Get(ROW_1); 168 Result result = remoteTable.get(get); 169 byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1); 170 byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2); 171 assertNotNull(value1); 172 assertTrue(Bytes.equals(VALUE_1, value1)); 173 assertNull(value2); 174 175 get = new Get(ROW_1); 176 get.addFamily(COLUMN_3); 177 result = remoteTable.get(get); 178 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 179 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 180 assertNull(value1); 181 assertNull(value2); 182 183 get = new Get(ROW_1); 184 get.addColumn(COLUMN_1, QUALIFIER_1); 185 get.addColumn(COLUMN_2, QUALIFIER_2); 186 result = remoteTable.get(get); 187 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 188 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 189 assertNotNull(value1); 190 assertTrue(Bytes.equals(VALUE_1, value1)); 191 assertNull(value2); 192 193 get = new Get(ROW_2); 194 result = remoteTable.get(get); 195 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 196 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 197 assertNotNull(value1); 198 assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2 199 assertNotNull(value2); 200 assertTrue(Bytes.equals(VALUE_2, value2)); 201 202 get = new Get(ROW_2); 203 get.addFamily(COLUMN_1); 204 result = remoteTable.get(get); 205 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 206 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 207 assertNotNull(value1); 208 assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2 209 assertNull(value2); 210 211 get = new Get(ROW_2); 212 get.addColumn(COLUMN_1, QUALIFIER_1); 213 get.addColumn(COLUMN_2, QUALIFIER_2); 214 result = remoteTable.get(get); 215 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 216 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 217 assertNotNull(value1); 218 assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2 219 assertNotNull(value2); 220 assertTrue(Bytes.equals(VALUE_2, value2)); 221 222 // test timestamp 223 get = new Get(ROW_2); 224 get.addFamily(COLUMN_1); 225 get.addFamily(COLUMN_2); 226 get.setTimestamp(TS_1); 227 result = remoteTable.get(get); 228 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 229 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 230 assertNotNull(value1); 231 assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1 232 assertNull(value2); 233 234 // test timerange 235 get = new Get(ROW_2); 236 get.addFamily(COLUMN_1); 237 get.addFamily(COLUMN_2); 238 get.setTimeRange(0, TS_1 + 1); 239 result = remoteTable.get(get); 240 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 241 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 242 assertNotNull(value1); 243 assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1 244 assertNull(value2); 245 246 // test maxVersions 247 get = new Get(ROW_2); 248 get.addFamily(COLUMN_1); 249 get.readVersions(2); 250 result = remoteTable.get(get); 251 int count = 0; 252 for (Cell kv : result.listCells()) { 253 if (CellUtil.matchingFamily(kv, COLUMN_1) && TS_1 == kv.getTimestamp()) { 254 assertTrue(CellUtil.matchingValue(kv, VALUE_1)); // @TS_1 255 count++; 256 } 257 if (CellUtil.matchingFamily(kv, COLUMN_1) && TS_2 == kv.getTimestamp()) { 258 assertTrue(CellUtil.matchingValue(kv, VALUE_2)); // @TS_2 259 count++; 260 } 261 } 262 assertEquals(2, count); 263 } 264 265 @Test 266 public void testMultiGet() throws Exception { 267 ArrayList<Get> gets = new ArrayList<>(2); 268 gets.add(new Get(ROW_1)); 269 gets.add(new Get(ROW_2)); 270 Result[] results = remoteTable.get(gets); 271 assertNotNull(results); 272 assertEquals(2, results.length); 273 assertEquals(1, results[0].size()); 274 assertEquals(2, results[1].size()); 275 276 // Test Versions 277 gets = new ArrayList<>(2); 278 Get g = new Get(ROW_1); 279 g.readVersions(3); 280 gets.add(g); 281 gets.add(new Get(ROW_2)); 282 results = remoteTable.get(gets); 283 assertNotNull(results); 284 assertEquals(2, results.length); 285 assertEquals(1, results[0].size()); 286 assertEquals(3, results[1].size()); 287 288 // 404 289 gets = new ArrayList<>(1); 290 gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE"))); 291 results = remoteTable.get(gets); 292 assertNotNull(results); 293 assertEquals(0, results.length); 294 295 gets = new ArrayList<>(3); 296 gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE"))); 297 gets.add(new Get(ROW_1)); 298 gets.add(new Get(ROW_2)); 299 results = remoteTable.get(gets); 300 assertNotNull(results); 301 assertEquals(2, results.length); 302 } 303 304 @Test 305 public void testPut() throws IOException { 306 Put put = new Put(ROW_3); 307 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 308 remoteTable.put(put); 309 310 Get get = new Get(ROW_3); 311 get.addFamily(COLUMN_1); 312 Result result = remoteTable.get(get); 313 byte[] value = result.getValue(COLUMN_1, QUALIFIER_1); 314 assertNotNull(value); 315 assertTrue(Bytes.equals(VALUE_1, value)); 316 317 // multiput 318 List<Put> puts = new ArrayList<>(3); 319 put = new Put(ROW_3); 320 put.addColumn(COLUMN_2, QUALIFIER_2, VALUE_2); 321 puts.add(put); 322 put = new Put(ROW_4); 323 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 324 puts.add(put); 325 put = new Put(ROW_4); 326 put.addColumn(COLUMN_2, QUALIFIER_2, VALUE_2); 327 puts.add(put); 328 remoteTable.put(puts); 329 330 get = new Get(ROW_3); 331 get.addFamily(COLUMN_2); 332 result = remoteTable.get(get); 333 value = result.getValue(COLUMN_2, QUALIFIER_2); 334 assertNotNull(value); 335 assertTrue(Bytes.equals(VALUE_2, value)); 336 get = new Get(ROW_4); 337 result = remoteTable.get(get); 338 value = result.getValue(COLUMN_1, QUALIFIER_1); 339 assertNotNull(value); 340 assertTrue(Bytes.equals(VALUE_1, value)); 341 value = result.getValue(COLUMN_2, QUALIFIER_2); 342 assertNotNull(value); 343 assertTrue(Bytes.equals(VALUE_2, value)); 344 345 assertTrue(Bytes.equals(Bytes.toBytes("TestRemoteTable" + VALID_TABLE_NAME_CHARS), 346 remoteTable.getTableName())); 347 } 348 349 @Test 350 public void testDelete() throws IOException { 351 Put put = new Put(ROW_3); 352 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 353 put.addColumn(COLUMN_2, QUALIFIER_2, VALUE_2); 354 put.addColumn(COLUMN_3, QUALIFIER_1, VALUE_1); 355 put.addColumn(COLUMN_3, QUALIFIER_2, VALUE_2); 356 remoteTable.put(put); 357 358 Get get = new Get(ROW_3); 359 get.addFamily(COLUMN_1); 360 get.addFamily(COLUMN_2); 361 get.addFamily(COLUMN_3); 362 Result result = remoteTable.get(get); 363 byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1); 364 byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2); 365 byte[] value3 = result.getValue(COLUMN_3, QUALIFIER_1); 366 byte[] value4 = result.getValue(COLUMN_3, QUALIFIER_2); 367 assertNotNull(value1); 368 assertTrue(Bytes.equals(VALUE_1, value1)); 369 assertNotNull(value2); 370 assertTrue(Bytes.equals(VALUE_2, value2)); 371 assertNotNull(value3); 372 assertTrue(Bytes.equals(VALUE_1, value3)); 373 assertNotNull(value4); 374 assertTrue(Bytes.equals(VALUE_2, value4)); 375 376 Delete delete = new Delete(ROW_3); 377 delete.addColumn(COLUMN_2, QUALIFIER_2); 378 remoteTable.delete(delete); 379 380 get = new Get(ROW_3); 381 get.addFamily(COLUMN_1); 382 get.addFamily(COLUMN_2); 383 result = remoteTable.get(get); 384 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 385 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 386 assertNotNull(value1); 387 assertTrue(Bytes.equals(VALUE_1, value1)); 388 assertNull(value2); 389 390 delete = new Delete(ROW_3); 391 delete.setTimestamp(1L); 392 remoteTable.delete(delete); 393 394 get = new Get(ROW_3); 395 get.addFamily(COLUMN_1); 396 get.addFamily(COLUMN_2); 397 result = remoteTable.get(get); 398 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 399 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 400 assertNotNull(value1); 401 assertTrue(Bytes.equals(VALUE_1, value1)); 402 assertNull(value2); 403 404 // Delete column family from row 405 delete = new Delete(ROW_3); 406 delete.addFamily(COLUMN_3); 407 remoteTable.delete(delete); 408 409 get = new Get(ROW_3); 410 get.addFamily(COLUMN_3); 411 result = remoteTable.get(get); 412 value3 = result.getValue(COLUMN_3, QUALIFIER_1); 413 value4 = result.getValue(COLUMN_3, QUALIFIER_2); 414 assertNull(value3); 415 assertNull(value4); 416 417 delete = new Delete(ROW_3); 418 remoteTable.delete(delete); 419 420 get = new Get(ROW_3); 421 get.addFamily(COLUMN_1); 422 get.addFamily(COLUMN_2); 423 result = remoteTable.get(get); 424 value1 = result.getValue(COLUMN_1, QUALIFIER_1); 425 value2 = result.getValue(COLUMN_2, QUALIFIER_2); 426 assertNull(value1); 427 assertNull(value2); 428 } 429 430 /** 431 * Test RemoteHTable.Scanner 432 */ 433 @Test 434 public void testScanner() throws IOException { 435 List<Put> puts = new ArrayList<>(4); 436 Put put = new Put(ROW_1); 437 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 438 puts.add(put); 439 put = new Put(ROW_2); 440 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 441 puts.add(put); 442 put = new Put(ROW_3); 443 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 444 puts.add(put); 445 put = new Put(ROW_4); 446 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 447 puts.add(put); 448 remoteTable.put(puts); 449 450 ResultScanner scanner = remoteTable.getScanner(new Scan()); 451 452 Result[] results = scanner.next(1); 453 assertNotNull(results); 454 assertEquals(1, results.length); 455 assertTrue(Bytes.equals(ROW_1, results[0].getRow())); 456 457 Result result = scanner.next(); 458 assertNotNull(result); 459 assertTrue(Bytes.equals(ROW_2, result.getRow())); 460 461 results = scanner.next(2); 462 assertNotNull(results); 463 assertEquals(2, results.length); 464 assertTrue(Bytes.equals(ROW_3, results[0].getRow())); 465 assertTrue(Bytes.equals(ROW_4, results[1].getRow())); 466 467 results = scanner.next(1); 468 assertNull(results); 469 scanner.close(); 470 471 scanner = remoteTable.getScanner(COLUMN_1); 472 results = scanner.next(4); 473 assertNotNull(results); 474 assertEquals(4, results.length); 475 assertTrue(Bytes.equals(ROW_1, results[0].getRow())); 476 assertTrue(Bytes.equals(ROW_2, results[1].getRow())); 477 assertTrue(Bytes.equals(ROW_3, results[2].getRow())); 478 assertTrue(Bytes.equals(ROW_4, results[3].getRow())); 479 480 scanner.close(); 481 482 scanner = remoteTable.getScanner(COLUMN_1, QUALIFIER_1); 483 results = scanner.next(4); 484 assertNotNull(results); 485 assertEquals(4, results.length); 486 assertTrue(Bytes.equals(ROW_1, results[0].getRow())); 487 assertTrue(Bytes.equals(ROW_2, results[1].getRow())); 488 assertTrue(Bytes.equals(ROW_3, results[2].getRow())); 489 assertTrue(Bytes.equals(ROW_4, results[3].getRow())); 490 scanner.close(); 491 assertTrue(remoteTable.isAutoFlush()); 492 } 493 494 @Test 495 public void testCheckAndDelete() throws IOException { 496 Get get = new Get(ROW_1); 497 Result result = remoteTable.get(get); 498 byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1); 499 byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2); 500 assertNotNull(value1); 501 assertTrue(Bytes.equals(VALUE_1, value1)); 502 assertNull(value2); 503 assertTrue(remoteTable.exists(get)); 504 assertEquals(1, remoteTable.exists(Collections.singletonList(get)).length); 505 Delete delete = new Delete(ROW_1); 506 507 remoteTable.checkAndMutate(ROW_1, COLUMN_1).qualifier(QUALIFIER_1).ifEquals(VALUE_1) 508 .thenDelete(delete); 509 assertFalse(remoteTable.exists(get)); 510 511 Put put = new Put(ROW_1); 512 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 513 remoteTable.put(put); 514 515 assertTrue(remoteTable.checkAndMutate(ROW_1, COLUMN_1).qualifier(QUALIFIER_1).ifEquals(VALUE_1) 516 .thenPut(put)); 517 assertFalse(remoteTable.checkAndMutate(ROW_1, COLUMN_1).qualifier(QUALIFIER_1).ifEquals(VALUE_2) 518 .thenPut(put)); 519 } 520 521 /** 522 * Test RemoteHable.Scanner.iterator method 523 */ 524 @Test 525 public void testIteratorScaner() throws IOException { 526 List<Put> puts = new ArrayList<>(4); 527 Put put = new Put(ROW_1); 528 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 529 puts.add(put); 530 put = new Put(ROW_2); 531 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 532 puts.add(put); 533 put = new Put(ROW_3); 534 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 535 puts.add(put); 536 put = new Put(ROW_4); 537 put.addColumn(COLUMN_1, QUALIFIER_1, VALUE_1); 538 puts.add(put); 539 remoteTable.put(puts); 540 541 ResultScanner scanner = remoteTable.getScanner(new Scan()); 542 Iterator<Result> iterator = scanner.iterator(); 543 assertTrue(iterator.hasNext()); 544 int counter = 0; 545 while (iterator.hasNext()) { 546 iterator.next(); 547 counter++; 548 } 549 assertEquals(4, counter); 550 } 551 552 /** 553 * Test a some methods of class Response. 554 */ 555 @Test 556 public void testResponse() { 557 Response response = new Response(200); 558 assertEquals(200, response.getCode()); 559 Header[] headers = new Header[2]; 560 headers[0] = new BasicHeader("header1", "value1"); 561 headers[1] = new BasicHeader("header2", "value2"); 562 response = new Response(200, headers); 563 assertEquals("value1", response.getHeader("header1")); 564 assertFalse(response.hasBody()); 565 response.setCode(404); 566 assertEquals(404, response.getCode()); 567 headers = new Header[2]; 568 headers[0] = new BasicHeader("header1", "value1.1"); 569 headers[1] = new BasicHeader("header2", "value2"); 570 response.setHeaders(headers); 571 assertEquals("value1.1", response.getHeader("header1")); 572 response.setBody(Bytes.toBytes("body")); 573 assertTrue(response.hasBody()); 574 } 575 576 /** 577 * Tests scanner with limitation limit the number of rows each scanner scan fetch at life time The 578 * number of rows returned should be equal to the limit 579 */ 580 @Test 581 public void testLimitedScan() throws Exception { 582 int numTrials = 100; 583 int limit = 60; 584 585 // Truncate the test table for inserting test scenarios rows keys 586 TEST_UTIL.getAdmin().disableTable(TABLE); 587 TEST_UTIL.getAdmin().truncateTable(TABLE, false); 588 String row = "testrow"; 589 590 try (Table table = TEST_UTIL.getConnection().getTable(TABLE)) { 591 List<Put> puts = new ArrayList<>(); 592 Put put = null; 593 for (int i = 1; i <= numTrials; i++) { 594 put = new Put(Bytes.toBytes(row + i)); 595 put.addColumn(COLUMN_1, QUALIFIER_1, TS_2, Bytes.toBytes("testvalue" + i)); 596 puts.add(put); 597 } 598 table.put(puts); 599 } 600 601 remoteTable = 602 new RemoteHTable(new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort())), 603 TEST_UTIL.getConfiguration(), TABLE.toBytes()); 604 605 Scan scan = new Scan(); 606 scan.setLimit(limit); 607 ResultScanner scanner = remoteTable.getScanner(scan); 608 Iterator<Result> resultIterator = scanner.iterator(); 609 int counter = 0; 610 while (resultIterator.hasNext()) { 611 resultIterator.next(); 612 counter++; 613 } 614 assertEquals(limit, counter); 615 } 616 617 /** 618 * Tests keeping a HBase scanner alive for long periods of time. Each call to next() should reset 619 * the ConnectionCache timeout for the scanner's connection. 620 * @throws Exception if starting the servlet container or disabling or truncating the table fails 621 */ 622 @Test 623 public void testLongLivedScan() throws Exception { 624 int numTrials = 6; 625 int trialPause = 1000; 626 int cleanUpInterval = 100; 627 628 // Shutdown the Rest Servlet container 629 REST_TEST_UTIL.shutdownServletContainer(); 630 631 // Set the ConnectionCache timeout to trigger halfway through the trials 632 TEST_UTIL.getConfiguration().setLong(RESTServlet.MAX_IDLETIME, (numTrials / 2) * trialPause); 633 TEST_UTIL.getConfiguration().setLong(RESTServlet.CLEANUP_INTERVAL, cleanUpInterval); 634 635 // Start the Rest Servlet container 636 REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); 637 638 // Truncate the test table for inserting test scenarios rows keys 639 TEST_UTIL.getAdmin().disableTable(TABLE); 640 TEST_UTIL.getAdmin().truncateTable(TABLE, false); 641 642 remoteTable = 643 new RemoteHTable(new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort())), 644 TEST_UTIL.getConfiguration(), TABLE.toBytes()); 645 646 String row = "testrow"; 647 648 try (Table table = TEST_UTIL.getConnection().getTable(TABLE)) { 649 List<Put> puts = new ArrayList<Put>(); 650 Put put = null; 651 for (int i = 1; i <= numTrials; i++) { 652 put = new Put(Bytes.toBytes(row + i)); 653 put.addColumn(COLUMN_1, QUALIFIER_1, TS_2, Bytes.toBytes("testvalue" + i)); 654 puts.add(put); 655 } 656 table.put(puts); 657 } 658 659 Scan scan = new Scan(); 660 scan.setCaching(1); 661 scan.setBatch(1); 662 663 ResultScanner scanner = remoteTable.getScanner(scan); 664 Result result = null; 665 // get scanner and rows 666 for (int i = 1; i <= numTrials; i++) { 667 // Make sure that the Scanner doesn't throw an exception after the ConnectionCache timeout 668 result = scanner.next(); 669 assertEquals(row + i, Bytes.toString(result.getRow())); 670 Thread.sleep(trialPause); 671 } 672 } 673}