Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.

Commit 2088ccd

Browse files
committed
Merge branch 'main' into mat-view
2 parents 9c56423 + 9096e70 commit 2088ccd

6 files changed

Lines changed: 307 additions & 35 deletions

File tree

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024 Google LLC
2+
* Copyright 2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@
3232
import com.google.cloud.bigtable.data.v2.stub.metrics.ErrorCountPerConnectionMetricTracker;
3333
import com.google.cloud.bigtable.data.v2.stub.metrics.MetricsProvider;
3434
import com.google.cloud.bigtable.data.v2.stub.metrics.NoopMetricsProvider;
35+
import com.google.cloud.bigtable.gaxx.grpc.BigtableTransportChannelProvider;
3536
import io.grpc.ManagedChannelBuilder;
3637
import io.grpc.opentelemetry.GrpcOpenTelemetry;
3738
import io.opentelemetry.api.OpenTelemetry;
@@ -131,7 +132,11 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
131132
builder.getHeaderProvider().getHeaders()));
132133
}
133134

134-
builder.setTransportChannelProvider(transportProvider.build());
135+
BigtableTransportChannelProvider btTransportProvider =
136+
BigtableTransportChannelProvider.create(
137+
(InstantiatingGrpcChannelProvider) transportProvider.build());
138+
139+
builder.setTransportChannelProvider(btTransportProvider);
135140
}
136141

