From e4e3e793ed3e78a848eb1a78bdb29e23ec6ff6cb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 27 Jul 2018 15:48:46 +0200 Subject: [PATCH] Allow customization of Vault's context path. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now support customization of the context path through VaultEndpoint.setPath(…). The path can also be part of an URI. Empty paths or a single slash are translated to the default context path of v1 denoting the supported API version. Closes gh-260. --- .../vault/client/VaultEndpoint.java | 48 +++++++++++++++++-- .../vault/client/VaultEndpointUnitTests.java | 15 +++++- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/spring-vault-core/src/main/java/org/springframework/vault/client/VaultEndpoint.java b/spring-vault-core/src/main/java/org/springframework/vault/client/VaultEndpoint.java index 8763936b..f4ab3af1 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/client/VaultEndpoint.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/client/VaultEndpoint.java @@ -21,13 +21,15 @@ import java.net.URI; import lombok.EqualsAndHashCode; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * Value object that defines Vault connection coordinates. *

- * A {@link VaultEndpoint} defines the hostname, TCP port and the protocol scheme (HTTP or - * HTTPS). + * A {@link VaultEndpoint} defines the hostname, TCP port, the protocol scheme (HTTP or + * HTTPS), and the context path prefix. The path defaults to {@link #API_VERSION}. * * @author Mark Paluch */ @@ -51,6 +53,11 @@ public class VaultEndpoint implements Serializable { */ private String scheme = "https"; + /** + * Context path of the Vault server. Defaults to {@link #API_VERSION}. + */ + private String path = API_VERSION; + /** * Create a secure {@link VaultEndpoint} given a {@code host} and {@code port} using * {@code https}. @@ -97,9 +104,22 @@ public class VaultEndpoint implements Serializable { } vaultEndpoint.setScheme(uri.getScheme()); + String path = getPath(uri); + + if (StringUtils.hasText(path)) { + vaultEndpoint.setPath(path); + } + return vaultEndpoint; } + @Nullable + private static String getPath(URI uri) { + + String path = uri.getPath(); + return path != null && path.startsWith("/") ? path.substring(1) : path; + } + /** * @return the hostname. */ @@ -152,6 +172,28 @@ public class VaultEndpoint implements Serializable { this.scheme = scheme; } + /** + * @return the context path prefix. + * @since 2.1 + */ + public String getPath() { + return path; + } + + /** + * @param path context path prefix. Must not be {@literal null} or empty and must not + * start with a leading slash. + * @since 2.1 + */ + public void setPath(String path) { + + Assert.hasText(path, "Path must not be null or empty"); + Assert.isTrue(!path.startsWith("/"), + () -> String.format("Path %s must not start with a leading slash", path)); + + this.path = path; + } + /** * Build the Vault {@link URI} based on the given {@code path}. * @@ -173,7 +215,7 @@ public class VaultEndpoint implements Serializable { Assert.hasText(path, "Path must not be empty"); return String.format("%s://%s:%s/%s/%s", getScheme(), getHost(), getPort(), - API_VERSION, path); + getPath(), path); } @Override diff --git a/spring-vault-core/src/test/java/org/springframework/vault/client/VaultEndpointUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/client/VaultEndpointUnitTests.java index 2c7f8f18..95e14624 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/client/VaultEndpointUnitTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/client/VaultEndpointUnitTests.java @@ -41,11 +41,12 @@ public class VaultEndpointUnitTests { @Test public void shouldCreateEndpointFromURI() { - VaultEndpoint endpoint = VaultEndpoint.from(URI.create("http://127.0.0.1:443")); + VaultEndpoint endpoint = VaultEndpoint.from(URI.create("http://127.0.0.1:443/")); assertThat(endpoint.getScheme()).isEqualTo("http"); assertThat(endpoint.getHost()).isEqualTo("127.0.0.1"); assertThat(endpoint.getPort()).isEqualTo(443); + assertThat(endpoint.getPath()).isEqualTo(VaultEndpoint.API_VERSION); } @Test @@ -56,5 +57,17 @@ public class VaultEndpointUnitTests { assertThat(endpoint.getScheme()).isEqualTo("http"); assertThat(endpoint.getHost()).isEqualTo("127.0.0.1"); assertThat(endpoint.getPort()).isEqualTo(80); + assertThat(endpoint.getPath()).isEqualTo(VaultEndpoint.API_VERSION); + } + + @Test + public void shouldCreateEndpointWithPath() { + + VaultEndpoint endpoint = VaultEndpoint.from(URI + .create("http://127.0.0.1/context")); + + assertThat(endpoint.getPath()).isEqualTo("context"); + assertThat(endpoint.createUri("foo")).isEqualTo( + URI.create("http://127.0.0.1:80/context/foo")); } }