Skip to content

Commit 9a432f7

Browse files
authored
feat: expose property in GrpcTransportChannel if it uses direct path. (googleapis#3170)
This should fix googleapis#3134. Spanner needs to know if `GrpcSpannerStub`’s transportChannel uses DirectPath for tracing purposes. `canUseDirectPath()` from `stubSettings.getTransportChannelProvider()` does not provide accurate information because credentials are set afterwards when creating the transportChannel for `GrpcSpannerStub` (`GrpcSpannerStub.create(stubSettings)`) Proposed change: Expose a property in `GrpcTransportChannel` and pass this information down from channel provider. Spanner can access from `ClientContext` as shown below ``` SpannerStubSettings stubSettings = options .getSpannerStubSettings() .toBuilder() .setTransportChannelProvider(channelProvider) .setCredentialsProvider(credentialsProvider) .setStreamWatchdogProvider(watchdogProvider) .setTracerFactory(options.getApiTracerFactory()) .build(); ClientContext clientContext = ClientContext.create(stubSettings); // create GrpcSpannerStub from clientContext instead. // this is equivelant to GrpcSpannerStub.create(stubSettings) this.spannerStub = GrpcSpannerStub.create(clientContext); // access this property from transport channel. ((GrpcTransportChannel) clientContext.getTransportChannel()).isDirectPath(); ```
1 parent 593e2f0 commit 9a432f7

File tree

6 files changed

+85
-13
lines changed

6 files changed

+85
-13
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- see http://www.mojohaus.org/clirr-maven-plugin/examples/ignored-differences.html -->
3+
<differences>
4+
<!-- Add AutoValue abstract method isDirectPath -->
5+
<difference>
6+
<differenceType>7013</differenceType>
7+
<className>com/google/api/gax/grpc/GrpcTransportChannel</className>
8+
<method>boolean isDirectPath()</method>
9+
</difference>
10+
</differences>

gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcTransportChannel.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public GrpcCallContext getEmptyCallContext() {
6060
/** The channel in use. */
6161
abstract ManagedChannel getManagedChannel();
6262

63+
public abstract boolean isDirectPath();
64+
6365
public Channel getChannel() {
6466
return getManagedChannel();
6567
}
@@ -100,7 +102,7 @@ public void close() {
100102
}
101103

102104
public static Builder newBuilder() {
103-
return new AutoValue_GrpcTransportChannel.Builder();
105+
return new AutoValue_GrpcTransportChannel.Builder().setDirectPath(false);
104106
}
105107

106108
public static GrpcTransportChannel create(ManagedChannel channel) {
@@ -111,6 +113,8 @@ public static GrpcTransportChannel create(ManagedChannel channel) {
111113
public abstract static class Builder {
112114
public abstract Builder setManagedChannel(ManagedChannel value);
113115

116+
abstract Builder setDirectPath(boolean value);
117+
114118
public abstract GrpcTransportChannel build();
115119
}
116120
}

gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,12 @@ public TransportChannel getTransportChannel() throws IOException {
258258
}
259259

260260
private TransportChannel createChannel() throws IOException {
261-
return GrpcTransportChannel.create(
262-
ChannelPool.create(
263-
channelPoolSettings, InstantiatingGrpcChannelProvider.this::createSingleChannel));
261+
return GrpcTransportChannel.newBuilder()
262+
.setManagedChannel(
263+
ChannelPool.create(
264+
channelPoolSettings, InstantiatingGrpcChannelProvider.this::createSingleChannel))
265+
.setDirectPath(this.canUseDirectPath())
266+
.build();
264267
}
265268

266269
private boolean isDirectPathEnabled() {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are
6+
* met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above
11+
* copyright notice, this list of conditions and the following disclaimer
12+
* in the documentation and/or other materials provided with the
13+
* distribution.
14+
* * Neither the name of Google LLC nor the names of its
15+
* contributors may be used to endorse or promote products derived from
16+
* this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
31+
package com.google.api.gax.grpc;
32+
33+
import static org.junit.jupiter.api.Assertions.*;
34+
35+
import io.grpc.ManagedChannel;
36+
import org.junit.jupiter.api.Test;
37+
import org.mockito.Mockito;
38+
39+
class GrpcTransportChannelTest {
40+
41+
@Test
42+
void testBuilderDefaults() {
43+
ManagedChannel channel = Mockito.mock(ManagedChannel.class);
44+
GrpcTransportChannel grpcTransportChannel =
45+
GrpcTransportChannel.newBuilder().setManagedChannel(channel).build();
46+
assertFalse(grpcTransportChannel.isDirectPath());
47+
}
48+
}

gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ void testLogDirectPathMisconfigNotOnGCE() throws Exception {
706706
}
707707

708708
@Test
709-
public void canUseDirectPath_happyPath() {
709+
public void canUseDirectPath_happyPath() throws IOException {
710710
System.setProperty("os.name", "Linux");
711711
EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class);
712712
Mockito.when(
@@ -718,14 +718,20 @@ public void canUseDirectPath_happyPath() {
718718
.setAttemptDirectPath(true)
719719
.setCredentials(computeEngineCredentials)
720720
.setEndpoint(DEFAULT_ENDPOINT)
721-
.setEnvProvider(envProvider);
721+
.setEnvProvider(envProvider)
722+
.setHeaderProvider(Mockito.mock(HeaderProvider.class));
722723
InstantiatingGrpcChannelProvider provider =
723724
new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016);
724725
Truth.assertThat(provider.canUseDirectPath()).isTrue();
726+
727+
// verify this info is passed correctly to transport channel
728+
TransportChannel transportChannel = provider.getTransportChannel();
729+
Truth.assertThat(((GrpcTransportChannel) transportChannel).isDirectPath()).isTrue();
730+
transportChannel.shutdownNow();
725731
}
726732

727733
@Test
728-
public void canUseDirectPath_directPathEnvVarDisabled() {
734+
public void canUseDirectPath_directPathEnvVarDisabled() throws IOException {
729735
System.setProperty("os.name", "Linux");
730736
EnvironmentProvider envProvider = Mockito.mock(EnvironmentProvider.class);
731737
Mockito.when(
@@ -737,10 +743,16 @@ public void canUseDirectPath_directPathEnvVarDisabled() {
737743
.setAttemptDirectPath(true)
738744
.setCredentials(computeEngineCredentials)
739745
.setEndpoint(DEFAULT_ENDPOINT)
740-
.setEnvProvider(envProvider);
746+
.setEnvProvider(envProvider)
747+
.setHeaderProvider(Mockito.mock(HeaderProvider.class));
741748
InstantiatingGrpcChannelProvider provider =
742749
new InstantiatingGrpcChannelProvider(builder, GCE_PRODUCTION_NAME_AFTER_2016);
743750
Truth.assertThat(provider.canUseDirectPath()).isFalse();
751+
752+
// verify this info is passed correctly to transport channel
753+
TransportChannel transportChannel = provider.getTransportChannel();
754+
Truth.assertThat(((GrpcTransportChannel) transportChannel).isDirectPath()).isFalse();
755+
transportChannel.shutdownNow();
744756
}
745757

746758
@Test

gax-java/gax/clirr-ignored-differences.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@
6666
<className>com/google/api/gax/*/*</className>
6767
<method>*org.threeten.bp.Duration *()</method>
6868
</difference>
69-
<difference>
70-
<differenceType>7002</differenceType>
71-
<className>com/google/api/gax/grpc/InstantiatingGrpcChannelProvider$Builder</className>
72-
<method>* *</method>
73-
</difference>
7469
<!-- Add a default Endpoint Getter -->
7570
<difference>
7671
<differenceType>7012</differenceType>

0 commit comments

Comments
 (0)