Microservices – Configuration with Spring Boot

In this article we will learn What is configuration, Why is it important to understand and what are the goals we will be covering in the context of configuration.

Configuration is very essential thing for any production application. Any decent production application requires some kind of settings. Put right gears and switches to the right place so that application can behave properly. Best practice is to separate out the Configuration from Code.

Let’s say you want to connect to a database. So connect to a database you must be needing some configurations. We don’t hard-code those configurations in our Java files. It is recommended to keep any settings (or any other) related data attributes at separate place instead of hard-coding. We typically keep those configurations (url, username, password etc.) in some property or xml file (or any other configuration file). This is called as separation of Configuration from Code.

Configuration Examples
Database Connections
Credentials
Application specific settings
Feature flags – Toggling a particular feature in your application by enabling or disabling
Business logic configuration parameters
Scenario Testing
Spring Boot Configuration

Microservice Configuration Goals

Externalizing Configuration (Property files)
Environment Specific Properties (Spring Profiles)
Consistent Across all Microservices (Spring Cloud Config Server)
Maintaining Version History (Get Repository Source – Requires server restart)
Real-time Management (Endpoint to refresh configs)

Pre-requisites

Java with Spring Boot
Understanding of Microservices

1. Externalizing Configuration

Properties can be externalized by using property files. Spring reads default property file as application.properties or application.yml from resources folder (add if not available).

1.1 Adding properties in property file

application.properties is used to configure properties as key-value pair.
Example

example.message=Hello World!

1.2 Accessing properties from property file

To access properties from Property file, @Value annotation is used over fields.
Example

@Value("${example.message}")
private String msg;

1.3 Setting default property

What if property doesn’t exist in config file?
Application fails to start.
The way to set default value when property doesn’t exist in your configuration file is given below.

Example

@Value("${example.message: default value}")
private String msg;

1.4 Accessing properties as list from property file

To access comma separated properties from Property file, @Value annotation is used over fields. Field type can be declared as List and auto conversion works automatically.
Example

example.messages.list=Msg1,Msg2,Msg3
@Value("${example.messages.list}")
private List<String> messages;

1.5 Accessing properties as map from property file

To access properties defined as map (JSON format) from Property file, @Value annotation is used over fields. Field type can be declared as Map and auto conversion works automatically.

Example

example.messages.map={msg1: 'My Message 1', msg2: 'My Message 2'}
@Value("#{${example.messages.map}}")
private Map<String,String> myMap;

1.6 Accessing grouped properties as bean from property file

To access grouped properties from Property file, @ConfigurationProperties annotation is used over class.

Example

example.messages.map={msg1: 'My Message 1', msg2: 'My Message 2'}
@Value("#{${example.messages.map}}")
private Map<String,String> myMap;

1.7 Overriding properties

Properties available in application.properties can be overridden while running the application by the way mentioned below.

java -jar product-details-service-1.0.jar --example.message="This is overridden message"

1.8 Overriding property file

Place application.properties with overridden properties in the location where your application resides. When you run your application your file will be picked up with overridden properties.

2. Environment Specific Properties

When your application is in development phase you require to run your application in different environments such as Dev, QA or UAT. Properties can be set specific to particular environment using Spring Profiles.

3. Consistent Across all Microservices

Let’s discuss about the scenario related to consistency first.

You have deployed multiple instances of a microservice (e.g. i1, i2, i3). Let’s say you need some configuration related changes in your microservice. You made changes and restarted i1. But you haven’t restarted i2 and i3. So configuration values in all the instances of your microservice are not consistent. So other microservices communicating with your microservice (Load balancing enabled) may get different results based on your configuration for each instance.

To overcome this issue we have bunch of options we can make use of.
1. Apache Zookeeper
2. ETCD – Distributed key-value store
3. Hashicorp Consul
4. Spring Cloud Configuration Server

We will be configuring Spring Cloud Configuration Server in this article to resolve consistency issue.

Configuring Spring Cloud Configuration Server
// Write configuration steps here

4. Maintaining Version History

Spring Cloud Configuration Server can communicate with Git/SVN Repo and get the configurations committed in repo. This is how it maintains the version history of configurations.

Configuring Spring Cloud Config Server to communicate with Git repo
// Write configuration steps here

5. Real-time Management

For managing the configurations in real time, Spring boot exposes an endpoint to refresh the configurations cached in your Spring Cloud Config Server.

Configuring Spring Cloud Config Server for Real-time management
// Write configuration steps here

6. Best Practices

// Write best practices here

Author: Mahesh

Technical Lead with 10 plus years of experience in developing web applications using Java/J2EE and web technologies. Strong in design and integration problem solving skills. Ability to learn, unlearn and relearn with strong written and verbal communications.