From 3af94ec93a18bb35e5e074295d49dad7f9057bf2 Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Thu, 9 Mar 2017 17:13:00 +0100 Subject: [PATCH] dns resolver configurable from outside via WebserviceConfiguration (#30) --- .../eet/client/dto/DnsResolver.java | 20 +++++++++++ .../client/dto/WebserviceConfiguration.java | 12 +++++++ .../{DnsResolver.java => DnsLookup.java} | 2 +- ...Timeout.java => DnsLookupWithTimeout.java} | 34 +++++++------------ .../networking/InetAddressDnsResolver.java | 15 ++++++++ .../security/SecureEETCommunication.java | 6 ++-- ...est.java => DnsLookupWithTimeoutTest.java} | 14 ++++---- 7 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 src/main/java/cz/tomasdvorak/eet/client/dto/DnsResolver.java rename src/main/java/cz/tomasdvorak/eet/client/networking/{DnsResolver.java => DnsLookup.java} (89%) rename src/main/java/cz/tomasdvorak/eet/client/networking/{DnsResolverWithTimeout.java => DnsLookupWithTimeout.java} (64%) create mode 100644 src/main/java/cz/tomasdvorak/eet/client/networking/InetAddressDnsResolver.java rename src/test/java/cz/tomasdvorak/eet/client/networking/{DnsResolverWithTimeoutTest.java => DnsLookupWithTimeoutTest.java} (88%) diff --git a/src/main/java/cz/tomasdvorak/eet/client/dto/DnsResolver.java b/src/main/java/cz/tomasdvorak/eet/client/dto/DnsResolver.java new file mode 100644 index 00000000..96f66b37 --- /dev/null +++ b/src/main/java/cz/tomasdvorak/eet/client/dto/DnsResolver.java @@ -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; +} diff --git a/src/main/java/cz/tomasdvorak/eet/client/dto/WebserviceConfiguration.java b/src/main/java/cz/tomasdvorak/eet/client/dto/WebserviceConfiguration.java index a694058c..730a7b03 100644 --- a/src/main/java/cz/tomasdvorak/eet/client/dto/WebserviceConfiguration.java +++ b/src/main/java/cz/tomasdvorak/eet/client/dto/WebserviceConfiguration.java @@ -1,5 +1,7 @@ package cz.tomasdvorak.eet.client.dto; +import cz.tomasdvorak.eet.client.networking.InetAddressDnsResolver; + /** * TODO: create builder for the configuration! */ @@ -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 @@ -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() { @@ -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; + } } diff --git a/src/main/java/cz/tomasdvorak/eet/client/networking/DnsResolver.java b/src/main/java/cz/tomasdvorak/eet/client/networking/DnsLookup.java similarity index 89% rename from src/main/java/cz/tomasdvorak/eet/client/networking/DnsResolver.java rename to src/main/java/cz/tomasdvorak/eet/client/networking/DnsLookup.java index 73008425..3f45b61e 100644 --- a/src/main/java/cz/tomasdvorak/eet/client/networking/DnsResolver.java +++ b/src/main/java/cz/tomasdvorak/eet/client/networking/DnsLookup.java @@ -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; } diff --git a/src/main/java/cz/tomasdvorak/eet/client/networking/DnsResolverWithTimeout.java b/src/main/java/cz/tomasdvorak/eet/client/networking/DnsLookupWithTimeout.java similarity index 64% rename from src/main/java/cz/tomasdvorak/eet/client/networking/DnsResolverWithTimeout.java rename to src/main/java/cz/tomasdvorak/eet/client/networking/DnsLookupWithTimeout.java index 973a50e7..6a3005fa 100644 --- a/src/main/java/cz/tomasdvorak/eet/client/networking/DnsResolverWithTimeout.java +++ b/src/main/java/cz/tomasdvorak/eet/client/networking/DnsLookupWithTimeout.java @@ -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); } @@ -36,28 +36,20 @@ public String resolveAddress(final String url) throws DnsLookupFailedException, Future result = executor.submit(new Callable() { @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(); - } } \ No newline at end of file diff --git a/src/main/java/cz/tomasdvorak/eet/client/networking/InetAddressDnsResolver.java b/src/main/java/cz/tomasdvorak/eet/client/networking/InetAddressDnsResolver.java new file mode 100644 index 00000000..6d7974c2 --- /dev/null +++ b/src/main/java/cz/tomasdvorak/eet/client/networking/InetAddressDnsResolver.java @@ -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(); + } +} diff --git a/src/main/java/cz/tomasdvorak/eet/client/security/SecureEETCommunication.java b/src/main/java/cz/tomasdvorak/eet/client/security/SecureEETCommunication.java index 7d2bebde..3bcd48c3 100644 --- a/src/main/java/cz/tomasdvorak/eet/client/security/SecureEETCommunication.java +++ b/src/main/java/cz/tomasdvorak/eet/client/security/SecureEETCommunication.java @@ -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; @@ -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)); } diff --git a/src/test/java/cz/tomasdvorak/eet/client/networking/DnsResolverWithTimeoutTest.java b/src/test/java/cz/tomasdvorak/eet/client/networking/DnsLookupWithTimeoutTest.java similarity index 88% rename from src/test/java/cz/tomasdvorak/eet/client/networking/DnsResolverWithTimeoutTest.java rename to src/test/java/cz/tomasdvorak/eet/client/networking/DnsLookupWithTimeoutTest.java index 83eac202..99ebde19 100644 --- a/src/test/java/cz/tomasdvorak/eet/client/networking/DnsResolverWithTimeoutTest.java +++ b/src/test/java/cz/tomasdvorak/eet/client/networking/DnsLookupWithTimeoutTest.java @@ -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; @@ -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 { @@ -34,7 +36,7 @@ protected String doResolve(final String host) throws UnknownHostException { } } }; - + this.resolver = new DnsLookupWithTimeout(resolverImpl, 100); } @Test(timeout = 10000)