I have this in my-microservice-configuration.yml
in my configuration service
spring:
servlet:
multipart:
max-file-size: 5MB
max-request-size: 10MB
datasource:
url: jdbc:sqlserver://www.xxx.yyy.zzz:1433;databaseName=my_database_name;encrypt=true;trustServerCertificate=true;
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
testWhileIdle: true
testOnBorrow: true
...
In my Hashicorp Vault
Server I have the secrets:
{
"request_id": "193255e4-e7d3-781b-70fa-bb9ce516a930",
"lease_id": "",
"lease_duration": 2764800,
"renewable": false,
"data": {
"spring.datasource.password": "myDBPassword",
"spring.datasource.username": "myDBUser"
},
"warnings": null
}
Now, I have this Component that execute this method after all environments variables has been read.
@Component
@RequiredArgsConstructor
@Slf4j
public class RunAfterStartupUtil {
@EventListener(ApplicationReadyEvent.class)
public void runAfterStartup() {
log.info("Microservice started and apparently ready to receive requests.");
}
}
I read this article https://www.baeldung.com/spring-boot-configure-data-source-programmatic with this code:
@Configuration
public class DataSourceConfig {
@Bean
public DataSource getDataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:mem:test");
dataSourceBuilder.username("SA");
dataSourceBuilder.password("");
return dataSourceBuilder.build();
}
}
QUESTION:
After my microservice has initialized everything, I need overwrite directly in my microservice (can be in the method runAfterStartup()
), the variables (both from the Vault Server and the Server Config) and/or components created to point to another database, with other credentials. And Obviously use them.
NOTE: I can't disable the config server nor vault server because I'm using a lot of other variables of them.
How could I do it?
Is there a specific reason you need to initialize the
DataSource
bean first pointing toH2
DB and then switch it to the desired DB? If there isn't, you can directly initialize the bean pointing to your required DB(SQLServer) with credentials from vault, which can be injected using spring-cloud-config-server.I used
Postgres
for my test, but the config required should be similar forSQLServer
as well. All the config and secrets added under the prefixspring.datasource
can be accessed via aDataSourceProperties
bean which can then be used to initialize theDataSource
. Below are all the changes I made:Gradle dependencies:
application.yml:
bootstrap.yml: (Contains config for spring cloud, will be read by
spring-cloud-starter-bootstrap
)Bean initialization:
I added the secrets to my vault under
/secret/data/spring-boot-demo
, withspring-boot-demo
being the value ofspring.cloud.config.name
specified inbootstrap.yml
. I did notice that my secret values in vault exist under a nesteddata
field, probably because the vault was using KV secrets engine v2. The secret value is below:You can find all the changes I made on github