Default Spring Data MongoDB properties values - spring-boot

I have a new MongoDB, that means there's no user, password and/or an authentication database.
Translating this to a .properties file, this should be:
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
...and for .yaml/.yml:
spring:
data:
mongodb:
host: localhost
port: 27017
Now let's suppose I want to use environment variables instead, if they're set, like this:
spring:
data:
mongodb:
host: ${MONGODB_HOST:localhost}
port: ${MONGODB_PORT:27017}
Everything until now works as expected.
What I want to achieve is the same for the spring.data.mongodb.user, spring.data.mongodb.password and spring.data.mongodb.authentication-database properties. I've tried doing the same technique for these properties, but in case they're not found in the environment, an exception is thrown, like this:
spring:
data:
mongodb:
host: ${MONGODB_HOST:localhost}
port: ${MONGODB_PORT:27017}
username: ${MONGODB_USERNAME}
password: ${MONGODB_PASSWORD}
authentication-database: ${MONGODB_AUTHENTICATION_DATABASE}
I have even tried setting empty/blank valuesm like ${MONGODB_USERNAME:}, ${MONGODB_USERNAME:''} and ${MONGODB_USERNAME:""}.
How do I get to achieve this? Is it even possible?

I've not tried this, but Spring boot should be able to pickup environment variables and use them as properties without having to put them in the yaml file. For example if you name a OS environment variable SPRING_DATA_MONGODB_USERNAME the value should show up in the spring property spring.data.mongodb.username. This would allow you to specify the username property only when you require it.
The other way to do this is to use externalised config. If you are booting your application from a fat jar, an application.yml outside the jar in the same directory can add in your additional properties:
spring:
data:
mongodb:
username: fred
password: password
without affecting the properties specified in the application.yml provided inside the jar.
There's a long ordered list of where spring-boot looks for properties documented here.

Related

spring boot: how to verify env variables?

Is it possible to check env vars on startup in Spring Boot?
For example config looks like this:
spring:
data:
mongodb:
uri: ${MONGODB_URI}
rabbitmq:
addresses: ${RMQ_CLUSTER_ADDRESSES}
I want the app to not start if one of var is not exists.

SpringBoot complementary configuration file in system directory

I need some help to consume another .yml file that complement the original one in the application. Then I have a file filled by me(dev) however some configuration(as database infos) should be inserted by our clients.
The one which is in the application(application.yml) have general configs, the other on path C:\Users\Public\ datasource.yml have:
spring:
datasource:
platform: postgres
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/mydb
username: foo
password: bar
Has anyone done this before?
configure the below annotation at your main configuration class
#PropertySource("classpath:datasource.yml")

Read values from consul while bootstrap spring boot

I have question is there any way to retrieve certain values and inject them to bootstrap.yml while application is coming up.
I have configuration file like this:
spring:
application:
name: myApp
cloud:
consul:
enabled: true
host: localhost
port: 8500
config:
enabled: true
datasource:
url: jdbc:oracle:thin:#localhost:1111:XXXX
username: ${nameOfVariable1}
password: ${nameOfVariable1}
driver-class-name: oracle.jdbc.OracleDriver
For example, I need to configure embedded tomcat port, or DB credentials, I don't want to put it hardcoded in .yml properties file, instead I want to put some variable name in .yml so Spring will go and bring value from Consul. Is it possible?
You can use Spring Cloud Consul Config project that helps to load configuration into the Spring Environment during the special "bootstrap" phase.
3 steps:
add pom dependency: spring-cloud-starter-consul-config
enable consul config: spring.cloud.consul.config.enabled=true
add some config in consul kv in specific folder, such as key: config/testConsulApp/server.port, value:8081
and then start the sample web app, it will listen 8081.
more detail at spring cloud consul doc.
and demo code here

Yml config files "Inheritance" with Spring boot

I couldn't find a straight answer online.
Do Spring Boot's yml files "inherit" from each other? I mean if I have:
application.yml which has
server:
port: 80
host: foo
and application-profile1.yml which has only
server:
port: 90
So if I start my Spring Boot with profile1 as active profile, will I also have server.host property set to foo?
Yes, application.yml file has higher precedence over any application-{profile}.yml file. Properties from profile specific yml file will override values from the default application.yml file and properties that do not exist in profile specific yml file will be loaded from the default one. It applies to .properties files as well as to bootstrap.yml or bootstrap.properties.
Spring Boot documentation mentions it in 72.7 Change configuration depending on the environment paragraph:
In this example the default port is 9000, but if the Spring profile ‘development’ is active then the port is 9001, and if ‘production’ is active then it is 0.
The YAML documents are merged in the order they are encountered (so later values override earlier ones).
To do the same thing with properties files you can use application-${profile}.properties to specify profile-specific values.
Here is my solution.
Assume application.yml:
spring:
profiles: default-server-config
server:
port: 9801
servlet:
context-path: '/ctp'
If I want use default-server-config profile, and use port 8080 in my application-dev.yml
application-dev.yml:
spring:
profiles:
include:
- default-server-config
- dev-config
---
spring:
profiles: dev-config
server:
port: 8080
Then -Dspring.profiles.active=dev

Spring cloud config environment variable interpolation

I'm using spring-cloud-config in my Spring Boot project and I don't understand how to interpolate environment variables.
For example I have MYSQL_PASSWORD variable set in the config server (as environment variable) and I want to get it from other clients, without redefining the variable inside all of them. This is my config:
service.yml (in config-server)
spring:
datasource:
url: jdbc:mysql://mysql:3306/${MYSQL_DATABASE}?autoReconnect=true&useSSL=false
username: ${MYSQL_USER}
password: ${MYSQL_PASSWORD}
bootstrap.yml (into the client)
spring:
application:
name: event-service
cloud:
config:
uri: http://config-service:8888
fail-fast: true
If I start my services with this configuration, placeholder ${MYSQL_***} is not interpolated and I cannot connect to the database obviously.
What I have to do to make it work is to define environment variables like MYSQL_*** also in the client.
This is weird for me as I want config-server to be the central repository for everything. Do you have any advice?
I suggest you try to replace ${MYSQL_USER} and ${MYSQL_PASSWORD} with ${mysql.user} and ${mysql.password} - that way you'll be relying on Spring Boot's default property replacement.
Although I'm not sure that configuration server supports what you're trying to use, I've never tried a similar use case, please write back with a solution if the approach I suggested didn't work :)

Resources