diff --git a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Client.java b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Client.java index b6f72659c092..4893d17eddf1 100644 --- a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Client.java +++ b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Client.java @@ -24,6 +24,7 @@ import com.google.bigtable.v2.OpenAuthorizedViewRequest; import com.google.bigtable.v2.OpenMaterializedViewRequest; import com.google.bigtable.v2.OpenTableRequest.Permission; +import com.google.cloud.bigtable.Version; import com.google.cloud.bigtable.data.v2.internal.api.ChannelProviders.ChannelProvider; import com.google.cloud.bigtable.data.v2.internal.api.ChannelProviders.ConfiguredChannelProvider; import com.google.cloud.bigtable.data.v2.internal.channels.ChannelPool; @@ -65,6 +66,8 @@ public class Client implements AutoCloseable { // up on it so close() returns. The watchdog interval is what makes the worst case finite. private static final Duration POOL_DRAIN_TIMEOUT = Duration.ofMinutes(6); + public static final String USER_AGENT = "bigtable-java/" + Version.VERSION; + public static final FeatureFlags BASE_FEATURE_FLAGS = FeatureFlags.newBuilder() .setReverseScans(false) @@ -113,6 +116,19 @@ public class Client implements AutoCloseable { // close() has already missed in its snapshot. private boolean closed = false; + public static ChannelProvider configureChannelProvider( + ChannelProvider channelProvider, Metrics metrics) { + return new ConfiguredChannelProvider( + channelProvider, + channelBuilder -> + metrics + .configureGrpcChannel(channelBuilder) + .userAgent(USER_AGENT) + .keepAliveTime(KEEPALIVE_TIME_MS, TimeUnit.MILLISECONDS) + .keepAliveTimeout(KEEPALIVE_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .maxInboundMessageSize(256 * 1024 * 1024)); + } + public static Client create(ClientSettings settings) throws IOException { FeatureFlags featureFlags = settings.getChannelProvider().updateFeatureFlags(BASE_FEATURE_FLAGS); @@ -156,6 +172,9 @@ public static Client create(ClientSettings settings) throws IOException { metrics.start(); } + ChannelProvider channelProvider = + configureChannelProvider(settings.getChannelProvider(), metrics); + ClientConfigurationManager configManager = null; try { @@ -163,7 +182,7 @@ public static Client create(ClientSettings settings) throws IOException { new ClientConfigurationManager( featureFlags, clientInfo, - settings.getChannelProvider(), + channelProvider, metrics.getDebugTagTracer(), backgroundExecutor); configManager.start().get(); @@ -193,7 +212,7 @@ public static Client create(ClientSettings settings) throws IOException { Resource.createOwned(backgroundExecutor, backgroundExecutor::shutdown), Resource.createOwned( userCallbackExecutor, () -> shutdownAndAwait(userCallbackExecutor)), - settings.getChannelProvider()); + channelProvider); } /** @@ -219,24 +238,9 @@ public Client( defaultCallOptions = CallOptions.DEFAULT; - ChannelProvider configuredChannelProvider = - new ConfiguredChannelProvider( - channelProvider, - channelBuilder -> - metrics - .get() - .configureGrpcChannel(channelBuilder) - .keepAliveTime(KEEPALIVE_TIME_MS, TimeUnit.MILLISECONDS) - .keepAliveTimeout(KEEPALIVE_TIMEOUT_MS, TimeUnit.MILLISECONDS) - // TODO: consider localizing this for large reads - .maxInboundMessageSize(256 * 1024 * 1024)); - SwitchingChannelPool switchingPool = new SwitchingChannelPool( - configuredChannelProvider, - configManager.get(), - metrics.get(), - backgroundExecutor.get()); + channelProvider, configManager.get(), metrics.get(), backgroundExecutor.get()); switchingPool.start(); this.channelPool = Resource.createOwned(switchingPool, switchingPool::close); } diff --git a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Util.java b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Util.java index fba8bd0b8710..c093b9967929 100644 --- a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Util.java +++ b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/api/Util.java @@ -18,6 +18,7 @@ import com.google.bigtable.v2.FeatureFlags; import com.google.bigtable.v2.Mutation; +import com.google.cloud.bigtable.Version; import io.grpc.Metadata; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -35,6 +36,11 @@ public class Util { private static final Metadata.Key FEATURE_FLAGS_KEY = Metadata.Key.of("bigtable-features", Metadata.ASCII_STRING_MARSHALLER); + private static final Metadata.Key API_CLIENT_KEY = + Metadata.Key.of("x-goog-api-client", Metadata.ASCII_STRING_MARSHALLER); + private static final String API_CLIENT_VALUE = + "gl-java/" + System.getProperty("java.version") + " gccl/" + Version.VERSION; + public static Metadata composeMetadata( FeatureFlags featureFlags, Map headerParams) { Metadata metadata = new Metadata(); @@ -59,6 +65,8 @@ public static Metadata composeMetadata( .map(e -> String.format("%s=%s", e.getKey(), urlEncode(e.getValue()))) .collect(Collectors.joining("&"))); + metadata.put(API_CLIENT_KEY, API_CLIENT_VALUE); + return metadata; } diff --git a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/compat/ShimImpl.java b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/compat/ShimImpl.java index 8db91d0a9308..86f91c57b274 100644 --- a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/compat/ShimImpl.java +++ b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/compat/ShimImpl.java @@ -33,7 +33,6 @@ import com.google.bigtable.v2.SessionReadModifyWriteRowResponse; import com.google.bigtable.v2.SessionReadRowResponse; import com.google.cloud.bigtable.data.v2.internal.api.ChannelProviders.ChannelProvider; -import com.google.cloud.bigtable.data.v2.internal.api.ChannelProviders.ConfiguredChannelProvider; import com.google.cloud.bigtable.data.v2.internal.api.Client; import com.google.cloud.bigtable.data.v2.internal.api.Client.Resource; import com.google.cloud.bigtable.data.v2.internal.channels.ChannelPool; @@ -72,7 +71,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -149,7 +147,7 @@ public static Shim create( // Channel provider for the client. DirectAccess with fallback by default. ChannelProvider clientChannelProvider = - configureChannelProvider( + Client.configureChannelProvider( GaxDirectAccessChannelProvider.createWithFallback( (InstantiatingGrpcChannelProvider) transportProvider, callCreds), metrics); @@ -158,7 +156,7 @@ public static Shim create( Client.BASE_FEATURE_FLAGS, clientInfo, clientChannelProvider, metrics, bgExecutor)) { // Directpath failed, revert to basic channel provider for the client. clientChannelProvider = - configureChannelProvider( + Client.configureChannelProvider( new GaxBasicChannelProvider( (InstantiatingGrpcChannelProvider) transportProvider, callCreds), metrics); @@ -166,7 +164,7 @@ public static Shim create( // ChannelProvider for configuration manager. ChannelProvider configChannelProvider = - configureChannelProvider( + Client.configureChannelProvider( new GaxBasicChannelProvider( (InstantiatingGrpcChannelProvider) transportProvider, callCreds), metrics); @@ -308,19 +306,6 @@ static Resource selectUserCallbackExecutor( return Resource.createOwned(owned, () -> Client.shutdownAndAwait(owned)); } - private static ChannelProvider configureChannelProvider( - ChannelProvider channelProvider, Metrics metrics) { - return new ConfiguredChannelProvider( - channelProvider, - channelBuilder -> - metrics - .configureGrpcChannel(channelBuilder) - .keepAliveTime(Client.KEEPALIVE_TIME_MS, TimeUnit.MILLISECONDS) - .keepAliveTimeout(Client.KEEPALIVE_TIMEOUT_MS, TimeUnit.MILLISECONDS) - // TODO: consider localizing this for large reads - .maxInboundMessageSize(256 * 1024 * 1024)); - } - private static boolean checkDirectAccessAvailable( FeatureFlags featureFlags, ClientInfo clientInfo,