137142
ClientContext clientContext = ClientContext.create(builder.build());

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPool.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,13 @@
4646
/**
4747
* A {@link ManagedChannel} that will send requests round-robin via a set of channels.
4848
*
49-
* <p>In addition to spreading requests over a set of child connections, the pool will also actively
50-
* manage the lifecycle of the channels. Currently lifecycle management is limited to pre-emptively
51-
* replacing channels every hour. In the future it will dynamically size the pool based on number of
52-
* outstanding requests.
49+
* <p>Spreads over a set of child connections, and actively manages lifecycle of connections.
50+
* Dynamically resizes pool based on number of outstanding connections.
5351
*
54-
* <p>Package-private for internal use.
52+
* <p>Internal API
5553
*/
56-
class BigtableChannelPool extends ManagedChannel {
54+
@InternalApi
55+
public class BigtableChannelPool extends ManagedChannel {
5756
@VisibleForTesting
5857
static final Logger LOG = Logger.getLogger(BigtableChannelPool.class.getName());
5958

@@ -68,7 +67,7 @@ class BigtableChannelPool extends ManagedChannel {
6867
private final AtomicInteger indexTicker = new AtomicInteger();
6968
private final String authority;
7069

71-
static BigtableChannelPool create(
70+
public static BigtableChannelPool create(
7271
BigtableChannelPoolSettings settings, ChannelFactory channelFactory) throws IOException {
7372
return new BigtableChannelPool(
7473
settings, channelFactory, Executors.newSingleThreadScheduledExecutor());

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPoolSettings.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.google.cloud.bigtable.gaxx.grpc;
1717

1818
import com.google.api.core.BetaApi;
19+
import com.google.api.gax.grpc.ChannelPoolSettings;
1920
import com.google.auto.value.AutoValue;
2021
import com.google.common.base.Preconditions;
2122
import java.time.Duration;
@@ -112,6 +113,17 @@ boolean isStaticSize() {
112113

113114
public abstract Builder toBuilder();
114115

116+
public static BigtableChannelPoolSettings copyFrom(ChannelPoolSettings externalSettings) {
117+
return BigtableChannelPoolSettings.builder()
118+
.setMinRpcsPerChannel(externalSettings.getMinRpcsPerChannel())
119+
.setMaxRpcsPerChannel(externalSettings.getMaxRpcsPerChannel())
120+
.setMinChannelCount(externalSettings.getMinChannelCount())
121+
.setMaxChannelCount(externalSettings.getMaxChannelCount())
122+
.setInitialChannelCount(externalSettings.getInitialChannelCount())
123+
.setPreemptiveRefreshEnabled(externalSettings.isPreemptiveRefreshEnabled())
124+
.build();
125+
}
126+
115127
public static BigtableChannelPoolSettings staticallySized(int size) {
116128
return builder()
117129
.setInitialChannelCount(size)
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.cloud.bigtable.gaxx.grpc;
17+
18+
import com.google.api.core.InternalApi;
19+
import com.google.api.gax.grpc.ChannelFactory;
20+
import com.google.api.gax.grpc.ChannelPoolSettings;
21+
import com.google.api.gax.grpc.GrpcTransportChannel;
22+
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
23+
import com.google.api.gax.rpc.TransportChannel;
24+
import com.google.api.gax.rpc.TransportChannelProvider;
25+
import com.google.auth.Credentials;
26+
import com.google.common.base.Preconditions;
27+
import io.grpc.ManagedChannel;
28+
import java.io.IOException;
29+
import java.util.Map;
30+
import java.util.concurrent.Executor;
31+
import java.util.concurrent.ScheduledExecutorService;
32+
33+
/**
34+
* An instance of TransportChannelProvider that provides a TransportChannel through a supplied
35+
* InstantiatingGrpcChannelProvider.
36+
*/
37+
@InternalApi
38+
public final class BigtableTransportChannelProvider implements TransportChannelProvider {
39+
40+
private final InstantiatingGrpcChannelProvider delegate;
41+
42+
private BigtableTransportChannelProvider(
43+
InstantiatingGrpcChannelProvider instantiatingGrpcChannelProvider) {
44+
delegate = Preconditions.checkNotNull(instantiatingGrpcChannelProvider);
45+
}
46+
47+
@Override
48+
public boolean shouldAutoClose() {
49+
return delegate.shouldAutoClose();
50+
}
51+
52+
@Override
53+
public boolean needsExecutor() {
54+
return delegate.needsExecutor();
55+
}
56+
57+
@Override
58+
public BigtableTransportChannelProvider withExecutor(ScheduledExecutorService executor) {
59+
return withExecutor((Executor) executor);
60+
}
61+
62+
@Override
63+
public BigtableTransportChannelProvider withExecutor(Executor executor) {
64+
InstantiatingGrpcChannelProvider newChannelProvider =
65+
(InstantiatingGrpcChannelProvider) delegate.withExecutor(executor);
66+
return new BigtableTransportChannelProvider(newChannelProvider);
67+
}
68+
69+
@Override
70+
public boolean needsHeaders() {
71+
return delegate.needsHeaders();
72+
}
73+
74+
@Override
75+
public BigtableTransportChannelProvider withHeaders(Map<String, String> headers) {
76+
InstantiatingGrpcChannelProvider newChannelProvider =
77+
(InstantiatingGrpcChannelProvider) delegate.withHeaders(headers);
78+
return new BigtableTransportChannelProvider(newChannelProvider);
79+
}
80+
81+
@Override
82+
public boolean needsEndpoint() {
83+
return delegate.needsEndpoint();
84+
}
85+
86+
@Override
87+
public TransportChannelProvider withEndpoint(String endpoint) {
88+
InstantiatingGrpcChannelProvider newChannelProvider =
89+
(InstantiatingGrpcChannelProvider) delegate.withEndpoint(endpoint);
90+
return new BigtableTransportChannelProvider(newChannelProvider);
91+
}
92+
93+
@Deprecated
94+
@Override
95+
public boolean acceptsPoolSize() {
96+
return delegate.acceptsPoolSize();
97+
}
98+
99+
@Deprecated
100+
@Override
101+
public TransportChannelProvider withPoolSize(int size) {
102+
InstantiatingGrpcChannelProvider newChannelProvider =
103+
(InstantiatingGrpcChannelProvider) delegate.withPoolSize(size);
104+
return new BigtableTransportChannelProvider(newChannelProvider);
105+
}
106+
107+
/** Expected to only be called once when BigtableClientContext is created */
108+
@Override
109+
public TransportChannel getTransportChannel() throws IOException {
110+
// This provider's main purpose is to replace the default GAX ChannelPool
111+
// with a custom BigtableChannelPool, reusing the delegate's configuration.
112+
113+
// To create our pool, we need a factory for raw gRPC channels.
114+
// We achieve this by configuring our delegate to not use its own pooling
115+
// (by setting pool size to 1) and then calling getTransportChannel() on it.
116+
InstantiatingGrpcChannelProvider singleChannelProvider =
117+
delegate.toBuilder().setChannelPoolSettings(ChannelPoolSettings.staticallySized(1)).build();
118+
119+
ChannelFactory channelFactory =
120+
() -> {
121+
try {
122+
GrpcTransportChannel channel =
123+
(GrpcTransportChannel) singleChannelProvider.getTransportChannel();
124+
return (ManagedChannel) channel.getChannel();
125+
} catch (IOException e) {
126+
throw new java.io.UncheckedIOException(e);
127+
}
128+
};
129+
130+
BigtableChannelPoolSettings btPoolSettings =
131+
BigtableChannelPoolSettings.copyFrom(delegate.getChannelPoolSettings());
132+
133+
BigtableChannelPool btChannelPool = BigtableChannelPool.create(btPoolSettings, channelFactory);
134+
135+
return GrpcTransportChannel.create(btChannelPool);
136+
}
137+
138+
@Override
139+
public String getTransportName() {
140+
return "bigtable";
141+
}
142+
143+
@Override
144+
public boolean needsCredentials() {
145+
return delegate.needsCredentials();
146+
}
147+
148+
@Override
149+
public TransportChannelProvider withCredentials(Credentials credentials) {
150+
InstantiatingGrpcChannelProvider newChannelProvider =
151+
(InstantiatingGrpcChannelProvider) delegate.withCredentials(credentials);
152+
return new BigtableTransportChannelProvider(newChannelProvider);
153+
}
154+
155+
/** Creates a BigtableTransportChannelProvider. */
156+
public static BigtableTransportChannelProvider create(
157+
InstantiatingGrpcChannelProvider instantiatingGrpcChannelProvider) {
158+
return new BigtableTransportChannelProvider(instantiatingGrpcChannelProvider);
159+
}
160+
}

google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableMaterializedViewIT.java

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import com.google.cloud.bigtable.admin.v2.models.CreateInstanceRequest;
2828
import com.google.cloud.bigtable.admin.v2.models.CreateMaterializedViewRequest;
2929
import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest;
30-
import com.google.cloud.bigtable.admin.v2.models.Instance;
3130
import com.google.cloud.bigtable.admin.v2.models.MaterializedView;
3231
import com.google.cloud.bigtable.admin.v2.models.StorageType;
3332
import com.google.cloud.bigtable.admin.v2.models.Table;
@@ -39,7 +38,7 @@
3938
import java.io.IOException;
4039
import java.util.List;
4140
import java.util.logging.Logger;
42-
import org.junit.AfterClass;
41+
import org.junit.After;
4342
import org.junit.Before;
4443
import org.junit.BeforeClass;
4544
import org.junit.ClassRule;
@@ -55,10 +54,10 @@ public class BigtableMaterializedViewIT {
5554
private static final Logger LOGGER = Logger.getLogger(BigtableMaterializedViewIT.class.getName());
5655
private static final int[] BACKOFF_DURATION = {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};
5756

58-
private static BigtableInstanceAdminClient client;
59-
private static BigtableTableAdminClient tableAdminClient;
60-
private static Table testTable;
61-
private static String instanceId = "";
57+
private BigtableInstanceAdminClient client;
58+
private BigtableTableAdminClient tableAdminClient;
59+
private Table testTable;
60+
private String instanceId = "";
6261

6362
// TODO: Update this test once emulator supports InstanceAdmin operation
6463
// https://github.com/googleapis/google-cloud-go/issues/1069
@@ -68,35 +67,30 @@ public static void validatePlatform() throws IOException {
6867
.withMessage("BigtableInstanceAdminClient doesn't support on Emulator")
6968
.that(testEnvRule.env())
7069
.isNotInstanceOf(EmulatorEnv.class);
71-
72-
createInstance();
7370
}
7471

75-
public static void createInstance() throws IOException {
72+
@Before
73+
public void setUp() throws InterruptedException, IOException {
7674
client = testEnvRule.env().getInstanceAdminClient();
7775

78-
Instance instance =
79-
client.createInstance(
80-
CreateInstanceRequest.of(new PrefixGenerator().newPrefix())
81-
.setDisplayName("BigtableMaterializedViewIT")
82-
.addCluster("my-cluster", "us-east1-c", 3, StorageType.SSD));
83-
instanceId = instance.getId();
84-
tableAdminClient =
85-
BigtableTableAdminClient.create(testEnvRule.env().getProjectId(), instanceId);
76+
instanceId = new PrefixGenerator().newPrefix();
77+
client.createInstance(
78+
CreateInstanceRequest.of(instanceId)
79+
.setDisplayName("BigtableMaterializedViewIT")
80+
.addCluster(
81+
instanceId + "-c1", testEnvRule.env().getPrimaryZone(), 1, StorageType.SSD));
82+
tableAdminClient = testEnvRule.env().getTableAdminClientForInstance(instanceId);
83+
84+
testTable = createTestTable(tableAdminClient);
8685
}
8786

88-
@AfterClass
89-
public static void deleteInstance() {
87+
@After
88+
public void deleteInstance() {
9089
if (!instanceId.isEmpty()) {
9190
client.deleteInstance(instanceId);
9291
}
9392
}
9493

95-
@Before
96-
public void setUp() throws InterruptedException {
97-
testTable = createTestTable(tableAdminClient);
98-
}
99-
10094
@Test
10195
public void createMaterializedViewAndGetMaterializedViewTest() {
10296
String materializedViewId = prefixGenerator.newPrefix();
@@ -211,8 +205,7 @@ private String getQuery() {
211205
+ "` GROUP BY _key";
212206
}
213207

214-
private static Table createTestTable(BigtableTableAdminClient tableAdmin)
215-
throws InterruptedException {
208+
private Table createTestTable(BigtableTableAdminClient tableAdmin) throws InterruptedException {
216209
String tableId = PrefixGenerator.newPrefix("BigtableMaterializedViewIT#createTestTable");
217210
Table testTable = tableAdmin.createTable(CreateTableRequest.of(tableId).addFamily("cf1"));
218211

0 commit comments

Comments
 (0)