Skip to content

Commit 0346e90

Browse files
authored
Merge branch 'master' into child-channel-plugin
2 parents 367640e + d68f260 commit 0346e90

13 files changed

Lines changed: 234 additions & 83 deletions

File tree

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ IO_GRPC_GRPC_JAVA_ARTIFACTS = [
1414
"com.google.auto.value:auto-value-annotations:1.11.0",
1515
"com.google.auto.value:auto-value:1.11.0",
1616
"com.google.code.findbugs:jsr305:3.0.2",
17-
"com.google.code.gson:gson:2.12.1",
17+
"com.google.code.gson:gson:2.13.2",
1818
"com.google.errorprone:error_prone_annotations:2.45.0",
1919
"com.google.guava:failureaccess:1.0.1",
2020
"com.google.guava:guava:33.5.0-android",

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ For a guided tour, take a look at the [quick start
4444
guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC
4545
basics](https://grpc.io/docs/languages/java/basics).
4646

47-
The [examples](https://github.com/grpc/grpc-java/tree/v1.79.0/examples) and the
48-
[Android example](https://github.com/grpc/grpc-java/tree/v1.79.0/examples/android)
47+
The [examples](https://github.com/grpc/grpc-java/tree/v1.80.0/examples) and the
48+
[Android example](https://github.com/grpc/grpc-java/tree/v1.80.0/examples/android)
4949
are standalone projects that showcase the usage of gRPC.
5050

5151
Download
@@ -56,42 +56,42 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
5656
<dependency>
5757
<groupId>io.grpc</groupId>
5858
<artifactId>grpc-netty-shaded</artifactId>
59-
<version>1.79.0</version>
59+
<version>1.80.0</version>
6060
<scope>runtime</scope>
6161
</dependency>
6262
<dependency>
6363
<groupId>io.grpc</groupId>
6464
<artifactId>grpc-protobuf</artifactId>
65-
<version>1.79.0</version>
65+
<version>1.80.0</version>
6666
</dependency>
6767
<dependency>
6868
<groupId>io.grpc</groupId>
6969
<artifactId>grpc-stub</artifactId>
70-
<version>1.79.0</version>
70+
<version>1.80.0</version>
7171
</dependency>
7272
```
7373

7474
Or for Gradle with non-Android, add to your dependencies:
7575
```gradle
76-
runtimeOnly 'io.grpc:grpc-netty-shaded:1.79.0'
77-
implementation 'io.grpc:grpc-protobuf:1.79.0'
78-
implementation 'io.grpc:grpc-stub:1.79.0'
76+
runtimeOnly 'io.grpc:grpc-netty-shaded:1.80.0'
77+
implementation 'io.grpc:grpc-protobuf:1.80.0'
78+
implementation 'io.grpc:grpc-stub:1.80.0'
7979
```
8080

8181
For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and
8282
`grpc-protobuf-lite` instead of `grpc-protobuf`:
8383
```gradle
84-
implementation 'io.grpc:grpc-okhttp:1.79.0'
85-
implementation 'io.grpc:grpc-protobuf-lite:1.79.0'
86-
implementation 'io.grpc:grpc-stub:1.79.0'
84+
implementation 'io.grpc:grpc-okhttp:1.80.0'
85+
implementation 'io.grpc:grpc-protobuf-lite:1.80.0'
86+
implementation 'io.grpc:grpc-stub:1.80.0'
8787
```
8888

8989
For [Bazel](https://bazel.build), you can either
9090
[use Maven](https://github.com/bazelbuild/rules_jvm_external)
9191
(with the GAVs from above), or use `@io_grpc_grpc_java//api` et al (see below).
9292

9393
[the JARs]:
94-
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.79.0
94+
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.80.0
9595

9696
Development snapshots are available in [Sonatypes's snapshot
9797
repository](https://central.sonatype.com/repository/maven-snapshots/).
@@ -123,7 +123,7 @@ For protobuf-based codegen integrated with the Maven build system, you can use
123123
<configuration>
124124
<protocArtifact>com.google.protobuf:protoc:3.25.8:exe:${os.detected.classifier}</protocArtifact>
125125
<pluginId>grpc-java</pluginId>
126-
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.79.0:exe:${os.detected.classifier}</pluginArtifact>
126+
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.80.0:exe:${os.detected.classifier}</pluginArtifact>
127127
</configuration>
128128
<executions>
129129
<execution>
@@ -153,7 +153,7 @@ protobuf {
153153
}
154154
plugins {
155155
grpc {
156-
artifact = 'io.grpc:protoc-gen-grpc-java:1.79.0'
156+
artifact = 'io.grpc:protoc-gen-grpc-java:1.80.0'
157157
}
158158
}
159159
generateProtoTasks {
@@ -186,7 +186,7 @@ protobuf {
186186
}
187187
plugins {
188188
grpc {
189-
artifact = 'io.grpc:protoc-gen-grpc-java:1.79.0'
189+
artifact = 'io.grpc:protoc-gen-grpc-java:1.80.0'
190190
}
191191
}
192192
generateProtoTasks {

android-interop-testing/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ dependencies {
7979
exclude group: 'com.google.guava'
8080
}
8181

82-
androidTestImplementation 'androidx.test.ext:junit:1.1.3',
82+
androidTestImplementation libraries.androidx.test.ext.junit,
8383
'androidx.test:runner:1.4.0'
8484
}
8585

examples/example-gauth/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
<type>pom</type>
2929
<scope>import</scope>
3030
</dependency>
31+
<dependency><!-- upgrade version from google-auth-library-oauth2-http -->
32+
<groupId>com.google.code.gson</groupId>
33+
<artifactId>gson</artifactId>
34+
<version>2.13.2</version>
35+
</dependency>
3136
</dependencies>
3237
</dependencyManagement>
3338

examples/example-oauth/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
<type>pom</type>
3131
<scope>import</scope>
3232
</dependency>
33+
<dependency><!-- upgrade version from google-auth-library-oauth2-http -->
34+
<groupId>com.google.code.gson</groupId>
35+
<artifactId>gson</artifactId>
36+
<version>2.13.2</version>
37+
</dependency>
3338
</dependencies>
3439
</dependencyManagement>
3540

gradle/libs.versions.toml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@ android-annotations = "com.google.android:annotations:4.1.1.4"
66
# 1.9.1+ uses Kotlin and requires Android Gradle Plugin 9+
77
# checkForUpdates: androidx-annotation:1.9.0
88
androidx-annotation = "androidx.annotation:annotation:1.9.0"
9-
# 1.15.0+ requires minSdkVersion 21 in android-interop-testing (1.14.x doesn't exist)
9+
# 1.14.x doesn't exist.
10+
# 1.15.0+ requires compileSdkVersion 35 which officially requires AGP 8.6.0+.
11+
# It might work before then, but AGP 7.4.1 fails with:
12+
# RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data.
13+
# 1.16.0+ requires AGP 8.6.0+
1014
# checkForUpdates: androidx-core:1.13.+
1115
androidx-core = "androidx.core:core:1.13.1"
12-
# 2.9+ requires minSdkVersion 21 in android-intetrop-testing
16+
# 2.9+ requires AGP 8.1.1+
1317
# checkForUpdates: androidx-lifecycle-common:2.8.+
1418
androidx-lifecycle-common = "androidx.lifecycle:lifecycle-common:2.8.7"
1519
# checkForUpdates: androidx-lifecycle-service:2.8.+
1620
androidx-lifecycle-service = "androidx.lifecycle:lifecycle-service:2.8.7"
1721
androidx-test-core = "androidx.test:core:1.7.0"
1822
androidx-test-ext-junit = "androidx.test.ext:junit:1.3.0"
19-
# 1.7.0+ requires minSdkVersion 21 in android-interop-testing
20-
# checkForUpdates: androidx-test-rules:1.6.+
21-
androidx-test-rules = "androidx.test:rules:1.6.1"
23+
androidx-test-rules = "androidx.test:rules:1.7.0"
2224
animalsniffer = "org.codehaus.mojo:animal-sniffer:1.26"
2325
animalsniffer-annotations = "org.codehaus.mojo:animal-sniffer-annotations:1.26"
2426
assertj-core = "org.assertj:assertj-core:3.27.6"
@@ -37,7 +39,7 @@ checkstyle = "com.puppycrawl.tools:checkstyle:10.26.1"
3739
checkstylejava8 = "com.puppycrawl.tools:checkstyle:9.3"
3840
commons-math3 = "org.apache.commons:commons-math3:3.6.1"
3941
conscrypt = "org.conscrypt:conscrypt-openjdk-uber:2.5.2"
40-
# 141.7340.3+ requires minSdkVersion 23
42+
# 141.7340.3+ requires Java 17+
4143
# checkForUpdates: cronet-api:119.6045.31
4244
cronet-api = "org.chromium.net:cronet-api:119.6045.31"
4345
# checkForUpdates: cronet-embedded:119.6045.31
@@ -54,9 +56,7 @@ google-auth-credentials = "com.google.auth:google-auth-library-credentials:1.41.
5456
google-auth-oauth2Http = "com.google.auth:google-auth-library-oauth2-http:1.41.0"
5557
# Release notes: https://cloud.google.com/logging/docs/release-notes
5658
google-cloud-logging = "com.google.cloud:google-cloud-logging:3.23.9"
57-
# 2.13.0 requires error_prone_annotations:2.37.0, but we are stuck with 2.36.0
58-
# checkForUpdates: gson:2.12.+
59-
gson = "com.google.code.gson:gson:2.12.1"
59+
gson = "com.google.code.gson:gson:2.13.2"
6060
guava = "com.google.guava:guava:33.5.0-android"
6161
guava-betaChecker = "com.google.guava:guava-beta-checker:1.0"
6262
guava-testlib = "com.google.guava:guava-testlib:33.5.0-android"

repositories.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ IO_GRPC_GRPC_JAVA_ARTIFACTS = [
1818
"com.google.auto.value:auto-value-annotations:1.11.0",
1919
"com.google.auto.value:auto-value:1.11.0",
2020
"com.google.code.findbugs:jsr305:3.0.2",
21-
"com.google.code.gson:gson:2.12.1",
21+
"com.google.code.gson:gson:2.13.2",
2222
"com.google.errorprone:error_prone_annotations:2.45.0",
2323
"com.google.guava:failureaccess:1.0.1",
2424
"com.google.guava:guava:33.5.0-android",

xds/src/main/java/io/grpc/xds/GrpcXdsTransportFactory.java

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,39 @@
3333
import io.grpc.Status;
3434
import io.grpc.xds.client.Bootstrapper;
3535
import io.grpc.xds.client.XdsTransportFactory;
36+
import java.util.Map;
37+
import java.util.concurrent.ConcurrentHashMap;
3638
import java.util.concurrent.TimeUnit;
3739

40+
/**
41+
* A factory for creating gRPC-based transports for xDS communication.
42+
*
43+
* <p>WARNING: This class reuses channels when possible, based on the provided {@link
44+
* Bootstrapper.ServerInfo} with important considerations. The {@link Bootstrapper.ServerInfo}
45+
* includes {@link ChannelCredentials}, which is compared by reference equality. This means every
46+
* {@link Bootstrapper.BootstrapInfo} would have non-equal copies of {@link
47+
* Bootstrapper.ServerInfo}, even if they all represent the same xDS server configuration. For gRPC
48+
* name resolution with the {@code xds} and {@code google-c2p} scheme, this transport sharing works
49+
* as expected as it internally reuses a single {@link Bootstrapper.BootstrapInfo} instance.
50+
* Otherwise, new transports would be created for each {@link Bootstrapper.ServerInfo} despite them
51+
* possibly representing the same xDS server configuration and defeating the purpose of transport
52+
* sharing.
53+
*/
3854
final class GrpcXdsTransportFactory implements XdsTransportFactory {
3955

4056
private final CallCredentials callCredentials;
57+
<<<<<<< child-channel-plugin
4158
private final ChannelConfigurer channelConfigurer;
59+
=======
60+
// The map of xDS server info to its corresponding gRPC xDS transport.
61+
// This enables reusing and sharing the same underlying gRPC channel.
62+
//
63+
// NOTE: ConcurrentHashMap is used as a per-entry lock and all reads and writes must be a mutation
64+
// via the ConcurrentHashMap APIs to acquire the per-entry lock in order to ensure thread safety
65+
// for reference counting of each GrpcXdsTransport instance.
66+
private static final Map<Bootstrapper.ServerInfo, GrpcXdsTransport> xdsServerInfoToTransportMap =
67+
new ConcurrentHashMap<>();
68+
>>>>>>> master
4269

4370

4471
GrpcXdsTransportFactory(CallCredentials callCredentials,
@@ -49,27 +76,42 @@ final class GrpcXdsTransportFactory implements XdsTransportFactory {
4976

5077
@Override
5178
public XdsTransport create(Bootstrapper.ServerInfo serverInfo) {
79+
<<<<<<< child-channel-plugin
5280
return new GrpcXdsTransport(serverInfo, callCredentials, channelConfigurer);
81+
=======
82+
return xdsServerInfoToTransportMap.compute(
83+
serverInfo,
84+
(info, transport) -> {
85+
if (transport == null) {
86+
transport = new GrpcXdsTransport(serverInfo, callCredentials);
87+
}
88+
++transport.refCount;
89+
return transport;
90+
});
91+
>>>>>>> master
5392
}
5493

5594
@VisibleForTesting
5695
public XdsTransport createForTest(ManagedChannel channel) {
57-
return new GrpcXdsTransport(channel, callCredentials);
96+
return new GrpcXdsTransport(channel, callCredentials, null);
5897
}
5998

6099
@VisibleForTesting
61100
static class GrpcXdsTransport implements XdsTransport {
62101

63102
private final ManagedChannel channel;
64103
private final CallCredentials callCredentials;
104+
private final Bootstrapper.ServerInfo serverInfo;
105+
// Must only be accessed via the ConcurrentHashMap APIs which act as the locking methods.
106+
private int refCount = 0;
65107

66108
public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo) {
67109
this(serverInfo, null);
68110
}
69111

70112
@VisibleForTesting
71113
public GrpcXdsTransport(ManagedChannel channel) {
72-
this(channel, null);
114+
this(channel, null, null);
73115
}
74116

75117
public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo, CallCredentials callCredentials) {
@@ -79,6 +121,7 @@ public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo, CallCredentials call
79121
.keepAliveTime(5, TimeUnit.MINUTES)
80122
.build();
81123
this.callCredentials = callCredentials;
124+
this.serverInfo = serverInfo;
82125
}
83126

84127
public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo,
@@ -96,9 +139,13 @@ public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo,
96139
}
97140

98141
@VisibleForTesting
99-
public GrpcXdsTransport(ManagedChannel channel, CallCredentials callCredentials) {
142+
public GrpcXdsTransport(
143+
ManagedChannel channel,
144+
CallCredentials callCredentials,
145+
Bootstrapper.ServerInfo serverInfo) {
100146
this.channel = checkNotNull(channel, "channel");
101147
this.callCredentials = callCredentials;
148+
this.serverInfo = serverInfo;
102149
}
103150

104151
@Override
@@ -118,7 +165,19 @@ public <ReqT, RespT> StreamingCall<ReqT, RespT> createStreamingCall(
118165

119166
@Override
120167
public void shutdown() {
121-
channel.shutdown();
168+
if (serverInfo == null) {
169+
channel.shutdown();
170+
return;
171+
}
172+
xdsServerInfoToTransportMap.computeIfPresent(
173+
serverInfo,
174+
(info, transport) -> {
175+
if (--transport.refCount == 0) { // Prefix decrement and return the updated value.
176+
transport.channel.shutdown();
177+
return null; // Remove mapping.
178+
}
179+
return transport;
180+
});
122181
}
123182

124183
private class XdsStreamingCall<ReqT, RespT> implements

xds/src/main/java/io/grpc/xds/XdsNameResolver.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
import io.grpc.xds.client.XdsInitializationException;
6969
import io.grpc.xds.client.XdsLogger;
7070
import io.grpc.xds.client.XdsLogger.XdsLogLevel;
71-
import java.net.URI;
7271
import java.util.ArrayList;
7372
import java.util.Collections;
7473
import java.util.HashMap;
@@ -111,7 +110,6 @@ final class XdsNameResolver extends NameResolver {
111110
private final XdsLogger logger;
112111
@Nullable
113112
private final String targetAuthority;
114-
private final String target;
115113
private final String serviceAuthority;
116114
// Encoded version of the service authority as per
117115
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.
@@ -142,12 +140,12 @@ final class XdsNameResolver extends NameResolver {
142140
private ResolveState resolveState;
143141

144142
XdsNameResolver(
145-
URI targetUri, String name, @Nullable String overrideAuthority,
146-
ServiceConfigParser serviceConfigParser,
143+
String target, @Nullable String targetAuthority, String name,
144+
@Nullable String overrideAuthority, ServiceConfigParser serviceConfigParser,
147145
SynchronizationContext syncContext, ScheduledExecutorService scheduler,
148146
@Nullable Map<String, ?> bootstrapOverride,
149147
MetricRecorder metricRecorder, Args nameResolverArgs) {
150-
this(targetUri, targetUri.getAuthority(), name, overrideAuthority, serviceConfigParser,
148+
this(target, targetAuthority, name, overrideAuthority, serviceConfigParser,
151149
syncContext, scheduler,
152150
bootstrapOverride == null
153151
? SharedXdsClientPoolProvider.getDefaultProvider()
@@ -158,14 +156,13 @@ final class XdsNameResolver extends NameResolver {
158156

159157
@VisibleForTesting
160158
XdsNameResolver(
161-
URI targetUri, @Nullable String targetAuthority, String name,
159+
String target, @Nullable String targetAuthority, String name,
162160
@Nullable String overrideAuthority, ServiceConfigParser serviceConfigParser,
163161
SynchronizationContext syncContext, ScheduledExecutorService scheduler,
164162
XdsClientPoolFactory xdsClientPoolFactory, ThreadSafeRandom random,
165163
FilterRegistry filterRegistry, @Nullable Map<String, ?> bootstrapOverride,
166164
MetricRecorder metricRecorder, Args nameResolverArgs) {
167165
this.targetAuthority = targetAuthority;
168-
target = targetUri.toString();
169166

170167
// The name might have multiple slashes so encode it before verifying.
171168
serviceAuthority = checkNotNull(name, "name");

0 commit comments

Comments
 (0)