Skip to content

Commit 8684bb4

Browse files
committed
add
1 parent 0ab3a4c commit 8684bb4

15 files changed

Lines changed: 119 additions & 64 deletions

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/metrics/ClientDpCompatGuage.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.ClientInfo;
1919
import com.google.cloud.bigtable.data.v2.internal.csm.metrics.Constants.MetricLabels;
2020
import com.google.cloud.bigtable.data.v2.internal.csm.schema.ClientSchema;
21+
import com.google.cloud.bigtable.data.v2.internal.dp.DirectAccessInvestigator;
2122
import io.opentelemetry.api.metrics.LongGauge;
2223
import io.opentelemetry.api.metrics.Meter;
2324

@@ -60,12 +61,12 @@ public void recordSuccess(ClientInfo clientInfo, String ipPreference) {
6061
}
6162

6263
// TODO: replace reason with an enum
63-
public void recordFailure(ClientInfo clientInfo, String reason) {
64+
public void recordFailure(ClientInfo clientInfo, DirectAccessInvestigator.FailureReason reason) {
6465
instrument.set(
6566
1,
6667
getSchema()
6768
.createResourceAttrs(clientInfo)
68-
.put(MetricLabels.DP_REASON_KEY, reason)
69+
.put(MetricLabels.DP_REASON_KEY, reason.getValue())
6970
.put(MetricLabels.DP_IP_PREFERENCE_KEY, "")
7071
.build());
7172
}

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/DirectPathCompatibleTracer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.google.api.core.InternalApi;
1919
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.Util;
20+
import com.google.cloud.bigtable.data.v2.internal.dp.DirectAccessInvestigator;
2021

2122
/** Interface for recording DirectPath/DirectAccess eligibility metrics. */
2223
@InternalApi
@@ -35,5 +36,5 @@ public interface DirectPathCompatibleTracer {
3536
* @param reason The reason for the failure (e.g., "routing_check_failed").
3637
*/
3738
// TODO: Make this an enum
38-
void recordFailure(String reason);
39+
void recordFailure(DirectAccessInvestigator.FailureReason reason);
3940
}

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/tracers/DirectPathCompatibleTracerImpl.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.google.cloud.bigtable.data.v2.internal.csm.MetricRegistry;
2020
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.ClientInfo;
2121
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.Util;
22+
import com.google.cloud.bigtable.data.v2.internal.dp.DirectAccessInvestigator;
23+
import com.google.common.base.Preconditions;
2224

2325
@InternalApi
2426
public class DirectPathCompatibleTracerImpl implements DirectPathCompatibleTracer {
@@ -27,8 +29,8 @@ public class DirectPathCompatibleTracerImpl implements DirectPathCompatibleTrace
2729

2830
public DirectPathCompatibleTracerImpl(
2931
ClientInfo clientInfo, MetricRegistry.RecorderRegistry recorder) {
30-
this.clientInfo = clientInfo;
31-
this.recorder = recorder;
32+
this.clientInfo = Preconditions.checkNotNull(clientInfo);
33+
this.recorder = Preconditions.checkNotNull(recorder);
3234
}
3335

3436
@Override
@@ -37,7 +39,7 @@ public void recordSuccess(Util.IpProtocol ipProtocol) {
3739
}
3840

3941
@Override
40-
public void recordFailure(String reason) {
42+
public void recordFailure(DirectAccessInvestigator.FailureReason reason) {
4143
recorder.dpCompatGuage.recordFailure(clientInfo, reason);
4244
}
4345
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2026 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+
17+
package com.google.cloud.bigtable.data.v2.internal.dp;
18+
19+
import com.google.api.core.InternalApi;
20+
import io.grpc.Channel;
21+
import io.grpc.ManagedChannel;
22+
import javax.annotation.Nullable;
23+
24+
@InternalApi
25+
public class AlwaysEnabledDirectAccessChecker implements DirectAccessChecker {
26+
public static final AlwaysEnabledDirectAccessChecker INSTANCE =
27+
new AlwaysEnabledDirectAccessChecker();
28+
29+
private AlwaysEnabledDirectAccessChecker() {}
30+
31+
@Override
32+
public boolean check(Channel channel) {
33+
if (channel instanceof ManagedChannel) {
34+
((ManagedChannel) channel).shutdownNow();
35+
}
36+
return true;
37+
}
38+
39+
@Override
40+
public void investigateFailure(@Nullable Throwable originalError) {
41+
// No-op:
42+
}
43+
}

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/dp/ClassicDirectAccessChecker.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.cloud.bigtable.data.v2.stub.MetadataExtractorInterceptor;
2222
import com.google.cloud.bigtable.gaxx.grpc.ChannelPrimer;
2323
import com.google.common.annotations.VisibleForTesting;
24+
import com.google.common.base.Preconditions;
2425
import io.grpc.Channel;
2526
import io.grpc.ClientInterceptors;
2627
import io.grpc.ManagedChannel;
@@ -45,9 +46,9 @@ public ClassicDirectAccessChecker(
4546
DirectPathCompatibleTracer tracer,
4647
ChannelPrimer channelPrimer,
4748
ScheduledExecutorService executor) {
48-
this.tracer = tracer;
49-
this.channelPrimer = channelPrimer;
50-
this.executor = executor;
49+
this.tracer = Preconditions.checkNotNull(tracer);
50+
this.channelPrimer = Preconditions.checkNotNull(channelPrimer);
51+
this.executor = Preconditions.checkNotNull(executor);
5152
}
5253

5354
@VisibleForTesting

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/dp/DirectAccessInvestigator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ private static void recordAndLog(
7575
} else {
7676
LOG.log(Level.FINE, logMessage);
7777
}
78-
tracer.recordFailure(reason.getValue());
78+
tracer.recordFailure(reason);
7979
}
8080
}

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.cloud.bigtable.data.v2.internal.csm.Metrics;
3333
import com.google.cloud.bigtable.data.v2.internal.csm.MetricsImpl;
3434
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.ClientInfo;
35+
import com.google.cloud.bigtable.data.v2.internal.dp.AlwaysEnabledDirectAccessChecker;
3536
import com.google.cloud.bigtable.data.v2.internal.dp.ClassicDirectAccessChecker;
3637
import com.google.cloud.bigtable.data.v2.internal.dp.DirectAccessChecker;
3738
import com.google.cloud.bigtable.data.v2.internal.dp.NoopDirectAccessChecker;
@@ -164,12 +165,17 @@ public static BigtableClientContext create(
164165
builder.getHeaderProvider().getHeaders());
165166
}
166167

