View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.rest.client;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertFalse;
24  import static org.junit.Assert.assertNotNull;
25  import static org.junit.Assert.assertNull;
26  import static org.junit.Assert.assertTrue;
27  
28  import java.io.IOException;
29  import java.util.ArrayList;
30  import java.util.Collections;
31  import java.util.Iterator;
32  import java.util.List;
33  
34  import org.apache.commons.httpclient.Header;
35  import org.apache.hadoop.hbase.Cell;
36  import org.apache.hadoop.hbase.CellUtil;
37  import org.apache.hadoop.hbase.HBaseTestingUtility;
38  import org.apache.hadoop.hbase.HColumnDescriptor;
39  import org.apache.hadoop.hbase.HTableDescriptor;
40  import org.apache.hadoop.hbase.client.HTable;
41  import org.apache.hadoop.hbase.testclassification.MediumTests;
42  import org.apache.hadoop.hbase.TableName;
43  import org.apache.hadoop.hbase.client.Admin;
44  import org.apache.hadoop.hbase.client.Delete;
45  import org.apache.hadoop.hbase.client.Get;
46  import org.apache.hadoop.hbase.client.Put;
47  import org.apache.hadoop.hbase.client.Result;
48  import org.apache.hadoop.hbase.client.ResultScanner;
49  import org.apache.hadoop.hbase.client.Scan;
50  import org.apache.hadoop.hbase.client.Table;
51  import org.apache.hadoop.hbase.rest.HBaseRESTTestingUtility;
52  import org.apache.hadoop.hbase.util.Bytes;
53  import org.junit.After;
54  import org.junit.AfterClass;
55  import org.junit.Before;
56  import org.junit.BeforeClass;
57  import org.junit.Test;
58  import org.junit.experimental.categories.Category;
59  
60  @Category(MediumTests.class)
61  public class TestRemoteTable {
62  
63    // Verify that invalid URL characters and arbitrary bytes are escaped when
64    // constructing REST URLs per HBASE-7621. RemoteHTable should support row keys
65    // and qualifiers containing any byte for all table operations.
66    private static final String INVALID_URL_CHARS_1 =
67        "|\"\\^{}\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000B\u000C";
68  
69    // HColumnDescriptor prevents certain characters in column names.  The following
70    // are examples of characters are allowed in column names but are not valid in
71    // URLs.
72    private static final String INVALID_URL_CHARS_2 = "|^{}\u0242";
73  
74    // Besides alphanumeric these characters can also be present in table names.
75    private static final String VALID_TABLE_NAME_CHARS = "_-.";
76  
77    private static final TableName TABLE =
78        TableName.valueOf("TestRemoteTable" + VALID_TABLE_NAME_CHARS);
79  
80    private static final byte[] ROW_1 = Bytes.toBytes("testrow1" + INVALID_URL_CHARS_1);
81    private static final byte[] ROW_2 = Bytes.toBytes("testrow2" + INVALID_URL_CHARS_1);
82    private static final byte[] ROW_3 = Bytes.toBytes("testrow3" + INVALID_URL_CHARS_1);
83    private static final byte[] ROW_4 = Bytes.toBytes("testrow4"+ INVALID_URL_CHARS_1);
84  
85    private static final byte[] COLUMN_1 = Bytes.toBytes("a" + INVALID_URL_CHARS_2);
86    private static final byte[] COLUMN_2 = Bytes.toBytes("b" + INVALID_URL_CHARS_2);
87    private static final byte[] COLUMN_3 = Bytes.toBytes("c" + INVALID_URL_CHARS_2);
88  
89    private static final byte[] QUALIFIER_1 = Bytes.toBytes("1" + INVALID_URL_CHARS_1);
90    private static final byte[] QUALIFIER_2 = Bytes.toBytes("2" + INVALID_URL_CHARS_1);
91    private static final byte[] VALUE_1 = Bytes.toBytes("testvalue1");
92    private static final byte[] VALUE_2 = Bytes.toBytes("testvalue2");
93  
94    private static final long ONE_HOUR = 60 * 60 * 1000;
95    private static final long TS_2 = System.currentTimeMillis();
96    private static final long TS_1 = TS_2 - ONE_HOUR;
97  
98    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
99    private static final HBaseRESTTestingUtility REST_TEST_UTIL = 
100     new HBaseRESTTestingUtility();
101   private RemoteHTable remoteTable;
102 
103   @BeforeClass
104   public static void setUpBeforeClass() throws Exception {
105     TEST_UTIL.startMiniCluster();
106     REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration());
107   }
108 
109   @Before
110   public void before() throws Exception  {
111     Admin admin = TEST_UTIL.getHBaseAdmin();
112     if (admin.tableExists(TABLE)) {
113       if (admin.isTableEnabled(TABLE)) admin.disableTable(TABLE);
114       admin.deleteTable(TABLE);
115     }
116     HTableDescriptor htd = new HTableDescriptor(TABLE);
117     htd.addFamily(new HColumnDescriptor(COLUMN_1).setMaxVersions(3));
118     htd.addFamily(new HColumnDescriptor(COLUMN_2).setMaxVersions(3));
119     htd.addFamily(new HColumnDescriptor(COLUMN_3).setMaxVersions(3));
120     admin.createTable(htd);
121     try (Table table = TEST_UTIL.getConnection().getTable(TABLE)) {
122       Put put = new Put(ROW_1);
123       put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_1);
124       table.put(put);
125       put = new Put(ROW_2);
126       put.add(COLUMN_1, QUALIFIER_1, TS_1, VALUE_1);
127       put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_2);
128       put.add(COLUMN_2, QUALIFIER_2, TS_2, VALUE_2);
129       table.put(put);
130     }
131     remoteTable = new RemoteHTable(
132       new Client(new Cluster().add("localhost", 
133           REST_TEST_UTIL.getServletPort())),
134         TEST_UTIL.getConfiguration(), TABLE.toBytes());
135   }
136   
137   @After
138   public void after() throws Exception {
139     remoteTable.close();
140   }
141   
142   @AfterClass
143   public static void tearDownAfterClass() throws Exception {
144     REST_TEST_UTIL.shutdownServletContainer();
145     TEST_UTIL.shutdownMiniCluster();
146   }
147 
148   @Test
149   public void testGetTableDescriptor() throws IOException {
150     Table table = null;
151     try {
152       table = new HTable(TEST_UTIL.getConfiguration(), TABLE);
153       HTableDescriptor local = table.getTableDescriptor();
154       assertEquals(remoteTable.getTableDescriptor(), local);
155     } finally {
156       if (null != table) table.close();
157     }
158   }
159 
160   @Test
161   public void testGet() throws IOException {
162     Get get = new Get(ROW_1);
163     Result result = remoteTable.get(get);
164     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
165     byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2);
166     assertNotNull(value1);
167     assertTrue(Bytes.equals(VALUE_1, value1));
168     assertNull(value2);
169 
170     get = new Get(ROW_1);
171     get.addFamily(COLUMN_3);
172     result = remoteTable.get(get);
173     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
174     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
175     assertNull(value1);
176     assertNull(value2);
177 
178     get = new Get(ROW_1);
179     get.addColumn(COLUMN_1, QUALIFIER_1);
180     get.addColumn(COLUMN_2, QUALIFIER_2);
181     result = remoteTable.get(get);
182     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
183     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
184     assertNotNull(value1);
185     assertTrue(Bytes.equals(VALUE_1, value1));
186     assertNull(value2);
187 
188     get = new Get(ROW_2);
189     result = remoteTable.get(get);
190     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
191     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
192     assertNotNull(value1);
193     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
194     assertNotNull(value2);
195     assertTrue(Bytes.equals(VALUE_2, value2));
196 
197     get = new Get(ROW_2);
198     get.addFamily(COLUMN_1);
199     result = remoteTable.get(get);
200     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
201     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
202     assertNotNull(value1);
203     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
204     assertNull(value2);
205 
206     get = new Get(ROW_2);
207     get.addColumn(COLUMN_1, QUALIFIER_1);
208     get.addColumn(COLUMN_2, QUALIFIER_2);
209     result = remoteTable.get(get);
210     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
211     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
212     assertNotNull(value1);
213     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
214     assertNotNull(value2);
215     assertTrue(Bytes.equals(VALUE_2, value2));
216 
217     // test timestamp
218 
219     get = new Get(ROW_2);
220     get.addFamily(COLUMN_1);
221     get.addFamily(COLUMN_2);
222     get.setTimeStamp(TS_1);
223     result = remoteTable.get(get);
224     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
225     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
226     assertNotNull(value1);
227     assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
228     assertNull(value2);
229 
230     // test timerange
231 
232     get = new Get(ROW_2);
233     get.addFamily(COLUMN_1);
234     get.addFamily(COLUMN_2);
235     get.setTimeRange(0, TS_1 + 1);
236     result = remoteTable.get(get);
237     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
238     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
239     assertNotNull(value1);
240     assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
241     assertNull(value2);
242 
243     // test maxVersions
244 
245     get = new Get(ROW_2);
246     get.addFamily(COLUMN_1);
247     get.setMaxVersions(2);
248     result = remoteTable.get(get);
249     int count = 0;
250     for (Cell kv: result.listCells()) {
251       if (CellUtil.matchingFamily(kv, COLUMN_1) && TS_1 == kv.getTimestamp()) {
252         assertTrue(CellUtil.matchingValue(kv, VALUE_1)); // @TS_1
253         count++;
254       }
255       if (CellUtil.matchingFamily(kv, COLUMN_1) && TS_2 == kv.getTimestamp()) {
256         assertTrue(CellUtil.matchingValue(kv, VALUE_2)); // @TS_2
257         count++;
258       }
259     }
260     assertEquals(2, count);
261   }
262 
263   @Test
264   public void testMultiGet() throws Exception {
265     ArrayList<Get> gets = new ArrayList<Get>();
266     gets.add(new Get(ROW_1));
267     gets.add(new Get(ROW_2));
268     Result[] results = remoteTable.get(gets);
269     assertNotNull(results);
270     assertEquals(2, results.length);
271     assertEquals(1, results[0].size());
272     assertEquals(2, results[1].size());
273 
274     //Test Versions
275     gets = new ArrayList<Get>();
276     Get g = new Get(ROW_1);
277     g.setMaxVersions(3);
278     gets.add(g);
279     gets.add(new Get(ROW_2));
280     results = remoteTable.get(gets);
281     assertNotNull(results);
282     assertEquals(2, results.length);
283     assertEquals(1, results[0].size());
284     assertEquals(3, results[1].size());
285 
286     //404
287     gets = new ArrayList<Get>();
288     gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE")));
289     results = remoteTable.get(gets);
290     assertNotNull(results);
291     assertEquals(0, results.length);
292 
293     gets = new ArrayList<Get>();
294     gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE")));
295     gets.add(new Get(ROW_1));
296     gets.add(new Get(ROW_2));
297     results = remoteTable.get(gets);
298     assertNotNull(results);
299     assertEquals(2, results.length);
300   }
301 
302   @Test
303   public void testPut() throws IOException {
304     Put put = new Put(ROW_3);
305     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
306     remoteTable.put(put);
307 
308     Get get = new Get(ROW_3);
309     get.addFamily(COLUMN_1);
310     Result result = remoteTable.get(get);
311     byte[] value = result.getValue(COLUMN_1, QUALIFIER_1);
312     assertNotNull(value);
313     assertTrue(Bytes.equals(VALUE_1, value));
314 
315     // multiput
316 
317     List<Put> puts = new ArrayList<Put>();
318     put = new Put(ROW_3);
319     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
320     puts.add(put);
321     put = new Put(ROW_4);
322     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
323     puts.add(put);
324     put = new Put(ROW_4);
325     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
326     puts.add(put);
327     remoteTable.put(puts);
328 
329     get = new Get(ROW_3);
330     get.addFamily(COLUMN_2);
331     result = remoteTable.get(get);
332     value = result.getValue(COLUMN_2, QUALIFIER_2);
333     assertNotNull(value);
334     assertTrue(Bytes.equals(VALUE_2, value));
335     get = new Get(ROW_4);
336     result = remoteTable.get(get);
337     value = result.getValue(COLUMN_1, QUALIFIER_1);
338     assertNotNull(value);
339     assertTrue(Bytes.equals(VALUE_1, value));
340     value = result.getValue(COLUMN_2, QUALIFIER_2);
341     assertNotNull(value);
342     assertTrue(Bytes.equals(VALUE_2, value));
343     
344     assertTrue(Bytes.equals(Bytes.toBytes("TestRemoteTable" + VALID_TABLE_NAME_CHARS), remoteTable.getTableName()));
345   }
346 
347   @Test
348   public void testDelete() throws IOException {
349     Put put = new Put(ROW_3);
350     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
351     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
352     put.add(COLUMN_3, QUALIFIER_1, VALUE_1);
353     put.add(COLUMN_3, QUALIFIER_2, VALUE_2);
354     remoteTable.put(put);
355 
356     Get get = new Get(ROW_3);
357     get.addFamily(COLUMN_1);
358     get.addFamily(COLUMN_2);
359     get.addFamily(COLUMN_3);
360     Result result = remoteTable.get(get);
361     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
362     byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2);
363     byte[] value3 = result.getValue(COLUMN_3, QUALIFIER_1);
364     byte[] value4 = result.getValue(COLUMN_3, QUALIFIER_2);
365     assertNotNull(value1);
366     assertTrue(Bytes.equals(VALUE_1, value1));
367     assertNotNull(value2);
368     assertTrue(Bytes.equals(VALUE_2, value2));
369     assertNotNull(value3);
370     assertTrue(Bytes.equals(VALUE_1, value3));
371     assertNotNull(value4);
372     assertTrue(Bytes.equals(VALUE_2, value4));
373 
374     Delete delete = new Delete(ROW_3);
375     delete.addColumn(COLUMN_2, QUALIFIER_2);
376     remoteTable.delete(delete);
377 
378     get = new Get(ROW_3);
379     get.addFamily(COLUMN_1);
380     get.addFamily(COLUMN_2);
381     result = remoteTable.get(get);
382     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
383     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
384     assertNotNull(value1);
385     assertTrue(Bytes.equals(VALUE_1, value1));
386     assertNull(value2);
387 
388     delete = new Delete(ROW_3);
389     delete.setTimestamp(1L);
390     remoteTable.delete(delete);
391 
392     get = new Get(ROW_3);
393     get.addFamily(COLUMN_1);
394     get.addFamily(COLUMN_2);
395     result = remoteTable.get(get);
396     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
397     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
398     assertNotNull(value1);
399     assertTrue(Bytes.equals(VALUE_1, value1));
400     assertNull(value2);
401 
402     // Delete column family from row
403     delete = new Delete(ROW_3);
404     delete.addFamily(COLUMN_3);
405     remoteTable.delete(delete);
406 
407     get = new Get(ROW_3);
408     get.addFamily(COLUMN_3);
409     result = remoteTable.get(get);
410     value3 = result.getValue(COLUMN_3, QUALIFIER_1);
411     value4 = result.getValue(COLUMN_3, QUALIFIER_2);
412     assertNull(value3);
413     assertNull(value4);
414 
415     delete = new Delete(ROW_3);
416     remoteTable.delete(delete);
417 
418     get = new Get(ROW_3);
419     get.addFamily(COLUMN_1);
420     get.addFamily(COLUMN_2);
421     result = remoteTable.get(get);
422     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
423     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
424     assertNull(value1);
425     assertNull(value2);
426   }
427   
428   /**
429    * Test RemoteHTable.Scanner 
430    */
431   @Test
432   public void testScanner() throws IOException {
433     List<Put> puts = new ArrayList<Put>();
434     Put put = new Put(ROW_1);
435     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
436     puts.add(put);
437     put = new Put(ROW_2);
438     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
439     puts.add(put);
440     put = new Put(ROW_3);
441     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
442     puts.add(put);
443     put = new Put(ROW_4);
444     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
445     puts.add(put);
446     remoteTable.put(puts);
447 
448     ResultScanner scanner = remoteTable.getScanner(new Scan());
449 
450     Result[] results = scanner.next(1);
451     assertNotNull(results);
452     assertEquals(1, results.length);
453     assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
454 
455     Result result = scanner.next();
456     assertNotNull(result);
457     assertTrue(Bytes.equals(ROW_2, result.getRow()));
458 
459     results = scanner.next(2);
460     assertNotNull(results);
461     assertEquals(2, results.length);
462     assertTrue(Bytes.equals(ROW_3, results[0].getRow()));
463     assertTrue(Bytes.equals(ROW_4, results[1].getRow()));
464 
465     results = scanner.next(1);
466     assertNull(results);
467     scanner.close();
468     
469     scanner = remoteTable.getScanner(COLUMN_1);
470     results = scanner.next(4);
471     assertNotNull(results);
472     assertEquals(4, results.length);
473     assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
474     assertTrue(Bytes.equals(ROW_2, results[1].getRow()));
475     assertTrue(Bytes.equals(ROW_3, results[2].getRow()));
476     assertTrue(Bytes.equals(ROW_4, results[3].getRow()));
477 
478     scanner.close();
479     
480     scanner = remoteTable.getScanner(COLUMN_1,QUALIFIER_1);
481     results = scanner.next(4);
482     assertNotNull(results);
483     assertEquals(4, results.length);
484     assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
485     assertTrue(Bytes.equals(ROW_2, results[1].getRow()));
486     assertTrue(Bytes.equals(ROW_3, results[2].getRow()));
487     assertTrue(Bytes.equals(ROW_4, results[3].getRow()));
488     scanner.close();
489     assertTrue(remoteTable.isAutoFlush());
490 
491   }
492   
493   @Test
494   public void testCheckAndDelete() throws IOException {
495     Get get = new Get(ROW_1);
496     Result result = remoteTable.get(get);
497     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
498     byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2);
499     assertNotNull(value1);
500     assertTrue(Bytes.equals(VALUE_1, value1));
501     assertNull(value2);
502     assertTrue(remoteTable.exists(get));
503     assertEquals(1, remoteTable.existsAll(Collections.singletonList(get)).length);
504     Delete delete = new Delete(ROW_1);
505 
506     remoteTable.checkAndDelete(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_1, delete);
507     assertFalse(remoteTable.exists(get));
508 
509     Put put = new Put(ROW_1);
510     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
511     remoteTable.put(put);
512 
513     assertTrue(remoteTable.checkAndPut(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_1,
514         put));
515     assertFalse(remoteTable.checkAndPut(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_2,
516         put));
517   }
518   
519   /**
520    * Test RemoteHable.Scanner.iterator method  
521    */
522   @Test
523   public void testIteratorScaner() throws IOException {
524     List<Put> puts = new ArrayList<Put>();
525     Put put = new Put(ROW_1);
526     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
527     puts.add(put);
528     put = new Put(ROW_2);
529     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
530     puts.add(put);
531     put = new Put(ROW_3);
532     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
533     puts.add(put);
534     put = new Put(ROW_4);
535     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
536     puts.add(put);
537     remoteTable.put(puts);
538 
539     ResultScanner scanner = remoteTable.getScanner(new Scan());
540     Iterator<Result> iterator = scanner.iterator();
541     assertTrue(iterator.hasNext());
542     int counter = 0;
543     while (iterator.hasNext()) {
544       iterator.next();
545       counter++;
546     }
547     assertEquals(4, counter);
548   }
549   
550   /**
551    * Test a some methods of class Response.
552    */
553   @Test
554   public void testResponse(){
555     Response response = new Response(200);
556     assertEquals(200, response.getCode());
557     Header[] headers = new Header[2];
558     headers[0] = new Header("header1", "value1");
559     headers[1] = new Header("header2", "value2");
560     response = new Response(200, headers);
561     assertEquals("value1", response.getHeader("header1"));
562     assertFalse(response.hasBody());
563     response.setCode(404);
564     assertEquals(404, response.getCode());
565     headers = new Header[2];
566     headers[0] = new Header("header1", "value1.1");
567     headers[1] = new Header("header2", "value2");
568     response.setHeaders(headers);
569     assertEquals("value1.1", response.getHeader("header1"));
570     response.setBody(Bytes.toBytes("body"));
571     assertTrue(response.hasBody());    
572   }
573   
574 }
575