Author: asavu
Date: Sat Dec 10 23:05:02 2011
New Revision: 1212918

URL: http://svn.apache.org/viewvc?rev=1212918&view=rev
Log:
WHIRR-447. FastDnsResolver fails with SocketTimeoutException (asavu)

Added:
    whirr/trunk/core/src/test/java/org/apache/whirr/net/FakeDnsResolver.java
Removed:
    
whirr/trunk/core/src/test/java/org/apache/whirr/net/integration/FakeDnsResolver.java
Modified:
    whirr/trunk/CHANGES.txt
    whirr/trunk/core/src/main/java/org/apache/whirr/net/FastDnsResolver.java
    
whirr/trunk/core/src/test/java/org/apache/whirr/net/integration/FastDnsResolverTest.java
    whirr/trunk/pom.xml
    
whirr/trunk/services/hadoop/src/test/java/org/apache/whirr/service/hadoop/HadoopConfigurationBuilderTest.java

Modified: whirr/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/whirr/trunk/CHANGES.txt?rev=1212918&r1=1212917&r2=1212918&view=diff
==============================================================================
--- whirr/trunk/CHANGES.txt (original)
+++ whirr/trunk/CHANGES.txt Sat Dec 10 23:05:02 2011
@@ -96,6 +96,8 @@ Trunk (unreleased changes)
 
     WHIRR-446. Upgrade all maven plugins to latest stable release (asavu)
 
+    WHIRR-447. FastDnsResolver fails with SocketTimeoutException (asavu)
+
   BUG FIXES
 
     WHIRR-377. Fix broken CLI logging config. (asavu via tomwhite)

Modified: 
whirr/trunk/core/src/main/java/org/apache/whirr/net/FastDnsResolver.java
URL: 
http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/net/FastDnsResolver.java?rev=1212918&r1=1212917&r2=1212918&view=diff
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/net/FastDnsResolver.java 
(original)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/net/FastDnsResolver.java 
Sat Dec 10 23:05:02 2011
@@ -20,6 +20,7 @@ package org.apache.whirr.net;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.net.SocketTimeoutException;
 
 import org.xbill.DNS.DClass;
 import org.xbill.DNS.ExtendedResolver;
@@ -31,41 +32,71 @@ import org.xbill.DNS.ReverseMap;
 import org.xbill.DNS.Section;
 import org.xbill.DNS.Type;
 
+import static org.xbill.DNS.Message.newQuery;
+
 /**
- * Utility functions for DNS.
+ * Fast DNS resolver
  */
 public class FastDnsResolver implements DnsResolver {
 
+  private int timeoutInSeconds;
+
+  public FastDnsResolver() {
+    this(5);  // default to 5 seconds
+  }
+
+  public FastDnsResolver(int timeoutInSeconds) {
+    this.timeoutInSeconds = timeoutInSeconds;
+  }
+
   /**
    * Resolve the reverse dns name for the given IP address
    * 
    * @param hostIp
-   * @return The resolved DNS name.
-   * @throws IOException
+   *      host IP address
+   * @return
+   *      the resolved DNS name or in some cases the IP address as a string
    */
   @Override
   public String apply(String hostIp) {
     try {
-      Resolver res = new ExtendedResolver();
-      res.setTimeout(5); // seconds
+      Resolver resolver = new ExtendedResolver();
+      resolver.setTimeout(timeoutInSeconds);
+      resolver.setTCP(true);
 
       Name name = ReverseMap.fromAddress(hostIp);
-      Record rec = Record.newRecord(name, Type.PTR, DClass.IN);
-      Message query = Message.newQuery(rec);
-      Message response = res.send(query);
+      Record record = Record.newRecord(name, Type.PTR, DClass.IN);
+      Message response = resolver.send(newQuery(record));
 
       Record[] answers = response.getSectionArray(Section.ANSWER);
       if (answers.length == 0) {
-        // Fall back to standard Java: in contrast to dnsjava, this also reads 
/etc/hosts
-        return new InetSocketAddress(hostIp, 
0).getAddress().getCanonicalHostName();
+        return fallback(hostIp);
+
       } else {
-        String revaddr = answers[0].rdataToString();
-        return revaddr.endsWith(".") ? revaddr.substring(0, revaddr.length() - 
1) : revaddr;
+        String reverseAddress = answers[0].rdataToString();
+        return reverseAddress.endsWith(".") ? reverseAddress.substring(0, 
reverseAddress.length() - 1) : reverseAddress;
       }
+    } catch(SocketTimeoutException e) {
+      return hostIp;  /* same response as standard Java on timeout */
+
     } catch(IOException e) {
-        throw new DnsException(e);
+      throw new DnsException(e);
     }
   }
 
+  /**
+   * Use standard Java for reverse DNS name resolution. This also
+   * reads /etc/hosts but it may take longer
+   *
+   * @param hostIp
+   *      host IP address
+   * @return
+   *      the fully qualified domain name for this IP address, or if the 
operation
+   *      is not allowed by the security check, the textual representation of 
the IP address.
+   */
+  private String fallback(String hostIp) {
+    return new InetSocketAddress(hostIp, 
0).getAddress().getCanonicalHostName();
+  }
+
 }
 

