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, Bytes.toBytes(VALUE_4)); 284 assertEquals(200, response.getCode()); 285 Thread.yield(); 286 response = client.get(path, Constants.MIMETYPE_JSON); 287 assertEquals(200, response.getCode()); 288 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); 289 response = deleteRow(TABLE, ROW_4); 290 assertEquals(200, response.getCode()); 291 } 292 293 @Test 294 public void testLatestCellGetJSON() throws IOException { 295 final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1; 296 CellSetModel cellSetModel = new CellSetModel(); 297 RowModel rowModel = new RowModel(ROW_4); 298 CellModel cellOne = new CellModel(Bytes.toBytes(COLUMN_1), 1L, Bytes.toBytes(VALUE_1)); 299 CellModel cellTwo = new CellModel(Bytes.toBytes(COLUMN_1), 2L, Bytes.toBytes(VALUE_2)); 300 rowModel.addCell(cellOne); 301 rowModel.addCell(cellTwo); 302 cellSetModel.addRow(rowModel); 303 String jsonString = jsonMapper.writeValueAsString(cellSetModel); 304 Response response = client.put(path, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString)); 305 assertEquals(200, response.getCode()); 306 Thread.yield(); 307 response = client.get(path, Constants.MIMETYPE_JSON); 308 assertEquals(200, response.getCode()); 309 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); 310 CellSetModel cellSet = jsonMapper.readValue(response.getBody(), CellSetModel.class); 311 assertTrue(cellSet.getRows().size() == 1); 312 assertTrue(cellSet.getRows().get(0).getCells().size() == 1); 313 CellModel cell = cellSet.getRows().get(0).getCells().get(0); 314 assertEquals(VALUE_2, Bytes.toString(cell.getValue())); 315 assertEquals(2L, cell.getTimestamp()); 316 response = deleteRow(TABLE, ROW_4); 317 assertEquals(200, response.getCode()); 318 } 319 320 @Test 321 public void testURLEncodedKey() throws IOException, JAXBException { 322 String urlKey = "http://example.com/foo"; 323 StringBuilder path = new StringBuilder(); 324 path.append('/'); 325 path.append(TABLE); 326 path.append('/'); 327 path.append(URLEncoder.encode(urlKey, HConstants.UTF8_ENCODING)); 328 path.append('/'); 329 path.append(COLUMN_1); 330 Response response; 331 response = putValueXML(path.toString(), TABLE, urlKey, COLUMN_1, VALUE_1); 332 assertEquals(200, response.getCode()); 333 checkValueXML(path.toString(), TABLE, urlKey, COLUMN_1, VALUE_1); 334 } 335 336 @Test 337 public void testNoSuchCF() throws IOException { 338 final String goodPath = "/" + TABLE + "/" + ROW_1 + "/" + CFA + ":"; 339 final String badPath = "/" + TABLE + "/" + ROW_1 + "/" + "BAD"; 340 Response response = client.post(goodPath, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1)); 341 assertEquals(200, response.getCode()); 342 assertEquals(200, client.get(goodPath, Constants.MIMETYPE_BINARY).getCode()); 343 assertEquals(404, client.get(badPath, Constants.MIMETYPE_BINARY).getCode()); 344 assertEquals(200, client.get(goodPath, Constants.MIMETYPE_BINARY).getCode()); 345 } 346 347 @Test 348 public void testMultiCellGetPutXML() throws IOException, JAXBException { 349 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 350 351 CellSetModel cellSetModel = new CellSetModel(); 352 RowModel rowModel = new RowModel(ROW_1); 353 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1))); 354 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_2))); 355 cellSetModel.addRow(rowModel); 356 rowModel = new RowModel(ROW_2); 357 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_3))); 358 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_4))); 359 cellSetModel.addRow(rowModel); 360 StringWriter writer = new StringWriter(); 361 xmlMarshaller.marshal(cellSetModel, writer); 362 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString())); 363 Thread.yield(); 364 365 // make sure the fake row was not actually created 366 response = client.get(path, Constants.MIMETYPE_XML); 367 assertEquals(404, response.getCode()); 368 369 // check that all of the values were created 370 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 371 checkValueXML(TABLE, ROW_1, COLUMN_2, VALUE_2); 372 checkValueXML(TABLE, ROW_2, COLUMN_1, VALUE_3); 373 checkValueXML(TABLE, ROW_2, COLUMN_2, VALUE_4); 374 375 response = deleteRow(TABLE, ROW_1); 376 assertEquals(200, response.getCode()); 377 response = deleteRow(TABLE, ROW_2); 378 assertEquals(200, response.getCode()); 379 } 380 381 @Test 382 public void testMultiCellGetPutPB() throws IOException { 383 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 384 385 CellSetModel cellSetModel = new CellSetModel(); 386 RowModel rowModel = new RowModel(ROW_1); 387 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1))); 388 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_2))); 389 cellSetModel.addRow(rowModel); 390 rowModel = new RowModel(ROW_2); 391 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_3))); 392 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_4))); 393 cellSetModel.addRow(rowModel); 394 Response response = 395 client.put(path, Constants.MIMETYPE_PROTOBUF, cellSetModel.createProtobufOutput()); 396 Thread.yield(); 397 398 // make sure the fake row was not actually created 399 response = client.get(path, Constants.MIMETYPE_PROTOBUF); 400 assertEquals(404, response.getCode()); 401 402 // check that all of the values were created 403 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 404 checkValuePB(TABLE, ROW_1, COLUMN_2, VALUE_2); 405 checkValuePB(TABLE, ROW_2, COLUMN_1, VALUE_3); 406 checkValuePB(TABLE, ROW_2, COLUMN_2, VALUE_4); 407 408 response = deleteRow(TABLE, ROW_1); 409 assertEquals(200, response.getCode()); 410 response = deleteRow(TABLE, ROW_2); 411 assertEquals(200, response.getCode()); 412 } 413 414 @Test 415 public void testStartEndRowGetPutXML() throws IOException, JAXBException { 416 String[] rows = { ROW_1, ROW_2, ROW_3 }; 417 String[] values = { VALUE_1, VALUE_2, VALUE_3 }; 418 Response response = null; 419 for (int i = 0; i < rows.length; i++) { 420 response = putValueXML(TABLE, rows[i], COLUMN_1, values[i]); 421 assertEquals(200, response.getCode()); 422 checkValueXML(TABLE, rows[i], COLUMN_1, values[i]); 423 } 424 response = getValueXML(TABLE, rows[0], rows[2], COLUMN_1); 425 assertEquals(200, response.getCode()); 426 CellSetModel cellSet = 427 (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody())); 428 assertEquals(2, cellSet.getRows().size()); 429 for (int i = 0; i < cellSet.getRows().size() - 1; i++) { 430 RowModel rowModel = cellSet.getRows().get(i); 431 for (CellModel cell : rowModel.getCells()) { 432 assertEquals(COLUMN_1, Bytes.toString(cell.getColumn())); 433 assertEquals(values[i], Bytes.toString(cell.getValue())); 434 } 435 } 436 for (String row : rows) { 437 response = deleteRow(TABLE, row); 438 assertEquals(200, response.getCode()); 439 } 440 } 441 442 @Test 443 public void testInvalidCheckParam() throws IOException, JAXBException { 444 CellSetModel cellSetModel = new CellSetModel(); 445 RowModel rowModel = new RowModel(ROW_1); 446 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1))); 447 cellSetModel.addRow(rowModel); 448 StringWriter writer = new StringWriter(); 449 xmlMarshaller.marshal(cellSetModel, writer); 450 451 final String path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "?check=blah"; 452 453 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString())); 454 assertEquals(400, response.getCode()); 455 } 456 457 @Test 458 public void testInvalidColumnPut() throws IOException, JAXBException { 459 String dummyColumn = "doesnot:exist"; 460 CellSetModel cellSetModel = new CellSetModel(); 461 RowModel rowModel = new RowModel(ROW_1); 462 rowModel.addCell(new CellModel(Bytes.toBytes(dummyColumn), 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 + "/" + dummyColumn; 468 469 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString())); 470 assertEquals(404, response.getCode()); 471 } 472 473 @Test 474 public void testMultiCellGetJson() throws IOException, JAXBException { 475 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 476 477 CellSetModel cellSetModel = new CellSetModel(); 478 RowModel rowModel = new RowModel(ROW_1); 479 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1))); 480 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_2))); 481 cellSetModel.addRow(rowModel); 482 rowModel = new RowModel(ROW_2); 483 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_3))); 484 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_4))); 485 cellSetModel.addRow(rowModel); 486 String jsonString = jsonMapper.writeValueAsString(cellSetModel); 487 488 Response response = client.put(path, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString)); 489 Thread.yield(); 490 491 // make sure the fake row was not actually created 492 response = client.get(path, Constants.MIMETYPE_JSON); 493 assertEquals(404, response.getCode()); 494 495 // check that all of the values were created 496 checkValueJSON(TABLE, ROW_1, COLUMN_1, VALUE_1); 497 checkValueJSON(TABLE, ROW_1, COLUMN_2, VALUE_2); 498 checkValueJSON(TABLE, ROW_2, COLUMN_1, VALUE_3); 499 checkValueJSON(TABLE, ROW_2, COLUMN_2, VALUE_4); 500 501 response = deleteRow(TABLE, ROW_1); 502 assertEquals(200, response.getCode()); 503 response = deleteRow(TABLE, ROW_2); 504 assertEquals(200, response.getCode()); 505 } 506 507 @Test 508 public void testMetrics() throws IOException { 509 final String path = "/" + TABLE + "/" + ROW_4 + "/" + COLUMN_1; 510 Response response = client.put(path, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_4)); 511 assertEquals(200, response.getCode()); 512 Thread.yield(); 513 response = client.get(path, Constants.MIMETYPE_JSON); 514 assertEquals(200, response.getCode()); 515 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); 516 response = deleteRow(TABLE, ROW_4); 517 assertEquals(200, response.getCode()); 518 519 UserProvider userProvider = UserProvider.instantiate(conf); 520 METRICS_ASSERT.assertCounterGt("requests", 2L, 521 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 522 523 METRICS_ASSERT.assertCounterGt("successfulGet", 0L, 524 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 525 526 METRICS_ASSERT.assertCounterGt("successfulPut", 0L, 527 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 528 529 METRICS_ASSERT.assertCounterGt("successfulDelete", 0L, 530 RESTServlet.getInstance(conf, userProvider).getMetrics().getSource()); 531 } 532 533 @Test 534 public void testMultiColumnGetXML() throws Exception { 535 String path = "/" + TABLE + "/fakerow"; 536 CellSetModel cellSetModel = new CellSetModel(); 537 RowModel rowModel = new RowModel(ROW_1); 538 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1))); 539 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_2))); 540 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_3), Bytes.toBytes(VALUE_2))); 541 cellSetModel.addRow(rowModel); 542 StringWriter writer = new StringWriter(); 543 xmlMarshaller.marshal(cellSetModel, writer); 544 545 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString())); 546 Thread.yield(); 547 548 // make sure the fake row was not actually created 549 response = client.get(path, Constants.MIMETYPE_XML); 550 assertEquals(404, response.getCode()); 551 552 // Try getting all the column values at once. 553 path = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1 + "," + COLUMN_2 + "," + COLUMN_3; 554 response = client.get(path, Constants.MIMETYPE_XML); 555 assertEquals(200, response.getCode()); 556 CellSetModel cellSet = 557 (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody())); 558 assertTrue(cellSet.getRows().size() == 1); 559 assertTrue(cellSet.getRows().get(0).getCells().size() == 3); 560 List<CellModel> cells = cellSet.getRows().get(0).getCells(); 561 562 assertTrue(containsCellModel(cells, COLUMN_1, VALUE_1)); 563 assertTrue(containsCellModel(cells, COLUMN_2, VALUE_2)); 564 assertTrue(containsCellModel(cells, COLUMN_3, VALUE_2)); 565 response = deleteRow(TABLE, ROW_1); 566 assertEquals(200, response.getCode()); 567 } 568 569 private boolean containsCellModel(List<CellModel> cells, String column, String value) { 570 boolean contains = false; 571 for (CellModel cell : cells) { 572 if ( 573 Bytes.toString(cell.getColumn()).equals(column) 574 && Bytes.toString(cell.getValue()).equals(value) 575 ) { 576 contains = true; 577 return contains; 578 } 579 } 580 return contains; 581 } 582 583 @Test 584 public void testSuffixGlobbingXMLWithNewScanner() throws IOException, JAXBException { 585 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 586 587 CellSetModel cellSetModel = new CellSetModel(); 588 RowModel rowModel = new RowModel(ROW_1); 589 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1))); 590 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_2))); 591 cellSetModel.addRow(rowModel); 592 rowModel = new RowModel(ROW_2); 593 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_3))); 594 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_4))); 595 cellSetModel.addRow(rowModel); 596 StringWriter writer = new StringWriter(); 597 xmlMarshaller.marshal(cellSetModel, writer); 598 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString())); 599 Thread.yield(); 600 601 // make sure the fake row was not actually created 602 response = client.get(path, Constants.MIMETYPE_XML); 603 assertEquals(404, response.getCode()); 604 605 // check that all of the values were created 606 StringBuilder query = new StringBuilder(); 607 query.append('/'); 608 query.append(TABLE); 609 query.append('/'); 610 query.append("testrow*"); 611 response = client.get(query.toString(), Constants.MIMETYPE_XML); 612 assertEquals(200, response.getCode()); 613 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); 614 CellSetModel cellSet = 615 (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody())); 616 assertTrue(cellSet.getRows().size() == 2); 617 618 response = deleteRow(TABLE, ROW_1); 619 assertEquals(200, response.getCode()); 620 response = deleteRow(TABLE, ROW_2); 621 assertEquals(200, response.getCode()); 622 } 623 624 @Test 625 public void testSuffixGlobbingXML() throws IOException, JAXBException { 626 String path = "/" + TABLE + "/fakerow"; // deliberate nonexistent row 627 628 CellSetModel cellSetModel = new CellSetModel(); 629 RowModel rowModel = new RowModel(ROW_1); 630 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_1))); 631 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_2))); 632 cellSetModel.addRow(rowModel); 633 rowModel = new RowModel(ROW_2); 634 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_1), Bytes.toBytes(VALUE_3))); 635 rowModel.addCell(new CellModel(Bytes.toBytes(COLUMN_2), Bytes.toBytes(VALUE_4))); 636 cellSetModel.addRow(rowModel); 637 StringWriter writer = new StringWriter(); 638 xmlMarshaller.marshal(cellSetModel, writer); 639 Response response = client.put(path, Constants.MIMETYPE_XML, Bytes.toBytes(writer.toString())); 640 Thread.yield(); 641 642 // make sure the fake row was not actually created 643 response = client.get(path, Constants.MIMETYPE_XML); 644 assertEquals(404, response.getCode()); 645 646 // check that all of the values were created 647 StringBuilder query = new StringBuilder(); 648 query.append('/'); 649 query.append(TABLE); 650 query.append('/'); 651 query.append("testrow*"); 652 query.append('/'); 653 query.append(COLUMN_1); 654 response = client.get(query.toString(), Constants.MIMETYPE_XML); 655 assertEquals(200, response.getCode()); 656 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); 657 CellSetModel cellSet = 658 (CellSetModel) xmlUnmarshaller.unmarshal(new ByteArrayInputStream(response.getBody())); 659 List<RowModel> rows = cellSet.getRows(); 660 assertTrue(rows.size() == 2); 661 for (RowModel row : rows) { 662 assertTrue(row.getCells().size() == 1); 663 assertEquals(COLUMN_1, Bytes.toString(row.getCells().get(0).getColumn())); 664 } 665 response = deleteRow(TABLE, ROW_1); 666 assertEquals(200, response.getCode()); 667 response = deleteRow(TABLE, ROW_2); 668 assertEquals(200, response.getCode()); 669 } 670 671 @Test 672 public void testAppendXML() throws IOException, JAXBException { 673 Response response = getValueXML(TABLE, ROW_1, COLUMN_1); 674 assertEquals(404, response.getCode()); 675 676 // append cell 677 response = appendValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 678 assertEquals(200, response.getCode()); 679 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); 680 response = appendValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2); 681 assertEquals(200, response.getCode()); 682 checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1 + VALUE_2); 683 684 response = deleteRow(TABLE, ROW_1); 685 assertEquals(200, response.getCode()); 686 } 687 688 @Test 689 public void testAppendPB() throws IOException, JAXBException { 690 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 691 assertEquals(404, response.getCode()); 692 693 // append cell 694 response = appendValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 695 assertEquals(200, response.getCode()); 696 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); 697 response = appendValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2); 698 assertEquals(200, response.getCode()); 699 checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1 + VALUE_2); 700 701 response = deleteRow(TABLE, ROW_1); 702 assertEquals(200, response.getCode()); 703 } 704 705 @Test 706 public void testAppendJSON() throws IOException, JAXBException { 707 Response response = getValueJson(TABLE, ROW_1, COLUMN_1); 708 assertEquals(404, response.getCode()); 709 710 // append cell 711 response = appendValueJson(TABLE, ROW_1, COLUMN_1, VALUE_1); 712 assertEquals(200, response.getCode()); 713 putValueJson(TABLE, ROW_1, COLUMN_1, VALUE_1); 714 response = appendValueJson(TABLE, ROW_1, COLUMN_1, VALUE_2); 715 assertEquals(200, response.getCode()); 716 putValueJson(TABLE, ROW_1, COLUMN_1, VALUE_1 + VALUE_2); 717 718 response = deleteRow(TABLE, ROW_1); 719 assertEquals(200, response.getCode()); 720 } 721 722 @Test 723 public void testIncrementXML() throws IOException, JAXBException { 724 Response response = getValueXML(TABLE, ROW_1, COLUMN_1); 725 assertEquals(404, response.getCode()); 726 727 // append single cell 728 response = incrementValueXML(TABLE, ROW_1, COLUMN_1, VALUE_5); 729 assertEquals(200, response.getCode()); 730 checkIncrementValueXML(TABLE, ROW_1, COLUMN_1, Long.parseLong(VALUE_5)); 731 response = incrementValueXML(TABLE, ROW_1, COLUMN_1, VALUE_6); 732 assertEquals(200, response.getCode()); 733 checkIncrementValueXML(TABLE, ROW_1, COLUMN_1, 734 Long.parseLong(VALUE_5) + Long.parseLong(VALUE_6)); 735 736 response = deleteRow(TABLE, ROW_1); 737 assertEquals(200, response.getCode()); 738 } 739 740 @Test 741 public void testIncrementPB() throws IOException, JAXBException { 742 Response response = getValuePB(TABLE, ROW_1, COLUMN_1); 743 assertEquals(404, response.getCode()); 744 745 // append cell 746 response = incrementValuePB(TABLE, ROW_1, COLUMN_1, VALUE_5); 747 assertEquals(200, response.getCode()); 748 checkIncrementValuePB(TABLE, ROW_1, COLUMN_1, Long.parseLong(VALUE_5)); 749 response = incrementValuePB(TABLE, ROW_1, COLUMN_1, VALUE_6); 750 assertEquals(200, response.getCode()); 751 checkIncrementValuePB(TABLE, ROW_1, COLUMN_1, 752 Long.parseLong(VALUE_5) + Long.parseLong(VALUE_6)); 753 754 response = deleteRow(TABLE, ROW_1); 755 assertEquals(200, response.getCode()); 756 } 757 758 @Test 759 public void testIncrementJSON() throws IOException, JAXBException { 760 Response response = getValueJson(TABLE, ROW_1, COLUMN_1); 761 assertEquals(404, response.getCode()); 762 763 // append cell 764 response = incrementValueJson(TABLE, ROW_1, COLUMN_1, VALUE_5); 765 assertEquals(200, response.getCode()); 766 checkIncrementValueJSON(TABLE, ROW_1, COLUMN_1, Long.parseLong(VALUE_5)); 767 response = incrementValueJson(TABLE, ROW_1, COLUMN_1, VALUE_6); 768 assertEquals(200, response.getCode()); 769 checkIncrementValueJSON(TABLE, ROW_1, COLUMN_1, 770 Long.parseLong(VALUE_5) + Long.parseLong(VALUE_6)); 771 772 response = deleteRow(TABLE, ROW_1); 773 assertEquals(200, response.getCode()); 774 } 775}