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.client; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNull; 023import static org.junit.Assert.assertTrue; 024import static org.junit.Assert.fail; 025 026import java.io.IOException; 027import java.util.Arrays; 028import java.util.Collections; 029import java.util.List; 030import org.apache.hadoop.hbase.CompareOperator; 031import org.apache.hadoop.hbase.HBaseClassTestRule; 032import org.apache.hadoop.hbase.HBaseTestingUtility; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.hadoop.hbase.filter.BinaryComparator; 035import org.apache.hadoop.hbase.filter.FamilyFilter; 036import org.apache.hadoop.hbase.filter.FilterList; 037import org.apache.hadoop.hbase.filter.QualifierFilter; 038import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 039import org.apache.hadoop.hbase.filter.TimestampsFilter; 040import org.apache.hadoop.hbase.io.TimeRange; 041import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException; 042import org.apache.hadoop.hbase.testclassification.MediumTests; 043import org.apache.hadoop.hbase.util.Bytes; 044import org.junit.AfterClass; 045import org.junit.BeforeClass; 046import org.junit.ClassRule; 047import org.junit.Rule; 048import org.junit.Test; 049import org.junit.experimental.categories.Category; 050import org.junit.rules.TestName; 051 052@Category(MediumTests.class) 053public class TestCheckAndMutate { 054 055 @ClassRule 056 public static final HBaseClassTestRule CLASS_RULE = 057 HBaseClassTestRule.forClass(TestCheckAndMutate.class); 058 059 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 060 private static final byte[] ROWKEY = Bytes.toBytes("12345"); 061 private static final byte[] ROWKEY2 = Bytes.toBytes("67890"); 062 private static final byte[] ROWKEY3 = Bytes.toBytes("abcde"); 063 private static final byte[] ROWKEY4 = Bytes.toBytes("fghij"); 064 private static final byte[] FAMILY = Bytes.toBytes("cf"); 065 066 @Rule 067 public TestName name = new TestName(); 068 069 @BeforeClass 070 public static void setUpBeforeClass() throws Exception { 071 TEST_UTIL.startMiniCluster(); 072 } 073 074 @AfterClass 075 public static void tearDownAfterClass() throws Exception { 076 TEST_UTIL.shutdownMiniCluster(); 077 } 078 079 private Table createTable() throws IOException, InterruptedException { 080 final TableName tableName = TableName.valueOf(name.getMethodName()); 081 Table table = TEST_UTIL.createTable(tableName, FAMILY); 082 TEST_UTIL.waitTableAvailable(tableName.getName(), 5000); 083 return table; 084 } 085 086 private void putOneRow(Table table) throws IOException { 087 Put put = new Put(ROWKEY); 088 put.addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")); 089 put.addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")); 090 put.addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")); 091 table.put(put); 092 } 093 094 private void getOneRowAndAssertAllExist(final Table table) throws IOException { 095 Get get = new Get(ROWKEY); 096 Result result = table.get(get); 097 assertTrue("Column A value should be a", 098 Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a")); 099 assertTrue("Column B value should be b", 100 Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b")); 101 assertTrue("Column C value should be c", 102 Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C"))).equals("c")); 103 } 104 105 private void getOneRowAndAssertAllButCExist(final Table table) throws IOException { 106 Get get = new Get(ROWKEY); 107 Result result = table.get(get); 108 assertTrue("Column A value should be a", 109 Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a")); 110 assertTrue("Column B value should be b", 111 Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b")); 112 assertTrue("Column C should not exist", result.getValue(FAMILY, Bytes.toBytes("C")) == null); 113 } 114 115 private RowMutations makeRowMutationsWithColumnCDeleted() throws IOException { 116 RowMutations rm = new RowMutations(ROWKEY, 2); 117 Put put = new Put(ROWKEY); 118 put.addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")); 119 put.addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")); 120 rm.add(put); 121 Delete del = new Delete(ROWKEY); 122 del.addColumn(FAMILY, Bytes.toBytes("C")); 123 rm.add(del); 124 return rm; 125 } 126 127 private RowMutations getBogusRowMutations() throws IOException { 128 Put p = new Put(ROWKEY); 129 byte[] value = new byte[0]; 130 p.addColumn(new byte[] { 'b', 'o', 'g', 'u', 's' }, new byte[] { 'A' }, value); 131 RowMutations rm = new RowMutations(ROWKEY); 132 rm.add(p); 133 return rm; 134 } 135 136 // Tests for old checkAndMutate API 137 138 @Test 139 @Deprecated 140 public void testCheckAndMutateForOldApi() throws Throwable { 141 try (Table table = createTable()) { 142 // put one row 143 putOneRow(table); 144 // get row back and assert the values 145 getOneRowAndAssertAllExist(table); 146 147 // put the same row again with C column deleted 148 RowMutations rm = makeRowMutationsWithColumnCDeleted(); 149 boolean res = table.checkAndMutate(ROWKEY, FAMILY).qualifier(Bytes.toBytes("A")) 150 .ifEquals(Bytes.toBytes("a")).thenMutate(rm); 151 assertTrue(res); 152 153 // get row back and assert the values 154 getOneRowAndAssertAllButCExist(table); 155 156 // Test that we get a region level exception 157 try { 158 rm = getBogusRowMutations(); 159 table.checkAndMutate(ROWKEY, FAMILY).qualifier(Bytes.toBytes("A")) 160 .ifEquals(Bytes.toBytes("a")).thenMutate(rm); 161 fail("Expected NoSuchColumnFamilyException"); 162 } catch (RetriesExhaustedWithDetailsException e) { 163 try { 164 throw e.getCause(0); 165 } catch (NoSuchColumnFamilyException e1) { 166 // expected 167 } 168 } 169 } 170 } 171 172 @Test 173 @Deprecated 174 public void testCheckAndMutateWithSingleFilterForOldApi() throws Throwable { 175 try (Table table = createTable()) { 176 // put one row 177 putOneRow(table); 178 // get row back and assert the values 179 getOneRowAndAssertAllExist(table); 180 181 // Put with success 182 boolean ok = table 183 .checkAndMutate(ROWKEY, 184 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 185 Bytes.toBytes("a"))) 186 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))); 187 assertTrue(ok); 188 189 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 190 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 191 192 // Put with failure 193 ok = table 194 .checkAndMutate(ROWKEY, 195 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 196 Bytes.toBytes("b"))) 197 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e"))); 198 assertFalse(ok); 199 200 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E")))); 201 202 // Delete with success 203 ok = table 204 .checkAndMutate(ROWKEY, 205 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 206 Bytes.toBytes("a"))) 207 .thenDelete(new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("D"))); 208 assertTrue(ok); 209 210 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D")))); 211 212 // Mutate with success 213 ok = table 214 .checkAndMutate(ROWKEY, 215 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 216 Bytes.toBytes("b"))) 217 .thenMutate(new RowMutations(ROWKEY) 218 .add((Mutation) new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))) 219 .add((Mutation) new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("A")))); 220 assertTrue(ok); 221 222 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 223 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 224 225 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A")))); 226 } 227 } 228 229 @Test 230 @Deprecated 231 public void testCheckAndMutateWithMultipleFiltersForOldApi() throws Throwable { 232 try (Table table = createTable()) { 233 // put one row 234 putOneRow(table); 235 // get row back and assert the values 236 getOneRowAndAssertAllExist(table); 237 238 // Put with success 239 boolean ok = table 240 .checkAndMutate(ROWKEY, 241 new FilterList( 242 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 243 Bytes.toBytes("a")), 244 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 245 Bytes.toBytes("b")))) 246 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))); 247 assertTrue(ok); 248 249 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 250 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 251 252 // Put with failure 253 ok = table 254 .checkAndMutate(ROWKEY, 255 new FilterList( 256 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 257 Bytes.toBytes("a")), 258 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 259 Bytes.toBytes("c")))) 260 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e"))); 261 assertFalse(ok); 262 263 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E")))); 264 265 // Delete with success 266 ok = table 267 .checkAndMutate(ROWKEY, 268 new FilterList( 269 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 270 Bytes.toBytes("a")), 271 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 272 Bytes.toBytes("b")))) 273 .thenDelete(new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("D"))); 274 assertTrue(ok); 275 276 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D")))); 277 278 // Mutate with success 279 ok = table 280 .checkAndMutate(ROWKEY, 281 new FilterList( 282 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 283 Bytes.toBytes("a")), 284 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 285 Bytes.toBytes("b")))) 286 .thenMutate(new RowMutations(ROWKEY) 287 .add((Mutation) new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))) 288 .add((Mutation) new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("A")))); 289 assertTrue(ok); 290 291 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 292 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 293 294 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A")))); 295 } 296 } 297 298 @Test 299 @Deprecated 300 public void testCheckAndMutateWithTimestampFilterForOldApi() throws Throwable { 301 try (Table table = createTable()) { 302 // Put with specifying the timestamp 303 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a"))); 304 305 // Put with success 306 boolean ok = table 307 .checkAndMutate(ROWKEY, 308 new FilterList(new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(FAMILY)), 309 new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("A"))), 310 new TimestampsFilter(Collections.singletonList(100L)))) 311 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))); 312 assertTrue(ok); 313 314 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 315 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 316 317 // Put with failure 318 ok = table 319 .checkAndMutate(ROWKEY, 320 new FilterList(new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(FAMILY)), 321 new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("A"))), 322 new TimestampsFilter(Collections.singletonList(101L)))) 323 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"))); 324 assertFalse(ok); 325 326 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C")))); 327 } 328 } 329 330 @Test 331 @Deprecated 332 public void testCheckAndMutateWithFilterAndTimeRangeForOldApi() throws Throwable { 333 try (Table table = createTable()) { 334 // Put with specifying the timestamp 335 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a"))); 336 337 // Put with success 338 boolean ok = table 339 .checkAndMutate(ROWKEY, 340 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 341 Bytes.toBytes("a"))) 342 .timeRange(TimeRange.between(0, 101)) 343 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))); 344 assertTrue(ok); 345 346 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 347 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 348 349 // Put with failure 350 ok = table 351 .checkAndMutate(ROWKEY, 352 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 353 Bytes.toBytes("a"))) 354 .timeRange(TimeRange.between(0, 100)) 355 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"))); 356 assertFalse(ok); 357 358 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C")))); 359 } 360 } 361 362 @Test(expected = NullPointerException.class) 363 @Deprecated 364 public void testCheckAndMutateWithoutConditionForOldApi() throws Throwable { 365 try (Table table = createTable()) { 366 table.checkAndMutate(ROWKEY, FAMILY) 367 .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))); 368 } 369 } 370 371 // Tests for new CheckAndMutate API 372 373 @Test 374 public void testCheckAndMutate() throws Throwable { 375 try (Table table = createTable()) { 376 // put one row 377 putOneRow(table); 378 // get row back and assert the values 379 getOneRowAndAssertAllExist(table); 380 381 // put the same row again with C column deleted 382 RowMutations rm = makeRowMutationsWithColumnCDeleted(); 383 CheckAndMutateResult res = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 384 .ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")).build(rm)); 385 assertTrue(res.isSuccess()); 386 assertNull(res.getResult()); 387 388 // get row back and assert the values 389 getOneRowAndAssertAllButCExist(table); 390 391 // Test that we get a region level exception 392 try { 393 rm = getBogusRowMutations(); 394 table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 395 .ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")).build(rm)); 396 fail("Expected NoSuchColumnFamilyException"); 397 } catch (RetriesExhaustedWithDetailsException e) { 398 try { 399 throw e.getCause(0); 400 } catch (NoSuchColumnFamilyException e1) { 401 // expected 402 } 403 } 404 } 405 } 406 407 @Test 408 public void testCheckAndMutateWithSingleFilter() throws Throwable { 409 try (Table table = createTable()) { 410 // put one row 411 putOneRow(table); 412 // get row back and assert the values 413 getOneRowAndAssertAllExist(table); 414 415 // Put with success 416 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 417 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 418 Bytes.toBytes("a"))) 419 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))); 420 assertTrue(result.isSuccess()); 421 assertNull(result.getResult()); 422 423 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 424 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 425 426 // Put with failure 427 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 428 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 429 Bytes.toBytes("b"))) 430 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))); 431 assertFalse(result.isSuccess()); 432 assertNull(result.getResult()); 433 434 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E")))); 435 436 // Delete with success 437 result = table.checkAndMutate(CheckAndMutate 438 .newBuilder(ROWKEY).ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), 439 CompareOperator.EQUAL, Bytes.toBytes("a"))) 440 .build(new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("D")))); 441 assertTrue(result.isSuccess()); 442 assertNull(result.getResult()); 443 444 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D")))); 445 446 // Mutate with success 447 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 448 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 449 Bytes.toBytes("b"))) 450 .build(new RowMutations(ROWKEY) 451 .add((Mutation) new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))) 452 .add((Mutation) new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("A"))))); 453 assertTrue(result.isSuccess()); 454 assertNull(result.getResult()); 455 456 r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 457 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 458 459 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A")))); 460 } 461 } 462 463 @Test 464 public void testCheckAndMutateWithMultipleFilters() throws Throwable { 465 try (Table table = createTable()) { 466 // put one row 467 putOneRow(table); 468 // get row back and assert the values 469 getOneRowAndAssertAllExist(table); 470 471 // Put with success 472 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 473 .ifMatches(new FilterList( 474 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 475 Bytes.toBytes("a")), 476 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 477 Bytes.toBytes("b")))) 478 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))); 479 assertTrue(result.isSuccess()); 480 assertNull(result.getResult()); 481 482 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 483 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 484 485 // Put with failure 486 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 487 .ifMatches(new FilterList( 488 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 489 Bytes.toBytes("a")), 490 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 491 Bytes.toBytes("c")))) 492 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))); 493 assertFalse(result.isSuccess()); 494 assertNull(result.getResult()); 495 496 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E")))); 497 498 // Delete with success 499 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 500 .ifMatches(new FilterList( 501 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 502 Bytes.toBytes("a")), 503 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 504 Bytes.toBytes("b")))) 505 .build(new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("D")))); 506 assertTrue(result.isSuccess()); 507 assertNull(result.getResult()); 508 509 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D")))); 510 511 // Mutate with success 512 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 513 .ifMatches(new FilterList( 514 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 515 Bytes.toBytes("a")), 516 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 517 Bytes.toBytes("b")))) 518 .build(new RowMutations(ROWKEY) 519 .add((Mutation) new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))) 520 .add((Mutation) new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("A"))))); 521 assertTrue(result.isSuccess()); 522 assertNull(result.getResult()); 523 524 r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 525 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 526 527 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A")))); 528 } 529 } 530 531 @Test 532 public void testCheckAndMutateWithTimestampFilter() throws Throwable { 533 try (Table table = createTable()) { 534 // Put with specifying the timestamp 535 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a"))); 536 537 // Put with success 538 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 539 .ifMatches( 540 new FilterList(new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(FAMILY)), 541 new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("A"))), 542 new TimestampsFilter(Collections.singletonList(100L)))) 543 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")))); 544 assertTrue(result.isSuccess()); 545 assertNull(result.getResult()); 546 547 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 548 assertEquals("b", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("B")))); 549 550 // Put with failure 551 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 552 .ifMatches( 553 new FilterList(new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(FAMILY)), 554 new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("A"))), 555 new TimestampsFilter(Collections.singletonList(101L)))) 556 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")))); 557 assertFalse(result.isSuccess()); 558 assertNull(result.getResult()); 559 560 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C")))); 561 } 562 } 563 564 @Test 565 public void testCheckAndMutateWithFilterAndTimeRange() throws Throwable { 566 try (Table table = createTable()) { 567 // Put with specifying the timestamp 568 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a"))); 569 570 // Put with success 571 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 572 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 573 Bytes.toBytes("a"))) 574 .timeRange(TimeRange.between(0, 101)) 575 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")))); 576 assertTrue(result.isSuccess()); 577 assertNull(result.getResult()); 578 579 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 580 assertEquals("b", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("B")))); 581 582 // Put with failure 583 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 584 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 585 Bytes.toBytes("a"))) 586 .timeRange(TimeRange.between(0, 100)) 587 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")))); 588 assertFalse(result.isSuccess()); 589 assertNull(result.getResult()); 590 591 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C")))); 592 } 593 } 594 595 @Test(expected = IllegalStateException.class) 596 public void testCheckAndMutateBuilderWithoutCondition() { 597 CheckAndMutate.newBuilder(ROWKEY) 598 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))); 599 } 600 601 @Test 602 public void testCheckAndIncrement() throws Throwable { 603 try (Table table = createTable()) { 604 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"))); 605 606 // CheckAndIncrement with correct value 607 CheckAndMutateResult res = table.checkAndMutate( 608 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")) 609 .build(new Increment(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), 1))); 610 assertTrue(res.isSuccess()); 611 assertEquals(1, Bytes.toLong(res.getResult().getValue(FAMILY, Bytes.toBytes("B")))); 612 613 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 614 assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B")))); 615 616 // CheckAndIncrement with wrong value 617 res = table.checkAndMutate( 618 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("b")) 619 .build(new Increment(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), 1))); 620 assertFalse(res.isSuccess()); 621 assertNull(res.getResult()); 622 623 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 624 assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B")))); 625 626 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"))); 627 628 // CheckAndIncrement with a filter and correct value 629 res = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 630 .ifMatches(new FilterList( 631 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 632 Bytes.toBytes("a")), 633 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL, 634 Bytes.toBytes("c")))) 635 .build(new Increment(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), 2))); 636 assertTrue(res.isSuccess()); 637 assertEquals(3, Bytes.toLong(res.getResult().getValue(FAMILY, Bytes.toBytes("B")))); 638 639 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 640 assertEquals(3, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B")))); 641 642 // CheckAndIncrement with a filter and correct value 643 res = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 644 .ifMatches(new FilterList( 645 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 646 Bytes.toBytes("b")), 647 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL, 648 Bytes.toBytes("d")))) 649 .build(new Increment(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), 2))); 650 assertFalse(res.isSuccess()); 651 assertNull(res.getResult()); 652 653 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 654 assertEquals(3, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B")))); 655 } 656 } 657 658 @Test 659 public void testCheckAndAppend() throws Throwable { 660 try (Table table = createTable()) { 661 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"))); 662 663 // CheckAndAppend with correct value 664 CheckAndMutateResult res = table.checkAndMutate( 665 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")) 666 .build(new Append(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")))); 667 assertTrue(res.isSuccess()); 668 assertEquals("b", Bytes.toString(res.getResult().getValue(FAMILY, Bytes.toBytes("B")))); 669 670 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 671 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 672 673 // CheckAndAppend with correct value 674 res = table.checkAndMutate( 675 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("b")) 676 .build(new Append(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")))); 677 assertFalse(res.isSuccess()); 678 assertNull(res.getResult()); 679 680 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 681 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 682 683 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"))); 684 685 // CheckAndAppend with a filter and correct value 686 res = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 687 .ifMatches(new FilterList( 688 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 689 Bytes.toBytes("a")), 690 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL, 691 Bytes.toBytes("c")))) 692 .build(new Append(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("bb")))); 693 assertTrue(res.isSuccess()); 694 assertEquals("bbb", Bytes.toString(res.getResult().getValue(FAMILY, Bytes.toBytes("B")))); 695 696 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 697 assertEquals("bbb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 698 699 // CheckAndAppend with a filter and wrong value 700 res = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 701 .ifMatches(new FilterList( 702 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 703 Bytes.toBytes("b")), 704 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("C"), CompareOperator.EQUAL, 705 Bytes.toBytes("d")))) 706 .build(new Append(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("bb")))); 707 assertFalse(res.isSuccess()); 708 assertNull(res.getResult()); 709 710 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 711 assertEquals("bbb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 712 } 713 } 714 715 @Test 716 public void testCheckAndRowMutations() throws Throwable { 717 final byte[] q1 = Bytes.toBytes("q1"); 718 final byte[] q2 = Bytes.toBytes("q2"); 719 final byte[] q3 = Bytes.toBytes("q3"); 720 final byte[] q4 = Bytes.toBytes("q4"); 721 final String v1 = "v1"; 722 723 try (Table table = createTable()) { 724 // Initial values 725 table.put(Arrays.asList(new Put(ROWKEY).addColumn(FAMILY, q2, Bytes.toBytes("toBeDeleted")), 726 new Put(ROWKEY).addColumn(FAMILY, q3, Bytes.toBytes(5L)), 727 new Put(ROWKEY).addColumn(FAMILY, q4, Bytes.toBytes("a")))); 728 729 // Do CheckAndRowMutations 730 CheckAndMutate checkAndMutate = CheckAndMutate.newBuilder(ROWKEY).ifNotExists(FAMILY, q1) 731 .build(new RowMutations(ROWKEY).add(Arrays.asList( 732 new Put(ROWKEY).addColumn(FAMILY, q1, Bytes.toBytes(v1)), 733 new Delete(ROWKEY).addColumns(FAMILY, q2), new Increment(ROWKEY).addColumn(FAMILY, q3, 1), 734 new Append(ROWKEY).addColumn(FAMILY, q4, Bytes.toBytes("b"))))); 735 736 CheckAndMutateResult result = table.checkAndMutate(checkAndMutate); 737 assertTrue(result.isSuccess()); 738 assertEquals(6L, Bytes.toLong(result.getResult().getValue(FAMILY, q3))); 739 assertEquals("ab", Bytes.toString(result.getResult().getValue(FAMILY, q4))); 740 741 // Verify the value 742 Result r = table.get(new Get(ROWKEY)); 743 assertEquals(v1, Bytes.toString(r.getValue(FAMILY, q1))); 744 assertNull(r.getValue(FAMILY, q2)); 745 assertEquals(6L, Bytes.toLong(r.getValue(FAMILY, q3))); 746 assertEquals("ab", Bytes.toString(r.getValue(FAMILY, q4))); 747 748 // Do CheckAndRowMutations again 749 checkAndMutate = CheckAndMutate.newBuilder(ROWKEY).ifNotExists(FAMILY, q1) 750 .build(new RowMutations(ROWKEY).add(Arrays.asList(new Delete(ROWKEY).addColumns(FAMILY, q1), 751 new Put(ROWKEY).addColumn(FAMILY, q2, Bytes.toBytes(v1)), 752 new Increment(ROWKEY).addColumn(FAMILY, q3, 1), 753 new Append(ROWKEY).addColumn(FAMILY, q4, Bytes.toBytes("b"))))); 754 755 result = table.checkAndMutate(checkAndMutate); 756 assertFalse(result.isSuccess()); 757 assertNull(result.getResult()); 758 759 // Verify the value 760 r = table.get(new Get(ROWKEY)); 761 assertEquals(v1, Bytes.toString(r.getValue(FAMILY, q1))); 762 assertNull(r.getValue(FAMILY, q2)); 763 assertEquals(6L, Bytes.toLong(r.getValue(FAMILY, q3))); 764 assertEquals("ab", Bytes.toString(r.getValue(FAMILY, q4))); 765 } 766 } 767 768 // Tests for batch version of checkAndMutate 769 770 @Test 771 public void testCheckAndMutateBatch() throws Throwable { 772 try (Table table = createTable()) { 773 table.put( 774 Arrays.asList(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")), 775 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")), 776 new Put(ROWKEY3).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")), 777 new Put(ROWKEY4).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))); 778 779 // Test for Put 780 CheckAndMutate checkAndMutate1 = 781 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")) 782 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("e"))); 783 784 CheckAndMutate checkAndMutate2 = 785 CheckAndMutate.newBuilder(ROWKEY2).ifEquals(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("a")) 786 .build(new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("f"))); 787 788 List<CheckAndMutateResult> results = 789 table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 790 791 assertTrue(results.get(0).isSuccess()); 792 assertNull(results.get(0).getResult()); 793 assertFalse(results.get(1).isSuccess()); 794 assertNull(results.get(1).getResult()); 795 796 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"))); 797 assertEquals("e", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A")))); 798 799 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"))); 800 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 801 802 // Test for Delete 803 checkAndMutate1 = CheckAndMutate.newBuilder(ROWKEY) 804 .ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("e")).build(new Delete(ROWKEY)); 805 806 checkAndMutate2 = CheckAndMutate.newBuilder(ROWKEY2) 807 .ifEquals(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("a")).build(new Delete(ROWKEY2)); 808 809 results = table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 810 811 assertTrue(results.get(0).isSuccess()); 812 assertNull(results.get(0).getResult()); 813 assertFalse(results.get(1).isSuccess()); 814 assertNull(results.get(1).getResult()); 815 816 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A")))); 817 818 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"))); 819 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 820 821 // Test for RowMutations 822 checkAndMutate1 = 823 CheckAndMutate.newBuilder(ROWKEY3).ifEquals(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")) 824 .build(new RowMutations(ROWKEY3) 825 .add( 826 (Mutation) new Put(ROWKEY3).addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("f"))) 827 .add((Mutation) new Delete(ROWKEY3).addColumns(FAMILY, Bytes.toBytes("C")))); 828 829 checkAndMutate2 = 830 CheckAndMutate.newBuilder(ROWKEY4).ifEquals(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("f")) 831 .build(new RowMutations(ROWKEY4) 832 .add( 833 (Mutation) new Put(ROWKEY4).addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("f"))) 834 .add((Mutation) new Delete(ROWKEY4).addColumns(FAMILY, Bytes.toBytes("D")))); 835 836 results = table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 837 838 assertTrue(results.get(0).isSuccess()); 839 assertNull(results.get(0).getResult()); 840 assertFalse(results.get(1).isSuccess()); 841 assertNull(results.get(1).getResult()); 842 843 result = table.get(new Get(ROWKEY3)); 844 assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F")))); 845 assertNull(result.getValue(FAMILY, Bytes.toBytes("D"))); 846 847 result = table.get(new Get(ROWKEY4)); 848 assertNull(result.getValue(FAMILY, Bytes.toBytes("F"))); 849 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 850 } 851 } 852 853 @Test 854 public void testCheckAndMutateBatch2() throws Throwable { 855 try (Table table = createTable()) { 856 table.put( 857 Arrays.asList(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")), 858 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")), 859 new Put(ROWKEY3).addColumn(FAMILY, Bytes.toBytes("C"), 100, Bytes.toBytes("c")), 860 new Put(ROWKEY4).addColumn(FAMILY, Bytes.toBytes("D"), 100, Bytes.toBytes("d")))); 861 862 // Test for ifNotExists() 863 CheckAndMutate checkAndMutate1 = 864 CheckAndMutate.newBuilder(ROWKEY).ifNotExists(FAMILY, Bytes.toBytes("B")) 865 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("e"))); 866 867 CheckAndMutate checkAndMutate2 = 868 CheckAndMutate.newBuilder(ROWKEY2).ifNotExists(FAMILY, Bytes.toBytes("B")) 869 .build(new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("f"))); 870 871 List<CheckAndMutateResult> results = 872 table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 873 874 assertTrue(results.get(0).isSuccess()); 875 assertNull(results.get(0).getResult()); 876 assertFalse(results.get(1).isSuccess()); 877 assertNull(results.get(1).getResult()); 878 879 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"))); 880 assertEquals("e", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A")))); 881 882 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"))); 883 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 884 885 // Test for ifMatches() 886 checkAndMutate1 = CheckAndMutate.newBuilder(ROWKEY) 887 .ifMatches(FAMILY, Bytes.toBytes("A"), CompareOperator.NOT_EQUAL, Bytes.toBytes("a")) 888 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a"))); 889 890 checkAndMutate2 = CheckAndMutate.newBuilder(ROWKEY2) 891 .ifMatches(FAMILY, Bytes.toBytes("B"), CompareOperator.GREATER, Bytes.toBytes("b")) 892 .build(new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("f"))); 893 894 results = table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 895 896 assertTrue(results.get(0).isSuccess()); 897 assertNull(results.get(0).getResult()); 898 assertFalse(results.get(1).isSuccess()); 899 assertNull(results.get(1).getResult()); 900 901 result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"))); 902 assertEquals("a", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A")))); 903 904 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("B"))); 905 assertEquals("b", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 906 907 // Test for timeRange() 908 checkAndMutate1 = 909 CheckAndMutate.newBuilder(ROWKEY3).ifEquals(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")) 910 .timeRange(TimeRange.between(0, 101)) 911 .build(new Put(ROWKEY3).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("e"))); 912 913 checkAndMutate2 = 914 CheckAndMutate.newBuilder(ROWKEY4).ifEquals(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")) 915 .timeRange(TimeRange.between(0, 100)) 916 .build(new Put(ROWKEY4).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("f"))); 917 918 results = table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 919 920 assertTrue(results.get(0).isSuccess()); 921 assertNull(results.get(0).getResult()); 922 assertFalse(results.get(1).isSuccess()); 923 assertNull(results.get(1).getResult()); 924 925 result = table.get(new Get(ROWKEY3).addColumn(FAMILY, Bytes.toBytes("C"))); 926 assertEquals("e", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C")))); 927 928 result = table.get(new Get(ROWKEY4).addColumn(FAMILY, Bytes.toBytes("D"))); 929 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 930 } 931 } 932 933 @Test 934 public void testCheckAndMutateBatchWithFilter() throws Throwable { 935 try (Table table = createTable()) { 936 table.put(Arrays.asList( 937 new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")) 938 .addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")) 939 .addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")), 940 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")) 941 .addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")) 942 .addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("f")))); 943 944 // Test for Put 945 CheckAndMutate checkAndMutate1 = CheckAndMutate.newBuilder(ROWKEY) 946 .ifMatches(new FilterList( 947 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 948 Bytes.toBytes("a")), 949 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 950 Bytes.toBytes("b")))) 951 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("g"))); 952 953 CheckAndMutate checkAndMutate2 = CheckAndMutate.newBuilder(ROWKEY2) 954 .ifMatches(new FilterList( 955 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("D"), CompareOperator.EQUAL, 956 Bytes.toBytes("a")), 957 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("E"), CompareOperator.EQUAL, 958 Bytes.toBytes("b")))) 959 .build(new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("h"))); 960 961 List<CheckAndMutateResult> results = 962 table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 963 964 assertTrue(results.get(0).isSuccess()); 965 assertNull(results.get(0).getResult()); 966 assertFalse(results.get(1).isSuccess()); 967 assertNull(results.get(1).getResult()); 968 969 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"))); 970 assertEquals("g", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C")))); 971 972 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"))); 973 assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F")))); 974 975 // Test for Delete 976 checkAndMutate1 = CheckAndMutate.newBuilder(ROWKEY) 977 .ifMatches(new FilterList( 978 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 979 Bytes.toBytes("a")), 980 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 981 Bytes.toBytes("b")))) 982 .build(new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("C"))); 983 984 checkAndMutate2 = CheckAndMutate.newBuilder(ROWKEY2) 985 .ifMatches(new FilterList( 986 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("D"), CompareOperator.EQUAL, 987 Bytes.toBytes("a")), 988 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("E"), CompareOperator.EQUAL, 989 Bytes.toBytes("b")))) 990 .build(new Delete(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"))); 991 992 results = table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 993 994 assertTrue(results.get(0).isSuccess()); 995 assertNull(results.get(0).getResult()); 996 assertFalse(results.get(1).isSuccess()); 997 assertNull(results.get(1).getResult()); 998 999 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C")))); 1000 1001 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"))); 1002 assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F")))); 1003 1004 // Test for RowMutations 1005 checkAndMutate1 = CheckAndMutate.newBuilder(ROWKEY) 1006 .ifMatches(new FilterList( 1007 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 1008 Bytes.toBytes("a")), 1009 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 1010 Bytes.toBytes("b")))) 1011 .build(new RowMutations(ROWKEY) 1012 .add((Mutation) new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c"))) 1013 .add((Mutation) new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("A")))); 1014 1015 checkAndMutate2 = CheckAndMutate.newBuilder(ROWKEY2) 1016 .ifMatches(new FilterList( 1017 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("D"), CompareOperator.EQUAL, 1018 Bytes.toBytes("a")), 1019 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("E"), CompareOperator.EQUAL, 1020 Bytes.toBytes("b")))) 1021 .build(new RowMutations(ROWKEY2) 1022 .add( 1023 (Mutation) new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("g"))) 1024 .add((Mutation) new Delete(ROWKEY2).addColumns(FAMILY, Bytes.toBytes("D")))); 1025 1026 results = table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 1027 1028 assertTrue(results.get(0).isSuccess()); 1029 assertNull(results.get(0).getResult()); 1030 assertFalse(results.get(1).isSuccess()); 1031 assertNull(results.get(1).getResult()); 1032 1033 result = table.get(new Get(ROWKEY)); 1034 assertNull(result.getValue(FAMILY, Bytes.toBytes("A"))); 1035 assertEquals("c", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C")))); 1036 1037 result = table.get(new Get(ROWKEY2)); 1038 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 1039 assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F")))); 1040 } 1041 } 1042 1043 @Test 1044 public void testCheckAndMutateBatchWithFilterAndTimeRange() throws Throwable { 1045 try (Table table = createTable()) { 1046 table.put(Arrays.asList( 1047 new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a")) 1048 .addColumn(FAMILY, Bytes.toBytes("B"), 100, Bytes.toBytes("b")) 1049 .addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")), 1050 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("D"), 100, Bytes.toBytes("d")) 1051 .addColumn(FAMILY, Bytes.toBytes("E"), 100, Bytes.toBytes("e")) 1052 .addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("f")))); 1053 1054 CheckAndMutate checkAndMutate1 = CheckAndMutate.newBuilder(ROWKEY) 1055 .ifMatches(new FilterList( 1056 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 1057 Bytes.toBytes("a")), 1058 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 1059 Bytes.toBytes("b")))) 1060 .timeRange(TimeRange.between(0, 101)) 1061 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("g"))); 1062 1063 CheckAndMutate checkAndMutate2 = CheckAndMutate.newBuilder(ROWKEY2) 1064 .ifMatches(new FilterList( 1065 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("D"), CompareOperator.EQUAL, 1066 Bytes.toBytes("d")), 1067 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("E"), CompareOperator.EQUAL, 1068 Bytes.toBytes("e")))) 1069 .timeRange(TimeRange.between(0, 100)) 1070 .build(new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("h"))); 1071 1072 List<CheckAndMutateResult> results = 1073 table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 1074 1075 assertTrue(results.get(0).isSuccess()); 1076 assertNull(results.get(0).getResult()); 1077 assertFalse(results.get(1).isSuccess()); 1078 assertNull(results.get(1).getResult()); 1079 1080 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"))); 1081 assertEquals("g", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C")))); 1082 1083 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"))); 1084 assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F")))); 1085 } 1086 } 1087 1088 @Test 1089 public void testCheckAndIncrementBatch() throws Throwable { 1090 try (Table table = createTable()) { 1091 table.put(Arrays.asList( 1092 new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")).addColumn(FAMILY, 1093 Bytes.toBytes("B"), Bytes.toBytes(0L)), 1094 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")).addColumn(FAMILY, 1095 Bytes.toBytes("D"), Bytes.toBytes(0L)))); 1096 1097 // CheckAndIncrement with correct value 1098 CheckAndMutate checkAndMutate1 = 1099 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")) 1100 .build(new Increment(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), 1)); 1101 1102 // CheckAndIncrement with wrong value 1103 CheckAndMutate checkAndMutate2 = 1104 CheckAndMutate.newBuilder(ROWKEY2).ifEquals(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("d")) 1105 .build(new Increment(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("D"), 1)); 1106 1107 List<CheckAndMutateResult> results = 1108 table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 1109 1110 assertTrue(results.get(0).isSuccess()); 1111 assertEquals(1, 1112 Bytes.toLong(results.get(0).getResult().getValue(FAMILY, Bytes.toBytes("B")))); 1113 assertFalse(results.get(1).isSuccess()); 1114 assertNull(results.get(1).getResult()); 1115 1116 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 1117 assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B")))); 1118 1119 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("D"))); 1120 assertEquals(0, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("D")))); 1121 } 1122 } 1123 1124 @Test 1125 public void testCheckAndAppendBatch() throws Throwable { 1126 try (Table table = createTable()) { 1127 table.put(Arrays.asList( 1128 new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")).addColumn(FAMILY, 1129 Bytes.toBytes("B"), Bytes.toBytes("b")), 1130 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")).addColumn(FAMILY, 1131 Bytes.toBytes("D"), Bytes.toBytes("d")))); 1132 1133 // CheckAndAppend with correct value 1134 CheckAndMutate checkAndMutate1 = 1135 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")) 1136 .build(new Append(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b"))); 1137 1138 // CheckAndAppend with wrong value 1139 CheckAndMutate checkAndMutate2 = 1140 CheckAndMutate.newBuilder(ROWKEY2).ifEquals(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("d")) 1141 .build(new Append(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))); 1142 1143 List<CheckAndMutateResult> results = 1144 table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 1145 1146 assertTrue(results.get(0).isSuccess()); 1147 assertEquals("bb", 1148 Bytes.toString(results.get(0).getResult().getValue(FAMILY, Bytes.toBytes("B")))); 1149 assertFalse(results.get(1).isSuccess()); 1150 assertNull(results.get(1).getResult()); 1151 1152 Result result = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 1153 assertEquals("bb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B")))); 1154 1155 result = table.get(new Get(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("D"))); 1156 assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 1157 } 1158 } 1159 1160 @Test 1161 public void testCheckAndRowMutationsBatch() throws Throwable { 1162 try (Table table = createTable()) { 1163 table.put(Arrays.asList( 1164 new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")) 1165 .addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes(1L)) 1166 .addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")), 1167 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("f")) 1168 .addColumn(FAMILY, Bytes.toBytes("G"), Bytes.toBytes(1L)) 1169 .addColumn(FAMILY, Bytes.toBytes("H"), Bytes.toBytes("h")))); 1170 1171 // CheckAndIncrement with correct value 1172 CheckAndMutate checkAndMutate1 = 1173 CheckAndMutate.newBuilder(ROWKEY).ifEquals(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")) 1174 .build(new RowMutations(ROWKEY).add( 1175 Arrays.asList(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")), 1176 new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("B")), 1177 new Increment(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), 1L), 1178 new Append(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))))); 1179 1180 // CheckAndIncrement with wrong value 1181 CheckAndMutate checkAndMutate2 = 1182 CheckAndMutate.newBuilder(ROWKEY2).ifEquals(FAMILY, Bytes.toBytes("F"), Bytes.toBytes("a")) 1183 .build(new RowMutations(ROWKEY2).add(Arrays.asList( 1184 new Put(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")), 1185 new Delete(ROWKEY2).addColumns(FAMILY, Bytes.toBytes("F")), 1186 new Increment(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("G"), 1L), 1187 new Append(ROWKEY2).addColumn(FAMILY, Bytes.toBytes("H"), Bytes.toBytes("h"))))); 1188 1189 List<CheckAndMutateResult> results = 1190 table.checkAndMutate(Arrays.asList(checkAndMutate1, checkAndMutate2)); 1191 1192 assertTrue(results.get(0).isSuccess()); 1193 assertEquals(2, 1194 Bytes.toLong(results.get(0).getResult().getValue(FAMILY, Bytes.toBytes("C")))); 1195 assertEquals("dd", 1196 Bytes.toString(results.get(0).getResult().getValue(FAMILY, Bytes.toBytes("D")))); 1197 1198 assertFalse(results.get(1).isSuccess()); 1199 assertNull(results.get(1).getResult()); 1200 1201 Result result = table.get(new Get(ROWKEY)); 1202 assertEquals("a", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A")))); 1203 assertNull(result.getValue(FAMILY, Bytes.toBytes("B"))); 1204 assertEquals(2, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("C")))); 1205 assertEquals("dd", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D")))); 1206 1207 result = table.get(new Get(ROWKEY2)); 1208 assertNull(result.getValue(FAMILY, Bytes.toBytes("E"))); 1209 assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F")))); 1210 assertEquals(1, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("G")))); 1211 assertEquals("h", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("H")))); 1212 } 1213 } 1214 1215 @Test 1216 public void testCheckAndMutateForNull() throws Exception { 1217 byte[] qualifier = Bytes.toBytes("Q"); 1218 try (Table table = createTable()) { 1219 byte[] row1 = Bytes.toBytes("testRow1"); 1220 Put put = new Put(row1); 1221 put.addColumn(FAMILY, qualifier, Bytes.toBytes("v0")); 1222 table.put(put); 1223 assertEquals("v0", Bytes.toString( 1224 table.get(new Get(row1).addColumn(FAMILY, qualifier)).getValue(FAMILY, qualifier))); 1225 1226 CheckAndMutate checkAndMutate1 = CheckAndMutate.newBuilder(row1) 1227 .ifMatches(FAMILY, qualifier, CompareOperator.NOT_EQUAL, new byte[] {}) 1228 .build(new Put(row1).addColumn(FAMILY, qualifier, Bytes.toBytes("v1"))); 1229 table.checkAndMutate(checkAndMutate1); 1230 assertEquals("v1", Bytes.toString( 1231 table.get(new Get(row1).addColumn(FAMILY, qualifier)).getValue(FAMILY, qualifier))); 1232 1233 byte[] row2 = Bytes.toBytes("testRow2"); 1234 put = new Put(row2); 1235 put.addColumn(FAMILY, qualifier, new byte[] {}); 1236 table.put(put); 1237 assertEquals(0, 1238 table.get(new Get(row2).addColumn(FAMILY, qualifier)).getValue(FAMILY, qualifier).length); 1239 1240 CheckAndMutate checkAndMutate2 = CheckAndMutate.newBuilder(row2) 1241 .ifMatches(FAMILY, qualifier, CompareOperator.EQUAL, new byte[] {}) 1242 .build(new Put(row2).addColumn(FAMILY, qualifier, Bytes.toBytes("v2"))); 1243 table.checkAndMutate(checkAndMutate2); 1244 assertEquals("v2", Bytes.toString( 1245 table.get(new Get(row2).addColumn(FAMILY, qualifier)).getValue(FAMILY, qualifier))); 1246 1247 byte[] row3 = Bytes.toBytes("testRow3"); 1248 put = new Put(row3).addColumn(FAMILY, qualifier, Bytes.toBytes("v0")); 1249 assertNull(table.get(new Get(row3).addColumn(FAMILY, qualifier)).getValue(FAMILY, qualifier)); 1250 CheckAndMutate checkAndMutate3 = CheckAndMutate.newBuilder(row3) 1251 .ifMatches(FAMILY, qualifier, CompareOperator.NOT_EQUAL, new byte[] {}).build(put); 1252 table.checkAndMutate(checkAndMutate3); 1253 assertNull(table.get(new Get(row3).addColumn(FAMILY, qualifier)).getValue(FAMILY, qualifier)); 1254 1255 CheckAndMutate checkAndMutate4 = CheckAndMutate.newBuilder(row3) 1256 .ifMatches(FAMILY, qualifier, CompareOperator.EQUAL, new byte[] {}).build(put); 1257 table.checkAndMutate(checkAndMutate4); 1258 assertEquals("v0", Bytes.toString( 1259 table.get(new Get(row3).addColumn(FAMILY, qualifier)).getValue(FAMILY, qualifier))); 1260 } 1261 } 1262}