Expose Environment in AbstractVaultConfiguration.

Accessing Environment when providing a VaultPropertySource in bean bootstrapping requires a class to implement ApplicationContextAware. This is, because autowiring didn't happen yet and the exposed method provides Environment in the appropriate way.

See gh-26.
This commit is contained in:
Mark Paluch
2016-10-27 16:52:07 +02:00
parent 67f7119d22
commit 23a95dd961
3 changed files with 35 additions and 27 deletions

View File

@@ -15,10 +15,14 @@
*/
package org.springframework.vault.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.http.client.ClientHttpRequestFactory;
@@ -41,7 +45,9 @@ import org.springframework.vault.support.SslConfiguration;
* @author Mark Paluch
*/
@Configuration
public abstract class AbstractVaultConfiguration {
public abstract class AbstractVaultConfiguration implements ApplicationContextAware {
private ApplicationContext applicationContext;
/**
* @return Vault endpoint coordinates for HTTP/HTTPS communication, must not be
@@ -164,6 +170,28 @@ public abstract class AbstractVaultConfiguration {
return new VaultTemplate(vaultClientFactory(), sessionManager());
}
/**
* Return the {@link Environment} to access property sources during Spring Vault
* bootstrapping. Requires {@link #setApplicationContext(ApplicationContext)
* ApplicationContext} to be set.
*
* @return the {@link Environment} to access property sources during Spring Vault
* bootstrapping.
*/
protected Environment getEnvironment() {
Assert.state(applicationContext != null,
"ApplicationContext must be set before accessing getEnvironment()");
return applicationContext.getEnvironment();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
/**
* Wrapper for {@link ClientHttpRequestFactory} to not expose the bean globally.
*/

View File

@@ -18,16 +18,12 @@ package org.springframework.vault.demo;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.vault.annotation.VaultPropertySource;
import org.springframework.vault.authentication.ClientAuthentication;
@@ -82,20 +78,11 @@ public class SecurePropertyUsage {
@VaultPropertySource({ "secret/secure-introduction" })
@Configuration
@ComponentScan
static class Config extends VaultIntegrationTestConfiguration implements
ApplicationContextAware {
private Environment environment;
static class Config extends VaultIntegrationTestConfiguration {
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication(environment.getProperty("vault.token"));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
environment = applicationContext.getEnvironment();
return new TokenAuthentication(getEnvironment().getProperty("vault.token"));
}
}

View File

@@ -26,25 +26,18 @@ OS access levels.
----
@PropertySource("configuration.properties"),
@Configuration
static class Config extends VaultIntegrationTestConfiguration implements
ApplicationContextAware {
private Environment environment;
public class Config extends AbstractVaultConfiguration {
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication(environment.getProperty("vault.token"));
return new TokenAuthentication(getEnvironment().getProperty("vault.token"));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
environment = applicationContext.getEnvironment();
}
}
----
====
NOTE: Spring allows multiple ways to obtain `Environment`. When using `VaultPropertySource`, injection via `@Autowired Environment environment` will not provide the `Environment` as the environment bean is still in construction and autowiring comes at a later stage. Your configuration class should rather implement `ApplicationContextAware` and obtain the `Environment` from `ApplicationContext`.
See https://github.com/spring-projects/spring-vault/blob/master/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java[`SecurePropertyUsage.java`]
for a sample on referencing properties in components and other property sources.