Spring Cloud Config Server and Config Client

In this tutorial on Spring Cloud you will learn how to create your own Spring Cloud Config Server and also, how to configure a Spring Boot Application to be a Spring Cloud Config Client.

Spring Cloud Config Server

Spring Cloud Config Server is a Spring Boot application. So to create our own Spring Cloud Config Server we need to first create a new Spring Boot Application. Follow the following tutorial to learn how to create a very simple Spring Boot application(contains a video tutorial).

POM.XML Dependencies 

Open pom.xml file of your new Spring Boot application and add the following dependency:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

also add the following dependency management section:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Spring Cloud Version

Specify the Spring Cloud version you want to use. At the time of writing this tutorial, the latest Spring Cloud version is Greenwich.RELEASE:

<properties>
    <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>

Complete POM.xml file

Here is my complete POM.xml file for a working Spring Cloud Config Server.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.appsdeveloperblog.photoapp.api</groupId>
    <artifactId>ConfigServer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>PhotoAppAPIConfigServer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

</project>

application.properties file

Update the application properties file with the following details:

server.port=8012
spring.application.name=PhotoAppAPIConfigServer
spring.cloud.config.server.git.uri = https://github.com/simplyi/PhotoAppConfigData
spring.cloud.config.server.git.username = USER NAME HERE
spring.cloud.config.server.git.password = PASSWORD HERE
spring.cloud.config.server.git.clone-on-start=true

where:

spring.cloud.config.server.git.uri  – is a URL to a PRIVATE repository which holds the shared configuration file. This configuration file contains properties which  Config Client applications pull from Config Server.

spring.cloud.config.server.git.username – A User Name to a private Git repository

spring.cloud.config.server.git.password – A Password to a private Git repository

Below is a sample configuration file which is stored in my private Git repository called “PhotoAppConfigData” and hosted on GitHub. 

PhotoAppAPIConfigServer.properties

token.secret = jf9i4jgu83nfl0jfu57ejf1

Please note: 

The name of the properties file stored in a Git repository should be called after the name of a Spring Cloud Configuration Server. The name of Spring Cloud Configuration Server is specified in application.properties file of your Spring Cloud Config server. In my example above it is:

spring.application.name=PhotoAppAPIConfigServer

Since the name of my Spring Cloud Config Server is “PhotoAppAPIConfigServer”, then the name of a shared config file stored in a private Git repository is “PhotoAppAPIConfigServer.properties”.

@EnableConfigServer Annotation

Annotate Spring Boot application main class with @EnableConfigServer annotation.

package com.appsdeveloperblog.photoapp.api.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);
 }
        
}

Now you should be able to start your application and preview properties Spring Config Server pulls from private Git Repository. If you start your application on localhost then the following URL should work.

http://localhost:8012/PhotoAppAPIConfigServer/default

where:

  • 8012 – is the port number on which we have started our Config Server,
  • PhotoAppAPIConfigServer – is application name defined in Spring Cloud Config Server application.properties file,
  • default – is a profile name. Since we did not use any profiles in this example, a default is used.

You should now have your Spring Cloud Config Server starter and working with a very basic configuration. There is more to learn about Config Server but the basic setup explained in this tutorial should help you to get started. Let’s now learn how to configure a Spring Boot Application to be a client of our Config Server.

Spring Cloud Config Client

Spring Cloud Config Client is also a Spring Boot application. So if you do not have one, follow this tutorial to learn how to create a very simple Spring Boot application using Spring Initializr.

pom.xml dependency

Once you have your Spring Boot application created, open its POM.xml file and add the following dependency:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

Spring Cloud version

Add Spring Cloud version to a properties element.

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.RC2</spring-cloud.version>
</properties>

bootstrap.properties file

When working with Spring Boot and Spring Cloud projects we usually specify configuration details either in application.properties or application.yml file. This time, additionally to already existing application.properties or application.yml file we need to create a new bootstrap.properties file. This file will be loaded before  the application.properties file loads and before Java beans are created during the application starts up.

Specifying the below two properties in a bootstrap.properties file will enable our Beans to initialize with the properties loaded from Spring Cloud Config Server.

There must be at least two following properties defined in your bootstrap.properties file:

spring.cloud.config.uri=http://localhost:8012
spring.cloud.config.name=PhotoAppAPIConfigServer

where:

  • spring.cloud.config.uri – is the URI to your Spring Cloud Config Server,
  • spring.cloud.config.name – is the name of your Spring Cloud Config Server.

Reading Properties

We read properties loaded by Config Client application from a Config Server just the same way we read properties from an application.properties file in a regular Spring Boot Application. Nothing changes here.

For example, to read a property value in your RestController class you can follow the below code example:

@RestController
@RequestMapping("/users")
public class UsersController {
    
    @Value("${token.secret}")
    String token;
 

    @Value("${server.port}")
    private String port;

    @GetMapping("/status/check")
    public String status() {
        return "Working on port " + port + " with token " + token;
    }
}

Where:

@Value(“${token.secret}”) -will read the value of a token.secret property key. If this key is available in a property file loaded by a Config Server then it will be assigned to a String variable “token” defined in the above Controller class. If the key is not found in the property file loaded from a Config Server application, then its value will be read from a local application.properties file.

You can also read properties using the Environment object. Have a look at the following tutorial to learn more about how to read values from application.properties file in Spring Boot Application.

Values loaded by Config Server always have higher priority. Which means that even if your Config Client application also has its own application.properties file with a key token.secret defied, the value loaded for the same key from a Config Server will be used.

I hope this tutorial was helpful to you. If you would like to learn more about Spring Cloud and like learning by following a step by step series of video lessons, then have a look at the below list of video courses. One of them might be just what you are looking for.