Use case :- Part of our datasource properties are known during development and put in the application yaml file. But then we would like to have the option to overwrite / add more properties using -Dspring.config.additional-location, so that we can avoid spinning new containers. Also we have a java library which provides us the username & password to be used by reading from a REST end-point. We want to avoid setting the username / password in the spring environment due to security constraints. We tried using the -Dspring.cloud.bootstrap.additional-location by pointing to the secrets file the java library refers to in vain (even though it loads the secrets in the environment). The file is being read by the bootstrap reader but the properties were not set in the datasource and hence the issue remain.
Functional need :- Support of properties injection from both application prop file & java configuration code. The precedence order should be:- spring.config.additional-location, java code, application prop file.
Proposals
1) We expose a method level annotation say @BeanProperties(value = "beanName"). The return type of the method is a key / value data structure. The values in this data structure in then merged with the other props from application props / additional config location and then utilized to initialize the bean.
2) We expose an encrpyt option either at Spring level or at each config level which controls if the credentials be encrypted in the spring environment memory by a random generated security key at startup.
=================== I am not sure if someone have faced a similar issue or not OR am doing something which is not the right way. In that case please suggest how I can achieve my use-case. Note:- We cannot use the Kubernetes vault / config map due to company requirements.
Cheers, Manish
Comment From: wilkinsona
We expose a method level annotation say @BeanProperties(value = "beanName")
A bean and annotation-based approach is too late for making property contributions as the Environment must be fully prepared before the application context is refreshed. It's for this reason that we recommend not using @PropertySource in a Spring Boot application.
Instead, you can add properties to the environment by implementing EnvironmentPostProcessor and registering the implementation in spring.factories using the key org.springframework.boot.env.EnvironmentPostProcessor. The post-processor can add a property source to the environment at whatever position is required to satisfy your desired property precedence.
Alternatively, as you want to load some configuration from a remote source (via a REST API call), you may want to consider plugging in your own additional config location. Please see the tip at the end of this section for some pointers on how to do so. If you have any further questions about this, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
We expose an encrpyt option either at Spring level or at each config level which controls if the credentials be encrypted in the spring environment memory by a random generated security key at startup
I don't think this will provide any additional security as the decrypted value is likely to be stored in memory somewhere. Even if it is not, both the encrypted value and the means to decrypt it must be available so anyone who compromises the system would have access to the decrypted value.
Comment From: DareUrDream
Thanks @wilkinsona for the information. I will look into the details provided.
Just a question though to clear my understanding on the below
A bean and annotation-based approach is too late for making property contributions as the Environment must be fully prepared before the application context is refreshed. It's for this reason that we recommend not using @PropertySource in a Spring Boot application.
Does this mean we cannot even have another annotation even at a class level / method level that precedes or executes before the environment refresh. I mean to say an processor which precedes or understands that we need to get the key / value data structure from the methods (and yes the method cannot use any other spring provided beans as they are not initialized yet).
Comment From: wilkinsona
Does this mean we cannot even have another annotation even at a class level / method level that precedes or executes before the environment refresh
Yes, that's right. We can't reliably find those methods or classes before the environment is prepared which is why we recommend against using @PropertySource. It can be used with care, for example by placing it on your main application class, but there are too many subtleties so, generally speaking, it's better to avoid it.