Skip to content

Commit 36c2927

Browse files
committed
plumb child channel options through xDS server
1 parent 4905f72 commit 36c2927

24 files changed

+243
-43
lines changed

api/src/main/java/io/grpc/ForwardingChannelBuilder.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,12 @@ public T configureChannel(ManagedChannel parentChannel) {
248248
return thisT();
249249
}
250250

251+
@Override
252+
public T configureChannel(Server parentServer) {
253+
delegate().configureChannel(parentServer);
254+
return thisT();
255+
}
256+
251257
@Override
252258
public T childChannelConfigurer(ChildChannelConfigurer childChannelConfigurer) {
253259
delegate().childChannelConfigurer(childChannelConfigurer);

api/src/main/java/io/grpc/ForwardingChannelBuilder2.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ public T configureChannel(ManagedChannel parentChannel) {
275275
return thisT();
276276
}
277277

278+
@Override
279+
public T configureChannel(Server parentServer) {
280+
delegate().configureChannel(parentServer);
281+
return thisT();
282+
}
283+
278284
@Override
279285
public T childChannelConfigurer(ChildChannelConfigurer childChannelConfigurer) {
280286
delegate().childChannelConfigurer(childChannelConfigurer);

api/src/main/java/io/grpc/ForwardingServerBuilder.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,18 @@ public T setBinaryLog(BinaryLog binaryLog) {
192192
return thisT();
193193
}
194194

195+
@Override
196+
public T configureChannel(Server parentServer) {
197+
delegate().configureChannel(parentServer);
198+
return thisT();
199+
}
200+
201+
@Override
202+
public T childChannelConfigurer(ChildChannelConfigurer childChannelConfigurer) {
203+
delegate().childChannelConfigurer(childChannelConfigurer);
204+
return thisT();
205+
}
206+
195207
/**
196208
* Returns the {@link Server} built by the delegate by default. Overriding method can return
197209
* different value.

api/src/main/java/io/grpc/ManagedChannel.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,14 @@ public ConnectivityState getState(boolean requestConnection) {
9292
* load balancers and the channel builder) to propagate configuration to child channels.
9393
* Application code should not call this method.
9494
*
95-
* @return the configurer, or {@code null} if none is set.
95+
* @return the configurer, or {@code noOp()} if none is set.
9696
* @since 1.79.0
9797
*/
9898
@Internal
9999
public ChildChannelConfigurer getChildChannelConfigurer() {
100-
// Return null by default so we don't break existing custom ManagedChannel implementations
100+
// Return noOP() by default so we don't break existing custom ManagedChannel implementations
101101
// (like wrappers or mocks) that don't override this method.
102-
return null;
102+
return ChildChannelConfigurers.noOp();
103103
}
104104

105105
/**

api/src/main/java/io/grpc/ManagedChannelBuilder.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -668,9 +668,6 @@ public <X> T setNameResolverArg(NameResolver.Args.Key<X> key, X value) {
668668
* child channels to ensure they inherit relevant configuration (like the
669669
* {@link ChildChannelConfigurer}) from the parent.
670670
*
671-
* <p>The specific settings copied are implementation dependent, but typically include
672-
* the child channel configurer and potentially user agents or offload executors.
673-
*
674671
* @param parentChannel the channel to inherit configuration from
675672
* @return this
676673
* @since 1.79.0
@@ -680,12 +677,27 @@ public T configureChannel(ManagedChannel parentChannel) {
680677
throw new UnsupportedOperationException();
681678
}
682679

680+
/**
681+
* Configures this builder using settings derived from an existing parent server.
682+
*
683+
* <p>This method is typically used by internal components (like LoadBalancers) when creating
684+
* child channels to ensure they inherit relevant configuration (like the
685+
* {@link ChildChannelConfigurer}) from the parent.
686+
*
687+
* @param parentServer the server to inherit configuration from
688+
* @return this
689+
* @since 1.79.0
690+
*/
691+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/12574")
692+
public T configureChannel(Server parentServer) {
693+
throw new UnsupportedOperationException();
694+
}
695+
683696
/**
684697
* Sets a configurer that will be applied to all internal child channels created by this channel.
685698
*
686699
* <p>This allows injecting configuration (like credentials, interceptors, or flow control)
687-
* into auxiliary channels created by gRPC infrastructure, such as xDS control plane connections
688-
* or OOB load balancing channels.
700+
* into auxiliary channels created by gRPC infrastructure, such as xDS control plane connections.
689701
*
690702
* @param childChannelConfigurer the configurer to apply.
691703
* @return this

api/src/main/java/io/grpc/Server.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,21 @@ public List<ServerServiceDefinition> getMutableServices() {
178178
* @since 1.0.0
179179
*/
180180
public abstract void awaitTermination() throws InterruptedException;
181+
182+
/**
183+
* Returns the configurer for child channels.
184+
*
185+
* <p>This method is intended for use by the internal gRPC infrastructure
186+
* to propagate configuration to child channels.
187+
* Application code should not call this method.
188+
*
189+
* @return the configurer, or {@code noOp()} if none is set.
190+
* @since 1.79.0
191+
*/
192+
@Internal
193+
public ChildChannelConfigurer getChildChannelConfigurer() {
194+
// Return noOp() by default so we don't break existing custom ManagedChannel implementations
195+
// (like wrappers or mocks) that don't override this method.
196+
return ChildChannelConfigurers.noOp();
197+
}
181198
}

api/src/main/java/io/grpc/ServerBuilder.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,39 @@ public T setBinaryLog(BinaryLog binaryLog) {
424424
throw new UnsupportedOperationException();
425425
}
426426

427+
/**
428+
* Configures this builder using settings derived from an existing parent server.
429+
*
430+
* <p>This method is typically used by internal components when creating
431+
* child channels to ensure they inherit relevant configuration (like the
432+
* {@link ChildChannelConfigurer}) from the parent.
433+
*
434+
* @param parentServer the server to inherit configuration from
435+
* @return this
436+
* @since 1.79.0
437+
*/
438+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/12574")
439+
public T configureChannel(Server parentServer) {
440+
throw new UnsupportedOperationException();
441+
}
442+
443+
/**
444+
* Sets a configurer that will be applied to all internal child channels created by this server.
445+
*
446+
* <p>This allows injecting configuration (like credentials, interceptors, or flow control)
447+
* into auxiliary channels created by gRPC infrastructure, such as xDS control plane connections
448+
* or OOB load balancing channels.
449+
*
450+
* @param childChannelConfigurer the configurer to apply.
451+
* @return this
452+
* @since 1.79.0
453+
*/
454+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/12574")
455+
public T childChannelConfigurer(ChildChannelConfigurer childChannelConfigurer) {
456+
throw new UnsupportedOperationException("Not implemented");
457+
}
458+
459+
427460
/**
428461
* Builds a server using the given parameters.
429462
*

core/src/main/java/io/grpc/internal/ManagedChannelImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ public Result selectConfig(PickSubchannelArgs args) {
159159
/**
160160
* Stores the user-provided configuration function for internal child channels.
161161
*
162-
* <p>This is intended for use by gRPC internal components (NameResolvers, LoadBalancers)
163-
* that are responsible for creating auxillary {@code ManagedChannel} instances.
162+
* <p>This is intended for use by gRPC internal components
163+
* that are responsible for creating auxiliary {@code ManagedChannel} instances.
164164
* guaranteed to be not null (defaults to no-op).
165165
*/
166166
private ChildChannelConfigurer childChannelConfigurer = ChildChannelConfigurers.noOp();
@@ -693,7 +693,7 @@ public CallTracer create() {
693693
/**
694694
* Retrieves the user-provided configuration function for internal child channels.
695695
*
696-
* <p>This method is intended for use by gRPC internal components (NameResolvers, LoadBalancers)
696+
* <p>This method is intended for use by gRPC internal components
697697
* that are responsible for creating auxiliary {@code ManagedChannel} instances.
698698
*
699699
* @return the ChildChannelConfigurer, guaranteed to be not null (defaults to no-op).

core/src/main/java/io/grpc/internal/ManagedChannelImplBuilder.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import io.grpc.NameResolverProvider;
4747
import io.grpc.NameResolverRegistry;
4848
import io.grpc.ProxyDetector;
49+
import io.grpc.Server;
4950
import io.grpc.StatusOr;
5051
import java.lang.reflect.InvocationTargetException;
5152
import java.lang.reflect.Method;
@@ -724,7 +725,8 @@ protected ManagedChannelImplBuilder addMetricSink(MetricSink metricSink) {
724725
* automatically from a parent channel to any child channels it creates
725726
* (e.g., Subchannels or OOB channels).
726727
*
727-
* @param parentChannel the channel whose configuration logic should be applied to this builder.
728+
* @param parentChannel the channel whose child's configuration logic
729+
* should be applied to this builder.
728730
*/
729731
@Override
730732
public ManagedChannelImplBuilder configureChannel(ManagedChannel parentChannel) {
@@ -737,6 +739,27 @@ public ManagedChannelImplBuilder configureChannel(ManagedChannel parentChannel)
737739
return this;
738740
}
739741

742+
/**
743+
* Applies the configuration logic from the given parent server to this builder.
744+
*
745+
* <p>This mechanism allows properties (like metrics, tracing, or interceptors) to propagate
746+
* automatically from a parent server to any child channels it creates
747+
* (e.g., xDS).
748+
*
749+
* @param parentServer the server whose child's configuration logic
750+
* should be applied to this builder.
751+
*/
752+
@Override
753+
public ManagedChannelImplBuilder configureChannel(Server parentServer) {
754+
if (parentServer != null) {
755+
ChildChannelConfigurer childChannelConfigurer = parentServer.getChildChannelConfigurer();
756+
if (childChannelConfigurer != null) {
757+
childChannelConfigurer.accept(this);
758+
}
759+
}
760+
return this;
761+
}
762+
740763
/**
741764
* Sets the configurer that will be stored in the channel built by this builder.
742765
*

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
import io.grpc.Context;
2727
import io.grpc.Grpc;
2828
import io.grpc.ManagedChannel;
29+
import io.grpc.ManagedChannelBuilder;
2930
import io.grpc.Metadata;
3031
import io.grpc.MethodDescriptor;
32+
import io.grpc.Server;
3133
import io.grpc.Status;
3234
import io.grpc.xds.client.Bootstrapper;
3335
import io.grpc.xds.client.XdsTransportFactory;
@@ -37,15 +39,19 @@ final class GrpcXdsTransportFactory implements XdsTransportFactory {
3739

3840
private final CallCredentials callCredentials;
3941
private final ManagedChannel parentChannel;
42+
private final Server parentServer;
4043

41-
GrpcXdsTransportFactory(CallCredentials callCredentials, ManagedChannel parentChannel) {
44+
45+
GrpcXdsTransportFactory(CallCredentials callCredentials, ManagedChannel parentChannel,
46+
Server parentServer) {
4247
this.callCredentials = callCredentials;
4348
this.parentChannel = parentChannel;
49+
this.parentServer = parentServer;
4450
}
4551

4652
@Override
4753
public XdsTransport create(Bootstrapper.ServerInfo serverInfo) {
48-
return new GrpcXdsTransport(serverInfo, callCredentials, parentChannel);
54+
return new GrpcXdsTransport(serverInfo, callCredentials, parentChannel, parentServer);
4955
}
5056

5157
@VisibleForTesting
@@ -78,13 +84,17 @@ public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo, CallCredentials call
7884
}
7985

8086
public GrpcXdsTransport(Bootstrapper.ServerInfo serverInfo, CallCredentials callCredentials,
81-
ManagedChannel parentChannel) {
87+
ManagedChannel parentChannel, Server parentServer) {
8288
String target = serverInfo.target();
8389
ChannelCredentials channelCredentials = (ChannelCredentials) serverInfo.implSpecificConfig();
84-
this.channel = Grpc.newChannelBuilder(target, channelCredentials)
85-
.keepAliveTime(5, TimeUnit.MINUTES)
86-
.configureChannel(parentChannel)
87-
.build();
90+
ManagedChannelBuilder<?> channelBuilder = Grpc.newChannelBuilder(target, channelCredentials)
91+
.keepAliveTime(5, TimeUnit.MINUTES);
92+
if (parentChannel != null) {
93+
channelBuilder.configureChannel(parentChannel);
94+
} else if (parentServer != null) {
95+
channelBuilder.configureChannel(parentServer);
96+
}
97+
this.channel = channelBuilder.build();
8898
this.callCredentials = callCredentials;
8999
}
90100

0 commit comments

Comments
 (0)