View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.rest;
19  
20  import static org.junit.Assert.assertEquals;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.IOException;
24  import java.io.StringWriter;
25  import java.util.*;
26  
27  import javax.ws.rs.core.MediaType;
28  import javax.xml.bind.JAXBContext;
29  import javax.xml.bind.JAXBException;
30  import javax.xml.bind.Marshaller;
31  import javax.xml.bind.Unmarshaller;
32  
33  import org.apache.commons.collections.keyvalue.AbstractMapEntry;
34  import org.apache.hadoop.conf.Configuration;
35  import org.apache.hadoop.hbase.HBaseTestingUtility;
36  import org.apache.hadoop.hbase.HColumnDescriptor;
37  import org.apache.hadoop.hbase.HTableDescriptor;
38  import org.apache.hadoop.hbase.TableName;
39  import org.apache.hadoop.hbase.client.Admin;
40  import org.apache.hadoop.hbase.rest.client.Client;
41  import org.apache.hadoop.hbase.rest.client.Cluster;
42  import org.apache.hadoop.hbase.rest.client.Response;
43  import org.apache.hadoop.hbase.rest.model.CellModel;
44  import org.apache.hadoop.hbase.rest.model.CellSetModel;
45  import org.apache.hadoop.hbase.rest.model.RowModel;
46  import org.apache.hadoop.hbase.rest.provider.JacksonProvider;
47  import org.apache.hadoop.hbase.util.Bytes;
48  import org.codehaus.jackson.map.ObjectMapper;
49  import org.junit.After;
50  import org.junit.AfterClass;
51  import org.junit.Before;
52  import org.junit.BeforeClass;
53  
54  public class RowResourceBase {
55  
56    protected static final String TABLE = "TestRowResource";
57    protected static final String CFA = "a";
58    protected static final String CFB = "b";
59    protected static final String COLUMN_1 = CFA + ":1";
60    protected static final String COLUMN_2 = CFB + ":2";
61    protected static final String COLUMN_3 = CFA + ":";
62    protected static final String ROW_1 = "testrow1";
63    protected static final String VALUE_1 = "testvalue1";
64    protected static final String ROW_2 = "testrow2";
65    protected static final String VALUE_2 = "testvalue2";
66    protected static final String ROW_3 = "testrow3";
67    protected static final String VALUE_3 = "testvalue3";
68    protected static final String ROW_4 = "testrow4";
69    protected static final String VALUE_4 = "testvalue4";
70  
71    protected static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
72    protected static final HBaseRESTTestingUtility REST_TEST_UTIL =
73      new HBaseRESTTestingUtility();
74    protected static Client client;
75    protected static JAXBContext context;
76    protected static Marshaller xmlMarshaller;
77    protected static Unmarshaller xmlUnmarshaller;
78    protected static Configuration conf;
79    protected static ObjectMapper jsonMapper;
80  
81    @BeforeClass
82    public static void setUpBeforeClass() throws Exception {
83      conf = TEST_UTIL.getConfiguration();
84      TEST_UTIL.startMiniCluster(3);
85      REST_TEST_UTIL.startServletContainer(conf);
86      context = JAXBContext.newInstance(
87          CellModel.class,
88          CellSetModel.class,
89          RowModel.class);
90      xmlMarshaller = context.createMarshaller();
91      xmlUnmarshaller = context.createUnmarshaller();
92      jsonMapper = new JacksonProvider()
93      .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
94      client = new Client(new Cluster().add("localhost",
95        REST_TEST_UTIL.getServletPort()));
96    }
97  
98    @AfterClass
99    public static void tearDownAfterClass() throws Exception {
100     REST_TEST_UTIL.shutdownServletContainer();
101     TEST_UTIL.shutdownMiniCluster();
102   }
103 
104   @Before
105   public void beforeMethod() throws Exception {
106     Admin admin = TEST_UTIL.getHBaseAdmin();
107     if (admin.tableExists(TableName.valueOf(TABLE))) {
108       TEST_UTIL.deleteTable(Bytes.toBytes(TABLE));
109     }
110     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLE));
111     htd.addFamily(new HColumnDescriptor(CFA));
112     htd.addFamily(new HColumnDescriptor(CFB));
113     admin.createTable(htd);
114   }
115 
116   @After
117   public void afterMethod() throws Exception {
118     Admin admin = TEST_UTIL.getHBaseAdmin();
119     if (admin.tableExists(TableName.valueOf(TABLE))) {
120       TEST_UTIL.deleteTable(Bytes.toBytes(TABLE));
121     }
122   }
123 
124   static Response putValuePB(String table, String row, String column,
125       String value) throws IOException {
126     StringBuilder path = new StringBuilder();
127     path.append('/');
128     path.append(table);
129     path.append('/');
130     path.append(row);
131     path.append('/');
132     path.append(column);
133     return putValuePB(path.toString(), table, row, column, value);
134   }
135 
136   static Response putValuePB(String url, String table, String row,
137       String column, String value) throws IOException {
138     RowModel rowModel = new RowModel(row);
139     rowModel.addCell(new CellModel(Bytes.toBytes(column),
140       Bytes.toBytes(value)));
141     CellSetModel cellSetModel = new CellSetModel();
142     cellSetModel.addRow(rowModel);
143     Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
144       cellSetModel.createProtobufOutput());
145     Thread.yield();
146     return response;
147   }
148 
149   protected static void checkValueXML(String url, String table, String row,
150       String column, String value) throws IOException, JAXBException {
151     Response response = getValueXML(url);
152     assertEquals(response.getCode(), 200);
153     assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
154     CellSetModel cellSet = (CellSetModel)
155       xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
156     RowModel rowModel = cellSet.getRows().get(0);
157     CellModel cell = rowModel.getCells().get(0);
158     assertEquals(Bytes.toString(cell.getColumn()), column);
159     assertEquals(Bytes.toString(cell.getValue()), value);
160   }
161 
162   protected static void checkValueXML(String table, String row, String column,
163       String value) throws IOException, JAXBException {
164     Response response = getValueXML(table, row, column);
165     assertEquals(response.getCode(), 200);
166     assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
167     CellSetModel cellSet = (CellSetModel)
168       xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
169     RowModel rowModel = cellSet.getRows().get(0);
170     CellModel cell = rowModel.getCells().get(0);
171     assertEquals(Bytes.toString(cell.getColumn()), column);
172     assertEquals(Bytes.toString(cell.getValue()), value);
173   }
174 
175   protected static Response getValuePB(String url) throws IOException {
176     Response response = client.get(url, Constants.MIMETYPE_PROTOBUF); 
177     return response;
178   }
179 
180   protected static Response putValueXML(String table, String row, String column,
181       String value) throws IOException, JAXBException {
182     StringBuilder path = new StringBuilder();
183     path.append('/');
184     path.append(table);
185     path.append('/');
186     path.append(row);
187     path.append('/');
188     path.append(column);
189     return putValueXML(path.toString(), table, row, column, value);
190   }
191 
192   protected static Response putValueXML(String url, String table, String row,
193       String column, String value) throws IOException, JAXBException {
194     RowModel rowModel = new RowModel(row);
195     rowModel.addCell(new CellModel(Bytes.toBytes(column),
196       Bytes.toBytes(value)));
197     CellSetModel cellSetModel = new CellSetModel();
198     cellSetModel.addRow(rowModel);
199     StringWriter writer = new StringWriter();
200     xmlMarshaller.marshal(cellSetModel, writer);
201     Response response = client.put(url, Constants.MIMETYPE_XML,
202       Bytes.toBytes(writer.toString()));
203     Thread.yield();
204     return response;
205   }
206 
207   protected static Response getValuePB(String table, String row, String column)
208       throws IOException {
209     StringBuilder path = new StringBuilder();
210     path.append('/');
211     path.append(table);
212     path.append('/');
213     path.append(row);
214     path.append('/');
215     path.append(column);
216     return getValuePB(path.toString());
217   }
218 
219   protected static void checkValuePB(String table, String row, String column,
220       String value) throws IOException {
221     Response response = getValuePB(table, row, column);
222     assertEquals(response.getCode(), 200);
223     assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
224     CellSetModel cellSet = new CellSetModel();
225     cellSet.getObjectFromMessage(response.getBody());
226     RowModel rowModel = cellSet.getRows().get(0);
227     CellModel cell = rowModel.getCells().get(0);
228     assertEquals(Bytes.toString(cell.getColumn()), column);
229     assertEquals(Bytes.toString(cell.getValue()), value);
230   }
231 
232   protected static Response checkAndPutValuePB(String url, String table,
233       String row, String column, String valueToCheck, String valueToPut, HashMap<String,String> otherCells)
234         throws IOException {
235     RowModel rowModel = new RowModel(row);
236     rowModel.addCell(new CellModel(Bytes.toBytes(column),
237       Bytes.toBytes(valueToPut)));
238 
239     if(otherCells != null) {
240       for (Map.Entry<String,String> entry :otherCells.entrySet()) {
241         rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
242       }
243     }
244 
245     // This Cell need to be added as last cell.
246     rowModel.addCell(new CellModel(Bytes.toBytes(column),
247       Bytes.toBytes(valueToCheck)));
248 
249     CellSetModel cellSetModel = new CellSetModel();
250     cellSetModel.addRow(rowModel);
251     Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
252       cellSetModel.createProtobufOutput());
253     Thread.yield();
254     return response;
255   }
256 
257   protected static Response checkAndPutValuePB(String table, String row,
258       String column, String valueToCheck, String valueToPut) throws IOException {
259     return checkAndPutValuePB(table,row,column,valueToCheck,valueToPut,null);
260   }
261     protected static Response checkAndPutValuePB(String table, String row,
262       String column, String valueToCheck, String valueToPut, HashMap<String,String> otherCells) throws IOException {
263     StringBuilder path = new StringBuilder();
264     path.append('/');
265     path.append(table);
266     path.append('/');
267     path.append(row);
268     path.append("?check=put");
269     return checkAndPutValuePB(path.toString(), table, row, column,
270       valueToCheck, valueToPut, otherCells);
271   }
272 
273   protected static Response checkAndPutValueXML(String url, String table,
274       String row, String column, String valueToCheck, String valueToPut, HashMap<String,String> otherCells)
275         throws IOException, JAXBException {
276     RowModel rowModel = new RowModel(row);
277     rowModel.addCell(new CellModel(Bytes.toBytes(column),
278       Bytes.toBytes(valueToPut)));
279 
280     if(otherCells != null) {
281       for (Map.Entry<String,String> entry :otherCells.entrySet()) {
282         rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
283       }
284     }
285 
286     // This Cell need to be added as last cell.
287     rowModel.addCell(new CellModel(Bytes.toBytes(column),
288       Bytes.toBytes(valueToCheck)));
289     CellSetModel cellSetModel = new CellSetModel();
290     cellSetModel.addRow(rowModel);
291     StringWriter writer = new StringWriter();
292     xmlMarshaller.marshal(cellSetModel, writer);
293     Response response = client.put(url, Constants.MIMETYPE_XML,
294       Bytes.toBytes(writer.toString()));
295     Thread.yield();
296     return response;
297   }
298 
299   protected static Response checkAndPutValueXML(String table, String row,
300                                                 String column, String valueToCheck, String valueToPut)
301           throws IOException, JAXBException {
302     return checkAndPutValueXML(table,row,column,valueToCheck,valueToPut, null);
303   }
304 
305   protected static Response checkAndPutValueXML(String table, String row,
306       String column, String valueToCheck, String valueToPut, HashMap<String,String> otherCells)
307         throws IOException, JAXBException {
308     StringBuilder path = new StringBuilder();
309     path.append('/');
310     path.append(table);
311     path.append('/');
312     path.append(row);
313     path.append("?check=put");
314     return checkAndPutValueXML(path.toString(), table, row, column,
315       valueToCheck, valueToPut, otherCells);
316   }
317 
318   protected static Response checkAndDeleteXML(String url, String table,
319       String row, String column, String valueToCheck, HashMap<String,String> cellsToDelete)
320         throws IOException, JAXBException {
321     RowModel rowModel = new RowModel(row);
322 
323     if(cellsToDelete != null) {
324       for (Map.Entry<String,String> entry :cellsToDelete.entrySet()) {
325         rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
326       }
327     }
328     // Add this at the end
329     rowModel.addCell(new CellModel(Bytes.toBytes(column),
330       Bytes.toBytes(valueToCheck)));
331     CellSetModel cellSetModel = new CellSetModel();
332     cellSetModel.addRow(rowModel);
333     StringWriter writer = new StringWriter();
334     xmlMarshaller.marshal(cellSetModel, writer);
335     Response response = client.put(url, Constants.MIMETYPE_XML,
336       Bytes.toBytes(writer.toString()));
337     Thread.yield();
338     return response;
339   }
340 
341   protected static Response checkAndDeleteXML(String table, String row,
342       String column, String valueToCheck) throws IOException, JAXBException {
343     return checkAndDeleteXML(table, row, column, valueToCheck, null);
344   }
345   protected static Response checkAndDeleteXML(String table, String row,
346       String column, String valueToCheck, HashMap<String,String> cellsToDelete) throws IOException, JAXBException {
347     StringBuilder path = new StringBuilder();
348     path.append('/');
349     path.append(table);
350     path.append('/');
351     path.append(row);
352     path.append("?check=delete");
353     return checkAndDeleteXML(path.toString(), table, row, column, valueToCheck, cellsToDelete);
354   }
355 
356   protected static Response checkAndDeleteJson(String table, String row,
357       String column, String valueToCheck) throws IOException, JAXBException {
358     return checkAndDeleteJson(table, row, column, valueToCheck, null);
359   }
360 
361   protected static Response checkAndDeleteJson(String table, String row,
362       String column, String valueToCheck, HashMap<String,String> cellsToDelete) throws IOException, JAXBException {
363     StringBuilder path = new StringBuilder();
364     path.append('/');
365     path.append(table);
366     path.append('/');
367     path.append(row);
368     path.append("?check=delete");
369     return checkAndDeleteJson(path.toString(), table, row, column, valueToCheck, cellsToDelete);
370   }
371 
372   protected static Response checkAndDeleteJson(String url, String table,
373       String row, String column, String valueToCheck, HashMap<String,String> cellsToDelete)
374         throws IOException, JAXBException {
375     RowModel rowModel = new RowModel(row);
376 
377     if(cellsToDelete != null) {
378       for (Map.Entry<String,String> entry :cellsToDelete.entrySet()) {
379         rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
380       }
381     }
382     // Add this at the end
383     rowModel.addCell(new CellModel(Bytes.toBytes(column),
384       Bytes.toBytes(valueToCheck)));
385     CellSetModel cellSetModel = new CellSetModel();
386     cellSetModel.addRow(rowModel);
387     String jsonString = jsonMapper.writeValueAsString(cellSetModel);
388     Response response = client.put(url, Constants.MIMETYPE_JSON,
389       Bytes.toBytes(jsonString));
390     Thread.yield();
391     return response;
392   }
393 
394   protected static Response checkAndDeletePB(String table, String row,
395       String column, String value) throws IOException {
396 
397     return checkAndDeletePB(table, row, column, value, null);
398   }
399 
400   protected static Response checkAndDeletePB(String table, String row,
401       String column, String value, HashMap<String,String> cellsToDelete) throws IOException {
402     StringBuilder path = new StringBuilder();
403     path.append('/');
404     path.append(table);
405     path.append('/');
406     path.append(row);
407     path.append("?check=delete");
408     return checkAndDeleteValuePB(path.toString(), table, row, column, value, cellsToDelete);
409   }
410   protected static Response checkAndDeleteValuePB(String url, String table,
411       String row, String column, String valueToCheck, HashMap<String,String> cellsToDelete)
412       throws IOException {
413     RowModel rowModel = new RowModel(row);
414 
415     if(cellsToDelete != null) {
416       for (Map.Entry<String,String> entry :cellsToDelete.entrySet()) {
417         rowModel.addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
418       }
419     }
420     // Add this at the end
421     rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes
422         .toBytes(valueToCheck)));
423     CellSetModel cellSetModel = new CellSetModel();
424     cellSetModel.addRow(rowModel);
425     Response response = client.put(url, Constants.MIMETYPE_PROTOBUF,
426         cellSetModel.createProtobufOutput());
427     Thread.yield();
428     return response;
429   }
430 
431   protected static Response getValueXML(String table, String startRow,
432       String endRow, String column) throws IOException {
433     StringBuilder path = new StringBuilder();
434     path.append('/');
435     path.append(table);
436     path.append('/');
437     path.append(startRow);
438     path.append(",");
439     path.append(endRow);
440     path.append('/');
441     path.append(column);
442     return getValueXML(path.toString());
443   }
444 
445   protected static Response getValueXML(String url) throws IOException {
446     Response response = client.get(url, Constants.MIMETYPE_XML);
447     return response;
448   }
449 
450   protected static Response getValueJson(String url) throws IOException {
451     Response response = client.get(url, Constants.MIMETYPE_JSON);
452     return response;
453   }
454 
455   protected static Response deleteValue(String table, String row, String column)
456       throws IOException {
457     StringBuilder path = new StringBuilder();
458     path.append('/');
459     path.append(table);
460     path.append('/');
461     path.append(row);
462     path.append('/');
463     path.append(column);
464     Response response = client.delete(path.toString());
465     Thread.yield();
466     return response;
467   }
468 
469   protected static Response getValueXML(String table, String row, String column)
470       throws IOException {
471     StringBuilder path = new StringBuilder();
472     path.append('/');
473     path.append(table);
474     path.append('/');
475     path.append(row);
476     path.append('/');
477     path.append(column);
478     return getValueXML(path.toString());
479   }
480 
481   protected static Response deleteRow(String table, String row)
482       throws IOException {
483     StringBuilder path = new StringBuilder();
484     path.append('/');
485     path.append(table);
486     path.append('/');
487     path.append(row);
488     Response response = client.delete(path.toString());
489     Thread.yield();
490     return response;
491   }
492 
493   protected static Response getValueJson(String table, String row,
494       String column) throws IOException {
495     StringBuilder path = new StringBuilder();
496     path.append('/');
497     path.append(table);
498     path.append('/');
499     path.append(row);
500     path.append('/');
501     path.append(column);
502     return getValueJson(path.toString());
503   }
504 
505   protected static void checkValueJSON(String table, String row, String column,
506       String value) throws IOException, JAXBException {
507     Response response = getValueJson(table, row, column);
508     assertEquals(response.getCode(), 200);
509     assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
510     ObjectMapper mapper = new JacksonProvider()
511     .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
512     CellSetModel cellSet = mapper.readValue(response.getBody(), CellSetModel.class);
513     RowModel rowModel = cellSet.getRows().get(0);
514     CellModel cell = rowModel.getCells().get(0);
515     assertEquals(Bytes.toString(cell.getColumn()), column);
516     assertEquals(Bytes.toString(cell.getValue()), value);
517   }
518 
519   protected static Response putValueJson(String table, String row, String column,
520       String value) throws IOException, JAXBException {
521     StringBuilder path = new StringBuilder();
522     path.append('/');
523     path.append(table);
524     path.append('/');
525     path.append(row);
526     path.append('/');
527     path.append(column);
528     return putValueJson(path.toString(), table, row, column, value);
529   }
530 
531   protected static Response putValueJson(String url, String table, String row, String column,
532       String value) throws IOException, JAXBException {
533     RowModel rowModel = new RowModel(row);
534     rowModel.addCell(new CellModel(Bytes.toBytes(column),
535       Bytes.toBytes(value)));
536     CellSetModel cellSetModel = new CellSetModel();
537     cellSetModel.addRow(rowModel);
538     String jsonString = jsonMapper.writeValueAsString(cellSetModel);
539     Response response = client.put(url, Constants.MIMETYPE_JSON,
540       Bytes.toBytes(jsonString));
541     Thread.yield();
542     return response;
543   }
544 
545 }