This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-text.git
The following commit(s) were added to refs/heads/master by this push: new d81879e [TEXT-170] Add String lookup for host names and IP addresses (#118) d81879e is described below commit d81879e0e705a6df5a9cd45563ce9a59804e5580 Author: Gary Gregory <garydgreg...@users.noreply.github.com> AuthorDate: Sun Aug 4 11:26:52 2019 -0400 [TEXT-170] Add String lookup for host names and IP addresses (#118) * [TEXT-170] Add String lookup for host names and IP addresses (DnsStringLookup). * [TEXT-170] Add String lookup for host names and IP addresses (DnsStringLookup). Do not use hardcoded IP addresses. * [TEXT-170] Add String lookup for host names and IP addresses (DnsStringLookup). Do not use hardcoded IP addresses. * [TEXT-170] Add String lookup for host names and IP addresses (DnsStringLookup). Fix Checkstyle issues. * Fix version number in Javadoc. * Update Javadoc per PR review. * [TEXT-170] Add String lookup for host names and IP addresses (DnsStringLookup). Update test per PR review. * [TEXT-170] Add String lookup for host names and IP addresses (DnsStringLookup). Update test per PR review. --- src/changes/changes.xml | 1 + .../commons/text/lookup/DefaultStringLookup.java | 7 ++ .../commons/text/lookup/DnsStringLookup.java | 85 ++++++++++++++++++++++ .../commons/text/lookup/InetAddressKeys.java | 44 +++++++++++ .../commons/text/lookup/LocalHostStringLookup.java | 6 +- .../commons/text/lookup/StringLookupFactory.java | 28 +++++++ ...ubstitutorWithInterpolatorStringLookupTest.java | 53 +++++++++++++- .../text/lookup/DefaultStringLookupTest.java | 1 + .../commons/text/lookup/DnsStringLookupTest.java | 71 ++++++++++++++++++ .../text/lookup/StringLookupFactoryTest.java | 2 + 10 files changed, 292 insertions(+), 6 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index b66bb0a..b0b2a60 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -49,6 +49,7 @@ The <action> type attribute can be add,update,fix,remove. <action issue="TEXT-167" type="fix" dev="ggregory" due-to="Larry West">commons-text web page missing "RELEASE-NOTES-1.7.txt"</action> <action issue="TEXT-168" type="fix" dev="ggregory" due-to="luksan47">(doc) Fixed wrong value for Jaro-Winkler example #117</action> <action issue="TEXT-169" type="add" dev="ggregory" due-to="Gary Gregory">Add helper factory method org.apache.commons.text.StringSubstitutor.createInterpolator().</action> + <action issue="TEXT-170" type="add" dev="ggregory" due-to="Gary Gregory">Add String lookup for host names and IP addresses (DnsStringLookup).</action> </release> <release version="1.7" date="2019-06-30" description="Release 1.7"> diff --git a/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java b/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java index ba57578..c9632fa 100644 --- a/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java +++ b/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java @@ -49,6 +49,13 @@ public enum DefaultStringLookup { DATE(StringLookupFactory.KEY_DATE, StringLookupFactory.INSTANCE.dateStringLookup()), /** + * The lookup for DNS. + * + * @since 1.8 + */ + DNS(StringLookupFactory.KEY_DNS, StringLookupFactory.INSTANCE.dnsStringLookup()), + + /** * The lookup for environment properties. */ ENVIRONMENT(StringLookupFactory.KEY_ENV, StringLookupFactory.INSTANCE.environmentVariableStringLookup()), diff --git a/src/main/java/org/apache/commons/text/lookup/DnsStringLookup.java b/src/main/java/org/apache/commons/text/lookup/DnsStringLookup.java new file mode 100644 index 0000000..ba89418 --- /dev/null +++ b/src/main/java/org/apache/commons/text/lookup/DnsStringLookup.java @@ -0,0 +1,85 @@ +/* + * 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.commons.text.lookup; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Looks up keys related to DNS entries like host name, canonical host name, host address. + * <p> + * The lookup keys are: + * </p> + * <ul> + * <li><b>name|<em>address</em></b>: for the host name, for example {@code "name|93.184.216.34"} -> + * {@code "example.com"}.</li> + * <li><b>canonical-name|<em>address</em></b>: for the canonical host name, for example {@code "name|93.184.216.34"} -> + * {@code "example.com"}.</li> + * <li><b>address|<em>hostname</em></b>: for the host address, for example {@code "address|example.com"} -> + * {@code "93.184.216.34"}.</li> + * <li><b><em>address</em></b>: same as {@code address|hostname}.</li> + * </ul> + * + * @since 1.8 + */ +final class DnsStringLookup extends AbstractStringLookup { + + /** + * Defines the singleton for this class. + */ + static final DnsStringLookup INSTANCE = new DnsStringLookup(); + + /** + * No need to build instances for now. + */ + private DnsStringLookup() { + // empty + } + + /** + * Looks up the DNS value of the key. + * + * @param key the key to be looked up, may be null + * @return The DNS value. + */ + @Override + public String lookup(final String key) { + if (key == null) { + return null; + } + final String[] keys = key.trim().split("\\|"); + final int keyLen = keys.length; + final String subKey = keys[0].trim(); + final String subValue = keyLen < 2 ? key : keys[1].trim(); + try { + final InetAddress inetAddress = InetAddress.getByName(subValue); + switch (subKey) { + case InetAddressKeys.KEY_NAME: + return inetAddress.getHostName(); + case InetAddressKeys.KEY_CANONICAL_NAME: + return inetAddress.getCanonicalHostName(); + case InetAddressKeys.KEY_ADDRESS: + return inetAddress.getHostAddress(); + default: + return inetAddress.getHostAddress(); + } + } catch (final UnknownHostException e) { + return null; + } + } + +} diff --git a/src/main/java/org/apache/commons/text/lookup/InetAddressKeys.java b/src/main/java/org/apache/commons/text/lookup/InetAddressKeys.java new file mode 100644 index 0000000..2465614 --- /dev/null +++ b/src/main/java/org/apache/commons/text/lookup/InetAddressKeys.java @@ -0,0 +1,44 @@ +/* + * 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.commons.text.lookup; + +import java.net.InetAddress; + +/** + * Constants for referring to {@link InetAddress} APIs. + * + * @since 1.8 + */ +class InetAddressKeys { + + /** + * Constants for referring to {@link InetAddress#getAddress()}. + */ + static final String KEY_ADDRESS = "address"; + + /** + * Constants for referring to {@link InetAddress#getCanonicalAddress()}. + */ + static final String KEY_CANONICAL_NAME = "canonical-name"; + + /** + * Constants for referring to {@link InetAddress#getName()}. + */ + static final String KEY_NAME = "name"; + +} diff --git a/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java b/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java index 9f4ee34..8bdc24d 100644 --- a/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java +++ b/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java @@ -59,11 +59,11 @@ final class LocalHostStringLookup extends AbstractStringLookup { } try { switch (key) { - case "name": + case InetAddressKeys.KEY_NAME: return InetAddress.getLocalHost().getHostName(); - case "canonical-name": + case InetAddressKeys.KEY_CANONICAL_NAME: return InetAddress.getLocalHost().getCanonicalHostName(); - case "address": + case InetAddressKeys.KEY_ADDRESS: return InetAddress.getLocalHost().getHostAddress(); default: throw new IllegalArgumentException(key); diff --git a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java index da61c6f..8fbf9b4 100644 --- a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java +++ b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java @@ -57,6 +57,12 @@ import java.util.Map; * <td>1.5</td> * </tr> * <tr> + * <td>{@value #KEY_DNS}</td> + * <td>{@link DnsStringLookup}</td> + * <td>{@link #dnsStringLookup()}</td> + * <td>1.8</td> + * </tr> + * <tr> * <td>{@value #KEY_ENV}</td> * <td>{@link EnvironmentVariableStringLookup}</td> * <td>{@link #environmentVariableStringLookup()}</td> @@ -170,6 +176,13 @@ public final class StringLookupFactory { /** * Default lookup key for interpolation. * + * @since 1.8 + */ + public static final String KEY_DNS = "dns"; + + /** + * Default lookup key for interpolation. + * * @since 1.6 */ public static final String KEY_ENV = "env"; @@ -455,6 +468,21 @@ public final class StringLookupFactory { } /** + * Returns the DnsStringLookup singleton instance where the lookup key is one of: + * <ul> + * <li><b>name</b>: for the local host name, for example {@code EXAMPLE} but also {@code EXAMPLE.apache.org}.</li> + * <li><b>canonical-name</b>: for the local canonical host name, for example {@code EXAMPLE.apache.org}.</li> + * <li><b>address</b>: for the local host address, for example {@code 192.168.56.1}.</li> + * </ul> + * + * @return the DateStringLookup singleton instance. + * @since 1.8 + */ + public StringLookup dnsStringLookup() { + return DnsStringLookup.INSTANCE; + } + + /** * Returns a new map-based lookup where the request for a lookup is answered with the value for that key. * * @param <V> diff --git a/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java b/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java index e70e953..ed4dc03 100644 --- a/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java +++ b/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java @@ -45,7 +45,7 @@ public class StringSubstitutorWithInterpolatorStringLookupTest { final Map<String, StringLookup> stringLookupMap = new HashMap<>(); stringLookupMap.put("customLookup", mapStringLookup); final StringSubstitutor strSubst = new StringSubstitutor( - StringLookupFactory.INSTANCE.interpolatorStringLookup(stringLookupMap, null, addDefaultLookups)); + StringLookupFactory.INSTANCE.interpolatorStringLookup(stringLookupMap, null, addDefaultLookups)); if (addDefaultLookups) { final String spKey = "user.name"; Assertions.assertEquals(System.getProperty(spKey), strSubst.replace("${sys:" + spKey + "}")); @@ -69,6 +69,53 @@ public class StringSubstitutorWithInterpolatorStringLookupTest { } @Test + public void testDnsLookup() throws UnknownHostException { + final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); + final String hostName = InetAddress.getLocalHost().getHostName(); + Assertions.assertEquals(InetAddress.getByName(hostName).getHostAddress(), + strSubst.replace("${dns:" + hostName + "}")); + } + + @Test + public void testDnsLookupAddress() throws UnknownHostException { + final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); + Assertions.assertEquals(InetAddress.getByName("apache.org").getHostAddress(), + strSubst.replace("${dns:address|apache.org}")); + } + + @Test + public void testDnsLookupCanonicalName() throws UnknownHostException { + final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); + final String address = InetAddress.getLocalHost().getHostAddress(); + final InetAddress inetAddress = InetAddress.getByName(address); + Assertions.assertEquals(inetAddress.getCanonicalHostName(), + strSubst.replace("${dns:canonical-name|" + address + "}")); + } + + @Test + public void testDnsLookupName() throws UnknownHostException { + final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); + final String address = InetAddress.getLocalHost().getHostAddress(); + final InetAddress inetAddress = InetAddress.getByName(address); + Assertions.assertEquals(inetAddress.getHostName(), strSubst.replace("${dns:name|" + address + "}")); + } + + @Test + public void testDnsLookupNameUntrimmed() throws UnknownHostException { + final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); + final String address = InetAddress.getLocalHost().getHostAddress(); + final InetAddress inetAddress = InetAddress.getByName(address); + Assertions.assertEquals(inetAddress.getHostName(), strSubst.replace("${dns:name| " + address + " }")); + } + + @Test + public void testDnsLookupUnknown() { + final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); + final String unknown = "${dns: u n k n o w n}"; + Assertions.assertEquals(unknown, strSubst.replace(unknown)); + } + + @Test public void testLocalHostLookup_Address() throws UnknownHostException { final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); Assertions.assertEquals(InetAddress.getLocalHost().getHostAddress(), strSubst.replace("${localhost:address}")); @@ -78,7 +125,7 @@ public class StringSubstitutorWithInterpolatorStringLookupTest { public void testLocalHostLookup_CanonicalName() throws UnknownHostException { final StringSubstitutor strSubst = StringSubstitutor.createInterpolator(); Assertions.assertEquals(InetAddress.getLocalHost().getCanonicalHostName(), - strSubst.replace("${localhost:canonical-name}")); + strSubst.replace("${localhost:canonical-name}")); } @Test @@ -94,7 +141,7 @@ public class StringSubstitutorWithInterpolatorStringLookupTest { final Map<String, String> map = new HashMap<>(); map.put(key, value); final StringSubstitutor strSubst = new StringSubstitutor( - StringLookupFactory.INSTANCE.interpolatorStringLookup(map)); + StringLookupFactory.INSTANCE.interpolatorStringLookup(map)); final String spKey = "user.name"; Assertions.assertEquals(System.getProperty(spKey), strSubst.replace("${sys:" + spKey + "}")); Assertions.assertEquals(value, strSubst.replace("${" + key + "}")); diff --git a/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java b/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java index 2302dd3..0fa967a 100644 --- a/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java +++ b/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java @@ -46,6 +46,7 @@ public class DefaultStringLookupTest { StringLookupFactory.INSTANCE.base64EncoderStringLookup()); assertSame(DefaultStringLookup.CONST.getStringLookup(), StringLookupFactory.INSTANCE.constantStringLookup()); assertSame(DefaultStringLookup.DATE.getStringLookup(), StringLookupFactory.INSTANCE.dateStringLookup()); + assertSame(DefaultStringLookup.DNS.getStringLookup(), StringLookupFactory.INSTANCE.dnsStringLookup()); assertSame(DefaultStringLookup.ENVIRONMENT.getStringLookup(), StringLookupFactory.INSTANCE.environmentVariableStringLookup()); assertSame(DefaultStringLookup.FILE.getStringLookup(), StringLookupFactory.INSTANCE.fileStringLookup()); diff --git a/src/test/java/org/apache/commons/text/lookup/DnsStringLookupTest.java b/src/test/java/org/apache/commons/text/lookup/DnsStringLookupTest.java new file mode 100644 index 0000000..fed3797 --- /dev/null +++ b/src/test/java/org/apache/commons/text/lookup/DnsStringLookupTest.java @@ -0,0 +1,71 @@ +/* + * 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.commons.text.lookup; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Tests {@link DnsStringLookup}. + */ +public class DnsStringLookupTest { + + @Test + public void testAddressFromHostAddress() throws UnknownHostException { + final InetAddress localHost = InetAddress.getLocalHost(); + Assertions.assertEquals(localHost.getHostAddress(), + DnsStringLookup.INSTANCE.lookup("address|" + localHost.getHostAddress())); + } + + @Test + public void testAddressFromHostName() throws UnknownHostException { + final InetAddress localHost = InetAddress.getLocalHost(); + Assertions.assertEquals(localHost.getHostAddress(), + DnsStringLookup.INSTANCE.lookup("address|" + localHost.getHostName())); + } + + @Test + public void testCanonicalNameFromHostAddress() throws UnknownHostException { + final InetAddress localHost = InetAddress.getLocalHost(); + Assertions.assertEquals(localHost.getCanonicalHostName(), + DnsStringLookup.INSTANCE.lookup("canonical-name|" + localHost.getHostAddress())); + } + + @Test + public void testCanonicalNameFromHostName() throws UnknownHostException { + final InetAddress localHost = InetAddress.getLocalHost(); + Assertions.assertEquals(localHost.getCanonicalHostName(), + DnsStringLookup.INSTANCE.lookup("canonical-name|" + localHost.getHostName())); + } + + @Test + public void testName() throws UnknownHostException { + final String address = InetAddress.getLocalHost().getHostAddress(); + final InetAddress localHost = InetAddress.getByName(address); + Assertions.assertEquals(localHost.getHostName(), DnsStringLookup.INSTANCE.lookup("name|" + address + "")); + } + + @Test + public void testNull() { + Assertions.assertNull(DnsStringLookup.INSTANCE.lookup(null)); + } + +} diff --git a/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java b/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java index 46893fd..e7731e7 100644 --- a/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java +++ b/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java @@ -34,6 +34,7 @@ public class StringLookupFactoryTest { assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_BASE64_ENCODER)); assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_CONST)); assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_DATE)); + assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_DNS)); assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_ENV)); assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_FILE)); assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_JAVA)); @@ -70,6 +71,7 @@ public class StringLookupFactoryTest { Assertions.assertSame(Base64EncoderStringLookup.INSTANCE, stringLookupFactory.base64EncoderStringLookup()); Assertions.assertSame(ConstantStringLookup.INSTANCE, stringLookupFactory.constantStringLookup()); Assertions.assertSame(DateStringLookup.INSTANCE, stringLookupFactory.dateStringLookup()); + Assertions.assertSame(DnsStringLookup.INSTANCE, stringLookupFactory.dnsStringLookup()); Assertions.assertSame(EnvironmentVariableStringLookup.INSTANCE, stringLookupFactory.environmentVariableStringLookup()); Assertions.assertSame(InterpolatorStringLookup.INSTANCE, stringLookupFactory.interpolatorStringLookup());