Implémentation d'un serveur de configuration Spring Cloud en environnement local

Architecture de Spring Cloud Config

Spring Cloud Config fournit une solution client-serveur permettant de centraliser et d'externaliser les propriétés des applications au sein de systèmes distribués. Le serveur de configuration (Config Server) agit comme un référentiel unique et environnement-agnostique, tandis que les microservices clients interrogent ce serveur pour récupérer leurs paramètres spécifiques lors de leur initialisation.

Déploiement du Config Server

Pour mettre en place le serveur, il est nécessaire de créer une application Spring Boot intégrant la dépendance spring-cloud-config-server. Voici une structure de projet modernisée (basée sur Spring Boot 2.7) :

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>io.techguide.config</groupId>
    <artifactId>config-repo-server</artifactId>
    <version>1.0.0</version>
    <name>Configuration Server</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
    </parent>

    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2021.0.8</spring-cloud.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>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

L'activation du serveur s'effectue via l'annotation @EnableConfigServer sur la classe principale de l'application :

package io.techguide.config;

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);
    }
}

Par défaut, Spring Cloud Config utilise un dépôt Git. Pour un environnement de développement local, il faut activer le profil "native" et définir un répertoire cible. Dans le fichier application.yml du serveur :

server:
  port: 8888

spring:
  profiles:
    active: native
  cloud:
    config:
      server:
        native:
          search-locations: file:./local-configs

Créez ensuite le dossier local-configs à la racine du projet et ajoutez-y un fichier nommé payment-service-dev.yml contenant les paramètres de la base de données :

datasource:
  payment:
    url: jdbc:postgresql://localhost:5432/payment_db
    driver-class-name: org.postgresql.Driver
    username: db_admin
    password: secure_password_123

Le serveur étant opérationnel sur le port 8888, la publication de la configuration peut être vérifiée en accédant à l'endpoint http://localhost:8888/payment-service/dev.

Intégration du Config Client

Le microservice client doit inclure le starter Config Client. À partir de Spring Boot 2.4, la lecture du fichier bootstrap est désactivée par défaut. Il est donc nécessaire d'ajouter la dépendance spring-cloud-starter-bootstrap pour conserver cette approche.

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

La connexion au serveur de configuration est établie dans le fichier bootstrap.yml, qui est chargé préalablement au contexte applicatif principal :

spring:
  application:
    name: payment-service
  cloud:
    config:
      uri: http://localhost:8888
      profile: dev

server:
  port: 8081

Pour récupérer et structurer les propriétés distantes, une approche orientée objet utilisant @ConfigurationProperties est préférable à l'injection unitaire par @Value. Créez la classe de mapping suivante :

package io.techguide.payment.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "datasource.payment")
public class DatabaseProperties {
    private String url;
    private String driverClassName;
    private String username;
    private String password;

    // Getters et Setters omis pour concision
    public String getUrl() { return url; }
    public void setUrl(String url) { this.url = url; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public String getDriverClassName() { return driverClassName; }
    public void setDriverClassName(String driverClassName) { this.driverClassName = driverClassName; }
}

Ces propriétés peuvent ensuite être exposées via un contrôleur REST pour validation :

package io.techguide.payment;

import io.techguide.payment.config.DatabaseProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class PaymentClientApplication {

    private final DatabaseProperties dbProperties;

    public PaymentClientApplication(DatabaseProperties dbProperties) {
        this.dbProperties = dbProperties;
    }

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

    @GetMapping("/database-info")
    public String displayDatabaseConfig() {
        return String.format("Connected to %s with user '%s'", 
                dbProperties.getUrl(), 
                dbProperties.getUsername());
    }
}

Lors du démarrage de l'application cliente sur le port 8081, celle-ci contacte le Config Server pour obtenir le fichier payment-service-dev.yml. L'appel à l'URL http://localhost:8081/database-info renvoie les valeurs dynamiques chargées depuis le système de fichiers local du serveur, démontrant ainsi la synchronisation réussie entre les deux instances.

Étiquettes: spring-cloud-config spring-boot Microservices Java Configuration-Management

Publié le 29 juin à 03h58