Skip to content
This repository has been archived by the owner on Apr 14, 2024. It is now read-only.

Commit

Permalink
Netty dns (#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
yschimke committed Feb 10, 2017
1 parent 85372e5 commit a727d33
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 28 deletions.
11 changes: 10 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@
<artifactId>byteunits</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-resolver-dns</artifactId>
<version>4.1.8.Final</version>
</dependency>
<dependency>
<groupId>us.physion</groupId>
<artifactId>osx-keychain</artifactId>
Expand Down Expand Up @@ -274,7 +284,6 @@
<descriptors>
<descriptor>src/assembly/bundle.xml</descriptor>
</descriptors>
<finalName>oksocial-${project.version}</finalName>
<archive>
<manifest>
<mainClass>com.baulsupp.oksocial.Main</mainClass>
Expand Down
20 changes: 18 additions & 2 deletions src/main/java/com/baulsupp/oksocial/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import com.baulsupp.oksocial.location.BestLocation;
import com.baulsupp.oksocial.location.LocationSource;
import com.baulsupp.oksocial.network.DnsOverride;
import com.baulsupp.oksocial.network.DnsSelector;
import com.baulsupp.oksocial.network.InterfaceSocketFactory;
import com.baulsupp.oksocial.network.NettyDns;
import com.baulsupp.oksocial.okhttp.OkHttpResponseFuture;
import com.baulsupp.oksocial.output.ConsoleHandler;
import com.baulsupp.oksocial.output.DownloadHandler;
Expand Down Expand Up @@ -51,6 +51,7 @@
import io.airlift.airline.HelpOption;
import io.airlift.airline.Option;
import io.airlift.airline.SingleCommand;
import io.netty.channel.nio.NioEventLoopGroup;
import java.io.File;
import java.io.IOException;
import java.net.Proxy;
Expand All @@ -62,6 +63,7 @@
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.SocketFactory;
Expand Down Expand Up @@ -245,6 +247,8 @@ public static void main(String... args) {

public LocationSource locationSource = new BestLocation();

private NioEventLoopGroup eventLoopGroup;

private String versionString() {
return Util.versionString("/oksocial-version.properties");
}
Expand Down Expand Up @@ -457,6 +461,10 @@ private void closeClients() {
client.dispatcher().executorService().shutdown();
client.connectionPool().evictAll();
}

if (eventLoopGroup != null) {
eventLoopGroup.shutdownGracefully(0, 0, TimeUnit.SECONDS);
}
}

private OutputHandler buildHandler() {
Expand Down Expand Up @@ -578,7 +586,7 @@ public OkHttpClient.Builder createClientBuilder() throws Exception {
builder.readTimeout(readTimeout, SECONDS);
}

Dns dns = DnsSelector.byName(ipmode);
Dns dns = NettyDns.byName(ipmode, getEventLoopGroup());
if (resolve != null) {
dns = DnsOverride.build(dns, resolve);
}
Expand Down Expand Up @@ -619,6 +627,14 @@ public OkHttpClient.Builder createClientBuilder() throws Exception {
return builder;
}

private NioEventLoopGroup getEventLoopGroup() {
if (eventLoopGroup == null) {
eventLoopGroup = new NioEventLoopGroup(1);
}

return eventLoopGroup;
}

private SocketFactory getSocketFactory() throws SocketException {
Optional<SocketFactory> socketFactory = InterfaceSocketFactory.byName(networkInterface);

Expand Down
17 changes: 1 addition & 16 deletions src/main/java/com/baulsupp/oksocial/network/DnsSelector.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package com.baulsupp.oksocial.network;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import okhttp3.Dns;

Expand All @@ -26,8 +23,6 @@ public enum Mode {
IPV4_ONLY
}

private Map<String, List<InetAddress>> overrides = Maps.newHashMap();

private Mode mode;

public DnsSelector(Mode mode) {
Expand Down Expand Up @@ -58,13 +53,7 @@ public static Dns byName(String ipMode) {
}

@Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {
List<InetAddress> addresses = overrides.get(hostname.toLowerCase());

if (addresses != null) {
return addresses;
}

addresses = Dns.SYSTEM.lookup(hostname);
List<InetAddress> addresses = Dns.SYSTEM.lookup(hostname);

switch (mode) {
case IPV6_FIRST:
Expand All @@ -87,8 +76,4 @@ public static Dns byName(String ipMode) {

return addresses;
}

public void addOverride(String hostname, InetAddress address) {
overrides.put(hostname.toLowerCase(), Lists.newArrayList(address));
}
}
89 changes: 89 additions & 0 deletions src/main/java/com/baulsupp/oksocial/network/NettyDns.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.baulsupp.oksocial.network;

import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.resolver.dns.DnsNameResolver;
import io.netty.resolver.dns.DnsNameResolverBuilder;
import io.netty.util.concurrent.Future;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import okhttp3.Dns;

import static io.netty.channel.socket.InternetProtocolFamily.IPv4;
import static io.netty.channel.socket.InternetProtocolFamily.IPv6;
import static java.util.stream.Collectors.joining;

public class NettyDns implements Dns {
private static Logger logger = Logger.getLogger(NettyDns.class.getName());

private final DnsNameResolver r;
private final EventLoopGroup group;

public NettyDns(EventLoopGroup group, Iterable<InternetProtocolFamily> addressTypes) {
this.group = group;
DnsNameResolverBuilder builder = new DnsNameResolverBuilder(this.group.next())
.channelType(NioDatagramChannel.class)
.optResourceEnabled(false)
.maxQueriesPerResolve(3)
.recursionDesired(true);

if (logger.isLoggable(Level.FINEST)) {
builder.traceEnabled(true);
}

if (addressTypes != null) {
builder.resolvedAddressTypes(addressTypes);
}

r = builder.build();
}

@Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {
Future<List<InetAddress>> f = r.resolveAll(hostname);

try {
List<InetAddress> addresses = f.get();

logger.fine("Dns (" + hostname + "): " + addresses.stream()
.map(Object::toString)
.collect(joining(", ")));

return addresses;
} catch (InterruptedException e) {
throw new UnknownHostException(e.toString());
} catch (ExecutionException e) {
throw ((UnknownHostException) new UnknownHostException(e.getCause().getMessage()).initCause(
e.getCause()));
}
}

public static Dns byName(String ipMode, EventLoopGroup eventLoopGroup) {
List<InternetProtocolFamily> types;

switch (ipMode) {
case "ipv6":
types = Arrays.asList(IPv6, IPv4);
break;
case "ipv4":
types = Arrays.asList(IPv4, IPv6);
break;
case "ipv6only":
types = Arrays.asList(IPv6);
break;
case "ipv4only":
types = Arrays.asList(IPv4);
break;
default:
types = null;
break;
}

return new NettyDns(eventLoopGroup, types);
}
}
12 changes: 10 additions & 2 deletions src/main/java/com/baulsupp/oksocial/util/LoggingUtil.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.baulsupp.oksocial.util;

import com.google.common.collect.Lists;
import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.util.internal.logging.JdkLoggerFactory;
import java.util.List;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
Expand All @@ -14,6 +16,8 @@ public class LoggingUtil {
private static List<Logger> activeLoggers = Lists.newArrayList();

public static void configureLogging(boolean debug, boolean showHttp2Frames) {
InternalLoggerFactory.setDefaultFactory(JdkLoggerFactory.INSTANCE);

if (debug || showHttp2Frames) {
LogManager.getLogManager().reset();
ConsoleHandler handler = new ConsoleHandler();
Expand All @@ -25,8 +29,9 @@ public static void configureLogging(boolean debug, boolean showHttp2Frames) {
activeLogger.addHandler(handler);
activeLogger.setLevel(Level.ALL);

Logger x = getLogger("org.zeroturnaround.exec.stream");
x.setLevel(Level.INFO);
getLogger("org.zeroturnaround.exec").setLevel(Level.INFO);
getLogger("io.netty").setLevel(Level.INFO);
getLogger("io.netty.resolver.dns").setLevel(Level.FINE);
} else if (showHttp2Frames) {
Logger activeLogger = getLogger(Http2.class.getName());
activeLogger.setLevel(Level.FINE);
Expand All @@ -37,7 +42,10 @@ public static void configureLogging(boolean debug, boolean showHttp2Frames) {
}
});
activeLogger.addHandler(handler);
getLogger("io.netty.resolver.dns.DnsServerAddresses").setLevel(Level.SEVERE);
}
} else {
getLogger("io.netty.resolver.dns.DnsServerAddresses").setLevel(Level.SEVERE);
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/test/java/com/baulsupp/oksocial/TestMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.baulsupp.oksocial;

public class TestMain {
public static void main(String[] args) throws Exception {
Main.main("--debug", "https://api.twitter.com/robots.txt");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,13 @@ public void loadPresenter() throws IOException {
"url: https://people.googleapis.com/v1/{+resourceName}",
"scopes: https://www.googleapis.com/auth/contacts, https://www.googleapis.com/auth/contacts.readonly, https://www.googleapis.com/auth/plus.login, https://www.googleapis.com/auth/user.addresses.read, https://www.googleapis.com/auth/user.birthday.read, https://www.googleapis.com/auth/user.emails.read, https://www.googleapis.com/auth/user.phonenumbers.read, https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile",
"",
"Provides information about a person resource for a resource name. Use `people/me` to indicate the authenticated user.",
"",
"parameter: resourceName (string)",
"The resource name of the person to provide information about. - To get information about the authenticated user, specify `people/me`. - To get information about any user, specify the resource name that identifies the user, such as the resource names returned by [`people.connections.list`](/people/api/rest/v1/people.connections/list).",
"parameter: requestMask.includeField (string)",
"Comma-separated list of fields to be included in the response. Omitting this field will include all fields. Each path should start with `person.`: for example, `person.names` or `person.photos`."
"Provides information about a person resource for a resource name. Use\n"
+ "`people/me` to indicate the authenticated user."
);

assertEquals(es, outputHandler.stdout);
for (String l: es) {
assertTrue(outputHandler.stdout.contains(l), l);
}
}

@Test public void testExplainsExpandedUrl() throws IOException {
Expand Down

0 comments on commit a727d33

Please sign in to comment.