Added: whirr/trunk/core/src/test/java/org/apache/whirr/net/FakeDnsResolver.java
URL: 
http://svn.apache.org/viewvc/whirr/trunk/core/src/test/java/org/apache/whirr/net/FakeDnsResolver.java?rev=1212918&view=auto
==============================================================================
--- whirr/trunk/core/src/test/java/org/apache/whirr/net/FakeDnsResolver.java 
(added)
+++ whirr/trunk/core/src/test/java/org/apache/whirr/net/FakeDnsResolver.java 
Sat Dec 10 23:05:02 2011
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.whirr.net;
+
+import static org.apache.commons.lang.StringUtils.replace;
+
+/**
+ * Fake reverse DNS resolver
+ */
+public class FakeDnsResolver implements DnsResolver {
+
+  @Override
+  public String apply(String hostIp) {
+    return replace(hostIp, ".", "-") + ".example.com";
+  }
+}

Modified: 
whirr/trunk/core/src/test/java/org/apache/whirr/net/integration/FastDnsResolverTest.java
URL: 
http://svn.apache.org/viewvc/whirr/trunk/core/src/test/java/org/apache/whirr/net/integration/FastDnsResolverTest.java?rev=1212918&r1=1212917&r2=1212918&view=diff
==============================================================================
--- 
whirr/trunk/core/src/test/java/org/apache/whirr/net/integration/FastDnsResolverTest.java
 (original)
+++ 
whirr/trunk/core/src/test/java/org/apache/whirr/net/integration/FastDnsResolverTest.java
 Sat Dec 10 23:05:02 2011
@@ -18,7 +18,7 @@
 
 package org.apache.whirr.net.integration;
 
