Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.

Commit 843ae5e

Browse files
feat: Support Idempotency in MutateRow API
1 parent b5acca6 commit 843ae5e

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/RowMutation.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.google.api.core.BetaApi;
1919
import com.google.api.core.InternalApi;
20+
import com.google.bigtable.v2.Idempotency;
2021
import com.google.bigtable.v2.MutateRowRequest;
2122
import com.google.bigtable.v2.MutateRowsRequest;
2223
import com.google.bigtable.v2.MutateRowsRequest.Entry;
@@ -38,6 +39,7 @@ public final class RowMutation implements MutationApi<RowMutation>, Serializable
3839
private final TargetId targetId;
3940
private final ByteString key;
4041
private final Mutation mutation;
42+
private ByteString idempotency_token;
4143

4244
private RowMutation(TargetId targetId, ByteString key, Mutation mutation) {
4345
Preconditions.checkNotNull(targetId, "target id can't be null.");
@@ -255,6 +257,11 @@ public RowMutation mergeToCell(
255257
return this;
256258
}
257259

260+
public RowMutation setIdempotency(@Nonnull ByteString token) {
261+
this.idempotency_token = token;
262+
return this;
263+
}
264+
258265
@InternalApi
259266
public MutateRowRequest toProto(RequestContext requestContext) {
260267
MutateRowRequest.Builder builder = MutateRowRequest.newBuilder();
@@ -266,6 +273,12 @@ public MutateRowRequest toProto(RequestContext requestContext) {
266273
builder.setTableName(resourceName);
267274
}
268275

276+
if (idempotency_token != null) {
277+
Idempotency.Builder idempotencyBuilder = Idempotency.newBuilder();
278+
idempotencyBuilder.setToken(idempotency_token);
279+
builder.setIdempotency(idempotencyBuilder);
280+
}
281+
269282
return builder
270283
.setAppProfileId(requestContext.getAppProfileId())
271284
.setRowKey(key)

google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/it/MutateRowIT.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static com.google.cloud.bigtable.misc_utilities.AuthorizedViewTestHelper.createTestAuthorizedView;
2121
import static com.google.common.truth.Truth.assertThat;
2222
import static com.google.common.truth.TruthJUnit.assume;
23+
import static org.junit.Assert.assertEquals;
2324
import static org.junit.Assert.fail;
2425

2526
import com.google.api.gax.rpc.PermissionDeniedException;
@@ -31,6 +32,8 @@
3132
import com.google.cloud.bigtable.test_helpers.env.EmulatorEnv;
3233
import com.google.cloud.bigtable.test_helpers.env.TestEnvRule;
3334
import com.google.protobuf.ByteString;
35+
36+
import java.math.BigInteger;
3437
import java.util.UUID;
3538
import java.util.concurrent.TimeUnit;
3639
import org.junit.ClassRule;
@@ -40,6 +43,16 @@
4043

4144
@RunWith(JUnit4.class)
4245
public class MutateRowIT {
46+
static {
47+
System.setProperty("bigtable.env", "cloud");
48+
System.setProperty("bigtable.project", "google.com:cloud-bigtable-dev");
49+
System.setProperty("bigtable.instance", "stepanian-agg");
50+
System.setProperty("bigtable.table", "my-table");
51+
System.setProperty("bigtable.data-endpoint", "test-bigtable.sandbox.googleapis.com:443");
52+
System.setProperty("bigtable.admin-endpoint", "test-bigtableadmin.sandbox.googleapis.com:443");
53+
54+
// -D -Dbigtable.data-endpoint=bigtable.googleapis.com -Dbigtable.admin-endpoint=test-bigtableadmin.sandbox.googleapis.com
55+
}
4356
@ClassRule public static TestEnvRule testEnvRule = new TestEnvRule();
4457

4558
@Test
@@ -152,4 +165,58 @@ public void testOnAuthorizedView() throws Exception {
152165
.getTableAdminClient()
153166
.deleteAuthorizedView(testEnvRule.env().getTableId(), testAuthorizedView.getId());
154167
}
168+
169+
@Test
170+
public void testIdempotentAggregates() throws Exception {
171+
String rowKey = UUID.randomUUID().toString();
172+
// String familyId = testEnvRule.env().getFamilyId();
173+
String familyId = "cfagg1";
174+
175+
// First mutation w/ idempotency token.
176+
testEnvRule
177+
.env()
178+
.getDataClient()
179+
.mutateRowAsync(
180+
RowMutation.create(testEnvRule.env().getTableId(), rowKey)
181+
.addToCell(familyId, "cq", 0, 10)
182+
.setIdempotency(ByteString.copyFromUtf8("abcdefgh"))
183+
)
184+
.get(1, TimeUnit.MINUTES);
185+
186+
// Now replay the mutation.
187+
testEnvRule
188+
.env()
189+
.getDataClient()
190+
.mutateRowAsync(
191+
RowMutation.create(testEnvRule.env().getTableId(), rowKey)
192+
.addToCell(familyId, "cq", 0, 10)
193+
.setIdempotency(ByteString.copyFromUtf8("abcdefgh"))
194+
)
195+
.get(1, TimeUnit.MINUTES);
196+
197+
Row row =
198+
testEnvRule
199+
.env()
200+
.getDataClient()
201+
.readRowsCallable()
202+
.first()
203+
.call(Query.create(testEnvRule.env().getTableId()).rowKey(rowKey));
204+
205+
System.out.println("Shant! " + row.toString());
206+
System.out.println("Shant! " + row.getCells().get(0));
207+
System.out.println("Shant! " + row.getCells().get(0).getValue().toByteArray());
208+
for (byte b : row.getCells().get(0).getValue().toByteArray()) {
209+
System.out.println("SHant byte " + b);
210+
}
211+
System.out.println("Shant bigint " + new BigInteger(row.getCells().get(0).getValue().toByteArray()));
212+
System.out.println("Shant bytebufsize " + row.getCells().get(0).getValue().size());
213+
System.out.println("Shant bytebuf " + java.nio.ByteBuffer.wrap(row.getCells().get(0).getValue().toByteArray()).getInt());
214+
System.out.println("Shant bytebuf " + java.nio.ByteBuffer.wrap(row.getCells().get(0).getValue().toByteArray()).order(java.nio.ByteOrder.BIG_ENDIAN).getInt());
215+
216+
// assertEquals(row.toString(), "shant");
217+
assertThat(row.getCells()).hasSize(1);
218+
// Ensure that the increment is only applied once.
219+
assertThat(new BigInteger(row.getCells().get(0).getValue().toByteArray())).isEqualTo(10);
220+
// assertThat(java.nio.ByteBuffer.wrap(row.getCells().get(0).getValue().toByteArray()).order(java.nio.ByteOrder.BIG_ENDIAN).getInt()).isEqualTo(10);
221+
}
155222
}

0 commit comments

Comments
 (0)