Skip to content

Commit 4df7c4f

Browse files
committed
use the new API in channelProviders
1 parent 6913156 commit 4df7c4f

File tree

11 files changed

+309
-15
lines changed

11 files changed

+309
-15
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ protected NewChannelBuilderResult newChannelBuilder(String target, ChannelCreden
103103
protected NewChannelBuilderResult newChannelBuilder(String target, ChannelCredentials creds,
104104
NameResolverRegistry nameResolverRegistry,
105105
NameResolverProvider nameResolverProvider) {
106-
// Implementation note: Currently delegates to the simplified version
107106
return newChannelBuilder(target, creds);
108107
}
109108

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

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ public static ManagedChannelBuilder<?> forTarget(String target) {
152152

153153
private final List<ClientInterceptor> interceptors = new ArrayList<>();
154154
NameResolverRegistry nameResolverRegistry = NameResolverRegistry.getDefaultRegistry();
155+
@Nullable
156+
NameResolverProvider nameResolverProvider;
155157

156158
final List<ClientTransportFilter> transportFilters = new ArrayList<>();
157159

@@ -433,11 +435,16 @@ public ManagedChannelImplBuilder nameResolverFactory(NameResolver.Factory resolv
433435
return this;
434436
}
435437

436-
ManagedChannelImplBuilder nameResolverRegistry(NameResolverRegistry resolverRegistry) {
438+
public ManagedChannelImplBuilder nameResolverRegistry(NameResolverRegistry resolverRegistry) {
437439
this.nameResolverRegistry = resolverRegistry;
438440
return this;
439441
}
440442

443+
public ManagedChannelImplBuilder nameResolverProvider(NameResolverProvider provider) {
444+
this.nameResolverProvider = provider;
445+
return this;
446+
}
447+
441448
@Override
442449
public ManagedChannelImplBuilder defaultLoadBalancingPolicy(String policy) {
443450
Preconditions.checkState(directServerAddress == null,
@@ -719,7 +726,8 @@ public ManagedChannel build() {
719726
ClientTransportFactory clientTransportFactory =
720727
clientTransportFactoryBuilder.buildClientTransportFactory();
721728
ResolvedNameResolver resolvedResolver = getNameResolverProvider(
722-
target, nameResolverRegistry, clientTransportFactory.getSupportedSocketAddressTypes());
729+
target, nameResolverRegistry, nameResolverProvider,
730+
clientTransportFactory.getSupportedSocketAddressTypes());
723731
return new ManagedChannelOrphanWrapper(new ManagedChannelImpl(
724732
this,
725733
clientTransportFactory,
@@ -826,7 +834,8 @@ public ResolvedNameResolver(URI targetUri, NameResolverProvider provider) {
826834
@VisibleForTesting
827835
static ResolvedNameResolver getNameResolverProvider(
828836
String target, NameResolverRegistry nameResolverRegistry,
829-
Collection<Class<? extends SocketAddress>> channelTransportSocketAddressTypes) {
837+
NameResolverProvider nameResolverProvider,
838+
Collection<Class<? extends SocketAddress>> channelTransportSocketAddressTypes) {
830839
// Finding a NameResolver. Try using the target string as the URI. If that fails, try prepending
831840
// "dns:///".
832841
NameResolverProvider provider = null;
@@ -841,19 +850,28 @@ static ResolvedNameResolver getNameResolverProvider(
841850
if (targetUri != null) {
842851
// For "localhost:8080" this would likely cause provider to be null, because "localhost" is
843852
// parsed as the scheme. Will hit the next case and try "dns:///localhost:8080".
844-
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
853+
provider = nameResolverProvider;
854+
if (provider == null) {
855+
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
856+
}
845857
}
846858

847-
if (provider == null && !URI_PATTERN.matcher(target).matches()) {
848-
// It doesn't look like a URI target. Maybe it's an authority string. Try with the default
849-
// scheme from the registry.
859+
if (!URI_PATTERN.matcher(target).matches()) {
860+
// It doesn't look like a URI target. Maybe it's an authority string. Try with
861+
// the default scheme from the registry (if provider is not specified) or
862+
// the provider's default scheme (if provider is specified).
863+
String scheme = (provider != null)
864+
? provider.getDefaultScheme()
865+
: nameResolverRegistry.getDefaultScheme();
850866
try {
851-
targetUri = new URI(nameResolverRegistry.getDefaultScheme(), "", "/" + target, null);
867+
targetUri = new URI(scheme, "", "/" + target, null);
852868
} catch (URISyntaxException e) {
853-
// Should not be possible.
869+
// Should not happen because we just validated the URI.
854870
throw new IllegalArgumentException(e);
855871
}
856-
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
872+
if (provider == null) {
873+
provider = nameResolverRegistry.getProviderForScheme(targetUri.getScheme());
874+
}
857875
}
858876

859877
if (provider == null) {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public void validTargetNoProvider() {
9696
NameResolverRegistry nameResolverRegistry = new NameResolverRegistry();
9797
try {
9898
ManagedChannelImplBuilder.getNameResolverProvider(
99-
"foo.googleapis.com:8080", nameResolverRegistry,
99+
"foo.googleapis.com:8080", nameResolverRegistry, null,
100100
Collections.singleton(InetSocketAddress.class));
101101
fail("Should fail");
102102
} catch (IllegalArgumentException e) {
@@ -109,7 +109,7 @@ public void validTargetProviderAddrTypesNotSupported() {
109109
NameResolverRegistry nameResolverRegistry = getTestRegistry("testscheme");
110110
try {
111111
ManagedChannelImplBuilder.getNameResolverProvider(
112-
"testscheme:///foo.googleapis.com:8080", nameResolverRegistry,
112+
"testscheme:///foo.googleapis.com:8080", nameResolverRegistry, null,
113113
Collections.singleton(CustomSocketAddress.class));
114114
fail("Should fail");
115115
} catch (IllegalArgumentException e) {
@@ -123,7 +123,7 @@ private void testValidTarget(String target, String expectedUriString, URI expect
123123
NameResolverRegistry nameResolverRegistry = getTestRegistry(expectedUri.getScheme());
124124
ManagedChannelImplBuilder.ResolvedNameResolver resolved =
125125
ManagedChannelImplBuilder.getNameResolverProvider(
126-
target, nameResolverRegistry, Collections.singleton(InetSocketAddress.class));
126+
target, nameResolverRegistry, null, Collections.singleton(InetSocketAddress.class));
127127
assertThat(resolved.provider).isInstanceOf(FakeNameResolverProvider.class);
128128
assertThat(resolved.targetUri).isEqualTo(expectedUri);
129129
assertThat(resolved.targetUri.toString()).isEqualTo(expectedUriString);
@@ -135,7 +135,7 @@ private void testInvalidTarget(String target) {
135135
try {
136136
ManagedChannelImplBuilder.ResolvedNameResolver resolved =
137137
ManagedChannelImplBuilder.getNameResolverProvider(
138-
target, nameResolverRegistry, Collections.singleton(InetSocketAddress.class));
138+
target, nameResolverRegistry, null, Collections.singleton(InetSocketAddress.class));
139139
FakeNameResolverProvider nameResolverProvider = (FakeNameResolverProvider) resolved.provider;
140140
fail("Should have failed, but got resolver provider " + nameResolverProvider);
141141
} catch (IllegalArgumentException e) {

netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import io.grpc.HttpConnectProxiedSocketAddress;
3939
import io.grpc.Internal;
4040
import io.grpc.ManagedChannelBuilder;
41+
import io.grpc.NameResolverProvider;
42+
import io.grpc.NameResolverRegistry;
4143
import io.grpc.internal.AtomicBackoff;
4244
import io.grpc.internal.ClientTransportFactory;
4345
import io.grpc.internal.ConnectionClientTransport;
@@ -708,6 +710,24 @@ NettyChannelBuilder setTransportTracerFactory(TransportTracer.Factory transportT
708710
return this;
709711
}
710712

713+
/**
714+
* Sets the registry used for looking up name resolvers.
715+
*/
716+
@CanIgnoreReturnValue
717+
public NettyChannelBuilder nameResolverRegistry(NameResolverRegistry registry) {
718+
managedChannelImplBuilder.nameResolverRegistry(registry);
719+
return this;
720+
}
721+
722+
/**
723+
* Sets the {@link io.grpc.NameResolverProvider} to use.
724+
*/
725+
@CanIgnoreReturnValue
726+
public NettyChannelBuilder nameResolverProvider(NameResolverProvider provider) {
727+
managedChannelImplBuilder.nameResolverProvider(provider);
728+
return this;
729+
}
730+
711731
static Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
712732
return Collections.singleton(InetSocketAddress.class);
713733
}

netty/src/main/java/io/grpc/netty/NettyChannelProvider.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import io.grpc.ChannelCredentials;
2020
import io.grpc.Internal;
2121
import io.grpc.ManagedChannelProvider;
22+
import io.grpc.NameResolverProvider;
23+
import io.grpc.NameResolverRegistry;
2224
import java.net.SocketAddress;
2325
import java.util.Collection;
2426

@@ -55,6 +57,25 @@ public NewChannelBuilderResult newChannelBuilder(String target, ChannelCredentia
5557
new NettyChannelBuilder(target, creds, result.callCredentials, result.negotiator));
5658
}
5759

60+
@Override
61+
public NewChannelBuilderResult newChannelBuilder(String target, ChannelCredentials creds,
62+
NameResolverRegistry nameResolverRegistry,
63+
NameResolverProvider nameResolverProvider) {
64+
ProtocolNegotiators.FromChannelCredentialsResult result = ProtocolNegotiators.from(creds);
65+
if (result.error != null) {
66+
return NewChannelBuilderResult.error(result.error);
67+
}
68+
NettyChannelBuilder builder = new NettyChannelBuilder(target, creds,
69+
result.callCredentials, result.negotiator);
70+
if (nameResolverRegistry != null) {
71+
builder.nameResolverRegistry(nameResolverRegistry);
72+
}
73+
if (nameResolverProvider != null) {
74+
builder.nameResolverProvider(nameResolverProvider);
75+
}
76+
return NewChannelBuilderResult.channelBuilder(builder);
77+
}
78+
5879
@Override
5980
protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
6081
return NettyChannelBuilder.getSupportedSocketAddressTypes();

netty/src/main/java/io/grpc/netty/UdsNettyChannelProvider.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import io.grpc.ChannelCredentials;
2121
import io.grpc.Internal;
2222
import io.grpc.ManagedChannelProvider;
23+
import io.grpc.NameResolverProvider;
24+
import io.grpc.NameResolverRegistry;
2325
import io.grpc.internal.SharedResourcePool;
2426
import io.netty.channel.unix.DomainSocketAddress;
2527
import java.net.SocketAddress;
@@ -62,6 +64,21 @@ public NewChannelBuilderResult newChannelBuilder(String target, ChannelCredentia
6264
return result;
6365
}
6466

67+
@Override
68+
public NewChannelBuilderResult newChannelBuilder(String target, ChannelCredentials creds,
69+
NameResolverRegistry nameResolverRegistry,
70+
NameResolverProvider nameResolverProvider) {
71+
Preconditions.checkState(isAvailable());
72+
NewChannelBuilderResult result = new NettyChannelProvider().newChannelBuilder(
73+
target, creds, nameResolverRegistry, nameResolverProvider);
74+
if (result.getChannelBuilder() != null) {
75+
((NettyChannelBuilder) result.getChannelBuilder())
76+
.eventLoopGroupPool(SharedResourcePool.forResource(Utils.DEFAULT_WORKER_EVENT_LOOP_GROUP))
77+
.channelType(Utils.EPOLL_DOMAIN_CLIENT_CHANNEL_TYPE, DomainSocketAddress.class);
78+
}
79+
return result;
80+
}
81+
6582
@Override
6683
protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
6784
return Collections.singleton(DomainSocketAddress.class);

netty/src/test/java/io/grpc/netty/NettyChannelProviderTest.java

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,164 @@ public void newChannelBuilder_fail() {
8787
TlsChannelCredentials.newBuilder().requireFakeFeature().build());
8888
assertThat(result.getError()).contains("FAKE");
8989
}
90+
91+
@Test
92+
public void newChannelBuilder_withRegistry() {
93+
io.grpc.NameResolverRegistry registry = new io.grpc.NameResolverRegistry();
94+
NewChannelBuilderResult result = provider.newChannelBuilder(
95+
"localhost:443", TlsChannelCredentials.create(), registry, null);
96+
assertThat(result.getChannelBuilder()).isInstanceOf(NettyChannelBuilder.class);
97+
}
98+
99+
@Test
100+
public void newChannelBuilder_withProvider() {
101+
io.grpc.NameResolverProvider resolverProvider = new io.grpc.NameResolverProvider() {
102+
@Override
103+
protected boolean isAvailable() {
104+
return true;
105+
}
106+
107+
@Override
108+
protected int priority() {
109+
return 5;
110+
}
111+
112+
@Override
113+
public String getDefaultScheme() {
114+
return "dns";
115+
}
116+
117+
@Override
118+
public io.grpc.NameResolver newNameResolver(java.net.URI targetUri,
119+
io.grpc.NameResolver.Args args) {
120+
return null;
121+
}
122+
};
123+
NewChannelBuilderResult result = provider.newChannelBuilder(
124+
"localhost:443", TlsChannelCredentials.create(), null,
125+
resolverProvider);
126+
assertThat(result.getChannelBuilder()).isInstanceOf(NettyChannelBuilder.class);
127+
}
128+
129+
@Test
130+
public void newChannelBuilder_registryPropagation_e2e() {
131+
String scheme = "testscheme";
132+
final io.grpc.NameResolverRegistry registry = new io.grpc.NameResolverRegistry();
133+
final java.util.concurrent.atomic.AtomicReference<io.grpc.NameResolverRegistry>
134+
capturedRegistry = new java.util.concurrent.atomic.AtomicReference<>();
135+
136+
final io.grpc.NameResolverProvider resolverProvider = new io.grpc.NameResolverProvider() {
137+
@Override
138+
protected boolean isAvailable() {
139+
return true;
140+
}
141+
142+
@Override
143+
protected int priority() {
144+
return 5;
145+
}
146+
147+
@Override
148+
public String getDefaultScheme() {
149+
return scheme;
150+
}
151+
152+
@Override
153+
public io.grpc.NameResolver newNameResolver(java.net.URI targetUri,
154+
io.grpc.NameResolver.Args args) {
155+
capturedRegistry.set(args.getNameResolverRegistry());
156+
return new io.grpc.NameResolver() {
157+
@Override
158+
public String getServiceAuthority() {
159+
return "authority";
160+
}
161+
162+
@Override
163+
public void start(Listener2 listener) {
164+
}
165+
166+
@Override
167+
public void shutdown() {
168+
}
169+
};
170+
}
171+
};
172+
registry.register(resolverProvider);
173+
174+
NewChannelBuilderResult result = provider.newChannelBuilder(
175+
scheme + ":///target", TlsChannelCredentials.create(), registry,
176+
null);
177+
assertThat(result.getChannelBuilder()).isInstanceOf(NettyChannelBuilder.class);
178+
// Verify build() succeeds
179+
result.getChannelBuilder().build();
180+
181+
// Verify the registry passed to args is the exact same instance
182+
assertSame("Registry should be propagated to NameResolver.Args", registry,
183+
capturedRegistry.get());
184+
185+
// Verify default registry (empty) fails
186+
NewChannelBuilderResult defaultResult = provider.newChannelBuilder(
187+
scheme + ":///target", TlsChannelCredentials.create(),
188+
new io.grpc.NameResolverRegistry(), null);
189+
// The provider might still return a builder, but build() should fail if it
190+
// can't find the resolver.
191+
// However, NettyChannelProvider just delegates to NettyChannelBuilder.
192+
// NettyChannelBuilder delegates to ManagedChannelImplBuilder.
193+
// ManagedChannelImplBuilder.build() calls getNameResolverProvider(), which
194+
// throws if not found.
195+
try {
196+
defaultResult.getChannelBuilder().build();
197+
fail("Should have failed to build() without correct registry");
198+
} catch (IllegalArgumentException e) {
199+
// Expected
200+
}
201+
}
202+
203+
@Test
204+
public void newChannelBuilder_providerPropagation_e2e() {
205+
String scheme = "otherscheme";
206+
final io.grpc.NameResolverProvider resolverProvider = new io.grpc.NameResolverProvider() {
207+
@Override
208+
protected boolean isAvailable() {
209+
return true;
210+
}
211+
212+
@Override
213+
protected int priority() {
214+
return 5;
215+
}
216+
217+
@Override
218+
public String getDefaultScheme() {
219+
return scheme;
220+
}
221+
222+
@Override
223+
public io.grpc.NameResolver newNameResolver(java.net.URI targetUri,
224+
io.grpc.NameResolver.Args args) {
225+
return new io.grpc.NameResolver() {
226+
@Override
227+
public String getServiceAuthority() {
228+
return "authority";
229+
}
230+
231+
@Override
232+
public void start(Listener2 listener) {
233+
}
234+
235+
@Override
236+
public void shutdown() {
237+
}
238+
};
239+
}
240+
};
241+
242+
// Pass explicit provider, null registry
243+
NewChannelBuilderResult result = provider.newChannelBuilder(
244+
scheme + ":///target", TlsChannelCredentials.create(),
245+
null, resolverProvider);
246+
assertThat(result.getChannelBuilder()).isInstanceOf(NettyChannelBuilder.class);
247+
// Should succeed because we passed the specific provider
248+
result.getChannelBuilder().build();
249+
}
90250
}

0 commit comments

Comments
 (0)