I am writing custom spring boot starter project where we have our own class VaultFactory which connects to the vault based on the consumer's properties defined in application.yml file.
In the custom starter project i can read all the secrets and corresponding values. Now, i want to expose all the these key/value pair as a property source so that consumers will directly access via @value
@Value{${some.vault.secret.name}}
private String value;
My starter project code
@Configuration
@EnableConfigurationProperties(VaultConfiguration.class)
@ConditionalOnClass(VaultFactory.class)
public class VaultEnableAutoConfiguration {
/**
* @param vaultConfiguration
* @return
* @throws VaultException
*/
@Bean
@ConditionalOnMissingBean
public Vault getVaultFactoryByProperties(VaultConfiguration vaultConfiguration) throws VaultException {
VaultFactory vaultFactory = VaultFactory.newInstance(vaultConfiguration.getVault().get("file.path"), vaultConfiguration.getVaultProperties());
return vaultFactory.getVault("vault-01");
}
}
@EnableConfigurationProperties(VaultConfiguration.class)
public class VaultPropertiesConfiguration {
@Autowired
Vault vault;
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(VaultConfiguration vaultConfiguration) throws VaultException {
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
ConfigurableEnvironment environment = new StandardEnvironment();
MutablePropertySources ps = environment.getPropertySources();
pspc.setIgnoreUnresolvablePlaceholders(Boolean.TRUE);
pspc.setIgnoreUnresolvablePlaceholders(true);
ps.addLast(new VaultPropertySource("vaultProperties", vault));
pspc.setPropertySources(ps);
return pspc;
}
}
public class VaultPropertySource extends PropertySource<Vault>{
Vault vault;
public VaultPropertySource(String name) {
super(name);
}
public VaultPropertySource(String name, Vault vault) {
super(name);
this.vault = vault;
}
@Override
public Object getProperty(String name) {
try {
return vault.getSecret(name).getValue();
} catch (VaultException e) {
e.printStackTrace();
}
return null;
}
}
@ConfigurationProperties("platform")
public class VaultConfiguration {
private final Map<String, String> vault = new HashMap<>();
public Map<String, String> getVault() {
return vault;
}
public Properties getVaultProperties() {
Properties p = new Properties();
vault.entrySet().stream().forEach( e -> p.put(e.getKey(), e.getValue()));
return p;
}
}
How can i do it ? Basically, to simply if i have a key/value map in my starter project, how i can make these avaliable to boot application via @value annotation ?
Facing Multiple issues :
VaultPropertiesConfiguration is always called first and the @EnableConfigurationProperties and @autowired is not working.
I harded coded to get workaround the above issue, but it is trying to load spring.messages.always-use-message-format property from propertysource which i dont have.