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;