package com.workshare.msnos.soup.net; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.apache.http.conn.DnsResolver; import org.apache.http.impl.conn.SystemDefaultDnsResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.workshare.msnos.core.protocols.ip.HttpClientFactory; import com.workshare.msnos.soup.threading.ExecutorServices; public class DnsResolverWithTimeout implements DnsResolver { static final ExecutorService DNS_RESOLVE_EXECUTOR = ExecutorServices.newCachedDaemonThreadPool(); private static final Logger log = LoggerFactory.getLogger(HttpClientFactory.class); private final ExecutorService executor; private final DnsResolver systemResolver; private final long timeoutInMillis; public DnsResolverWithTimeout() { this(DNS_RESOLVE_EXECUTOR, new SystemDefaultDnsResolver(), getDnsTimeout()); } public DnsResolverWithTimeout(ExecutorService executor, DnsResolver systemResolver, long timeoutInMillis) { this.executor = executor; this.systemResolver = systemResolver; this.timeoutInMillis = timeoutInMillis; log.debug("DNS resolution with timeout of {} millis", timeoutInMillis); } private static int getDnsTimeout() { return Integer.getInteger("com.ws.msnos.dns.timeout", 5000); } @Override public InetAddress[] resolve(final String host) throws UnknownHostException { Future<InetAddress[]> result = executor.submit(new Callable<InetAddress[]>() { @Override public InetAddress[] call() throws Exception { return systemResolver.resolve(host); } }); try { return result.get(timeoutInMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { log.warn("Unexpected interrupton while resolving host "+host, e); Thread.currentThread().interrupt(); } catch (ExecutionException e) { log.warn("Unexpected execution exception", e.getCause()); } catch (TimeoutException e) { log.warn("Timeout of {} millis elapsed resolving host {}", timeoutInMillis, host); } throw new UnknownHostException(host + ": DNS timeout"); } }