Github user eribeiro commented on a diff in the pull request:
https://github.com/apache/zookeeper/pull/451#discussion_r186694289
--- Diff: src/java/main/org/apache/zookeeper/client/StaticHostProvider.java
---
@@ -30,76 +31,118 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
* Most simple HostProvider, resolves only on instantiation.
- *
+ *
*/
@InterfaceAudience.Public
public final class StaticHostProvider implements HostProvider {
+ public interface Resolver {
+ InetAddress[] getAllByName(String name) throws
UnknownHostException;
+ }
+
private static final Logger LOG = LoggerFactory
.getLogger(StaticHostProvider.class);
- private final List<InetSocketAddress> serverAddresses = new
ArrayList<InetSocketAddress>(
- 5);
+ private final List<InetSocketAddress> serverAddresses = new
ArrayList<InetSocketAddress>(5);
private int lastIndex = -1;
private int currentIndex = -1;
+ private Resolver resolver;
+
/**
* Constructs a SimpleHostSet.
- *
+ *
* @param serverAddresses
* possibly unresolved ZooKeeper server addresses
* @throws IllegalArgumentException
* if serverAddresses is empty or resolves to an empty list
*/
public StaticHostProvider(Collection<InetSocketAddress>
serverAddresses) {
- for (InetSocketAddress address : serverAddresses) {
- try {
- InetAddress ia = address.getAddress();
- InetAddress resolvedAddresses[] =
InetAddress.getAllByName((ia != null) ? ia.getHostAddress() :
- address.getHostName());
- for (InetAddress resolvedAddress : resolvedAddresses) {
- // If hostName is null but the address is not, we can
tell that
- // the hostName is an literal IP address. Then we can
set the host string as the hostname
- // safely to avoid reverse DNS lookup.
- // As far as i know, the only way to check if the
hostName is null is use toString().
- // Both the two implementations of InetAddress are
final class, so we can trust the return value of
- // the toString() method.
- if (resolvedAddress.toString().startsWith("/")
- && resolvedAddress.getAddress() != null) {
- this.serverAddresses.add(
- new
InetSocketAddress(InetAddress.getByAddress(
- address.getHostName(),
- resolvedAddress.getAddress()),
- address.getPort()));
- } else {
- this.serverAddresses.add(new
InetSocketAddress(resolvedAddress.getHostAddress(), address.getPort()));
- }
- }
- } catch (UnknownHostException e) {
- LOG.error("Unable to connect to server: {}", address, e);
+ this.resolver = new Resolver() {
+ @Override
+ public InetAddress[] getAllByName(String name) throws
UnknownHostException {
+ return InetAddress.getAllByName(name);
}
- }
-
- if (this.serverAddresses.isEmpty()) {
+ };
+ init(serverAddresses);
+ }
+
+ /**
+ * Introduced for testing purposes. getAllByName() is a static method
of InetAddress, therefore cannot be easily mocked.
+ * By abstraction of Resolver interface we can easily inject a mocked
implementation in tests.
+ *
+ * @param serverAddresses
+ * possibly unresolved ZooKeeper server addresses
+ * @param resolver
+ * custom resolver implementation
+ * @throws IllegalArgumentException
+ * if serverAddresses is empty or resolves to an empty list
+ */
+ public StaticHostProvider(Collection<InetSocketAddress>
serverAddresses, Resolver resolver) {
+ this.resolver = resolver;
+ init(serverAddresses);
+ }
+
+ /**
+ * Common init method for all constructors.
+ * Resolve all unresolved server addresses, put them in a list and
shuffle.
+ */
+ private void init(Collection<InetSocketAddress> serverAddresses) {
+ if (serverAddresses.isEmpty()) {
throw new IllegalArgumentException(
"A HostProvider may not be empty!");
}
+
+ this.serverAddresses.addAll(serverAddresses);
Collections.shuffle(this.serverAddresses);
}
+ /**
+ * Evaluate to a hostname if one is available and otherwise it returns
the
+ * string representation of the IP address.
+ *
+ * In Java 7, we have a method getHostString, but earlier versions do
not support it.
+ * This method is to provide a replacement for
InetSocketAddress.getHostString().
+ *
+ * @param addr
+ * @return Hostname string of address parameter
+ */
+ private String getHostString(InetSocketAddress addr) {
--- End diff --
As ZK JVM version is jdk7, there is still a need for this method?
---