diff --git a/google-cloud-spanner/clirr-ignored-differences.xml b/google-cloud-spanner/clirr-ignored-differences.xml
index 46a11518dbb..12657dd15b1 100644
--- a/google-cloud-spanner/clirr-ignored-differences.xml
+++ b/google-cloud-spanner/clirr-ignored-differences.xml
@@ -1028,4 +1028,9 @@
com/google/cloud/spanner/StructReader
java.lang.Object getOrDefault(java.lang.String, java.util.function.BiFunction, java.lang.Object)
+
+ 7012
+ com/google/cloud/spanner/SpannerOptions$SpannerEnvironment
+ boolean isEnableDirectAccess()
+
diff --git a/google-cloud-spanner/pom.xml b/google-cloud-spanner/pom.xml
index c502922d0e1..172d2e045fb 100644
--- a/google-cloud-spanner/pom.xml
+++ b/google-cloud-spanner/pom.xml
@@ -592,7 +592,7 @@
com.google.cloud.spanner.GceTestEnvConfig
projects/directpath-prod-manual-testing/instances/spanner-testing
directpath-prod-manual-testing
- true
+ true
ipv4
3000
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java
index c3e9215a20e..e8941c52756 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java
@@ -175,7 +175,7 @@ public class SpannerOptions extends ServiceOptions {
private final CloseableExecutorProvider asyncExecutorProvider;
private final String compressorName;
private final boolean leaderAwareRoutingEnabled;
- private final boolean attemptDirectPath;
+ private final boolean enableDirectAccess;
private final DirectedReadOptions directedReadOptions;
private final boolean useVirtualThreads;
private final OpenTelemetry openTelemetry;
@@ -806,7 +806,7 @@ protected SpannerOptions(Builder builder) {
asyncExecutorProvider = builder.asyncExecutorProvider;
compressorName = builder.compressorName;
leaderAwareRoutingEnabled = builder.leaderAwareRoutingEnabled;
- attemptDirectPath = builder.attemptDirectPath;
+ enableDirectAccess = builder.enableDirectAccess;
directedReadOptions = builder.directedReadOptions;
useVirtualThreads = builder.useVirtualThreads;
openTelemetry = builder.openTelemetry;
@@ -849,6 +849,10 @@ default boolean isEnableApiTracing() {
return false;
}
+ default boolean isEnableDirectAccess() {
+ return false;
+ }
+
default boolean isEnableBuiltInMetrics() {
return true;
}
@@ -884,6 +888,8 @@ private static class SpannerEnvironmentImpl implements SpannerEnvironment {
"SPANNER_OPTIMIZER_STATISTICS_PACKAGE";
private static final String SPANNER_ENABLE_EXTENDED_TRACING = "SPANNER_ENABLE_EXTENDED_TRACING";
private static final String SPANNER_ENABLE_API_TRACING = "SPANNER_ENABLE_API_TRACING";
+ private static final String GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS =
+ "GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS";
private static final String SPANNER_ENABLE_END_TO_END_TRACING =
"SPANNER_ENABLE_END_TO_END_TRACING";
private static final String SPANNER_DISABLE_BUILTIN_METRICS = "SPANNER_DISABLE_BUILTIN_METRICS";
@@ -916,6 +922,11 @@ public boolean isEnableApiTracing() {
return Boolean.parseBoolean(System.getenv(SPANNER_ENABLE_API_TRACING));
}
+ @Override
+ public boolean isEnableDirectAccess() {
+ return Boolean.parseBoolean(System.getenv(GOOGLE_SPANNER_ENABLE_DIRECT_ACCESS));
+ }
+
@Override
public boolean isEnableBuiltInMetrics() {
return !Boolean.parseBoolean(System.getenv(SPANNER_DISABLE_BUILTIN_METRICS));
@@ -1000,7 +1011,7 @@ public static class Builder
private String compressorName;
private String emulatorHost = System.getenv("SPANNER_EMULATOR_HOST");
private boolean leaderAwareRoutingEnabled = true;
- private boolean attemptDirectPath = false;
+ private boolean enableDirectAccess = SpannerOptions.environment.isEnableDirectAccess();
private DirectedReadOptions directedReadOptions;
private boolean useVirtualThreads = false;
private OpenTelemetry openTelemetry;
@@ -1072,7 +1083,7 @@ protected Builder() {
this.channelProvider = options.channelProvider;
this.channelConfigurator = options.channelConfigurator;
this.interceptorProvider = options.interceptorProvider;
- this.attemptDirectPath = options.attemptDirectPath;
+ this.enableDirectAccess = options.enableDirectAccess;
this.directedReadOptions = options.directedReadOptions;
this.useVirtualThreads = options.useVirtualThreads;
this.enableApiTracing = options.enableApiTracing;
@@ -1605,14 +1616,15 @@ public Builder disableLeaderAwareRouting() {
}
@BetaApi
- public Builder enableDirectPath() {
- this.attemptDirectPath = true;
+ public Builder setEnableDirectAccess(boolean enableDirectAccess) {
+ this.enableDirectAccess = enableDirectAccess;
return this;
}
- @BetaApi
+ @ObsoleteApi("Use setEnableDirectAccess(false) instead")
+ @Deprecated
public Builder disableDirectPath() {
- this.attemptDirectPath = false;
+ this.enableDirectAccess = false;
return this;
}
@@ -1980,8 +1992,14 @@ public DirectedReadOptions getDirectedReadOptions() {
}
@BetaApi
+ public Boolean isEnableDirectAccess() {
+ return enableDirectAccess;
+ }
+
+ @ObsoleteApi("Use isEnableDirectAccess() instead")
+ @Deprecated
public boolean isAttemptDirectPath() {
- return attemptDirectPath;
+ return enableDirectAccess;
}
/**
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java
index d9ba873b412..2c86192443d 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java
@@ -16,7 +16,6 @@
package com.google.cloud.spanner.connection;
-import static com.google.cloud.spanner.connection.ConnectionProperties.ATTEMPT_DIRECT_PATH;
import static com.google.cloud.spanner.connection.ConnectionProperties.AUTOCOMMIT;
import static com.google.cloud.spanner.connection.ConnectionProperties.AUTO_CONFIG_EMULATOR;
import static com.google.cloud.spanner.connection.ConnectionProperties.AUTO_PARTITION_MODE;
@@ -29,6 +28,7 @@
import static com.google.cloud.spanner.connection.ConnectionProperties.DATA_BOOST_ENABLED;
import static com.google.cloud.spanner.connection.ConnectionProperties.DIALECT;
import static com.google.cloud.spanner.connection.ConnectionProperties.ENABLE_API_TRACING;
+import static com.google.cloud.spanner.connection.ConnectionProperties.ENABLE_DIRECT_ACCESS;
import static com.google.cloud.spanner.connection.ConnectionProperties.ENABLE_END_TO_END_TRACING;
import static com.google.cloud.spanner.connection.ConnectionProperties.ENABLE_EXTENDED_TRACING;
import static com.google.cloud.spanner.connection.ConnectionProperties.ENCODED_CREDENTIALS;
@@ -1082,8 +1082,8 @@ boolean isExperimentalHost() {
return getInitialConnectionPropertyValue(IS_EXPERIMENTAL_HOST);
}
- boolean isAttemptDirectPath() {
- return getInitialConnectionPropertyValue(ATTEMPT_DIRECT_PATH);
+ Boolean isEnableDirectAccess() {
+ return getInitialConnectionPropertyValue(ENABLE_DIRECT_ACCESS);
}
String getClientCertificate() {
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java
index 042d7217586..ac53b800bb5 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java
@@ -183,9 +183,9 @@ public class ConnectionProperties {
BOOLEANS,
BooleanConverter.INSTANCE,
Context.STARTUP);
- static final ConnectionProperty ATTEMPT_DIRECT_PATH =
+ static final ConnectionProperty ENABLE_DIRECT_ACCESS =
create(
- "attemptDirectPath",
+ "enableDirectAccess",
"Configure the connection to try to connect to Spanner using "
+ "DirectPath (true/false). The client will try to connect to Spanner "
+ "using a direct Google network connection. DirectPath will work only "
@@ -193,7 +193,7 @@ public class ConnectionProperties {
+ "Otherwise it will automatically fallback to the standard network path. "
+ "NOTE: The default for this property is currently false, "
+ "but this could be changed in the future.",
- false,
+ null,
BOOLEANS,
BooleanConverter.INSTANCE,
Context.STARTUP);
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java
index ea76b727dbb..b21e8c84db0 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java
@@ -164,7 +164,7 @@ static class SpannerPoolKey {
private final String clientCertificate;
private final String clientCertificateKey;
private final boolean isExperimentalHost;
- private final boolean attemptDirectPath;
+ private final Boolean enableDirectAccess;
@VisibleForTesting
static SpannerPoolKey of(ConnectionOptions options) {
@@ -199,7 +199,7 @@ private SpannerPoolKey(ConnectionOptions options) throws IOException {
this.clientCertificate = options.getClientCertificate();
this.clientCertificateKey = options.getClientCertificateKey();
this.isExperimentalHost = options.isExperimentalHost();
- this.attemptDirectPath = options.isAttemptDirectPath();
+ this.enableDirectAccess = options.isEnableDirectAccess();
}
@Override
@@ -226,7 +226,7 @@ public boolean equals(Object o) {
&& Objects.equals(this.clientCertificate, other.clientCertificate)
&& Objects.equals(this.clientCertificateKey, other.clientCertificateKey)
&& Objects.equals(this.isExperimentalHost, other.isExperimentalHost)
- && Objects.equals(this.attemptDirectPath, other.attemptDirectPath);
+ && Objects.equals(this.enableDirectAccess, other.enableDirectAccess);
}
@Override
@@ -249,7 +249,7 @@ public int hashCode() {
this.clientCertificate,
this.clientCertificateKey,
this.isExperimentalHost,
- this.attemptDirectPath);
+ this.enableDirectAccess);
}
}
@@ -416,8 +416,8 @@ Spanner createSpanner(SpannerPoolKey key, ConnectionOptions options) {
if (key.isExperimentalHost) {
builder.setExperimentalHost(key.host);
}
- if (key.attemptDirectPath) {
- builder.enableDirectPath();
+ if (key.enableDirectAccess != null) {
+ builder.setEnableDirectAccess(key.enableDirectAccess);
}
if (options.getConfigurator() != null) {
options.getConfigurator().configure(builder);
diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
index 1a83a195cec..5abf3ea98e7 100644
--- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
+++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
@@ -365,8 +365,8 @@ public GapicSpannerRpc(final SpannerOptions options) {
.withEncoding(compressorName))
.setHeaderProvider(headerProviderWithUserAgent)
.setAllowNonDefaultServiceAccount(true);
- boolean isAttemptDirectPathXds = isEnableDirectPathXdsEnv() || options.isAttemptDirectPath();
- if (isAttemptDirectPathXds) {
+ boolean isEnableDirectAccess = options.isEnableDirectAccess();
+ if (isEnableDirectAccess) {
defaultChannelProviderBuilder.setAttemptDirectPath(true);
// This will let the credentials try to fetch a hard-bound access token if the runtime
// environment supports it.
@@ -426,7 +426,7 @@ public GapicSpannerRpc(final SpannerOptions options) {
spannerStubSettings, clientContext);
DIRECTPATH_CHANNEL_CREATED =
((GrpcTransportChannel) clientContext.getTransportChannel()).isDirectPath()
- && isAttemptDirectPathXds;
+ && isEnableDirectAccess;
this.readRetrySettings =
options.getSpannerStubSettings().streamingReadSettings().getRetrySettings();
this.readRetryableCodes =
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GceTestEnvConfig.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GceTestEnvConfig.java
index efb012ba8e2..fab0e453f5a 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GceTestEnvConfig.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/GceTestEnvConfig.java
@@ -46,7 +46,7 @@ public class GceTestEnvConfig implements TestEnvConfig {
public static final String GCE_CREDENTIALS_FILE = "spanner.gce.config.credentials_file";
public static final String GCE_STREAM_BROKEN_PROBABILITY =
"spanner.gce.config.stream_broken_probability";
- public static final String ATTEMPT_DIRECT_PATH = "spanner.attempt_directpath";
+ public static final String ENABLE_DIRECT_ACCESS = "spanner.enable_direct_access";
public static final String DIRECT_PATH_TEST_SCENARIO = "spanner.directpath_test_scenario";
// IP address prefixes allocated for DirectPath backends.
@@ -64,7 +64,7 @@ public GceTestEnvConfig() {
double errorProbability =
Double.parseDouble(System.getProperty(GCE_STREAM_BROKEN_PROBABILITY, "0.0"));
checkState(errorProbability <= 1.0);
- boolean attemptDirectPath = Boolean.getBoolean(ATTEMPT_DIRECT_PATH);
+ boolean enableDirectAccess = Boolean.getBoolean(ENABLE_DIRECT_ACCESS);
String directPathTestScenario = System.getProperty(DIRECT_PATH_TEST_SCENARIO, "");
SpannerOptions.Builder builder =
SpannerOptions.newBuilder()
@@ -85,7 +85,7 @@ public GceTestEnvConfig() {
}
SpannerInterceptorProvider interceptorProvider =
SpannerInterceptorProvider.createDefault().with(new GrpcErrorInjector(errorProbability));
- if (attemptDirectPath) {
+ if (enableDirectAccess) {
interceptorProvider =
interceptorProvider.with(new DirectPathAddressCheckInterceptor(directPathTestScenario));
}
@@ -93,7 +93,7 @@ public GceTestEnvConfig() {
// DirectPath tests need to set a custom endpoint to the ChannelProvider
InstantiatingGrpcChannelProvider.Builder customChannelProviderBuilder =
InstantiatingGrpcChannelProvider.newBuilder();
- if (attemptDirectPath) {
+ if (enableDirectAccess) {
customChannelProviderBuilder
.setEndpoint(DIRECT_PATH_ENDPOINT)
.setAttemptDirectPath(true)
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java
index 9fb6adea6ef..e274c0e6c04 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java
@@ -1313,15 +1313,20 @@ public void testExperimentalHost() {
}
@Test
- public void testAttemptDirectPath() {
+ public void testEnableDirectAccess() {
ConnectionOptions.Builder builderWithoutDirectPathParam = ConnectionOptions.newBuilder();
builderWithoutDirectPathParam.setUri(
"spanner://localhost:15000/instances/default/databases/singers-db;usePlainText=true");
- assertFalse(builderWithoutDirectPathParam.build().isAttemptDirectPath());
+ assertNull(builderWithoutDirectPathParam.build().isEnableDirectAccess());
+
+ ConnectionOptions.Builder builderWithDirectPathParamFalse = ConnectionOptions.newBuilder();
+ builderWithDirectPathParamFalse.setUri(
+ "spanner://localhost:15000/instances/default/databases/singers-db;usePlainText=true;enableDirectAccess=false");
+ assertFalse(builderWithDirectPathParamFalse.build().isEnableDirectAccess());
ConnectionOptions.Builder builderWithDirectPathParam = ConnectionOptions.newBuilder();
builderWithDirectPathParam.setUri(
- "spanner://localhost:15000/projects/default/instances/default/databases/singers-db;usePlainText=true;attemptDirectPath=true");
- assertTrue(builderWithDirectPathParam.build().isAttemptDirectPath());
+ "spanner://localhost:15000/projects/default/instances/default/databases/singers-db;usePlainText=true;enableDirectAccess=true");
+ assertTrue(builderWithDirectPathParam.build().isEnableDirectAccess());
}
}
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/CredentialsProviderTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/CredentialsProviderTest.java
index 9e2979e1aaf..f082fa7042a 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/CredentialsProviderTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/CredentialsProviderTest.java
@@ -93,7 +93,7 @@ public void testCredentialsProvider() throws Throwable {
.setConfigurator(
spannerOptions -> {
spannerOptions.setChannelConfigurator(ManagedChannelBuilder::usePlaintext);
- spannerOptions.disableDirectPath();
+ spannerOptions.setEnableDirectAccess(false);
})
.build();
@@ -135,7 +135,7 @@ public void testCredentialsProvider() throws Throwable {
.setConfigurator(
spannerOptions -> {
spannerOptions.setChannelConfigurator(ManagedChannelBuilder::usePlaintext);
- spannerOptions.disableDirectPath();
+ spannerOptions.setEnableDirectAccess(false);
})
.build();
try (Connection connection = options.getConnection()) {
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java
index 9cc2ebc450e..bf6c1450973 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITDirectPathFallback.java
@@ -100,7 +100,7 @@ public class ITDirectPathFallback {
// TODO(mohanli): Remove this temporary endpoint once DirectPath goes to public beta.
private static final String DIRECT_PATH_ENDPOINT = "aa423245250f2bbf.sandbox.googleapis.com:443";
- private static final String ATTEMPT_DIRECT_PATH = "spanner.attempt_directpath";
+ private static final String ENABLE_DIRECT_ACCESS = "spanner.enable_direct_access";
public ITDirectPathFallback() {
// Create a transport channel provider that can intercept ipv6 packets.
@@ -112,7 +112,7 @@ public ITDirectPathFallback() {
public void setup() {
assume()
.withMessage("DirectPath integration tests can only run against DirectPathEnv")
- .that(Boolean.getBoolean(ATTEMPT_DIRECT_PATH))
+ .that(Boolean.getBoolean(ENABLE_DIRECT_ACCESS))
.isTrue();
// Get default spanner options for Ingetration test
SpannerOptions.Builder builder = env.getTestHelper().getOptions().toBuilder();
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java
index 24b09d56f83..e46f61a8ce7 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpcTest.java
@@ -879,7 +879,7 @@ private SpannerOptions createSpannerOptions() {
.setProjectId("[PROJECT]")
// Set a custom channel configurator to allow http instead of https.
.setChannelConfigurator(ManagedChannelBuilder::usePlaintext)
- .disableDirectPath()
+ .setEnableDirectAccess(false)
.setHost("http://" + endpoint)
// Set static credentials that will return the static OAuth test token.
.setCredentials(STATIC_CREDENTIALS)
diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java
index 908a4ad5573..f2d8a07538c 100644
--- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java
+++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/spi/v1/GfeLatencyTest.java
@@ -290,7 +290,7 @@ private static SpannerOptions createSpannerOptions(InetSocketAddress address, Se
.setProjectId("[PROJECT]")
// Set a custom channel configurator to allow http instead of https.
.setChannelConfigurator(ManagedChannelBuilder::usePlaintext)
- .disableDirectPath()
+ .setEnableDirectAccess(false)
.setHost("http://" + endpoint)
// Set static credentials that will return the static OAuth test token.
.setCredentials(STATIC_CREDENTIALS)