Skip to content

Commit 393a80d

Browse files
feat: Allow JDBC to configure directpath for connection (#3927)
* feat: Allow JDBC to configure directpath for connection * Update JDBC connection property description
1 parent ff3d212 commit 393a80d

File tree

6 files changed

+49
-4
lines changed

6 files changed

+49
-4
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ public static class Builder
10001000
private String compressorName;
10011001
private String emulatorHost = System.getenv("SPANNER_EMULATOR_HOST");
10021002
private boolean leaderAwareRoutingEnabled = true;
1003-
private boolean attemptDirectPath = true;
1003+
private boolean attemptDirectPath = false;
10041004
private DirectedReadOptions directedReadOptions;
10051005
private boolean useVirtualThreads = false;
10061006
private OpenTelemetry openTelemetry;
@@ -1604,6 +1604,12 @@ public Builder disableLeaderAwareRouting() {
16041604
return this;
16051605
}
16061606

1607+
@BetaApi
1608+
public Builder enableDirectPath() {
1609+
this.attemptDirectPath = true;
1610+
return this;
1611+
}
1612+
16071613
@BetaApi
16081614
public Builder disableDirectPath() {
16091615
this.attemptDirectPath = false;

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionOptions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.google.cloud.spanner.connection;
1818

19+
import static com.google.cloud.spanner.connection.ConnectionProperties.ATTEMPT_DIRECT_PATH;
1920
import static com.google.cloud.spanner.connection.ConnectionProperties.AUTOCOMMIT;
2021
import static com.google.cloud.spanner.connection.ConnectionProperties.AUTO_CONFIG_EMULATOR;
2122
import static com.google.cloud.spanner.connection.ConnectionProperties.AUTO_PARTITION_MODE;
@@ -1081,6 +1082,10 @@ boolean isExperimentalHost() {
10811082
return getInitialConnectionPropertyValue(IS_EXPERIMENTAL_HOST);
10821083
}
10831084

1085+
boolean isAttemptDirectPath() {
1086+
return getInitialConnectionPropertyValue(ATTEMPT_DIRECT_PATH);
1087+
}
1088+
10841089
String getClientCertificate() {
10851090
return getInitialConnectionPropertyValue(CLIENT_CERTIFICATE);
10861091
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionProperties.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ public class ConnectionProperties {
183183
BOOLEANS,
184184
BooleanConverter.INSTANCE,
185185
Context.STARTUP);
186+
static final ConnectionProperty<Boolean> ATTEMPT_DIRECT_PATH =
187+
create(
188+
"attemptDirectPath",
189+
"Configure the connection to try to connect to Spanner using "
190+
+ "DirectPath (true/false). The client will try to connect to Spanner "
191+
+ "using a direct Google network connection. DirectPath will work only "
192+
+ "if the client is trying to establish a connection from a Google Cloud VM. "
193+
+ "Otherwise it will automatically fallback to the standard network path. "
194+
+ "NOTE: The default for this property is currently false, "
195+
+ "but this could be changed in the future.",
196+
false,
197+
BOOLEANS,
198+
BooleanConverter.INSTANCE,
199+
Context.STARTUP);
186200
static final ConnectionProperty<Boolean> USE_AUTO_SAVEPOINTS_FOR_EMULATOR =
187201
create(
188202
"useAutoSavepointsForEmulator",

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/SpannerPool.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static class SpannerPoolKey {
164164
private final String clientCertificate;
165165
private final String clientCertificateKey;
166166
private final boolean isExperimentalHost;
167+
private final boolean attemptDirectPath;
167168

168169
@VisibleForTesting
169170
static SpannerPoolKey of(ConnectionOptions options) {
@@ -198,6 +199,7 @@ private SpannerPoolKey(ConnectionOptions options) throws IOException {
198199
this.clientCertificate = options.getClientCertificate();
199200
this.clientCertificateKey = options.getClientCertificateKey();
200201
this.isExperimentalHost = options.isExperimentalHost();
202+
this.attemptDirectPath = options.isAttemptDirectPath();
201203
}
202204

203205
@Override
@@ -223,7 +225,8 @@ public boolean equals(Object o) {
223225
&& Objects.equals(this.enableEndToEndTracing, other.enableEndToEndTracing)
224226
&& Objects.equals(this.clientCertificate, other.clientCertificate)
225227
&& Objects.equals(this.clientCertificateKey, other.clientCertificateKey)
226-
&& Objects.equals(this.isExperimentalHost, other.isExperimentalHost);
228+
&& Objects.equals(this.isExperimentalHost, other.isExperimentalHost)
229+
&& Objects.equals(this.attemptDirectPath, other.attemptDirectPath);
227230
}
228231

229232
@Override
@@ -245,7 +248,8 @@ public int hashCode() {
245248
this.enableEndToEndTracing,
246249
this.clientCertificate,
247250
this.clientCertificateKey,
248-
this.isExperimentalHost);
251+
this.isExperimentalHost,
252+
this.attemptDirectPath);
249253
}
250254
}
251255

@@ -412,6 +416,9 @@ Spanner createSpanner(SpannerPoolKey key, ConnectionOptions options) {
412416
if (key.isExperimentalHost) {
413417
builder.setExperimentalHost(key.host);
414418
}
419+
if (key.attemptDirectPath) {
420+
builder.enableDirectPath();
421+
}
415422
if (options.getConfigurator() != null) {
416423
options.getConfigurator().configure(builder);
417424
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ public GapicSpannerRpc(final SpannerOptions options) {
365365
.withEncoding(compressorName))
366366
.setHeaderProvider(headerProviderWithUserAgent)
367367
.setAllowNonDefaultServiceAccount(true);
368-
boolean isAttemptDirectPathXds = isEnableDirectPathXdsEnv();
368+
boolean isAttemptDirectPathXds = isEnableDirectPathXdsEnv() || options.isAttemptDirectPath();
369369
if (isAttemptDirectPathXds) {
370370
defaultChannelProviderBuilder.setAttemptDirectPath(true);
371371
// This will let the credentials try to fetch a hard-bound access token if the runtime

google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/ConnectionOptionsTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,4 +1311,17 @@ public void testExperimentalHost() {
13111311
.getSessionPoolOptions()
13121312
.getUseMultiplexedSessionPartitionedOps());
13131313
}
1314+
1315+
@Test
1316+
public void testAttemptDirectPath() {
1317+
ConnectionOptions.Builder builderWithoutDirectPathParam = ConnectionOptions.newBuilder();
1318+
builderWithoutDirectPathParam.setUri(
1319+
"spanner://localhost:15000/instances/default/databases/singers-db;usePlainText=true");
1320+
assertFalse(builderWithoutDirectPathParam.build().isAttemptDirectPath());
1321+
1322+
ConnectionOptions.Builder builderWithDirectPathParam = ConnectionOptions.newBuilder();
1323+
builderWithDirectPathParam.setUri(
1324+
"spanner://localhost:15000/projects/default/instances/default/databases/singers-db;usePlainText=true;attemptDirectPath=true");
1325+
assertTrue(builderWithDirectPathParam.build().isAttemptDirectPath());
1326+
}
13141327
}

0 commit comments

Comments
 (0)