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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org
.apache
.hadoop
.hbase
.rest
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertTrue
;
23 import java
.io
.ByteArrayInputStream
;
24 import java
.io
.IOException
;
25 import java
.io
.StringWriter
;
26 import java
.net
.URLEncoder
;
27 import java
.util
.HashMap
;
28 import java
.util
.List
;
29 import javax
.xml
.bind
.JAXBException
;
30 import org
.apache
.hadoop
.hbase
.CompatibilityFactory
;
31 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
32 import org
.apache
.hadoop
.hbase
.HConstants
;
33 import org
.apache
.hadoop
.hbase
.rest
.client
.Response
;
34 import org
.apache
.hadoop
.hbase
.rest
.model
.CellModel
;
35 import org
.apache
.hadoop
.hbase
.rest
.model
.CellSetModel
;
36 import org
.apache
.hadoop
.hbase
.rest
.model
.RowModel
;
37 import org
.apache
.hadoop
.hbase
.security
.UserProvider
;
38 import org
.apache
.hadoop
.hbase
.test
.MetricsAssertHelper
;
39 import org
.apache
.hadoop
.hbase
.testclassification
.MediumTests
;
40 import org
.apache
.hadoop
.hbase
.testclassification
.RestTests
;
41 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
42 import org
.apache
.http
.Header
;
43 import org
.junit
.ClassRule
;
44 import org
.junit
.Test
;
45 import org
.junit
.experimental
.categories
.Category
;
47 @Category({RestTests
.class, MediumTests
.class})
48 public class TestGetAndPutResource
extends RowResourceBase
{
50 public static final HBaseClassTestRule CLASS_RULE
=
51 HBaseClassTestRule
.forClass(TestGetAndPutResource
.class);
53 private static final MetricsAssertHelper METRICS_ASSERT
=
54 CompatibilityFactory
.getInstance(MetricsAssertHelper
.class);
57 public void testForbidden() throws IOException
, JAXBException
{
58 conf
.set("hbase.rest.readonly", "true");
60 Response response
= putValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
61 assertEquals(403, response
.getCode());
62 response
= putValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
63 assertEquals(403, response
.getCode());
64 response
= checkAndPutValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, VALUE_2
);
65 assertEquals(403, response
.getCode());
66 response
= checkAndPutValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, VALUE_2
);
67 assertEquals(403, response
.getCode());
68 response
= deleteValue(TABLE
, ROW_1
, COLUMN_1
);
69 assertEquals(403, response
.getCode());
70 response
= checkAndDeletePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
71 assertEquals(403, response
.getCode());
72 response
= deleteRow(TABLE
, ROW_1
);
73 assertEquals(403, response
.getCode());
75 conf
.set("hbase.rest.readonly", "false");
77 response
= putValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
78 assertEquals(200, response
.getCode());
79 response
= putValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
80 assertEquals(200, response
.getCode());
81 response
= checkAndPutValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, VALUE_2
);
82 assertEquals(200, response
.getCode());
83 response
= checkAndPutValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
, VALUE_3
);
84 assertEquals(200, response
.getCode());
85 response
= deleteValue(TABLE
, ROW_1
, COLUMN_1
);
86 assertEquals(200, response
.getCode());
87 response
= deleteRow(TABLE
, ROW_1
);
88 assertEquals(200, response
.getCode());
92 public void testSingleCellGetPutXML() throws IOException
, JAXBException
{
93 Response response
= getValueXML(TABLE
, ROW_1
, COLUMN_1
);
94 assertEquals(404, response
.getCode());
96 response
= putValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
97 assertEquals(200, response
.getCode());
98 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
99 response
= putValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
);
100 assertEquals(200, response
.getCode());
101 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
);
102 response
= checkAndPutValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
, VALUE_3
);
103 assertEquals(200, response
.getCode());
104 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
);
105 response
= checkAndDeleteXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
);
106 assertEquals(200, response
.getCode());
108 response
= deleteRow(TABLE
, ROW_1
);
109 assertEquals(200, response
.getCode());
113 public void testSingleCellGetPutPB() throws IOException
, JAXBException
{
114 Response response
= getValuePB(TABLE
, ROW_1
, COLUMN_1
);
115 assertEquals(404, response
.getCode());
117 response
= putValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
118 assertEquals(200, response
.getCode());
119 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
120 response
= putValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
);
121 assertEquals(200, response
.getCode());
122 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
);
124 response
= checkAndPutValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
, VALUE_3
);
125 assertEquals(200, response
.getCode());
126 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
);
127 response
= checkAndPutValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
, VALUE_4
);
128 assertEquals(200, response
.getCode());
129 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_4
);
131 response
= deleteRow(TABLE
, ROW_1
);
132 assertEquals(200, response
.getCode());
136 public void testMultipleCellCheckPutPB() throws IOException
{
137 Response response
= getValuePB(TABLE
, ROW_1
, COLUMN_1
);
138 assertEquals(404, response
.getCode());
140 // Add 2 Columns to setup the test
141 response
= putValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
142 assertEquals(200, response
.getCode());
143 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
145 response
= putValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
146 assertEquals(200, response
.getCode());
147 checkValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
149 HashMap
<String
,String
> otherCells
= new HashMap
<>();
150 otherCells
.put(COLUMN_2
,VALUE_3
);
152 // On Success update both the cells
153 response
= checkAndPutValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, VALUE_3
, otherCells
);
154 assertEquals(200, response
.getCode());
155 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
);
156 checkValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_3
);
158 // On Failure, we dont update any cells
159 response
= checkAndPutValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, VALUE_4
, otherCells
);
160 assertEquals(304, response
.getCode());
161 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
);
162 checkValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_3
);
164 response
= deleteRow(TABLE
, ROW_1
);
165 assertEquals(200, response
.getCode());
169 public void testMultipleCellCheckPutXML() throws IOException
, JAXBException
{
170 Response response
= getValuePB(TABLE
, ROW_1
, COLUMN_1
);
171 assertEquals(404, response
.getCode());
173 // Add 2 Columns to setup the test
174 response
= putValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
175 assertEquals(200, response
.getCode());
176 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
178 response
= putValueXML(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
179 assertEquals(200, response
.getCode());
180 checkValueXML(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
182 HashMap
<String
,String
> otherCells
= new HashMap
<>();
183 otherCells
.put(COLUMN_2
,VALUE_3
);
185 // On Success update both the cells
186 response
= checkAndPutValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, VALUE_3
, otherCells
);
187 assertEquals(200, response
.getCode());
188 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
);
189 checkValueXML(TABLE
, ROW_1
, COLUMN_2
, VALUE_3
);
191 // On Failure, we dont update any cells
192 response
= checkAndPutValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, VALUE_4
, otherCells
);
193 assertEquals(304, response
.getCode());
194 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
);
195 checkValueXML(TABLE
, ROW_1
, COLUMN_2
, VALUE_3
);
197 response
= deleteRow(TABLE
, ROW_1
);
198 assertEquals(200, response
.getCode());
202 public void testMultipleCellCheckDeletePB() throws IOException
{
203 Response response
= getValuePB(TABLE
, ROW_1
, COLUMN_1
);
204 assertEquals(404, response
.getCode());
206 // Add 3 Columns to setup the test
207 response
= putValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
208 assertEquals(200, response
.getCode());
209 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
211 response
= putValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
212 assertEquals(200, response
.getCode());
213 checkValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
215 response
= putValuePB(TABLE
, ROW_1
, COLUMN_3
, VALUE_3
);
216 assertEquals(200, response
.getCode());
217 checkValuePB(TABLE
, ROW_1
, COLUMN_3
, VALUE_3
);
219 // Deletes the following columns based on Column1 check
220 HashMap
<String
,String
> cellsToDelete
= new HashMap
<>();
221 cellsToDelete
.put(COLUMN_2
,VALUE_2
); // Value does not matter
222 cellsToDelete
.put(COLUMN_3
,VALUE_3
); // Value does not matter
224 // On Success update both the cells
225 response
= checkAndDeletePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
, cellsToDelete
);
226 assertEquals(200, response
.getCode());
228 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
230 response
= getValuePB(TABLE
, ROW_1
, COLUMN_2
);
231 assertEquals(404, response
.getCode());
233 response
= getValuePB(TABLE
, ROW_1
, COLUMN_3
);
234 assertEquals(404, response
.getCode());
236 response
= putValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
237 assertEquals(200, response
.getCode());
238 checkValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
240 response
= putValuePB(TABLE
, ROW_1
, COLUMN_3
, VALUE_3
);
241 assertEquals(200, response
.getCode());
242 checkValuePB(TABLE
, ROW_1
, COLUMN_3
, VALUE_3
);
244 // On Failure, we dont update any cells
245 response
= checkAndDeletePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_3
, cellsToDelete
);
246 assertEquals(304, response
.getCode());
247 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
248 checkValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
249 checkValuePB(TABLE
, ROW_1
, COLUMN_3
, VALUE_3
);
251 response
= deleteRow(TABLE
, ROW_1
);
252 assertEquals(200, response
.getCode());
256 public void testSingleCellGetPutBinary() throws IOException
{
257 final String path
= "/" + TABLE
+ "/" + ROW_3
+ "/" + COLUMN_1
;
258 final byte[] body
= Bytes
.toBytes(VALUE_3
);
259 Response response
= client
.put(path
, Constants
.MIMETYPE_BINARY
, body
);
260 assertEquals(200, response
.getCode());
263 response
= client
.get(path
, Constants
.MIMETYPE_BINARY
);
264 assertEquals(200, response
.getCode());
265 assertEquals(Constants
.MIMETYPE_BINARY
, response
.getHeader("content-type"));
266 assertTrue(Bytes
.equals(response
.getBody(), body
));
267 boolean foundTimestampHeader
= false;
268 for (Header header
: response
.getHeaders()) {
269 if (header
.getName().equals("X-Timestamp")) {
270 foundTimestampHeader
= true;
274 assertTrue(foundTimestampHeader
);
276 response
= deleteRow(TABLE
, ROW_3
);
277 assertEquals(200, response
.getCode());
281 public void testSingleCellGetJSON() throws IOException
{
282 final String path
= "/" + TABLE
+ "/" + ROW_4
+ "/" + COLUMN_1
;
283 Response response
= client
.put(path
, Constants
.MIMETYPE_BINARY
,
284 Bytes
.toBytes(VALUE_4
));
285 assertEquals(200, response
.getCode());
287 response
= client
.get(path
, Constants
.MIMETYPE_JSON
);
288 assertEquals(200, response
.getCode());
289 assertEquals(Constants
.MIMETYPE_JSON
, response
.getHeader("content-type"));
290 response
= deleteRow(TABLE
, ROW_4
);
291 assertEquals(200, response
.getCode());
295 public void testLatestCellGetJSON() throws IOException
{
296 final String path
= "/" + TABLE
+ "/" + ROW_4
+ "/" + COLUMN_1
;
297 CellSetModel cellSetModel
= new CellSetModel();
298 RowModel rowModel
= new RowModel(ROW_4
);
299 CellModel cellOne
= new CellModel(Bytes
.toBytes(COLUMN_1
), 1L,
300 Bytes
.toBytes(VALUE_1
));
301 CellModel cellTwo
= new CellModel(Bytes
.toBytes(COLUMN_1
), 2L,
302 Bytes
.toBytes(VALUE_2
));
303 rowModel
.addCell(cellOne
);
304 rowModel
.addCell(cellTwo
);
305 cellSetModel
.addRow(rowModel
);
306 String jsonString
= jsonMapper
.writeValueAsString(cellSetModel
);
307 Response response
= client
.put(path
, Constants
.MIMETYPE_JSON
,
308 Bytes
.toBytes(jsonString
));
309 assertEquals(200, response
.getCode());
311 response
= client
.get(path
, Constants
.MIMETYPE_JSON
);
312 assertEquals(200, response
.getCode());
313 assertEquals(Constants
.MIMETYPE_JSON
, response
.getHeader("content-type"));
314 CellSetModel cellSet
= jsonMapper
.readValue(response
.getBody(), CellSetModel
.class);
315 assertTrue(cellSet
.getRows().size() == 1);
316 assertTrue(cellSet
.getRows().get(0).getCells().size() == 1);
317 CellModel cell
= cellSet
.getRows().get(0).getCells().get(0);
318 assertEquals(VALUE_2
, Bytes
.toString(cell
.getValue()));
319 assertEquals(2L , cell
.getTimestamp());
320 response
= deleteRow(TABLE
, ROW_4
);
321 assertEquals(200, response
.getCode());
325 public void testURLEncodedKey() throws IOException
, JAXBException
{
326 String urlKey
= "http://example.com/foo";
327 StringBuilder path
= new StringBuilder();
331 path
.append(URLEncoder
.encode(urlKey
, HConstants
.UTF8_ENCODING
));
333 path
.append(COLUMN_1
);
335 response
= putValueXML(path
.toString(), TABLE
, urlKey
, COLUMN_1
,
337 assertEquals(200, response
.getCode());
338 checkValueXML(path
.toString(), TABLE
, urlKey
, COLUMN_1
, VALUE_1
);
342 public void testNoSuchCF() throws IOException
{
343 final String goodPath
= "/" + TABLE
+ "/" + ROW_1
+ "/" + CFA
+":";
344 final String badPath
= "/" + TABLE
+ "/" + ROW_1
+ "/" + "BAD";
345 Response response
= client
.post(goodPath
, Constants
.MIMETYPE_BINARY
,
346 Bytes
.toBytes(VALUE_1
));
347 assertEquals(200, response
.getCode());
348 assertEquals(200, client
.get(goodPath
, Constants
.MIMETYPE_BINARY
).getCode());
349 assertEquals(404, client
.get(badPath
, Constants
.MIMETYPE_BINARY
).getCode());
350 assertEquals(200, client
.get(goodPath
, Constants
.MIMETYPE_BINARY
).getCode());
354 public void testMultiCellGetPutXML() throws IOException
, JAXBException
{
355 String path
= "/" + TABLE
+ "/fakerow"; // deliberate nonexistent row
357 CellSetModel cellSetModel
= new CellSetModel();
358 RowModel rowModel
= new RowModel(ROW_1
);
359 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
360 Bytes
.toBytes(VALUE_1
)));
361 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
362 Bytes
.toBytes(VALUE_2
)));
363 cellSetModel
.addRow(rowModel
);
364 rowModel
= new RowModel(ROW_2
);
365 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
366 Bytes
.toBytes(VALUE_3
)));
367 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
368 Bytes
.toBytes(VALUE_4
)));
369 cellSetModel
.addRow(rowModel
);
370 StringWriter writer
= new StringWriter();
371 xmlMarshaller
.marshal(cellSetModel
, writer
);
372 Response response
= client
.put(path
, Constants
.MIMETYPE_XML
,
373 Bytes
.toBytes(writer
.toString()));
376 // make sure the fake row was not actually created
377 response
= client
.get(path
, Constants
.MIMETYPE_XML
);
378 assertEquals(404, response
.getCode());
380 // check that all of the values were created
381 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
382 checkValueXML(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
383 checkValueXML(TABLE
, ROW_2
, COLUMN_1
, VALUE_3
);
384 checkValueXML(TABLE
, ROW_2
, COLUMN_2
, VALUE_4
);
386 response
= deleteRow(TABLE
, ROW_1
);
387 assertEquals(200, response
.getCode());
388 response
= deleteRow(TABLE
, ROW_2
);
389 assertEquals(200, response
.getCode());
393 public void testMultiCellGetPutPB() throws IOException
{
394 String path
= "/" + TABLE
+ "/fakerow"; // deliberate nonexistent row
396 CellSetModel cellSetModel
= new CellSetModel();
397 RowModel rowModel
= new RowModel(ROW_1
);
398 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
399 Bytes
.toBytes(VALUE_1
)));
400 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
401 Bytes
.toBytes(VALUE_2
)));
402 cellSetModel
.addRow(rowModel
);
403 rowModel
= new RowModel(ROW_2
);
404 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
405 Bytes
.toBytes(VALUE_3
)));
406 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
407 Bytes
.toBytes(VALUE_4
)));
408 cellSetModel
.addRow(rowModel
);
409 Response response
= client
.put(path
, Constants
.MIMETYPE_PROTOBUF
,
410 cellSetModel
.createProtobufOutput());
413 // make sure the fake row was not actually created
414 response
= client
.get(path
, Constants
.MIMETYPE_PROTOBUF
);
415 assertEquals(404, response
.getCode());
417 // check that all of the values were created
418 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
419 checkValuePB(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
420 checkValuePB(TABLE
, ROW_2
, COLUMN_1
, VALUE_3
);
421 checkValuePB(TABLE
, ROW_2
, COLUMN_2
, VALUE_4
);
423 response
= deleteRow(TABLE
, ROW_1
);
424 assertEquals(200, response
.getCode());
425 response
= deleteRow(TABLE
, ROW_2
);
426 assertEquals(200, response
.getCode());
430 public void testStartEndRowGetPutXML() throws IOException
, JAXBException
{
431 String
[] rows
= { ROW_1
, ROW_2
, ROW_3
};
432 String
[] values
= { VALUE_1
, VALUE_2
, VALUE_3
};
433 Response response
= null;
434 for (int i
= 0; i
< rows
.length
; i
++) {
435 response
= putValueXML(TABLE
, rows
[i
], COLUMN_1
, values
[i
]);
436 assertEquals(200, response
.getCode());
437 checkValueXML(TABLE
, rows
[i
], COLUMN_1
, values
[i
]);
439 response
= getValueXML(TABLE
, rows
[0], rows
[2], COLUMN_1
);
440 assertEquals(200, response
.getCode());
441 CellSetModel cellSet
= (CellSetModel
)
442 xmlUnmarshaller
.unmarshal(new ByteArrayInputStream(response
.getBody()));
443 assertEquals(2, cellSet
.getRows().size());
444 for (int i
= 0; i
< cellSet
.getRows().size()-1; i
++) {
445 RowModel rowModel
= cellSet
.getRows().get(i
);
446 for (CellModel cell
: rowModel
.getCells()) {
447 assertEquals(COLUMN_1
, Bytes
.toString(cell
.getColumn()));
448 assertEquals(values
[i
], Bytes
.toString(cell
.getValue()));
451 for (String row
: rows
) {
452 response
= deleteRow(TABLE
, row
);
453 assertEquals(200, response
.getCode());
458 public void testInvalidCheckParam() throws IOException
, JAXBException
{
459 CellSetModel cellSetModel
= new CellSetModel();
460 RowModel rowModel
= new RowModel(ROW_1
);
461 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
462 Bytes
.toBytes(VALUE_1
)));
463 cellSetModel
.addRow(rowModel
);
464 StringWriter writer
= new StringWriter();
465 xmlMarshaller
.marshal(cellSetModel
, writer
);
467 final String path
= "/" + TABLE
+ "/" + ROW_1
+ "/" + COLUMN_1
+ "?check=blah";
469 Response response
= client
.put(path
, Constants
.MIMETYPE_XML
,
470 Bytes
.toBytes(writer
.toString()));
471 assertEquals(400, response
.getCode());
475 public void testInvalidColumnPut() throws IOException
, JAXBException
{
476 String dummyColumn
= "doesnot:exist";
477 CellSetModel cellSetModel
= new CellSetModel();
478 RowModel rowModel
= new RowModel(ROW_1
);
479 rowModel
.addCell(new CellModel(Bytes
.toBytes(dummyColumn
),
480 Bytes
.toBytes(VALUE_1
)));
481 cellSetModel
.addRow(rowModel
);
482 StringWriter writer
= new StringWriter();
483 xmlMarshaller
.marshal(cellSetModel
, writer
);
485 final String path
= "/" + TABLE
+ "/" + ROW_1
+ "/" + dummyColumn
;
487 Response response
= client
.put(path
, Constants
.MIMETYPE_XML
,
488 Bytes
.toBytes(writer
.toString()));
489 assertEquals(404, response
.getCode());
493 public void testMultiCellGetJson() throws IOException
, JAXBException
{
494 String path
= "/" + TABLE
+ "/fakerow"; // deliberate nonexistent row
496 CellSetModel cellSetModel
= new CellSetModel();
497 RowModel rowModel
= new RowModel(ROW_1
);
498 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
499 Bytes
.toBytes(VALUE_1
)));
500 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
501 Bytes
.toBytes(VALUE_2
)));
502 cellSetModel
.addRow(rowModel
);
503 rowModel
= new RowModel(ROW_2
);
504 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
505 Bytes
.toBytes(VALUE_3
)));
506 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
507 Bytes
.toBytes(VALUE_4
)));
508 cellSetModel
.addRow(rowModel
);
509 String jsonString
= jsonMapper
.writeValueAsString(cellSetModel
);
511 Response response
= client
.put(path
, Constants
.MIMETYPE_JSON
,
512 Bytes
.toBytes(jsonString
));
515 // make sure the fake row was not actually created
516 response
= client
.get(path
, Constants
.MIMETYPE_JSON
);
517 assertEquals(404, response
.getCode());
519 // check that all of the values were created
520 checkValueJSON(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
521 checkValueJSON(TABLE
, ROW_1
, COLUMN_2
, VALUE_2
);
522 checkValueJSON(TABLE
, ROW_2
, COLUMN_1
, VALUE_3
);
523 checkValueJSON(TABLE
, ROW_2
, COLUMN_2
, VALUE_4
);
525 response
= deleteRow(TABLE
, ROW_1
);
526 assertEquals(200, response
.getCode());
527 response
= deleteRow(TABLE
, ROW_2
);
528 assertEquals(200, response
.getCode());
532 public void testMetrics() throws IOException
{
533 final String path
= "/" + TABLE
+ "/" + ROW_4
+ "/" + COLUMN_1
;
534 Response response
= client
.put(path
, Constants
.MIMETYPE_BINARY
,
535 Bytes
.toBytes(VALUE_4
));
536 assertEquals(200, response
.getCode());
538 response
= client
.get(path
, Constants
.MIMETYPE_JSON
);
539 assertEquals(200, response
.getCode());
540 assertEquals(Constants
.MIMETYPE_JSON
, response
.getHeader("content-type"));
541 response
= deleteRow(TABLE
, ROW_4
);
542 assertEquals(200, response
.getCode());
544 UserProvider userProvider
= UserProvider
.instantiate(conf
);
545 METRICS_ASSERT
.assertCounterGt("requests", 2L,
546 RESTServlet
.getInstance(conf
, userProvider
).getMetrics().getSource());
548 METRICS_ASSERT
.assertCounterGt("successfulGet", 0L,
549 RESTServlet
.getInstance(conf
, userProvider
).getMetrics().getSource());
551 METRICS_ASSERT
.assertCounterGt("successfulPut", 0L,
552 RESTServlet
.getInstance(conf
, userProvider
).getMetrics().getSource());
554 METRICS_ASSERT
.assertCounterGt("successfulDelete", 0L,
555 RESTServlet
.getInstance(conf
, userProvider
).getMetrics().getSource());
559 public void testMultiColumnGetXML() throws Exception
{
560 String path
= "/" + TABLE
+ "/fakerow";
561 CellSetModel cellSetModel
= new CellSetModel();
562 RowModel rowModel
= new RowModel(ROW_1
);
563 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
), Bytes
.toBytes(VALUE_1
)));
564 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
), Bytes
.toBytes(VALUE_2
)));
565 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_3
), Bytes
.toBytes(VALUE_2
)));
566 cellSetModel
.addRow(rowModel
);
567 StringWriter writer
= new StringWriter();
568 xmlMarshaller
.marshal(cellSetModel
, writer
);
570 Response response
= client
.put(path
, Constants
.MIMETYPE_XML
, Bytes
.toBytes(writer
.toString()));
573 // make sure the fake row was not actually created
574 response
= client
.get(path
, Constants
.MIMETYPE_XML
);
575 assertEquals(404, response
.getCode());
577 // Try getting all the column values at once.
578 path
= "/" + TABLE
+ "/" + ROW_1
+ "/" + COLUMN_1
+ "," + COLUMN_2
+ "," + COLUMN_3
;
579 response
= client
.get(path
, Constants
.MIMETYPE_XML
);
580 assertEquals(200, response
.getCode());
581 CellSetModel cellSet
=
582 (CellSetModel
) xmlUnmarshaller
.unmarshal(new ByteArrayInputStream(response
.getBody()));
583 assertTrue(cellSet
.getRows().size() == 1);
584 assertTrue(cellSet
.getRows().get(0).getCells().size() == 3);
585 List
<CellModel
> cells
= cellSet
.getRows().get(0).getCells();
587 assertTrue(containsCellModel(cells
, COLUMN_1
, VALUE_1
));
588 assertTrue(containsCellModel(cells
, COLUMN_2
, VALUE_2
));
589 assertTrue(containsCellModel(cells
, COLUMN_3
, VALUE_2
));
590 response
= deleteRow(TABLE
, ROW_1
);
591 assertEquals(200, response
.getCode());
594 private boolean containsCellModel(List
<CellModel
> cells
, String column
, String value
) {
595 boolean contains
= false;
596 for (CellModel cell
: cells
) {
597 if (Bytes
.toString(cell
.getColumn()).equals(column
)
598 && Bytes
.toString(cell
.getValue()).equals(value
)) {
607 public void testSuffixGlobbingXMLWithNewScanner() throws IOException
, JAXBException
{
608 String path
= "/" + TABLE
+ "/fakerow"; // deliberate nonexistent row
610 CellSetModel cellSetModel
= new CellSetModel();
611 RowModel rowModel
= new RowModel(ROW_1
);
612 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
613 Bytes
.toBytes(VALUE_1
)));
614 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
615 Bytes
.toBytes(VALUE_2
)));
616 cellSetModel
.addRow(rowModel
);
617 rowModel
= new RowModel(ROW_2
);
618 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
619 Bytes
.toBytes(VALUE_3
)));
620 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
621 Bytes
.toBytes(VALUE_4
)));
622 cellSetModel
.addRow(rowModel
);
623 StringWriter writer
= new StringWriter();
624 xmlMarshaller
.marshal(cellSetModel
, writer
);
625 Response response
= client
.put(path
, Constants
.MIMETYPE_XML
,
626 Bytes
.toBytes(writer
.toString()));
629 // make sure the fake row was not actually created
630 response
= client
.get(path
, Constants
.MIMETYPE_XML
);
631 assertEquals(404, response
.getCode());
633 // check that all of the values were created
634 StringBuilder query
= new StringBuilder();
638 query
.append("testrow*");
639 response
= client
.get(query
.toString(), Constants
.MIMETYPE_XML
);
640 assertEquals(200, response
.getCode());
641 assertEquals(Constants
.MIMETYPE_XML
, response
.getHeader("content-type"));
642 CellSetModel cellSet
= (CellSetModel
)
643 xmlUnmarshaller
.unmarshal(new ByteArrayInputStream(response
.getBody()));
644 assertTrue(cellSet
.getRows().size() == 2);
646 response
= deleteRow(TABLE
, ROW_1
);
647 assertEquals(200, response
.getCode());
648 response
= deleteRow(TABLE
, ROW_2
);
649 assertEquals(200, response
.getCode());
653 public void testSuffixGlobbingXML() throws IOException
, JAXBException
{
654 String path
= "/" + TABLE
+ "/fakerow"; // deliberate nonexistent row
656 CellSetModel cellSetModel
= new CellSetModel();
657 RowModel rowModel
= new RowModel(ROW_1
);
658 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
659 Bytes
.toBytes(VALUE_1
)));
660 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
661 Bytes
.toBytes(VALUE_2
)));
662 cellSetModel
.addRow(rowModel
);
663 rowModel
= new RowModel(ROW_2
);
664 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_1
),
665 Bytes
.toBytes(VALUE_3
)));
666 rowModel
.addCell(new CellModel(Bytes
.toBytes(COLUMN_2
),
667 Bytes
.toBytes(VALUE_4
)));
668 cellSetModel
.addRow(rowModel
);
669 StringWriter writer
= new StringWriter();
670 xmlMarshaller
.marshal(cellSetModel
, writer
);
671 Response response
= client
.put(path
, Constants
.MIMETYPE_XML
,
672 Bytes
.toBytes(writer
.toString()));
675 // make sure the fake row was not actually created
676 response
= client
.get(path
, Constants
.MIMETYPE_XML
);
677 assertEquals(404, response
.getCode());
679 // check that all of the values were created
680 StringBuilder query
= new StringBuilder();
684 query
.append("testrow*");
686 query
.append(COLUMN_1
);
687 response
= client
.get(query
.toString(), Constants
.MIMETYPE_XML
);
688 assertEquals(200, response
.getCode());
689 assertEquals(Constants
.MIMETYPE_XML
, response
.getHeader("content-type"));
690 CellSetModel cellSet
= (CellSetModel
)
691 xmlUnmarshaller
.unmarshal(new ByteArrayInputStream(response
.getBody()));
692 List
<RowModel
> rows
= cellSet
.getRows();
693 assertTrue(rows
.size() == 2);
694 for (RowModel row
: rows
) {
695 assertTrue(row
.getCells().size() == 1);
696 assertEquals(COLUMN_1
, Bytes
.toString(row
.getCells().get(0).getColumn()));
698 response
= deleteRow(TABLE
, ROW_1
);
699 assertEquals(200, response
.getCode());
700 response
= deleteRow(TABLE
, ROW_2
);
701 assertEquals(200, response
.getCode());
705 public void testAppendXML() throws IOException
, JAXBException
{
706 Response response
= getValueXML(TABLE
, ROW_1
, COLUMN_1
);
707 assertEquals(404, response
.getCode());
710 response
= appendValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
711 assertEquals(200, response
.getCode());
712 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
713 response
= appendValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
);
714 assertEquals(200, response
.getCode());
715 checkValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
+ VALUE_2
);
717 response
= deleteRow(TABLE
, ROW_1
);
718 assertEquals(200, response
.getCode());
722 public void testAppendPB() throws IOException
, JAXBException
{
723 Response response
= getValuePB(TABLE
, ROW_1
, COLUMN_1
);
724 assertEquals(404, response
.getCode());
727 response
= appendValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
728 assertEquals(200, response
.getCode());
729 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
730 response
= appendValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
);
731 assertEquals(200, response
.getCode());
732 checkValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
+ VALUE_2
);
734 response
= deleteRow(TABLE
, ROW_1
);
735 assertEquals(200, response
.getCode());
739 public void testAppendJSON() throws IOException
, JAXBException
{
740 Response response
= getValueJson(TABLE
, ROW_1
, COLUMN_1
);
741 assertEquals(404, response
.getCode());
744 response
= appendValueJson(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
745 assertEquals(200, response
.getCode());
746 putValueJson(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
);
747 response
= appendValueJson(TABLE
, ROW_1
, COLUMN_1
, VALUE_2
);
748 assertEquals(200, response
.getCode());
749 putValueJson(TABLE
, ROW_1
, COLUMN_1
, VALUE_1
+ VALUE_2
);
751 response
= deleteRow(TABLE
, ROW_1
);
752 assertEquals(200, response
.getCode());
756 public void testIncrementXML() throws IOException
, JAXBException
{
757 Response response
= getValueXML(TABLE
, ROW_1
, COLUMN_1
);
758 assertEquals(404, response
.getCode());
761 response
= incrementValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_5
);
762 assertEquals(200, response
.getCode());
763 checkIncrementValueXML(TABLE
, ROW_1
, COLUMN_1
, Long
.parseLong(VALUE_5
));
764 response
= incrementValueXML(TABLE
, ROW_1
, COLUMN_1
, VALUE_6
);
765 assertEquals(200, response
.getCode());
766 checkIncrementValueXML(TABLE
, ROW_1
, COLUMN_1
,
767 Long
.parseLong(VALUE_5
) + Long
.parseLong(VALUE_6
));
769 response
= deleteRow(TABLE
, ROW_1
);
770 assertEquals(200, response
.getCode());
774 public void testIncrementPB() throws IOException
, JAXBException
{
775 Response response
= getValuePB(TABLE
, ROW_1
, COLUMN_1
);
776 assertEquals(404, response
.getCode());
779 response
= incrementValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_5
);
780 assertEquals(200, response
.getCode());
781 checkIncrementValuePB(TABLE
, ROW_1
, COLUMN_1
, Long
.parseLong(VALUE_5
));
782 response
= incrementValuePB(TABLE
, ROW_1
, COLUMN_1
, VALUE_6
);
783 assertEquals(200, response
.getCode());
784 checkIncrementValuePB(TABLE
, ROW_1
, COLUMN_1
,
785 Long
.parseLong(VALUE_5
) + Long
.parseLong(VALUE_6
));
787 response
= deleteRow(TABLE
, ROW_1
);
788 assertEquals(200, response
.getCode());
792 public void testIncrementJSON() throws IOException
, JAXBException
{
793 Response response
= getValueJson(TABLE
, ROW_1
, COLUMN_1
);
794 assertEquals(404, response
.getCode());
797 response
= incrementValueJson(TABLE
, ROW_1
, COLUMN_1
, VALUE_5
);
798 assertEquals(200, response
.getCode());
799 checkIncrementValueJSON(TABLE
, ROW_1
, COLUMN_1
, Long
.parseLong(VALUE_5
));
800 response
= incrementValueJson(TABLE
, ROW_1
, COLUMN_1
, VALUE_6
);
801 assertEquals(200, response
.getCode());
802 checkIncrementValueJSON(TABLE
, ROW_1
, COLUMN_1
,
803 Long
.parseLong(VALUE_5
) + Long
.parseLong(VALUE_6
));
805 response
= deleteRow(TABLE
, ROW_1
);
806 assertEquals(200, response
.getCode());