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 050 @ClassRule 051 public static final HBaseClassTestRule CLASS_RULE = 052 HBaseClassTestRule.forClass(TestGetAndPutResource.class); 053 054 private static final MetricsAssertHelper METRICS_ASSERT = 055 CompatibilityFactory.getInstance(MetricsAssertHelper.class); 056 057 @Test 058 public void testForbidden() throws IOException, JAXBException { 059 conf.set("hbase.rest.readonly", "true"); 060 061 Response response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 062 assertEquals(403, response.getCode()); 063 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 064 assertEquals(403, response.getCode()); 065 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2); 066 assertEquals(403, response.getCode()); 067 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2); 068 assertEquals(403, response.getCode()); 069 response = deleteValue(TABLE, ROW_1, COLUMN_1); 070 assertEquals(403, response.getCode()); 071 response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 072 assertEquals(403, response.getCode()); 073 response = deleteRow(TABLE, ROW_1); 074 assertEquals(403, response.getCode()); 075 076 conf.set("hbase.rest.readonly", "false"); 077 078 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 079 assertEquals(200, response.getCode()); 080 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 081 assertEquals(200, response.getCode()); 082 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_2); 083 assertEquals(200, response.getCode()); 084 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2, VALUE_3); 085 assertEquals(200, response.getCode()); 086 response = deleteValue(TABLE, ROW_1, COLUMN_1); 087 assertEquals(200, response.getCode()); 088 response = deleteRow(TABLE, ROW_1); 089 assertEquals(200, response.getCode()); 090 } 091 092 @Test 093 public void testSingleCellGetPutXML() throws IOException, JAXBException { 094 Response response = getValueXML(TABLE, ROW_1, COLUMN_1); 095 assertEquals(404, response.getCode()); 096 097 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 098 assertEquals(200, response.getCode()); 099 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 100 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2); 101 assertEquals(200, response.getCode()); 102 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2); 103 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2, VALUE_3); 104 assertEquals(200, response.getCode()); 105 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3); 106 response = checkAndDeleteXML(TABLE, ROW_1, COLUMN_1, VALUE_3); 107 assertEquals(200, response.getCode()); 108 109 response = deleteRow(TABLE, ROW_1); 110 assertEquals(200, response.getCode()); 111 } 112 113 @Test 114 public void testSingleCellGetPutPB() throws IOException, JAXBException { 115 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 116 assertEquals(404, response.getCode()); 117 118 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 119 assertEquals(200, response.getCode()); 120 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 121 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2); 122 assertEquals(200, response.getCode()); 123 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2); 124 125 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2, VALUE_3); 126 assertEquals(200, response.getCode()); 127 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_3); 128 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3, VALUE_4); 129 assertEquals(200, response.getCode()); 130 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_4); 131 132 response = deleteRow(TABLE, ROW_1); 133 assertEquals(200, response.getCode()); 134 } 135 136 @Test 137 public void testMultipleCellCheckPutPB() throws IOException, JAXBException { 138 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 139 assertEquals(404, response.getCode()); 140 141 // Add 2 Columns to setup the test 142 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 143 assertEquals(200, response.getCode()); 144 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 145 146 response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 147 assertEquals(200, response.getCode()); 148 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 149 150 HashMap<String,String> otherCells = new HashMap<>(); 151 otherCells.put(COLUMN_2,VALUE_3); 152 153 // On Success update both the cells 154 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_3, otherCells); 155 assertEquals(200, response.getCode()); 156 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_3); 157 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_3); 158 159 // On Failure, we dont update any cells 160 response = checkAndPutValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_4, otherCells); 161 assertEquals(304, response.getCode()); 162 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_3); 163 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_3); 164 165 response = deleteRow(TABLE, ROW_1); 166 assertEquals(200, response.getCode()); 167 } 168 169 @Test 170 public void testMultipleCellCheckPutXML() throws IOException, JAXBException { 171 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 172 assertEquals(404, response.getCode()); 173 174 // Add 2 Columns to setup the test 175 response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 176 assertEquals(200, response.getCode()); 177 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 178 179 response = putValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2); 180 assertEquals(200, response.getCode()); 181 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2); 182 183 HashMap<String,String> otherCells = new HashMap<>(); 184 otherCells.put(COLUMN_2,VALUE_3); 185 186 // On Success update both the cells 187 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_3, otherCells); 188 assertEquals(200, response.getCode()); 189 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3); 190 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_3); 191 192 // On Failure, we dont update any cells 193 response = checkAndPutValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1, VALUE_4, otherCells); 194 assertEquals(304, response.getCode()); 195 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_3); 196 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_3); 197 198 response = deleteRow(TABLE, ROW_1); 199 assertEquals(200, response.getCode()); 200 } 201 202 @Test 203 public void testMultipleCellCheckDeletePB() throws IOException, JAXBException { 204 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 205 assertEquals(404, response.getCode()); 206 207 // Add 3 Columns to setup the test 208 response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 209 assertEquals(200, response.getCode()); 210 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 211 212 response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 213 assertEquals(200, response.getCode()); 214 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 215 216 response = putValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 217 assertEquals(200, response.getCode()); 218 checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 219 220 // Deletes the following columns based on Column1 check 221 HashMap<String,String> cellsToDelete = new HashMap<>(); 222 cellsToDelete.put(COLUMN_2,VALUE_2); // Value does not matter 223 cellsToDelete.put(COLUMN_3,VALUE_3); // Value does not matter 224 225 // On Success update both the cells 226 response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_1, cellsToDelete); 227 assertEquals(200, response.getCode()); 228 229 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 230 231 response = getValuePB(TABLE, ROW_1, COLUMN_2); 232 assertEquals(404, response.getCode()); 233 234 response = getValuePB(TABLE, ROW_1, COLUMN_3); 235 assertEquals(404, response.getCode()); 236 237 response = putValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 238 assertEquals(200, response.getCode()); 239 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 240 241 response = putValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 242 assertEquals(200, response.getCode()); 243 checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 244 245 // On Failure, we dont update any cells 246 response = checkAndDeletePB(TABLE, ROW_1, COLUMN_1, VALUE_3, cellsToDelete); 247 assertEquals(304, response.getCode()); 248 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 249 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 250 checkValuePB(TABLE, ROW_1, COLUMN_3, VALUE_3); 251 252 response = deleteRow(TABLE, ROW_1); 253 assertEquals(200, response.getCode()); 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, JAXBException { 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, JAXBException { 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, JAXBException { 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, JAXBException { 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} 809