Spring Cloud Config with File System Backend
With Spring Boot, we write our configuration values into:
- application.properties (loaded automatically by Spring Boot)
- any .properties file (we need to load them with @PropertySource annotation)
However, those configurations we make are specific for the application that loads them.
With Spring Cloud Config, we can externalize & centralize our configurations and use them in any of our Java application. It is particularly useful when you have multiple Java applications sharing common configurations. What is more, we can use spring profiles and set different values for the same key for different platforms.
In this story, I will show how to create a spring cloud config server and how to use the configurations in it in a separate Java application.
The Spring Cloud Config Server
To create a Spring Cloud Config Server we need to:
- add the required dependencies
- tell spring where to look for our configuration files
- add @EnableConfigServer annotation
Yes, that’s all for the server side.
Required dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Required Configuration
With Spring Cloud Config, we can use a git or a file system to put our configuration files.
To use a file system backend, we need to:
- set the
spring.cloud.config.server.native.search-locations
property in ourapplication.properties
file. - run our application with the
native
spring profile.
Setting the Search Location
If you want to put your configuration files outside of your classpath, set the spring.cloud.config.server.native.search-locations to the place where you put your configuration files:
spring.cloud.config.server.native.search-locations=file:///C:/config
The above configuration is just an example. If you are using spring cloud config with a file system backend, then you should put your configuration files in a shared file system.
If you want to put your configuration files in your classpath on the other hand, set the spring.cloud.config.server.native.search-locations like below :
spring.cloud.config.server.native.search-locations=classpath:/config
Running Your Application with a Spring Profile
If you want to load the configurations from a file system or your project’s classpath you need to run your application with “native” spring profile.
VM argument:
-Dspring.profiles.active=native
Don’t forget that you can provide multiple spring profiles by separating each value with a comma:
-Dspring.profiles.active=native,local
Running application with Maven Spring-Boot plugin from Command Line
Open a command line from the location where your project’s pom.xml resides and run the following command.
> mvn spring-boot:run -Drun.profiles=native
Enabling Spring Security To Secure Your Configurations
If you want to protect your configurations from public access you can enable spring security by adding:
- spring-boot-starter-security dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
- define a username and password (in application.properties file)
security.user.name=my-user
security.user.password=my-password
Application Entry Point
@EnableConfigServer
@SpringBootApplication
public class Program {
/**
* The entry point of application.
*
* @param args the input arguments
*/
public static void main(String[] args) {
SpringApplication.run(Program.class, args);
}
}
Our Spring Cloud Server is ready by now. We just need to add our configuration files under the location we specified in:
spring.cloud.config.server.native.search-locations=...
Supporting Multiple Platforms
When we have multiple environments like development, staging, production we have different configuration files for each environment with the same name but with a different profile name like below:
- application.properties
- application-local.properties
- application-staging.properties
- application-production.properties
If we do not provide any spring profile while running our application application.properties
will be loaded by default. However, if we provide a spring profile than the properties file corresponding to that profile will be loaded automatically. (-Dspring.profiles.active=staging
)
Spring Cloud Config supports Spring profiles, therefore we can create different properties file for each environment like we do in any spring boot application.
Testing Your Spring Cloud Server App
- Run your application
- Open a browser
- Navigate to: http://host:port/contextPath/config-file-name/spring-profile
Note: If you do not provide server.contextPath
in your application.properties file, it will be empty by default.
A sample URL: http://localhost:8080/database/staging
You should get a response like the following:
{
"name": "database",
"profiles": [
"staging"
],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "classpath:/config/database-staging.properties",
"source": {
"driver": "org.postgresql.Driver"
}
}
]
}
Notice that the content of the source depends on what you put into your properties file.
Using Externalized Configurations in other Applications
To be able to use the externalized configurations we just made, we need to:
- add the required dependencies
- Provide the spring.cloud.config settings in
bootstrap.properties
(Notice that notapplication.properties
)
After that we can use any configuration file loaded with our Spring Cloud Config Server with any profile we need.
Required Dependencies
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Cloud Config Settings
In bootstrap.properties
(which is also automatically loaded by spring boot but earlier than application.properties
) we need to give our spring cloud server app’s settings:
spring.application.name=test
spring.cloud.config.uri=http://host:port/contextPath
spring.cloud.config.username=my-user
spring.cloud.config.password=my-password
Note that you don’t need to set spring.cloud.config.username
and spring.cloud.config.password
if you do not activate spring-security in your spring cloud config server app.
Now, we can use the configurations like they are in a properties file in the classpath:
- by injection with @Value or
- by using the
org.springframework.core.env.Environment
@Value("${driver}")
private String databaseDriver;
or
@Autowired
Environment environment;public void myAction(...) {
...
this.environment.getProperty("driver"); ...
}
Overriding Remote Property Values in Local Environment
If you want to override the values provided in the property files of your Spring Cloud Config Server, you need to add the following two settings into the properties
files loaded by your Spring Cloud Config:
spring.cloud.config.allow-override=true
spring.cloud.config.override-none=true
There is more to learn about spring cloud config but I hope this helps you with the basics.