diff --git a/.gitignore b/.gitignore
index dbde6a740b09..4a670f8c5367 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,4 @@ api_key
artman-genfiles
.flattened-pom.xml
+dependency-reduced-pom.xml
diff --git a/.kokoro/presubmit/graalvm-native-17.cfg b/.kokoro/presubmit/graalvm-native-17.cfg
index 8872a78aa94e..1b8880d2d37c 100644
--- a/.kokoro/presubmit/graalvm-native-17.cfg
+++ b/.kokoro/presubmit/graalvm-native-17.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.24.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.25.0"
}
env_vars: {
diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg
index 13b7c419a2b0..c12b8ac41790 100644
--- a/.kokoro/presubmit/graalvm-native.cfg
+++ b/.kokoro/presubmit/graalvm-native.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.24.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.25.0"
}
env_vars: {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44974f9fd5af..54d5c18f19d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## [2.34.0](https://github.com/googleapis/java-bigtable/compare/v2.33.0...v2.34.0) (2024-02-21)
+
+
+### Features
+
+* Add the export logic for per-connection error rate metric ([#2121](https://github.com/googleapis/java-bigtable/issues/2121)) ([d053f2d](https://github.com/googleapis/java-bigtable/commit/d053f2dc98eb8576f33471d728c6fbf32d537ece))
+* Create the backbone of counting errors per connection each minute. ([#2094](https://github.com/googleapis/java-bigtable/issues/2094)) ([7d27816](https://github.com/googleapis/java-bigtable/commit/7d27816b959a06412f59f49023611f0bca8e3536))
+
+
+### Dependencies
+
+* Update actions/setup-java action to v4 ([#2106](https://github.com/googleapis/java-bigtable/issues/2106)) ([a694296](https://github.com/googleapis/java-bigtable/commit/a694296a76faefe31585aabc9dce0adcf4a342bf))
+* Update dependency com.google.cloud:gapic-libraries-bom to v1.30.0 ([#2126](https://github.com/googleapis/java-bigtable/issues/2126)) ([f613bd0](https://github.com/googleapis/java-bigtable/commit/f613bd0dd449d218a0d8b6d20344155f9762cfb1))
+* Update dependency com.google.cloud:sdk-platform-java-config to v3.25.0 ([#2113](https://github.com/googleapis/java-bigtable/issues/2113)) ([ba1973e](https://github.com/googleapis/java-bigtable/commit/ba1973e20c4cbb9be778840cc202eb7e4daf04f4))
+* Update dependency com.google.truth.extensions:truth-proto-extension to v1.4.1 ([#2119](https://github.com/googleapis/java-bigtable/issues/2119)) ([0a7ad66](https://github.com/googleapis/java-bigtable/commit/0a7ad66fa9e2c1858f51c25d1ea01b26da0b944f))
+* Update dependency org.graalvm.buildtools:junit-platform-native to v0.10.1 ([#2122](https://github.com/googleapis/java-bigtable/issues/2122)) ([99ec284](https://github.com/googleapis/java-bigtable/commit/99ec28425c2caac6a992cb7edd83f2029cce92ec))
+* Update dependency org.graalvm.buildtools:native-maven-plugin to v0.10.1 ([#2123](https://github.com/googleapis/java-bigtable/issues/2123)) ([12d961a](https://github.com/googleapis/java-bigtable/commit/12d961aad5d15feb27a7996de8b9a626fcdfbc5b))
+
## [2.33.0](https://github.com/googleapis/java-bigtable/compare/v2.32.0...v2.33.0) (2024-02-12)
diff --git a/README.md b/README.md
index 93c82698928e..997ebe423041 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-bigtable
- 2.32.0
+ 2.33.0
```
@@ -50,20 +50,20 @@ If you are using Maven without the BOM, add this to your dependencies:
If you are using Gradle 5.x or later, add this to your dependencies:
```Groovy
-implementation platform('com.google.cloud:libraries-bom:26.31.0')
+implementation platform('com.google.cloud:libraries-bom:26.32.0')
implementation 'com.google.cloud:google-cloud-bigtable'
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-bigtable:2.32.0'
+implementation 'com.google.cloud:google-cloud-bigtable:2.33.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-bigtable" % "2.32.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-bigtable" % "2.33.0"
```
@@ -609,7 +609,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-bigtable/java11.html
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-bigtable.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigtable/2.32.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigtable/2.33.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/google-cloud-bigtable-bom/pom.xml b/google-cloud-bigtable-bom/pom.xml
index c9674c0fa046..a89ec2ae275d 100644
--- a/google-cloud-bigtable-bom/pom.xml
+++ b/google-cloud-bigtable-bom/pom.xml
@@ -3,12 +3,12 @@
4.0.0
com.google.cloud
google-cloud-bigtable-bom
- 2.33.0
+ 2.34.0
pom
com.google.cloud
sdk-platform-java-config
- 3.24.0
+ 3.25.0
@@ -63,42 +63,42 @@
com.google.cloud
google-cloud-bigtable
- 2.33.0
+ 2.34.0
com.google.cloud
google-cloud-bigtable-emulator
- 0.170.0
+ 0.171.0
com.google.cloud
google-cloud-bigtable-emulator-core
- 0.170.0
+ 0.171.0
com.google.api.grpc
grpc-google-cloud-bigtable-admin-v2
- 2.33.0
+ 2.34.0
com.google.api.grpc
grpc-google-cloud-bigtable-v2
- 2.33.0
+ 2.34.0
com.google.api.grpc
proto-google-cloud-bigtable-admin-v2
- 2.33.0
+ 2.34.0
com.google.api.grpc
proto-google-cloud-bigtable-v2
- 2.33.0
+ 2.34.0
com.google.cloud
google-cloud-bigtable-stats
- 2.33.0
+ 2.34.0
diff --git a/google-cloud-bigtable-deps-bom/pom.xml b/google-cloud-bigtable-deps-bom/pom.xml
index de6d66d959a2..6577b14e787d 100644
--- a/google-cloud-bigtable-deps-bom/pom.xml
+++ b/google-cloud-bigtable-deps-bom/pom.xml
@@ -7,13 +7,13 @@
com.google.cloud
sdk-platform-java-config
- 3.24.0
+ 3.25.0
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
@@ -66,7 +66,7 @@
com.google.cloud
gapic-libraries-bom
- 1.29.0
+ 1.30.0
pom
import
@@ -77,6 +77,12 @@
pom
import
+
+
+ io.opencensus
+ opencensus-contrib-resource-util
+ 0.31.1
+
diff --git a/google-cloud-bigtable-emulator-core/pom.xml b/google-cloud-bigtable-emulator-core/pom.xml
index 2747494faacd..3f0cb697d9c8 100644
--- a/google-cloud-bigtable-emulator-core/pom.xml
+++ b/google-cloud-bigtable-emulator-core/pom.xml
@@ -7,11 +7,11 @@
google-cloud-bigtable-parent
com.google.cloud
- 2.33.0
+ 2.34.0
google-cloud-bigtable-emulator-core
- 0.170.0
+ 0.171.0
A Java wrapper for the Cloud Bigtable emulator.
diff --git a/google-cloud-bigtable-emulator/pom.xml b/google-cloud-bigtable-emulator/pom.xml
index 8b0e7225e447..59c0505e13d6 100644
--- a/google-cloud-bigtable-emulator/pom.xml
+++ b/google-cloud-bigtable-emulator/pom.xml
@@ -5,7 +5,7 @@
4.0.0
google-cloud-bigtable-emulator
- 0.170.0
+ 0.171.0
Google Cloud Java - Bigtable Emulator
https://github.com/googleapis/java-bigtable
@@ -14,7 +14,7 @@
com.google.cloud
google-cloud-bigtable-parent
- 2.33.0
+ 2.34.0
scm:git:git@github.com:googleapis/java-bigtable.git
@@ -81,14 +81,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.33.0
+ 2.34.0
pom
import
@@ -99,7 +99,7 @@
com.google.cloud
google-cloud-bigtable-emulator-core
- 0.170.0
+ 0.171.0
diff --git a/google-cloud-bigtable-stats/pom.xml b/google-cloud-bigtable-stats/pom.xml
index 051af90e048f..9c5895409fa4 100644
--- a/google-cloud-bigtable-stats/pom.xml
+++ b/google-cloud-bigtable-stats/pom.xml
@@ -5,7 +5,7 @@
com.google.cloud
google-cloud-bigtable-parent
- 2.33.0
+ 2.34.0
4.0.0
@@ -13,7 +13,7 @@
through Stackdriver. Built-in metrics will be implemented with shaded OpenCensus so it won't interfere with
customer's application metrics. -->
google-cloud-bigtable-stats
- 2.33.0
+ 2.34.0
Experimental project to shade OpenCensus dependencies.
@@ -21,7 +21,7 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
import
@@ -38,6 +38,10 @@
io.opencensus
opencensus-exporter-stats-stackdriver
+
+ io.opencensus
+ opencensus-contrib-resource-util
+
io.opencensus
opencensus-impl
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporter.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporter.java
index 325a07a0c5b6..e8b95e2ab0c5 100644
--- a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporter.java
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporter.java
@@ -33,14 +33,14 @@ final class BigtableCreateTimeSeriesExporter extends MetricExporter {
private static final Logger logger =
Logger.getLogger(BigtableCreateTimeSeriesExporter.class.getName());
private final MetricServiceClient metricServiceClient;
- private final MonitoredResource monitoredResource;
+ private final MonitoredResource gceOrGkeMonitoredResource;
private final String clientId;
BigtableCreateTimeSeriesExporter(
- MetricServiceClient metricServiceClient, MonitoredResource monitoredResource) {
+ MetricServiceClient metricServiceClient, MonitoredResource gceOrGkeMonitoredResource) {
this.metricServiceClient = metricServiceClient;
- this.monitoredResource = monitoredResource;
this.clientId = BigtableStackdriverExportUtils.getDefaultTaskValue();
+ this.gceOrGkeMonitoredResource = gceOrGkeMonitoredResource;
}
public void export(Collection metrics) {
@@ -48,7 +48,7 @@ public void export(Collection metrics) {
for (Metric metric : metrics) {
// only export bigtable metrics
- if (!metric.getMetricDescriptor().getName().contains("bigtable")) {
+ if (!BigtableStackdriverExportUtils.shouldExportMetric(metric.getMetricDescriptor())) {
continue;
}
@@ -65,7 +65,7 @@ public void export(Collection metrics) {
metric.getMetricDescriptor(),
timeSeries,
clientId,
- monitoredResource),
+ gceOrGkeMonitoredResource),
Collectors.toList())));
for (Map.Entry> entry :
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverExportUtils.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverExportUtils.java
index ff3e93158bd3..e7591f0062c2 100644
--- a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverExportUtils.java
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverExportUtils.java
@@ -15,6 +15,8 @@
*/
package com.google.cloud.bigtable.stats;
+import static com.google.cloud.bigtable.stats.BuiltinViewConstants.PER_CONNECTION_ERROR_COUNT_VIEW;
+
import com.google.api.Distribution.BucketOptions;
import com.google.api.Distribution.BucketOptions.Explicit;
import com.google.api.Metric;
@@ -52,7 +54,7 @@
import javax.annotation.Nullable;
class BigtableStackdriverExportUtils {
-
+ private static final String BIGTABLE_RESOURCE_TYPE = "bigtable_client_raw";
private static final Logger logger =
Logger.getLogger(BigtableStackdriverExportUtils.class.getName());
@@ -90,8 +92,8 @@ class BigtableStackdriverExportUtils {
return builder.build();
};
- // promote the following metric labels to monitored resource labels
- private static final Set PROMOTED_RESOURCE_LABELS =
+ // promote the following metric labels to Bigtable monitored resource labels
+ private static final Set PROMOTED_BIGTABLE_RESOURCE_LABELS =
ImmutableSet.of(
BuiltinMeasureConstants.PROJECT_ID.getName(),
BuiltinMeasureConstants.INSTANCE_ID.getName(),
@@ -102,17 +104,59 @@ class BigtableStackdriverExportUtils {
private static final LabelKey CLIENT_UID_LABEL_KEY =
LabelKey.create(BuiltinMeasureConstants.CLIENT_UID.getName(), "client uid");
+ static boolean isBigtableTableMetric(MetricDescriptor metricDescriptor) {
+ return metricDescriptor.getName().contains("bigtable")
+ && !metricDescriptor.getName().equals(PER_CONNECTION_ERROR_COUNT_VIEW.getName().asString());
+ }
+
+ static boolean shouldExportMetric(MetricDescriptor metricDescriptor) {
+ return isBigtableTableMetric(metricDescriptor)
+ || (metricDescriptor.getName().equals(PER_CONNECTION_ERROR_COUNT_VIEW.getName().asString())
+ && (ConsumerEnvironmentUtils.isEnvGce() || ConsumerEnvironmentUtils.isEnvGke()));
+ }
+
static com.google.monitoring.v3.TimeSeries convertTimeSeries(
MetricDescriptor metricDescriptor,
TimeSeries timeSeries,
String clientId,
- MonitoredResource monitoredResource) {
- String metricName = metricDescriptor.getName();
- List labelKeys = metricDescriptor.getLabelKeys();
+ MonitoredResource gceOrGkeMonitoredResource) {
Type metricType = metricDescriptor.getType();
- MonitoredResource.Builder monitoredResourceBuilder = monitoredResource.toBuilder();
+ com.google.monitoring.v3.TimeSeries.Builder builder;
+ if (isBigtableTableMetric(metricDescriptor)) {
+ builder =
+ setupBuilderForBigtableResource(
+ metricDescriptor,
+ MonitoredResource.newBuilder().setType(BIGTABLE_RESOURCE_TYPE),
+ timeSeries,
+ clientId);
+ } else if (ConsumerEnvironmentUtils.isEnvGce() || ConsumerEnvironmentUtils.isEnvGke()) {
+ builder =
+ setupBuilderForGceOrGKEResource(
+ metricDescriptor, gceOrGkeMonitoredResource, timeSeries, clientId);
+ } else {
+ logger.warning(
+ "Trying to export metric "
+ + metricDescriptor.getName()
+ + " in a non-GCE/GKE environment.");
+ return com.google.monitoring.v3.TimeSeries.newBuilder().build();
+ }
+ builder.setMetricKind(createMetricKind(metricType));
+ builder.setValueType(createValueType(metricType));
+ Timestamp startTimeStamp = timeSeries.getStartTimestamp();
+ for (Point point : timeSeries.getPoints()) {
+ builder.addPoints(createPoint(point, startTimeStamp));
+ }
+ return builder.build();
+ }
+ private static com.google.monitoring.v3.TimeSeries.Builder setupBuilderForBigtableResource(
+ MetricDescriptor metricDescriptor,
+ MonitoredResource.Builder monitoredResourceBuilder,
+ TimeSeries timeSeries,
+ String clientId) {
+ List labelKeys = metricDescriptor.getLabelKeys();
+ String metricName = metricDescriptor.getName();
List metricTagKeys = new ArrayList<>();
List metricTagValues = new ArrayList<>();
@@ -120,7 +164,7 @@ static com.google.monitoring.v3.TimeSeries convertTimeSeries(
for (int i = 0; i < labelValues.size(); i++) {
// If the label is defined in the monitored resource, convert it to
// a monitored resource label. Otherwise, keep it as a metric label.
- if (PROMOTED_RESOURCE_LABELS.contains(labelKeys.get(i).getKey())) {
+ if (PROMOTED_BIGTABLE_RESOURCE_LABELS.contains(labelKeys.get(i).getKey())) {
monitoredResourceBuilder.putLabels(
labelKeys.get(i).getKey(), labelValues.get(i).getValue());
} else {
@@ -135,13 +179,34 @@ static com.google.monitoring.v3.TimeSeries convertTimeSeries(
com.google.monitoring.v3.TimeSeries.newBuilder();
builder.setResource(monitoredResourceBuilder.build());
builder.setMetric(createMetric(metricName, metricTagKeys, metricTagValues));
- builder.setMetricKind(createMetricKind(metricType));
- builder.setValueType(createValueType(metricType));
- Timestamp startTimeStamp = timeSeries.getStartTimestamp();
- for (Point point : timeSeries.getPoints()) {
- builder.addPoints(createPoint(point, startTimeStamp));
+
+ return builder;
+ }
+
+ private static com.google.monitoring.v3.TimeSeries.Builder setupBuilderForGceOrGKEResource(
+ MetricDescriptor metricDescriptor,
+ MonitoredResource gceOrGkeMonitoredResource,
+ TimeSeries timeSeries,
+ String clientId) {
+ List labelKeys = metricDescriptor.getLabelKeys();
+ String metricName = metricDescriptor.getName();
+ List metricTagKeys = new ArrayList<>();
+ List metricTagValues = new ArrayList<>();
+
+ List labelValues = timeSeries.getLabelValues();
+ for (int i = 0; i < labelValues.size(); i++) {
+ metricTagKeys.add(labelKeys.get(i));
+ metricTagValues.add(labelValues.get(i));
}
- return builder.build();
+ metricTagKeys.add(CLIENT_UID_LABEL_KEY);
+ metricTagValues.add(LabelValue.create(clientId));
+
+ com.google.monitoring.v3.TimeSeries.Builder builder =
+ com.google.monitoring.v3.TimeSeries.newBuilder();
+ builder.setResource(gceOrGkeMonitoredResource);
+ builder.setMetric(createMetric(metricName, metricTagKeys, metricTagValues));
+
+ return builder;
}
static String getProjectId(MetricDescriptor metricDescriptor, TimeSeries timeSeries) {
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverStatsExporter.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverStatsExporter.java
index 76a36215c664..856353cfd0c9 100644
--- a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverStatsExporter.java
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BigtableStackdriverStatsExporter.java
@@ -28,6 +28,7 @@
import io.opencensus.common.Duration;
import io.opencensus.exporter.metrics.util.IntervalMetricReader;
import io.opencensus.exporter.metrics.util.MetricReader;
+import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration;
import io.opencensus.metrics.Metrics;
import java.io.IOException;
import javax.annotation.Nullable;
@@ -43,7 +44,6 @@ public class BigtableStackdriverStatsExporter {
// Default export interval is 1 minute
private static final Duration EXPORT_INTERVAL = Duration.create(60, 0);
- private static final String RESOURCE_TYPE = "bigtable_client_raw";
private static final String MONITORING_ENDPOINT =
MoreObjects.firstNonNull(
@@ -55,13 +55,13 @@ public class BigtableStackdriverStatsExporter {
private BigtableStackdriverStatsExporter(
MetricServiceClient metricServiceClient,
Duration exportInterval,
- MonitoredResource monitoredResource) {
+ MonitoredResource gceOrGkeMonitoredResource) {
IntervalMetricReader.Options.Builder intervalMetricReaderOptionsBuilder =
IntervalMetricReader.Options.builder();
intervalMetricReaderOptionsBuilder.setExportInterval(exportInterval);
this.intervalMetricReader =
IntervalMetricReader.create(
- new BigtableCreateTimeSeriesExporter(metricServiceClient, monitoredResource),
+ new BigtableCreateTimeSeriesExporter(metricServiceClient, gceOrGkeMonitoredResource),
MetricReader.create(
MetricReader.Options.builder()
.setMetricProducerManager(
@@ -76,9 +76,13 @@ public static void register(Credentials credentials) throws IOException {
instance == null, "Bigtable Stackdriver stats exporter is already created");
// Default timeout for creating a client is 1 minute
MetricServiceClient client = createMetricServiceClient(credentials, Duration.create(60L, 0));
- MonitoredResource resourceType =
- MonitoredResource.newBuilder().setType(RESOURCE_TYPE).build();
- instance = new BigtableStackdriverStatsExporter(client, EXPORT_INTERVAL, resourceType);
+ MonitoredResource gceOrGkeMonitoredResource = null;
+ if (ConsumerEnvironmentUtils.isEnvGce() || ConsumerEnvironmentUtils.isEnvGke()) {
+ gceOrGkeMonitoredResource =
+ StackdriverStatsConfiguration.builder().build().getMonitoredResource();
+ }
+ instance =
+ new BigtableStackdriverStatsExporter(client, EXPORT_INTERVAL, gceOrGkeMonitoredResource);
}
}
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViewConstants.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViewConstants.java
index 06364a228855..82ce61e2d383 100644
--- a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViewConstants.java
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViewConstants.java
@@ -15,7 +15,25 @@
*/
package com.google.cloud.bigtable.stats;
-import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.*;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.APPLICATION_LATENCIES;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.APP_PROFILE;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.ATTEMPT_LATENCIES;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.CLIENT_NAME;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.CLUSTER;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.CONNECTIVITY_ERROR_COUNT;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.FIRST_RESPONSE_LATENCIES;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.INSTANCE_ID;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.METHOD;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.OPERATION_LATENCIES;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.PER_CONNECTION_ERROR_COUNT;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.PROJECT_ID;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.RETRY_COUNT;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.SERVER_LATENCIES;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.STATUS;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.STREAMING;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.TABLE;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.THROTTLING_LATENCIES;
+import static com.google.cloud.bigtable.stats.BuiltinMeasureConstants.ZONE;
import static io.opencensus.stats.Aggregation.Distribution;
import static io.opencensus.stats.Aggregation.Sum;
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViews.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViews.java
index e62117cb7e07..2b91ee60c389 100644
--- a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViews.java
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinViews.java
@@ -37,12 +37,19 @@ public class BuiltinViews {
BuiltinViewConstants.CONNECTIVITY_ERROR_COUNT_VIEW,
BuiltinViewConstants.APPLICATION_LATENCIES_VIEW,
BuiltinViewConstants.THROTTLING_LATENCIES_VIEW);
+ // We store views that don't use the Bigtable schema and need different tags in a separate set to
+ // simplify testing.
+ static final ImmutableSet NON_BIGTABLE_BUILTIN_VIEWS =
+ ImmutableSet.of(BuiltinViewConstants.PER_CONNECTION_ERROR_COUNT_VIEW);
@VisibleForTesting
void registerPrivateViews(ViewManager viewManager) {
for (View view : BIGTABLE_BUILTIN_VIEWS) {
viewManager.registerView(view);
}
+ for (View view : NON_BIGTABLE_BUILTIN_VIEWS) {
+ viewManager.registerView(view);
+ }
}
public static void registerBigtableBuiltinViews() {
@@ -50,5 +57,8 @@ public static void registerBigtableBuiltinViews() {
for (View view : BIGTABLE_BUILTIN_VIEWS) {
viewManager.registerView(view);
}
+ for (View view : NON_BIGTABLE_BUILTIN_VIEWS) {
+ viewManager.registerView(view);
+ }
}
}
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/ConsumerEnvironmentUtils.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/ConsumerEnvironmentUtils.java
new file mode 100644
index 000000000000..6eeaa7326599
--- /dev/null
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/ConsumerEnvironmentUtils.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2024 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.stats;
+
+import com.google.common.annotations.VisibleForTesting;
+import io.opencensus.contrib.resource.util.CloudResource;
+import io.opencensus.contrib.resource.util.ContainerResource;
+import io.opencensus.contrib.resource.util.HostResource;
+import io.opencensus.contrib.resource.util.ResourceUtils;
+import io.opencensus.resource.Resource;
+import java.util.Objects;
+
+/** A class for extracting details about consumer environments (GCE and GKE) for metrics. */
+class ConsumerEnvironmentUtils {
+
+ private static ResourceUtilsWrapper resourceUtilsWrapper = new ResourceUtilsWrapper();
+
+ @VisibleForTesting
+ public static void setResourceUtilsWrapper(ResourceUtilsWrapper newResourceUtilsWrapper) {
+ resourceUtilsWrapper = newResourceUtilsWrapper;
+ }
+
+ public static boolean isEnvGce() {
+ Resource resource = resourceUtilsWrapper.detectResource();
+ return Objects.equals(resource.getType(), HostResource.TYPE)
+ && Objects.equals(
+ resource.getLabels().get(CloudResource.PROVIDER_KEY), CloudResource.PROVIDER_GCP);
+ }
+
+ public static boolean isEnvGke() {
+ Resource resource = resourceUtilsWrapper.detectResource();
+ return Objects.equals(resource.getType(), ContainerResource.TYPE)
+ && Objects.equals(
+ resource.getLabels().get(CloudResource.PROVIDER_KEY), CloudResource.PROVIDER_GCP);
+ }
+
+ // We wrap the static ResourceUtils.detectResource() method in a non-static method for mocking.
+ @VisibleForTesting
+ public static class ResourceUtilsWrapper {
+ public Resource detectResource() {
+ return ResourceUtils.detectResource();
+ }
+ }
+}
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/StatsRecorderWrapperForConnection.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/StatsRecorderWrapperForConnection.java
new file mode 100644
index 000000000000..3c335d28bca3
--- /dev/null
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/StatsRecorderWrapperForConnection.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2024 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.stats;
+
+import com.google.api.core.InternalApi;
+import io.opencensus.stats.MeasureMap;
+import io.opencensus.stats.StatsRecorder;
+import io.opencensus.tags.TagContext;
+import io.opencensus.tags.TagContextBuilder;
+import io.opencensus.tags.TagKey;
+import io.opencensus.tags.TagValue;
+import io.opencensus.tags.Tagger;
+import io.opencensus.tags.Tags;
+import java.util.Map;
+
+/** A wrapper to record built-in metrics for connection metrics not tied to operations/RPCs. */
+@InternalApi("For internal use only")
+public class StatsRecorderWrapperForConnection {
+ private final StatsRecorder statsRecorder;
+ private final TagContext tagContext;
+ private MeasureMap perConnectionErrorCountMeasureMap;
+
+ public StatsRecorderWrapperForConnection(
+ Map statsAttributes, StatsRecorder statsRecorder) {
+ this.statsRecorder = statsRecorder;
+
+ this.perConnectionErrorCountMeasureMap = statsRecorder.newMeasureMap();
+
+ Tagger tagger = Tags.getTagger();
+ TagContextBuilder tagContextBuilder = tagger.toBuilder(tagger.getCurrentTagContext());
+ for (Map.Entry entry : statsAttributes.entrySet()) {
+ tagContextBuilder.putLocal(TagKey.create(entry.getKey()), TagValue.create(entry.getValue()));
+ }
+ this.tagContext = tagContextBuilder.build();
+ }
+
+ public void putAndRecordPerConnectionErrorCount(long errorCount) {
+ perConnectionErrorCountMeasureMap.put(
+ BuiltinMeasureConstants.PER_CONNECTION_ERROR_COUNT, errorCount);
+
+ perConnectionErrorCountMeasureMap.record(tagContext);
+ perConnectionErrorCountMeasureMap = statsRecorder.newMeasureMap();
+ }
+}
diff --git a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/StatsWrapper.java b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/StatsWrapper.java
index 401a1cf97521..fc6a072d0162 100644
--- a/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/StatsWrapper.java
+++ b/google-cloud-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/StatsWrapper.java
@@ -40,6 +40,11 @@ public static StatsRecorderWrapper createRecorder(
operationType, spanName, statsAttributes, Stats.getStatsRecorder());
}
+ public static StatsRecorderWrapperForConnection createRecorderForConnection(
+ Map statsAttributes) {
+ return new StatsRecorderWrapperForConnection(statsAttributes, Stats.getStatsRecorder());
+ }
+
// This is used in integration tests to get the tag value strings from view manager because Stats
// is relocated to com.google.bigtable.veneer.repackaged.io.opencensus.
@InternalApi("Visible for testing")
@@ -56,7 +61,7 @@ public static List getOperationLatencyViewTagValueStrings() {
// the packaging step. Opencensus classes will be relocated when they are packaged but the
// integration test files will not be. So the integration tests can't reference any transitive
// dependencies that have been relocated.
- static Map> getViewToTagMap() {
+ static Map> getBigtableViewToTagMap() {
Map> map = new HashMap<>();
for (View view : BuiltinViews.BIGTABLE_BUILTIN_VIEWS) {
List tagKeys = view.getColumns();
diff --git a/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporterTest.java b/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporterTest.java
index 26654c09afa5..a0fb2ca0d1cb 100644
--- a/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporterTest.java
+++ b/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/BigtableCreateTimeSeriesExporterTest.java
@@ -23,9 +23,13 @@
import com.google.api.gax.rpc.UnaryCallable;
import com.google.cloud.monitoring.v3.MetricServiceClient;
import com.google.cloud.monitoring.v3.stub.MetricServiceStub;
+import com.google.common.collect.ImmutableMap;
import com.google.monitoring.v3.CreateTimeSeriesRequest;
import com.google.protobuf.Empty;
import io.opencensus.common.Timestamp;
+import io.opencensus.contrib.resource.util.CloudResource;
+import io.opencensus.contrib.resource.util.ContainerResource;
+import io.opencensus.contrib.resource.util.HostResource;
import io.opencensus.metrics.LabelKey;
import io.opencensus.metrics.LabelValue;
import io.opencensus.metrics.export.Metric;
@@ -33,6 +37,7 @@
import io.opencensus.metrics.export.Point;
import io.opencensus.metrics.export.TimeSeries;
import io.opencensus.metrics.export.Value;
+import io.opencensus.resource.Resource;
import java.util.Arrays;
import org.junit.After;
import org.junit.Before;
@@ -42,41 +47,39 @@
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@RunWith(JUnit4.class)
public class BigtableCreateTimeSeriesExporterTest {
- private static final String projectId = "fake-project";
- private static final String instanceId = "fake-instance";
+ private static final String bigtableProjectId = "fake-bigtable-project";
+ private static final String bigtableInstanceId = "fake-bigtable-instance";
private static final String appProfileId = "default";
private static final String tableId = "fake-table";
- private static final String zone = "us-east-1";
- private static final String cluster = "cluster-1";
+ private static final String bigtableZone = "us-east-1";
+ private static final String bigtableCluster = "cluster-1";
+ private static final String clientName = "client-name";
@Rule public final MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private MetricServiceStub mockMetricServiceStub;
private MetricServiceClient fakeMetricServiceClient;
- private BigtableCreateTimeSeriesExporter exporter;
@Before
public void setUp() {
fakeMetricServiceClient = new FakeMetricServiceClient(mockMetricServiceStub);
-
- exporter =
- new BigtableCreateTimeSeriesExporter(
- fakeMetricServiceClient,
- MonitoredResource.newBuilder().setType("bigtable-table").build());
}
@After
public void tearDown() {}
@Test
- public void testTimeSeries() {
+ public void testTimeSeriesForMetricWithBigtableResource() {
+ BigtableCreateTimeSeriesExporter exporter =
+ new BigtableCreateTimeSeriesExporter(fakeMetricServiceClient, null);
ArgumentCaptor argumentCaptor =
ArgumentCaptor.forClass(CreateTimeSeriesRequest.class);
@@ -89,7 +92,7 @@ public void testTimeSeries() {
Metric.create(
MetricDescriptor.create(
"bigtable/test",
- "descritpion",
+ "description",
"ms",
MetricDescriptor.Type.CUMULATIVE_DOUBLE,
Arrays.asList(
@@ -102,11 +105,11 @@ public void testTimeSeries() {
Arrays.asList(
TimeSeries.create(
Arrays.asList(
- LabelValue.create(projectId),
- LabelValue.create(instanceId),
+ LabelValue.create(bigtableProjectId),
+ LabelValue.create(bigtableInstanceId),
LabelValue.create(tableId),
- LabelValue.create(cluster),
- LabelValue.create(zone),
+ LabelValue.create(bigtableCluster),
+ LabelValue.create(bigtableZone),
LabelValue.create(appProfileId)),
Arrays.asList(
Point.create(
@@ -124,11 +127,11 @@ public void testTimeSeries() {
assertThat(timeSeries.getResource().getLabelsMap())
.containsExactly(
- BuiltinMeasureConstants.PROJECT_ID.getName(), projectId,
- BuiltinMeasureConstants.INSTANCE_ID.getName(), instanceId,
+ BuiltinMeasureConstants.PROJECT_ID.getName(), bigtableProjectId,
+ BuiltinMeasureConstants.INSTANCE_ID.getName(), bigtableInstanceId,
BuiltinMeasureConstants.TABLE.getName(), tableId,
- BuiltinMeasureConstants.CLUSTER.getName(), cluster,
- BuiltinMeasureConstants.ZONE.getName(), zone);
+ BuiltinMeasureConstants.CLUSTER.getName(), bigtableCluster,
+ BuiltinMeasureConstants.ZONE.getName(), bigtableZone);
assertThat(timeSeries.getMetric().getLabelsMap()).hasSize(2);
assertThat(timeSeries.getMetric().getLabelsMap())
@@ -139,6 +142,161 @@ public void testTimeSeries() {
assertThat(timeSeries.getPoints(0).getValue().getDoubleValue()).isEqualTo(fakeValue);
}
+ @Test
+ public void testTimeSeriesForMetricWithGceResource() {
+ BigtableCreateTimeSeriesExporter exporter =
+ new BigtableCreateTimeSeriesExporter(
+ fakeMetricServiceClient,
+ MonitoredResource.newBuilder()
+ .setType("gce-instance")
+ .putLabels("some-gce-key", "some-gce-value")
+ .build());
+ ArgumentCaptor argumentCaptor =
+ ArgumentCaptor.forClass(CreateTimeSeriesRequest.class);
+
+ UnaryCallable mockCallable = mock(UnaryCallable.class);
+ when(mockMetricServiceStub.createServiceTimeSeriesCallable()).thenReturn(mockCallable);
+ when(mockCallable.call(argumentCaptor.capture())).thenReturn(Empty.getDefaultInstance());
+
+ ConsumerEnvironmentUtils.ResourceUtilsWrapper resourceUtilsWrapperMock =
+ Mockito.mock(ConsumerEnvironmentUtils.ResourceUtilsWrapper.class);
+ ConsumerEnvironmentUtils.setResourceUtilsWrapper(resourceUtilsWrapperMock);
+ Mockito.when(resourceUtilsWrapperMock.detectResource())
+ .thenReturn(
+ Resource.create(
+ HostResource.TYPE,
+ ImmutableMap.of(CloudResource.PROVIDER_KEY, CloudResource.PROVIDER_GCP)));
+
+ double fakeValue = 10.0;
+ Metric fakeMetric =
+ Metric.create(
+ MetricDescriptor.create(
+ "bigtable.googleapis.com/internal/client/per_connection_error_count",
+ "description",
+ "ms",
+ MetricDescriptor.Type.CUMULATIVE_DOUBLE,
+ Arrays.asList(
+ LabelKey.create(BuiltinMeasureConstants.PROJECT_ID.getName(), ""),
+ LabelKey.create(BuiltinMeasureConstants.INSTANCE_ID.getName(), ""),
+ LabelKey.create(BuiltinMeasureConstants.APP_PROFILE.getName(), ""),
+ LabelKey.create(BuiltinMeasureConstants.CLIENT_NAME.getName(), ""))),
+ Arrays.asList(
+ TimeSeries.create(
+ Arrays.asList(
+ LabelValue.create(bigtableProjectId),
+ LabelValue.create(bigtableInstanceId),
+ LabelValue.create(appProfileId),
+ LabelValue.create(clientName)),
+ Arrays.asList(
+ Point.create(
+ Value.doubleValue(fakeValue),
+ Timestamp.fromMillis(System.currentTimeMillis()))),
+ Timestamp.fromMillis(System.currentTimeMillis()))));
+
+ exporter.export(Arrays.asList(fakeMetric));
+
+ CreateTimeSeriesRequest request = argumentCaptor.getValue();
+
+ assertThat(request.getTimeSeriesList()).hasSize(1);
+
+ com.google.monitoring.v3.TimeSeries timeSeries = request.getTimeSeriesList().get(0);
+
+ assertThat(timeSeries.getResource().getLabelsMap())
+ .containsExactly("some-gce-key", "some-gce-value");
+
+ assertThat(timeSeries.getMetric().getLabelsMap()).hasSize(5);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.PROJECT_ID.getName(), bigtableProjectId);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.INSTANCE_ID.getName(), bigtableInstanceId);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.APP_PROFILE.getName(), appProfileId);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.CLIENT_NAME.getName(), clientName);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsKey(BuiltinMeasureConstants.CLIENT_UID.getName());
+
+ assertThat(timeSeries.getPoints(0).getValue().getDoubleValue()).isEqualTo(fakeValue);
+ }
+
+ @Test
+ public void testTimeSeriesForMetricWithGkeResource() {
+ BigtableCreateTimeSeriesExporter exporter =
+ new BigtableCreateTimeSeriesExporter(
+ fakeMetricServiceClient,
+ MonitoredResource.newBuilder()
+ .setType("gke-container")
+ .putLabels("some-gke-key", "some-gke-value")
+ .build());
+ ArgumentCaptor argumentCaptor =
+ ArgumentCaptor.forClass(CreateTimeSeriesRequest.class);
+
+ UnaryCallable mockCallable = mock(UnaryCallable.class);
+ when(mockMetricServiceStub.createServiceTimeSeriesCallable()).thenReturn(mockCallable);
+ when(mockCallable.call(argumentCaptor.capture())).thenReturn(Empty.getDefaultInstance());
+
+ ConsumerEnvironmentUtils.ResourceUtilsWrapper resourceUtilsWrapperMock =
+ Mockito.mock(ConsumerEnvironmentUtils.ResourceUtilsWrapper.class);
+ ConsumerEnvironmentUtils.setResourceUtilsWrapper(resourceUtilsWrapperMock);
+
+ Mockito.when(resourceUtilsWrapperMock.detectResource())
+ .thenReturn(
+ Resource.create(
+ ContainerResource.TYPE,
+ ImmutableMap.of(CloudResource.PROVIDER_KEY, CloudResource.PROVIDER_GCP)));
+
+ double fakeValue = 10.0;
+ Metric fakeMetric =
+ Metric.create(
+ MetricDescriptor.create(
+ "bigtable.googleapis.com/internal/client/per_connection_error_count",
+ "description",
+ "ms",
+ MetricDescriptor.Type.CUMULATIVE_DOUBLE,
+ Arrays.asList(
+ LabelKey.create(BuiltinMeasureConstants.PROJECT_ID.getName(), ""),
+ LabelKey.create(BuiltinMeasureConstants.INSTANCE_ID.getName(), ""),
+ LabelKey.create(BuiltinMeasureConstants.APP_PROFILE.getName(), ""),
+ LabelKey.create(BuiltinMeasureConstants.CLIENT_NAME.getName(), ""))),
+ Arrays.asList(
+ TimeSeries.create(
+ Arrays.asList(
+ LabelValue.create(bigtableProjectId),
+ LabelValue.create(bigtableInstanceId),
+ LabelValue.create(appProfileId),
+ LabelValue.create(clientName)),
+ Arrays.asList(
+ Point.create(
+ Value.doubleValue(fakeValue),
+ Timestamp.fromMillis(System.currentTimeMillis()))),
+ Timestamp.fromMillis(System.currentTimeMillis()))));
+
+ exporter.export(Arrays.asList(fakeMetric));
+
+ CreateTimeSeriesRequest request = argumentCaptor.getValue();
+
+ assertThat(request.getTimeSeriesList()).hasSize(1);
+
+ com.google.monitoring.v3.TimeSeries timeSeries = request.getTimeSeriesList().get(0);
+
+ assertThat(timeSeries.getResource().getLabelsMap())
+ .containsExactly("some-gke-key", "some-gke-value");
+
+ assertThat(timeSeries.getMetric().getLabelsMap()).hasSize(5);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.PROJECT_ID.getName(), bigtableProjectId);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.INSTANCE_ID.getName(), bigtableInstanceId);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.APP_PROFILE.getName(), appProfileId);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsAtLeast(BuiltinMeasureConstants.CLIENT_NAME.getName(), clientName);
+ assertThat(timeSeries.getMetric().getLabelsMap())
+ .containsKey(BuiltinMeasureConstants.CLIENT_UID.getName());
+
+ assertThat(timeSeries.getPoints(0).getValue().getDoubleValue()).isEqualTo(fakeValue);
+ }
+
private class FakeMetricServiceClient extends MetricServiceClient {
protected FakeMetricServiceClient(MetricServiceStub stub) {
diff --git a/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/ITBuiltinViewConstantsTest.java b/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/ITBuiltinViewConstantsTest.java
index 929ee85f481a..c2dcc2a60290 100644
--- a/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/ITBuiltinViewConstantsTest.java
+++ b/google-cloud-bigtable-stats/src/test/java/com/google/cloud/bigtable/stats/ITBuiltinViewConstantsTest.java
@@ -27,7 +27,7 @@
public class ITBuiltinViewConstantsTest {
@Test
public void testBasicTagsExistForAllViews() {
- Map> viewToTagMap = StatsWrapper.getViewToTagMap();
+ Map> viewToTagMap = StatsWrapper.getBigtableViewToTagMap();
for (String view : viewToTagMap.keySet()) {
assertWithMessage(view + " should have all basic tags")
.that(viewToTagMap.get(view))
diff --git a/google-cloud-bigtable/pom.xml b/google-cloud-bigtable/pom.xml
index f16e2545785c..a7f8a019488e 100644
--- a/google-cloud-bigtable/pom.xml
+++ b/google-cloud-bigtable/pom.xml
@@ -2,7 +2,7 @@
4.0.0
google-cloud-bigtable
- 2.33.0
+ 2.34.0
jar
Google Cloud Bigtable
https://github.com/googleapis/java-bigtable
@@ -12,11 +12,11 @@
com.google.cloud
google-cloud-bigtable-parent
- 2.33.0
+ 2.34.0
- 2.33.0
+ 2.34.0
google-cloud-bigtable
@@ -39,7 +39,7 @@
1.61.1
- 3.25.2
+ 3.25.3
@@ -47,14 +47,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.33.0
+ 2.34.0
pom
import
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java
index d173d005454f..6cf2b635541e 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java
@@ -20,6 +20,6 @@
@InternalApi("For internal use only")
public final class Version {
// {x-version-update-start:google-cloud-bigtable:current}
- public static String VERSION = "2.33.0";
+ public static String VERSION = "2.34.0";
// {x-version-update-end}
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClient.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClient.java
index 29b32cd70a0c..749947a6f6e7 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClient.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminSettings.java
index 9d7916eadaf6..65b582f74a1e 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
import static com.google.cloud.bigtable.admin.v2.BaseBigtableInstanceAdminClient.ListHotTabletsPagedResponse;
import com.google.api.core.ApiFunction;
-import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.api.gax.core.GoogleCredentialsProvider;
import com.google.api.gax.core.InstantiatingExecutorProvider;
@@ -260,7 +259,6 @@ public static TransportChannelProvider defaultTransportChannelProvider() {
return BigtableInstanceAdminStubSettings.defaultTransportChannelProvider();
}
- @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
return BigtableInstanceAdminStubSettings.defaultApiClientHeaderProviderBuilder();
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClient.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClient.java
index ea426279358c..ff409bfa9c04 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClient.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminSettings.java
index 3b1ae503f156..97d92cbc2dfe 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
import static com.google.cloud.bigtable.admin.v2.BaseBigtableTableAdminClient.ListTablesPagedResponse;
import com.google.api.core.ApiFunction;
-import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.api.gax.core.GoogleCredentialsProvider;
import com.google.api.gax.core.InstantiatingExecutorProvider;
@@ -298,7 +297,6 @@ public static TransportChannelProvider defaultTransportChannelProvider() {
return BigtableTableAdminStubSettings.defaultTransportChannelProvider();
}
- @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
return BigtableTableAdminStubSettings.defaultApiClientHeaderProviderBuilder();
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStub.java
index c31d11d09860..7b066da10dc9 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStubSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStubSettings.java
index 7bdd5efce2e0..dc34cead80ab 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStubSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableInstanceAdminStubSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -508,7 +508,6 @@ public static TransportChannelProvider defaultTransportChannelProvider() {
return defaultGrpcTransportProviderBuilder().build();
}
- @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
return ApiClientHeaderProvider.newBuilder()
.setGeneratedLibToken(
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStub.java
index 4b80937e5469..2bc5da6eda23 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStubSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStubSettings.java
index ddefaba91f3b..043ee375b9fb 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStubSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/BigtableTableAdminStubSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -596,7 +596,6 @@ public static TransportChannelProvider defaultTransportChannelProvider() {
return defaultGrpcTransportProviderBuilder().build();
}
- @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
return ApiClientHeaderProvider.newBuilder()
.setGeneratedLibToken(
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminCallableFactory.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminCallableFactory.java
index 52d778122edf..b76b0933ca59 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminCallableFactory.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminCallableFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminStub.java
index 945f882a6f71..76d82e57eaee 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableInstanceAdminStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminCallableFactory.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminCallableFactory.java
index 6508d54e6879..70559ba873f0 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminCallableFactory.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminCallableFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminStub.java
index 6c24bc9fbce7..cca28bbd7b92 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/GrpcBigtableTableAdminStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStub.java
index dfc5764db5f9..01bc5d9e8574 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java
index 55c33dd14f3a..075c096c84bf 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableStubSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package com.google.cloud.bigtable.data.v2.stub;
import com.google.api.core.ApiFunction;
-import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.api.gax.core.GaxProperties;
import com.google.api.gax.core.GoogleCredentialsProvider;
@@ -211,7 +210,6 @@ public static TransportChannelProvider defaultTransportChannelProvider() {
return defaultGrpcTransportProviderBuilder().build();
}
- @BetaApi("The surface for customizing headers is not stable yet and may change in the future.")
public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder() {
return ApiClientHeaderProvider.newBuilder()
.setGeneratedLibToken("gapic", GaxProperties.getLibraryVersion(BigtableStubSettings.class))
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java
index 9fb906c2d174..ef37dd4e48e0 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java
@@ -15,6 +15,7 @@
*/
package com.google.cloud.bigtable.data.v2.stub;
+import com.google.api.core.ApiFunction;
import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.api.gax.batching.Batcher;
@@ -94,6 +95,7 @@
import com.google.cloud.bigtable.data.v2.stub.metrics.BigtableTracerUnaryCallable;
import com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsTracerFactory;
import com.google.cloud.bigtable.data.v2.stub.metrics.CompositeTracerFactory;
+import com.google.cloud.bigtable.data.v2.stub.metrics.ErrorCountPerConnectionMetricTracker;
import com.google.cloud.bigtable.data.v2.stub.metrics.MetricsTracerFactory;
import com.google.cloud.bigtable.data.v2.stub.metrics.RpcMeasureConstants;
import com.google.cloud.bigtable.data.v2.stub.metrics.StatsHeadersServerStreamingCallable;
@@ -117,6 +119,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.protobuf.ByteString;
+import io.grpc.ManagedChannelBuilder;
import io.opencensus.stats.Stats;
import io.opencensus.stats.StatsRecorder;
import io.opencensus.tags.TagKey;
@@ -149,7 +152,6 @@
public class EnhancedBigtableStub implements AutoCloseable {
private static final String CLIENT_NAME = "Bigtable";
private static final long FLOW_CONTROL_ADJUSTING_INTERVAL_MS = TimeUnit.SECONDS.toMillis(20);
-
private final EnhancedBigtableStubSettings settings;
private final ClientContext clientContext;
@@ -176,7 +178,6 @@ public class EnhancedBigtableStub implements AutoCloseable {
public static EnhancedBigtableStub create(EnhancedBigtableStubSettings settings)
throws IOException {
-
settings = settings.toBuilder().setTracerFactory(createBigtableTracerFactory(settings)).build();
ClientContext clientContext = createClientContext(settings);
@@ -204,10 +205,27 @@ public static ClientContext createClientContext(EnhancedBigtableStubSettings set
? ((InstantiatingGrpcChannelProvider) builder.getTransportChannelProvider()).toBuilder()
: null;
- if (builder.getEnableRoutingCookie() && transportProvider != null) {
- // TODO: this also need to be added to BigtableClientFactory
- // patch cookies interceptor
- transportProvider.setInterceptorProvider(() -> ImmutableList.of(new CookiesInterceptor()));
+ ErrorCountPerConnectionMetricTracker errorCountPerConnectionMetricTracker;
+ if (transportProvider != null) {
+ errorCountPerConnectionMetricTracker =
+ new ErrorCountPerConnectionMetricTracker(createBuiltinAttributes(builder));
+ ApiFunction oldChannelConfigurator =
+ transportProvider.getChannelConfigurator();
+ transportProvider.setChannelConfigurator(
+ managedChannelBuilder -> {
+ if (settings.getEnableRoutingCookie()) {
+ managedChannelBuilder.intercept(new CookiesInterceptor());
+ }
+
+ managedChannelBuilder.intercept(errorCountPerConnectionMetricTracker.getInterceptor());
+
+ if (oldChannelConfigurator != null) {
+ managedChannelBuilder = oldChannelConfigurator.apply(managedChannelBuilder);
+ }
+ return managedChannelBuilder;
+ });
+ } else {
+ errorCountPerConnectionMetricTracker = null;
}
// Inject channel priming
@@ -233,7 +251,12 @@ public static ClientContext createClientContext(EnhancedBigtableStubSettings set
builder.setTransportChannelProvider(transportProvider.build());
}
- return ClientContext.create(builder.build());
+ ClientContext clientContext = ClientContext.create(builder.build());
+ if (errorCountPerConnectionMetricTracker != null) {
+ errorCountPerConnectionMetricTracker.startConnectionErrorCountTracker(
+ clientContext.getExecutor());
+ }
+ return clientContext;
}
public static ApiTracerFactory createBigtableTracerFactory(
@@ -254,13 +277,7 @@ public static ApiTracerFactory createBigtableTracerFactory(
.put(RpcMeasureConstants.BIGTABLE_INSTANCE_ID, TagValue.create(instanceId))
.put(RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID, TagValue.create(appProfileId))
.build();
- ImmutableMap builtinAttributes =
- ImmutableMap.builder()
- .put("project_id", projectId)
- .put("instance", instanceId)
- .put("app_profile", appProfileId)
- .put("client_name", "bigtable-java/" + Version.VERSION)
- .build();
+ ImmutableMap builtinAttributes = createBuiltinAttributes(settings.toBuilder());
return new CompositeTracerFactory(
ImmutableList.of(
@@ -283,6 +300,16 @@ public static ApiTracerFactory createBigtableTracerFactory(
settings.getTracerFactory()));
}
+ private static ImmutableMap createBuiltinAttributes(
+ EnhancedBigtableStubSettings.Builder builder) {
+ return ImmutableMap.builder()
+ .put("project_id", builder.getProjectId())
+ .put("instance", builder.getInstanceId())
+ .put("app_profile", builder.getAppProfileId())
+ .put("client_name", "bigtable-java/" + Version.VERSION)
+ .build();
+ }
+
private static void patchCredentials(EnhancedBigtableStubSettings.Builder settings)
throws IOException {
int i = settings.getEndpoint().lastIndexOf(":");
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java
index 44e4752cd515..9a5027c7402f 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java
@@ -652,7 +652,6 @@ private Builder() {
setCredentialsProvider(defaultCredentialsProviderBuilder().build());
this.enableRoutingCookie = true;
this.enableRetryInfo = true;
-
// Defaults provider
BigtableStubSettings.Builder baseDefaults = BigtableStubSettings.newBuilder();
@@ -772,7 +771,6 @@ private Builder(EnhancedBigtableStubSettings settings) {
jwtAudienceMapping = settings.jwtAudienceMapping;
enableRoutingCookie = settings.enableRoutingCookie;
enableRetryInfo = settings.enableRetryInfo;
-
// Per method settings.
readRowsSettings = settings.readRowsSettings.toBuilder();
readRowSettings = settings.readRowSettings.toBuilder();
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableCallableFactory.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableCallableFactory.java
index c8e3e133720b..ac688963aea3 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableCallableFactory.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableCallableFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableStub.java
index 4324f7c2b2d7..3c57d05fd0ba 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableStub.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/GrpcBigtableStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/ConnectionErrorCountInterceptor.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/ConnectionErrorCountInterceptor.java
new file mode 100644
index 000000000000..17fcf9018e90
--- /dev/null
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/ConnectionErrorCountInterceptor.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2024 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 io.grpc.CallOptions;
+import io.grpc.Channel;
+import io.grpc.ClientCall;
+import io.grpc.ClientInterceptor;
+import io.grpc.ForwardingClientCall;
+import io.grpc.ForwardingClientCallListener;
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor;
+import io.grpc.Status;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** An interceptor which counts the number of failed responses for a channel. */
+class ConnectionErrorCountInterceptor implements ClientInterceptor {
+ private static final Logger LOG =
+ Logger.getLogger(ConnectionErrorCountInterceptor.class.toString());
+ private final LongAdder numOfErrors;
+ private final LongAdder numOfSuccesses;
+
+ ConnectionErrorCountInterceptor() {
+ numOfErrors = new LongAdder();
+ numOfSuccesses = new LongAdder();
+ }
+
+ @Override
+ public ClientCall interceptCall(
+ MethodDescriptor methodDescriptor, CallOptions callOptions, Channel channel) {
+ return new ForwardingClientCall.SimpleForwardingClientCall(
+ channel.newCall(methodDescriptor, callOptions)) {
+ @Override
+ public void start(Listener responseListener, Metadata headers) {
+ super.start(
+ new ForwardingClientCallListener.SimpleForwardingClientCallListener(
+ responseListener) {
+ @Override
+ public void onClose(Status status, Metadata trailers) {
+ // Connection accounting is non-critical, so we log the exception, but let normal
+ // processing proceed.
+ try {
+ handleOnCloseUnsafe(status);
+ } catch (Throwable t) {
+ if (t instanceof InterruptedException) {
+ Thread.currentThread().interrupt();
+ }
+ LOG.log(
+ Level.WARNING, "Unexpected error while updating connection error stats", t);
+ }
+ super.onClose(status, trailers);
+ }
+
+ private void handleOnCloseUnsafe(Status status) {
+ if (status.isOk()) {
+ numOfSuccesses.increment();
+ } else {
+ numOfErrors.increment();
+ }
+ }
+ },
+ headers);
+ }
+ };
+ }
+
+ long getAndResetNumOfErrors() {
+ return numOfErrors.sumThenReset();
+ }
+
+ long getAndResetNumOfSuccesses() {
+ return numOfSuccesses.sumThenReset();
+ }
+}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/ErrorCountPerConnectionMetricTracker.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/ErrorCountPerConnectionMetricTracker.java
new file mode 100644
index 000000000000..cab3b0bbd0b0
--- /dev/null
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/ErrorCountPerConnectionMetricTracker.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2024 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.InternalApi;
+import com.google.cloud.bigtable.stats.StatsRecorderWrapperForConnection;
+import com.google.cloud.bigtable.stats.StatsWrapper;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
+import io.grpc.ClientInterceptor;
+import java.util.Collections;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/* Background task that goes through all connections and updates the errors_per_connection metric. */
+@InternalApi("For internal use only")
+public class ErrorCountPerConnectionMetricTracker implements Runnable {
+ private static final Integer PER_CONNECTION_ERROR_COUNT_PERIOD_SECONDS = 60;
+ private final Set connectionErrorCountInterceptors;
+ private final Object interceptorsLock = new Object();
+ // This is not final so that it can be updated and mocked during testing.
+ private StatsRecorderWrapperForConnection statsRecorderWrapperForConnection;
+
+ @VisibleForTesting
+ void setStatsRecorderWrapperForConnection(
+ StatsRecorderWrapperForConnection statsRecorderWrapperForConnection) {
+ this.statsRecorderWrapperForConnection = statsRecorderWrapperForConnection;
+ }
+
+ public ErrorCountPerConnectionMetricTracker(ImmutableMap builtinAttributes) {
+ connectionErrorCountInterceptors =
+ Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
+
+ this.statsRecorderWrapperForConnection =
+ StatsWrapper.createRecorderForConnection(builtinAttributes);
+ }
+
+ public void startConnectionErrorCountTracker(ScheduledExecutorService scheduler) {
+ scheduler.scheduleAtFixedRate(
+ this, 0, PER_CONNECTION_ERROR_COUNT_PERIOD_SECONDS, TimeUnit.SECONDS);
+ }
+
+ public ClientInterceptor getInterceptor() {
+ ConnectionErrorCountInterceptor connectionErrorCountInterceptor =
+ new ConnectionErrorCountInterceptor();
+ synchronized (interceptorsLock) {
+ connectionErrorCountInterceptors.add(connectionErrorCountInterceptor);
+ }
+ return connectionErrorCountInterceptor;
+ }
+
+ @Override
+ public void run() {
+ synchronized (interceptorsLock) {
+ for (ConnectionErrorCountInterceptor interceptor : connectionErrorCountInterceptors) {
+ long errors = interceptor.getAndResetNumOfErrors();
+ long successes = interceptor.getAndResetNumOfSuccesses();
+ // We avoid keeping track of inactive connections (i.e., without any failed or successful
+ // requests).
+ if (errors > 0 || successes > 0) {
+ // TODO: add a metric to also keep track of the number of successful requests per each
+ // connection.
+ statsRecorderWrapperForConnection.putAndRecordPerConnectionErrorCount(errors);
+ }
+ }
+ }
+ }
+}
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClientTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClientTest.java
index 8cf0894d4b55..777f0f7cbd78 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClientTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableInstanceAdminClientTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClientTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClientTest.java
index 2b49b476dabc..cdbac532006c 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClientTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BaseBigtableTableAdminClientTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdmin.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdmin.java
index 938277bdd89b..ffefe14a160f 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdmin.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdmin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdminImpl.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdminImpl.java
index 16df57486548..4a7e35e96a38 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdminImpl.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableInstanceAdminImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdmin.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdmin.java
index 3fe7174e729d..2b48974975ac 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdmin.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdmin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdminImpl.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdminImpl.java
index 8b87bc19f638..a315e72ccfd9 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdminImpl.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/MockBigtableTableAdminImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java
index edcda459381e..a35112b38049 100644
--- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactoryTest.java
@@ -266,7 +266,7 @@ public void testCreateWithRefreshingChannel() throws Exception {
factory.createForAppProfile("other-appprofile");
factory.createForInstance("other-project", "other-instance");
- // Make sure that only 1 instance is created for all clients
+ // Make sure that only 1 instance is created by each provider
Mockito.verify(credentialsProvider, Mockito.times(1)).getCredentials();
Mockito.verify(executorProvider, Mockito.times(1)).getExecutor();
Mockito.verify(watchdogProvider, Mockito.times(1)).getWatchdog();
diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/ErrorCountPerConnectionTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/ErrorCountPerConnectionTest.java
new file mode 100644
index 000000000000..a6670182b86c
--- /dev/null
+++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/ErrorCountPerConnectionTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2024 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 static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+
+import com.google.api.gax.core.FixedExecutorProvider;
+import com.google.api.gax.grpc.ChannelPoolSettings;
+import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.bigtable.v2.*;
+import com.google.cloud.bigtable.data.v2.BigtableDataSettings;
+import com.google.cloud.bigtable.data.v2.FakeServiceBuilder;
+import com.google.cloud.bigtable.data.v2.models.*;
+import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStub;
+import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStubSettings;
+import com.google.cloud.bigtable.stats.StatsRecorderWrapperForConnection;
+import io.grpc.Server;
+import io.grpc.Status;
+import io.grpc.StatusRuntimeException;
+import io.grpc.stub.StreamObserver;
+import java.util.List;
+import java.util.concurrent.ScheduledExecutorService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+@RunWith(JUnit4.class)
+public class ErrorCountPerConnectionTest {
+ private static final String SUCCESS_TABLE_NAME = "some-table";
+ private static final String ERROR_TABLE_NAME = "nonexistent-table";
+ private Server server;
+ private final FakeService fakeService = new FakeService();
+ private EnhancedBigtableStubSettings.Builder builder;
+ private ArgumentCaptor runnableCaptor;
+ private StatsRecorderWrapperForConnection statsRecorderWrapperForConnection;
+
+ @Before
+ public void setup() throws Exception {
+ server = FakeServiceBuilder.create(fakeService).start();
+
+ ScheduledExecutorService executors = Mockito.mock(ScheduledExecutorService.class);
+ builder =
+ BigtableDataSettings.newBuilderForEmulator(server.getPort())
+ .stubSettings()
+ .setBackgroundExecutorProvider(FixedExecutorProvider.create(executors))
+ .setProjectId("fake-project")
+ .setInstanceId("fake-instance");
+ runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ Mockito.when(
+ executors.scheduleAtFixedRate(runnableCaptor.capture(), anyLong(), anyLong(), any()))
+ .thenReturn(null);
+
+ statsRecorderWrapperForConnection = Mockito.mock(StatsRecorderWrapperForConnection.class);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (server != null) {
+ server.shutdown();
+ }
+ }
+
+ @Test
+ public void readWithOneChannel() throws Exception {
+ EnhancedBigtableStub stub = EnhancedBigtableStub.create(builder.build());
+ long errorCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ Query query;
+ if (i % 3 == 0) {
+ query = Query.create(ERROR_TABLE_NAME);
+ errorCount += 1;
+ } else {
+ query = Query.create(SUCCESS_TABLE_NAME);
+ }
+ try {
+ stub.readRowsCallable().call(query).iterator().hasNext();
+ } catch (Exception e) {
+ // noop
+ }
+ }
+ ArgumentCaptor errorCountCaptor = ArgumentCaptor.forClass(long.class);
+ Mockito.doNothing()
+ .when(statsRecorderWrapperForConnection)
+ .putAndRecordPerConnectionErrorCount(errorCountCaptor.capture());
+ runInterceptorTasksAndAssertCount();
+ List allErrorCounts = errorCountCaptor.getAllValues();
+ assertThat(allErrorCounts.size()).isEqualTo(1);
+ assertThat(allErrorCounts.get(0)).isEqualTo(errorCount);
+ }
+
+ @Test
+ public void readWithTwoChannels() throws Exception {
+ EnhancedBigtableStubSettings.Builder builderWithTwoChannels =
+ builder.setTransportChannelProvider(
+ ((InstantiatingGrpcChannelProvider) builder.getTransportChannelProvider())
+ .toBuilder()
+ .setChannelPoolSettings(ChannelPoolSettings.staticallySized(2))
+ .build());
+ EnhancedBigtableStub stub = EnhancedBigtableStub.create(builderWithTwoChannels.build());
+ long totalErrorCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ try {
+ if (i < 10) {
+ totalErrorCount += 1;
+ stub.readRowsCallable().call(Query.create(ERROR_TABLE_NAME)).iterator().hasNext();
+ } else {
+ stub.readRowsCallable().call(Query.create(SUCCESS_TABLE_NAME)).iterator().hasNext();
+ }
+ } catch (Exception e) {
+ // noop
+ }
+ }
+ ArgumentCaptor errorCountCaptor = ArgumentCaptor.forClass(long.class);
+ Mockito.doNothing()
+ .when(statsRecorderWrapperForConnection)
+ .putAndRecordPerConnectionErrorCount(errorCountCaptor.capture());
+ runInterceptorTasksAndAssertCount();
+
+ List allErrorCounts = errorCountCaptor.getAllValues();
+ assertThat(allErrorCounts.size()).isEqualTo(2);
+ // Requests get assigned to channels using a Round Robin algorithm, so half to each.
+ assertThat(allErrorCounts).containsExactly(totalErrorCount / 2, totalErrorCount / 2);
+ }
+
+ @Test
+ public void readOverTwoPeriods() throws Exception {
+ EnhancedBigtableStub stub = EnhancedBigtableStub.create(builder.build());
+ long errorCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ Query query;
+ if (i % 3 == 0) {
+ query = Query.create(ERROR_TABLE_NAME);
+ errorCount += 1;
+ } else {
+ query = Query.create(SUCCESS_TABLE_NAME);
+ }
+ try {
+ stub.readRowsCallable().call(query).iterator().hasNext();
+ } catch (Exception e) {
+ // noop
+ }
+ }
+ ArgumentCaptor errorCountCaptor = ArgumentCaptor.forClass(long.class);
+ Mockito.doNothing()
+ .when(statsRecorderWrapperForConnection)
+ .putAndRecordPerConnectionErrorCount(errorCountCaptor.capture());
+ runInterceptorTasksAndAssertCount();
+ List allErrorCounts = errorCountCaptor.getAllValues();
+ assertThat(allErrorCounts.size()).isEqualTo(1);
+ assertThat(allErrorCounts.get(0)).isEqualTo(errorCount);
+
+ errorCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ Query query;
+ if (i % 3 == 0) {
+ query = Query.create(SUCCESS_TABLE_NAME);
+ } else {
+ query = Query.create(ERROR_TABLE_NAME);
+ errorCount += 1;
+ }
+ try {
+ stub.readRowsCallable().call(query).iterator().hasNext();
+ } catch (Exception e) {
+ // noop
+ }
+ }
+ errorCountCaptor = ArgumentCaptor.forClass(long.class);
+ Mockito.doNothing()
+ .when(statsRecorderWrapperForConnection)
+ .putAndRecordPerConnectionErrorCount(errorCountCaptor.capture());
+ runInterceptorTasksAndAssertCount();
+ allErrorCounts = errorCountCaptor.getAllValues();
+ assertThat(allErrorCounts.size()).isEqualTo(1);
+ assertThat(allErrorCounts.get(0)).isEqualTo(errorCount);
+ }
+
+ @Test
+ public void ignoreInactiveConnection() throws Exception {
+ EnhancedBigtableStub stub = EnhancedBigtableStub.create(builder.build());
+
+ ArgumentCaptor errorCountCaptor = ArgumentCaptor.forClass(long.class);
+ Mockito.doNothing()
+ .when(statsRecorderWrapperForConnection)
+ .putAndRecordPerConnectionErrorCount(errorCountCaptor.capture());
+ runInterceptorTasksAndAssertCount();
+ List allErrorCounts = errorCountCaptor.getAllValues();
+ assertThat(allErrorCounts).isEmpty();
+ }
+
+ @Test
+ public void noFailedRequests() throws Exception {
+ EnhancedBigtableStub stub = EnhancedBigtableStub.create(builder.build());
+
+ for (int i = 0; i < 20; i++) {
+ try {
+ stub.readRowsCallable().call(Query.create(SUCCESS_TABLE_NAME)).iterator().hasNext();
+ } catch (Exception e) {
+ // noop
+ }
+ }
+ ArgumentCaptor errorCountCaptor = ArgumentCaptor.forClass(long.class);
+ Mockito.doNothing()
+ .when(statsRecorderWrapperForConnection)
+ .putAndRecordPerConnectionErrorCount(errorCountCaptor.capture());
+ runInterceptorTasksAndAssertCount();
+ List allErrorCounts = errorCountCaptor.getAllValues();
+ assertThat(allErrorCounts.size()).isEqualTo(1);
+ assertThat(allErrorCounts.get(0)).isEqualTo(0);
+ }
+
+ private void runInterceptorTasksAndAssertCount() {
+ int actualNumOfTasks = 0;
+ for (Runnable runnable : runnableCaptor.getAllValues()) {
+ if (runnable instanceof ErrorCountPerConnectionMetricTracker) {
+ ((ErrorCountPerConnectionMetricTracker) runnable)
+ .setStatsRecorderWrapperForConnection(statsRecorderWrapperForConnection);
+ runnable.run();
+ actualNumOfTasks++;
+ }
+ }
+ assertThat(actualNumOfTasks).isEqualTo(1);
+ }
+
+ static class FakeService extends BigtableGrpc.BigtableImplBase {
+ @Override
+ public void readRows(
+ ReadRowsRequest request, StreamObserver responseObserver) {
+ if (request.getTableName().contains(SUCCESS_TABLE_NAME)) {
+ responseObserver.onNext(ReadRowsResponse.getDefaultInstance());
+ responseObserver.onCompleted();
+ } else {
+ // Send a non-retriable error, since otherwise the client tries to use the mocked
+ // ScheduledExecutorService object for retyring, resulting in a hang.
+ StatusRuntimeException exception = new StatusRuntimeException(Status.INTERNAL);
+ responseObserver.onError(exception);
+ }
+ }
+ }
+}
diff --git a/grpc-google-cloud-bigtable-admin-v2/pom.xml b/grpc-google-cloud-bigtable-admin-v2/pom.xml
index b4da4d1bb2b7..61a78288c501 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.0
com.google.api.grpc
grpc-google-cloud-bigtable-admin-v2
- 2.33.0
+ 2.34.0
grpc-google-cloud-bigtable-admin-v2
GRPC library for grpc-google-cloud-bigtable-admin-v2
com.google.cloud
google-cloud-bigtable-parent
- 2.33.0
+ 2.34.0
@@ -18,14 +18,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.33.0
+ 2.34.0
pom
import
diff --git a/grpc-google-cloud-bigtable-v2/pom.xml b/grpc-google-cloud-bigtable-v2/pom.xml
index 5f0bb54e5303..134f752963f8 100644
--- a/grpc-google-cloud-bigtable-v2/pom.xml
+++ b/grpc-google-cloud-bigtable-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-bigtable-v2
- 2.33.0
+ 2.34.0
grpc-google-cloud-bigtable-v2
GRPC library for grpc-google-cloud-bigtable-v2
com.google.cloud
google-cloud-bigtable-parent
- 2.33.0
+ 2.34.0
@@ -18,14 +18,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.33.0
+ 2.34.0
pom
import
diff --git a/pom.xml b/pom.xml
index fd066df57324..f114d250160f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
google-cloud-bigtable-parent
pom
- 2.33.0
+ 2.34.0
Google Cloud Bigtable Parent
https://github.com/googleapis/java-bigtable
@@ -13,8 +13,8 @@
com.google.cloud
- google-cloud-shared-config
- 1.7.1
+ sdk-platform-java-config
+ 3.25.0
@@ -153,27 +153,27 @@
com.google.api.grpc
proto-google-cloud-bigtable-v2
- 2.33.0
+ 2.34.0
com.google.api.grpc
proto-google-cloud-bigtable-admin-v2
- 2.33.0
+ 2.34.0
com.google.api.grpc
grpc-google-cloud-bigtable-v2
- 2.33.0
+ 2.34.0
com.google.api.grpc
grpc-google-cloud-bigtable-admin-v2
- 2.33.0
+ 2.34.0
com.google.cloud
google-cloud-bigtable
- 2.33.0
+ 2.34.0
@@ -184,12 +184,12 @@
com.google.truth
truth
- 1.4.0
+ 1.4.1
com.google.truth.extensions
truth-proto-extension
- 1.4.0
+ 1.4.1
test
diff --git a/proto-google-cloud-bigtable-admin-v2/pom.xml b/proto-google-cloud-bigtable-admin-v2/pom.xml
index a7ee32ab5819..560c845e48df 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.0
com.google.api.grpc
proto-google-cloud-bigtable-admin-v2
- 2.33.0
+ 2.34.0
proto-google-cloud-bigtable-admin-v2
PROTO library for proto-google-cloud-bigtable-admin-v2
com.google.cloud
google-cloud-bigtable-parent
- 2.33.0
+ 2.34.0
@@ -18,14 +18,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.33.0
+ 2.34.0
pom
import
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/AppProfileName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/AppProfileName.java
index 2339e490b8b6..4e4eb28823e9 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/AppProfileName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/AppProfileName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/BackupName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/BackupName.java
index b23fd3ff4dd2..7e3c83907d9b 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/BackupName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/BackupName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ClusterName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ClusterName.java
index 139203975919..1b19c7d04faf 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ClusterName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ClusterName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/InstanceName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/InstanceName.java
index 427a8adc9471..16b4648ff0f5 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/InstanceName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/InstanceName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/LocationName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/LocationName.java
index 9fcb7d2f7143..7bb8a9d141bd 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/LocationName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/LocationName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ProjectName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ProjectName.java
index ad618981f282..b4f47f5bd97f 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ProjectName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/ProjectName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/SnapshotName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/SnapshotName.java
index add6051719f6..881075fe8c99 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/SnapshotName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/SnapshotName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/TableName.java b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/TableName.java
index 0167ebfba8b6..25337b915d29 100644
--- a/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/TableName.java
+++ b/proto-google-cloud-bigtable-admin-v2/src/main/java/com/google/bigtable/admin/v2/TableName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-v2/pom.xml b/proto-google-cloud-bigtable-v2/pom.xml
index 19e4dc2c17a7..8ad0f9a1dd39 100644
--- a/proto-google-cloud-bigtable-v2/pom.xml
+++ b/proto-google-cloud-bigtable-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-bigtable-v2
- 2.33.0
+ 2.34.0
proto-google-cloud-bigtable-v2
PROTO library for proto-google-cloud-bigtable-v2
com.google.cloud
google-cloud-bigtable-parent
- 2.33.0
+ 2.34.0
@@ -18,14 +18,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.33.0
+ 2.34.0
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.33.0
+ 2.34.0
pom
import
diff --git a/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/InstanceName.java b/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/InstanceName.java
index 7cf6525b1c92..cc4f7e627ba6 100644
--- a/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/InstanceName.java
+++ b/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/InstanceName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/TableName.java b/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/TableName.java
index b154274117f6..98f191234113 100644
--- a/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/TableName.java
+++ b/proto-google-cloud-bigtable-v2/src/main/java/com/google/bigtable/v2/TableName.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 Google LLC
+ * Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 89bb477c1bd8..bf1031e5c35a 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -29,7 +29,7 @@
com.google.cloud
google-cloud-bigtable
- 2.32.0
+ 2.33.0
@@ -42,7 +42,7 @@
com.google.truth
truth
- 1.4.0
+ 1.4.1
test
diff --git a/samples/native-image-sample/pom.xml b/samples/native-image-sample/pom.xml
index d74243faf1ef..cf4c6a7046ac 100644
--- a/samples/native-image-sample/pom.xml
+++ b/samples/native-image-sample/pom.xml
@@ -52,7 +52,7 @@
com.google.truth
truth
- 1.4.0
+ 1.4.1
test
@@ -89,7 +89,7 @@
org.graalvm.buildtools
junit-platform-native
- 0.10.0
+ 0.10.1
test
@@ -99,7 +99,7 @@
org.graalvm.buildtools
native-maven-plugin
- 0.10.0
+ 0.10.1
true
com.example.bigtable.NativeImageBigtableSample
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index 75bff46d331f..0a31424b2c45 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -28,7 +28,7 @@
com.google.cloud
google-cloud-bigtable
- 2.33.0
+ 2.34.0
@@ -41,7 +41,7 @@
com.google.truth
truth
- 1.4.0
+ 1.4.1
test
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index 12eea47633ea..ff96eeb442e6 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -53,7 +53,7 @@
com.google.truth
truth
- 1.4.0
+ 1.4.1
test
diff --git a/test-proxy/pom.xml b/test-proxy/pom.xml
index 6d5cb4287b6e..a93adda74155 100644
--- a/test-proxy/pom.xml
+++ b/test-proxy/pom.xml
@@ -12,11 +12,11 @@
google-cloud-bigtable-parent
com.google.cloud
- 2.33.0
+ 2.34.0
- 2.33.0
+ 2.34.0
diff --git a/versions.txt b/versions.txt
index a2bd1a07459c..0c117710626f 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,10 +1,10 @@
# Format:
# module:released-version:current-version
-google-cloud-bigtable:2.33.0:2.33.0
-grpc-google-cloud-bigtable-admin-v2:2.33.0:2.33.0
-grpc-google-cloud-bigtable-v2:2.33.0:2.33.0
-proto-google-cloud-bigtable-admin-v2:2.33.0:2.33.0
-proto-google-cloud-bigtable-v2:2.33.0:2.33.0
-google-cloud-bigtable-emulator:0.170.0:0.170.0
-google-cloud-bigtable-emulator-core:0.170.0:0.170.0
+google-cloud-bigtable:2.34.0:2.34.0
+grpc-google-cloud-bigtable-admin-v2:2.34.0:2.34.0
+grpc-google-cloud-bigtable-v2:2.34.0:2.34.0
+proto-google-cloud-bigtable-admin-v2:2.34.0:2.34.0
+proto-google-cloud-bigtable-v2:2.34.0:2.34.0
+google-cloud-bigtable-emulator:0.171.0:0.171.0
+google-cloud-bigtable-emulator-core:0.171.0:0.171.0