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