-import static java.lang.System.out;
+import static java.lang.System.currentTimeMillis;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -34,53 +34,73 @@ import java.util.Enumeration;
 import org.apache.whirr.net.DnsResolver;
 import org.apache.whirr.net.FastDnsResolver;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.xbill.DNS.Address;
 
 public class FastDnsResolverTest {
 
-  private static final DnsResolver DNS_RESOLVER = new FastDnsResolver();
+  private static final Logger LOG = 
LoggerFactory.getLogger(FastDnsResolverTest.class);
 
+  protected DnsResolver getDnsResolver() {
+    return new FastDnsResolver();
+  }
+
+  /**
+   * Try the reverse DNS name resolver on all IPv4 interfaces
+   *
+   * @throws IOException
+   */
   @Test
   public void testResolveAddress() throws IOException {
-    // test it with all interfaces
+    long start, end;
     Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
+
     while (en.hasMoreElements()) {
-      NetworkInterface netint = (NetworkInterface) en.nextElement();
+      NetworkInterface netint = en.nextElement();
       Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
+
       for (InetAddress inetAddress : Collections.list(inetAddresses)) {
         if (inetAddress instanceof Inet4Address) {
-          long start = System.currentTimeMillis();
-          String reverse = DNS_RESOLVER.apply(inetAddress.getHostAddress());
-          long end = System.currentTimeMillis();
-          // we know that java.net.InetAddress's getHostName takes > 4.5s if
-          // there is no reverse address assigned to it
-          // FastDnsResolver should resolve any address in less than 5 seconds 
or fail
-          assertTrue("FastDnsResolver.resolveAddress takes " + (end - start)
-              + " millis, it should be shorter than five seconds",
-              end - start < 5000);
-          if (inetAddress.toString().substring(1).equals(reverse)) {
-            out.printf(
-                "InetAddress %s on interface %s does not have reverse dns 
name, so their reverse remains: %s\n",
-                inetAddress, netint.getDisplayName(), reverse);
-          } else {
-            if (inetAddress.isLoopbackAddress()) {
-              out.printf(
-                  "InetAddress %s on loopback interface %s obtained reverse 
name as %s\n",
-                  inetAddress, netint.getDisplayName(), reverse);
-            } else {
-              out.printf(
-                  "InetAddress %s on interface %s has reverse dns name: %s\n",
-                  inetAddress, netint.getDisplayName(), reverse);
-              try {
-                InetAddress checkedAddr = Address.getByName(reverse);
-                assertEquals(inetAddress, checkedAddr);
-              } catch (UnknownHostException uhex) {
-                fail("InetAddress " + inetAddress + " on interface "
-                    + netint.getDisplayName() + " got " + reverse
-                    + " reverse dns name which in return is an unknown host!");
-              }
-            }
-          }
+
+          /* We know that java.net.InetAddress's getHostName takes > 4.5s if
+            there is no reverse address assigned to it. FastDnsResolver should
+            resolve any address in less than 5 seconds or return the IP */
+
+          start = currentTimeMillis();
+          String reverse = 
getDnsResolver().apply(inetAddress.getHostAddress());
+          end = currentTimeMillis();
+
+          assertTrue("resolveAddress takes " + (end - start) + " millis, it 
should be " +
+            "shorter than 5 seconds", (end - start) < 5500);
+
+          checkResponse(reverse, netint, inetAddress);
+        }
+      }
+    }
+  }
+
+  private void checkResponse(String reverse, NetworkInterface 
networkInterface, InetAddress inetAddress) {
+    if (inetAddress.toString().substring(1).equals(reverse)) {
+      LOG.info(String.format("InetAddress %s on interface %s does not have 
reverse dns name, " +
+        "so their reverse remains: %s", inetAddress, 
networkInterface.getDisplayName(), reverse));
+
+    } else {
+      if (inetAddress.isLoopbackAddress()) {
+        LOG.info(String.format("InetAddress %s on loopback interface %s 
obtained reverse name as %s",
+          inetAddress, networkInterface.getDisplayName(), reverse));
+
+      } else {
+        LOG.info(String.format("InetAddress %s on interface %s has reverse dns 
name: %s\n",
+          inetAddress, networkInterface.getDisplayName(), reverse));
+
+        try {
+          InetAddress checkedAddr = Address.getByName(reverse);
+          assertEquals(inetAddress, checkedAddr);
+
+        } catch (UnknownHostException uhex) {
+          fail("InetAddress " + inetAddress + " on interface " + 
networkInterface.getDisplayName() +
+            " got " + reverse + " reverse dns name which in return is an 
unknown host!");
         }
       }
     }

Modified: whirr/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/whirr/trunk/pom.xml?rev=1212918&r1=1212917&r2=1212918&view=diff
==============================================================================
--- whirr/trunk/pom.xml (original)
+++ whirr/trunk/pom.xml Sat Dec 10 23:05:02 2011
@@ -187,7 +187,7 @@
       <dependency>
         <groupId>dnsjava</groupId>
         <artifactId>dnsjava</artifactId>
-        <version>2.0.8</version>
+        <version>2.1.1</version>
       </dependency>
     </dependencies>
   </dependencyManagement>

Modified: 
whirr/trunk/services/hadoop/src/test/java/org/apache/whirr/service/hadoop/HadoopConfigurationBuilderTest.java
URL: 
http://svn.apache.org/viewvc/whirr/trunk/services/hadoop/src/test/java/org/apache/whirr/service/hadoop/HadoopConfigurationBuilderTest.java?rev=1212918&r1=1212917&r2=1212918&view=diff
==============================================================================
--- 
whirr/trunk/services/hadoop/src/test/java/org/apache/whirr/service/hadoop/HadoopConfigurationBuilderTest.java
 (original)
+++ 
whirr/trunk/services/hadoop/src/test/java/org/apache/whirr/service/hadoop/HadoopConfigurationBuilderTest.java
 Sat Dec 10 23:05:02 2011
@@ -37,7 +37,7 @@ import org.apache.whirr.Cluster;
 import org.apache.whirr.Cluster.Instance;
 import org.apache.whirr.ClusterSpec;
 import org.apache.whirr.net.DnsResolver;
-import org.apache.whirr.net.integration.FakeDnsResolver;
+import org.apache.whirr.net.FakeDnsResolver;
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.jclouds.compute.domain.Hardware;


Reply via email to