Skip to content

Commit 33c7558

Browse files
deps: partial upgrade to hbase 2.5 (#4328)
Unfortunately mirroring-client still has to depend on hbase < 2.4 due to unresolved binary compatibility issues with mutateRow
1 parent 1a42277 commit 33c7558

File tree

22 files changed

+798
-145
lines changed

22 files changed

+798
-145
lines changed

bigtable-client-core-parent/bigtable-hbase-integration-tests-common/src/test/java/com/google/cloud/bigtable/hbase/AbstractTestBatch.java

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import static org.junit.Assert.assertTrue;
2222

2323
import java.io.IOException;
24+
import java.lang.reflect.InvocationTargetException;
25+
import java.lang.reflect.Method;
2426
import java.util.ArrayList;
2527
import java.util.Arrays;
2628
import java.util.Collections;
@@ -268,7 +270,7 @@ public void testRowMutations() throws IOException {
268270
RowMutations rm = new RowMutations(rowKey);
269271
rm.add(put0);
270272
rm.add(put1);
271-
table.mutateRow(rm);
273+
invokeMutateRow(table, rm);
272274

273275
// Check
274276
Result result = table.get(new Get(rowKey));
@@ -288,7 +290,7 @@ public void testRowMutations() throws IOException {
288290
rm = new RowMutations(rowKey);
289291
rm.add(delete);
290292
rm.add(put2);
291-
table.mutateRow(rm);
293+
invokeMutateRow(table, rm);
292294

293295
// Check
294296
result = table.get(new Get(rowKey));
@@ -419,7 +421,7 @@ public void testBatchAppend() throws IOException, InterruptedException {
419421
@Test
420422
public void testBatchWithNullAndEmptyElements() throws IOException {
421423
Table table = getDefaultTable();
422-
Exception actualError = null;
424+
Throwable actualError = null;
423425
try {
424426
table.batch(null, new Object[1]);
425427
} catch (Exception ex) {
@@ -437,7 +439,7 @@ public void testBatchWithNullAndEmptyElements() throws IOException {
437439

438440
try {
439441
table.batch(Collections.singletonList(null), new Object[0]);
440-
} catch (Exception ex) {
442+
} catch (Throwable ex) {
441443
actualError = ex;
442444
}
443445
assertNotNull(actualError);
@@ -448,35 +450,27 @@ public void testMutateRowWithEmptyElements() throws Exception {
448450
Table table = getDefaultTable();
449451
Exception actualError = null;
450452
try {
451-
table.mutateRow(null);
453+
invokeMutateRow(table, null);
452454
} catch (Exception ex) {
453455
actualError = ex;
454456
}
455457
assertNotNull(actualError);
456458
actualError = null;
457459

458460
try {
459-
table.mutateRow(new RowMutations(new byte[0]));
461+
invokeMutateRow(table, new RowMutations(new byte[0]));
460462
} catch (Exception ex) {
461463
actualError = ex;
462464
}
463465
assertNotNull(actualError);
464466
actualError = null;
465467

466-
try {
467-
// Table#mutateRow ignores requests without Mutations.
468-
table.mutateRow(new RowMutations(new byte[1]));
469-
} catch (Exception ex) {
470-
actualError = ex;
471-
}
472-
assertNull(actualError);
473-
474468
try {
475469
byte[] rowKeyForPut = dataHelper.randomData("test-rowKey");
476470
RowMutations rowMutations = new RowMutations(rowKeyForPut);
477471
rowMutations.add(new Put(rowKeyForPut));
478472

479-
table.mutateRow(rowMutations);
473+
invokeMutateRow(table, rowMutations);
480474
} catch (Exception ex) {
481475
actualError = ex;
482476
}
@@ -489,7 +483,7 @@ public void testMutateRowWithEmptyElements() throws Exception {
489483
rowMutations.add(new Put(rowKeyWithNullQual).addColumn(COLUMN_FAMILY, null, null));
490484

491485
// Table#mutateRow should add a row with null qualifier.
492-
table.mutateRow(rowMutations);
486+
invokeMutateRow(table, rowMutations);
493487

494488
assertTrue(table.exists(new Get(rowKeyWithNullQual)));
495489
} catch (Exception ex) {
@@ -503,7 +497,7 @@ public void testMutateRowWithEmptyElements() throws Exception {
503497
rowMutations.add(new Put(rowKeyWithEmptyQual).addColumn(COLUMN_FAMILY, new byte[0], null));
504498

505499
// Table#mutateRow should add a row with an empty qualifier.
506-
table.mutateRow(rowMutations);
500+
invokeMutateRow(table, rowMutations);
507501

508502
assertTrue(table.exists(new Get(rowKeyWithEmptyQual)));
509503
} catch (Exception ex) {
@@ -517,7 +511,7 @@ public void testMutateRowWithEmptyElements() throws Exception {
517511
rowMutations.add(new Put(rowKeyWithNullValue).addColumn(COLUMN_FAMILY, "q".getBytes(), null));
518512

519513
// Table#mutateRow should add a row with null values.
520-
table.mutateRow(rowMutations);
514+
invokeMutateRow(table, rowMutations);
521515

522516
assertTrue(table.exists(new Get(rowKeyWithNullValue)));
523517
} catch (Exception ex) {
@@ -526,6 +520,17 @@ public void testMutateRowWithEmptyElements() throws Exception {
526520
assertNull(actualError);
527521
}
528522

523+
// workaround binary incompatible change in HBase 2.4 that changed the return type of mutateRow
524+
// This is necessary because this test is shared by bigtable-hbase 1x & 2x
525+
private void invokeMutateRow(Table table, RowMutations rm) {
526+
try {
527+
Method mutateRow = Table.class.getMethod("mutateRow", RowMutations.class);
528+
mutateRow.invoke(table, rm);
529+
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
530+
throw new RuntimeException(e);
531+
}
532+
}
533+
529534
protected abstract void appendAdd(
530535
Append append, byte[] columnFamily, byte[] qualifier, byte[] value);
531536
}

bigtable-client-core-parent/bigtable-hbase-integration-tests-common/src/test/java/com/google/cloud/bigtable/hbase/AbstractTestCheckAndMutate.java

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,17 @@ public void testCheckAndDeleteSameQual() throws Exception {
127127
Assert.assertFalse(
128128
"Wrong value. Should fail.",
129129
checkAndDelete(rowKey, SharedTestEnvRule.COLUMN_FAMILY, qual, value2, delete));
130-
Assert.assertFalse(
131-
"Zero bytes value. Should fail.",
132-
checkAndDelete(rowKey, SharedTestEnvRule.COLUMN_FAMILY, qual, ZERO_BYTES, delete));
130+
131+
// Newer versions of HBase throw an error instead of returning false
132+
Exception actualError = null;
133+
Boolean result = null;
134+
try {
135+
result = checkAndDelete(rowKey, SharedTestEnvRule.COLUMN_FAMILY, qual, ZERO_BYTES, delete);
136+
} catch (Exception e) {
137+
actualError = e;
138+
}
139+
140+
Assert.assertTrue("Zero bytes value. Should fail.", actualError != null || !result);
133141
Assert.assertTrue(
134142
checkAndDelete(rowKey, SharedTestEnvRule.COLUMN_FAMILY, qual, value1, delete));
135143
Assert.assertFalse("Row should be gone", table.exists(new Get(rowKey)));
@@ -245,18 +253,9 @@ public void testCheckAndPutDiffRow() throws Exception {
245253

246254
// Put then again
247255
Put put = new Put(rowKey1).addColumn(SharedTestEnvRule.COLUMN_FAMILY, qual, value);
248-
try {
249-
checkAndPut(rowKey2, SharedTestEnvRule.COLUMN_FAMILY, qual, null, put);
250-
Assert.fail("IOException expected");
251-
} catch (IOException e) {
252-
assertGetRowException(e);
253-
} finally {
254-
table.close();
255-
}
256-
}
257-
258-
private static void assertGetRowException(IOException e) {
259-
Assert.assertTrue(e.getMessage(), e.getMessage().contains("Action's getRow must match"));
256+
Assert.assertThrows(
257+
IOException.class,
258+
() -> checkAndPut(rowKey2, SharedTestEnvRule.COLUMN_FAMILY, qual, null, put));
260259
}
261260

262261
@Test
@@ -269,10 +268,9 @@ public void testCheckAndDeleteDiffRow() throws Exception {
269268

270269
// Put then again
271270
Delete delete = new Delete(rowKey1).addColumns(SharedTestEnvRule.COLUMN_FAMILY, qual);
272-
checkAndDelete(rowKey2, SharedTestEnvRule.COLUMN_FAMILY, qual, null, delete);
273-
Assert.fail("IOException expected");
274-
} catch (IOException e) {
275-
assertGetRowException(e);
271+
Assert.assertThrows(
272+
IOException.class,
273+
() -> checkAndDelete(rowKey2, SharedTestEnvRule.COLUMN_FAMILY, qual, null, delete));
276274
}
277275
}
278276

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.cloud.bigtable.hbase.test_helpers;
17+
18+
import static com.google.common.truth.Fact.simpleFact;
19+
import static com.google.common.truth.Truth.assertAbout;
20+
21+
import com.google.common.truth.FailureMetadata;
22+
import com.google.common.truth.Subject;
23+
import java.util.List;
24+
import org.apache.hadoop.hbase.Cell;
25+
import org.apache.hadoop.hbase.CellUtil;
26+
import org.apache.hadoop.hbase.client.Result;
27+
import org.apache.hadoop.hbase.util.Bytes;
28+
import org.checkerframework.checker.nullness.qual.Nullable;
29+
30+
public class ResultSubject extends Subject {
31+
// User-defined entry point
32+
public static ResultSubject assertThat(org.apache.hadoop.hbase.client.Result result) {
33+
return assertAbout(results()).that(result);
34+
}
35+
36+
// Static method for getting the subject factory (for use with assertAbout())
37+
public static Subject.Factory<ResultSubject, Result> results() {
38+
return ResultSubject::new;
39+
}
40+
41+
private final Result actual;
42+
43+
public ResultSubject(FailureMetadata metadata, @Nullable Result actual) {
44+
super(metadata, actual);
45+
this.actual = actual;
46+
}
47+
48+
public void latestCellHasValue(byte[] family, byte[] qualifier, byte[] value) {
49+
Cell cell = actual.getColumnLatestCell(family, qualifier);
50+
byte[] actualValue = CellUtil.cloneValue(cell);
51+
check("getColumnLatestCell(%s, %s).value()", family, Bytes.toStringBinary(qualifier))
52+
.that(Bytes.toStringBinary(actualValue))
53+
.isEqualTo(Bytes.toStringBinary(value));
54+
}
55+
56+
public void doesNotHaveCell(byte[] family, byte[] qualifier) {
57+
List<Cell> columnCells = actual.getColumnCells(family, qualifier);
58+
59+
check("doesNotHaveCell(%s,%s)", Bytes.toStringBinary(family), Bytes.toStringBinary(qualifier))
60+
.that(columnCells)
61+
.isEmpty();
62+
}
63+
64+
@Override
65+
public void isEqualTo(@Nullable Object expected) {
66+
if (actual == expected) {
67+
return;
68+
}
69+
if (actual == null) {
70+
failWithoutActual(simpleFact("got null when expecting a value"));
71+
return;
72+
}
73+
if (expected == null) {
74+
failWithoutActual(simpleFact("expected null but got: " + actual));
75+
return;
76+
}
77+
78+
try {
79+
Result.compareResults(actual, (Result) expected);
80+
} catch (Exception e) {
81+
failWithoutActual(simpleFact(e.getMessage()));
82+
}
83+
}
84+
85+
@Override
86+
public void isNotEqualTo(@Nullable Object unexpected) {
87+
if (actual == unexpected) {
88+
failWithoutActual(simpleFact("Expected different values, but got same instance"));
89+
return;
90+
}
91+
if (actual == null || unexpected == null) {
92+
return;
93+
}
94+
95+
try {
96+
Result.compareResults(actual, (Result) unexpected);
97+
failWithoutActual(simpleFact("Results were equal to each other"));
98+
} catch (Exception e) {
99+
// noop
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)