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; 021import static org.junit.Assert.assertTrue; 022 023import java.io.ByteArrayInputStream; 024import java.io.IOException; 025import java.io.StringWriter; 026import java.net.URLEncoder; 027import java.util.HashMap; 028import java.util.List; 029import javax.xml.bind.JAXBException; 030import org.apache.hadoop.hbase.CompatibilityFactory; 031import org.apache.hadoop.hbase.HBaseClassTestRule; 032import org.apache.hadoop.hbase.HConstants; 033import org.apache.hadoop.hbase.rest.client.Response; 034import org.apache.hadoop.hbase.rest.model.CellModel; 035import org.apache.hadoop.hbase.rest.model.CellSetModel; 036import org.apache.hadoop.hbase.rest.model.RowModel; 037import org.apache.hadoop.hbase.security.UserProvider; 038import org.apache.hadoop.hbase.test.MetricsAssertHelper; 039import org.apache.hadoop.hbase.testclassification.MediumTests; 040import org.apache.hadoop.hbase.testclassification.RestTests; 041import org.apache.hadoop.hbase.util.Bytes; 042import org.apache.http.Header; 043import org.junit.ClassRule; 044import org.junit.Test; 045import org.junit.experimental.categories.Category; 046 047@Category({RestTests.class, MediumTests.class}) 048public class TestGetAndPutResource extends RowResourceBase { 049 @ClassRule 050 public static final HBaseClassTestRule CLASS_RULE = 051 HBaseClassTestRule.forClass(TestGetAndPutResource.class); 052 053 private static final MetricsAssertHelper METRICS_ASSERT = 054 CompatibilityFactory.getInstance(MetricsAssertHelper.class); 055 056 @Test 057 public void testForbidden() throws IOException, JAXBException { 058 conf.set("hbase.rest.readonly", "true"); 059 060 Response response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 061 assertEquals(403, response.getCode()); 062 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 063 assertEquals(403, response.getCode()); 064 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2); 065 assertEquals(403, response.getCode()); 066 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2); 067 assertEquals(403, response.getCode()); 068 response = deleteValue(TABLE, ROW_1, COLUMN_1); 069 assertEquals(403, response.getCode()); 070 response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 071 assertEquals(403, response.getCode()); 072 response = deleteRow(TABLE, ROW_1); 073 assertEquals(403, response.getCode()); 074 075 conf.set("hbase.rest.readonly", "false"); 076 077 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 078 assertEquals(200, response.getCode()); 079 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 080 assertEquals(200, response.getCode()); 081 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2); 082 assertEquals(200, response.getCode()); 083 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2, VALUE_3); 084 assertEquals(200, response.getCode()); 085 response = deleteValue(TABLE, ROW_1, COLUMN_1); 086 assertEquals(200, response.getCode()); 087 response = deleteRow(TABLE, ROW_1); 088 assertEquals(200, response.getCode()); 089 } 090 091 @Test 092 public void testSingleCellGetPutXML() throws IOException, JAXBException { 093 Response response = getValueXML(TABLE, ROW_1, COLUMN_1); 094 assertEquals(404, response.getCode()); 095 096 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 097 assertEquals(200, response.getCode()); 098 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 099 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()); 107 108 response = deleteRow(TABLE, ROW_1); 109 assertEquals(200, response.getCode()); 110 } 111 112 @Test 113 public void testSingleCellGetPutPB() throws IOException, JAXBException { 114 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 115 assertEquals(404, response.getCode()); 116 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); 123 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); 130 131 response = deleteRow(TABLE, ROW_1); 132 assertEquals(200, response.getCode()); 133 } 134 135 @Test 136 public void testMultipleCellCheckPutPB() throws IOException { 137 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 138 assertEquals(404, response.getCode()); 139 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); 144 145 response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 146 assertEquals(200, response.getCode()); 147 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 148 149 HashMap<String,String> otherCells = new HashMap<>(); 150 otherCells.put(COLUMN_2,VALUE_3); 151 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); 157 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); 163 164 response = deleteRow(TABLE, ROW_1); 165 assertEquals(200, response.getCode()); 166 } 167 168 @Test 169 public void testMultipleCellCheckPutXML() throws IOException, JAXBException { 170 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 171 assertEquals(404, response.getCode()); 172 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); 177 178 response = putValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2); 179 assertEquals(200, response.getCode()); 180 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2); 181 182 HashMap<String,String> otherCells = new HashMap<>(); 183 otherCells.put(COLUMN_2,VALUE_3); 184 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); 190 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); 196 197 response = deleteRow(TABLE, ROW_1); 198 assertEquals(200, response.getCode()); 199 } 200 201 @Test 202 public void testMultipleCellCheckDeletePB() throws IOException { 203 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 204 assertEquals(404, response.getCode()); 205 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); 210 211 response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 212 assertEquals(200, response.getCode()); 213 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 214 215 response = putValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 216 assertEquals(200, response.getCode()); 217 checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 218 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 223 224 // On Success update both the cells 225 response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1, cellsToDelete); 226 assertEquals(200, response.getCode()); 227 228 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 229 230 response = getValuePB(TABLE, ROW_1, COLUMN_2); 231 assertEquals(404, response.getCode()); 232 233 response = getValuePB(TABLE, ROW_1, COLUMN_3); 234 assertEquals(404, response.getCode()); 235 236 response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 237 assertEquals(200, response.getCode()); 238 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 239 240 response = putValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 241 assertEquals(200, response.getCode()); 242 checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 243 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); 250 251 response = deleteRow(TABLE, ROW_1); 252 assertEquals(200, response.getCode()); 253 } 254 255 @Test 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()); 261 Thread.yield(); 262 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; 271 break; 272 } 273 } 274 assertTrue(foundTimestampHeader); 275 276 response = deleteRow(TABLE, ROW_3); 277 assertEquals(200, response.getCode()); 278 } 279 280 @Test 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()); 286 Thread.yield(); 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()); 292 } 293 294 @Test 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()); 310 Thread.yield(); 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()); 322 } 323 324 @Test 325 public void testURLEncodedKey() throws IOException, JAXBException { 326 String urlKey = "http://example.com/foo"; 327 StringBuilder path = new StringBuilder(); 328 path.append('/'); 329 path.append(TABLE); 330 path.append('/'); 331 path.append(URLEncoder.encode(urlKey, HConstants.UTF8_ENCODING)); 332 path.append('/'); 333 path.append(COLUMN_1); 334 Response response; 335 response = putValueXML(path.toString(), TABLE, urlKey, COLUMN_1, 336 VALUE_1); 337 assertEquals(200, response.getCode()); 338 checkValueXML(path.toString(), TABLE, urlKey, COLUMN_1, VALUE_1); 339 } 340 341 @Test 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()); 351 } 352 353 @Test 354 public void testMultiCellGetPutXML() throws IOException, JAXBException { 355 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 356 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())); 374 Thread.yield(); 375 376 // make sure the fake row was not actually created 377 response = client.get(path, Constants.MIMETYPE_XML); 378 assertEquals(404, response.getCode()); 379 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); 385 386 response = deleteRow(TABLE, ROW_1); 387 assertEquals(200, response.getCode()); 388 response = deleteRow(TABLE, ROW_2); 389 assertEquals(200, response.getCode()); 390 } 391 392 @Test 393 public void testMultiCellGetPutPB() throws IOException { 394 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 395 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()); 411 Thread.yield(); 412 413 // make sure the fake row was not actually created 414 response = client.get(path, Constants.MIMETYPE_PROTOBUF); 415 assertEquals(404, response.getCode()); 416 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); 422 423 response = deleteRow(TABLE, ROW_1); 424 assertEquals(200, response.getCode()); 425 response = deleteRow(TABLE, ROW_2); 426 assertEquals(200, response.getCode()); 427 } 428 429 @Test 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]); 438 } 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())); 449 } 450 } 451 for (String row : rows) { 452 response = deleteRow(TABLE, row); 453 assertEquals(200, response.getCode()); 454 } 455 } 456 457 @Test 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); 466 467 final String path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "?check=blah"; 468 469 Response response = client.put(path, Constants.MIMETYPE_XML, 470 Bytes.toBytes(writer.toString())); 471 assertEquals(400, response.getCode()); 472 } 473 474 @Test 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); 484 485 final String path = "/" + TABLE + "/" + ROW_1 + "/" + dummyColumn; 486 487 Response response = client.put(path, Constants.MIMETYPE_XML, 488 Bytes.toBytes(writer.toString())); 489 assertEquals(404, response.getCode()); 490 } 491 492 @Test 493 public void testMultiCellGetJson() throws IOException, JAXBException { 494 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 495 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); 510 511 Response response = client.put(path, Constants.MIMETYPE_JSON, 512 Bytes.toBytes(jsonString)); 513 Thread.yield(); 514 515 // make sure the fake row was not actually created 516 response = client.get(path, Constants.MIMETYPE_JSON); 517 assertEquals(404, response.getCode()); 518 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); 524 525 response = deleteRow(TABLE, ROW_1); 526 assertEquals(200, response.getCode()); 527 response = deleteRow(TABLE, ROW_2); 528 assertEquals(200, response.getCode()); 529 } 530 531 @Test 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()); 537 Thread.yield(); 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()); 543 544 UserProvider userProvider = UserProvider.instantiate(conf); 545 METRICS_ASSERT.assertCounterGt("requests", 2L, 546 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 547 548 METRICS_ASSERT.assertCounterGt("successfulGet", 0L, 549 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 550 551 METRICS_ASSERT.assertCounterGt("successfulPut", 0L, 552 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 553 554 METRICS_ASSERT.assertCounterGt("successfulDelete", 0L, 555 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 556 } 557 558 @Test 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); 569 570 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString())); 571 Thread.yield(); 572 573 // make sure the fake row was not actually created 574 response = client.get(path, Constants.MIMETYPE_XML); 575 assertEquals(404, response.getCode()); 576 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(); 586 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()); 592 } 593 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)) { 599 contains = true; 600 return contains; 601 } 602 } 603 return contains; 604 } 605 606 @Test 607 public void testSuffixGlobbingXMLWithNewScanner() throws IOException, JAXBException { 608 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 609 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())); 627 Thread.yield(); 628 629 // make sure the fake row was not actually created 630 response = client.get(path, Constants.MIMETYPE_XML); 631 assertEquals(404, response.getCode()); 632 633 // check that all of the values were created 634 StringBuilder query = new StringBuilder(); 635 query.append('/'); 636 query.append(TABLE); 637 query.append('/'); 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); 645 646 response = deleteRow(TABLE, ROW_1); 647 assertEquals(200, response.getCode()); 648 response = deleteRow(TABLE, ROW_2); 649 assertEquals(200, response.getCode()); 650 } 651 652 @Test 653 public void testSuffixGlobbingXML() throws IOException, JAXBException { 654 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 655 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())); 673 Thread.yield(); 674 675 // make sure the fake row was not actually created 676 response = client.get(path, Constants.MIMETYPE_XML); 677 assertEquals(404, response.getCode()); 678 679 // check that all of the values were created 680 StringBuilder query = new StringBuilder(); 681 query.append('/'); 682 query.append(TABLE); 683 query.append('/'); 684 query.append("testrow*"); 685 query.append('/'); 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())); 697 } 698 response = deleteRow(TABLE, ROW_1); 699 assertEquals(200, response.getCode()); 700 response = deleteRow(TABLE, ROW_2); 701 assertEquals(200, response.getCode()); 702 } 703 704 @Test 705 public void testAppendXML() throws IOException, JAXBException { 706 Response response = getValueXML(TABLE, ROW_1, COLUMN_1); 707 assertEquals(404, response.getCode()); 708 709 //append cell 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); 716 717 response = deleteRow(TABLE, ROW_1); 718 assertEquals(200, response.getCode()); 719 } 720 721 @Test 722 public void testAppendPB() throws IOException, JAXBException { 723 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 724 assertEquals(404, response.getCode()); 725 726 //append cell 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); 733 734 response = deleteRow(TABLE, ROW_1); 735 assertEquals(200, response.getCode()); 736 } 737 738 @Test 739 public void testAppendJSON() throws IOException, JAXBException { 740 Response response = getValueJson(TABLE, ROW_1, COLUMN_1); 741 assertEquals(404, response.getCode()); 742 743 //append cell 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); 750 751 response = deleteRow(TABLE, ROW_1); 752 assertEquals(200, response.getCode()); 753 } 754 755 @Test 756 public void testIncrementXML() throws IOException, JAXBException { 757 Response response = getValueXML(TABLE, ROW_1, COLUMN_1); 758 assertEquals(404, response.getCode()); 759 760 //append single cell 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)); 768 769 response = deleteRow(TABLE, ROW_1); 770 assertEquals(200, response.getCode()); 771 } 772 773 @Test 774 public void testIncrementPB() throws IOException, JAXBException { 775 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 776 assertEquals(404, response.getCode()); 777 778 //append cell 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)); 786 787 response = deleteRow(TABLE, ROW_1); 788 assertEquals(200, response.getCode()); 789 } 790 791 @Test 792 public void testIncrementJSON() throws IOException, JAXBException { 793 Response response = getValueJson(TABLE, ROW_1, COLUMN_1); 794 assertEquals(404, response.getCode()); 795 796 //append cell 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)); 804 805 response = deleteRow(TABLE, ROW_1); 806 assertEquals(200, response.getCode()); 807 } 808}