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