167-
DirectAccessChecker directAccessChecker =
168-
settings.isDirectPathEnabledByDefault()
169-
? new ClassicDirectAccessChecker(
170-
metrics.getDirectPathCompatibleTracer(), channelPrimer, backgroundExecutor)
171-
: NoopDirectAccessChecker.INSTANCE;
172-
168+
DirectAccessChecker directAccessChecker = null;
169+
switch (settings.getDirectPathConfig()) {
170+
case FORCED_ON:
171+
directAccessChecker = AlwaysEnabledDirectAccessChecker.INSTANCE;
172+
break;
173+
case FORCED_OFF:
174+
case DEFAULT:
175+
directAccessChecker = NoopDirectAccessChecker.INSTANCE;
176+
break;
177+
}
178+
173179
BigtableTransportChannelProvider btTransportProvider =
174180
BigtableTransportChannelProvider.create(
175181
transportProvider.build(),

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

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,17 @@ public class EnhancedBigtableStubSettings extends StubSettings<EnhancedBigtableS
9797
// The largest message that can be received is a 256 MB ReadRowsResponse.
9898
private static final int MAX_MESSAGE_SIZE = 256 * 1024 * 1024;
9999
private static final String SERVER_DEFAULT_APP_PROFILE_ID = "";
100-
// If true, disable the bound-token-by-default feature for DirectPath.
101-
private static final boolean DIRECT_PATH_BOUND_TOKEN_DISABLED =
102-
Boolean.parseBoolean(System.getenv("CBT_DISABLE_DIRECTPATH_BOUND_TOKEN"));
103100

104101
// TODO change this to true when enabling directpath by default
105102
// For now, Only runs Direct Access Checker if user explicitly sets CBT_ENABLE_DIRECTPATH=true
106-
private static final boolean ENABLE_DIRECT_PATH_BY_DEFAULT =
107-
Optional.ofNullable(System.getenv("CBT_ENABLE_DIRECTPATH"))
108-
.map(Boolean::parseBoolean)
109-
.orElse(false);
103+
private static final DirectPathConfig DIRECT_PATH_CONFIG =
104+
Optional.ofNullable(System.getenv("CBT_ENABLE_DIRECTPATH")).map(
105+
Boolean::parseBoolean
106+
).map(b -> b ? DirectPathConfig.FORCED_ON : DirectPathConfig.FORCED_OFF).orElse(DirectPathConfig.DEFAULT);
107+
108+
// If true, disable the bound-token-by-default feature for DirectPath.
109+
private static final boolean DIRECT_PATH_BOUND_TOKEN_DISABLED =
110+
Boolean.parseBoolean(System.getenv("CBT_DISABLE_DIRECTPATH_BOUND_TOKEN"));
110111

111112
/**
112113
* Scopes that are equivalent to JWT's audience.
@@ -141,13 +142,19 @@ public class EnhancedBigtableStubSettings extends StubSettings<EnhancedBigtableS
141142
@Nullable private final String metricsEndpoint;
142143
private final boolean areInternalMetricsEnabled;
143144
private final String jwtAudience;
144-
private boolean enableDirectPathByDefault;
145+
146+
@InternalApi
147+
public enum DirectPathConfig {
148+
DEFAULT,
149+
FORCED_ON,
150+
FORCED_OFF,
151+
}
152+
private final DirectPathConfig directPathConfig;
145153

146154
private EnhancedBigtableStubSettings(Builder builder) {
147155
super(builder);
148156

149-
enableDirectPathByDefault = builder.enableDirectPathByDefault;
150-
157+
directPathConfig = builder.directPathConfig;
151158
projectId = builder.projectId;
152159
instanceId = builder.instanceId;
153160
appProfileId = builder.appProfileId;
@@ -171,8 +178,8 @@ public String getProjectId() {
171178
return projectId;
172179
}
173180

174-
public boolean isDirectPathEnabledByDefault() {
175-
return enableDirectPathByDefault;
181+
public DirectPathConfig getDirectPathConfig() {
182+
return DIRECT_PATH_CONFIG;
176183
}
177184

178185
/** Returns the target instance id. */
@@ -580,7 +587,7 @@ public Builder toBuilder() {
580587

581588
/** Builder for BigtableDataSettings. */
582589
public static class Builder extends StubSettings.Builder<EnhancedBigtableStubSettings, Builder> {
583-
private boolean enableDirectPathByDefault;
590+
private DirectPathConfig directPathConfig;
584591
private String projectId;
585592
private String instanceId;
586593
private String appProfileId;
@@ -605,8 +612,8 @@ public static class Builder extends StubSettings.Builder<EnhancedBigtableStubSet
605612
*/
606613
private Builder() {
607614
// TODO(enable this by default)
608-
// Only runs Direct Access Checker if user explicitly sets CBT_ENABLE_DIRECTPATH=true
609-
this.enableDirectPathByDefault = ENABLE_DIRECT_PATH_BY_DEFAULT;
615+
// Only runs Direct Access Checker if it is DIRECTPATH_ENABLED_BY_DEFAULT
616+
this.directPathConfig = DIRECT_PATH_CONFIG;
610617
this.appProfileId = SERVER_DEFAULT_APP_PROFILE_ID;
611618
this.isRefreshingChannel = true;
612619
setCredentialsProvider(defaultCredentialsProviderBuilder().build());
@@ -624,18 +631,16 @@ private Builder() {
624631

625632
perOpSettings = new ClientOperationSettings.Builder();
626633

627-
// Note: RouteLookup evaluates and returns directpath targets
628-
// only if Traffic Director sends the request (with grpc as target type)
629-
// For GFE/CFE, sending setDirectAccessRequested
630-
// is fine as GFE/CFE sends with gslb target type
631634
// TODO: flip the bit setDirectAccessRequested and setTrafficDirectorEnabled once we make
632635
// client compatible by default.
636+
boolean isDirectPathRequested =
637+
directPathConfig == DirectPathConfig.FORCED_ON || directPathConfig == DirectPathConfig.DEFAULT;
633638
featureFlags =
634639
FeatureFlags.newBuilder()
635640
.setReverseScans(true)
636641
.setLastScannedRowResponses(true)
637-
.setDirectAccessRequested(enableDirectPathByDefault)
638-
.setTrafficDirectorEnabled(enableDirectPathByDefault)
642+
.setDirectAccessRequested(isDirectPathRequested)
643+
.setTrafficDirectorEnabled(isDirectPathRequested)
639644
.setPeerInfo(true);
640645
}
641646

@@ -649,7 +654,7 @@ private Builder(EnhancedBigtableStubSettings settings) {
649654
metricsEndpoint = settings.getMetricsEndpoint();
650655
areInternalMetricsEnabled = settings.areInternalMetricsEnabled;
651656
jwtAudience = settings.jwtAudience;
652-
this.enableDirectPathByDefault = settings.isDirectPathEnabledByDefault();
657+
this.directPathConfig = settings.getDirectPathConfig();
653658

654659
this.perOpSettings = new ClientOperationSettings.Builder(settings.perOpSettings);
655660

@@ -736,8 +741,8 @@ public Builder setRefreshingChannel(boolean isRefreshingChannel) {
736741
}
737742

738743
@InternalApi("For internal use only.")
739-
public Builder setEnableDirectPathByDefault(boolean enableDirectPathByDefault) {
740-
this.enableDirectPathByDefault = enableDirectPathByDefault;
744+
public Builder setDirectPathConfig(DirectPathConfig directPathConfig) {
745+
this.directPathConfig = directPathConfig;
741746
return this;
742747
}
743748

@@ -1022,7 +1027,7 @@ public String toString() {
10221027
.add("metricsEndpoint", metricsEndpoint)
10231028
.add("areInternalMetricsEnabled", areInternalMetricsEnabled)
10241029
.add("jwtAudience", jwtAudience)
1025-
.add("enableDirectPathByDefault", enableDirectPathByDefault)
1030+
.add("directPathConfig", getDirectPathConfig().toString())
10261031
.add("parent", super.toString())
10271032
.toString();
10281033
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.Util;
1919
import com.google.cloud.bigtable.data.v2.internal.csm.tracers.DirectPathCompatibleTracer;
20+
import com.google.cloud.bigtable.data.v2.internal.dp.DirectAccessInvestigator;
2021
import com.google.common.base.MoreObjects;
2122

2223
/**
@@ -50,7 +51,7 @@ public void recordSuccess(Util.IpProtocol ipProtocol) {
5051
}
5152

5253
@Override
53-
public void recordFailure(String reason) {
54+
public void recordFailure(DirectAccessInvestigator.FailureReason reason) {
5455
// No-op
5556
}
5657
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,19 @@
2323

2424
@InternalApi("For internal use by google-cloud-java clients only")
2525
public interface ChannelPrimer {
26-
@Deprecated
27-
default void primeChannel(ManagedChannel channel) {
26+
/**
27+
* @deprecated Use {@link #primeChannel(Channel)}
28+
*/
29+
@Deprecated
30+
default void primeChannel(ManagedChannel channel) {
2831
primeChannel((Channel) channel);
2932
}
3033

3134
void primeChannel(Channel channel);
3235

36+
/**
37+
* @deprecated Use {@link #sendPrimeRequestsAsync(Channel)}
38+
*/
3339
@Deprecated
3440
default ApiFuture<PingAndWarmResponse> sendPrimeRequestsAsync(ManagedChannel channel) {
3541
return sendPrimeRequestsAsync((Channel) channel);

0 commit comments

Comments
 (0)