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.hamcrest.CoreMatchers.instanceOf; 021import static org.hamcrest.MatcherAssert.assertThat; 022import static org.junit.jupiter.api.Assertions.assertEquals; 023import static org.junit.jupiter.api.Assertions.assertFalse; 024import static org.junit.jupiter.api.Assertions.assertNull; 025import static org.junit.jupiter.api.Assertions.assertThrows; 026import static org.junit.jupiter.api.Assertions.assertTrue; 027import static org.junit.jupiter.api.Assertions.fail; 028 029import java.io.IOException; 030import java.util.Arrays; 031import java.util.Collections; 032import java.util.List; 033import org.apache.hadoop.hbase.CompareOperator; 034import org.apache.hadoop.hbase.HBaseTestingUtil; 035import org.apache.hadoop.hbase.TableName; 036import org.apache.hadoop.hbase.filter.BinaryComparator; 037import org.apache.hadoop.hbase.filter.FamilyFilter; 038import org.apache.hadoop.hbase.filter.FilterList; 039import org.apache.hadoop.hbase.filter.QualifierFilter; 040import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 041import org.apache.hadoop.hbase.filter.TimestampsFilter; 042import org.apache.hadoop.hbase.io.TimeRange; 043import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException; 044import org.apache.hadoop.hbase.testclassification.ClientTests; 045import org.apache.hadoop.hbase.testclassification.MediumTests; 046import org.apache.hadoop.hbase.util.Bytes; 047import org.junit.jupiter.api.AfterAll; 048import org.junit.jupiter.api.BeforeAll; 049import org.junit.jupiter.api.BeforeEach; 050import org.junit.jupiter.api.Tag; 051import org.junit.jupiter.api.Test; 052import org.junit.jupiter.api.TestInfo; 053 054@Tag(MediumTests.TAG) 055@Tag(ClientTests.TAG) 056public class TestCheckAndMutate { 057 058 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 059 private static final byte[] ROWKEY = Bytes.toBytes("12345"); 060 private static final byte[] ROWKEY2 = Bytes.toBytes("67890"); 061 private static final byte[] ROWKEY3 = Bytes.toBytes("abcde"); 062 private static final byte[] ROWKEY4 = Bytes.toBytes("fghij"); 063 private static final byte[] FAMILY = Bytes.toBytes("cf"); 064 private String methodName; 065 066 @BeforeAll 067 public static void setUpBeforeClass() throws Exception { 068 TEST_UTIL.startMiniCluster(); 069 } 070 071 @AfterAll 072 public static void tearDownAfterClass() throws Exception { 073 TEST_UTIL.shutdownMiniCluster(); 074 } 075 076 @BeforeEach 077 public void setUp(TestInfo testInfo) { 078 this.methodName = testInfo.getTestMethod().get().getName(); 079 } 080 081 private Table createTable() throws IOException, InterruptedException { 082 final TableName tableName = TableName.valueOf(methodName); 083 Table table = TEST_UTIL.createTable(tableName, FAMILY); 084 TEST_UTIL.waitTableAvailable(tableName.getName(), 5000); 085 return table; 086 } 087 088 private void putOneRow(Table table) throws IOException { 089 Put put = new Put(ROWKEY); 090 put.addColumn(FAMILY, Bytes.toBytes("A"), Bytes.toBytes("a")); 091 put.addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")); 092 put.addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")); 093 table.put(put); 094 } 095 096 private void getOneRowAndAssertAllExist(final Table table) throws IOException { 097 Get get = new Get(ROWKEY); 098 Result result = table.get(get); 099 assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a"), 100 "Column A value should be a"); 101 assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b"), 102 "Column B value should be b"); 103 assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C"))).equals("c"), 104 "Column C value should be c"); 105 } 106 107 private void getOneRowAndAssertAllButCExist(final Table table) throws IOException { 108 Get get = new Get(ROWKEY); 109 Result result = table.get(get); 110 assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a"), 111 "Column A value should be a"); 112 assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b"), 113 "Column B value should be b"); 114 assertTrue(result.getValue(FAMILY, Bytes.toBytes("C")) == null, "Column C should not exist"); 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 (NoSuchColumnFamilyException e) { 165 // expected 166 } catch (RetriesExhaustedException e) { 167 assertThat(e.getCause(), instanceOf(NoSuchColumnFamilyException.class)); 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 363 @Deprecated 364 public void testCheckAndMutateWithoutConditionForOldApi() throws Throwable { 365 try (Table table = createTable()) { 366 assertThrows(NullPointerException.class, () -> 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 (NoSuchColumnFamilyException e) { 398 // expected 399 } catch (RetriesExhaustedException e) { 400 assertThat(e.getCause(), instanceOf(NoSuchColumnFamilyException.class)); 401 } 402 } 403 } 404 405 @Test 406 public void testCheckAndMutateWithSingleFilter() throws Throwable { 407 try (Table table = createTable()) { 408 // put one row 409 putOneRow(table); 410 // get row back and assert the values 411 getOneRowAndAssertAllExist(table); 412 413 // Put with success 414 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 415 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 416 Bytes.toBytes("a"))) 417 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))); 418 assertTrue(result.isSuccess()); 419 assertNull(result.getResult()); 420 421 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 422 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 423 424 // Put with failure 425 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 426 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 427 Bytes.toBytes("b"))) 428 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))); 429 assertFalse(result.isSuccess()); 430 assertNull(result.getResult()); 431 432 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E")))); 433 434 // Delete with success 435 result = table.checkAndMutate(CheckAndMutate 436 .newBuilder(ROWKEY).ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), 437 CompareOperator.EQUAL, Bytes.toBytes("a"))) 438 .build(new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("D")))); 439 assertTrue(result.isSuccess()); 440 assertNull(result.getResult()); 441 442 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D")))); 443 444 // Mutate with success 445 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 446 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 447 Bytes.toBytes("b"))) 448 .build(new RowMutations(ROWKEY) 449 .add((Mutation) new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))) 450 .add((Mutation) new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("A"))))); 451 assertTrue(result.isSuccess()); 452 assertNull(result.getResult()); 453 454 r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 455 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 456 457 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A")))); 458 } 459 } 460 461 @Test 462 public void testCheckAndMutateWithMultipleFilters() throws Throwable { 463 try (Table table = createTable()) { 464 // put one row 465 putOneRow(table); 466 // get row back and assert the values 467 getOneRowAndAssertAllExist(table); 468 469 // Put with success 470 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 471 .ifMatches(new FilterList( 472 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 473 Bytes.toBytes("a")), 474 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 475 Bytes.toBytes("b")))) 476 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")))); 477 assertTrue(result.isSuccess()); 478 assertNull(result.getResult()); 479 480 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 481 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 482 483 // Put with failure 484 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 485 .ifMatches(new FilterList( 486 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 487 Bytes.toBytes("a")), 488 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 489 Bytes.toBytes("c")))) 490 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E"), Bytes.toBytes("e")))); 491 assertFalse(result.isSuccess()); 492 assertNull(result.getResult()); 493 494 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("E")))); 495 496 // Delete with success 497 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 498 .ifMatches(new FilterList( 499 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 500 Bytes.toBytes("a")), 501 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 502 Bytes.toBytes("b")))) 503 .build(new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("D")))); 504 assertTrue(result.isSuccess()); 505 assertNull(result.getResult()); 506 507 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D")))); 508 509 // Mutate with success 510 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 511 .ifMatches(new FilterList( 512 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 513 Bytes.toBytes("a")), 514 new SingleColumnValueFilter(FAMILY, Bytes.toBytes("B"), CompareOperator.EQUAL, 515 Bytes.toBytes("b")))) 516 .build(new RowMutations(ROWKEY) 517 .add((Mutation) new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))) 518 .add((Mutation) new Delete(ROWKEY).addColumns(FAMILY, Bytes.toBytes("A"))))); 519 assertTrue(result.isSuccess()); 520 assertNull(result.getResult()); 521 522 r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"))); 523 assertEquals("d", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("D")))); 524 525 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A")))); 526 } 527 } 528 529 @Test 530 public void testCheckAndMutateWithTimestampFilter() throws Throwable { 531 try (Table table = createTable()) { 532 // Put with specifying the timestamp 533 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a"))); 534 535 // Put with success 536 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 537 .ifMatches( 538 new FilterList(new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(FAMILY)), 539 new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("A"))), 540 new TimestampsFilter(Collections.singletonList(100L)))) 541 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")))); 542 assertTrue(result.isSuccess()); 543 assertNull(result.getResult()); 544 545 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 546 assertEquals("b", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("B")))); 547 548 // Put with failure 549 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 550 .ifMatches( 551 new FilterList(new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(FAMILY)), 552 new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("A"))), 553 new TimestampsFilter(Collections.singletonList(101L)))) 554 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")))); 555 assertFalse(result.isSuccess()); 556 assertNull(result.getResult()); 557 558 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C")))); 559 } 560 } 561 562 @Test 563 public void testCheckAndMutateWithFilterAndTimeRange() throws Throwable { 564 try (Table table = createTable()) { 565 // Put with specifying the timestamp 566 table.put(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("A"), 100, Bytes.toBytes("a"))); 567 568 // Put with success 569 CheckAndMutateResult result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 570 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 571 Bytes.toBytes("a"))) 572 .timeRange(TimeRange.between(0, 101)) 573 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"), Bytes.toBytes("b")))); 574 assertTrue(result.isSuccess()); 575 assertNull(result.getResult()); 576 577 Result r = table.get(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("B"))); 578 assertEquals("b", Bytes.toString(r.getValue(FAMILY, Bytes.toBytes("B")))); 579 580 // Put with failure 581 result = table.checkAndMutate(CheckAndMutate.newBuilder(ROWKEY) 582 .ifMatches(new SingleColumnValueFilter(FAMILY, Bytes.toBytes("A"), CompareOperator.EQUAL, 583 Bytes.toBytes("a"))) 584 .timeRange(TimeRange.between(0, 100)) 585 .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C"), Bytes.toBytes("c")))); 586 assertFalse(result.isSuccess()); 587 assertNull(result.getResult()); 588 589 assertFalse(table.exists(new Get(ROWKEY).addColumn(FAMILY, Bytes.toBytes("C")))); 590 } 591 } 592 593 @Test 594 public void testCheckAndMutateBuilderWithoutCondition() { 595 CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(ROWKEY); 596 assertThrows(IllegalStateException.class, () -> { 597 builder.build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))); 598 }); 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}