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;
019
020import static org.junit.Assert.assertEquals;
021
022import com.fasterxml.jackson.databind.ObjectMapper;
023import java.io.ByteArrayInputStream;
024import java.io.IOException;
025import java.io.StringWriter;
026import java.util.Base64;
027import java.util.HashMap;
028import java.util.Map;
029import javax.xml.bind.JAXBContext;
030import javax.xml.bind.JAXBException;
031import javax.xml.bind.Marshaller;
032import javax.xml.bind.Unmarshaller;
033import org.apache.hadoop.conf.Configuration;
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.ColumnFamilyDescriptor;
038import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
039import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
040import org.apache.hadoop.hbase.rest.client.Client;
041import org.apache.hadoop.hbase.rest.client.Cluster;
042import org.apache.hadoop.hbase.rest.client.Response;
043import org.apache.hadoop.hbase.rest.model.CellModel;
044import org.apache.hadoop.hbase.rest.model.CellSetModel;
045import org.apache.hadoop.hbase.rest.model.RowModel;
046import org.apache.hadoop.hbase.util.Bytes;
047import org.apache.http.Header;
048import org.apache.http.message.BasicHeader;
049import org.junit.After;
050import org.junit.AfterClass;
051import org.junit.Before;
052import org.junit.BeforeClass;
053
054import org.apache.hbase.thirdparty.com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
055import org.apache.hbase.thirdparty.javax.ws.rs.core.MediaType;
056
057public class RowResourceBase {
058  protected static final String TABLE = "TestRowResource";
059
060  protected static final TableName TABLE_NAME = TableName.valueOf(TABLE);
061
062  protected static final String CFA = "a";
063  protected static final String CFB = "b";
064  protected static final String COLUMN_1 = CFA + ":1";
065  protected static final String COLUMN_2 = CFB + ":2";
066  protected static final String COLUMN_3 = CFA + ":";
067  protected static final String ROW_1 = "testrow1";
068  protected static final String VALUE_1 = "testvalue1";
069  protected static final String ROW_2 = "testrow2";
070  protected static final String VALUE_2 = "testvalue2";
071  protected static final String ROW_3 = "testrow3";
072  protected static final String VALUE_3 = "testvalue3";
073  protected static final String ROW_4 = "testrow4";
074  protected static final String VALUE_4 = "testvalue4";
075  protected static final String VALUE_5 = "5";
076  protected static final String VALUE_6 = "6";
077
078  protected static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
079  protected static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility();
080  protected static Client client;
081  protected static JAXBContext context;
082  protected static Marshaller xmlMarshaller;
083  protected static Unmarshaller xmlUnmarshaller;
084  protected static Configuration conf;
085  protected static ObjectMapper jsonMapper;
086
087  @BeforeClass
088  public static void setUpBeforeClass() throws Exception {
089    conf = TEST_UTIL.getConfiguration();
090    TEST_UTIL.startMiniCluster(3);
091    REST_TEST_UTIL.startServletContainer(conf);
092    context = JAXBContext.newInstance(CellModel.class, CellSetModel.class, RowModel.class);
093    xmlMarshaller = context.createMarshaller();
094    xmlUnmarshaller = context.createUnmarshaller();
095    jsonMapper = new JacksonJaxbJsonProvider().locateMapper(CellSetModel.class,
096      MediaType.APPLICATION_JSON_TYPE);
097    client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort()));
098  }
099
100  @AfterClass
101  public static void tearDownAfterClass() throws Exception {
102    REST_TEST_UTIL.shutdownServletContainer();
103    TEST_UTIL.shutdownMiniCluster();
104  }
105
106  @Before
107  public void beforeMethod() throws Exception {
108    Admin admin = TEST_UTIL.getAdmin();
109    if (admin.tableExists(TABLE_NAME)) {
110      TEST_UTIL.deleteTable(TABLE_NAME);
111    }
112    TableDescriptorBuilder tableDescriptorBuilder =
113      TableDescriptorBuilder.newBuilder(TableName.valueOf(TABLE));
114    ColumnFamilyDescriptor columnFamilyDescriptor =
115      ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(CFA)).build();
116    tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
117    columnFamilyDescriptor = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(CFB)).build();
118    tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
119    admin.createTable(tableDescriptorBuilder.build());
120  }
121
122  @After
123  public void afterMethod() throws Exception {
124    Admin admin = TEST_UTIL.getAdmin();
125    if (admin.tableExists(TABLE_NAME)) {
126      TEST_UTIL.deleteTable(TABLE_NAME);
127    }
128  }
129
130  static Response putValuePB(String table, String row, String column, String value)
131    throws IOException {
132    StringBuilder path = new StringBuilder();
133    path.append('/');
134    path.append(table);
135    path.append('/');
136    path.append(row);
137    path.append('/');
138    path.append(column);
139    return putValuePB(path.toString(), table, row, column, value);
140  }
141
142  static Response putValuePB(String url, String table, String row, String column, String value)
143    throws IOException {
144    RowModel rowModel = new RowModel(row);
145    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(value)));
146    CellSetModel cellSetModel = new CellSetModel();
147    cellSetModel.addRow(rowModel);
148    Response response =
149      client.put(url, Constants.MIMETYPE_PROTOBUF, cellSetModel.createProtobufOutput());
150    Thread.yield();
151    return response;
152  }
153
154  protected static void checkValueXML(String url, String table, String row, String column,
155    String value) throws IOException, JAXBException {
156    Response response = getValueXML(url);
157    assertEquals(200, response.getCode());
158    assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
159    CellSetModel cellSet =
160      (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
161    RowModel rowModel = cellSet.getRows().get(0);
162    CellModel cell = rowModel.getCells().get(0);
163    assertEquals(Bytes.toString(cell.getColumn()), column);
164    assertEquals(Bytes.toString(cell.getValue()), value);
165  }
166
167  protected static void checkValueXML(String table, String row, String column, String value)
168    throws IOException, JAXBException {
169    Response response = getValueXML(table, row, column);
170    assertEquals(200, response.getCode());
171    assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
172    CellSetModel cellSet =
173      (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody()));
174    RowModel rowModel = cellSet.getRows().get(0);
175    CellModel cell = rowModel.getCells().get(0);
176    assertEquals(Bytes.toString(cell.getColumn()), column);
177    assertEquals(Bytes.toString(cell.getValue()), value);
178  }
179
180  protected static void checkIncrementValueXML(String table, String row, String column, long value)
181    throws IOException, JAXBException {
182    Response response1 = getValueXML(table, row, column);
183    assertEquals(200, response1.getCode());
184    assertEquals(Constants.MIMETYPE_XML, response1.getHeader("content-type"));
185    CellSetModel cellSet =
186      (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response1.getBody()));
187    RowModel rowModel = cellSet.getRows().get(0);
188    CellModel cell = rowModel.getCells().get(0);
189    assertEquals(Bytes.toString(cell.getColumn()), column);
190    assertEquals(Bytes.toLong(cell.getValue()), value);
191  }
192
193  protected static Response getValuePB(String url) throws IOException {
194    Response response = client.get(url, Constants.MIMETYPE_PROTOBUF);
195    return response;
196  }
197
198  protected static Response putValueXML(String table, String row, String column, String value)
199    throws IOException, JAXBException {
200    StringBuilder path = new StringBuilder();
201    path.append('/');
202    path.append(table);
203    path.append('/');
204    path.append(row);
205    path.append('/');
206    path.append(column);
207    return putValueXML(path.toString(), table, row, column, value);
208  }
209
210  protected static Response putValueXML(String url, String table, String row, String column,
211    String value) throws IOException, JAXBException {
212    RowModel rowModel = new RowModel(row);
213    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(value)));
214    CellSetModel cellSetModel = new CellSetModel();
215    cellSetModel.addRow(rowModel);
216    StringWriter writer = new StringWriter();
217    xmlMarshaller.marshal(cellSetModel, writer);
218    Response response = client.put(url, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
219    Thread.yield();
220    return response;
221  }
222
223  protected static Response getValuePB(String table, String row, String column) throws IOException {
224    StringBuilder path = new StringBuilder();
225    path.append('/');
226    path.append(table);
227    path.append('/');
228    path.append(row);
229    path.append('/');
230    path.append(column);
231    return getValuePB(path.toString());
232  }
233
234  protected static void checkValuePB(String table, String row, String column, String value)
235    throws IOException {
236    Response response = getValuePB(table, row, column);
237    assertEquals(200, response.getCode());
238    assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
239    CellSetModel cellSet = new CellSetModel();
240    cellSet.getObjectFromMessage(response.getBody());
241    RowModel rowModel = cellSet.getRows().get(0);
242    CellModel cell = rowModel.getCells().get(0);
243    assertEquals(Bytes.toString(cell.getColumn()), column);
244    assertEquals(Bytes.toString(cell.getValue()), value);
245  }
246
247  protected static void checkIncrementValuePB(String table, String row, String column, long value)
248    throws IOException {
249    Response response = getValuePB(table, row, column);
250    assertEquals(200, response.getCode());
251    assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
252    CellSetModel cellSet = new CellSetModel();
253    cellSet.getObjectFromMessage(response.getBody());
254    RowModel rowModel = cellSet.getRows().get(0);
255    CellModel cell = rowModel.getCells().get(0);
256    assertEquals(Bytes.toString(cell.getColumn()), column);
257    assertEquals(Bytes.toLong(cell.getValue()), value);
258  }
259
260  protected static Response checkAndPutValuePB(String url, String table, String row, String column,
261    String valueToCheck, String valueToPut, HashMap<String, String> otherCells) throws IOException {
262    RowModel rowModel = new RowModel(row);
263    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(valueToPut)));
264
265    if (otherCells != null) {
266      for (Map.Entry<String, String> entry : otherCells.entrySet()) {
267        rowModel
268          .addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
269      }
270    }
271
272    // This Cell need to be added as last cell.
273    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(valueToCheck)));
274
275    CellSetModel cellSetModel = new CellSetModel();
276    cellSetModel.addRow(rowModel);
277    Response response =
278      client.put(url, Constants.MIMETYPE_PROTOBUF, cellSetModel.createProtobufOutput());
279    Thread.yield();
280    return response;
281  }
282
283  protected static Response checkAndPutValuePB(String table, String row, String column,
284    String valueToCheck, String valueToPut) throws IOException {
285    return checkAndPutValuePB(table, row, column, valueToCheck, valueToPut, null);
286  }
287
288  protected static Response checkAndPutValuePB(String table, String row, String column,
289    String valueToCheck, String valueToPut, HashMap<String, String> otherCells) throws IOException {
290    StringBuilder path = new StringBuilder();
291    path.append('/');
292    path.append(table);
293    path.append('/');
294    path.append(row);
295    path.append("?check=put");
296    return checkAndPutValuePB(path.toString(), table, row, column, valueToCheck, valueToPut,
297      otherCells);
298  }
299
300  protected static Response checkAndPutValueXML(String url, String table, String row, String column,
301    String valueToCheck, String valueToPut, HashMap<String, String> otherCells)
302    throws IOException, JAXBException {
303    RowModel rowModel = new RowModel(row);
304    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(valueToPut)));
305
306    if (otherCells != null) {
307      for (Map.Entry<String, String> entry : otherCells.entrySet()) {
308        rowModel
309          .addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
310      }
311    }
312
313    // This Cell need to be added as last cell.
314    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(valueToCheck)));
315    CellSetModel cellSetModel = new CellSetModel();
316    cellSetModel.addRow(rowModel);
317    StringWriter writer = new StringWriter();
318    xmlMarshaller.marshal(cellSetModel, writer);
319    Response response = client.put(url, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
320    Thread.yield();
321    return response;
322  }
323
324  protected static Response checkAndPutValueXML(String table, String row, String column,
325    String valueToCheck, String valueToPut) throws IOException, JAXBException {
326    return checkAndPutValueXML(table, row, column, valueToCheck, valueToPut, null);
327  }
328
329  protected static Response checkAndPutValueXML(String table, String row, String column,
330    String valueToCheck, String valueToPut, HashMap<String, String> otherCells)
331    throws IOException, JAXBException {
332    StringBuilder path = new StringBuilder();
333    path.append('/');
334    path.append(table);
335    path.append('/');
336    path.append(row);
337    path.append("?check=put");
338    return checkAndPutValueXML(path.toString(), table, row, column, valueToCheck, valueToPut,
339      otherCells);
340  }
341
342  protected static Response checkAndDeleteXML(String url, String table, String row, String column,
343    String valueToCheck, HashMap<String, String> cellsToDelete) throws IOException, JAXBException {
344    RowModel rowModel = new RowModel(row);
345
346    if (cellsToDelete != null) {
347      for (Map.Entry<String, String> entry : cellsToDelete.entrySet()) {
348        rowModel
349          .addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
350      }
351    }
352    // Add this at the end
353    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(valueToCheck)));
354    CellSetModel cellSetModel = new CellSetModel();
355    cellSetModel.addRow(rowModel);
356    StringWriter writer = new StringWriter();
357    xmlMarshaller.marshal(cellSetModel, writer);
358    Response response = client.put(url, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString()));
359    Thread.yield();
360    return response;
361  }
362
363  protected static Response checkAndDeleteXML(String table, String row, String column,
364    String valueToCheck) throws IOException, JAXBException {
365    return checkAndDeleteXML(table, row, column, valueToCheck, null);
366  }
367
368  protected static Response checkAndDeleteXML(String table, String row, String column,
369    String valueToCheck, HashMap<String, String> cellsToDelete) throws IOException, JAXBException {
370    StringBuilder path = new StringBuilder();
371    path.append('/');
372    path.append(table);
373    path.append('/');
374    path.append(row);
375    path.append("?check=delete");
376    return checkAndDeleteXML(path.toString(), table, row, column, valueToCheck, cellsToDelete);
377  }
378
379  protected static Response checkAndDeleteJson(String table, String row, String column,
380    String valueToCheck) throws IOException {
381    return checkAndDeleteJson(table, row, column, valueToCheck, null);
382  }
383
384  protected static Response checkAndDeleteJson(String table, String row, String column,
385    String valueToCheck, HashMap<String, String> cellsToDelete) throws IOException {
386    StringBuilder path = new StringBuilder();
387    path.append('/');
388    path.append(table);
389    path.append('/');
390    path.append(row);
391    path.append("?check=delete");
392    return checkAndDeleteJson(path.toString(), table, row, column, valueToCheck, cellsToDelete);
393  }
394
395  protected static Response checkAndDeleteJson(String url, String table, String row, String column,
396    String valueToCheck, HashMap<String, String> cellsToDelete) throws IOException {
397    RowModel rowModel = new RowModel(row);
398
399    if (cellsToDelete != null) {
400      for (Map.Entry<String, String> entry : cellsToDelete.entrySet()) {
401        rowModel
402          .addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
403      }
404    }
405    // Add this at the end
406    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(valueToCheck)));
407    CellSetModel cellSetModel = new CellSetModel();
408    cellSetModel.addRow(rowModel);
409    String jsonString = jsonMapper.writeValueAsString(cellSetModel);
410    Response response = client.put(url, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
411    Thread.yield();
412    return response;
413  }
414
415  protected static Response checkAndDeletePB(String table, String row, String column, String value)
416    throws IOException {
417    return checkAndDeletePB(table, row, column, value, null);
418  }
419
420  protected static Response checkAndDeletePB(String table, String row, String column, String value,
421    HashMap<String, String> cellsToDelete) throws IOException {
422    StringBuilder path = new StringBuilder();
423    path.append('/');
424    path.append(table);
425    path.append('/');
426    path.append(row);
427    path.append("?check=delete");
428    return checkAndDeleteValuePB(path.toString(), table, row, column, value, cellsToDelete);
429  }
430
431  protected static Response checkAndDeleteValuePB(String url, String table, String row,
432    String column, String valueToCheck, HashMap<String, String> cellsToDelete) throws IOException {
433    RowModel rowModel = new RowModel(row);
434
435    if (cellsToDelete != null) {
436      for (Map.Entry<String, String> entry : cellsToDelete.entrySet()) {
437        rowModel
438          .addCell(new CellModel(Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue())));
439      }
440    }
441    // Add this at the end
442    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(valueToCheck)));
443    CellSetModel cellSetModel = new CellSetModel();
444    cellSetModel.addRow(rowModel);
445    Response response =
446      client.put(url, Constants.MIMETYPE_PROTOBUF, cellSetModel.createProtobufOutput());
447    Thread.yield();
448    return response;
449  }
450
451  protected static Response getValueXML(String table, String startRow, String endRow, String column)
452    throws IOException {
453    StringBuilder path = new StringBuilder();
454    path.append('/');
455    path.append(table);
456    path.append('/');
457    path.append(startRow);
458    path.append(",");
459    path.append(endRow);
460    path.append('/');
461    path.append(column);
462    return getValueXML(path.toString());
463  }
464
465  protected static Response getValueXML(String url) throws IOException {
466    Response response = client.get(url, Constants.MIMETYPE_XML);
467    return response;
468  }
469
470  protected static Response getValueXML(String url, Header[] headers) throws IOException {
471    Header[] fullHeaders = new Header[headers.length + 1];
472    for (int i = 0; i < headers.length; i++)
473      fullHeaders[i] = headers[i];
474    fullHeaders[headers.length] = new BasicHeader("Accept", Constants.MIMETYPE_XML);
475    Response response = client.get(url, fullHeaders);
476    return response;
477  }
478
479  protected static Response getValueJson(String url) throws IOException {
480    Response response = client.get(url, Constants.MIMETYPE_JSON);
481    return response;
482  }
483
484  protected static Response deleteValue(String table, String row, String column)
485    throws IOException {
486    StringBuilder path = new StringBuilder();
487    path.append('/');
488    path.append(table);
489    path.append('/');
490    path.append(row);
491    path.append('/');
492    path.append(column);
493    Response response = client.delete(path.toString());
494    Thread.yield();
495    return response;
496  }
497
498  protected static Response deleteValueB64(String table, String row, String column,
499    boolean useQueryString) throws IOException {
500    StringBuilder path = new StringBuilder();
501    Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();
502    path.append('/');
503    path.append(table);
504    path.append('/');
505    path.append(encoder.encodeToString(row.getBytes("UTF-8")));
506    path.append('/');
507    path.append(encoder.encodeToString(column.getBytes("UTF-8")));
508
509    Response response;
510    if (useQueryString) {
511      path.append("?e=b64");
512      response = client.delete(path.toString());
513    } else {
514      response = client.delete(path.toString(), new BasicHeader("Encoding", "b64"));
515    }
516    Thread.yield();
517    return response;
518  }
519
520  protected static Response getValueXML(String table, String row, String column)
521    throws IOException {
522    StringBuilder path = new StringBuilder();
523    path.append('/');
524    path.append(table);
525    path.append('/');
526    path.append(row);
527    path.append('/');
528    path.append(column);
529    return getValueXML(path.toString());
530  }
531
532  protected static Response deleteRow(String table, String row) throws IOException {
533    StringBuilder path = new StringBuilder();
534    path.append('/');
535    path.append(table);
536    path.append('/');
537    path.append(row);
538    Response response = client.delete(path.toString());
539    Thread.yield();
540    return response;
541  }
542
543  protected static Response deleteRowB64(String table, String row, boolean useQueryString)
544    throws IOException {
545    StringBuilder path = new StringBuilder();
546    Base64.Encoder encoder = Base64.getUrlEncoder().withoutPadding();
547    path.append('/');
548    path.append(table);
549    path.append('/');
550    path.append(encoder.encodeToString(row.getBytes("UTF-8")));
551
552    Response response;
553    if (useQueryString) {
554      path.append("?e=b64");
555      response = client.delete(path.toString());
556    } else {
557      response = client.delete(path.toString(), new BasicHeader("Encoding", "b64"));
558    }
559    Thread.yield();
560    return response;
561  }
562
563  protected static Response getValueJson(String table, String row, String column)
564    throws IOException {
565    StringBuilder path = new StringBuilder();
566    path.append('/');
567    path.append(table);
568    path.append('/');
569    path.append(row);
570    path.append('/');
571    path.append(column);
572    return getValueJson(path.toString());
573  }
574
575  protected static void checkValueJSON(String table, String row, String column, String value)
576    throws IOException {
577    Response response = getValueJson(table, row, column);
578    assertEquals(200, response.getCode());
579    assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
580    ObjectMapper mapper = new JacksonJaxbJsonProvider().locateMapper(CellSetModel.class,
581      MediaType.APPLICATION_JSON_TYPE);
582    CellSetModel cellSet = mapper.readValue(response.getBody(), CellSetModel.class);
583    RowModel rowModel = cellSet.getRows().get(0);
584    CellModel cell = rowModel.getCells().get(0);
585    assertEquals(Bytes.toString(cell.getColumn()), column);
586    assertEquals(Bytes.toString(cell.getValue()), value);
587  }
588
589  protected static void checkIncrementValueJSON(String table, String row, String column, long value)
590    throws IOException {
591    Response response = getValueJson(table, row, column);
592    assertEquals(200, response.getCode());
593    assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
594    ObjectMapper mapper = new JacksonJaxbJsonProvider().locateMapper(CellSetModel.class,
595      MediaType.APPLICATION_JSON_TYPE);
596    CellSetModel cellSet = mapper.readValue(response.getBody(), CellSetModel.class);
597    RowModel rowModel = cellSet.getRows().get(0);
598    CellModel cell = rowModel.getCells().get(0);
599    assertEquals(Bytes.toString(cell.getColumn()), column);
600    assertEquals(Bytes.toLong(cell.getValue()), value);
601  }
602
603  protected static Response putValueJson(String table, String row, String column, String value)
604    throws IOException {
605    StringBuilder path = new StringBuilder();
606    path.append('/');
607    path.append(table);
608    path.append('/');
609    path.append(row);
610    path.append('/');
611    path.append(column);
612    return putValueJson(path.toString(), table, row, column, value);
613  }
614
615  protected static Response putValueJson(String url, String table, String row, String column,
616    String value) throws IOException {
617    RowModel rowModel = new RowModel(row);
618    rowModel.addCell(new CellModel(Bytes.toBytes(column), Bytes.toBytes(value)));
619    CellSetModel cellSetModel = new CellSetModel();
620    cellSetModel.addRow(rowModel);
621    String jsonString = jsonMapper.writeValueAsString(cellSetModel);
622    Response response = client.put(url, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
623    Thread.yield();
624    return response;
625  }
626
627  protected static Response appendValueXML(String table, String row, String column, String value)
628    throws IOException, JAXBException {
629    StringBuilder path = new StringBuilder();
630    path.append('/');
631    path.append(table);
632    path.append('/');
633    path.append(row);
634    path.append("?check=append");
635    return putValueXML(path.toString(), table, row, column, value);
636  }
637
638  protected static Response appendValuePB(String table, String row, String column, String value)
639    throws IOException {
640    StringBuilder path = new StringBuilder();
641    path.append('/');
642    path.append(table);
643    path.append('/');
644    path.append(row);
645    path.append("?check=append");
646    return putValuePB(path.toString(), table, row, column, value);
647  }
648
649  protected static Response appendValueJson(String table, String row, String column, String value)
650    throws IOException, JAXBException {
651    StringBuilder path = new StringBuilder();
652    path.append('/');
653    path.append(table);
654    path.append('/');
655    path.append(row);
656    path.append("?check=append");
657    return putValueJson(path.toString(), table, row, column, value);
658  }
659
660  protected static Response incrementValueXML(String table, String row, String column, String value)
661    throws IOException, JAXBException {
662    StringBuilder path = new StringBuilder();
663    path.append('/');
664    path.append(table);
665    path.append('/');
666    path.append(row);
667    path.append("?check=increment");
668    return putValueXML(path.toString(), table, row, column, value);
669  }
670
671  protected static Response incrementValuePB(String table, String row, String column, String value)
672    throws IOException {
673    StringBuilder path = new StringBuilder();
674    path.append('/');
675    path.append(table);
676    path.append('/');
677    path.append(row);
678    path.append("?check=increment");
679    return putValuePB(path.toString(), table, row, column, value);
680  }
681
682  protected static Response incrementValueJson(String table, String row, String column,
683    String value) throws IOException, JAXBException {
684    StringBuilder path = new StringBuilder();
685    path.append('/');
686    path.append(table);
687    path.append('/');
688    path.append(row);
689    path.append("?check=increment");
690    return putValueJson(path.toString(), table, row, column, value);
691  }
692}