Name resolver API + implementations

(This is a work in progress)

This pull request adds a new interface called `NameResolver`, which is designed to perform an asynchronous name resolusion such as DNS loopkup.

Currently, there's only one implementation - `JdkDomainNameResolver`, which simply delegates the resolution request to `InetAddress.getByName()`.  Eventually, I'm going to add a fully working asynchronous DNS resolver on top of netty-codec-dns in a separate package.

`Bootstrap` now has a new option that allows you to specify the resolver to use.  Right before a connection attempt is made, `Bootstrap` resolves the remote address using the resolver:

```java
EventLoopGroup group = ...;
EventLoop loop = group.next();
AsyncDomainNameResolver resolver = new AsyncDomainNameResolver(loop);
Bootstrap b = ...;
b.group(loop); // Make sure to use the same event loop for resolver and the actual connection.
b.resolver(resolver);
// Internally, Bootstrap.connect(inetHost, inetPort) uses InetSocketAddress.createUnresolved(...)
// instead of `new InetSocketAddress(...)` to avoid immediate name lookup via JDK.
b.connect("host", port);
```

The caveat with the current API is that a `NameResolver` is tied to an `EventLoop`, because otherwise there's no way to tell the resolver to use the same event loop with the actual connection attempt.  We could probably add `EventExecutor` or `EventLoop` to `NameResolver.resolve()` as a parameter instead, so that `Bootstrap` can simply tell the resolver to use the same event loop.  However, it should be noted that 1) not all resolvers do resolution using Netty API and 2) an OIO event loop is supposed to handle only one single channel.

Besides fully asynchronous DNS resolution, this feature has a lot of potential; imagine you implement:

* fully configurable name cache that works for all resolver types
* resolver that uses other protocols than DNS, such as Zookeeper


Sounds like a good idea.
2014. 9. 20. 오전 3:28에 "Norman Maurer" <notifications@github.com>님이 작성:

> In transport/src/main/java/io/netty/resolver/NameResolver.java:
>
> > +
> > +    /**
> > +     * Returns {@code true} if and only if the specified address has been resolved.
> > +     *
> > +     * @throws UnsupportedAddressTypeException if the specified address is not supported by this resolver
> > +     */
> > +    boolean isResolved(SocketAddress address);
> > +
> > +    /**
> > +     * Resolves the specified name into a {@link SocketAddress}.
> > +     *
> > +     * @param inetHost the name to resolve
> > +     *
> > +     * @return the {@link SocketAddress} as the result of the resolution
> > +     */
> > +    Future<SocketAddress> resolve(String inetHost, int inetPort);
>
> I wonder if we may want to allow the user to also have a method that takes
> a Promise. This may be useful and is inline with what we do for other
> methods. Same goes for the method below.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/netty/netty/pull/2917/files#r17800835>.
>