下面列出了 io.netty.handler.codec.dns.DefaultDnsQuestion #io.netty.resolver.AddressResolver 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
void removedWhenNoCacheHit() throws Exception {
try (TestDnsServer server = new TestDnsServer(ImmutableMap.of(
new DefaultDnsQuestion("foo.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "1.1.1.1", 1))))
) {
final EventLoop eventLoop = eventLoopExtension.get();
final DnsResolverGroupBuilder builder = builder(server);
try (RefreshingAddressResolverGroup group = builder.build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final long start = System.nanoTime();
final Future<InetSocketAddress> foo = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().untilAsserted(() -> assertThat(foo.isSuccess()).isTrue());
assertThat(foo.getNow().getAddress().getHostAddress()).isEqualTo("1.1.1.1");
final ConcurrentMap<String, CompletableFuture<CacheEntry>> cache = group.cache();
await().until(cache::isEmpty);
assertThat(System.nanoTime() - start).isGreaterThanOrEqualTo(
(long) (TimeUnit.SECONDS.toNanos(1) * 0.9));
}
}
}
@Test
void cacheClearWhenClosed() throws Exception {
try (TestDnsServer server = new TestDnsServer(ImmutableMap.of(
new DefaultDnsQuestion("foo.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "1.1.1.1"))))
) {
final EventLoop eventLoop = eventLoopExtension.get();
final RefreshingAddressResolverGroup group = builder(server).build(eventLoop);
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final Future<InetSocketAddress> foo = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().untilAsserted(() -> assertThat(foo.isSuccess()).isTrue());
assertThat(foo.getNow().getAddress().getHostAddress()).isEqualTo("1.1.1.1");
final ConcurrentMap<String, CompletableFuture<CacheEntry>> cache = group.cache();
assertThat(cache.size()).isEqualTo(1);
final CacheEntry cacheEntry = cache.get("foo.com").join();
group.close();
await().until(() -> {
final ScheduledFuture<?> future = cacheEntry.refreshFuture;
return future != null && future.isCancelled();
});
assertThat(cache).isEmpty();
}
}
@Test
void returnDnsQuestionsWhenAllQueryTimeout() throws Exception {
try (TestDnsServer server1 = new TestDnsServer(ImmutableMap.of(), new AlwaysTimeoutHandler());
TestDnsServer server2 = new TestDnsServer(ImmutableMap.of(), new AlwaysTimeoutHandler())) {
final EventLoop eventLoop = eventLoopExtension.get();
final DnsResolverGroupBuilder builder = builder(server1, server2)
.queryTimeoutMillis(1000)
.resolvedAddressTypes(ResolvedAddressTypes.IPV4_PREFERRED);
try (RefreshingAddressResolverGroup group = builder.build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final Future<InetSocketAddress> future = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().until(future::isDone);
assertThat(future.cause()).isInstanceOf(DnsTimeoutException.class);
}
}
}
@Test
void returnPartialDnsQuestions() throws Exception {
// Returns IPv6 correctly and make IPv4 timeout.
try (TestDnsServer server = new TestDnsServer(
ImmutableMap.of(
new DefaultDnsQuestion("foo.com.", AAAA),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "::1", 1))))
) {
final EventLoop eventLoop = eventLoopExtension.get();
final DnsResolverGroupBuilder builder = builder(server)
.queryTimeoutMillis(1000)
.resolvedAddressTypes(ResolvedAddressTypes.IPV4_PREFERRED);
try (RefreshingAddressResolverGroup group = builder.build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final Future<InetSocketAddress> future = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().until(future::isDone);
assertThat(future.getNow().getAddress().getHostAddress()).isEqualTo("0:0:0:0:0:0:0:1");
}
}
}
@Test
void preferredOrderIpv4() throws Exception {
try (TestDnsServer server = new TestDnsServer(
ImmutableMap.of(
new DefaultDnsQuestion("foo.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "1.1.1.1")),
new DefaultDnsQuestion("foo.com.", AAAA),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "::1", 1))),
new DelayHandler(A))
) {
final EventLoop eventLoop = eventLoopExtension.get();
final DnsResolverGroupBuilder builder = builder(server)
.resolvedAddressTypes(ResolvedAddressTypes.IPV4_PREFERRED);
try (RefreshingAddressResolverGroup group = builder.build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final Future<InetSocketAddress> future = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().until(future::isSuccess);
assertThat(future.getNow().getAddress().getHostAddress()).isEqualTo("1.1.1.1");
}
}
}
@Test
void preferredOrderIpv6() throws Exception {
try (TestDnsServer server = new TestDnsServer(
ImmutableMap.of(
new DefaultDnsQuestion("foo.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "1.1.1.1")),
new DefaultDnsQuestion("foo.com.", AAAA),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "::1", 1))),
new DelayHandler(AAAA))
) {
final EventLoop eventLoop = eventLoopExtension.get();
final DnsResolverGroupBuilder builder = builder(server)
.resolvedAddressTypes(ResolvedAddressTypes.IPV6_PREFERRED);
try (RefreshingAddressResolverGroup group = builder.build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final Future<InetSocketAddress> future = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().until(future::isSuccess);
assertThat(future.getNow().getAddress().getHostAddress()).isEqualTo("0:0:0:0:0:0:0:1");
}
}
}
@SuppressWarnings("deprecation")
@Override
protected final AddressResolver<InetSocketAddress> newResolver(EventExecutor executor) throws Exception {
if (!(executor instanceof EventLoop)) {
throw new IllegalStateException(
"unsupported executor type: " + StringUtil.simpleClassName(executor) +
" (expected: " + StringUtil.simpleClassName(EventLoop.class));
}
return newResolver((EventLoop) executor, channelFactory, nameServerProvider);
}
/**
* @deprecated Override {@link #newNameResolver(EventLoop, ChannelFactory, DnsServerAddressStreamProvider)}.
*/
@Deprecated
protected AddressResolver<InetSocketAddress> newResolver(
EventLoop eventLoop, ChannelFactory<? extends DatagramChannel> channelFactory,
DnsServerAddressStreamProvider nameServerProvider) throws Exception {
final NameResolver<InetAddress> resolver = new InflightNameResolver<InetAddress>(
eventLoop,
newNameResolver(eventLoop, channelFactory, nameServerProvider),
resolvesInProgress,
resolveAllsInProgress);
return newAddressResolver(eventLoop, resolver);
}
@Override
protected AddressResolver<InetSocketAddress> newResolver(EventExecutor executor) throws Exception {
assert executor instanceof EventLoop;
final EventLoop eventLoop = (EventLoop) executor;
final DnsNameResolverBuilder builder = new DnsNameResolverBuilder(eventLoop);
resolverConfigurator.accept(builder);
final DefaultDnsNameResolver resolver = new DefaultDnsNameResolver(builder.build(), eventLoop,
queryTimeoutMillis);
return new RefreshingAddressResolver(eventLoop, cache, resolver, dnsRecordTypes, minTtl, maxTtl,
negativeTtl, refreshBackoff);
}
@Test
void refreshing() throws Exception {
try (TestDnsServer server = new TestDnsServer(ImmutableMap.of(
new DefaultDnsQuestion("baz.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("baz.com.", "1.1.1.1", 1))))
) {
final EventLoop eventLoop = eventLoopExtension.get();
try (RefreshingAddressResolverGroup group = builder(server).build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final long start = System.nanoTime();
final Future<InetSocketAddress> foo = resolver.resolve(
InetSocketAddress.createUnresolved("baz.com", 36462));
await().untilAsserted(() -> assertThat(foo.isSuccess()).isTrue());
assertThat(foo.getNow().getAddress().getHostAddress()).isEqualTo("1.1.1.1");
final ConcurrentMap<String, CompletableFuture<CacheEntry>> cache = group.cache();
assertThat(cache.size()).isOne();
assertThat(cache.get("baz.com").join().address()).isEqualTo(
InetAddress.getByAddress("baz.com", new byte[] { 1, 1, 1, 1 }));
// Resolve one more to increase cache hits.
resolver.resolve(InetSocketAddress.createUnresolved("baz.com", 36462));
server.setResponses(ImmutableMap.of(
new DefaultDnsQuestion("baz.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("baz.com.", "2.2.2.2"))));
await().until(() -> {
final CompletableFuture<CacheEntry> future = cache.get("baz.com");
return future != null && future.join().address().equals(
InetAddress.getByAddress("baz.com", new byte[] { 2, 2, 2, 2 }));
});
assertThat(System.nanoTime() - start).isGreaterThanOrEqualTo(
(long) (TimeUnit.SECONDS.toNanos(1) * 0.9)); // ttl 2 seconds * buffer (90%)
}
}
}
@Test
void negativeTtl() {
// TimeoutHandler times out only the first query.
try (TestDnsServer server = new TestDnsServer(ImmutableMap.of(), new TimeoutHandler())) {
final EventLoop eventLoop = eventLoopExtension.get();
final DnsResolverGroupBuilder builder = builder(server).negativeTtl(60).queryTimeoutMillis(1000);
try (RefreshingAddressResolverGroup group = builder.build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final Future<InetSocketAddress> future = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().until(future::isDone);
final Throwable cause = future.cause();
assertThat(cause).isInstanceOfAny(UnknownHostException.class,
DnsTimeoutException.class);
if (cause instanceof UnknownHostException) {
assertThat(cause).hasCauseInstanceOf(DnsNameResolverTimeoutException.class);
}
// Because it's timed out, the result is not cached.
final ConcurrentMap<String, CompletableFuture<CacheEntry>> cache = group.cache();
assertThat(cache.size()).isZero();
final Future<InetSocketAddress> future2 = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().until(future2::isDone);
assertThat(future2.cause()).isInstanceOf(UnknownHostException.class)
.hasNoCause();
// Because it is NXDOMAIN, the result is cached.
assertThat(cache.size()).isOne();
}
}
}
/**
* Creates a new {@link AddressResolver}. Override this method to create an alternative {@link AddressResolver}
* implementation or override the default configuration.
*/
protected AddressResolver<InetSocketAddress> newAddressResolver(EventLoop eventLoop,
NameResolver<InetAddress> resolver)
throws Exception {
return new InetSocketAddressResolver(eventLoop, resolver);
}
@Override
protected AddressResolver<SocketAddress> newResolver(EventExecutor executor) {
return NOOP_ADDRESS_RESOLVER;
}
@Override
public AddressResolver<SocketAddress> getResolver(final EventExecutor executor) {
return NOOP_ADDRESS_RESOLVER;
}
@Test
void resolve() throws Exception {
try (TestDnsServer server = new TestDnsServer(ImmutableMap.of(
new DefaultDnsQuestion("foo.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "1.1.1.1")),
new DefaultDnsQuestion("bar.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("bar.com.", "1.2.3.4"))))
) {
final EventLoop eventLoop = eventLoopExtension.get();
try (RefreshingAddressResolverGroup group = builder(server).build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final Future<InetSocketAddress> foo = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().untilAsserted(() -> assertThat(foo.isSuccess()).isTrue());
InetSocketAddress addr = foo.getNow();
assertThat(addr.getAddress().getHostAddress()).isEqualTo("1.1.1.1");
assertThat(addr.getPort()).isEqualTo(36462);
final ConcurrentMap<String, CompletableFuture<CacheEntry>> cache = group.cache();
assertThat(cache.size()).isOne();
final Future<InetSocketAddress> bar = resolver.resolve(
InetSocketAddress.createUnresolved("bar.com", 36462));
await().untilAsserted(() -> assertThat(bar.isSuccess()).isTrue());
addr = bar.getNow();
assertThat(addr.getAddress().getHostAddress()).isEqualTo("1.2.3.4");
assertThat(addr.getPort()).isEqualTo(36462);
assertThat(cache.size()).isEqualTo(2);
final Future<InetSocketAddress> foo1 = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 80));
addr = foo1.getNow();
assertThat(addr.getAddress().getHostAddress()).isEqualTo("1.1.1.1");
assertThat(addr.getPort()).isEqualTo(80);
assertThat(cache.size()).isEqualTo(2);
final List<InetAddress> addresses =
cache.values()
.stream()
.map(future -> future.join().address())
.collect(toImmutableList());
assertThat(addresses).containsExactlyInAnyOrder(
InetAddress.getByAddress("foo.com", new byte[] { 1, 1, 1, 1 }),
InetAddress.getByAddress("bar.com", new byte[] { 1, 2, 3, 4 }));
}
}
}
@Test
void removedWhenExceedingBackoffMaxAttempts() throws Exception {
try (TestDnsServer server = new TestDnsServer(ImmutableMap.of(
new DefaultDnsQuestion("foo.com.", A),
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("foo.com.", "1.1.1.1", 1))))
) {
final EventLoop eventLoop = eventLoopExtension.get();
final DnsResolverGroupBuilder builder = builder(server);
builder.refreshBackoff(Backoff.ofDefault().withMaxAttempts(1));
try (RefreshingAddressResolverGroup group = builder.build(eventLoop)) {
final AddressResolver<InetSocketAddress> resolver = group.getResolver(eventLoop);
final long start = System.nanoTime();
final Future<InetSocketAddress> foo = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().untilAsserted(() -> assertThat(foo.isSuccess()).isTrue());
assertThat(foo.getNow().getAddress().getHostAddress()).isEqualTo("1.1.1.1");
server.setResponses(ImmutableMap.of());
// Schedule resolve() every 500 millis to keep cache hits greater than 0.
for (int i = 1; i <= 4; i++) {
eventLoop.schedule(
() -> resolver.resolve(InetSocketAddress.createUnresolved("foo.com", 36462)),
500 * i, TimeUnit.MILLISECONDS);
}
final ConcurrentMap<String, CompletableFuture<CacheEntry>> cache = group.cache();
await().until(cache::isEmpty);
assertThat(System.nanoTime() - start).isGreaterThanOrEqualTo(
(long) (TimeUnit.SECONDS.toNanos(1) * 0.9)); // buffer (90%)
final Future<InetSocketAddress> future = resolver.resolve(
InetSocketAddress.createUnresolved("foo.com", 36462));
await().until(future::isDone);
assertThat(future.cause()).isInstanceOf(UnknownHostException.class);
}
}
}
/**
* We need to override this method, not
* {@link #newNameResolver(EventLoop, ChannelFactory, DnsServerAddressStreamProvider)},
* because we need to eliminate possible caching of {@link io.netty.resolver.NameResolver#resolve}
* by {@link InflightNameResolver} created in
* {@link #newResolver(EventLoop, ChannelFactory, DnsServerAddressStreamProvider)}.
*/
@Override
protected final AddressResolver<InetSocketAddress> newAddressResolver(EventLoop eventLoop,
NameResolver<InetAddress> resolver)
throws Exception {
return new RoundRobinInetAddressResolver(eventLoop, resolver).asAddressResolver();
}