From 18c78059a755a42cf0c48ad8a7dca5431fbe0fdc Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 11 Jul 2017 11:33:47 +0200 Subject: [PATCH] Add NonNullApi/Nullable annotations to indicate null-safety. See gh-112. --- .../VaultPropertySourceRegistrar.java | 3 +- .../vault/annotation/package-info.java | 3 + .../authentication/AppIdAuthentication.java | 3 + .../authentication/AppRoleAuthentication.java | 7 +- .../AppRoleAuthenticationOptions.java | 8 +- .../authentication/AuthenticationSteps.java | 18 +++- .../AuthenticationStepsExecutor.java | 8 +- .../AuthenticationStepsOperator.java | 4 + .../authentication/AwsEc2Authentication.java | 3 + .../AwsEc2AuthenticationOptions.java | 10 ++- .../ClientCertificateAuthentication.java | 2 + .../CubbyholeAuthentication.java | 11 ++- .../CubbyholeAuthenticationOptions.java | 7 +- .../LifecycleAwareSessionManager.java | 6 +- .../authentication/LoginTokenAdapter.java | 5 +- .../vault/authentication/LoginTokenUtil.java | 8 +- .../vault/authentication/package-info.java | 2 + .../vault/client/VaultClients.java | 3 +- .../vault/client/package-info.java | 2 + .../vault/core/ReactiveVaultOperations.java | 6 +- .../vault/core/ReactiveVaultTemplate.java | 9 +- .../vault/core/RestOperationsCallback.java | 4 +- .../vault/core/VaultOperations.java | 11 ++- .../vault/core/VaultPkiTemplate.java | 36 ++++---- .../vault/core/VaultSysTemplate.java | 83 +++++++++++-------- .../vault/core/VaultTemplate.java | 53 ++++++------ .../vault/core/VaultTokenTemplate.java | 44 ++++++++-- .../vault/core/VaultTransitOperations.java | 14 +++- .../vault/core/VaultTransitTemplate.java | 52 +++++++----- .../vault/core/env/VaultPropertySource.java | 2 + .../vault/core/env/package-info.java | 2 + .../core/lease/SecretLeaseContainer.java | 21 ++++- .../core/lease/SecretLeaseEventPublisher.java | 4 +- .../vault/core/lease/domain/Lease.java | 7 +- .../vault/core/lease/domain/package-info.java | 2 + .../lease/event/SecretLeaseErrorEvent.java | 5 +- .../core/lease/event/SecretLeaseEvent.java | 5 +- .../vault/core/lease/event/package-info.java | 2 + .../vault/core/lease/package-info.java | 2 + .../vault/core/package-info.java | 2 + .../vault/core/util/package-info.java | 6 +- .../springframework/vault/package-info.java | 2 + .../springframework/vault/support/Base64.java | 2 +- .../vault/support/JsonMapFlattener.java | 3 +- .../vault/support/SslConfiguration.java | 67 ++++++++------- .../support/VaultCertificateRequest.java | 13 ++- .../vault/support/VaultHealth.java | 3 + .../vault/support/VaultMount.java | 20 ++++- .../vault/support/VaultResponseSupport.java | 61 +++++++++++--- .../vault/support/VaultTokenRequest.java | 33 +++++++- .../vault/support/VaultTokenResponse.java | 2 +- .../vault/support/VaultTransitContext.java | 14 +++- .../support/VaultTransitKeyConfiguration.java | 13 ++- .../VaultTransitKeyCreationRequest.java | 16 +++- .../vault/support/package-info.java | 6 +- 55 files changed, 527 insertions(+), 213 deletions(-) diff --git a/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java b/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java index d05df632..1a43c069 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java @@ -34,6 +34,7 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import org.springframework.core.type.AnnotationMetadata; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.vault.annotation.VaultPropertySource.Renewal; @@ -197,7 +198,7 @@ class VaultPropertySourceRegistrar implements ImportBeanDefinitionRegistrar, } private static void addAttributesIfNotNull(Set result, - Map attributes) { + @Nullable Map attributes) { if (attributes != null) { result.add(AnnotationAttributes.fromMap(attributes)); } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java index 5a5491c9..ddace64e 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java @@ -1,5 +1,8 @@ /** * Annotation support for the Spring Vault. */ +@NonNullApi package org.springframework.vault.annotation; +import org.springframework.lang.NonNullApi; + diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java index 6c36c6b7..5d092559 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppIdAuthentication.java @@ -104,6 +104,9 @@ public class AppIdAuthentication implements ClientAuthentication, VaultResponse response = restOperations.postForObject("auth/{mount}/login", login, VaultResponse.class, options.getPath()); + Assert.state(response != null && response.getAuth() != null, + "Auth field must not be null"); + logger.debug("Login successful using AppId authentication"); return LoginTokenUtil.from(response.getAuth()); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java index 8e35b64a..2da3832b 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java @@ -21,6 +21,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.VaultException; import org.springframework.vault.client.VaultResponses; @@ -105,6 +106,9 @@ public class AppRoleAuthentication implements ClientAuthentication, VaultResponse response = restOperations.postForObject("auth/{mount}/login", login, VaultResponse.class, options.getPath()); + Assert.state(response != null && response.getAuth() != null, + "Auth field must not be null"); + logger.debug("Login successful using AppRole authentication"); return LoginTokenUtil.from(response.getAuth()); @@ -115,7 +119,8 @@ public class AppRoleAuthentication implements ClientAuthentication, } } - private static Map getAppRoleLogin(String roleId, String secretId) { + private static Map getAppRoleLogin(String roleId, + @Nullable String secretId) { Map login = new HashMap<>(); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java index 7cddebb9..5f52fbcc 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java @@ -15,6 +15,7 @@ */ package org.springframework.vault.authentication; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -45,9 +46,11 @@ public class AppRoleAuthenticationOptions { /** * The Bind SecretId. */ + @Nullable private final String secretId; - private AppRoleAuthenticationOptions(String path, String roleId, String secretId) { + private AppRoleAuthenticationOptions(String path, String roleId, + @Nullable String secretId) { this.path = path; this.roleId = roleId; @@ -78,6 +81,7 @@ public class AppRoleAuthenticationOptions { /** * @return the bound SecretId. */ + @Nullable public String getSecretId() { return secretId; } @@ -89,8 +93,10 @@ public class AppRoleAuthenticationOptions { private String path = DEFAULT_APPROLE_AUTHENTICATION_PATH; + @Nullable private String roleId; + @Nullable private String secretId; AppRoleAuthenticationOptionsBuilder() { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java index b2644032..41e76143 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java @@ -35,6 +35,7 @@ import lombok.experimental.FieldDefaults; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultToken; @@ -270,12 +271,16 @@ public class AuthenticationSteps { HttpMethod method; + @Nullable URI uri; + @Nullable String uriTemplate; + @Nullable String[] urlVariables; + @Nullable HttpEntity entity; /** @@ -325,15 +330,16 @@ public class AuthenticationSteps { this.uri = uri; } - private HttpRequestBuilder(HttpMethod method, String uriTemplate, - String[] urlVariables) { + private HttpRequestBuilder(HttpMethod method, @Nullable String uriTemplate, + @Nullable String[] urlVariables) { this.method = method; this.uriTemplate = uriTemplate; this.urlVariables = urlVariables; } - private HttpRequestBuilder(HttpMethod method, URI uri, String uriTemplate, - String[] urlVariables, HttpEntity entity) { + private HttpRequestBuilder(HttpMethod method, @Nullable URI uri, + @Nullable String uriTemplate, @Nullable String[] urlVariables, + @Nullable HttpEntity entity) { this.method = method; this.uri = uri; this.uriTemplate = uriTemplate; @@ -393,12 +399,16 @@ public class AuthenticationSteps { HttpMethod method; + @Nullable URI uri; + @Nullable String uriTemplate; + @Nullable String[] urlVariables; + @Nullable HttpEntity entity; Class responseType; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java index 279e94ff..018b9db2 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.VaultException; import org.springframework.vault.authentication.AuthenticationSteps.HttpRequest; @@ -121,6 +122,7 @@ public class AuthenticationStepsExecutor implements ClientAuthentication { if (state instanceof VaultResponse) { VaultResponse response = (VaultResponse) state; + Assert.state(response.getAuth() != null, "Auth field must not be null"); return LoginTokenUtil.from(response.getAuth()); } @@ -141,7 +143,9 @@ public class AuthenticationStepsExecutor implements ClientAuthentication { return o.apply(state); } - private Object doHttpRequest(HttpRequestNode step, Object state) { + @SuppressWarnings("ConstantConditions") + @Nullable + private Object doHttpRequest(HttpRequestNode step, @Nullable Object state) { HttpRequest definition = step.getDefinition(); @@ -163,7 +167,7 @@ public class AuthenticationStepsExecutor implements ClientAuthentication { } - private static HttpEntity getEntity(HttpEntity entity, Object state) { + private static HttpEntity getEntity(HttpEntity entity, @Nullable Object state) { if (entity == null) { return state == null ? HttpEntity.EMPTY : new HttpEntity<>(state); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java index c19b91a8..3ec02e39 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java @@ -120,6 +120,10 @@ public class AuthenticationStepsOperator implements VaultTokenSupplier { if (stateObject instanceof VaultResponse) { VaultResponse response = (VaultResponse) stateObject; + + Assert.state(response.getAuth() != null, + "Auth field must not be null"); + return LoginTokenUtil.from(response.getAuth()); } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2Authentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2Authentication.java index 15f9b66c..e8cb5ad0 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2Authentication.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2Authentication.java @@ -163,6 +163,9 @@ public class AwsEc2Authentication implements ClientAuthentication, VaultResponse response = this.vaultRestOperations.postForObject( "auth/{mount}/login", login, VaultResponse.class, options.getPath()); + Assert.state(response != null && response.getAuth() != null, + "Auth field must not be null"); + if (logger.isDebugEnabled()) { if (response.getAuth().get("metadata") instanceof Map) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2AuthenticationOptions.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2AuthenticationOptions.java index f26abf1e..c3693863 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2AuthenticationOptions.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AwsEc2AuthenticationOptions.java @@ -19,6 +19,7 @@ import java.net.URI; import java.util.Arrays; import java.util.UUID; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -59,6 +60,7 @@ public class AwsEc2AuthenticationOptions { /** * EC2 instance role name. May be {@literal null} if none. */ + @Nullable private final String role; /** @@ -72,7 +74,7 @@ public class AwsEc2AuthenticationOptions { } private AwsEc2AuthenticationOptions(String path, URI identityDocumentUri, - String role, Nonce nonce) { + @Nullable String role, Nonce nonce) { this.path = path; this.identityDocumentUri = identityDocumentUri; @@ -104,6 +106,7 @@ public class AwsEc2AuthenticationOptions { /** * @return the role, may be {@literal null} if none. */ + @Nullable public String getRole() { return role; } @@ -122,7 +125,10 @@ public class AwsEc2AuthenticationOptions { private String path = DEFAULT_AWS_AUTHENTICATION_PATH; private URI identityDocumentUri = DEFAULT_PKCS7_IDENTITY_DOCUMENT_URI; + + @Nullable private String role; + private Nonce nonce = Nonce.generated(); AwsEc2AuthenticationOptionsBuilder() { @@ -164,7 +170,7 @@ public class AwsEc2AuthenticationOptions { * @param role may be empty or {@literal null}. * @return {@code this} {@link AwsEc2AuthenticationOptionsBuilder}. */ - public AwsEc2AuthenticationOptionsBuilder role(String role) { + public AwsEc2AuthenticationOptionsBuilder role(@Nullable String role) { this.role = role; return this; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/ClientCertificateAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/ClientCertificateAuthentication.java index f3cd7861..7bec18ce 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/ClientCertificateAuthentication.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/ClientCertificateAuthentication.java @@ -81,6 +81,8 @@ public class ClientCertificateAuthentication implements ClientAuthentication, VaultResponse response = restOperations.postForObject("auth/{mount}/login", Collections.emptyMap(), VaultResponse.class, path); + Assert.state(response.getAuth() != null, "Auth field must not be null"); + logger.debug("Login successful using TLS certificates"); return LoginTokenUtil.from(response.getAuth()); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthentication.java index a651d5d1..b0e1a8a8 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthentication.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthentication.java @@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.VaultException; import org.springframework.vault.authentication.AuthenticationSteps.HttpRequest; @@ -207,6 +208,7 @@ public class CubbyholeAuthentication implements ClientAuthentication, return createAuthenticationSteps(options); } + @Nullable private Map lookupToken() { try { @@ -216,6 +218,8 @@ public class CubbyholeAuthentication implements ClientAuthentication, new HttpEntity<>(VaultHttpHeaders.from(options.getInitialToken())), VaultResponse.class); + Assert.state(entity.getBody() != null, "Auth response must not be null"); + return entity.getBody().getData(); } catch (HttpStatusCodeException e) { @@ -244,12 +248,17 @@ public class CubbyholeAuthentication implements ClientAuthentication, } private static VaultToken getToken(CubbyholeAuthenticationOptions options, - Map data) { + @Nullable Map data) { if (options.isWrappedToken()) { + Assert.state(data != null, "Auth data must not be null"); + VaultResponse response = VaultResponses.unwrap((String) data.get("response"), VaultResponse.class); + + Assert.state(response.getAuth() != null, "Auth field must not be null"); + return LoginTokenUtil.from(response.getAuth()); } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthenticationOptions.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthenticationOptions.java index 40831a2b..ae6a9209 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthenticationOptions.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/CubbyholeAuthenticationOptions.java @@ -15,6 +15,7 @@ */ package org.springframework.vault.authentication; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.support.VaultToken; @@ -106,8 +107,10 @@ public class CubbyholeAuthenticationOptions { */ public static class CubbyholeAuthenticationOptionsBuilder { + @Nullable private VaultToken initialToken; + @Nullable private String path; private boolean wrappedToken; @@ -123,8 +126,7 @@ public class CubbyholeAuthenticationOptions { * @param initialToken must not be {@literal null}. * @return {@code this} {@link CubbyholeAuthenticationOptionsBuilder}. */ - public CubbyholeAuthenticationOptionsBuilder initialToken( - VaultToken initialToken) { + public CubbyholeAuthenticationOptionsBuilder initialToken(VaultToken initialToken) { Assert.notNull(initialToken, "Initial Vault Token must not be null"); @@ -183,6 +185,7 @@ public class CubbyholeAuthenticationOptions { public CubbyholeAuthenticationOptions build() { Assert.notNull(initialToken, "Initial Vault Token must not be null"); + Assert.notNull(path, "Path must not be null"); return new CubbyholeAuthenticationOptions(initialToken, path, wrappedToken, selfLookup); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java index 117841b9..d3fa5e40 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LifecycleAwareSessionManager.java @@ -175,7 +175,7 @@ public class LifecycleAwareSessionManager implements SessionManager, DisposableB logger.debug(String .format("Cannot refresh token, resetting token and performing re-login: %s", VaultResponses.getError(e.getResponseBodyAsString()))); - token = null; + token = Optional.empty(); return false; } @@ -194,7 +194,7 @@ public class LifecycleAwareSessionManager implements SessionManager, DisposableB synchronized (lock) { if (!token.isPresent()) { - token = Optional.ofNullable(clientAuthentication.login()); + token = Optional.of(clientAuthentication.login()); if (isTokenRenewable()) { scheduleRenewal(); @@ -230,7 +230,7 @@ public class LifecycleAwareSessionManager implements SessionManager, DisposableB @Override public void run() { try { - if (LifecycleAwareSessionManager.this.token != null + if (LifecycleAwareSessionManager.this.token.isPresent() && isTokenRenewable()) { if (renewToken()) { scheduleRenewal(); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenAdapter.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenAdapter.java index 9794a22b..db0b1487 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenAdapter.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenAdapter.java @@ -86,9 +86,12 @@ public class LoginTokenAdapter implements ClientAuthentication { try { ResponseEntity entity = restOperations.exchange( - "auth/token/lookup-self", HttpMethod.GET, new HttpEntity( + "auth/token/lookup-self", HttpMethod.GET, new HttpEntity<>( VaultHttpHeaders.from(token)), VaultResponse.class); + Assert.state(entity.getBody() != null && entity.getBody().getData() != null, + "Token response is null"); + return entity.getBody().getData(); } catch (HttpStatusCodeException e) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenUtil.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenUtil.java index 71e1900e..144676b8 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenUtil.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/LoginTokenUtil.java @@ -19,9 +19,11 @@ import java.util.Map; import lombok.experimental.UtilityClass; +import org.springframework.util.Assert; + /** * Utility class for {@link LoginToken}. - * + * * @author Mark Paluch */ @UtilityClass @@ -29,12 +31,14 @@ class LoginTokenUtil { /** * Construct a {@link LoginToken} from an auth response. - * + * * @param auth {@link Map} holding a login response. * @return the {@link LoginToken} */ static LoginToken from(Map auth) { + Assert.notNull(auth, "Authentication must not be null"); + String token = (String) auth.get("client_token"); Boolean renewable = (Boolean) auth.get("renewable"); Number leaseDuration = (Number) auth.get("lease_duration"); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/package-info.java index 2e78086a..09894b5d 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/package-info.java @@ -1,5 +1,7 @@ /** * Support for authentication and session management. */ +@NonNullApi package org.springframework.vault.authentication; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/client/VaultClients.java b/spring-vault-core/src/main/java/org/springframework/vault/client/VaultClients.java index 63b8c828..21478e8b 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/client/VaultClients.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/client/VaultClients.java @@ -26,6 +26,7 @@ import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.lang.Nullable; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.DefaultUriBuilderFactory; import org.springframework.web.util.DefaultUriTemplateHandler; @@ -159,7 +160,7 @@ public class VaultClients { * @param uriTemplate * @return */ - static String prepareUriTemplate(String baseUrl, String uriTemplate) { + static String prepareUriTemplate(@Nullable String baseUrl, String uriTemplate) { if (baseUrl != null) { if (uriTemplate.startsWith("/") && baseUrl.endsWith("/")) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/client/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/client/package-info.java index fa2c3af7..a028b4ca 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/client/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/client/package-info.java @@ -1,5 +1,7 @@ /** * Spring Vault Client abstraction. */ +@NonNullApi package org.springframework.vault.client; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultOperations.java index b2f8771a..324726d1 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultOperations.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultOperations.java @@ -52,7 +52,7 @@ public interface ReactiveVaultOperations { * backends that do not require a request body. * * @param path must not be {@literal null}. - * @return the data. May be {@literal null} if the path does not exist. + * @return the data. May be empty if the path does not exist. */ Mono read(String path); @@ -62,7 +62,7 @@ public interface ReactiveVaultOperations { * * @param path must not be {@literal null}. * @param responseType must not be {@literal null}. - * @return the data. May be {@literal null} if the path does not exist. + * @return the data. May be empty if the path does not exist. */ Mono> read(String path, Class responseType); @@ -70,7 +70,7 @@ public interface ReactiveVaultOperations { * Enumerate keys from a secret backend. * * @param path must not be {@literal null}. - * @return the data. May be {@literal null} if the path does not exist. + * @return the data. May be empty if the path does not exist. */ Flux list(String path); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultTemplate.java index 2041e0b2..5703720e 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/ReactiveVaultTemplate.java @@ -117,11 +117,12 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations { String.format("%s?list=true", path.endsWith("/") ? path : (path + "/")), VaultListResponse.class); - return read.filter( - response -> response.getData() != null - && response.getData().containsKey("keys")) // + return read + .filter(response -> response.getData() != null + && response.getData().containsKey("keys")) + // .flatMapIterable( - response -> (List) response.getData().get("keys")); + response -> (List) response.getRequiredData().get("keys")); } @Override diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/RestOperationsCallback.java b/spring-vault-core/src/main/java/org/springframework/vault/core/RestOperationsCallback.java index e0dcf44f..d3dc5ede 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/RestOperationsCallback.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/RestOperationsCallback.java @@ -15,6 +15,7 @@ */ package org.springframework.vault.core; +import org.springframework.lang.Nullable; import org.springframework.web.client.RestOperations; /** @@ -30,5 +31,6 @@ public interface RestOperationsCallback { * @param restOperations restOperations to use, must not be {@literal null}. * @return a result object or null if none. */ + @Nullable T doWithRestOperations(RestOperations restOperations); -} \ No newline at end of file +} 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 21dd9c1e..8bcb4427 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 @@ -17,6 +17,7 @@ package org.springframework.vault.core; import java.util.List; +import org.springframework.lang.Nullable; import org.springframework.vault.VaultException; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultResponseSupport; @@ -87,6 +88,7 @@ public interface VaultOperations { * @param path must not be {@literal null}. * @return the data. May be {@literal null} if the path does not exist. */ + @Nullable VaultResponse read(String path); /** @@ -97,6 +99,7 @@ public interface VaultOperations { * @param responseType must not be {@literal null}. * @return the data. May be {@literal null} if the path does not exist. */ + @Nullable VaultResponseSupport read(String path, Class responseType); /** @@ -105,6 +108,7 @@ public interface VaultOperations { * @param path must not be {@literal null}. * @return the data. May be {@literal null} if the path does not exist. */ + @Nullable List list(String path); /** @@ -112,9 +116,10 @@ public interface VaultOperations { * * @param path must not be {@literal null}. * @param body the body, may be {@literal null} if absent. - * @return the configuration data. May be empty but never {@literal null}. + * @return the configuration data. May be {@literal null}. */ - VaultResponse write(String path, Object body); + @Nullable + VaultResponse write(String path, @Nullable Object body); /** * Delete a path in the secret backend. @@ -135,6 +140,7 @@ public interface VaultOperations { * @throws RestClientException exceptions from * {@link org.springframework.web.client.RestOperations}. */ + @Nullable T doWithVault(RestOperationsCallback clientCallback) throws VaultException, RestClientException; @@ -149,6 +155,7 @@ public interface VaultOperations { * @throws RestClientException exceptions from * {@link org.springframework.web.client.RestOperations}. */ + @Nullable T doWithSession(RestOperationsCallback sessionCallback) throws VaultException, RestClientException; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java index 3b9e6a09..f7c5a2d1 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultPkiTemplate.java @@ -64,13 +64,17 @@ public class VaultPkiTemplate implements VaultPkiOperations { request.put("common_name", certificateRequest.getCommonName()); if (!certificateRequest.getAltNames().isEmpty()) { - request.put("alt_names", StringUtils - .collectionToDelimitedString(certificateRequest.getAltNames(), ",")); + request.put( + "alt_names", + StringUtils.collectionToDelimitedString( + certificateRequest.getAltNames(), ",")); } if (!certificateRequest.getIpSubjectAltNames().isEmpty()) { - request.put("ip_sans", StringUtils.collectionToDelimitedString( - certificateRequest.getIpSubjectAltNames(), ",")); + request.put( + "ip_sans", + StringUtils.collectionToDelimitedString( + certificateRequest.getIpSubjectAltNames(), ",")); } if (certificateRequest.getTtl() != null) { @@ -83,16 +87,20 @@ public class VaultPkiTemplate implements VaultPkiOperations { request.put("exclude_cn_from_sans", true); } - return vaultOperations.doWithSession(restOperations -> { + VaultCertificateResponse response = vaultOperations + .doWithSession(restOperations -> { - try { - return restOperations.postForObject("{path}/issue/{roleName}", request, - VaultCertificateResponse.class, path, roleName); - } - catch (HttpStatusCodeException e) { - throw VaultResponses.buildException(e); - } - }); + try { + return restOperations.postForObject("{path}/issue/{roleName}", + request, VaultCertificateResponse.class, path, roleName); + } + catch (HttpStatusCodeException e) { + throw VaultResponses.buildException(e); + } + }); + + Assert.state(response != null, "VaultCertificateResponse must not be null"); + + return response; } - } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultSysTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultSysTemplate.java index 4863fe8d..190046e0 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultSysTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultSysTemplate.java @@ -32,6 +32,7 @@ import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.VaultException; import org.springframework.vault.client.VaultResponses; @@ -77,20 +78,23 @@ public class VaultSysTemplate implements VaultSysOperations { } @Override + @SuppressWarnings("unchecked") public boolean isInitialized() { - return vaultOperations.doWithVault(restOperations -> { + return requireResponse(vaultOperations.doWithVault(restOperations -> { try { Map body = restOperations.getForObject("sys/init", Map.class); + Assert.state(body != null, "Initialization response must not be null"); + return body.get("initialized"); } catch (HttpStatusCodeException e) { throw VaultResponses.buildException(e); } - }); + })); } @Override @@ -99,23 +103,23 @@ public class VaultSysTemplate implements VaultSysOperations { Assert.notNull(vaultInitializationRequest, "VaultInitialization must not be null"); - return vaultOperations - .doWithVault( - (RestOperationsCallback) restOperations -> { + return requireResponse(vaultOperations.doWithVault(restOperations -> { - try { - ResponseEntity exchange = restOperations - .exchange("sys/init", HttpMethod.PUT, - new HttpEntity( - vaultInitializationRequest), - VaultInitializationResponseImpl.class); + try { + ResponseEntity exchange = restOperations + .exchange("sys/init", HttpMethod.PUT, new HttpEntity( + vaultInitializationRequest), + VaultInitializationResponseImpl.class); - return exchange.getBody(); - } - catch (HttpStatusCodeException e) { - throw VaultResponses.buildException(e); - } - }); + Assert.state(exchange.getBody() != null, + "Initialization response must not be null"); + + return exchange.getBody(); + } + catch (HttpStatusCodeException e) { + throw VaultResponses.buildException(e); + } + })); } @Override @@ -126,23 +130,22 @@ public class VaultSysTemplate implements VaultSysOperations { @Override public VaultUnsealStatus unseal(final String keyShare) { - return vaultOperations - .doWithVault( - (RestOperationsCallback) restOperations -> { + return requireResponse(vaultOperations.doWithVault(restOperations -> { - ResponseEntity response = restOperations - .exchange("sys/unseal", HttpMethod.PUT, - new HttpEntity(Collections - .singletonMap("key", keyShare)), - VaultUnsealStatusImpl.class); + ResponseEntity response = restOperations.exchange( + "sys/unseal", HttpMethod.PUT, + new HttpEntity(Collections.singletonMap("key", keyShare)), + VaultUnsealStatusImpl.class); - return response.getBody(); - }); + Assert.state(response.getBody() != null, "Unseal response must not be null"); + + return response.getBody(); + })); } @Override public VaultUnsealStatus getUnsealStatus() { - return vaultOperations.doWithVault(GET_UNSEAL_STATUS); + return requireResponse(vaultOperations.doWithVault(GET_UNSEAL_STATUS)); } @Override @@ -156,7 +159,7 @@ public class VaultSysTemplate implements VaultSysOperations { @Override public Map getMounts() { - return vaultOperations.doWithSession(GET_MOUNTS); + return requireResponse(vaultOperations.doWithSession(GET_MOUNTS)); } @Override @@ -179,7 +182,7 @@ public class VaultSysTemplate implements VaultSysOperations { @Override public Map getAuthMounts() throws VaultException { - return vaultOperations.doWithSession(GET_AUTH_MOUNTS); + return requireResponse(vaultOperations.doWithSession(GET_AUTH_MOUNTS)); } @Override @@ -192,7 +195,14 @@ public class VaultSysTemplate implements VaultSysOperations { @Override public VaultHealth health() { - return vaultOperations.doWithVault(HEALTH); + return requireResponse(vaultOperations.doWithVault(HEALTH)); + } + + private static T requireResponse(@Nullable T response) { + + Assert.state(response != null, "Response must not be null"); + + return response; } private static class GetUnsealStatus implements @@ -231,11 +241,12 @@ public class VaultSysTemplate implements VaultSysOperations { public Map doWithRestOperations(RestOperations restOperations) { ResponseEntity exchange = restOperations.exchange(path, - HttpMethod.GET, null, MOUNT_TYPE_REF, - Collections.emptyMap()); + HttpMethod.GET, null, MOUNT_TYPE_REF, Collections.emptyMap()); VaultMountsResponse body = exchange.getBody(); + Assert.state(body != null, "Get mounts response must not be null"); + if (body.getData() != null) { return body.getData(); } @@ -306,7 +317,7 @@ public class VaultSysTemplate implements VaultSysOperations { private List keys = new ArrayList<>(); @JsonProperty("root_token") - private String rootToken; + private String rootToken = ""; public VaultToken getRootToken() { return VaultToken.of(rootToken); @@ -335,13 +346,15 @@ public class VaultSysTemplate implements VaultSysOperations { private final boolean sealed; private final boolean standby; private final int serverTimeUtc; + + @Nullable private final String version; private VaultHealthImpl(@JsonProperty("initialized") boolean initialized, @JsonProperty("sealed") boolean sealed, @JsonProperty("standby") boolean standby, @JsonProperty("server_time_utc") int serverTimeUtc, - @JsonProperty("version") String version) { + @Nullable @JsonProperty("version") String version) { this.initialized = initialized; this.sealed = sealed; 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 b2474c4b..e5672633 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 @@ -27,6 +27,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.authentication.ClientAuthentication; import org.springframework.vault.authentication.SessionManager; @@ -38,7 +39,6 @@ import org.springframework.vault.client.VaultResponses; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultResponseSupport; import org.springframework.web.client.HttpStatusCodeException; -import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; /** @@ -50,22 +50,15 @@ import org.springframework.web.client.RestTemplate; */ public class VaultTemplate implements InitializingBean, VaultOperations, DisposableBean { + private final RestTemplate sessionTemplate; + + private final RestTemplate plainTemplate; + + @Nullable private SessionManager sessionManager; - private RestTemplate sessionTemplate; - - private RestTemplate plainTemplate; - private final boolean dedicatedSessionManager; - /** - * Create a new {@link VaultTemplate} without setting {@link RestOperations} and - * {@link SessionManager}. - */ - public VaultTemplate() { - this.dedicatedSessionManager = false; - } - /** * Create a new {@link VaultTemplate} with a {@link VaultEndpoint} and * {@link ClientAuthentication}. @@ -121,13 +114,16 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa RestTemplate restTemplate = VaultClients.createRestTemplate(endpoint, requestFactory); - restTemplate.getInterceptors().add((request, body, execution) -> { + restTemplate.getInterceptors().add( + (request, body, execution) -> { - request.getHeaders().add(VaultHttpHeaders.VAULT_TOKEN, - sessionManager.getSessionToken().getToken()); + Assert.notNull(sessionManager, "SessionManager must not be null"); - return execution.execute(request, body); - }); + request.getHeaders().add(VaultHttpHeaders.VAULT_TOKEN, + sessionManager.getSessionToken().getToken()); + + return execution.execute(request, body); + }); return restTemplate; } @@ -146,7 +142,6 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa @Override public void afterPropertiesSet() { - Assert.notNull(sessionManager, "SessionManager must not be null"); } @@ -198,15 +193,15 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa @SuppressWarnings("unchecked") @Override - public VaultResponseSupport read(final String path, - final Class responseType) { + @Nullable + public VaultResponseSupport read(final String path, final Class responseType) { final ParameterizedTypeReference> ref = VaultResponses .getTypeReference(responseType); try { - ResponseEntity> exchange = sessionTemplate - .exchange(path, HttpMethod.GET, null, ref); + ResponseEntity> exchange = sessionTemplate.exchange( + path, HttpMethod.GET, null, ref); return exchange.getBody(); } @@ -221,6 +216,8 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa } @Override + @SuppressWarnings("unchecked") + @Nullable public List list(String path) { Assert.hasText(path, "Path must not be empty"); @@ -232,11 +229,12 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa return Collections.emptyList(); } - return (List) read.getData().get("keys"); + return (List) read.getRequiredData().get("keys"); } @Override - public VaultResponse write(final String path, final Object body) { + @Nullable + public VaultResponse write(String path, @Nullable Object body) { Assert.hasText(path, "Path must not be empty"); @@ -292,6 +290,7 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa } } + @Nullable private T doRead(final String path, final Class responseType) { return doWithSession(restOperations -> { @@ -310,7 +309,7 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa }); } - private static class VaultListResponse - extends VaultResponseSupport> { + private static class VaultListResponse extends + VaultResponseSupport> { } } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java index 8b4ce398..46a97963 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTokenTemplate.java @@ -18,6 +18,7 @@ package org.springframework.vault.core; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.client.VaultResponses; import org.springframework.vault.support.VaultResponseSupport; @@ -57,7 +58,7 @@ public class VaultTokenTemplate implements VaultTokenOperations { Assert.notNull(request, "VaultTokenRequest must not be null"); - return write("auth/token/create", request, VaultTokenResponse.class); + return writeAndReturn("auth/token/create", request, VaultTokenResponse.class); } @Override @@ -70,7 +71,8 @@ public class VaultTokenTemplate implements VaultTokenOperations { Assert.notNull(request, "VaultTokenRequest must not be null"); - return write("auth/token/create-orphan", request, VaultTokenResponse.class); + return writeAndReturn("auth/token/create-orphan", request, + VaultTokenResponse.class); } @Override @@ -78,7 +80,8 @@ public class VaultTokenTemplate implements VaultTokenOperations { Assert.notNull(vaultToken, "VaultToken must not be null"); - return write(String.format("auth/token/renew/%s", vaultToken.getToken()), null, + return writeAndReturn( + String.format("auth/token/renew/%s", vaultToken.getToken()), null, VaultTokenResponse.class); } @@ -87,7 +90,7 @@ public class VaultTokenTemplate implements VaultTokenOperations { Assert.notNull(vaultToken, "VaultToken must not be null"); - write(String.format("auth/token/revoke/%s", vaultToken.getToken()), null, + write(String.format("auth/token/revoke/%s", vaultToken.getToken()), VaultTokenResponse.class); } @@ -96,19 +99,20 @@ public class VaultTokenTemplate implements VaultTokenOperations { Assert.notNull(vaultToken, "VaultToken must not be null"); - write(String.format("auth/token/revoke-orphan/%s", vaultToken.getToken()), null, + write(String.format("auth/token/revoke-orphan/%s", vaultToken.getToken()), VaultTokenResponse.class); } - public > T write(final String path, - final Object body, final Class responseType) { + private > T writeAndReturn(String path, + @Nullable Object body, Class responseType) { Assert.hasText(path, "Path must not be empty"); - return vaultOperations.doWithSession(restOperations -> { + T response = vaultOperations.doWithSession(restOperations -> { try { ResponseEntity exchange = restOperations.exchange(path, - HttpMethod.POST, new HttpEntity<>(body), responseType); + HttpMethod.POST, body == null ? HttpEntity.EMPTY + : new HttpEntity<>(body), responseType); return exchange.getBody(); } @@ -116,5 +120,27 @@ public class VaultTokenTemplate implements VaultTokenOperations { throw VaultResponses.buildException(e, path); } }); + + Assert.state(response != null, "Response must not be null"); + + return response; + } + + private void write(String path, Class responseType) { + + Assert.hasText(path, "Path must not be empty"); + + vaultOperations.doWithSession(restOperations -> { + + try { + restOperations.exchange(path, HttpMethod.POST, HttpEntity.EMPTY, + responseType); + } + catch (HttpStatusCodeException e) { + throw VaultResponses.buildException(e, path); + } + + return null; + }); } } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java index 41c5d51f..b17a4b32 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitOperations.java @@ -17,12 +17,13 @@ package org.springframework.vault.core; import java.util.List; +import org.springframework.lang.Nullable; +import org.springframework.vault.support.RawTransitKey; import org.springframework.vault.support.TransitKeyType; import org.springframework.vault.support.VaultTransitContext; import org.springframework.vault.support.VaultTransitKey; import org.springframework.vault.support.VaultTransitKeyConfiguration; import org.springframework.vault.support.VaultTransitKeyCreationRequest; -import org.springframework.vault.support.RawTransitKey; /** * Interface that specifies operations using the {@code transit} backend. @@ -75,6 +76,7 @@ public interface VaultTransitOperations { * @param type must not be {@literal null}. * @return the {@link RawTransitKey}. */ + @Nullable RawTransitKey exportKey(String keyName, TransitKeyType type); /** @@ -83,6 +85,7 @@ public interface VaultTransitOperations { * @param keyName must not be empty or {@literal null}. * @return the {@link VaultTransitKey}. */ + @Nullable VaultTransitKey getKey(String keyName); /** @@ -120,7 +123,8 @@ public interface VaultTransitOperations { * @param transitRequest may be {@literal null} if no request options provided. * @return cipher text. */ - String encrypt(String keyName, byte[] plaintext, VaultTransitContext transitRequest); + String encrypt(String keyName, byte[] plaintext, + @Nullable VaultTransitContext transitRequest); /** * Decrypts the provided plaintext using the named key. @@ -139,7 +143,8 @@ public interface VaultTransitOperations { * @param transitRequest may be {@literal null} if no request options provided. * @return plain text. */ - byte[] decrypt(String keyName, String ciphertext, VaultTransitContext transitRequest); + byte[] decrypt(String keyName, String ciphertext, + @Nullable VaultTransitContext transitRequest); /** * Rewrap the provided ciphertext using the latest version of the named key. Because @@ -164,5 +169,6 @@ public interface VaultTransitOperations { * @return cipher text. * @see #rotate(String) */ - String rewrap(String keyName, String ciphertext, VaultTransitContext transitRequest); + String rewrap(String keyName, String ciphertext, + @Nullable VaultTransitContext transitRequest); } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java index 94a87096..1e83f396 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/VaultTransitTemplate.java @@ -23,8 +23,10 @@ import java.util.Map; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.Base64Utils; +import org.springframework.vault.support.RawTransitKey; import org.springframework.vault.support.TransitKeyType; import org.springframework.vault.support.VaultResponse; import org.springframework.vault.support.VaultResponseSupport; @@ -32,7 +34,6 @@ import org.springframework.vault.support.VaultTransitContext; import org.springframework.vault.support.VaultTransitKey; import org.springframework.vault.support.VaultTransitKeyConfiguration; import org.springframework.vault.support.VaultTransitKeyCreationRequest; -import org.springframework.vault.support.RawTransitKey; /** * Default implementation of {@link VaultTransitOperations}. @@ -80,8 +81,8 @@ public class VaultTransitTemplate implements VaultTransitOperations { VaultResponse response = vaultOperations.read(String.format("%s/keys?list=true", path)); - return response == null ? Collections.emptyList() : (List) response.getData() - .get("keys"); + return response == null ? Collections.emptyList() : (List) response + .getRequiredData().get("keys"); } @Override @@ -95,6 +96,7 @@ public class VaultTransitTemplate implements VaultTransitOperations { } @Override + @Nullable public RawTransitKey exportKey(String keyName, TransitKeyType type) { Assert.hasText(keyName, "KeyName must not be empty"); @@ -104,10 +106,11 @@ public class VaultTransitTemplate implements VaultTransitOperations { String.format("%s/export/%s/%s", path, type.getValue(), keyName), RawTransitKeyImpl.class); - return result != null ? result.getData() : null; + return result != null ? result.getRequiredData() : null; } @Override + @Nullable public VaultTransitKey getKey(String keyName) { Assert.hasText(keyName, "KeyName must not be empty"); @@ -116,7 +119,7 @@ public class VaultTransitTemplate implements VaultTransitOperations { String.format("%s/keys/%s", path, keyName), VaultTransitKeyImpl.class); if (result != null) { - return result.getData(); + return result.getRequiredData(); } return null; @@ -149,13 +152,13 @@ public class VaultTransitTemplate implements VaultTransitOperations { request.put("plaintext", Base64Utils.encodeToString(plaintext.getBytes())); return (String) vaultOperations - .write(String.format("%s/encrypt/%s", path, keyName), request).getData() - .get("ciphertext"); + .write(String.format("%s/encrypt/%s", path, keyName), request) + .getRequiredData().get("ciphertext"); } @Override public String encrypt(String keyName, byte[] plaintext, - VaultTransitContext transitRequest) { + @Nullable VaultTransitContext transitRequest) { Assert.hasText(keyName, "KeyName must not be empty"); Assert.notNull(plaintext, "Plain text must not be null"); @@ -169,8 +172,8 @@ public class VaultTransitTemplate implements VaultTransitOperations { } return (String) vaultOperations - .write(String.format("%s/encrypt/%s", path, keyName), request).getData() - .get("ciphertext"); + .write(String.format("%s/encrypt/%s", path, keyName), request) + .getRequiredData().get("ciphertext"); } @Override @@ -184,15 +187,15 @@ public class VaultTransitTemplate implements VaultTransitOperations { request.put("ciphertext", ciphertext); String plaintext = (String) vaultOperations - .write(String.format("%s/decrypt/%s", path, keyName), request).getData() - .get("plaintext"); + .write(String.format("%s/decrypt/%s", path, keyName), request) + .getRequiredData().get("plaintext"); return new String(Base64Utils.decodeFromString(plaintext)); } @Override public byte[] decrypt(String keyName, String ciphertext, - VaultTransitContext transitRequest) { + @Nullable VaultTransitContext transitRequest) { Assert.hasText(keyName, "KeyName must not be empty"); Assert.hasText(keyName, "Cipher text must not be empty"); @@ -206,8 +209,8 @@ public class VaultTransitTemplate implements VaultTransitOperations { } String plaintext = (String) vaultOperations - .write(String.format("%s/decrypt/%s", path, keyName), request).getData() - .get("plaintext"); + .write(String.format("%s/decrypt/%s", path, keyName), request) + .getRequiredData().get("plaintext"); return Base64Utils.decodeFromString(plaintext); } @@ -222,13 +225,13 @@ public class VaultTransitTemplate implements VaultTransitOperations { request.put("ciphertext", ciphertext); return (String) vaultOperations - .write(String.format("%s/rewrap/%s", path, keyName), request).getData() - .get("ciphertext"); + .write(String.format("%s/rewrap/%s", path, keyName), request) + .getRequiredData().get("ciphertext"); } @Override public String rewrap(String keyName, String ciphertext, - VaultTransitContext transitRequest) { + @Nullable VaultTransitContext transitRequest) { Assert.hasText(keyName, "KeyName must not be empty"); Assert.hasText(ciphertext, "Cipher text must not be empty"); @@ -242,8 +245,8 @@ public class VaultTransitTemplate implements VaultTransitOperations { } return (String) vaultOperations - .write(String.format("%s/rewrap/%s", path, keyName), request).getData() - .get("ciphertext"); + .write(String.format("%s/rewrap/%s", path, keyName), request) + .getRequiredData().get("ciphertext"); } private void applyTransitOptions(VaultTransitContext transitRequest, @@ -263,9 +266,10 @@ public class VaultTransitTemplate implements VaultTransitOperations { static class VaultTransitKeyImpl implements VaultTransitKey { @JsonProperty("cipher_mode") - private String cipherMode; + private String cipherMode = ""; @JsonProperty("type") + @Nullable private String type; @JsonProperty("deletion_allowed") @@ -275,7 +279,7 @@ public class VaultTransitTemplate implements VaultTransitOperations { private boolean exportable; - private Map keys; + private Map keys = Collections.emptyMap(); @JsonProperty("latest_version") private boolean latestVersion; @@ -283,6 +287,7 @@ public class VaultTransitTemplate implements VaultTransitOperations { @JsonProperty("min_decryption_version") private int minDecryptionVersion; + @Nullable private String name; @Override @@ -299,8 +304,9 @@ public class VaultTransitTemplate implements VaultTransitOperations { @Data static class RawTransitKeyImpl implements RawTransitKey { - private Map keys; + private Map keys = Collections.emptyMap(); + @Nullable private String name; } } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/env/VaultPropertySource.java b/spring-vault-core/src/main/java/org/springframework/vault/core/env/VaultPropertySource.java index c3784feb..8d2fac2f 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/env/VaultPropertySource.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/env/VaultPropertySource.java @@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.PropertySource; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.VaultException; import org.springframework.vault.core.VaultOperations; @@ -152,6 +153,7 @@ public class VaultPropertySource extends EnumerablePropertySource doGetProperties(String path) throws VaultException { VaultResponse vaultResponse = this.source.read(path); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/env/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/core/env/package-info.java index 13066922..c52702ad 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/env/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/env/package-info.java @@ -1,5 +1,7 @@ /** * Spring Vault's environment abstraction consisting property source support. */ +@NonNullApi package org.springframework.vault.core.env; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java index fbff6cc6..ae8a307e 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseContainer.java @@ -38,6 +38,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; @@ -138,6 +139,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements private Duration expiryThreshold = Duration.ofSeconds(60); + @Nullable private TaskScheduler taskScheduler; private boolean manageTaskScheduler; @@ -304,6 +306,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements if (initialized) { + Assert.state(this.taskScheduler != null, "TaskScheduler must not be null"); + LeaseRenewalScheduler leaseRenewalScheduler = new LeaseRenewalScheduler( this.taskScheduler); this.renewals.put(requestedSecret, leaseRenewalScheduler); @@ -370,7 +374,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements } potentiallyScheduleLeaseRenewal(requestedSecret, lease, renewalScheduler); - onSecretsObtained(requestedSecret, lease, secrets.getData()); + onSecretsObtained(requestedSecret, lease, secrets.getRequiredData()); } } @@ -514,6 +518,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements * {@code path}. * @return the response. */ + @Nullable protected VaultResponseSupport> doGetSecrets( RequestedSecret requestedSecret) { @@ -566,11 +571,16 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements return Lease.none(); } + @SuppressWarnings("unchecked") private Lease renew(final Lease lease) { + ResponseEntity> entity = operations .doWithSession(restOperations -> (ResponseEntity) restOperations - .exchange("sys/renew/{leaseId}", HttpMethod.PUT, null, - Map.class, lease.getLeaseId())); + .exchange("sys/renew/{leaseId}", HttpMethod.PUT, null, Map.class, + lease.getLeaseId())); + + Assert.state(entity != null && entity.getBody() != null, + "Renew response must not be null"); Map body = entity.getBody(); String leaseId = (String) body.get("lease_id"); @@ -604,6 +614,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements * @param requestedSecret must not be {@literal null}. * @param lease must not be {@literal null}. */ + @SuppressWarnings("unchecked") protected void doRevokeLease(RequestedSecret requestedSecret, final Lease lease) { try { @@ -765,7 +776,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements .getSeconds() - expiryThreshold.getSeconds()); } - private boolean isLeaseRenewable(Lease lease, RequestedSecret requestedSecret) { + private boolean isLeaseRenewable(@Nullable Lease lease, + RequestedSecret requestedSecret) { if (lease == null) { return false; @@ -809,6 +821,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements } @Override + @Nullable public Date nextExecutionTime(TriggerContext triggerContext) { if (UPDATER.compareAndSet(this, STATUS_ARMED, STATUS_FIRED)) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseEventPublisher.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseEventPublisher.java index bdfcc5bd..437f4ff5 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseEventPublisher.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/SecretLeaseEventPublisher.java @@ -22,6 +22,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import lombok.extern.apachecommons.CommonsLog; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.vault.core.lease.domain.Lease; import org.springframework.vault.core.lease.domain.RequestedSecret; @@ -196,7 +197,8 @@ public class SecretLeaseEventPublisher implements InitializingBean { * @param lease may be {@literal null} * @param e the causing exception. */ - protected void onError(RequestedSecret requestedSecret, Lease lease, Exception e) { + protected void onError(RequestedSecret requestedSecret, @Nullable Lease lease, + Exception e) { for (LeaseErrorListener leaseErrorListener : leaseErrorListeners) { leaseErrorListener.onLeaseError(new SecretLeaseErrorEvent(requestedSecret, diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/Lease.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/Lease.java index f469e0e0..613547e7 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/Lease.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/Lease.java @@ -17,6 +17,7 @@ package org.springframework.vault.core.lease.domain; import java.time.Duration; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -29,13 +30,14 @@ public class Lease { private static final Lease NONE = new Lease(null, Duration.ZERO, false); + @Nullable private final String leaseId; private final Duration leaseDuration; private final boolean renewable; - private Lease(String leaseId, Duration leaseDuration, boolean renewable) { + private Lease(@Nullable String leaseId, Duration leaseDuration, boolean renewable) { this.leaseId = leaseId; this.leaseDuration = leaseDuration; @@ -131,6 +133,7 @@ public class Lease { /** * @return the lease Id */ + @Nullable public String getLeaseId() { return leaseId; } @@ -170,7 +173,7 @@ public class Lease { public int hashCode() { int result = leaseId != null ? leaseId.hashCode() : 0; - result = 31 * result + (leaseDuration != null ? leaseDuration.hashCode() : 0); + result = 31 * result + leaseDuration.hashCode(); result = 31 * result + (renewable ? 1 : 0); return result; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/package-info.java index 7c156995..da6289cf 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/domain/package-info.java @@ -1,5 +1,7 @@ /** * Lease domain classes. */ +@NonNullApi package org.springframework.vault.core.lease.domain; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseErrorEvent.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseErrorEvent.java index 7e10ebb8..dba80510 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseErrorEvent.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseErrorEvent.java @@ -15,6 +15,7 @@ */ package org.springframework.vault.core.lease.event; +import org.springframework.lang.Nullable; import org.springframework.vault.core.lease.domain.Lease; import org.springframework.vault.core.lease.domain.RequestedSecret; @@ -38,9 +39,11 @@ public class SecretLeaseErrorEvent extends SecretLeaseEvent { * @param lease can be {@literal null}. * @param exception must not be {@literal null}. */ - public SecretLeaseErrorEvent(RequestedSecret requestedSecret, Lease lease, + public SecretLeaseErrorEvent(RequestedSecret requestedSecret, @Nullable Lease lease, Throwable exception) { + super(requestedSecret, lease); + this.exception = exception; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseEvent.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseEvent.java index 9c59a9d2..013ff377 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseEvent.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/SecretLeaseEvent.java @@ -16,6 +16,7 @@ package org.springframework.vault.core.lease.event; import org.springframework.context.ApplicationEvent; +import org.springframework.lang.Nullable; import org.springframework.vault.core.lease.domain.Lease; import org.springframework.vault.core.lease.domain.RequestedSecret; @@ -32,6 +33,7 @@ public abstract class SecretLeaseEvent extends ApplicationEvent { private static final long serialVersionUID = 1L; + @Nullable private final Lease lease; /** @@ -41,7 +43,7 @@ public abstract class SecretLeaseEvent extends ApplicationEvent { * @param requestedSecret must not be {@literal null}. * @param lease can be {@literal null}. */ - protected SecretLeaseEvent(RequestedSecret requestedSecret, Lease lease) { + protected SecretLeaseEvent(RequestedSecret requestedSecret, @Nullable Lease lease) { super(requestedSecret); this.lease = lease; @@ -52,6 +54,7 @@ public abstract class SecretLeaseEvent extends ApplicationEvent { return (RequestedSecret) super.getSource(); } + @Nullable public Lease getLease() { return lease; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/package-info.java index d97bfdab..81a9e702 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/event/package-info.java @@ -1,5 +1,7 @@ /** * Support classes for lease application events. */ +@NonNullApi package org.springframework.vault.core.lease.event; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/package-info.java index a14efbc8..202799d9 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/lease/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/lease/package-info.java @@ -1,5 +1,7 @@ /** * The core package implementing lease renewal and secret rotation. */ +@NonNullApi package org.springframework.vault.core.lease; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/core/package-info.java index 5c35cf81..9f734b65 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/package-info.java @@ -1,5 +1,7 @@ /** * Vault core support. */ +@NonNullApi package org.springframework.vault.core; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/core/util/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/core/util/package-info.java index 8e4533c2..6474ef71 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/core/util/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/core/util/package-info.java @@ -1,4 +1,8 @@ /** * Property transformer classes for Spring Vault core support. */ -package org.springframework.vault.core.util; \ No newline at end of file +@NonNullApi +package org.springframework.vault.core.util; + +import org.springframework.lang.NonNullApi; + diff --git a/spring-vault-core/src/main/java/org/springframework/vault/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/package-info.java index d3ce5712..4a73c3c3 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/package-info.java @@ -1,5 +1,7 @@ /** * Spring support for Hashicorp Vault. */ +@NonNullApi package org.springframework.vault; +import org.springframework.lang.NonNullApi; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/Base64.java b/spring-vault-core/src/main/java/org/springframework/vault/support/Base64.java index 9a232064..5e0f62a1 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/Base64.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/Base64.java @@ -19,7 +19,7 @@ class Base64 { private Base64() { } - public static byte[] decode(String in) { + static byte[] decode(String in) { // Ignore trailing '=' padding and whitespace from the input. int limit = in.length(); for (; limit > 0; limit--) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/JsonMapFlattener.java b/spring-vault-core/src/main/java/org/springframework/vault/support/JsonMapFlattener.java index 77754d2c..de6531c8 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/JsonMapFlattener.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/JsonMapFlattener.java @@ -20,6 +20,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -92,7 +93,7 @@ public abstract class JsonMapFlattener { } @SuppressWarnings("unchecked") - private static void flattenElement(String propertyPrefix, Object source, + private static void flattenElement(String propertyPrefix, @Nullable Object source, Map resultMap) { if (source instanceof Iterable) { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/SslConfiguration.java b/spring-vault-core/src/main/java/org/springframework/vault/support/SslConfiguration.java index ef300106..eafffe4f 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/SslConfiguration.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/SslConfiguration.java @@ -19,6 +19,7 @@ import java.security.KeyStore; import java.util.Arrays; import org.springframework.core.io.Resource; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -59,13 +60,13 @@ public class SslConfiguration { * GC than necessary. */ @Deprecated - public SslConfiguration(Resource keyStore, String keyStorePassword, - Resource trustStore, String trustStorePassword) { + public SslConfiguration(@Nullable Resource keyStore, + @Nullable String keyStorePassword, @Nullable Resource trustStore, + @Nullable String trustStorePassword) { this(new KeyStoreConfiguration(keyStore, charsOrNull(keyStorePassword), - KeyStore.getDefaultType()), - new KeyStoreConfiguration(trustStore, charsOrNull(trustStorePassword), - KeyStore.getDefaultType())); + KeyStore.getDefaultType()), new KeyStoreConfiguration(trustStore, + charsOrNull(trustStorePassword), KeyStore.getDefaultType())); } /** @@ -101,7 +102,7 @@ public class SslConfiguration { */ @Deprecated public static SslConfiguration forTrustStore(Resource trustStore, - String trustStorePassword) { + @Nullable String trustStorePassword) { return forTrustStore(trustStore, charsOrNull(trustStorePassword)); } @@ -116,10 +117,10 @@ public class SslConfiguration { * @see java.security.KeyStore */ public static SslConfiguration forTrustStore(Resource trustStore, - char[] trustStorePassword) { + @Nullable char[] trustStorePassword) { Assert.notNull(trustStore, "TrustStore must not be null"); - Assert.notNull(trustStore.exists(), + Assert.isTrue(trustStore.exists(), String.format("TrustStore %s does not exist", trustStore)); return new SslConfiguration(KeyStoreConfiguration.EMPTY, @@ -142,7 +143,7 @@ public class SslConfiguration { */ @Deprecated public static SslConfiguration forKeyStore(Resource keyStore, - String keyStorePassword) { + @Nullable String keyStorePassword) { return forKeyStore(keyStore, charsOrNull(keyStorePassword)); } @@ -156,11 +157,11 @@ public class SslConfiguration { * @return the created {@link SslConfiguration}. * @see java.security.KeyStore */ - public static SslConfiguration forKeyStore(Resource keyStore, - char[] keyStorePassword) { + public static SslConfiguration forKeyStore(@Nullable Resource keyStore, + @Nullable char[] keyStorePassword) { Assert.notNull(keyStore, "KeyStore must not be null"); - Assert.notNull(keyStore.exists(), + Assert.isTrue(keyStore.exists(), String.format("KeyStore %s does not exist", keyStore)); return new SslConfiguration(new KeyStoreConfiguration(keyStore, keyStorePassword, @@ -184,8 +185,8 @@ public class SslConfiguration { * longer from GC than necessary. */ @Deprecated - public SslConfiguration create(Resource keyStore, String keyStorePassword, - Resource trustStore, String trustStorePassword) { + public SslConfiguration create(Resource keyStore, @Nullable String keyStorePassword, + Resource trustStore, @Nullable String trustStorePassword) { return create(keyStore, charsOrNull(keyStorePassword), trustStore, charsOrNull(trustStorePassword)); } @@ -203,28 +204,27 @@ public class SslConfiguration { * @return the created {@link SslConfiguration}. * @see java.security.KeyStore */ - public SslConfiguration create(Resource keyStore, char[] keyStorePassword, - Resource trustStore, char[] trustStorePassword) { + public SslConfiguration create(Resource keyStore, @Nullable char[] keyStorePassword, + Resource trustStore, @Nullable char[] trustStorePassword) { Assert.notNull(keyStore, "KeyStore must not be null"); - Assert.notNull(keyStore.exists(), + Assert.isTrue(keyStore.exists(), String.format("KeyStore %s does not exist", trustStore)); Assert.notNull(trustStore, "TrustStore must not be null"); - Assert.notNull(trustStore.exists(), + Assert.isTrue(trustStore.exists(), String.format("TrustStore %s does not exist", trustStore)); - return new SslConfiguration( - new KeyStoreConfiguration(keyStore, keyStorePassword, - KeyStore.getDefaultType()), - new KeyStoreConfiguration(trustStore, trustStorePassword, - KeyStore.getDefaultType())); + return new SslConfiguration(new KeyStoreConfiguration(keyStore, keyStorePassword, + KeyStore.getDefaultType()), new KeyStoreConfiguration(trustStore, + trustStorePassword, KeyStore.getDefaultType())); } /** * @return the {@link java.security.KeyStore key store} resource or {@literal null} if * not configured. */ + @Nullable public Resource getKeyStore() { return keyStoreConfiguration.getResource(); } @@ -236,6 +236,7 @@ public class SslConfiguration { * longer from GC than necessary. */ @Deprecated + @Nullable public String getKeyStorePassword() { return stringOrNull(keyStoreConfiguration.getStorePassword()); } @@ -252,6 +253,7 @@ public class SslConfiguration { * @return the {@link java.security.KeyStore key store} resource or {@literal null} if * not configured. */ + @Nullable public Resource getTrustStore() { return trustStoreConfiguration.getResource(); } @@ -263,6 +265,7 @@ public class SslConfiguration { * longer from GC than necessary. */ @Deprecated + @Nullable public String getTrustStorePassword() { return stringOrNull(trustStoreConfiguration.getStorePassword()); } @@ -275,12 +278,14 @@ public class SslConfiguration { return trustStoreConfiguration; } - private static String stringOrNull(char[] storePassword) { + @Nullable + private static String stringOrNull(@Nullable char[] storePassword) { return storePassword != null ? new String(storePassword) : null; } - private static char[] charsOrNull(String trustStorePassword) { - return trustStorePassword == null ? null : trustStorePassword.toCharArray(); + @Nullable + private static char[] charsOrNull(@Nullable String trustStorePassword) { + return trustStorePassword != null ? trustStorePassword.toCharArray() : null; } /** @@ -296,23 +301,26 @@ public class SslConfiguration { /** * Store that holds certificates, private keys, …. */ + @Nullable private final Resource resource; /** * Password used to access the key store/trust store. */ + @Nullable private final char[] storePassword; /** * Key store/trust store type. */ + @Nullable private final String storeType; /** * Create a new {@link KeyStoreConfiguration}. */ - public KeyStoreConfiguration(Resource resource, char[] storePassword, - String storeType) { + public KeyStoreConfiguration(@Nullable Resource resource, + @Nullable char[] storePassword, @Nullable String storeType) { this.resource = resource; this.storeType = storeType; @@ -329,6 +337,7 @@ public class SslConfiguration { * @return the {@link java.security.KeyStore key store} resource or * {@literal null} if not configured. */ + @Nullable public Resource getResource() { return resource; } @@ -337,6 +346,7 @@ public class SslConfiguration { * @return the key store/trust store password or {@literal null} if not * configured. */ + @Nullable public char[] getStorePassword() { return storePassword; } @@ -344,6 +354,7 @@ public class SslConfiguration { /** * @return the trust store type or {@literal null} if not configured. */ + @Nullable public String getStoreType() { return storeType; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java index 4f851712..e99ee502 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultCertificateRequest.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -47,6 +48,7 @@ public class VaultCertificateRequest { /** * Requested Time to Live */ + @Nullable private final Duration ttl; /** @@ -57,8 +59,8 @@ public class VaultCertificateRequest { private final boolean excludeCommonNameFromSubjectAltNames; VaultCertificateRequest(String commonName, List altNames, - List ipSubjectAltNames, Duration ttl, - Boolean excludeCommonNameFromSubjectAltNames) { + List ipSubjectAltNames, @Nullable Duration ttl, + @Nullable Boolean excludeCommonNameFromSubjectAltNames) { this.commonName = commonName; this.altNames = altNames; @@ -97,6 +99,7 @@ public class VaultCertificateRequest { return ipSubjectAltNames; } + @Nullable public Duration getTtl() { return ttl; } @@ -107,10 +110,15 @@ public class VaultCertificateRequest { public static class VaultCertificateRequestBuilder { + @Nullable private String commonName; private List altNames = new ArrayList<>(); private List ipSubjectAltNames = new ArrayList<>(); + + @Nullable private Duration ttl; + + @Nullable private Boolean excludeCommonNameFromSubjectAltNames; VaultCertificateRequestBuilder() { @@ -257,6 +265,7 @@ public class VaultCertificateRequest { */ public VaultCertificateRequest build() { + Assert.notNull(commonName, "Common name must not be null"); Assert.hasText(commonName, "Common name must not be empty"); List altNames; diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultHealth.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultHealth.java index aa0e07c3..9bc057f1 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultHealth.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultHealth.java @@ -15,6 +15,8 @@ */ package org.springframework.vault.support; +import org.springframework.lang.Nullable; + /** * Vault health state. * @@ -50,5 +52,6 @@ public interface VaultHealth { /** * @return the Vault version. */ + @Nullable String getVersion(); } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultMount.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultMount.java index b2028342..ddada2ae 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultMount.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultMount.java @@ -15,10 +15,12 @@ */ package org.springframework.vault.support; +import java.util.Collections; import java.util.Map; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -40,6 +42,7 @@ public class VaultMount { /** * Human readable description of the mount. */ + @Nullable private final String description; /** @@ -48,11 +51,11 @@ public class VaultMount { private final Map config; private VaultMount(@JsonProperty("type") String type, - @JsonProperty("description") String description, - @JsonProperty("config") Map config) { + @Nullable @JsonProperty("description") String description, + @Nullable @JsonProperty("config") Map config) { this.type = type; this.description = description; - this.config = config; + this.config = config != null ? config : Collections.emptyMap(); } /** @@ -82,6 +85,7 @@ public class VaultMount { /** * @return human readable description of this mount. */ + @Nullable public String getDescription() { return description; } @@ -89,6 +93,7 @@ public class VaultMount { /** * @return additional configuration details. */ + @Nullable public Map getConfig() { return config; } @@ -98,11 +103,13 @@ public class VaultMount { */ public static class VaultMountBuilder { + @Nullable private String type; + @Nullable private String description; - private Map config; + private Map config = Collections.emptyMap(); VaultMountBuilder() { } @@ -128,6 +135,7 @@ public class VaultMount { * @return {@literal this} {@link VaultMountBuilder}. */ public VaultMountBuilder description(String description) { + this.description = description; return this; } @@ -139,6 +147,9 @@ public class VaultMount { * @return {@literal this} {@link VaultMountBuilder}. */ public VaultMountBuilder config(Map config) { + + Assert.notNull(config, "Configuration map must not be null"); + this.config = config; return this; } @@ -151,6 +162,7 @@ public class VaultMount { */ public VaultMount build() { + Assert.notNull(type, "Type must not be null"); Assert.hasText(type, "Type must not be empty or null"); return new VaultMount(type, description, config); diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultResponseSupport.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultResponseSupport.java index 6191c9d7..3294ccff 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultResponseSupport.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultResponseSupport.java @@ -22,6 +22,8 @@ import java.util.Map; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.lang.Nullable; + /** * Value object to bind generic Vault HTTP API responses. * @@ -32,64 +34,95 @@ import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties(ignoreUnknown = true) public class VaultResponseSupport { + @Nullable private Map auth; + @Nullable private T data; + @Nullable private Map metadata; @JsonProperty("wrap_info") + @Nullable private Map wrapInfo; @JsonProperty("lease_duration") private long leaseDuration; @JsonProperty("lease_id") + @Nullable private String leaseId; @JsonProperty("request_id") + @Nullable private String requestId; private boolean renewable; + @Nullable private List warnings; /** - * * @return authentication payload. */ + @Nullable public Map getAuth() { return auth; } /** - * + * @return the authentication payload. + * @throws IllegalStateException if {@code auth} is null. + */ + public Map getRequiredAuth() { + + if (auth != null) { + return auth; + } + + throw new IllegalStateException("Auth field is empty"); + } + + /** * @param auth the authentication payload. */ - public void setAuth(Map auth) { + public void setAuth(@Nullable Map auth) { this.auth = auth; } /** - * * @return secret data. */ + @Nullable public T getData() { return data; } /** - * + * @return the required secret data. + * @throws IllegalStateException if {@code data} is null. + */ + public T getRequiredData() { + + if (data != null) { + return data; + } + + throw new IllegalStateException("Data field is empty"); + } + + /** * @param data secret data. */ - public void setData(T data) { + public void setData(@Nullable T data) { this.data = data; } /** - * * @return request metadata. */ + @Nullable public Map getMetadata() { return metadata; } @@ -98,7 +131,7 @@ public class VaultResponseSupport { * * @param metadata request metadata. */ - public void setMetadata(Map metadata) { + public void setMetadata(@Nullable Map metadata) { this.metadata = metadata; } @@ -122,6 +155,7 @@ public class VaultResponseSupport { * * @return the lease Id. */ + @Nullable public String getLeaseId() { return leaseId; } @@ -130,7 +164,7 @@ public class VaultResponseSupport { * * @param leaseId the lease Id. */ - public void setLeaseId(String leaseId) { + public void setLeaseId(@Nullable String leaseId) { this.leaseId = leaseId; } @@ -154,6 +188,7 @@ public class VaultResponseSupport { * * @return response wrapping details. */ + @Nullable public Map getWrapInfo() { return wrapInfo; } @@ -162,7 +197,7 @@ public class VaultResponseSupport { * * @param wrapInfo response wrapping details. */ - public void setWrapInfo(Map wrapInfo) { + public void setWrapInfo(@Nullable Map wrapInfo) { this.wrapInfo = wrapInfo; } @@ -170,6 +205,7 @@ public class VaultResponseSupport { * * @return the request Id. */ + @Nullable public String getRequestId() { return requestId; } @@ -178,7 +214,7 @@ public class VaultResponseSupport { * * @param requestId the request Id. */ - public void setRequestId(String requestId) { + public void setRequestId(@Nullable String requestId) { this.requestId = requestId; } @@ -186,6 +222,7 @@ public class VaultResponseSupport { * * @return the warnings. */ + @Nullable public List getWarnings() { return warnings; } @@ -194,7 +231,7 @@ public class VaultResponseSupport { * * @param warnings the warnings. */ - public void setWarnings(List warnings) { + public void setWarnings(@Nullable List warnings) { this.warnings = warnings; } } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java index dac9087b..479c6278 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenRequest.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -34,33 +35,43 @@ import org.springframework.util.Assert; */ public class VaultTokenRequest { + @Nullable private final String id; private final List policies; private final Map meta; + @Nullable private final Boolean noParent; @JsonProperty("no_default_policy") + @Nullable private final Boolean noDefaultPolicy; + @Nullable private final Boolean renewable; + @Nullable private final String ttl; @JsonProperty("explicit_max_ttl") + @Nullable private final String explicitMaxTtl; @JsonProperty("display_name") + @Nullable private final String displayName; @JsonProperty("num_uses") + @Nullable private final Integer numUses; - VaultTokenRequest(String id, List policies, Map meta, - Boolean noParent, Boolean noDefaultPolicy, Boolean renewable, String ttl, - String explicitMaxTtl, String displayName, Integer numUses) { + VaultTokenRequest(@Nullable String id, List policies, + Map meta, @Nullable Boolean noParent, + @Nullable Boolean noDefaultPolicy, @Nullable Boolean renewable, + @Nullable String ttl, @Nullable String explicitMaxTtl, + @Nullable String displayName, @Nullable Integer numUses) { this.id = id; this.policies = policies; @@ -85,6 +96,7 @@ public class VaultTokenRequest { * * @return Id of the client token. */ + @Nullable public String getId() { return id; } @@ -110,6 +122,7 @@ public class VaultTokenRequest { * * @return {@literal true} if the token should not have the parent. */ + @Nullable public Boolean getNoParent() { return noParent; } @@ -118,6 +131,7 @@ public class VaultTokenRequest { * * @return {@literal true} if the default policy should not be be applied. */ + @Nullable public Boolean getNoDefaultPolicy() { return noDefaultPolicy; } @@ -126,6 +140,7 @@ public class VaultTokenRequest { * * @return {@literal true} if then the token should be renewable. */ + @Nullable public Boolean getRenewable() { return renewable; } @@ -134,6 +149,7 @@ public class VaultTokenRequest { * * @return TTL period of the token. */ + @Nullable public String getTtl() { return ttl; } @@ -142,6 +158,7 @@ public class VaultTokenRequest { * * @return explicit TTL of the token. */ + @Nullable public String getExplicitMaxTtl() { return explicitMaxTtl; } @@ -150,6 +167,7 @@ public class VaultTokenRequest { * * @return the display name. */ + @Nullable public String getDisplayName() { return displayName; } @@ -158,6 +176,7 @@ public class VaultTokenRequest { * * @return the number of allowed token uses. */ + @Nullable public Integer getNumUses() { return numUses; } @@ -167,24 +186,32 @@ public class VaultTokenRequest { */ public static class VaultTokenRequestBuilder { + @Nullable private String id; private List policies = new ArrayList<>(); private Map meta = new LinkedHashMap<>(); + @Nullable private Boolean noParent; + @Nullable private Boolean noDefaultPolicy; + @Nullable private Boolean renewable; + @Nullable private String ttl; + @Nullable private String explicitMaxTtl; + @Nullable private String displayName; + @Nullable private Integer numUses; VaultTokenRequestBuilder() { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenResponse.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenResponse.java index a6e5e534..ea241ebd 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenResponse.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTokenResponse.java @@ -28,6 +28,6 @@ public class VaultTokenResponse extends VaultResponse { * @return the {@link VaultToken}. */ public VaultToken getToken() { - return VaultToken.of((String) getAuth().get("client_token")); + return VaultToken.of((String) getRequiredAuth().get("client_token")); } } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitContext.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitContext.java index 8173c257..ec807fca 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitContext.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitContext.java @@ -15,6 +15,8 @@ */ package org.springframework.vault.support; +import org.springframework.lang.Nullable; + /** * Transit backend encryption/decryption/rewrapping context. * @@ -28,11 +30,13 @@ public class VaultTransitContext { */ private static final VaultTransitContext EMPTY = new VaultTransitContext(null, null); + @Nullable private final byte[] context; + @Nullable private final byte[] nonce; - VaultTransitContext(byte[] context, byte[] nonce) { + VaultTransitContext(@Nullable byte[] context, @Nullable byte[] nonce) { this.context = context; this.nonce = nonce; } @@ -54,6 +58,7 @@ public class VaultTransitContext { /** * @return the key derivation context. */ + @Nullable public byte[] getContext() { return context; } @@ -61,6 +66,7 @@ public class VaultTransitContext { /** * @return the */ + @Nullable public byte[] getNonce() { return nonce; } @@ -70,8 +76,10 @@ public class VaultTransitContext { */ public static class VaultTransitRequestBuilder { + @Nullable private byte[] context; + @Nullable private byte[] nonce; VaultTransitRequestBuilder() { @@ -84,7 +92,7 @@ public class VaultTransitContext { * provided if derivation is enabled. * @return {@code this} {@link VaultTransitRequestBuilder}. */ - public VaultTransitRequestBuilder context(byte[] context) { + public VaultTransitRequestBuilder context(@Nullable byte[] context) { this.context = context; return this; } @@ -99,7 +107,7 @@ public class VaultTransitContext { * nonce value is never reused * @return {@code this} {@link VaultTransitRequestBuilder}. */ - public VaultTransitRequestBuilder nonce(byte[] nonce) { + public VaultTransitRequestBuilder nonce(@Nullable byte[] nonce) { this.nonce = nonce; return this; } diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyConfiguration.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyConfiguration.java index 53267d38..565790a3 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyConfiguration.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyConfiguration.java @@ -17,20 +17,25 @@ package org.springframework.vault.support; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.lang.Nullable; + /** * Value object to bind Vault HTTP Transit Key Config API requests. - * + * * @author Mark Paluch */ public class VaultTransitKeyConfiguration { @JsonProperty("deletion_allowed") + @Nullable private final Boolean deletionAllowed; @JsonProperty("latest_version") + @Nullable private final Integer latestVersion; - private VaultTransitKeyConfiguration(Boolean deletionAllowed, Integer latestVersion) { + private VaultTransitKeyConfiguration(@Nullable Boolean deletionAllowed, + @Nullable Integer latestVersion) { this.deletionAllowed = deletionAllowed; this.latestVersion = latestVersion; } @@ -45,6 +50,7 @@ public class VaultTransitKeyConfiguration { /** * @return whether key deletion is configured */ + @Nullable public Boolean getDeletionAllowed() { return deletionAllowed; } @@ -52,6 +58,7 @@ public class VaultTransitKeyConfiguration { /** * @return latest key version */ + @Nullable public Integer getLatestVersion() { return latestVersion; } @@ -61,8 +68,10 @@ public class VaultTransitKeyConfiguration { */ public static class VaultTransitKeyConfigurationBuilder { + @Nullable private Boolean deletionAllowed; + @Nullable private Integer latestVersion; VaultTransitKeyConfigurationBuilder() { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java index 6ffd0018..68464837 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/VaultTransitKeyCreationRequest.java @@ -17,6 +17,7 @@ package org.springframework.vault.support; import com.fasterxml.jackson.annotation.JsonProperty; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -27,18 +28,21 @@ import org.springframework.util.Assert; */ public class VaultTransitKeyCreationRequest { + @Nullable private final Boolean derived; @JsonProperty("type") private final String type; @JsonProperty("convergent_encryption") + @Nullable private final Boolean convergentEncryption; + @Nullable private final Boolean exportable; - private VaultTransitKeyCreationRequest(Boolean derived, String type, - Boolean convergentEncryption, Boolean exportable) { + private VaultTransitKeyCreationRequest(@Nullable Boolean derived, String type, + @Nullable Boolean convergentEncryption, @Nullable Boolean exportable) { this.derived = derived; this.type = type; this.convergentEncryption = convergentEncryption; @@ -56,6 +60,7 @@ public class VaultTransitKeyCreationRequest { * * @return {@literal true} if key derivation MUST be used. */ + @Nullable public Boolean getDerived() { return derived; } @@ -65,6 +70,7 @@ public class VaultTransitKeyCreationRequest { * @return {@literal true} if convergent encryption should be used (where the same * plaintext creates the same cipher text). */ + @Nullable public Boolean getConvergentEncryption() { return convergentEncryption; } @@ -81,6 +87,7 @@ public class VaultTransitKeyCreationRequest { * * @return {@literal true} if key MUST be exportable. */ + @Nullable public Boolean getExportable() { return this.exportable; } @@ -90,9 +97,14 @@ public class VaultTransitKeyCreationRequest { */ public static class VaultTransitKeyCreationRequestBuilder { + @Nullable private Boolean derived; private String type = "aes256-gcm96"; + + @Nullable private Boolean convergentEncryption; + + @Nullable private Boolean exportable; VaultTransitKeyCreationRequestBuilder() { diff --git a/spring-vault-core/src/main/java/org/springframework/vault/support/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/support/package-info.java index c0eb1833..21dcc895 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/support/package-info.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/support/package-info.java @@ -1,4 +1,8 @@ /** * Classes supporting the Vault packages, such as value objects. */ -package org.springframework.vault.support; \ No newline at end of file +@NonNullApi +package org.springframework.vault.support; + +import org.springframework.lang.NonNullApi; +