Close

Spring Cloud Config with File System Backend

[Updated: Jan 28, 2019, Created: Oct 16, 2018]

External Centralized configuration

Spring Cloud Config allows different cloud components (microservices, service-registry etc) to access configuration properties externally from a central place. The properties can be accessed in multiple environment (dev, test, production etc) without any changes to application components.

Cloud Config Server

The config properties are hosted on Spring Cloud Config Server.

To embed the config server we need to use @EnableConfigServer on our spring boot main class.

By default Spring Cloud Config uses a Git backend. A backend is where config properties are stored.

In this tutorial we will use File System Backend which is easier for getting started quickly and for testing.

To use File System Backend we need to specify followings in application.properties on the Cloud Config Server side:

  • spring.profiles.active=native
  • spring.cloud.config.server.native.searchLocations=<configFileLocations>

Where configFileLocations can be of classpath (using classpath:/ prefix) or locations on file system (using file:// prefix). If we don't specify this property then Spring Application default classpath are searched.

Cloud Config Clients

The configurations hosted by a Cloud Config Server can be accessed by a Config Client.
A Config Client can be a microservice, registry server or any other component in microservice architecture.
A Config Client can even be a standalone Spring Boot application.

The cloud externalized properties approach fits well with Spring Environment abstractions. The access of different environment properties on the client side is based on Spring Boot Loading Profile Specific properties.

We need to specify following properties on the client side (bootstrap.properties):

  • spring.cloud.config.uri where config server runs
  • spring.profiles.active=myProfileName
  • spring.application.name as comma-separated-list which are same as the names of property files used on the backend

Example

Cloud Config Server

pom.xml

<project .....>
<modelVersion>4.0.0</modelVersion>
<groupId>com.logicbig.example</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

src/main/resources/application.properties

server.port=7777
spring.profiles.active=native
spring.cloud.config.server.native.searchLocations=file:///D:/app-config

At location D:/app-config we have following files:

D:\app-config>dir /B
test-dev.properties
test-prod.properties
test2-dev.properties
test2-prod.properties

test-dev.properties:

test.greeting=Hi developer!

test2-dev.properties:

test.msg=How is your coding going?

test-prod.properties

test.greeting=Hi there!

test2-prod.properties

test.msg=How are you doing?

Boot main class

package com.logicbig.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

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

Run above class from your IDE.

Now we can access the backend via http://localhost:7777/{application}/{profile}

We can also access properties using following URLs:

/{application}-{profile}.yml
/{application}-{profile}.properties

Cloud Config Client

We are going to create a simple standalone Boot application as a Config Client.

pom.xml

<project .....>
<modelVersion>4.0.0</modelVersion>
<groupId>com.logicbig.example</groupId>
<artifactId>spring-cloud-config-client</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

src/main/resources/bootstrap.properties

spring.cloud.config.uri=http://localhost:7777
spring.application.name=test,test2
spring.profiles.active=dev

Example client bean

package com.logicbig.example;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;

@Component
public class ClientBean {
  @Value("${test.greeting}")
  private String msg1;

  @Value("${test.msg}")
  private String msg2;

  @PostConstruct
  public void postConstruct() {
      System.out.println(msg1);
      System.out.println(msg2);
  }
}

Main class

package com.logicbig.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


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

Run above class from your IDE.

Output

Hi developer!
How is your coding going?

On the client side, if we change the active profile property to spring.profiles.active=prod (in bootstrap.properties) and run the client again:

Hi there!
How are you doing?

Example Project

Dependencies and Technologies Used:

  • Spring Boot 2.0.5.RELEASE
    Corresponding Spring Version 5.0.9.RELEASE
  • Spring Cloud Finchley.SR1
  • spring-cloud-config-client 2.0.1.RELEASE: This project is a Spring configuration client.
  • spring-cloud-config-server 2.0.1.RELEASE: spring-cloud-config-server.
  • JDK 1.8
  • Maven 3.5.4

Spring Cloud Config with File System Backend Select All Download
  • spring-cloud-config-with-file-system-backend
    • spring-cloud-config-client
      • pom.xml
      • spring-cloud-config-server

    See Also