Convert a {@link Query} into a {@link com.google.bigtable.v2.ReadRowsRequest}.
+ *
Upon receiving the response stream, it will merge the {@link
+ * com.google.bigtable.v2.ReadRowsResponse.CellChunk}s in logical rows. The actual row
+ * implementation can be configured in by the {@code rowAdapter} parameter.
+ *
Retry/resume on failure.
+ *
Filter out marker rows.
+ *
Construct a {@link UnaryCallable} that will buffer the entire stream into memory before
+ * completing. If the stream is empty, then the list will be empty.
+ *
Add tracing & metrics.
+ *
+ */
+ private UnaryCallable> createBulkReadRowsCallable(
+ RowAdapter rowAdapter) {
+ ServerStreamingCallable readRowsCallable =
+ createReadRowsBaseCallable(settings.readRowsSettings(), rowAdapter);
+
+ ServerStreamingCallable readRowsUserCallable =
+ new ReadRowsUserCallable<>(readRowsCallable, requestContext);
+
+ SpanName span = getSpanName("ReadRows");
+
+ // The TracedBatcherUnaryCallable has to be wrapped by the TracedUnaryCallable, so that
+ // TracedUnaryCallable can inject a tracer for the TracedBatcherUnaryCallable to interact with
+ UnaryCallable> tracedBatcher =
+ new TracedBatcherUnaryCallable<>(readRowsUserCallable.all());
+
+ UnaryCallable> withHeaderTracer =
+ new HeaderTracerUnaryCallable(tracedBatcher);
+
+ UnaryCallable> traced =
+ new TracedUnaryCallable<>(withHeaderTracer, clientContext.getTracerFactory(), span);
+
+ return traced.withDefaultCallContext(clientContext.getDefaultCallContext());
+ }
+
/**
* Creates a callable chain to handle SampleRowKeys RPcs. The chain will:
*
@@ -549,8 +593,12 @@ private UnaryCallable createBulkMutateRowsCallable() {
flowControlCallable != null ? flowControlCallable : baseCallable, requestContext);
SpanName spanName = getSpanName("MutateRows");
+
+ UnaryCallable tracedBatcher = new TracedBatcherUnaryCallable<>(userFacing);
+
UnaryCallable withHeaderTracer =
- new HeaderTracerUnaryCallable<>(userFacing);
+ new HeaderTracerUnaryCallable<>(tracedBatcher);
+
UnaryCallable traced =
new TracedUnaryCallable<>(withHeaderTracer, clientContext.getTracerFactory(), spanName);
@@ -578,17 +626,14 @@ private UnaryCallable createBulkMutateRowsCallable() {
*/
public Batcher newMutateRowsBatcher(
@Nonnull String tableId, @Nullable GrpcCallContext ctx) {
- UnaryCallable callable = this.bulkMutateRowsCallable;
- if (ctx != null) {
- callable = callable.withDefaultCallContext(ctx);
- }
return new BatcherImpl<>(
settings.bulkMutateRowsSettings().getBatchingDescriptor(),
- callable,
+ bulkMutateRowsCallable,
BulkMutation.create(tableId),
settings.bulkMutateRowsSettings().getBatchingSettings(),
clientContext.getExecutor(),
- bulkMutationFlowController);
+ bulkMutationFlowController,
+ MoreObjects.firstNonNull(ctx, clientContext.getDefaultCallContext()));
}
/**
@@ -609,16 +654,14 @@ public Batcher newMutateRowsBatcher(
public Batcher newBulkReadRowsBatcher(
@Nonnull Query query, @Nullable GrpcCallContext ctx) {
Preconditions.checkNotNull(query, "query cannot be null");
- UnaryCallable> callable = readRowsCallable().all();
- if (ctx != null) {
- callable = callable.withDefaultCallContext(ctx);
- }
return new BatcherImpl<>(
settings.bulkReadRowsSettings().getBatchingDescriptor(),
- callable,
+ bulkReadRowsCallable,
query,
settings.bulkReadRowsSettings().getBatchingSettings(),
- clientContext.getExecutor());
+ clientContext.getExecutor(),
+ null,
+ MoreObjects.firstNonNull(ctx, clientContext.getDefaultCallContext()));
}
/**
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java
index 844bb8d09f..3d7707cc4c 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java
@@ -21,21 +21,40 @@
import com.google.api.gax.tracing.BaseApiTracer;
import javax.annotation.Nullable;
-/** A Bigtable specific {@link ApiTracer} that includes additional contexts. */
+/**
+ * A Bigtable specific {@link ApiTracer} that includes additional contexts. This class is a base
+ * implementation that does nothing.
+ */
@BetaApi("This surface is stable yet it might be removed in the future.")
-public abstract class BigtableTracer extends BaseApiTracer {
+public class BigtableTracer extends BaseApiTracer {
+
+ private volatile int attempt = 0;
+
+ @Override
+ public void attemptStarted(int attemptNumber) {
+ this.attempt = attemptNumber;
+ }
/**
* Get the attempt number of the current call. Attempt number for the current call is passed in
* and should be recorded in {@link #attemptStarted(int)}. With the getter we can access it from
* {@link ApiCallContext}. Attempt number starts from 0.
*/
- public abstract int getAttempt();
+ public int getAttempt() {
+ return attempt;
+ }
/**
* Record the latency between Google's network receives the RPC and reads back the first byte of
* the response from server-timing header. If server-timing header is missing, increment the
* missing header count.
*/
- public abstract void recordGfeMetadata(@Nullable Long latency, @Nullable Throwable throwable);
+ public void recordGfeMetadata(@Nullable Long latency, @Nullable Throwable throwable) {
+ // noop
+ }
+
+ /** Adds an annotation of the total throttled time of a batch. */
+ public void batchRequestThrottled(long throttledTimeMs) {
+ // noop
+ }
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracer.java
index 38f9da7329..5f4580743b 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracer.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracer.java
@@ -178,4 +178,11 @@ public void recordGfeMetadata(@Nullable Long latency, @Nullable Throwable throwa
tracer.recordGfeMetadata(latency, throwable);
}
}
+
+ @Override
+ public void batchRequestThrottled(long throttledTimeMs) {
+ for (BigtableTracer tracer : bigtableTracers) {
+ tracer.batchRequestThrottled(throttledTimeMs);
+ }
+ }
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracer.java
index af220aee78..f28b07c0cb 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracer.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracer.java
@@ -129,8 +129,8 @@ public void connectionSelected(String s) {
}
@Override
- public void attemptStarted(int i) {
- attempt = i;
+ public void attemptStarted(int attemptNumber) {
+ attempt = attemptNumber;
attemptCount++;
attemptTimer = Stopwatch.createStarted();
attemptResponseCount = 0;
@@ -226,6 +226,15 @@ public void recordGfeMetadata(@Nullable Long latency, @Nullable Throwable throwa
.build());
}
+ @Override
+ public void batchRequestThrottled(long totalThrottledMs) {
+ MeasureMap measures =
+ stats
+ .newMeasureMap()
+ .put(RpcMeasureConstants.BIGTABLE_BATCH_THROTTLED_TIME, totalThrottledMs);
+ measures.record(newTagCtxBuilder().build());
+ }
+
private TagContextBuilder newTagCtxBuilder() {
TagContextBuilder tagCtx =
tagger
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcMeasureConstants.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcMeasureConstants.java
index e6e5c70db1..edd73fc81d 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcMeasureConstants.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcMeasureConstants.java
@@ -88,4 +88,11 @@ public class RpcMeasureConstants {
"cloud.google.com/java/bigtable/gfe_header_missing_count",
"Number of RPC responses received without the server-timing header, most likely means that the RPC never reached Google's network",
COUNT);
+
+ /** Total throttled time of a batch in msecs. */
+ public static final MeasureLong BIGTABLE_BATCH_THROTTLED_TIME =
+ MeasureLong.create(
+ "cloud.google.com/java/bigtable/batch_throttled_time",
+ "Total throttled time of a batch in msecs",
+ MILLISECOND);
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViewConstants.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViewConstants.java
index a4acf9ea6e..0d85c75e9c 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViewConstants.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViewConstants.java
@@ -17,6 +17,7 @@
import static com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID;
import static com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants.BIGTABLE_ATTEMPT_LATENCY;
+import static com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants.BIGTABLE_BATCH_THROTTLED_TIME;
import static com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants.BIGTABLE_GFE_HEADER_MISSING_COUNT;
import static com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants.BIGTABLE_GFE_LATENCY;
import static com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants.BIGTABLE_INSTANCE_ID;
@@ -154,4 +155,14 @@ class RpcViewConstants {
BIGTABLE_APP_PROFILE_ID,
BIGTABLE_OP,
BIGTABLE_STATUS));
+
+ // use distribution so we can correlate batch throttled time with op_latency
+ static final View BIGTABLE_BATCH_THROTTLED_TIME_VIEW =
+ View.create(
+ View.Name.create("cloud.google.com/java/bigtable/batch_throttled_time"),
+ "Total throttled time of a batch in msecs",
+ BIGTABLE_BATCH_THROTTLED_TIME,
+ AGGREGATION_WITH_MILLIS_HISTOGRAM,
+ ImmutableList.of(
+ BIGTABLE_INSTANCE_ID, BIGTABLE_PROJECT_ID, BIGTABLE_APP_PROFILE_ID, BIGTABLE_OP));
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViews.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViews.java
index 9e8f6084a2..8b8296b054 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViews.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/RpcViews.java
@@ -31,7 +31,8 @@ public class RpcViews {
RpcViewConstants.BIGTABLE_COMPLETED_OP_VIEW,
RpcViewConstants.BIGTABLE_READ_ROWS_FIRST_ROW_LATENCY_VIEW,
RpcViewConstants.BIGTABLE_ATTEMPT_LATENCY_VIEW,
- RpcViewConstants.BIGTABLE_ATTEMPTS_PER_OP_VIEW);
+ RpcViewConstants.BIGTABLE_ATTEMPTS_PER_OP_VIEW,
+ RpcViewConstants.BIGTABLE_BATCH_THROTTLED_TIME_VIEW);
private static final ImmutableSet GFE_VIEW_SET =
ImmutableSet.of(
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/TracedBatcherUnaryCallable.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/TracedBatcherUnaryCallable.java
new file mode 100644
index 0000000000..b7140f0156
--- /dev/null
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/TracedBatcherUnaryCallable.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.cloud.bigtable.data.v2.stub.metrics;
+
+import com.google.api.core.ApiFuture;
+import com.google.api.core.InternalApi;
+import com.google.api.gax.batching.Batcher;
+import com.google.api.gax.rpc.ApiCallContext;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.api.gax.tracing.ApiTracer;
+
+/**
+ * This callable will extract total throttled time from {@link ApiCallContext} and add it to {@link
+ * ApiTracer}. This class needs to be wrapped by a callable that injects the {@link ApiTracer}.
+ */
+@InternalApi
+public final class TracedBatcherUnaryCallable
+ extends UnaryCallable {
+ private final UnaryCallable innerCallable;
+
+ public TracedBatcherUnaryCallable(UnaryCallable innerCallable) {
+ this.innerCallable = innerCallable;
+ }
+
+ @Override
+ public ApiFuture futureCall(RequestT request, ApiCallContext context) {
+ if (context.getOption(Batcher.THROTTLED_TIME_KEY) != null) {
+ ApiTracer tracer = context.getTracer();
+ // this should always be true
+ if (tracer instanceof BigtableTracer) {
+ ((BigtableTracer) tracer)
+ .batchRequestThrottled(context.getOption(Batcher.THROTTLED_TIME_KEY));
+ }
+ }
+ return innerCallable.futureCall(request, context);
+ }
+}
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableInstanceAdminClientIT.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableInstanceAdminClientIT.java
index 8496561676..fcb9c36b62 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableInstanceAdminClientIT.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableInstanceAdminClientIT.java
@@ -37,6 +37,7 @@
import com.google.cloud.bigtable.test_helpers.env.PrefixGenerator;
import com.google.cloud.bigtable.test_helpers.env.TestEnvRule;
import java.util.List;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
@@ -314,6 +315,8 @@ public void createClusterWithAutoscalingTest() {
assertThat(cluster.getAutoscalingMinServeNodes()).isEqualTo(1);
assertThat(cluster.getAutoscalingMaxServeNodes()).isEqualTo(4);
assertThat(cluster.getAutoscalingCpuPercentageTarget()).isEqualTo(20);
+ } catch (Exception e) {
+ Assert.fail("error in the test" + e.getMessage());
} finally {
client.deleteInstance(newInstanceId);
}
@@ -379,6 +382,8 @@ public void createClusterWithAutoscalingAndPartialUpdateTest() {
assertThat(updatedCluster.getAutoscalingMinServeNodes()).isEqualTo(2);
assertThat(updatedCluster.getAutoscalingMaxServeNodes()).isEqualTo(5);
assertThat(updatedCluster.getAutoscalingCpuPercentageTarget()).isEqualTo(45);
+ } catch (Exception e) {
+ Assert.fail("error in the test: " + e.getMessage());
} finally {
client.deleteInstance(newInstanceId);
}
@@ -409,6 +414,8 @@ public void createClusterWithManualScalingTest() {
assertThat(cluster.getAutoscalingMaxServeNodes()).isEqualTo(0);
assertThat(cluster.getAutoscalingMinServeNodes()).isEqualTo(0);
assertThat(cluster.getAutoscalingCpuPercentageTarget()).isEqualTo(0);
+ } catch (Exception e) {
+ Assert.fail("error in the test: " + e.getMessage());
} finally {
client.deleteInstance(newInstanceId);
}
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracerTest.java
index bed0921feb..69a741d0e3 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracerTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/CompositeTracerTest.java
@@ -15,6 +15,7 @@
*/
package com.google.cloud.bigtable.data.v2.stub.metrics;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -22,9 +23,12 @@
import com.google.api.gax.tracing.ApiTracer;
import com.google.api.gax.tracing.ApiTracer.Scope;
+import com.google.cloud.bigtable.misc_utilities.MethodComparator;
import com.google.common.collect.ImmutableList;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -229,4 +233,20 @@ public void testRecordGfeLatency() {
verify(child3, times(1)).recordGfeMetadata(20L, t);
verify(child4, times(1)).recordGfeMetadata(20L, t);
}
+
+ @Test
+ public void testBatchRequestThrottled() {
+ compositeTracer.batchRequestThrottled(5L);
+ verify(child3, times(1)).batchRequestThrottled(5L);
+ verify(child4, times(1)).batchRequestThrottled(5L);
+ }
+
+ @Test
+ public void testMethodsOverride() {
+ Method[] baseMethods = BigtableTracer.class.getDeclaredMethods();
+ Method[] compositeTracerMethods = CompositeTracer.class.getDeclaredMethods();
+ assertThat(Arrays.asList(compositeTracerMethods))
+ .comparingElementsUsing(MethodComparator.METHOD_CORRESPONDENCE)
+ .containsAtLeastElementsIn(baseMethods);
+ }
}
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java
index 735629977f..69183f1375 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java
@@ -18,9 +18,18 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
-
+import static org.mockito.Mockito.when;
+
+import com.google.api.gax.batching.Batcher;
+import com.google.api.gax.batching.BatcherImpl;
+import com.google.api.gax.batching.BatchingDescriptor;
+import com.google.api.gax.batching.FlowController;
+import com.google.api.gax.grpc.GrpcCallContext;
+import com.google.api.gax.rpc.ApiCallContext;
import com.google.api.gax.rpc.ClientContext;
import com.google.bigtable.v2.BigtableGrpc;
+import com.google.bigtable.v2.MutateRowsRequest;
+import com.google.bigtable.v2.MutateRowsResponse;
import com.google.bigtable.v2.ReadRowsRequest;
import com.google.bigtable.v2.ReadRowsResponse;
import com.google.bigtable.v2.ReadRowsResponse.CellChunk;
@@ -28,8 +37,11 @@
import com.google.cloud.bigtable.data.v2.FakeServiceHelper;
import com.google.cloud.bigtable.data.v2.models.BulkMutation;
import com.google.cloud.bigtable.data.v2.models.Query;
+import com.google.cloud.bigtable.data.v2.models.RowMutationEntry;
import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStub;
import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStubSettings;
+import com.google.cloud.bigtable.data.v2.stub.mutaterows.MutateRowsBatchingDescriptor;
+import com.google.cloud.bigtable.misc_utilities.MethodComparator;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
@@ -44,6 +56,9 @@
import io.opencensus.tags.TagKey;
import io.opencensus.tags.TagValue;
import io.opencensus.tags.Tags;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.After;
@@ -55,6 +70,7 @@
import org.junit.runners.JUnit4;
import org.mockito.Answers;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -88,6 +104,7 @@ public class MetricsTracerTest {
private StatsComponentImpl localStats = new StatsComponentImpl();
private EnhancedBigtableStub stub;
+ private BigtableDataSettings settings;
@Before
public void setUp() throws Exception {
@@ -96,7 +113,7 @@ public void setUp() throws Exception {
RpcViews.registerBigtableClientViews(localStats.getViewManager());
- BigtableDataSettings settings =
+ settings =
BigtableDataSettings.newBuilderForEmulator(serviceHelper.getPort())
.setProjectId(PROJECT_ID)
.setInstanceId(INSTANCE_ID)
@@ -351,6 +368,117 @@ public void testInvalidRequest() throws InterruptedException {
}
}
+ @Test
+ public void testBatchReadRowsThrottledTime() throws Exception {
+ doAnswer(
+ new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) {
+ @SuppressWarnings("unchecked")
+ StreamObserver observer =
+ (StreamObserver) invocation.getArguments()[1];
+ observer.onNext(DEFAULT_READ_ROWS_RESPONSES);
+ observer.onCompleted();
+ return null;
+ }
+ })
+ .when(mockService)
+ .readRows(any(ReadRowsRequest.class), any());
+
+ try (Batcher batcher =
+ stub.newBulkReadRowsBatcher(Query.create(TABLE_ID), GrpcCallContext.createDefault())) {
+ batcher.add(ByteString.copyFromUtf8("row1"));
+ batcher.sendOutstanding();
+
+ // Give OpenCensus a chance to update the views asynchronously.
+ Thread.sleep(100);
+
+ long throttledTimeMetric =
+ StatsTestUtils.getAggregationValueAsLong(
+ localStats,
+ RpcViewConstants.BIGTABLE_BATCH_THROTTLED_TIME_VIEW,
+ ImmutableMap.of(
+ RpcMeasureConstants.BIGTABLE_OP, TagValue.create("Bigtable.ReadRows")),
+ PROJECT_ID,
+ INSTANCE_ID,
+ APP_PROFILE_ID);
+ assertThat(throttledTimeMetric).isEqualTo(0);
+ }
+ }
+
+ @Test
+ public void testBatchMutateRowsThrottledTime() throws Exception {
+ FlowController flowController = Mockito.mock(FlowController.class);
+ BatchingDescriptor batchingDescriptor = Mockito.mock(MutateRowsBatchingDescriptor.class);
+ // Mock throttling
+ final long throttled = 50;
+ doAnswer(
+ new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ Thread.sleep(throttled);
+ return null;
+ }
+ })
+ .when(flowController)
+ .reserve(any(Long.class), any(Long.class));
+ when(flowController.getMaxElementCountLimit()).thenReturn(null);
+ when(flowController.getMaxRequestBytesLimit()).thenReturn(null);
+ when(batchingDescriptor.countBytes(any())).thenReturn(1l);
+ when(batchingDescriptor.newRequestBuilder(any())).thenCallRealMethod();
+
+ doAnswer(
+ new Answer() {
+ @Override
+ public Object answer(InvocationOnMock invocation) {
+ @SuppressWarnings("unchecked")
+ StreamObserver observer =
+ (StreamObserver) invocation.getArguments()[1];
+ observer.onNext(MutateRowsResponse.getDefaultInstance());
+ observer.onCompleted();
+ return null;
+ }
+ })
+ .when(mockService)
+ .mutateRows(any(MutateRowsRequest.class), any());
+
+ ApiCallContext defaultContext = GrpcCallContext.createDefault();
+
+ Batcher batcher =
+ new BatcherImpl(
+ batchingDescriptor,
+ stub.bulkMutateRowsCallable().withDefaultCallContext(defaultContext),
+ BulkMutation.create(TABLE_ID),
+ settings.getStubSettings().bulkMutateRowsSettings().getBatchingSettings(),
+ Executors.newSingleThreadScheduledExecutor(),
+ flowController,
+ defaultContext);
+
+ batcher.add(RowMutationEntry.create("key"));
+ batcher.sendOutstanding();
+
+ Thread.sleep(100);
+ long throttledTimeMetric =
+ StatsTestUtils.getAggregationValueAsLong(
+ localStats,
+ RpcViewConstants.BIGTABLE_BATCH_THROTTLED_TIME_VIEW,
+ ImmutableMap.of(
+ RpcMeasureConstants.BIGTABLE_OP, TagValue.create("Bigtable.MutateRows")),
+ PROJECT_ID,
+ INSTANCE_ID,
+ APP_PROFILE_ID);
+ assertThat(throttledTimeMetric).isAtLeast(throttled);
+ }
+
+ @Test
+ public void testMethodsOverride() {
+ Method[] baseMethods = BigtableTracer.class.getDeclaredMethods();
+ Method[] metricsTracerMethods = MetricsTracer.class.getDeclaredMethods();
+ assertThat(Arrays.asList(metricsTracerMethods))
+ .comparingElementsUsing(MethodComparator.METHOD_CORRESPONDENCE)
+ .containsAtLeastElementsIn(baseMethods);
+ }
+
@SuppressWarnings("unchecked")
private static StreamObserver anyObserver(Class returnType) {
return (StreamObserver) any(returnType);
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/misc_utilities/MethodComparator.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/misc_utilities/MethodComparator.java
new file mode 100644
index 0000000000..4c3ecd2744
--- /dev/null
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/misc_utilities/MethodComparator.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.cloud.bigtable.misc_utilities;
+
+import com.google.common.truth.Correspondence;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * A {@link Correspondence} to compare methods names, parameters and return types in different
+ * classes. An example usage is to make sure a child class is implementing all the methods in the
+ * non-abstract parent class.
+ */
+public class MethodComparator {
+
+ public static final Correspondence METHOD_CORRESPONDENCE =
+ Correspondence.from(
+ MethodComparator::compareMethods, "compare method names, parameters and return types");
+
+ private static boolean compareMethods(Method actual, Method expected) {
+ return actual.getName().equals(expected.getName())
+ && Arrays.equals(actual.getParameterTypes(), expected.getParameterTypes())
+ && actual.getModifiers() == expected.getModifiers()
+ && actual.getReturnType().equals(expected.getReturnType());
+ }
+}
diff --git a/grpc-google-cloud-bigtable-admin-v2/pom.xml b/grpc-google-cloud-bigtable-admin-v2/pom.xml
index 11a5fd7d9b..b1b3a7f7cf 100644
--- a/grpc-google-cloud-bigtable-admin-v2/pom.xml
+++ b/grpc-google-cloud-bigtable-admin-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0com.google.api.grpcgrpc-google-cloud-bigtable-admin-v2
- 2.4.0
+ 2.5.0grpc-google-cloud-bigtable-admin-v2GRPC library for grpc-google-cloud-bigtable-admin-v2com.google.cloudgoogle-cloud-bigtable-parent
- 2.4.0
+ 2.5.0
@@ -18,14 +18,14 @@
com.google.cloudgoogle-cloud-bigtable-deps-bom
- 2.4.0
+ 2.5.0pomimportcom.google.cloudgoogle-cloud-bigtable-bom
- 2.4.0
+ 2.5.0pomimport
diff --git a/grpc-google-cloud-bigtable-v2/pom.xml b/grpc-google-cloud-bigtable-v2/pom.xml
index 4c269473ab..271674b369 100644
--- a/grpc-google-cloud-bigtable-v2/pom.xml
+++ b/grpc-google-cloud-bigtable-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0com.google.api.grpcgrpc-google-cloud-bigtable-v2
- 2.4.0
+ 2.5.0grpc-google-cloud-bigtable-v2GRPC library for grpc-google-cloud-bigtable-v2com.google.cloudgoogle-cloud-bigtable-parent
- 2.4.0
+ 2.5.0
@@ -18,14 +18,14 @@
com.google.cloudgoogle-cloud-bigtable-deps-bom
- 2.4.0
+ 2.5.0pomimportcom.google.cloudgoogle-cloud-bigtable-bom
- 2.4.0
+ 2.5.0pomimport
diff --git a/pom.xml b/pom.xml
index c5acc852c0..de39df46f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
google-cloud-bigtable-parentpom
- 2.4.0
+ 2.5.0Google Cloud Bigtable Parenthttps://github.com/googleapis/java-bigtable
@@ -153,7 +153,7 @@
com.google.cloudgoogle-cloud-conformance-tests
- 0.2.4
+ 0.2.5com.google.truth
@@ -181,7 +181,7 @@
org.mockitomockito-core
- 4.1.0
+ 4.2.0
@@ -260,6 +260,9 @@
**/com/google/cloud/bigtable/data/v2/stub/metrics/**
+
+ com.google.cloud.bigtable.stats
+
https://googleapis.dev/java/gax/${gax.version}/
diff --git a/proto-google-cloud-bigtable-admin-v2/pom.xml b/proto-google-cloud-bigtable-admin-v2/pom.xml
index 13d74c6068..aca997697f 100644
--- a/proto-google-cloud-bigtable-admin-v2/pom.xml
+++ b/proto-google-cloud-bigtable-admin-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0com.google.api.grpcproto-google-cloud-bigtable-admin-v2
- 2.4.0
+ 2.5.0proto-google-cloud-bigtable-admin-v2PROTO library for proto-google-cloud-bigtable-admin-v2com.google.cloudgoogle-cloud-bigtable-parent
- 2.4.0
+ 2.5.0
@@ -18,14 +18,14 @@
com.google.cloudgoogle-cloud-bigtable-deps-bom
- 2.4.0
+ 2.5.0pomimportcom.google.cloudgoogle-cloud-bigtable-bom
- 2.4.0
+ 2.5.0pomimport
diff --git a/proto-google-cloud-bigtable-v2/pom.xml b/proto-google-cloud-bigtable-v2/pom.xml
index a49ae7fc7c..0c9be97805 100644
--- a/proto-google-cloud-bigtable-v2/pom.xml
+++ b/proto-google-cloud-bigtable-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0com.google.api.grpcproto-google-cloud-bigtable-v2
- 2.4.0
+ 2.5.0proto-google-cloud-bigtable-v2PROTO library for proto-google-cloud-bigtable-v2com.google.cloudgoogle-cloud-bigtable-parent
- 2.4.0
+ 2.5.0
@@ -18,14 +18,14 @@
com.google.cloudgoogle-cloud-bigtable-deps-bom
- 2.4.0
+ 2.5.0pomimportcom.google.cloudgoogle-cloud-bigtable-bom
- 2.4.0
+ 2.5.0pomimport
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index cb91328b57..34df06f468 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -14,7 +14,7 @@
com.google.cloud.samplesshared-configuration
- 1.0.23
+ 1.2.0
@@ -29,7 +29,7 @@
com.google.cloudgoogle-cloud-bigtable
- 2.3.1
+ 2.4.0
diff --git a/samples/pom.xml b/samples/pom.xml
index d8f14b3270..a05f97835d 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -18,7 +18,7 @@
com.google.cloud.samplesshared-configuration
- 1.0.23
+ 1.2.0
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index a730fe5bc4..70c6bb2b13 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -14,7 +14,7 @@
com.google.cloud.samplesshared-configuration
- 1.0.23
+ 1.2.0
@@ -28,7 +28,7 @@
com.google.cloudgoogle-cloud-bigtable
- 2.4.0
+ 2.5.0
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index 45cbc5e59a..a3a3cb2268 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -14,7 +14,7 @@
com.google.cloud.samplesshared-configuration
- 1.0.23
+ 1.2.0
@@ -30,7 +30,7 @@
com.google.cloudlibraries-bom
- 24.0.0
+ 24.1.1pomimport
diff --git a/synth.metadata b/synth.metadata
index 8464dab853..cc0bb65bcd 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -4,7 +4,7 @@
"git": {
"name": ".",
"remote": "https://github.com/googleapis/java-bigtable.git",
- "sha": "08207a890af522b24085d96f111bbe2b4c0da62a"
+ "sha": "77649195c3dd0e3e10a0e3adfe8cf0af3d3b0ebd"
}
},
{
diff --git a/versions.txt b/versions.txt
index 4058c16e87..25bba21463 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,9 +1,9 @@
# Format:
# module:released-version:current-version
-google-cloud-bigtable:2.4.0:2.4.0
-grpc-google-cloud-bigtable-admin-v2:2.4.0:2.4.0
-grpc-google-cloud-bigtable-v2:2.4.0:2.4.0
-proto-google-cloud-bigtable-admin-v2:2.4.0:2.4.0
-proto-google-cloud-bigtable-v2:2.4.0:2.4.0
-google-cloud-bigtable-emulator:0.141.0:0.141.0
+google-cloud-bigtable:2.5.0:2.5.0
+grpc-google-cloud-bigtable-admin-v2:2.5.0:2.5.0
+grpc-google-cloud-bigtable-v2:2.5.0:2.5.0
+proto-google-cloud-bigtable-admin-v2:2.5.0:2.5.0
+proto-google-cloud-bigtable-v2:2.5.0:2.5.0
+google-cloud-bigtable-emulator:0.142.0:0.142.0