diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 605555ecae..f5f585bcd0 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -33,6 +33,7 @@ retry_with_backoff 3 10 \ -DskipTests=true \ -Dclirr.skip=true \ -Denforcer.skip=true \ + -Dcheckstyle.skip=true \ -Dmaven.javadoc.skip=true \ -Dgcloud.download.skip=true \ -T 1C @@ -66,7 +67,8 @@ integration) -DtrimStackTrace=false \ -Dclirr.skip=true \ -Denforcer.skip=true \ - -fae \ + -Dcheckstyle.skip=true \ + -DskipUnitTests=true \ verify RETURN_CODE=$? ;; diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a450e7cae..974ce8dd2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [2.49.0](https://github.com/googleapis/java-bigtable/compare/v2.48.0...v2.49.0) (2024-12-03) + + +### Features + +* Add support for table deletion protection ([#2430](https://github.com/googleapis/java-bigtable/issues/2430)) ([687b6df](https://github.com/googleapis/java-bigtable/commit/687b6df14b743358e8207cda26022dfc75338d55)) + + +### Bug Fixes + +* Allow factory to export to different projects ([#2374](https://github.com/googleapis/java-bigtable/issues/2374)) ([06b912c](https://github.com/googleapis/java-bigtable/commit/06b912cc5d63436757008e79edfa8286b2ccac18)) +* Send priming requests on the channel directly ([#2435](https://github.com/googleapis/java-bigtable/issues/2435)) ([b76698d](https://github.com/googleapis/java-bigtable/commit/b76698dfb2c8552185f34e01e924ecc80798ba4f)) + ## [2.48.0](https://github.com/googleapis/java-bigtable/compare/v2.47.0...v2.48.0) (2024-11-19) diff --git a/README.md b/README.md index d114930c70..837665a4aa 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,13 @@ 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.48.0' +implementation 'com.google.cloud:google-cloud-bigtable:2.49.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-bigtable" % "2.48.0" +libraryDependencies += "com.google.cloud" % "google-cloud-bigtable" % "2.49.0" ``` ## Authentication @@ -543,7 +543,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.48.0 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigtable/2.49.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 fe5ae44bf1..e241a11534 100644 --- a/google-cloud-bigtable-bom/pom.xml +++ b/google-cloud-bigtable-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.cloud google-cloud-bigtable-bom - 2.48.1-SNAPSHOT + 2.49.0 pom com.google.cloud @@ -63,37 +63,37 @@ com.google.cloud google-cloud-bigtable - 2.48.1-SNAPSHOT + 2.49.0 com.google.cloud google-cloud-bigtable-emulator - 0.185.1-SNAPSHOT + 0.186.0 com.google.cloud google-cloud-bigtable-emulator-core - 0.185.1-SNAPSHOT + 0.186.0 com.google.api.grpc grpc-google-cloud-bigtable-admin-v2 - 2.48.1-SNAPSHOT + 2.49.0 com.google.api.grpc grpc-google-cloud-bigtable-v2 - 2.48.1-SNAPSHOT + 2.49.0 com.google.api.grpc proto-google-cloud-bigtable-admin-v2 - 2.48.1-SNAPSHOT + 2.49.0 com.google.api.grpc proto-google-cloud-bigtable-v2 - 2.48.1-SNAPSHOT + 2.49.0 diff --git a/google-cloud-bigtable-deps-bom/pom.xml b/google-cloud-bigtable-deps-bom/pom.xml index 90aaf3d691..8e59114a52 100644 --- a/google-cloud-bigtable-deps-bom/pom.xml +++ b/google-cloud-bigtable-deps-bom/pom.xml @@ -13,7 +13,7 @@ com.google.cloud google-cloud-bigtable-deps-bom - 2.48.1-SNAPSHOT + 2.49.0 pom diff --git a/google-cloud-bigtable-emulator-core/pom.xml b/google-cloud-bigtable-emulator-core/pom.xml index 25b50d954e..e320a64d24 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.48.1-SNAPSHOT + 2.49.0 google-cloud-bigtable-emulator-core - 0.185.1-SNAPSHOT + 0.186.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 2af777c013..ec853bf2a9 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.185.1-SNAPSHOT + 0.186.0 Google Cloud Java - Bigtable Emulator https://github.com/googleapis/java-bigtable @@ -14,7 +14,7 @@ com.google.cloud google-cloud-bigtable-parent - 2.48.1-SNAPSHOT + 2.49.0 scm:git:git@github.com:googleapis/java-bigtable.git @@ -81,14 +81,14 @@ com.google.cloud google-cloud-bigtable-deps-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import com.google.cloud google-cloud-bigtable-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import @@ -99,7 +99,7 @@ com.google.cloud google-cloud-bigtable-emulator-core - 0.185.1-SNAPSHOT + 0.186.0 diff --git a/google-cloud-bigtable/pom.xml b/google-cloud-bigtable/pom.xml index 7d027c995c..b4be0a9ef5 100644 --- a/google-cloud-bigtable/pom.xml +++ b/google-cloud-bigtable/pom.xml @@ -2,7 +2,7 @@ 4.0.0 google-cloud-bigtable - 2.48.1-SNAPSHOT + 2.49.0 jar Google Cloud Bigtable https://github.com/googleapis/java-bigtable @@ -12,11 +12,11 @@ com.google.cloud google-cloud-bigtable-parent - 2.48.1-SNAPSHOT + 2.49.0 - 2.48.1-SNAPSHOT + 2.49.0 google-cloud-bigtable @@ -52,14 +52,14 @@ com.google.cloud google-cloud-bigtable-deps-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import com.google.cloud google-cloud-bigtable-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import @@ -709,7 +709,6 @@ grpc-auth is not directly used transitively, but is pulled to align with other grpc parts opencensus-impl-core is brought in transitively through opencensus-impl --> - io.grpc:grpc-auth io.opencensus:opencensus-impl-core 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 ff7568bbd6..21bdfd5e09 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.48.1-SNAPSHOT"; + public static String VERSION = "2.49.0"; // {x-version-update-end} } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimer.java index ecbef85be5..7495ca6ceb 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimer.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimer.java @@ -16,18 +16,27 @@ package com.google.cloud.bigtable.data.v2.stub; import com.google.api.core.BetaApi; -import com.google.api.gax.core.FixedCredentialsProvider; -import com.google.api.gax.core.InstantiatingExecutorProvider; +import com.google.api.core.SettableApiFuture; import com.google.api.gax.grpc.ChannelPrimer; -import com.google.api.gax.grpc.GrpcTransportChannel; -import com.google.api.gax.rpc.FixedTransportChannelProvider; import com.google.auth.Credentials; +import com.google.bigtable.v2.BigtableGrpc; +import com.google.bigtable.v2.InstanceName; import com.google.bigtable.v2.PingAndWarmRequest; -import com.google.cloud.bigtable.data.v2.internal.NameUtil; -import com.google.common.base.Preconditions; +import com.google.bigtable.v2.PingAndWarmResponse; +import io.grpc.CallCredentials; +import io.grpc.CallOptions; +import io.grpc.ClientCall; +import io.grpc.Deadline; import io.grpc.ManagedChannel; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.auth.MoreCallCredentials; import java.io.IOException; -import java.util.concurrent.ExecutionException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -41,27 +50,40 @@ class BigtableChannelPrimer implements ChannelPrimer { private static Logger LOG = Logger.getLogger(BigtableChannelPrimer.class.toString()); - private final EnhancedBigtableStubSettings settingsTemplate; + static final Metadata.Key REQUEST_PARAMS = + Metadata.Key.of("x-goog-request-params", Metadata.ASCII_STRING_MARSHALLER); + private final PingAndWarmRequest request; + private final CallCredentials callCredentials; + private final Map headers; static BigtableChannelPrimer create( - Credentials credentials, String projectId, String instanceId, String appProfileId) { - EnhancedBigtableStubSettings.Builder builder = - EnhancedBigtableStubSettings.newBuilder() - .setProjectId(projectId) - .setInstanceId(instanceId) - .setAppProfileId(appProfileId) - .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) - // Disable refreshing channel here to avoid creating settings in a loop - .setRefreshingChannel(false) - .setExecutorProvider( - InstantiatingExecutorProvider.newBuilder().setExecutorThreadCount(1).build()); - - return new BigtableChannelPrimer(builder.build()); + String projectId, + String instanceId, + String appProfileId, + Credentials credentials, + Map headers) { + return new BigtableChannelPrimer(projectId, instanceId, appProfileId, credentials, headers); } - private BigtableChannelPrimer(EnhancedBigtableStubSettings settingsTemplate) { - Preconditions.checkNotNull(settingsTemplate, "settingsTemplate can't be null"); - this.settingsTemplate = settingsTemplate; + BigtableChannelPrimer( + String projectId, + String instanceId, + String appProfileId, + Credentials credentials, + Map headers) { + if (credentials != null) { + callCredentials = MoreCallCredentials.from(credentials); + } else { + callCredentials = null; + } + + request = + PingAndWarmRequest.newBuilder() + .setName(InstanceName.format(projectId, instanceId)) + .setAppProfileId(appProfileId) + .build(); + + this.headers = headers; } @Override @@ -69,8 +91,7 @@ public void primeChannel(ManagedChannel managedChannel) { try { primeChannelUnsafe(managedChannel); } catch (IOException | RuntimeException e) { - LOG.warning( - String.format("Unexpected error while trying to prime a channel: %s", e.getMessage())); + LOG.log(Level.WARNING, "Unexpected error while trying to prime a channel", e); } } @@ -78,35 +99,64 @@ private void primeChannelUnsafe(ManagedChannel managedChannel) throws IOExceptio sendPrimeRequests(managedChannel); } - private void sendPrimeRequests(ManagedChannel managedChannel) throws IOException { - // Wrap the channel in a temporary stub - EnhancedBigtableStubSettings primingSettings = - settingsTemplate - .toBuilder() - .setTransportChannelProvider( - FixedTransportChannelProvider.create(GrpcTransportChannel.create(managedChannel))) - .build(); + private void sendPrimeRequests(ManagedChannel managedChannel) { + try { + ClientCall clientCall = + managedChannel.newCall( + BigtableGrpc.getPingAndWarmMethod(), + CallOptions.DEFAULT + .withCallCredentials(callCredentials) + .withDeadline(Deadline.after(1, TimeUnit.MINUTES))); - try (EnhancedBigtableStub stub = EnhancedBigtableStub.create(primingSettings)) { - PingAndWarmRequest request = - PingAndWarmRequest.newBuilder() - .setName( - NameUtil.formatInstanceName( - primingSettings.getProjectId(), primingSettings.getInstanceId())) - .setAppProfileId(primingSettings.getAppProfileId()) - .build(); - - try { - stub.pingAndWarmCallable().call(request); - } catch (Throwable e) { - // TODO: Not sure if we should swallow the error here. We are pre-emptively swapping - // channels if the new - // channel is bad. - if (e instanceof ExecutionException) { - e = e.getCause(); - } - LOG.warning(String.format("Failed to prime channel: %s", e)); - } + SettableApiFuture future = SettableApiFuture.create(); + clientCall.start( + new ClientCall.Listener() { + PingAndWarmResponse response; + + @Override + public void onMessage(PingAndWarmResponse message) { + response = message; + } + + @Override + public void onClose(Status status, Metadata trailers) { + if (status.isOk()) { + future.set(response); + } else { + future.setException(status.asException()); + } + } + }, + createMetadata(headers, request)); + clientCall.sendMessage(request); + clientCall.halfClose(); + clientCall.request(Integer.MAX_VALUE); + + future.get(1, TimeUnit.MINUTES); + } catch (Throwable e) { + // TODO: Not sure if we should swallow the error here. We are pre-emptively swapping + // channels if the new + // channel is bad. + LOG.log(Level.WARNING, "Failed to prime channel", e); } } + + private static Metadata createMetadata(Map headers, PingAndWarmRequest request) { + Metadata metadata = new Metadata(); + + headers.forEach( + (k, v) -> metadata.put(Metadata.Key.of(k, Metadata.ASCII_STRING_MARSHALLER), v)); + try { + metadata.put( + REQUEST_PARAMS, + String.format( + "name=%s&app_profile_id=%s", + URLEncoder.encode(request.getName(), "UTF-8"), + URLEncoder.encode(request.getAppProfileId(), "UTF-8"))); + } catch (UnsupportedEncodingException e) { + LOG.log(Level.WARNING, "Failed to encode request params", e); + } + + return metadata; + } } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java index a8e18f364e..a2587b0dd9 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java @@ -100,10 +100,11 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings if (builder.isRefreshingChannel()) { transportProvider.setChannelPrimer( BigtableChannelPrimer.create( + builder.getProjectId(), + builder.getInstanceId(), + builder.getAppProfileId(), credentials, - settings.getProjectId(), - settings.getInstanceId(), - settings.getAppProfileId())); + builder.getHeaderProvider().getHeaders())); } builder.setTransportChannelProvider(transportProvider.build()); 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 5cab91c92c..46377fbc41 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 @@ -61,8 +61,6 @@ import com.google.bigtable.v2.GenerateInitialChangeStreamPartitionsResponse; import com.google.bigtable.v2.MutateRowsRequest; import com.google.bigtable.v2.MutateRowsResponse; -import com.google.bigtable.v2.PingAndWarmRequest; -import com.google.bigtable.v2.PingAndWarmResponse; import com.google.bigtable.v2.ReadChangeStreamRequest; import com.google.bigtable.v2.ReadChangeStreamResponse; import com.google.bigtable.v2.ReadRowsRequest; @@ -188,7 +186,6 @@ public class EnhancedBigtableStub implements AutoCloseable { private final UnaryCallable externalBulkMutateRowsCallable; private final UnaryCallable checkAndMutateRowCallable; private final UnaryCallable readModifyWriteRowCallable; - private final UnaryCallable pingAndWarmCallable; private final ServerStreamingCallable generateInitialChangeStreamPartitionsCallable; @@ -321,7 +318,6 @@ public EnhancedBigtableStub( createGenerateInitialChangeStreamPartitionsCallable(); readChangeStreamCallable = createReadChangeStreamCallable(new DefaultChangeStreamRecordAdapter()); - pingAndWarmCallable = createPingAndWarmCallable(); executeQueryCallable = createExecuteQueryCallable(); } @@ -1252,28 +1248,6 @@ ServerStreamingCallSettings convertUnaryToServerStreamingSettings( .build(); } - private UnaryCallable createPingAndWarmCallable() { - UnaryCallable pingAndWarm = - GrpcRawCallableFactory.createUnaryCallable( - GrpcCallSettings.newBuilder() - .setMethodDescriptor(BigtableGrpc.getPingAndWarmMethod()) - .setParamsExtractor( - new RequestParamsExtractor() { - @Override - public Map extract(PingAndWarmRequest request) { - return ImmutableMap.of( - "name", request.getName(), - "app_profile_id", request.getAppProfileId()); - } - }) - .build(), - Collections.emptySet()); - return pingAndWarm.withDefaultCallContext( - clientContext - .getDefaultCallContext() - .withRetrySettings(settings.pingAndWarmSettings().getRetrySettings())); - } - private UnaryCallable withRetries( UnaryCallable innerCallable, UnaryCallSettings unaryCallSettings) { UnaryCallable retrying; @@ -1381,10 +1355,6 @@ public ExecuteQueryCallable executeQueryCallable() { return executeQueryCallable; } - UnaryCallable pingAndWarmCallable() { - return pingAndWarmCallable; - } - // private SpanName getSpanName(String methodName) { diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/it/BuiltinMetricsIT.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/it/BuiltinMetricsIT.java index 2438d7e9c6..d929627e12 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/it/BuiltinMetricsIT.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/it/BuiltinMetricsIT.java @@ -70,6 +70,7 @@ import org.junit.After; import org.junit.Before; import org.junit.ClassRule; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; @@ -78,6 +79,7 @@ import org.threeten.bp.Duration; import org.threeten.bp.Instant; +@Ignore("Temporarily disable flaky test") @RunWith(JUnit4.class) public class BuiltinMetricsIT { @ClassRule public static TestEnvRule testEnvRule = new TestEnvRule(); diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimerTest.java index e1f22bebbd..709b482477 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/BigtableChannelPrimerTest.java @@ -24,6 +24,7 @@ import com.google.bigtable.v2.PingAndWarmRequest; import com.google.bigtable.v2.PingAndWarmResponse; import com.google.cloud.bigtable.data.v2.FakeServiceBuilder; +import com.google.common.collect.ImmutableMap; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.Metadata; @@ -69,10 +70,11 @@ public void setup() throws IOException { primer = BigtableChannelPrimer.create( - OAuth2Credentials.create(new AccessToken(TOKEN_VALUE, null)), "fake-project", "fake-instance", - "fake-app-profile"); + "fake-app-profile", + OAuth2Credentials.create(new AccessToken(TOKEN_VALUE, null)), + ImmutableMap.of("bigtable-feature", "fake-feature")); channel = ManagedChannelBuilder.forAddress("localhost", server.getPort()).usePlaintext().build(); @@ -133,7 +135,7 @@ public PingAndWarmResponse apply(PingAndWarmRequest pingAndWarmRequest) { assertThat(logHandler.logs).hasSize(1); for (LogRecord log : logHandler.logs) { - assertThat(log.getMessage()).contains("FAILED_PRECONDITION"); + assertThat(log.getThrown().getMessage()).contains("FAILED_PRECONDITION"); } } @@ -146,7 +148,21 @@ public void testChannelErrorsAreLogged() { assertThat(logHandler.logs).hasSize(1); for (LogRecord log : logHandler.logs) { - assertThat(log.getMessage()).contains("UnsupportedOperationException"); + assertThat(log.getThrown()).isInstanceOf(UnsupportedOperationException.class); + } + } + + @Test + public void testHeadersAreSent() { + primer.primeChannel(channel); + + for (Metadata metadata : metadataInterceptor.metadataList) { + assertThat(metadata.get(BigtableChannelPrimer.REQUEST_PARAMS)) + .isEqualTo( + "name=projects%2Ffake-project%2Finstances%2Ffake-instance&app_profile_id=fake-app-profile"); + assertThat( + metadata.get(Metadata.Key.of("bigtable-feature", Metadata.ASCII_STRING_MARSHALLER))) + .isEqualTo("fake-feature"); } } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubTest.java index 67ac3f24d9..fcdb4a0624 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubTest.java @@ -84,8 +84,10 @@ import com.google.cloud.bigtable.data.v2.models.TableId; import com.google.cloud.bigtable.data.v2.models.sql.ResultSetMetadata; import com.google.cloud.bigtable.data.v2.models.sql.Statement; +import com.google.cloud.bigtable.data.v2.stub.metrics.NoopMetricsProvider; import com.google.cloud.bigtable.data.v2.stub.sql.ExecuteQueryCallable; import com.google.cloud.bigtable.data.v2.stub.sql.SqlServerStream; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Queues; import com.google.common.io.BaseEncoding; @@ -97,7 +99,6 @@ import io.grpc.CallOptions; import io.grpc.Context; import io.grpc.Deadline; -import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.Metadata; import io.grpc.Metadata.Key; @@ -172,6 +173,7 @@ public void setUp() throws IOException, IllegalAccessException, InstantiationExc .setInstanceId(INSTANCE_ID) .setAppProfileId(APP_PROFILE_ID) .setCredentialsProvider(NoCredentialsProvider.create()) + .setMetricsProvider(NoopMetricsProvider.INSTANCE) .build() .getStubSettings(); @@ -187,9 +189,6 @@ public void tearDown() { @Test public void testJwtAudience() throws InterruptedException, IOException, NoSuchAlgorithmException, ExecutionException { - // close default stub - need to create custom one - enhancedBigtableStub.close(); - // Create fake jwt creds KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); KeyPair keyPair = keyGen.genKeyPair(); @@ -210,9 +209,10 @@ public void testJwtAudience() .setJwtAudienceMapping(ImmutableMap.of("localhost", expectedAudience)) .setCredentialsProvider(FixedCredentialsProvider.create(jwtCreds)) .build(); - enhancedBigtableStub = EnhancedBigtableStub.create(settings); + try (EnhancedBigtableStub stub = EnhancedBigtableStub.create(settings)) { + stub.readRowCallable().futureCall(Query.create("fake-table")).get(); + } // Send rpc and grab the credentials sent - enhancedBigtableStub.readRowCallable().futureCall(Query.create("fake-table")).get(); Metadata metadata = metadataInterceptor.headers.take(); String authValue = metadata.get(Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)); @@ -226,9 +226,6 @@ public void testJwtAudience() @Test public void testBatchJwtAudience() throws InterruptedException, IOException, NoSuchAlgorithmException, ExecutionException { - // close default stub - need to create custom one - enhancedBigtableStub.close(); - // Create fake jwt creds KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); KeyPair keyPair = keyGen.genKeyPair(); @@ -241,31 +238,30 @@ public void testBatchJwtAudience() .setPrivateKeyId("fake-private-key") .build(); - // Create a fixed channel that will ignore the default endpoint and connect to the emulator - ManagedChannel emulatorChannel = - ManagedChannelBuilder.forAddress("localhost", server.getPort()).usePlaintext().build(); + EnhancedBigtableStubSettings settings = + EnhancedBigtableStubSettings.newBuilder() + .setProjectId("fake-project") + .setInstanceId("fake-instance") + .setEndpoint("batch-bigtable.googleapis.com:443") + .setCredentialsProvider(FixedCredentialsProvider.create(jwtCreds)) + .setMetricsProvider(NoopMetricsProvider.INSTANCE) + // Use a fixed channel that will ignore the default endpoint and connect to the emulator + .setTransportChannelProvider( + FixedTransportChannelProvider.create( + GrpcTransportChannel.create( + ManagedChannelBuilder.forAddress("localhost", server.getPort()) + .usePlaintext() + .build()))) + // Channel refreshing doesn't work with FixedTransportChannelProvider. Disable it for + // the test + .setRefreshingChannel(false) + .build(); Metadata metadata; - try { - EnhancedBigtableStubSettings settings = - EnhancedBigtableStubSettings.newBuilder() - .setProjectId("fake-project") - .setInstanceId("fake-instance") - .setEndpoint("batch-bigtable.googleapis.com:443") - .setCredentialsProvider(FixedCredentialsProvider.create(jwtCreds)) - .setTransportChannelProvider( - FixedTransportChannelProvider.create( - GrpcTransportChannel.create(emulatorChannel))) - // Channel refreshing doesn't work with FixedTransportChannelProvider. Disable it for - // the test - .setRefreshingChannel(false) - .build(); - enhancedBigtableStub = EnhancedBigtableStub.create(settings); + try (EnhancedBigtableStub stub = EnhancedBigtableStub.create(settings)) { // Send rpc and grab the credentials sent - enhancedBigtableStub.readRowCallable().futureCall(Query.create("fake-table")).get(); + stub.readRowCallable().futureCall(Query.create("fake-table")).get(); metadata = metadataInterceptor.headers.take(); - } finally { - emulatorChannel.shutdown(); } String authValue = metadata.get(Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER)); @@ -278,7 +274,6 @@ public void testBatchJwtAudience() @Test public void testFeatureFlags() throws InterruptedException, IOException, ExecutionException { - enhancedBigtableStub.readRowCallable().futureCall(Query.create("fake-table")).get(); Metadata metadata = metadataInterceptor.headers.take(); @@ -291,6 +286,28 @@ public void testFeatureFlags() throws InterruptedException, IOException, Executi assertThat(featureFlags.getLastScannedRowResponses()).isTrue(); } + @Test + public void testPingAndWarmFeatureFlags() + throws InterruptedException, IOException, ExecutionException { + EnhancedBigtableStubSettings settings = + defaultSettings.toBuilder().setRefreshingChannel(true).build(); + try (EnhancedBigtableStub ignored = EnhancedBigtableStub.create(settings)) { + Preconditions.checkState( + !fakeDataService.pingRequests.isEmpty(), "Ping request was not sent during setup"); + Metadata metadata = metadataInterceptor.headers.take(); + + String encodedFeatureFlags = + metadata.get(Key.of("bigtable-features", Metadata.ASCII_STRING_MARSHALLER)); + FeatureFlags featureFlags = + FeatureFlags.parseFrom(BaseEncoding.base64Url().decode(encodedFeatureFlags)); + + assertThat(featureFlags.getReverseScans()).isTrue(); + assertThat(featureFlags.getLastScannedRowResponses()).isTrue(); + assertThat(featureFlags.getRoutingCookie()).isTrue(); + assertThat(featureFlags.getRetryInfo()).isTrue(); + } + } + @Test public void testCheckAndMutateRequestResponseConversion() throws ExecutionException, InterruptedException { diff --git a/grpc-google-cloud-bigtable-admin-v2/pom.xml b/grpc-google-cloud-bigtable-admin-v2/pom.xml index dbe05980c8..94231ba7fa 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.48.1-SNAPSHOT + 2.49.0 grpc-google-cloud-bigtable-admin-v2 GRPC library for grpc-google-cloud-bigtable-admin-v2 com.google.cloud google-cloud-bigtable-parent - 2.48.1-SNAPSHOT + 2.49.0 @@ -18,14 +18,14 @@ com.google.cloud google-cloud-bigtable-deps-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import com.google.cloud google-cloud-bigtable-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import diff --git a/grpc-google-cloud-bigtable-v2/pom.xml b/grpc-google-cloud-bigtable-v2/pom.xml index 0fdb146424..b09f14695d 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.48.1-SNAPSHOT + 2.49.0 grpc-google-cloud-bigtable-v2 GRPC library for grpc-google-cloud-bigtable-v2 com.google.cloud google-cloud-bigtable-parent - 2.48.1-SNAPSHOT + 2.49.0 @@ -18,14 +18,14 @@ com.google.cloud google-cloud-bigtable-deps-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import com.google.cloud google-cloud-bigtable-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import diff --git a/pom.xml b/pom.xml index 74b75c2576..0a945a3853 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ google-cloud-bigtable-parent pom - 2.48.1-SNAPSHOT + 2.49.0 Google Cloud Bigtable Parent https://github.com/googleapis/java-bigtable @@ -153,27 +153,27 @@ com.google.api.grpc proto-google-cloud-bigtable-v2 - 2.48.1-SNAPSHOT + 2.49.0 com.google.api.grpc proto-google-cloud-bigtable-admin-v2 - 2.48.1-SNAPSHOT + 2.49.0 com.google.api.grpc grpc-google-cloud-bigtable-v2 - 2.48.1-SNAPSHOT + 2.49.0 com.google.api.grpc grpc-google-cloud-bigtable-admin-v2 - 2.48.1-SNAPSHOT + 2.49.0 com.google.cloud google-cloud-bigtable - 2.48.1-SNAPSHOT + 2.49.0 diff --git a/proto-google-cloud-bigtable-admin-v2/pom.xml b/proto-google-cloud-bigtable-admin-v2/pom.xml index ca3f645d65..48f59de7e1 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.48.1-SNAPSHOT + 2.49.0 proto-google-cloud-bigtable-admin-v2 PROTO library for proto-google-cloud-bigtable-admin-v2 com.google.cloud google-cloud-bigtable-parent - 2.48.1-SNAPSHOT + 2.49.0 @@ -18,14 +18,14 @@ com.google.cloud google-cloud-bigtable-deps-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import com.google.cloud google-cloud-bigtable-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import diff --git a/proto-google-cloud-bigtable-v2/pom.xml b/proto-google-cloud-bigtable-v2/pom.xml index 437d9ca5b2..9b61631b52 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.48.1-SNAPSHOT + 2.49.0 proto-google-cloud-bigtable-v2 PROTO library for proto-google-cloud-bigtable-v2 com.google.cloud google-cloud-bigtable-parent - 2.48.1-SNAPSHOT + 2.49.0 @@ -18,14 +18,14 @@ com.google.cloud google-cloud-bigtable-deps-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import com.google.cloud google-cloud-bigtable-bom - 2.48.1-SNAPSHOT + 2.49.0 pom import diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index d80ffd9c8a..30a503385d 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -28,7 +28,7 @@ com.google.cloud google-cloud-bigtable - 2.48.1-SNAPSHOT + 2.49.0 diff --git a/test-proxy/pom.xml b/test-proxy/pom.xml index 10506e2020..1bd83d098a 100644 --- a/test-proxy/pom.xml +++ b/test-proxy/pom.xml @@ -12,11 +12,11 @@ google-cloud-bigtable-parent com.google.cloud - 2.48.1-SNAPSHOT + 2.49.0 - 2.48.1-SNAPSHOT + 2.49.0 diff --git a/versions.txt b/versions.txt index 85e102bdd3..021d20cb62 100644 --- a/versions.txt +++ b/versions.txt @@ -1,10 +1,10 @@ # Format: # module:released-version:current-version -google-cloud-bigtable:2.48.0:2.48.1-SNAPSHOT -grpc-google-cloud-bigtable-admin-v2:2.48.0:2.48.1-SNAPSHOT -grpc-google-cloud-bigtable-v2:2.48.0:2.48.1-SNAPSHOT -proto-google-cloud-bigtable-admin-v2:2.48.0:2.48.1-SNAPSHOT -proto-google-cloud-bigtable-v2:2.48.0:2.48.1-SNAPSHOT -google-cloud-bigtable-emulator:0.185.0:0.185.1-SNAPSHOT -google-cloud-bigtable-emulator-core:0.185.0:0.185.1-SNAPSHOT +google-cloud-bigtable:2.49.0:2.49.0 +grpc-google-cloud-bigtable-admin-v2:2.49.0:2.49.0 +grpc-google-cloud-bigtable-v2:2.49.0:2.49.0 +proto-google-cloud-bigtable-admin-v2:2.49.0:2.49.0 +proto-google-cloud-bigtable-v2:2.49.0:2.49.0 +google-cloud-bigtable-emulator:0.186.0:0.186.0 +google-cloud-bigtable-emulator-core:0.186.0:0.186.0