diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2022-04-09 14:00:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-09 14:00:04 +0200 |
commit | 87e5b33c003d07ca585d73e0166857fe22b4c16f (patch) | |
tree | 6748bfa41fac16ad9b22d0afba4d150b44414542 /vespajlib | |
parent | 80b96d32550ae0df59572a58cd62f507e8068c2c (diff) | |
parent | 1c27950698237c7ebe0f8ea7ed5848889d6b4759 (diff) |
Merge pull request #22072 from vespa-engine/jonmv/unify-hostname-classes
Jonmv/unify hostname classes
Diffstat (limited to 'vespajlib')
-rw-r--r-- | vespajlib/abi-spec.json | 4 | ||||
-rw-r--r-- | vespajlib/src/main/java/ai/vespa/http/DomainName.java | 6 | ||||
-rw-r--r-- | vespajlib/src/main/java/ai/vespa/validation/StringWrapper.java | 2 | ||||
-rw-r--r-- | vespajlib/src/main/java/com/yahoo/net/HostName.java | 37 | ||||
-rw-r--r-- | vespajlib/src/test/java/com/yahoo/net/HostNameTest.java | 25 |
5 files changed, 60 insertions, 14 deletions
diff --git a/vespajlib/abi-spec.json b/vespajlib/abi-spec.json index 6044666ebf8..ae69564b671 100644 --- a/vespajlib/abi-spec.json +++ b/vespajlib/abi-spec.json @@ -350,13 +350,13 @@ "fields": [] }, "com.yahoo.net.HostName": { - "superClass": "java.lang.Object", + "superClass": "ai.vespa.validation.PatternedStringWrapper", "interfaces": [], "attributes": [ "public" ], "methods": [ - "public void <init>()", + "public static com.yahoo.net.HostName of(java.lang.String)", "public static synchronized java.lang.String getLocalhost()", "public static void setHostNameForTestingOnly(java.lang.String)" ], diff --git a/vespajlib/src/main/java/ai/vespa/http/DomainName.java b/vespajlib/src/main/java/ai/vespa/http/DomainName.java index 737f6b6d863..a566f5b95be 100644 --- a/vespajlib/src/main/java/ai/vespa/http/DomainName.java +++ b/vespajlib/src/main/java/ai/vespa/http/DomainName.java @@ -15,12 +15,12 @@ import static ai.vespa.validation.Validation.requireMatch; */ public class DomainName extends PatternedStringWrapper<DomainName> { - protected static final Pattern labelPattern = Pattern.compile("([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])"); - protected static final Pattern domainNamePattern = Pattern.compile("(" + labelPattern + "\\.)*" + labelPattern); + static final Pattern labelPattern = Pattern.compile("([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])"); + static final Pattern domainNamePattern = Pattern.compile("(" + labelPattern + "\\.)*" + labelPattern); public static final DomainName localhost = DomainName.of("localhost"); - protected DomainName(String value) { + private DomainName(String value) { super(requireLength(value, "domain name length", 1, 255), domainNamePattern, "domain name"); } diff --git a/vespajlib/src/main/java/ai/vespa/validation/StringWrapper.java b/vespajlib/src/main/java/ai/vespa/validation/StringWrapper.java index 12be0002f6f..0937627b57e 100644 --- a/vespajlib/src/main/java/ai/vespa/validation/StringWrapper.java +++ b/vespajlib/src/main/java/ai/vespa/validation/StringWrapper.java @@ -40,7 +40,7 @@ public abstract class StringWrapper<T extends StringWrapper<T>> implements Compa @Override public final boolean equals(Object o) { if (this == o) return true; - if ( ! (o instanceof StringWrapper<?>)) return false; + if (o == null || getClass() != o.getClass()) return false; return value.equals(((StringWrapper<?>) o).value); } diff --git a/vespajlib/src/main/java/com/yahoo/net/HostName.java b/vespajlib/src/main/java/com/yahoo/net/HostName.java index 7446771f57c..20f1008055e 100644 --- a/vespajlib/src/main/java/com/yahoo/net/HostName.java +++ b/vespajlib/src/main/java/com/yahoo/net/HostName.java @@ -1,18 +1,39 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.net; +import ai.vespa.http.DomainName; +import ai.vespa.validation.PatternedStringWrapper; + import java.util.Optional; +import java.util.regex.Pattern; + +import static ai.vespa.validation.Validation.requireLength; /** - * This class has utilities for getting the hostname of the system running the JVM. + * Hostnames match {@link #hostNamePattern}, and are restricted to 64 characters in length. + * + * This class also has utilities for getting the hostname of the system running the JVM. * Detection of the hostname is now done before starting any Vespa * programs and provided in the environment variable VESPA_HOSTNAME; * if that variable isn't set a default of "localhost" is always returned. * * @author arnej + * @author jonmv */ -public class HostName { +public class HostName extends PatternedStringWrapper<HostName> { + + static final Pattern labelPattern = Pattern.compile("([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])"); + static final Pattern hostNamePattern = Pattern.compile("(" + labelPattern + "\\.)*" + labelPattern); - private static String preferredHostName = null; + private static HostName preferredHostName = null; + + private HostName(String value) { + super(requireLength(value, "hostname length", 1, 64), hostNamePattern, "hostname"); + } + + public static HostName of(String value) { + return new HostName(value); + } /** * Return a public and fully qualified hostname for localhost that @@ -24,19 +45,19 @@ public class HostName { if (preferredHostName == null) { preferredHostName = getPreferredHostName(); } - return preferredHostName; + return preferredHostName.value(); } - static private String getPreferredHostName() { + static private HostName getPreferredHostName() { Optional<String> vespaHostEnv = Optional.ofNullable(System.getenv("VESPA_HOSTNAME")); if (vespaHostEnv.isPresent() && ! vespaHostEnv.get().trim().isEmpty()) { - return vespaHostEnv.get().trim(); + return of(vespaHostEnv.get().trim()); } - return "localhost"; + return of("localhost"); } public static void setHostNameForTestingOnly(String hostName) { - preferredHostName = hostName; + preferredHostName = HostName.of(hostName); } } diff --git a/vespajlib/src/test/java/com/yahoo/net/HostNameTest.java b/vespajlib/src/test/java/com/yahoo/net/HostNameTest.java index 2548c3cea60..fa756b31616 100644 --- a/vespajlib/src/test/java/com/yahoo/net/HostNameTest.java +++ b/vespajlib/src/test/java/com/yahoo/net/HostNameTest.java @@ -1,14 +1,39 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.net; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; +/** + * @author jonmv + */ public class HostNameTest { @Test + void testNames() { + HostName.of("name-123.0.321-eman"); + HostName.of(("." + "a".repeat(32)).repeat(2).substring(1, 65)); + HostName.of("123"); + + assertThrows(IllegalArgumentException.class, () -> HostName.of("_")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("-")); + assertThrows(IllegalArgumentException.class, () -> HostName.of(".")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("-foo")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("foo-")); + assertThrows(IllegalArgumentException.class, () -> HostName.of(".foo")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("foo.")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("foo..bar")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("foo.-.bar")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("foo/")); + assertThrows(IllegalArgumentException.class, () -> HostName.of("foo%")); + assertThrows(IllegalArgumentException.class, () -> HostName.of(("." + "a".repeat(32)).repeat(2).substring(1, 66))); + assertThrows(IllegalArgumentException.class, () -> HostName.of("a".repeat(64))); + } + + @Test void testHostnameIsFound() { assertFalse(HostName.getLocalhost().isEmpty()); } |