0

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 :

  1. VaultPropertiesConfiguration is always called first and the @EnableConfigurationProperties and @autowired is not working.

  2. 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.

sagar kancherla
  • 129
  • 1
  • 3
  • 12
  • Just register a new `PropertySource` with the environment or create a dedicated one for your case (like Spirng Cloud Config does) and register that. – M. Deinum Mar 09 '20 at 11:38
  • @M.Deinum I tried adding property source in my custom starter project but i am facing some issues. Could you tell what am i doing wrong. – sagar kancherla Mar 09 '20 at 14:17

1 Answers1

0

You cannot use @Value with .yml file same way as with .properties file.

Can you exmplain more the meaning of "i can read all the secrets and corresponding values". So how is it available in application?

Betlista
  • 10,327
  • 13
  • 69
  • 110
  • Sorry for the confusion, In custom starter, we have our own VaultFactory class which connects to vault and get the data. This data i want to expose to the boot applications(who uses custom starter) as @value – sagar kancherla Mar 09 '20 at 11:56