From 1e36b8f90c5aecd76472a8ab94ea651750907542 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Sat, 5 May 2018 13:16:46 +0200 Subject: [PATCH] Require API version for Key/Value backend usage. We now require specification of the desired Key/Value API version to interact with Vault's Key/Value backends. Vault 0.10.1 removed request downgrading so the client is in charge of using the proper API version. KeyValue API implementation classes are package-protected now as API stability in Vault isn't given so we want to be able to adapt to API changes without breaking public API. See gh-245. --- .../vault/core/VaultKeyValue1Template.java | 124 ++++++++++++++++ .../vault/core/VaultKeyValue2Accessor.java | 89 ++++++++++++ ...plate.java => VaultKeyValue2Template.java} | 10 +- .../vault/core/VaultKeyValueAccessor.java | 135 +++++++++--------- .../vault/core/VaultKeyValueOperations.java | 1 + .../core/VaultKeyValueOperationsSupport.java | 35 +++++ .../vault/core/VaultOperations.java | 9 +- .../vault/core/VaultTemplate.java | 15 +- .../core/VaultVersionedKeyValueTemplate.java | 13 +- ...VaultKeyValueTemplateIntegrationTests.java | 14 +- ...VaultKeyValueTemplateIntegrationTests.java | 7 +- ...alueTemplateVersionedIntegrationTests.java | 7 +- 12 files changed, 367 insertions(+), 92 deletions(-) create mode 100644 spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue1Template.java create mode 100644 spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue2Accessor.java rename spring-vault-core/src/main/java/org/springframework/vault/core/{VaultKeyValueTemplate.java => VaultKeyValue2Template.java} (88%) diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue1Template.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue1Template.java new file mode 100644 index 00000000..6998ab77 --- /dev/null +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue1Template.java @@ -0,0 +1,124 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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.springframework.vault.core; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; + +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.vault.support.VaultResponse; +import org.springframework.vault.support.VaultResponseSupport; + +/** + * Default implementation of {@link VaultKeyValueOperations} for the Key/Value backend + * version 1. + * + * @author Mark Paluch + * @since 2.1 + * @see KeyValueBackend#KV_1 + */ +class VaultKeyValue1Template extends VaultKeyValueAccessor implements + VaultKeyValueOperations { + + private final VaultOperations vaultOperations; + private final String path; + + /** + * Create a new {@link VaultKeyValue1Template} given {@link VaultOperations} and the + * mount {@code path}. + * + * @param vaultOperations must not be {@literal null}. + * @param path must not be empty or {@literal null}. + */ + public VaultKeyValue1Template(VaultOperations vaultOperations, String path) { + + super(vaultOperations, path); + + this.vaultOperations = vaultOperations; + this.path = path; + } + + @Nullable + @Override + public List list(String path) { + return vaultOperations.list(createDataPath(path)); + } + + @Nullable + @Override + public VaultResponse get(String path) { + + Assert.hasText(path, "Path must not be empty"); + + return doRead(path, Map.class, (response, data) -> { + + VaultResponse vaultResponse = new VaultResponse(); + vaultResponse.setRenewable(response.isRenewable()); + vaultResponse.setAuth(response.getAuth()); + vaultResponse.setLeaseDuration(response.getLeaseDuration()); + vaultResponse.setLeaseId(response.getLeaseId()); + vaultResponse.setMetadata(response.getMetadata()); + vaultResponse.setRequestId(response.getRequestId()); + vaultResponse.setWarnings(response.getWarnings()); + vaultResponse.setWrapInfo(response.getWrapInfo()); + vaultResponse.setData(data); + + return vaultResponse; + }); + } + + @Nullable + @Override + @SuppressWarnings("unchecked") + public VaultResponseSupport get(String path, Class responseType) { + + Assert.hasText(path, "Path must not be empty"); + Assert.notNull(responseType, "Response type must not be null"); + + return doRead(path, responseType, (response, data) -> { + + VaultResponseSupport result = response; + result.setData(data); + return result; + }); + } + + @Override + public void put(String path, Object body) { + + Assert.hasText(path, "Path must not be empty"); + + doWrite(createDataPath(path), body); + } + + @Override + public KeyValueBackend getApiVersion() { + return KeyValueBackend.KV_1; + } + + @Override + JsonNode getJsonNode(VaultResponseSupport response) { + return response.getRequiredData(); + } + + @Override + String createDataPath(String path) { + return String.format("%s/%s", this.path, path); + } +} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue2Accessor.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue2Accessor.java new file mode 100644 index 00000000..aebe78d0 --- /dev/null +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue2Accessor.java @@ -0,0 +1,89 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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.springframework.vault.core; + +import java.util.Collections; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +import org.springframework.http.HttpMethod; +import org.springframework.lang.Nullable; +import org.springframework.vault.support.VaultResponseSupport; + +/** + * Support class to build accessor methods for the Vault key-value backend version 2. + * + * @author Mark Paluch + * @since 2.1 + * @see KeyValueBackend#KV_2 + */ +abstract class VaultKeyValue2Accessor extends VaultKeyValueAccessor { + + private final String path; + + /** + * Create a new {@link VaultKeyValue2Accessor} given {@link VaultOperations} and the + * mount {@code path}. + * + * @param vaultOperations must not be {@literal null}. + * @param path must not be empty or {@literal null}. + */ + VaultKeyValue2Accessor(VaultOperations vaultOperations, String path) { + + super(vaultOperations, path); + + this.path = path; + } + + @Nullable + @Override + @SuppressWarnings("unchecked") + public List list(String path) { + + String pathToUse = path.equals("/") ? "" : path.endsWith("/") ? path + : (path + "/"); + + VaultListResponse read = doRead(restOperations -> { + return restOperations.exchange(String.format("%s?list=true", + createBackendPath("metadata", pathToUse)), HttpMethod.GET, null, + VaultListResponse.class); + }); + + if (read == null) { + return Collections.emptyList(); + } + + return (List) read.getRequiredData().get("keys"); + } + + @Override + public KeyValueBackend getApiVersion() { + return KeyValueBackend.KV_2; + } + + JsonNode getJsonNode(VaultResponseSupport response) { + return response.getRequiredData().at("/data"); + } + + String createDataPath(String path) { + return createBackendPath("data", path); + } + + String createBackendPath(String segment, String path) { + return String.format("%s/%s/%s", this.path, segment, path); + } +} diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue2Template.java similarity index 88% rename from spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueTemplate.java rename to spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue2Template.java index caac0495..75f5e31c 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValue2Template.java @@ -24,23 +24,23 @@ import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultResponseSupport; /** - * Default implementation of {@link VaultKeyValueOperations}. + * Default implementation of {@link VaultKeyValueOperations} for the key-value backend + * version 2. * * @author Mark Paluch * @since 2.1 */ -public class VaultKeyValueTemplate extends VaultKeyValueAccessor implements +class VaultKeyValue2Template extends VaultKeyValue2Accessor implements VaultKeyValueOperations { /** - * Create a new {@link VaultKeyValueTemplate} given {@link VaultOperations} and the + * Create a new {@link VaultKeyValue2Template} given {@link VaultOperations} and the * mount {@code path}. * * @param vaultOperations must not be {@literal null}. * @param path must not be empty or {@literal null}. */ - public VaultKeyValueTemplate(VaultOperations vaultOperations, String path) { - + public VaultKeyValue2Template(VaultOperations vaultOperations, String path) { super(vaultOperations, path); } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueAccessor.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueAccessor.java index b2dff399..992a4faa 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueAccessor.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueAccessor.java @@ -16,17 +16,15 @@ package org.springframework.vault.core; import java.io.IOException; -import java.util.Collections; -import java.util.List; import java.util.Optional; import java.util.function.BiFunction; +import java.util.function.Function; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -42,16 +40,16 @@ import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; /** - * Base class for {@link VaultVersionedKeyValueTemplate} and {@link VaultKeyValueTemplate} - * and other Vault KV-accessing helpers, defining common + * Base class for {@link VaultVersionedKeyValueTemplate} and + * {@link VaultKeyValue2Template} and other Vault KV-accessing helpers, defining common *

* Not intended to be used directly. See {@link VaultVersionedKeyValueTemplate} and - * {@link VaultKeyValueTemplate}. + * {@link VaultKeyValue2Template}. * * @author Mark Paluch * @since 2.1 */ -public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport { +abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport { private final VaultOperations vaultOperations; @@ -66,7 +64,7 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu * @param vaultOperations must not be {@literal null}. * @param path must not be empty or {@literal null}. */ - public VaultKeyValueAccessor(VaultOperations vaultOperations, String path) { + VaultKeyValueAccessor(VaultOperations vaultOperations, String path) { Assert.notNull(vaultOperations, "VaultOperations must not be null"); Assert.hasText(path, "Path must not be empty"); @@ -76,43 +74,23 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu this.mapper = extractObjectMapper(vaultOperations); } - @Nullable - @Override - @SuppressWarnings("unchecked") - public List list(String path) { - - String pathToUse = path.equals("/") ? "" : path.endsWith("/") ? path - : (path + "/"); - - VaultListResponse read = doRead((restOperations, httpEntity) -> { - return restOperations.exchange(String.format("%s?list=true", - createBackendPath("metadata", pathToUse)), HttpMethod.GET, - httpEntity, VaultListResponse.class); - }); - - if (read == null) { - return Collections.emptyList(); - } - - return (List) read.getRequiredData().get("keys"); - } - @Override public void delete(String path) { Assert.hasText(path, "Path must not be empty"); - doWithSession(((restOperations, httpHeaders) -> { + vaultOperations.doWithSession((restOperations -> { restOperations.exchange(createDataPath(path), HttpMethod.DELETE, - new HttpEntity<>(httpHeaders), Void.class); + null, + Void.class); return null; })); } /** - * Read a secret at {@code path} and deserialize the nested {@literal data} element to - * the given {@link Class type}. + * Read a secret at {@code path} and deserialize the {@literal data} element to the + * given {@link Class type}. * * @param path must not be {@literal null}. * @param deserializeAs must not be {@literal null}. @@ -133,7 +111,7 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu if (response != null) { - JsonNode jsonNode = response.getRequiredData().at("/data"); + JsonNode jsonNode = getJsonNode(response); return mappingFunction.apply(response, deserialize(jsonNode, deserializeAs)); } @@ -141,6 +119,29 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu return null; } + /** + * Read a secret at {@code path} and deserialize the {@literal data} element to the + * given {@link ParameterizedTypeReference type}. + * + * @param path must not be {@literal null} or empty. + * @param typeReference must not be {@literal null} + * @return mapped value. + */ + @Nullable + T doRead(String path, ParameterizedTypeReference typeReference) { + + return doRead((restOperations) -> { + return restOperations.exchange(path, HttpMethod.GET, null, typeReference); + }); + } + + /** + * Deserialize a {@link JsonNode} to the requested {@link Class type}. + * + * @param jsonNode must not be {@literal null}. + * @param type must not be {@literal null}. + * @return the deserialized object. + */ T deserialize(JsonNode jsonNode, Class type) { try { @@ -151,23 +152,21 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu } } + /** + * Perform a read action within a callback that gets access to a session-bound + * {@link RestOperations} object. {@link HttpStatusCodeException} with + * {@link HttpStatus#NOT_FOUND} are translated to a {@literal null} response. + * + * @param callback must not be {@literal null}. + * @return can be {@literal null}. + */ @Nullable - private T doRead(String path, ParameterizedTypeReference typeReference) { + T doRead(Function> callback) { - return doRead((restOperations, httpEntity) -> { - return restOperations.exchange(path, HttpMethod.GET, httpEntity, - typeReference); - }); - } - - @Nullable - private T doRead( - BiFunction, ResponseEntity> callback) { - - return doWithSession((restOperations, headers) -> { + return vaultOperations.doWithSession((restOperations) -> { try { - return callback.apply(restOperations, new HttpEntity<>(headers)) + return callback.apply(restOperations) .getBody(); } catch (HttpStatusCodeException e) { @@ -181,6 +180,13 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu }); } + /** + * Write the {@code body} to the given Vault {@code path}. + * + * @param path must not be {@literal null} or empty. + * @param body + * @return the response of this write action. + */ @Nullable VaultResponse doWrite(String path, Object body) { @@ -188,9 +194,9 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu try { - return doWithSession((restOperations, httpHeaders) -> { + return vaultOperations.doWithSession((restOperations) -> { return restOperations.exchange(path, HttpMethod.POST, - new HttpEntity<>(body, httpHeaders), VaultResponse.class) + new HttpEntity<>(body), VaultResponse.class) .getBody(); }); } @@ -199,25 +205,19 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu } } - @Nullable - T doWithSession(BiFunction callback) { + /** + * Return the {@link JsonNode} that contains the actual response body. + * + * @param response + * @return + */ + abstract JsonNode getJsonNode(VaultResponseSupport response); - return vaultOperations.doWithSession(restOperations -> { - - HttpHeaders headers = new HttpHeaders(); - headers.set("X-Vault-Kv-Client", "v2"); - - return callback.apply(restOperations, headers); - }); - } - - String createDataPath(String path) { - return createBackendPath("data", path); - } - - String createBackendPath(String segment, String path) { - return String.format("%s/%s/%s", this.path, segment, path); - } + /** + * @param path must not be {@literal null} or empty. + * @return backend path representing the data path. + */ + abstract String createDataPath(String path); private static ObjectMapper extractObjectMapper(VaultOperations vaultOperations) { @@ -231,7 +231,6 @@ public abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSu Optional jackson2Converter = template .getMessageConverters() .stream() - // .filter(AbstractJackson2HttpMessageConverter.class::isInstance) // .map(AbstractJackson2HttpMessageConverter.class::cast) // .findFirst(); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperations.java index 839c319b..cab3ff41 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperations.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperations.java @@ -31,6 +31,7 @@ import org.springframework.vault.support.VaultResponseSupport; * @author Mark Paluch * @since 2.1 * @see VaultVersionedKeyValueOperations + * @see KeyValueBackend */ public interface VaultKeyValueOperations extends VaultKeyValueOperationsSupport { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperationsSupport.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperationsSupport.java index c436134f..fced19b6 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperationsSupport.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultKeyValueOperationsSupport.java @@ -54,4 +54,39 @@ public interface VaultKeyValueOperationsSupport { * @param path must not be {@literal null}. */ void delete(String path); + + /** + * @return the used API version. + */ + KeyValueBackend getApiVersion(); + + /** + * Enumeration of supported Key/Value backend API versions. + */ + enum KeyValueBackend { + + /** + * Key/Value backend version 1 (unversioned). + */ + KV_1, + + /** + * K/V backend version 2 (versioned). + */ + KV_2; + + /** + * @return the K/V version 1 (unversioned). + */ + public static KeyValueBackend unversioned() { + return KV_1; + } + + /** + * @return the K/V version 2 (versioned). + */ + public static KeyValueBackend versioned() { + return KV_2; + } + } } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java index a520507a..1cfdb8c1 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultOperations.java @@ -19,6 +19,7 @@ import java.util.List; import org.springframework.lang.Nullable; import org.springframework.vault.VaultException; +import org.springframework.vault.core.VaultKeyValueOperationsSupport.KeyValueBackend; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultResponseSupport; import org.springframework.web.client.RestClientException; @@ -46,12 +47,12 @@ public interface VaultOperations { /** * Return {@link VaultKeyValueOperations}. * - * @param path the mount path - * @return the operations interface to interact with the Vault Key/Value (version 2) - * backend. + * @param path the mount path, must not be empty or {@literal null}. + * @param apiVersion API version to use, must not be {@literal null}. + * @return the operations interface to interact with the Vault Key/Value backend. * @since 2.1 */ - VaultKeyValueOperations opsForKeyValue(String path); + VaultKeyValueOperations opsForKeyValue(String path, KeyValueBackend apiVersion); /** * Return {@link VaultVersionedKeyValueOperations}. diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTemplate.java index d06e89a6..3f2ed254 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTemplate.java @@ -37,6 +37,7 @@ import org.springframework.vault.client.VaultEndpoint; import org.springframework.vault.client.VaultEndpointProvider; import org.springframework.vault.client.VaultHttpHeaders; import org.springframework.vault.client.VaultResponses; +import org.springframework.vault.core.VaultKeyValueOperationsSupport.KeyValueBackend; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultResponseSupport; import org.springframework.web.client.HttpStatusCodeException; @@ -206,8 +207,18 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa } @Override - public VaultKeyValueOperations opsForKeyValue(String path) { - return new VaultKeyValueTemplate(this, path); + public VaultKeyValueOperations opsForKeyValue(String path, KeyValueBackend apiVersion) { + + switch (apiVersion) { + case KV_1: + return new VaultKeyValue1Template(this, path); + case KV_2: + return new VaultKeyValue2Template(this, path); + } + + throw new UnsupportedOperationException(String.format( + "Key/Value backend version %s not supported", apiVersion)); + } @Override diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultVersionedKeyValueTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultVersionedKeyValueTemplate.java index 8e655818..bd31e432 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultVersionedKeyValueTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultVersionedKeyValueTemplate.java @@ -27,7 +27,6 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.databind.JsonNode; -import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.lang.Nullable; @@ -48,9 +47,11 @@ import org.springframework.web.client.HttpStatusCodeException; * @author Mark Paluch * @since 2.1 */ -public class VaultVersionedKeyValueTemplate extends VaultKeyValueAccessor implements +public class VaultVersionedKeyValueTemplate extends VaultKeyValue2Accessor implements VaultVersionedKeyValueOperations { + private final VaultOperations vaultOperations; + /** * Create a new {@link VaultVersionedKeyValueTemplate} given {@link VaultOperations} * and the mount {@code path}. @@ -59,7 +60,10 @@ public class VaultVersionedKeyValueTemplate extends VaultKeyValueAccessor implem * @param path must not be empty or {@literal null}. */ public VaultVersionedKeyValueTemplate(VaultOperations vaultOperations, String path) { + super(vaultOperations, path); + + this.vaultOperations = vaultOperations; } @Nullable @@ -90,11 +94,12 @@ public class VaultVersionedKeyValueTemplate extends VaultKeyValueAccessor implem String secretPath = version.isVersioned() ? String.format("%s?version=%d", createDataPath(path), version.getVersion()) : createDataPath(path); - VersionedResponse response = doWithSession((restOperations, httpHeaders) -> { + VersionedResponse response = vaultOperations.doWithSession(restOperations -> { try { return restOperations.exchange(secretPath, HttpMethod.GET, - new HttpEntity<>(httpHeaders), VersionedResponse.class).getBody(); + null, + VersionedResponse.class).getBody(); } catch (HttpStatusCodeException e) { diff --git a/spring-vault-core/src/test/java/org/springframework/vault/core/AbstractVaultKeyValueTemplateIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/core/AbstractVaultKeyValueTemplateIntegrationTests.java index 013e5ab3..9662892f 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/core/AbstractVaultKeyValueTemplateIntegrationTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/core/AbstractVaultKeyValueTemplateIntegrationTests.java @@ -24,6 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.vault.core.VaultKeyValueOperationsSupport.KeyValueBackend; import org.springframework.vault.util.IntegrationTestSupport; import org.springframework.vault.util.VaultRule; @@ -31,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assume.assumeTrue; /** - * Integration tests for {@link VaultKeyValueTemplate}. + * Integration tests for {@link VaultKeyValue2Template}. * * @author Mark Paluch */ @@ -39,13 +40,15 @@ public abstract class AbstractVaultKeyValueTemplateIntegrationTests extends IntegrationTestSupport { private final String path; + private final KeyValueBackend apiVersion; @Autowired VaultOperations vaultOperations; VaultKeyValueOperations kvOperations; - AbstractVaultKeyValueTemplateIntegrationTests(String path) { + AbstractVaultKeyValueTemplateIntegrationTests(String path, KeyValueBackend apiVersion) { this.path = path; + this.apiVersion = apiVersion; } @Before @@ -54,7 +57,12 @@ public abstract class AbstractVaultKeyValueTemplateIntegrationTests extends assumeTrue(prepare().getVersion().isGreaterThanOrEqualTo( VaultRule.VERSIONING_INTRODUCED_WITH)); - kvOperations = vaultOperations.opsForKeyValue(path); + kvOperations = vaultOperations.opsForKeyValue(path, apiVersion); + } + + @Test + public void shouldReportExpectedApiVersion() { + assertThat(kvOperations.getApiVersion()).isEqualTo(apiVersion); } @Test diff --git a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateIntegrationTests.java index e02da0de..d844538a 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateIntegrationTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateIntegrationTests.java @@ -23,13 +23,14 @@ import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.vault.core.VaultKeyValueOperationsSupport.KeyValueBackend; import org.springframework.vault.support.VaultResponse; import static org.assertj.core.api.Assertions.assertThat; /** - * Integration tests for {@link VaultKeyValueTemplate} using the non-versioned key-value - * backend. + * Integration tests for {@link VaultKeyValue2Template} using the non-versioned Key/Value + * (k/v version 1) backend. * * @author Mark Paluch */ @@ -39,7 +40,7 @@ public class VaultKeyValueTemplateIntegrationTests extends AbstractVaultKeyValueTemplateIntegrationTests { public VaultKeyValueTemplateIntegrationTests() { - super("secret"); + super("secret", KeyValueBackend.unversioned()); } @Test diff --git a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateVersionedIntegrationTests.java b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateVersionedIntegrationTests.java index 6f917e52..5091ef60 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateVersionedIntegrationTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/core/VaultKeyValueTemplateVersionedIntegrationTests.java @@ -19,10 +19,11 @@ import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.vault.core.VaultKeyValueOperationsSupport.KeyValueBackend; /** - * Integration tests for {@link VaultKeyValueTemplate} using the versioned key-value - * backend. + * Integration tests for {@link VaultKeyValue2Template} using the versioned Key/Value (k/v + * version 2) backend. * * @author Mark Paluch */ @@ -32,6 +33,6 @@ public class VaultKeyValueTemplateVersionedIntegrationTests extends AbstractVaultKeyValueTemplateIntegrationTests { public VaultKeyValueTemplateVersionedIntegrationTests() { - super("versioned"); + super("versioned", KeyValueBackend.versioned()); } }