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.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023 024import java.util.Arrays; 025import org.apache.hadoop.hbase.CompareOperator; 026import org.apache.hadoop.hbase.filter.FilterList; 027import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 028import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; 029import org.apache.hadoop.hbase.util.Bytes; 030import org.junit.jupiter.api.TestTemplate; 031 032import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 033import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto; 034import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.MutationType; 035import org.apache.hadoop.hbase.shaded.protobuf.generated.MultiRowMutationProtos.MultiRowMutationService; 036import org.apache.hadoop.hbase.shaded.protobuf.generated.MultiRowMutationProtos.MutateRowsRequest; 037import org.apache.hadoop.hbase.shaded.protobuf.generated.MultiRowMutationProtos.MutateRowsResponse; 038 039public class FromClientSideTestMultiRowMutation extends FromClientSideTestBase { 040 041 protected FromClientSideTestMultiRowMutation(Class<? extends ConnectionRegistry> registryImpl, 042 int numHedgedReqs) { 043 super(registryImpl, numHedgedReqs); 044 } 045 046 @TestTemplate 047 public void testMultiRowMutation() throws Exception { 048 final byte[] ROW1 = Bytes.toBytes("testRow1"); 049 final byte[] ROW2 = Bytes.toBytes("testRow2"); 050 final byte[] ROW3 = Bytes.toBytes("testRow3"); 051 TEST_UTIL.createTable(tableName, FAMILY); 052 try (Connection conn = getConnection(); Table t = conn.getTable(tableName)) { 053 // Add initial data 054 t.batch(Arrays.asList(new Put(ROW1).addColumn(FAMILY, QUALIFIER, VALUE), 055 new Put(ROW2).addColumn(FAMILY, QUALIFIER, Bytes.toBytes(1L)), 056 new Put(ROW3).addColumn(FAMILY, QUALIFIER, VALUE)), new Object[3]); 057 058 // Execute MultiRowMutation 059 Put put = new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE); 060 MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, put); 061 062 Delete delete = new Delete(ROW1); 063 MutationProto m2 = ProtobufUtil.toMutation(MutationType.DELETE, delete); 064 065 Increment increment = new Increment(ROW2).addColumn(FAMILY, QUALIFIER, 1L); 066 MutationProto m3 = ProtobufUtil.toMutation(MutationType.INCREMENT, increment); 067 068 Append append = new Append(ROW3).addColumn(FAMILY, QUALIFIER, VALUE); 069 MutationProto m4 = ProtobufUtil.toMutation(MutationType.APPEND, append); 070 071 MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder(); 072 mrmBuilder.addMutationRequest(m1); 073 mrmBuilder.addMutationRequest(m2); 074 mrmBuilder.addMutationRequest(m3); 075 mrmBuilder.addMutationRequest(m4); 076 077 CoprocessorRpcChannel channel = t.coprocessorService(ROW); 078 MultiRowMutationService.BlockingInterface service = 079 MultiRowMutationService.newBlockingStub(channel); 080 MutateRowsResponse response = service.mutateRows(null, mrmBuilder.build()); 081 082 // Assert 083 assertTrue(response.getProcessed()); 084 085 Result r = t.get(new Get(ROW)); 086 assertEquals(Bytes.toString(VALUE), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 087 088 r = t.get(new Get(ROW1)); 089 assertTrue(r.isEmpty()); 090 091 r = t.get(new Get(ROW2)); 092 assertEquals(2L, Bytes.toLong(r.getValue(FAMILY, QUALIFIER))); 093 094 r = t.get(new Get(ROW3)); 095 assertEquals(Bytes.toString(VALUE) + Bytes.toString(VALUE), 096 Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 097 } 098 } 099 100 @TestTemplate 101 public void testMultiRowMutationWithSingleConditionWhenConditionMatches() throws Exception { 102 final byte[] ROW1 = Bytes.toBytes("testRow1"); 103 final byte[] ROW2 = Bytes.toBytes("testRow2"); 104 final byte[] VALUE1 = Bytes.toBytes("testValue1"); 105 final byte[] VALUE2 = Bytes.toBytes("testValue2"); 106 TEST_UTIL.createTable(tableName, FAMILY); 107 try (Connection conn = getConnection(); Table t = conn.getTable(tableName)) { 108 // Add initial data 109 t.put(new Put(ROW2).addColumn(FAMILY, QUALIFIER, VALUE2)); 110 111 // Execute MultiRowMutation with conditions 112 Put put1 = new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE); 113 MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, put1); 114 Put put2 = new Put(ROW1).addColumn(FAMILY, QUALIFIER, VALUE1); 115 MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, put2); 116 Delete delete = new Delete(ROW2); 117 MutationProto m3 = ProtobufUtil.toMutation(MutationType.DELETE, delete); 118 119 MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder(); 120 mrmBuilder.addMutationRequest(m1); 121 mrmBuilder.addMutationRequest(m2); 122 mrmBuilder.addMutationRequest(m3); 123 mrmBuilder.addCondition( 124 ProtobufUtil.toCondition(ROW2, FAMILY, QUALIFIER, CompareOperator.EQUAL, VALUE2, null)); 125 126 CoprocessorRpcChannel channel = t.coprocessorService(ROW); 127 MultiRowMutationService.BlockingInterface service = 128 MultiRowMutationService.newBlockingStub(channel); 129 MutateRowsResponse response = service.mutateRows(null, mrmBuilder.build()); 130 131 // Assert 132 assertTrue(response.getProcessed()); 133 134 Result r = t.get(new Get(ROW)); 135 assertEquals(Bytes.toString(VALUE), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 136 137 r = t.get(new Get(ROW1)); 138 assertEquals(Bytes.toString(VALUE1), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 139 140 r = t.get(new Get(ROW2)); 141 assertTrue(r.isEmpty()); 142 } 143 } 144 145 @TestTemplate 146 public void testMultiRowMutationWithSingleConditionWhenConditionNotMatch() throws Exception { 147 final byte[] ROW1 = Bytes.toBytes("testRow1"); 148 final byte[] ROW2 = Bytes.toBytes("testRow2"); 149 final byte[] VALUE1 = Bytes.toBytes("testValue1"); 150 final byte[] VALUE2 = Bytes.toBytes("testValue2"); 151 TEST_UTIL.createTable(tableName, FAMILY); 152 try (Connection conn = getConnection(); Table t = conn.getTable(tableName)) { 153 // Add initial data 154 t.put(new Put(ROW2).addColumn(FAMILY, QUALIFIER, VALUE2)); 155 156 // Execute MultiRowMutation with conditions 157 Put put1 = new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE); 158 MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, put1); 159 Put put2 = new Put(ROW1).addColumn(FAMILY, QUALIFIER, VALUE1); 160 MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, put2); 161 Delete delete = new Delete(ROW2); 162 MutationProto m3 = ProtobufUtil.toMutation(MutationType.DELETE, delete); 163 164 MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder(); 165 mrmBuilder.addMutationRequest(m1); 166 mrmBuilder.addMutationRequest(m2); 167 mrmBuilder.addMutationRequest(m3); 168 mrmBuilder.addCondition( 169 ProtobufUtil.toCondition(ROW2, FAMILY, QUALIFIER, CompareOperator.EQUAL, VALUE1, null)); 170 171 CoprocessorRpcChannel channel = t.coprocessorService(ROW); 172 MultiRowMutationService.BlockingInterface service = 173 MultiRowMutationService.newBlockingStub(channel); 174 MutateRowsResponse response = service.mutateRows(null, mrmBuilder.build()); 175 176 // Assert 177 assertFalse(response.getProcessed()); 178 179 Result r = t.get(new Get(ROW)); 180 assertTrue(r.isEmpty()); 181 182 r = t.get(new Get(ROW1)); 183 assertTrue(r.isEmpty()); 184 185 r = t.get(new Get(ROW2)); 186 assertEquals(Bytes.toString(VALUE2), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 187 } 188 } 189 190 @TestTemplate 191 public void testMultiRowMutationWithMultipleConditionsWhenConditionsMatch() throws Exception { 192 final byte[] ROW1 = Bytes.toBytes("testRow1"); 193 final byte[] ROW2 = Bytes.toBytes("testRow2"); 194 final byte[] VALUE1 = Bytes.toBytes("testValue1"); 195 final byte[] VALUE2 = Bytes.toBytes("testValue2"); 196 TEST_UTIL.createTable(tableName, FAMILY); 197 try (Connection conn = getConnection(); Table t = conn.getTable(tableName)) { 198 // Add initial data 199 t.put(new Put(ROW2).addColumn(FAMILY, QUALIFIER, VALUE2)); 200 201 // Execute MultiRowMutation with conditions 202 Put put1 = new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE); 203 MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, put1); 204 Put put2 = new Put(ROW1).addColumn(FAMILY, QUALIFIER, VALUE1); 205 MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, put2); 206 Delete delete = new Delete(ROW2); 207 MutationProto m3 = ProtobufUtil.toMutation(MutationType.DELETE, delete); 208 209 MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder(); 210 mrmBuilder.addMutationRequest(m1); 211 mrmBuilder.addMutationRequest(m2); 212 mrmBuilder.addMutationRequest(m3); 213 mrmBuilder.addCondition( 214 ProtobufUtil.toCondition(ROW, FAMILY, QUALIFIER, CompareOperator.EQUAL, null, null)); 215 mrmBuilder.addCondition( 216 ProtobufUtil.toCondition(ROW2, FAMILY, QUALIFIER, CompareOperator.EQUAL, VALUE2, null)); 217 218 CoprocessorRpcChannel channel = t.coprocessorService(ROW); 219 MultiRowMutationService.BlockingInterface service = 220 MultiRowMutationService.newBlockingStub(channel); 221 MutateRowsResponse response = service.mutateRows(null, mrmBuilder.build()); 222 223 // Assert 224 assertTrue(response.getProcessed()); 225 226 Result r = t.get(new Get(ROW)); 227 assertEquals(Bytes.toString(VALUE), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 228 229 r = t.get(new Get(ROW1)); 230 assertEquals(Bytes.toString(VALUE1), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 231 232 r = t.get(new Get(ROW2)); 233 assertTrue(r.isEmpty()); 234 } 235 } 236 237 @TestTemplate 238 public void testMultiRowMutationWithMultipleConditionsWhenConditionsNotMatch() throws Exception { 239 final byte[] ROW1 = Bytes.toBytes("testRow1"); 240 final byte[] ROW2 = Bytes.toBytes("testRow2"); 241 final byte[] VALUE1 = Bytes.toBytes("testValue1"); 242 final byte[] VALUE2 = Bytes.toBytes("testValue2"); 243 TEST_UTIL.createTable(tableName, FAMILY); 244 try (Connection conn = getConnection(); Table t = conn.getTable(tableName)) { 245 // Add initial data 246 t.put(new Put(ROW2).addColumn(FAMILY, QUALIFIER, VALUE2)); 247 248 // Execute MultiRowMutation with conditions 249 Put put1 = new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE); 250 MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, put1); 251 Put put2 = new Put(ROW1).addColumn(FAMILY, QUALIFIER, VALUE1); 252 MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, put2); 253 Delete delete = new Delete(ROW2); 254 MutationProto m3 = ProtobufUtil.toMutation(MutationType.DELETE, delete); 255 256 MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder(); 257 mrmBuilder.addMutationRequest(m1); 258 mrmBuilder.addMutationRequest(m2); 259 mrmBuilder.addMutationRequest(m3); 260 mrmBuilder.addCondition( 261 ProtobufUtil.toCondition(ROW1, FAMILY, QUALIFIER, CompareOperator.EQUAL, null, null)); 262 mrmBuilder.addCondition( 263 ProtobufUtil.toCondition(ROW2, FAMILY, QUALIFIER, CompareOperator.EQUAL, VALUE1, null)); 264 265 CoprocessorRpcChannel channel = t.coprocessorService(ROW); 266 MultiRowMutationService.BlockingInterface service = 267 MultiRowMutationService.newBlockingStub(channel); 268 MutateRowsResponse response = service.mutateRows(null, mrmBuilder.build()); 269 270 // Assert 271 assertFalse(response.getProcessed()); 272 273 Result r = t.get(new Get(ROW)); 274 assertTrue(r.isEmpty()); 275 276 r = t.get(new Get(ROW1)); 277 assertTrue(r.isEmpty()); 278 279 r = t.get(new Get(ROW2)); 280 assertEquals(Bytes.toString(VALUE2), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 281 } 282 } 283 284 @TestTemplate 285 public void testMultiRowMutationWithFilterConditionWhenConditionMatches() throws Exception { 286 final byte[] ROW1 = Bytes.toBytes("testRow1"); 287 final byte[] ROW2 = Bytes.toBytes("testRow2"); 288 final byte[] QUALIFIER2 = Bytes.toBytes("testQualifier2"); 289 final byte[] VALUE1 = Bytes.toBytes("testValue1"); 290 final byte[] VALUE2 = Bytes.toBytes("testValue2"); 291 final byte[] VALUE3 = Bytes.toBytes("testValue3"); 292 TEST_UTIL.createTable(tableName, FAMILY); 293 try (Connection conn = getConnection(); Table t = conn.getTable(tableName)) { 294 // Add initial data 295 t.put( 296 new Put(ROW2).addColumn(FAMILY, QUALIFIER, VALUE2).addColumn(FAMILY, QUALIFIER2, VALUE3)); 297 298 // Execute MultiRowMutation with conditions 299 Put put1 = new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE); 300 MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, put1); 301 Put put2 = new Put(ROW1).addColumn(FAMILY, QUALIFIER, VALUE1); 302 MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, put2); 303 Delete delete = new Delete(ROW2); 304 MutationProto m3 = ProtobufUtil.toMutation(MutationType.DELETE, delete); 305 306 MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder(); 307 mrmBuilder.addMutationRequest(m1); 308 mrmBuilder.addMutationRequest(m2); 309 mrmBuilder.addMutationRequest(m3); 310 mrmBuilder.addCondition(ProtobufUtil.toCondition(ROW2, 311 new FilterList( 312 new SingleColumnValueFilter(FAMILY, QUALIFIER, CompareOperator.EQUAL, VALUE2), 313 new SingleColumnValueFilter(FAMILY, QUALIFIER2, CompareOperator.EQUAL, VALUE3)), 314 null)); 315 316 CoprocessorRpcChannel channel = t.coprocessorService(ROW); 317 MultiRowMutationService.BlockingInterface service = 318 MultiRowMutationService.newBlockingStub(channel); 319 MutateRowsResponse response = service.mutateRows(null, mrmBuilder.build()); 320 321 // Assert 322 assertTrue(response.getProcessed()); 323 324 Result r = t.get(new Get(ROW)); 325 assertEquals(Bytes.toString(VALUE), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 326 327 r = t.get(new Get(ROW1)); 328 assertEquals(Bytes.toString(VALUE1), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 329 330 r = t.get(new Get(ROW2)); 331 assertTrue(r.isEmpty()); 332 } 333 } 334 335 @TestTemplate 336 public void testMultiRowMutationWithFilterConditionWhenConditionNotMatch() throws Exception { 337 final byte[] ROW1 = Bytes.toBytes("testRow1"); 338 final byte[] ROW2 = Bytes.toBytes("testRow2"); 339 final byte[] QUALIFIER2 = Bytes.toBytes("testQualifier2"); 340 final byte[] VALUE1 = Bytes.toBytes("testValue1"); 341 final byte[] VALUE2 = Bytes.toBytes("testValue2"); 342 final byte[] VALUE3 = Bytes.toBytes("testValue3"); 343 TEST_UTIL.createTable(tableName, FAMILY); 344 try (Connection conn = getConnection(); Table t = conn.getTable(tableName)) { 345 // Add initial data 346 t.put( 347 new Put(ROW2).addColumn(FAMILY, QUALIFIER, VALUE2).addColumn(FAMILY, QUALIFIER2, VALUE3)); 348 349 // Execute MultiRowMutation with conditions 350 Put put1 = new Put(ROW).addColumn(FAMILY, QUALIFIER, VALUE); 351 MutationProto m1 = ProtobufUtil.toMutation(MutationType.PUT, put1); 352 Put put2 = new Put(ROW1).addColumn(FAMILY, QUALIFIER, VALUE1); 353 MutationProto m2 = ProtobufUtil.toMutation(MutationType.PUT, put2); 354 Delete delete = new Delete(ROW2); 355 MutationProto m3 = ProtobufUtil.toMutation(MutationType.DELETE, delete); 356 357 MutateRowsRequest.Builder mrmBuilder = MutateRowsRequest.newBuilder(); 358 mrmBuilder.addMutationRequest(m1); 359 mrmBuilder.addMutationRequest(m2); 360 mrmBuilder.addMutationRequest(m3); 361 mrmBuilder.addCondition(ProtobufUtil.toCondition(ROW2, 362 new FilterList( 363 new SingleColumnValueFilter(FAMILY, QUALIFIER, CompareOperator.EQUAL, VALUE2), 364 new SingleColumnValueFilter(FAMILY, QUALIFIER2, CompareOperator.EQUAL, VALUE2)), 365 null)); 366 367 CoprocessorRpcChannel channel = t.coprocessorService(ROW); 368 MultiRowMutationService.BlockingInterface service = 369 MultiRowMutationService.newBlockingStub(channel); 370 MutateRowsResponse response = service.mutateRows(null, mrmBuilder.build()); 371 372 // Assert 373 assertFalse(response.getProcessed()); 374 375 Result r = t.get(new Get(ROW)); 376 assertTrue(r.isEmpty()); 377 378 r = t.get(new Get(ROW1)); 379 assertTrue(r.isEmpty()); 380 381 r = t.get(new Get(ROW2)); 382 assertEquals(Bytes.toString(VALUE2), Bytes.toString(r.getValue(FAMILY, QUALIFIER))); 383 } 384 } 385}