Introduction to Spring Cloud Config 
Tags: microservices, java
Published: 2020-11-14 20:48:08

In my [previous article](https://dev.to/devfanooos/managing-configurations-in-microservices-1l1o) I have mentioned four products/applications for managing configuration in microservices architecture. In this article we will explain the first option (Spring Cloud Config)


## What is spring cloud config
Spring cloud config is part of spring cloud tool set for developing cloud native application and microservices. It provides server and client support for externalize configurations in a distributed systems. 

![Spring cloud server](https://dev-to-uploads.s3.amazonaws.com/i/51asjbdxbw5qv5dt42qp.png)

In much simpler words, spring cloud config is a normal spring project that reads configurations from a centralized configuration repository and provides these configuration to other application (microservices). 


## Setting up the config server.
Getting spring cloud config server is easy as much as creating any other spring project. 

* Go to [start.spring.io](https://start.spring.io/)
* Set the project name (Artifact) to config-server and in the dependencies section add config server.
* Download the zipped file (config-server.zip).
* Extract the project `$ unzip config-server.zip`.
* In the **ConfigServerApplication** class add **@EnableConfigServer** annotation.

```
package com.example.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

	public static void main(String[] args) {
         SpringApplication.run(ConfigServerApplication.class, args);
	}
}
```


* Execute the following commands to create a local git repository. This git repository will be used by the spring config server as the source of configuration for the other service.
```
$mkdir config-repo
$cd config-repo
$echo "foo.property=property_dev_value" > my-service-dev.properties
$echo "foo.property=property_sit_value" > my-service-sit.properties
$echo "foo.property=property_prod_value" > my-service-prod.properties
$git init
$git add .
$git commit -m"Adding configurations"
```
* Add the following properties to the `application.properties` file.
```
spring.cloud.config.server.git.uri=file://${user.home}/config-repo
spring.cloud.config.server.git.clone-on-start=true
```
* Build the project `$ cd config-server && mvn clean package`.
* Run the project `$ java -jar target/config-server.VERSION.jar`.

Now you have a full featured configuration server up and running. 


## Creating a spring boot client application.
Now we need to create another application that will act as a microservices that needs to load its configuration from our configuration server. 
Obviously we will use spring boot and the other part of spring cloud config project (the client library).
<br/>
There are two points we need to mention here before getting into the steps of creating the client. 
1. As the configuration of any project usually needs to be loaded at the startup process, we need to change the behavior of application bootstraping. This happens just by adding a new file `bootstrap.properties` to the resources directory.  
2. The link between the client application and the config server is the application name. In our case `my-service`. 

<br/>
Here are the steps needed to create a client application.
* As usual, go to [start.spring.io](https://start.spring.io/)
* set the project name (Artifact) to my-service.
* add `config client` to the dependencies.
* Change `MyserviceApplication.java` class to be as following
```
package com.example.myservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;

@SpringBootApplication
@RefreshScope
public class MyserviceApplication {

	public static void main(String[] args) {
		SpringApplication.run(MyserviceApplication.class, args);
	}

}
```
* Add `bootstrap.properties` file to the resource directory and write the following configuration into it.
```
server.port=8081
spring.application.name=my-service
spring.cloud.config.uri=http://localhost:8080
```
The `spring.cloud.config.uri` property is pointing to the URL of the config server.
* For testing, we will create a REST controller `ConfigController`, inject a value from the properties files in the configuration server (`foo.property`), then display the value. For that purpose, create the following class. 
```
package com.example.myservice;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigController{


    @Value("${foo.property: nothing}")
    private String configProperty;


    @GetMapping("/getConfigs")
    public String getConfigProperty(){
        return this.configProperty;
    }
}
```

* Package the client application `$mvn clean package`
* Run the client application `$java -jar target/myservice.VERSION.jar`.
<BR/>
Now if you open this URL (http://localhost:8081/getConfigs) in the browser, you should see the value of the `foo.property` displayed. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xp63h0m3czon8m4sc19o.png)
* If you want to get the configuration of another profile, you have to set the `spring.profiles.active` property in the `bootstrap.properties` file.
```
spring.profiles.active=prod
```
Now if you package and rerun the application, you will get the value of the same property from the `prod` profile.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qeww2q7ws04axxz3ackm.png)
<br/>
<br/>

## Final note.
At the time of writing this article, I faced an issue getting the client up and running using spring boot version `2.4.0`. I had to use the previous stable version `2.3.6`.