Skip to content

Commit fe7343e

Browse files
committed
feat: enable microsecond timestamps in client
- Enable microsecond timestamp flag in stub settings - Plumb timestamp origin to Mutation setCell - Skip emulator in mutation-based integration tests to prevent failures Change-Id: Ifd8824a5934f17c9d6a5e0e8cf8b0a0a7343ccb1
1 parent e02346a commit fe7343e

6 files changed

Lines changed: 48 additions & 5 deletions

File tree

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.bigtable.v2.Mutation.DeleteFromRow;
2424
import com.google.bigtable.v2.Mutation.MergeToCell;
2525
import com.google.bigtable.v2.Mutation.SetCell;
26+
import com.google.bigtable.v2.Mutation.TimestampOrigin;
2627
import com.google.cloud.bigtable.data.v2.models.Range.TimestampRange;
2728
import com.google.common.base.Preconditions;
2829
import com.google.common.collect.ImmutableList;
@@ -32,6 +33,8 @@
3233
import java.io.ObjectInputStream;
3334
import java.io.ObjectOutputStream;
3435
import java.io.Serializable;
36+
import java.time.Instant;
37+
import java.time.temporal.ChronoUnit;
3538
import java.util.List;
3639
import javax.annotation.Nonnull;
3740

@@ -154,9 +157,10 @@ public Mutation setCell(
154157
@Override
155158
public Mutation setCell(
156159
@Nonnull String familyName, @Nonnull ByteString qualifier, @Nonnull ByteString value) {
157-
long timestamp = System.currentTimeMillis() * 1_000;
160+
long timestamp = Instant.EPOCH.until(Instant.now(), ChronoUnit.MICROS);
158161

159-
return setCell(familyName, qualifier, timestamp, value);
162+
return setCell(
163+
familyName, qualifier, timestamp, value, TimestampOrigin.CLIENT_AUTO_GENERATED);
160164
}
161165

162166
@Override
@@ -165,6 +169,16 @@ public Mutation setCell(
165169
@Nonnull ByteString qualifier,
166170
long timestamp,
167171
@Nonnull ByteString value) {
172+
return setCell(
173+
familyName, qualifier, timestamp, value, TimestampOrigin.USER_SPECIFIED);
174+
}
175+
176+
private Mutation setCell(
177+
@Nonnull String familyName,
178+
@Nonnull ByteString qualifier,
179+
long timestamp,
180+
@Nonnull ByteString value,
181+
TimestampOrigin timestampOrigin) {
168182
Validations.validateFamily(familyName);
169183
Preconditions.checkNotNull(qualifier, "qualifier can't be null.");
170184
Preconditions.checkNotNull(value, "value can't be null.");
@@ -182,6 +196,7 @@ public Mutation setCell(
182196
.setTimestampMicros(timestamp)
183197
.setValue(value)
184198
.build())
199+
.setTimestampOrigin(timestampOrigin)
185200
.build());
186201

187202
return this;

java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,8 @@ private Builder() {
660660
.setDirectAccessRequested(isDirectPathRequested)
661661
.setTrafficDirectorEnabled(isDirectPathRequested)
662662
.setPeerInfo(true)
663-
.setSessionsCompatible(true);
663+
.setSessionsCompatible(true)
664+
.setMicrosecondTimestamp(true);
664665
}
665666

666667
private Builder(EnhancedBigtableStubSettings settings) {
@@ -1008,6 +1009,7 @@ public EnhancedBigtableStubSettings build() {
10081009

10091010
featureFlags.setRoutingCookie(true);
10101011
featureFlags.setRetryInfo(true);
1012+
featureFlags.setMicrosecondTimestamp(true);
10111013
// client_Side_metrics_enabled feature flag is only set when a user is running with a
10121014
// DefaultMetricsProvider. This may cause false negatives when a user registered the
10131015
// metrics on their CustomOpenTelemetryMetricsProvider.

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public class BulkMutateIT {
5353

5454
@Test(timeout = 60 * 1000)
5555
public void test() throws IOException, InterruptedException {
56+
assume()
57+
.withMessage("Emulator does not support microsecond timestamp granularity")
58+
.that(testEnvRule.env())
59+
.isNotInstanceOf(EmulatorEnv.class);
60+
5661
BigtableDataSettings settings = testEnvRule.env().getDataClientSettings();
5762
String rowPrefix = UUID.randomUUID().toString();
5863
// Set target latency really low so it'll trigger adjusting thresholds

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ public class CheckAndMutateIT {
4949

5050
@Test
5151
public void test() throws Exception {
52+
assume()
53+
.withMessage("Emulator does not support microsecond timestamp granularity")
54+
.that(testEnvRule.env())
55+
.isNotInstanceOf(EmulatorEnv.class);
56+
5257
TableId tableId = testEnvRule.env().getTableId();
5358
String familyId = testEnvRule.env().getFamilyId();
5459
String rowKey = UUID.randomUUID().toString();

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ public class MutateRowIT {
4444

4545
@Test
4646
public void test() throws Exception {
47+
assume()
48+
.withMessage("Emulator does not support microsecond timestamp granularity")
49+
.that(testEnvRule.env())
50+
.isNotInstanceOf(EmulatorEnv.class);
51+
4752
String rowKey = UUID.randomUUID().toString();
4853
String familyId = testEnvRule.env().getFamilyId();
4954

java-bigtable/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/MutationTest.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
import com.google.bigtable.v2.Mutation.DeleteFromFamily;
2323
import com.google.bigtable.v2.Mutation.DeleteFromRow;
2424
import com.google.bigtable.v2.Mutation.MergeToCell;
25+
import com.google.bigtable.v2.Mutation.TimestampOrigin;
2526
import com.google.cloud.bigtable.data.v2.models.Range.TimestampRange;
2627
import com.google.common.primitives.Longs;
2728
import com.google.protobuf.ByteString;
29+
import java.time.Instant;
30+
import java.time.temporal.ChronoUnit;
2831
import java.io.ByteArrayInputStream;
2932
import java.io.ByteArrayOutputStream;
3033
import java.io.IOException;
@@ -48,7 +51,7 @@ public void setUp() {
4851

4952
@Test
5053
public void setCellTest() {
51-
long minTimestamp = System.currentTimeMillis() * 1_000;
54+
long minTimestamp = Instant.EPOCH.until(Instant.now(), ChronoUnit.MICROS);
5255

5356
mutation
5457
.setCell(
@@ -65,7 +68,7 @@ public void setCellTest() {
6568

6669
List<com.google.bigtable.v2.Mutation> actual = mutation.getMutations();
6770

68-
long maxTimestamp = System.currentTimeMillis() * 1_000;
71+
long maxTimestamp = Instant.EPOCH.until(Instant.now(), ChronoUnit.MICROS);
6972
com.google.common.collect.Range<Long> expectedTimestampRange =
7073
com.google.common.collect.Range.closed(minTimestamp, maxTimestamp);
7174

@@ -77,27 +80,31 @@ public void setCellTest() {
7780
assertThat(actual.get(0).getSetCell().getValue())
7881
.isEqualTo(ByteString.copyFromUtf8("fake-value"));
7982
assertThat(actual.get(0).getSetCell().getTimestampMicros()).isEqualTo(1_000);
83+
assertThat(actual.get(0).getTimestampOrigin()).isEqualTo(TimestampOrigin.USER_SPECIFIED);
8084

8185
assertThat(actual.get(1).getSetCell().getFamilyName()).isEqualTo("fake-family");
8286
assertThat(actual.get(1).getSetCell().getColumnQualifier())
8387
.isEqualTo(ByteString.copyFromUtf8("fake-qualifier"));
8488
assertThat(actual.get(1).getSetCell().getValue())
8589
.isEqualTo(ByteString.copyFromUtf8("fake-value"));
8690
assertThat(actual.get(1).getSetCell().getTimestampMicros()).isIn(expectedTimestampRange);
91+
assertThat(actual.get(1).getTimestampOrigin()).isEqualTo(TimestampOrigin.CLIENT_AUTO_GENERATED);
8792

8893
assertThat(actual.get(2).getSetCell().getFamilyName()).isEqualTo("fake-family2");
8994
assertThat(actual.get(2).getSetCell().getColumnQualifier())
9095
.isEqualTo(ByteString.copyFromUtf8("fake-qualifier2"));
9196
assertThat(actual.get(2).getSetCell().getValue())
9297
.isEqualTo(ByteString.copyFromUtf8("fake-value2"));
9398
assertThat(actual.get(2).getSetCell().getTimestampMicros()).isEqualTo(1_000);
99+
assertThat(actual.get(2).getTimestampOrigin()).isEqualTo(TimestampOrigin.USER_SPECIFIED);
94100

95101
assertThat(actual.get(3).getSetCell().getFamilyName()).isEqualTo("fake-family2");
96102
assertThat(actual.get(3).getSetCell().getColumnQualifier())
97103
.isEqualTo(ByteString.copyFromUtf8("fake-qualifier2"));
98104
assertThat(actual.get(3).getSetCell().getValue())
99105
.isEqualTo(ByteString.copyFromUtf8("fake-value2"));
100106
assertThat(actual.get(3).getSetCell().getTimestampMicros()).isIn(expectedTimestampRange);
107+
assertThat(actual.get(3).getTimestampOrigin()).isEqualTo(TimestampOrigin.CLIENT_AUTO_GENERATED);
101108

102109
assertThat(Mutation.fromProtoUnsafe(actual).getMutations()).isEqualTo(actual);
103110
}
@@ -113,6 +120,7 @@ public void setCellWithServerSideTimestamp() {
113120
List<com.google.bigtable.v2.Mutation> actual = mutation.getMutations();
114121
assertThat(actual.get(0).getSetCell().getTimestampMicros())
115122
.isEqualTo(Mutation.SERVER_SIDE_TIMESTAMP);
123+
assertThat(actual.get(0).getTimestampOrigin()).isEqualTo(TimestampOrigin.USER_SPECIFIED);
116124
}
117125

118126
@Test
@@ -276,6 +284,8 @@ public void testWithLongValue() {
276284

277285
assertThat(actualMutation.getSetCell().getValue())
278286
.isEqualTo(ByteString.copyFrom(Longs.toByteArray(100_000L)));
287+
assertThat(mutations.get(0).getTimestampOrigin()).isEqualTo(TimestampOrigin.CLIENT_AUTO_GENERATED);
288+
assertThat(mutations.get(1).getTimestampOrigin()).isEqualTo(TimestampOrigin.CLIENT_AUTO_GENERATED);
279289

280290
assertThat(mutations.get(2).getSetCell())
281291
.isEqualTo(
@@ -285,6 +295,7 @@ public void testWithLongValue() {
285295
.setTimestampMicros(30_000L)
286296
.setValue(ByteString.copyFrom(Longs.toByteArray(20_000L)))
287297
.build());
298+
assertThat(mutations.get(2).getTimestampOrigin()).isEqualTo(TimestampOrigin.USER_SPECIFIED);
288299
}
289300

290301
@Test

0 commit comments

Comments
 (0)