From 5be0fa2868d4e8a7d7c0e2d3277e297e7af5cdaa Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 30 Mar 2020 15:22:42 +0200 Subject: [PATCH] Retrieve beans from BeanFactory instead of calling local configuration class bean methods. We now lookup beans from the BeanFactory instead of expecting a proxied arrangement of configuration class bean methods which allows using @Configuration(proxyBeanMethods = false). Closes gh-546. --- .../AbstractReactiveVaultConfiguration.java | 13 +++++-- .../config/AbstractVaultConfiguration.java | 38 ++++++++++++++----- ...rationAzureMSIAuthenticationUnitTests.java | 9 ++--- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractReactiveVaultConfiguration.java b/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractReactiveVaultConfiguration.java index 0555f06a..1a0fd40b 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractReactiveVaultConfiguration.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractReactiveVaultConfiguration.java @@ -60,7 +60,7 @@ import org.springframework.web.reactive.function.client.WebClient; * @author Mark Paluch * @since 2.0 */ -@Configuration +@Configuration(proxyBeanMethods = false) public abstract class AbstractReactiveVaultConfiguration extends AbstractVaultConfiguration { @@ -91,7 +91,7 @@ public abstract class AbstractReactiveVaultConfiguration public ReactiveVaultTemplate reactiveVaultTemplate() { return new ReactiveVaultTemplate( webClientBuilder(vaultEndpointProvider(), clientHttpConnector()), - reactiveSessionManager()); + getReactiveSessionManager()); } /** @@ -103,7 +103,7 @@ public abstract class AbstractReactiveVaultConfiguration @Bean @Override public SessionManager sessionManager() { - return new ReactiveSessionManagerAdapter(reactiveSessionManager()); + return new ReactiveSessionManagerAdapter(getReactiveSessionManager()); } /** @@ -121,7 +121,7 @@ public abstract class AbstractReactiveVaultConfiguration WebClient webClient = ReactiveVaultClients.createWebClient(vaultEndpoint(), clientHttpConnector()); return new ReactiveLifecycleAwareSessionManager(vaultTokenSupplier(), - threadPoolTaskScheduler(), webClient); + getVaultThreadPoolTaskScheduler(), webClient); } /** @@ -173,6 +173,11 @@ public abstract class AbstractReactiveVaultConfiguration return ClientHttpConnectorFactory.create(clientOptions(), sslConfiguration()); } + private ReactiveSessionManager getReactiveSessionManager() { + return getBeanFactory().getBean("reactiveSessionManager", + ReactiveSessionManager.class); + } + /** * Simple {@link SessionManager} adapter using a {@link ReactiveSessionManager} to * obtain tokens. diff --git a/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java b/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java index bb84b793..722eab73 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.vault.config; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; @@ -33,7 +34,6 @@ import org.springframework.vault.authentication.SessionManager; import org.springframework.vault.client.ClientHttpRequestFactoryFactory; import org.springframework.vault.client.RestTemplateBuilder; import org.springframework.vault.client.SimpleVaultEndpointProvider; -import org.springframework.vault.client.VaultClients; import org.springframework.vault.client.VaultEndpoint; import org.springframework.vault.client.VaultEndpointProvider; import org.springframework.vault.core.VaultTemplate; @@ -48,7 +48,7 @@ import org.springframework.web.client.RestOperations; * @author Spencer Gibb * @author Mark Paluch */ -@Configuration +@Configuration(proxyBeanMethods = false) public abstract class AbstractVaultConfiguration implements ApplicationContextAware { private @Nullable ApplicationContext applicationContext; @@ -105,8 +105,8 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw public VaultTemplate vaultTemplate() { return new VaultTemplate( restTemplateBuilder(vaultEndpointProvider(), - clientHttpRequestFactoryWrapper().getClientHttpRequestFactory()), - sessionManager()); + getClientFactoryWrapper().getClientHttpRequestFactory()), + getBeanFactory().getBean("sessionManager", SessionManager.class)); } /** @@ -129,7 +129,7 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw Assert.notNull(clientAuthentication, "ClientAuthentication must not be null"); return new LifecycleAwareSessionManager(clientAuthentication, - threadPoolTaskScheduler(), restOperations()); + getVaultThreadPoolTaskScheduler(), restOperations()); } /** @@ -145,7 +145,8 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw public SecretLeaseContainer secretLeaseContainer() throws Exception { SecretLeaseContainer secretLeaseContainer = new SecretLeaseContainer( - vaultTemplate(), threadPoolTaskScheduler()); + getBeanFactory().getBean("vaultTemplate", VaultTemplate.class), + getVaultThreadPoolTaskScheduler()); secretLeaseContainer.afterPropertiesSet(); secretLeaseContainer.start(); @@ -178,15 +179,16 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw /** * Construct a {@link RestOperations} object configured for Vault session management - * and authentication usage. + * and authentication usage. Can be customized by overriding + * {@link #restTemplateBuilder(VaultEndpointProvider, ClientHttpRequestFactory)}. * * @return the {@link RestOperations} to be used for Vault access. * @see #vaultEndpointProvider() * @see #clientHttpRequestFactoryWrapper() */ public RestOperations restOperations() { - return VaultClients.createRestTemplate(vaultEndpointProvider(), - clientHttpRequestFactoryWrapper().getClientHttpRequestFactory()); + return restTemplateBuilder(vaultEndpointProvider(), + getClientFactoryWrapper().getClientHttpRequestFactory()).build(); } /** @@ -247,6 +249,24 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw this.applicationContext = applicationContext; } + BeanFactory getBeanFactory() { + + Assert.state(applicationContext != null, + "ApplicationContext must be set before accessing getBeanFactory()"); + + return applicationContext; + } + + ThreadPoolTaskScheduler getVaultThreadPoolTaskScheduler() { + return getBeanFactory().getBean("vaultThreadPoolTaskScheduler", + ThreadPoolTaskScheduler.class); + } + + private ClientFactoryWrapper getClientFactoryWrapper() { + return getBeanFactory().getBean("clientHttpRequestFactoryWrapper", + ClientFactoryWrapper.class); + } + /** * Wrapper for {@link ClientHttpRequestFactory} to not expose the bean globally. */ diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAzureMSIAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAzureMSIAuthenticationUnitTests.java index 10384f8e..24ffb29a 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAzureMSIAuthenticationUnitTests.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAzureMSIAuthenticationUnitTests.java @@ -22,8 +22,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.vault.authentication.AzureMsiAuthentication; @@ -44,15 +44,14 @@ import static org.assertj.core.api.Assertions.assertThat; class EnvironmentVaultConfigurationAzureMSIAuthenticationUnitTests { @Configuration + @Import(EnvironmentVaultConfiguration.class) static class MyConfig { } @Test - void shouldConfigureAuthentication(@Autowired ApplicationContext context) { - - EnvironmentVaultConfiguration configuration = new EnvironmentVaultConfiguration(); - configuration.setApplicationContext(context); + void shouldConfigureAuthentication( + @Autowired EnvironmentVaultConfiguration configuration) { ClientAuthentication clientAuthentication = configuration.clientAuthentication();