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