Skip to content

Commit

Permalink
dns resolver configurable from outside via WebserviceConfiguration (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
todvora authored Mar 9, 2017
1 parent c3efc97 commit 3af94ec
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 31 deletions.
20 changes: 20 additions & 0 deletions src/main/java/cz/tomasdvorak/eet/client/dto/DnsResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cz.tomasdvorak.eet.client.dto;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
* Implement this interface if you want to use dns lookup different than default implementation based on {@link InetAddress}.
* You can for example use http://www.xbill.org/dnsjava/ implementation or any other custom logic.
*/
public interface DnsResolver {

/**
* Convert a domain name to IP address.
*
* @param hostname Pure hostname, without protocol or path. For example pg.eet.cz
* @return IP address as a String
* @throws UnknownHostException in case DNS lookup fails.
*/
String getHostAddress(String hostname) throws UnknownHostException;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cz.tomasdvorak.eet.client.dto;

import cz.tomasdvorak.eet.client.networking.InetAddressDnsResolver;

/**
* TODO: create builder for the configuration!
*/
Expand All @@ -15,6 +17,7 @@ public class WebserviceConfiguration {
);
private long receiveTimeout;
private long dnsLookupTimeout;
private DnsResolver dnsResolver;

/**
* @param receiveTimeout receiving timeout of the Webservice call in millis
Expand All @@ -30,6 +33,7 @@ public WebserviceConfiguration(final long receiveTimeout) {
public WebserviceConfiguration(final long receiveTimeout, final long dnsLookupTimeout) {
this.receiveTimeout = receiveTimeout;
this.dnsLookupTimeout = dnsLookupTimeout;
this.dnsResolver = new InetAddressDnsResolver();
}

public long getReceiveTimeout() {
Expand All @@ -39,4 +43,12 @@ public long getReceiveTimeout() {
public long getDnsLookupTimeout() {
return dnsLookupTimeout;
}

public DnsResolver getDnsResolver() {
return dnsResolver;
}

public void setDnsResolver(final DnsResolver dnsResolver) {
this.dnsResolver = dnsResolver;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
import cz.tomasdvorak.eet.client.exceptions.DnsLookupFailedException;
import cz.tomasdvorak.eet.client.exceptions.DnsTimeoutException;

public interface DnsResolver {
public interface DnsLookup {
String resolveAddress(String url) throws DnsLookupFailedException, DnsTimeoutException;
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
package cz.tomasdvorak.eet.client.networking;

import cz.tomasdvorak.eet.client.dto.DnsResolver;
import cz.tomasdvorak.eet.client.exceptions.DnsLookupFailedException;
import cz.tomasdvorak.eet.client.exceptions.DnsTimeoutException;
import cz.tomasdvorak.eet.client.security.SecureEETCommunication;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.concurrent.*;

public class DnsResolverWithTimeout implements DnsResolver {
public class DnsLookupWithTimeout implements DnsLookup {

private static final Logger logger = LogManager.getLogger(SecureEETCommunication.class);
private static final Logger logger = LogManager.getLogger(DnsLookupWithTimeout.class);

private final long timeoutMillis;
private final DnsResolver dnsResolver;

public DnsResolverWithTimeout(long timeoutMillis) {
public DnsLookupWithTimeout(final DnsResolver dnsResolver, final long timeoutMillis) {
this.dnsResolver = dnsResolver;
this.timeoutMillis = timeoutMillis;
}

@Override
public String resolveAddress(final String url) throws DnsLookupFailedException, DnsTimeoutException {
final String host;
final String hostname;
try {
host = new URL(url).getHost();
hostname = new URL(url).getHost();
} catch (MalformedURLException e) {
throw new DnsLookupFailedException(String.format("URL %s is malformed", url), e);
}
Expand All @@ -36,28 +36,20 @@ public String resolveAddress(final String url) throws DnsLookupFailedException,
Future<String> result = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return doResolve(host);
return dnsResolver.getHostAddress(hostname);
}
});
return result.get(timeoutMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
logger.warn("Unexpected interrupton while resolving host " + host, e);
logger.warn("Unexpected interrupton while resolving hostname " + hostname, e);
Thread.currentThread().interrupt();
throw new DnsLookupFailedException("Unexpected interruption while resolving host " + host, e);
throw new DnsLookupFailedException("Unexpected interruption while resolving hostname " + hostname, e);
} catch (ExecutionException e) {
throw new DnsLookupFailedException("Failed resolving host " + host, e.getCause());
throw new DnsLookupFailedException("Failed resolving hostname " + hostname, e.getCause());
} catch (TimeoutException e) {
throw new DnsTimeoutException(String.format("DNS Lookup for host %s timed out", host), e);
throw new DnsTimeoutException(String.format("DNS Lookup for host %s timed out", hostname), e);
} finally {
executor.shutdownNow();
}
}

/**
* Internal method to allow easier unit testing without dependency on internet connection
*/
protected String doResolve(final String host) throws UnknownHostException {
InetAddress address = InetAddress.getByName(host);
return address.getHostAddress();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cz.tomasdvorak.eet.client.networking;

import cz.tomasdvorak.eet.client.dto.DnsResolver;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressDnsResolver implements DnsResolver {

@Override
public String getHostAddress(final String hostname) throws UnknownHostException {
InetAddress address = InetAddress.getByName(hostname);
return address.getHostAddress();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import cz.tomasdvorak.eet.client.exceptions.DnsLookupFailedException;
import cz.tomasdvorak.eet.client.exceptions.DnsTimeoutException;
import cz.tomasdvorak.eet.client.networking.DnsResolver;
import cz.tomasdvorak.eet.client.networking.DnsResolverWithTimeout;
import cz.tomasdvorak.eet.client.networking.DnsLookup;
import cz.tomasdvorak.eet.client.networking.DnsLookupWithTimeout;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
Expand Down Expand Up @@ -75,7 +75,7 @@ protected SecureEETCommunication(final ClientKey clientKey, final ServerKey serv

protected EET getPort(final EndpointType endpointType) throws DnsTimeoutException, DnsLookupFailedException {
if (wsConfiguration.getDnsLookupTimeout() > 0) {
final DnsResolver resolver = new DnsResolverWithTimeout(wsConfiguration.getDnsLookupTimeout());
final DnsLookup resolver = new DnsLookupWithTimeout(wsConfiguration.getDnsResolver(), wsConfiguration.getDnsLookupTimeout());
final String ip = resolver.resolveAddress(endpointType.getWebserviceUrl());
logger.info(String.format("DNS lookup resolved %s to %s", endpointType, ip));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cz.tomasdvorak.eet.client.networking;

import cz.tomasdvorak.eet.client.config.EndpointType;
import cz.tomasdvorak.eet.client.dto.DnsResolver;
import cz.tomasdvorak.eet.client.exceptions.DnsLookupFailedException;
import cz.tomasdvorak.eet.client.exceptions.DnsTimeoutException;
import org.junit.Assert;
Expand All @@ -11,16 +12,17 @@
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;

public class DnsResolverWithTimeoutTest {
public class DnsLookupWithTimeoutTest {

private DnsResolver resolver;
private DnsLookup resolver;

@Before
public void setUp() throws Exception {
resolver = new DnsResolverWithTimeout(100) {

final DnsResolver resolverImpl = new DnsResolver() {
@Override
protected String doResolve(final String host) throws UnknownHostException {
if("pg.eet.cz".equals(host)) {
public String getHostAddress(final String host) throws UnknownHostException {
if ("pg.eet.cz".equals(host)) {
return "5.145.105.129";
} else if ("nonsense-timeouting.tomas-dvorak.cz".equals(host)) {
try {
Expand All @@ -34,7 +36,7 @@ protected String doResolve(final String host) throws UnknownHostException {
}
}
};

this.resolver = new DnsLookupWithTimeout(resolverImpl, 100);
}

@Test(timeout = 10000)
Expand Down

0 comments on commit 3af94ec

Please sign in to comment.