下面列出了怎么用io.grpc.NameResolver的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void validTargetNoResovler() {
Factory nameResolverFactory = new NameResolver.Factory() {
@Override
public NameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
return null;
}
@Override
public String getDefaultScheme() {
return "defaultscheme";
}
};
try {
ManagedChannelImpl.getNameResolver(
"foo.googleapis.com:8080", nameResolverFactory, NAMERESOLVER_ARGS);
fail("Should fail");
} catch (IllegalArgumentException e) {
// expected
}
}
@Test
public void forwardsNonOverridenCalls() {
NameResolver.Factory wrappedFactory = mock(NameResolver.Factory.class);
NameResolver mockResolver = mock(NameResolver.class);
when(wrappedFactory.newNameResolver(any(URI.class), any(NameResolver.Args.class)))
.thenReturn(mockResolver);
NameResolver.Factory factory =
new OverrideAuthorityNameResolverFactory(wrappedFactory, "override:5678");
NameResolver overrideResolver =
factory.newNameResolver(URI.create("dns:///localhost:443"), ARGS);
assertNotNull(overrideResolver);
NameResolver.Listener2 listener = mock(NameResolver.Listener2.class);
overrideResolver.start(listener);
verify(mockResolver).start(listener);
overrideResolver.shutdown();
verify(mockResolver).shutdown();
overrideResolver.refresh();
verify(mockResolver).refresh();
}
@Override
public NameResolver newNameResolver(URI notUsedUri, Attributes params) {
return new NameResolver() {
@Override
public String getServiceAuthority() {
return authority;
}
@Override
public void start(final Listener listener) {
listener.onAddresses(
Collections.singletonList(new EquivalentAddressGroup(address)),
Attributes.EMPTY);
}
@Override
public void shutdown() {}
};
}
@Override
public NameResolver newNameResolver(URI notUsedUri, NameResolver.Args args) {
return new NameResolver() {
@Override
public String getServiceAuthority() {
return authority;
}
@Override
public void start(Listener2 listener) {
listener.onResult(
ResolutionResult.newBuilder()
.setAddresses(Collections.singletonList(new EquivalentAddressGroup(address)))
.setAttributes(Attributes.EMPTY)
.build());
}
@Override
public void shutdown() {}
};
}
@Test
public void validTargetNoResovler() {
Factory nameResolverFactory = new NameResolver.Factory() {
@Override
public NameResolver newNameResolver(URI targetUri, Attributes params) {
return null;
}
@Override
public String getDefaultScheme() {
return "defaultscheme";
}
};
try {
ManagedChannelImpl.getNameResolver(
"foo.googleapis.com:8080", nameResolverFactory, NAME_RESOLVER_PARAMS);
fail("Should fail");
} catch (IllegalArgumentException e) {
// expected
}
}
private DnsNameResolver newResolver(
String name,
int port,
ProxyDetector proxyDetector,
Stopwatch stopwatch,
boolean isAndroid) {
DnsNameResolver dnsResolver = new DnsNameResolver(
null,
name,
Attributes.newBuilder().set(NameResolver.Factory.PARAMS_DEFAULT_PORT, port).build(),
fakeExecutorResource,
proxyDetector,
stopwatch,
isAndroid);
// By default, using the mocked ResourceResolver to avoid I/O
dnsResolver.setResourceResolver(new JndiResourceResolver(recordFetcher));
return dnsResolver;
}
/**
* Creates a new {@link NameResolver} for the given authority and attributes.
*
* @param targetAuthority The authority to connect to.
* @param defaultPort The default port to use, if none is specified.
* @return The newly created name resolver for the given target.
*/
private NameResolver of(final String targetAuthority, int defaultPort) {
requireNonNull(targetAuthority, "targetAuthority");
// Determine target ips
final String[] hosts = PATTERN_COMMA.split(targetAuthority);
final List<EquivalentAddressGroup> targets = new ArrayList<>(hosts.length);
for (final String host : hosts) {
final URI uri = URI.create("//" + host);
int port = uri.getPort();
if (port == -1) {
port = defaultPort;
}
targets.add(new EquivalentAddressGroup(new InetSocketAddress(uri.getHost(), port)));
}
if (targets.isEmpty()) {
throw new IllegalArgumentException("Must have at least one target, but was: " + targetAuthority);
}
return new StaticNameResolver(targetAuthority, targets);
}
/**
* Creates a new {@link NameResolver} for the given authority and attributes.
*
* @param targetAuthority The authority to connect to.
* @param defaultPort The default port to use, if none is specified.
* @return The newly created name resolver for the given target.
*/
private NameResolver of(final String targetAuthority, int defaultPort) {
requireNonNull(targetAuthority, "targetAuthority");
// Determine target ips
final String[] hosts = PATTERN_COMMA.split(targetAuthority);
final List<EquivalentAddressGroup> targets = new ArrayList<>(hosts.length);
for (final String host : hosts) {
final URI uri = URI.create("//" + host);
int port = uri.getPort();
if (port == -1) {
port = defaultPort;
}
targets.add(new EquivalentAddressGroup(new InetSocketAddress(uri.getHost(), port)));
}
if (targets.isEmpty()) {
throw new IllegalArgumentException("Must have at least one target, but was: " + targetAuthority);
}
return new StaticNameResolver(targetAuthority, targets);
}
@Nullable
@Override
public NameResolver newNameResolver(final URI targetUri, final NameResolver.Args args) {
if (DISCOVERY_SCHEME.equals(targetUri.getScheme())) {
final String serviceName = targetUri.getPath();
if (serviceName == null || serviceName.length() <= 1 || !serviceName.startsWith("/")) {
throw new IllegalArgumentException("Incorrectly formatted target uri; "
+ "expected: '" + DISCOVERY_SCHEME + ":[//]/<service-name>'; "
+ "but was '" + targetUri.toString() + "'");
}
final AtomicReference<DiscoveryClientNameResolver> reference = new AtomicReference<>();
final DiscoveryClientNameResolver discoveryClientNameResolver =
new DiscoveryClientNameResolver(serviceName.substring(1), this.client, args,
GrpcUtil.SHARED_CHANNEL_EXECUTOR,
() -> this.discoveryClientNameResolvers.remove(reference.get()));
reference.set(discoveryClientNameResolver);
this.discoveryClientNameResolvers.add(discoveryClientNameResolver);
return discoveryClientNameResolver;
}
return null;
}
@Nullable
@Override
public NameResolver newNameResolver(URI targetUri, Attributes params) {
final String scheme = targetUri.getScheme();
if (!SCHEME_DISCOVER.equals(scheme) && !SCHEME_DISCOVER_TLS.equals(scheme) &&
!SCHEME_DIRECT.equals(scheme) && !SCHEME_DIRECT_SSL.equals(scheme) && !SCHEME_DIRECT_TLS.equals(scheme)) {
return null;
}
final String authority = targetUri.getAuthority();
final List<InetSocketAddress> addresses = Splitter.on(',').splitToList(authority).stream().map(host -> {
final String[] strings = host.split(":");
Preconditions.checkArgument(strings.length == 2, "URI should have both address and port");
return InetSocketAddress.createUnresolved(strings[0], Integer.parseInt(strings[1]));
}).collect(Collectors.toList());
return new ControllerNameResolver(authority, addresses, SCHEME_DISCOVER.equals(scheme) || SCHEME_DISCOVER_TLS.equals(scheme), executor);
}
@Nullable
@Override
public NameResolver newNameResolver(URI targetUri, Attributes params) {
if (SCHEME.equals(targetUri.getScheme())) {
String targetPath = Preconditions.checkNotNull(targetUri.getPath(), "targetPath");
Preconditions.checkArgument(targetPath.startsWith("/"),
"the path component (%s) of the target (%s) must start with '/'", targetPath, targetUri);
String[] parts = targetPath.split("/");
if (parts.length != 4) {
throw new IllegalArgumentException("Must be formatted like kubernetes:///{namespace}/{service}/{port}");
}
try {
int port = Integer.valueOf(parts[3]);
return new KubernetesNameResolver(parts[1], parts[2], port, params, GrpcUtil.TIMER_SERVICE,
GrpcUtil.SHARED_CHANNEL_EXECUTOR);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Unable to parse port number", e);
}
} else {
return null;
}
}
@Before
public void setUp() {
GrpclbNameResolver.setEnableTxt(true);
NameResolver.Args args =
NameResolver.Args.newBuilder()
.setDefaultPort(DEFAULT_PORT)
.setProxyDetector(GrpcUtil.NOOP_PROXY_DETECTOR)
.setSynchronizationContext(syncContext)
.setServiceConfigParser(serviceConfigParser)
.setChannelLogger(mock(ChannelLogger.class))
.build();
resolver =
new GrpclbNameResolver(
null, NAME, args, fakeExecutorResource, fakeClock.getStopwatchSupplier().get(),
/* isAndroid */false);
hostName = resolver.getHost();
assertThat(hostName).isEqualTo(NAME);
}
@Override
public NameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
if (expectedScheme.equals(targetUri.getScheme())) {
return new FakeNameResolver(targetUri);
}
return null;
}
@Deprecated
@Override
public final T nameResolverFactory(NameResolver.Factory resolverFactory) {
Preconditions.checkState(directServerAddress == null,
"directServerAddress is set (%s), which forbids the use of NameResolverFactory",
directServerAddress);
if (resolverFactory != null) {
this.nameResolverFactory = resolverFactory;
} else {
this.nameResolverFactory = nameResolverRegistry.asFactory();
}
return thisT();
}
/**
* 获取一致性Hash负载均衡算法的参数值
*
* @author sxp
* @since 2019/8/27
*/
static Object getArgument(NameResolver nameResolver) {
String serviceName = null;
if (nameResolver != null) {
serviceName = nameResolver.getServiceName();
}
Object argument = ConsistentHashArguments.getArgument(serviceName);
return argument;
}
/**
* 获取客户端服务列表中服务提供者的数量
*
* @author sxp
* @since 2018-7-7
*/
private static int getConsumerProvidersAmount(NameResolver nameResolver) {
Map<String, ServiceProvider> providersForLoadBalance = nameResolver.getProvidersForLoadBalance();
if (providersForLoadBalance == null) {
return 0;
}
return providersForLoadBalance.size();
}
/**
* 注册中心上该消费者的服务提供者列表是否为空
*
* @author sxp
* @since 2018-7-7
*/
private static boolean isZkProviderListEmpty(NameResolver nameResolver) {
ProvidersListener listener = nameResolver.getProvidersListener();
if (listener == null) {
return true;// 为空
}
return listener.isProviderListEmpty();
}
/**
* 重置服务失败次数为0
*
* @author wlh
* @since 2019/12/11
*/
public static void resetFailTimes(NameResolver nameResolver, String consumerId, String providerId, Object argument, String method) {
String key = consumerId + CONSUMERID_PROVIDERID_SEPARATOR + providerId;
if (requestFailures.containsKey(key)) {
requestFailures.get(key).set(0);
}
}
public NameResolver build() {
if (hasServiveServerList) {
// 手工指定服务端地址列表后,忽略注册中心
return this;
}
URL zkUrl;
String key = RegisterCenterConf.getConsumerRcProKey();
boolean hasTwoRc = GlobalConstants.PUBLIC_PRIVATE_REGISTRY_CENTER.equals(key);
if (hasTwoRc) {
zkUrl = findProviderZk();
if (zkUrl == null) {
logger.warn(cannotFindZkMsg);
findZkFuture = findZkExecutor.schedule(findZkTask, FIND_DELAY, TimeUnit.SECONDS);
// 暂时将客户端注册到公共注册中心
zkUrl = UrlUtils.getRegisterURL(key);
}
} else {
zkUrl = UrlUtils.getRegisterURL(key);
}
if (registry != null && zkUrl != null) {
zkRegistryURL = zkUrl;
registry = registry.forTarget(zkUrl).build();
}
return this;
}
@Test
@SuppressWarnings("deprecation") // this will be removed in 1.21.0
public void start_listener() {
NameResolver.Listener listener = new NameResolver.Listener() {
@Override
public void onAddresses(List<EquivalentAddressGroup> servers, Attributes attributes) { }
@Override
public void onError(Status error) { }
};
forwarder.start(listener);
verify(delegate).start(listener);
}
/**
* Returns a {@link NameResolver.Factory} for the channel.
*/
NameResolver.Factory getNameResolverFactory() {
if (authorityOverride == null) {
return nameResolverFactory;
} else {
return new OverrideAuthorityNameResolverFactory(nameResolverFactory, authorityOverride);
}
}
@Override
public NameResolver newNameResolver(final URI targetUri, NameResolver.Args args) {
if (!expectedUri.equals(targetUri)) {
return null;
}
assertEquals(DEFAULT_PORT, args.getDefaultPort());
FakeNameResolver resolver = new FakeNameResolver(args.getServiceConfigParser());
resolvers.add(resolver);
return resolver;
}
@Test
@SuppressWarnings("deprecation")
public void nameResolverFactory_null() {
NameResolver.Factory defaultValue = builder.getNameResolverFactory();
builder.nameResolverFactory(mock(NameResolver.Factory.class));
assertEquals(builder, builder.nameResolverFactory(null));
assertEquals(defaultValue, builder.getNameResolverFactory());
}
DnsNameResolver(@Nullable String nsAuthority, String name, Attributes params,
Resource<Executor> executorResource, ProxyDetector proxyDetector,
Stopwatch stopwatch, boolean isAndroid) {
// TODO: if a DNS server is provided as nsAuthority, use it.
// https://www.captechconsulting.com/blogs/accessing-the-dusty-corners-of-dns-with-java
this.executorResource = executorResource;
// Must prepend a "//" to the name when constructing a URI, otherwise it will be treated as an
// opaque URI, thus the authority and host of the resulted URI would be null.
URI nameUri = URI.create("//" + checkNotNull(name, "name"));
Preconditions.checkArgument(nameUri.getHost() != null, "Invalid DNS name: %s", name);
authority = Preconditions.checkNotNull(nameUri.getAuthority(),
"nameUri (%s) doesn't have an authority", nameUri);
host = nameUri.getHost();
if (nameUri.getPort() == -1) {
Integer defaultPort = params.get(NameResolver.Factory.PARAMS_DEFAULT_PORT);
if (defaultPort != null) {
port = defaultPort;
} else {
throw new IllegalArgumentException(
"name '" + name + "' doesn't contain a port, and default port is not set in params");
}
} else {
port = nameUri.getPort();
}
this.proxyDetector = proxyDetector;
this.resolveRunnable = new Resolve(this, stopwatch, getNetworkAddressCacheTtlNanos(isAndroid));
}
@Test
public void lbHelper_getNameResolverArgs() {
createChannel();
NameResolver.Args args = helper.getNameResolverArgs();
assertThat(args.getDefaultPort()).isEqualTo(DEFAULT_PORT);
assertThat(args.getProxyDetector()).isSameInstanceAs(GrpcUtil.DEFAULT_PROXY_DETECTOR);
assertThat(args.getSynchronizationContext())
.isSameInstanceAs(helper.getSynchronizationContext());
assertThat(args.getServiceConfigParser()).isNotNull();
}
@Test
public void overridesAuthority() {
NameResolver nameResolverMock = mock(NameResolver.class);
NameResolver.Factory wrappedFactory = mock(NameResolver.Factory.class);
when(wrappedFactory.newNameResolver(any(URI.class), any(Attributes.class)))
.thenReturn(nameResolverMock);
String override = "override:5678";
NameResolver.Factory factory =
new OverrideAuthorityNameResolverFactory(wrappedFactory, override);
NameResolver nameResolver = factory.newNameResolver(URI.create("dns:///localhost:443"),
Attributes.EMPTY);
assertNotNull(nameResolver);
assertEquals(override, nameResolver.getServiceAuthority());
}
@Test
public void wontWrapNull() {
NameResolver.Factory wrappedFactory = mock(NameResolver.Factory.class);
when(wrappedFactory.newNameResolver(any(URI.class), any(Attributes.class))).thenReturn(null);
NameResolver.Factory factory =
new OverrideAuthorityNameResolverFactory(wrappedFactory, "override:5678");
assertEquals(null,
factory.newNameResolver(URI.create("dns:///localhost:443"), Attributes.EMPTY));
}
private DnsNameResolver newResolver(
String name,
Stopwatch stopwatch,
boolean isAndroid,
NameResolver.Args args) {
DnsNameResolver dnsResolver =
new DnsNameResolver(
null, name, args, fakeExecutorResource, stopwatch, isAndroid);
// By default, using the mocked ResourceResolver to avoid I/O
dnsResolver.setResourceResolver(new JndiResourceResolver(recordFetcher));
return dnsResolver;
}
@Override
public NameResolver newNameResolver(URI targetUri, Attributes params) {
if (expectedScheme.equals(targetUri.getScheme())) {
return new FakeNameResolver(targetUri);
}
return null;
}
@Test
@SuppressWarnings("deprecation")
public void nameResolverFactory_normal() {
NameResolver.Factory nameResolverFactory = mock(NameResolver.Factory.class);
assertEquals(builder, builder.nameResolverFactory(nameResolverFactory));
assertEquals(nameResolverFactory, builder.getNameResolverFactory());
}