Skip to content

Commit 2a5b554

Browse files
committed
Fix: Append child channel configurators instead of overwriting
1 parent da2213c commit 2a5b554

6 files changed

Lines changed: 87 additions & 24 deletions

File tree

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,8 +762,16 @@ protected ManagedChannelImplBuilder addMetricSink(MetricSink metricSink) {
762762
@Override
763763
public ManagedChannelImplBuilder childChannelConfigurator(
764764
ChannelConfigurator channelConfigurator) {
765-
this.channelConfigurator = checkNotNull(channelConfigurator,
766-
"childChannelConfigurator");
765+
checkNotNull(channelConfigurator, "childChannelConfigurator");
766+
if (this.channelConfigurator == null) {
767+
this.channelConfigurator = channelConfigurator;
768+
} else {
769+
ChannelConfigurator oldConfigurator = this.channelConfigurator;
770+
this.channelConfigurator = builder -> {
771+
oldConfigurator.configureChannelBuilder(builder);
772+
channelConfigurator.configureChannelBuilder(builder);
773+
};
774+
}
767775
return this;
768776
}
769777

core/src/test/java/io/grpc/internal/ManagedChannelImplBuilderTest.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -808,13 +808,6 @@ public void setNameResolverExtArgs() {
808808
assertThat(builder.nameResolverCustomArgs.get(testKey)).isEqualTo(42);
809809
}
810810

811-
@Test
812-
public void childChannelConfigurator_setsField() {
813-
ChannelConfigurator configurator = builder -> { };
814-
assertSame(builder, builder.childChannelConfigurator(configurator));
815-
assertSame(configurator, builder.channelConfigurator);
816-
}
817-
818811
@Test
819812
public void childChannelConfigurator_propagatesMetricsAndInterceptors_xdsTarget() {
820813
// Setup Mocks
@@ -902,16 +895,13 @@ public String getDefaultScheme() {
902895
assertNotNull("Child channel configurator should be present in NameResolver.Args",
903896
channelConfiguratorInArgs);
904897

905-
// Verify the configurator is the one we passed
906-
assertThat(channelConfiguratorInArgs).isSameInstanceAs(configurator);
907-
908898
// Verify the configurator logically applies (by running it on a real builder)
909899
ManagedChannelImplBuilder childBuilder = new ManagedChannelImplBuilder(
910900
"xds:///child-service-target",
911901
mockClientTransportFactoryBuilder,
912902
new FixedPortProvider(DUMMY_PORT));
913903

914-
configurator.configureChannelBuilder(childBuilder);
904+
channelConfiguratorInArgs.configureChannelBuilder(childBuilder);
915905
assertThat(childBuilder.metricSinks).contains(mockMetricSink);
916906
}
917907

core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,10 @@ public void immediateDeadlineExceeded() {
499499

500500
@Test
501501
public void childChannelConfigurator_passedToNameResolverArgs() {
502-
ChannelConfigurator configurator = builder -> { };
502+
final boolean[] configuratorInvoked = new boolean[1];
503+
ChannelConfigurator configurator = builder -> {
504+
configuratorInvoked[0] = true;
505+
};
503506
channelBuilder.childChannelConfigurator(configurator);
504507
AtomicReference<NameResolver.Args> actualArgs = new AtomicReference<>();
505508
channelBuilder.nameResolverRegistry.register(new NameResolverProvider() {
@@ -528,12 +531,18 @@ protected int priority() {
528531
});
529532
createChannel();
530533
assertNotNull(actualArgs.get());
531-
assertSame(configurator, actualArgs.get().getChildChannelConfigurator());
534+
ChannelConfigurator childConfigurator = actualArgs.get().getChildChannelConfigurator();
535+
assertNotNull(childConfigurator);
536+
childConfigurator.configureChannelBuilder(channelBuilder);
537+
assertTrue(configuratorInvoked[0]);
532538
}
533539

534540
@Test
535541
public void childChannelConfigurator_passedToResolvingOobChannelNameResolverArgs() {
536-
ChannelConfigurator configurator = builder -> { };
542+
final boolean[] configuratorInvoked = new boolean[1];
543+
ChannelConfigurator configurator = builder -> {
544+
configuratorInvoked[0] = true;
545+
};
537546
channelBuilder.childChannelConfigurator(configurator);
538547
AtomicReference<NameResolver.Args> oobArgs = new AtomicReference<>();
539548
channelBuilder.nameResolverRegistry.register(new NameResolverProvider() {
@@ -567,7 +576,10 @@ protected int priority() {
567576
ManagedChannel oob = helper.createResolvingOobChannelBuilder("oobauthority").build();
568577
oob.getState(true);
569578
assertNotNull(oobArgs.get());
570-
assertSame(configurator, oobArgs.get().getChildChannelConfigurator());
579+
ChannelConfigurator childConfigurator = oobArgs.get().getChildChannelConfigurator();
580+
assertNotNull(childConfigurator);
581+
childConfigurator.configureChannelBuilder(channelBuilder);
582+
assertTrue(configuratorInvoked[0]);
571583
oob.shutdownNow();
572584
}
573585

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,16 @@ public XdsServerBuilder drainGraceTime(long drainGraceTime, TimeUnit drainGraceT
113113
* @return this
114114
*/
115115
public XdsServerBuilder childChannelConfigurator(ChannelConfigurator channelConfigurator) {
116-
this.channelConfigurator = checkNotNull(channelConfigurator, "channelConfigurator");
116+
checkNotNull(channelConfigurator, "channelConfigurator");
117+
if (this.channelConfigurator == null) {
118+
this.channelConfigurator = channelConfigurator;
119+
} else {
120+
ChannelConfigurator oldConfigurator = this.channelConfigurator;
121+
this.channelConfigurator = builder -> {
122+
oldConfigurator.configureChannelBuilder(builder);
123+
channelConfigurator.configureChannelBuilder(builder);
124+
};
125+
}
117126
return this;
118127
}
119128

xds/src/test/java/io/grpc/xds/GrpcXdsTransportFactoryTest.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import static com.google.common.truth.Truth.assertThat;
2020
import static org.junit.Assert.assertNotNull;
21-
import static org.junit.Assert.assertSame;
2221
import static org.mockito.Mockito.mock;
2322
import static org.mockito.Mockito.verify;
2423
import static org.mockito.Mockito.when;
@@ -260,13 +259,20 @@ protected int priority() {
260259
};
261260
NameResolverRegistry.getDefaultRegistry().register(testProvider);
262261
try {
263-
ChannelConfigurator configurer = builder -> { };
262+
final boolean[] configuratorInvoked = new boolean[1];
263+
ChannelConfigurator configurer = builder -> {
264+
configuratorInvoked[0] = true;
265+
};
264266
GrpcXdsTransportFactory factory = new GrpcXdsTransportFactory(null, configurer);
265267
XdsTransportFactory.XdsTransport transport = factory.create(
266268
Bootstrapper.ServerInfo.create(
267269
"test-xds-transport://localhost:8080", InsecureChannelCredentials.create()));
268270
assertNotNull(capturedArgs.get());
269-
assertSame(configurer, capturedArgs.get().getChildChannelConfigurator());
271+
ChannelConfigurator childConfigurator = capturedArgs.get().getChildChannelConfigurator();
272+
assertNotNull(childConfigurator);
273+
ManagedChannelBuilder<?> testBuilder = mock(ManagedChannelBuilder.class);
274+
childConfigurator.configureChannelBuilder(testBuilder);
275+
assertThat(configuratorInvoked[0]).isTrue();
270276
transport.shutdown();
271277
} finally {
272278
NameResolverRegistry.getDefaultRegistry().deregister(testProvider);

xds/src/test/java/io/grpc/xds/XdsServerBuilderTest.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
import static com.google.common.truth.Truth.assertThat;
2020
import static io.grpc.xds.XdsServerTestHelper.buildTestListener;
21+
import static org.junit.Assert.assertNotSame;
2122
import static org.junit.Assert.fail;
2223
import static org.mockito.Mockito.any;
23-
import static org.mockito.Mockito.eq;
2424
import static org.mockito.Mockito.mock;
2525
import static org.mockito.Mockito.never;
2626
import static org.mockito.Mockito.reset;
@@ -332,7 +332,10 @@ public void testOverrideBootstrap() throws Exception {
332332

333333
@Test
334334
public void start_passesChannelConfiguratorToClientPoolFactory() throws Exception {
335-
ChannelConfigurator configurer = builder -> { };
335+
final boolean[] configuratorInvoked = new boolean[1];
336+
ChannelConfigurator configurer = builder -> {
337+
configuratorInvoked[0] = true;
338+
};
336339
XdsClientPoolFactory mockPoolFactory = mock(XdsClientPoolFactory.class);
337340
@SuppressWarnings("unchecked")
338341
ObjectPool<XdsClient> mockPool = mock(ObjectPool.class);
@@ -346,8 +349,43 @@ public void start_passesChannelConfiguratorToClientPoolFactory() throws Exceptio
346349

347350
Future<?> unused = startServerAsync();
348351

352+
ArgumentCaptor<ChannelConfigurator> configuratorCaptor =
353+
ArgumentCaptor.forClass(ChannelConfigurator.class);
349354
verify(mockPoolFactory).getOrCreate(
350-
any(), any(), any(), eq(configurer));
355+
any(), any(), any(), configuratorCaptor.capture());
356+
357+
io.grpc.ManagedChannelBuilder<?> testBuilder = mock(io.grpc.ManagedChannelBuilder.class);
358+
configuratorCaptor.getValue().configureChannelBuilder(testBuilder);
359+
assertThat(configuratorInvoked[0]).isTrue();
360+
}
361+
362+
@Test
363+
public void childChannelConfigurator_appendsConfigurators() throws Exception {
364+
ChannelConfigurator configurer1 = builder -> { };
365+
ChannelConfigurator configurer2 = builder -> { };
366+
367+
XdsClientPoolFactory mockPoolFactory = mock(XdsClientPoolFactory.class);
368+
@SuppressWarnings("unchecked")
369+
ObjectPool<XdsClient> mockPool = mock(ObjectPool.class);
370+
when(mockPool.getObject()).thenReturn(xdsClient);
371+
when(mockPoolFactory.getOrCreate(any(), any(), any(), any())).thenReturn(mockPool);
372+
373+
buildBuilder(null);
374+
builder.childChannelConfigurator(configurer1);
375+
builder.childChannelConfigurator(configurer2);
376+
builder.xdsClientPoolFactory(mockPoolFactory);
377+
xdsServer = cleanupRule.register((XdsServerWrapper) builder.build());
378+
379+
Future<?> unused = startServerAsync();
380+
381+
// The captured configurator should be a composite of configurer1 and configurer2
382+
ArgumentCaptor<ChannelConfigurator> captor = ArgumentCaptor.forClass(ChannelConfigurator.class);
383+
verify(mockPoolFactory).getOrCreate(
384+
any(), any(), any(), captor.capture());
385+
ChannelConfigurator captured = captor.getValue();
386+
387+
assertNotSame(configurer1, captured);
388+
assertNotSame(configurer2, captured);
351389
}
352390

353391
@Test

0 commit comments

Comments
 (0)