Cloud computing

Introduction

Architecture de Spring Cloud

Eureka Config Serve Zuul Consul Hystrix Resilience4J

Spring Boot (BackEnd) TPs

Creation,Dépendance,Configuration Exemple Video RestController

Produit Rest API

Entity et repository Ajouter Afficher Liste Produit Détails,Supprimer,Vider Modifier

Angular (FrontEnd)

Angular Rappel CLient CRUD

Spring Security

User Auth

CRUD

Vente CRUD

To be Continued...

Middlewares Orientés Messages

Communication Synchrone vs. Asynchrone API JMS : Java Message Service JMS avec ActiveMQ et HornetQ KAFKA

Spring Batch

Spring Batch

Stream Processing

Kafka Streams

Architectures Serverless

Architectures Serverless Résumé



Tutoriel: Architecture de Spring Cloud

Introduction

Spring Cloud est une solution robuste pour créer des systèmes distribués et des microservices. Il aide à gérer la complexité des architectures distribuées avec des composants clés comme Eureka, Config Server, Zuul, et Hystrix.

Cloud Computing Architecture for Spring Cloud

Cloud Computing Architecture for Spring Cloud detailed

Cloud Computing Architecture for Azure Services

  1. Spring Boot Microservices (Service A, B, and C):

    • Role: These are the core business services that provide functionality like fetching data, processing requests, etc.
    • Input: Requests from clients or other services routed via Zuul.
    • Output: Processed data or service responses sent back to the requesting client or service.
  2. Eureka Server:

    • Role: Acts as a service registry where all services (Service A, B, and C) register themselves. It allows services to discover each other dynamically.
    • Input: Registration requests from services and discovery requests from other services (or Zuul).
    • Output: Service instances' metadata and location information.
  3. Config Server:

    • Role: Provides a centralized external configuration for all services (Service A, B, C). Configurations are typically stored in a Git repository.
    • Input: Configuration requests from services (Service A, B, C) when they start or refresh.
    • Output: Configuration properties such as URLs, database credentials, or feature toggles.
  4. Zuul Gateway:

    • Role: Acts as an API Gateway that routes external requests to the correct microservice (Service A, B, or C). It provides a unified entry point for all external requests.
    • Input: HTTP requests from clients.
    • Output: Routed responses from appropriate microservices back to the client.
  5. Hystrix:

    • Role: Provides fault tolerance and latency tolerance for distributed systems. It wraps service calls in a circuit breaker pattern, so if one service is down or slow, the system continues to function by either providing fallback responses or short-circuiting the failed request.
    • Input: Service calls (via Feign clients) made from one service to another.
    • Output: Either the normal service response or a fallback response if the service is down.

Eureka

Eureka is a service registry that allows microservices to register themselves so they can be discovered by others.

  1. Service Registration and Discovery
  2. Instance management in dynamic cloud environments
  3. Supports high availability through failover mechanisms
  4. Rest-based client-server interactions

Exemple

Étapes pour configurer un projet Spring Cloud

Voici un guide étape par étape pour configurer une architecture de microservices avec Spring Cloud.

Étape 1: Créer un projet Spring Boot

  • Accédez à https://start.spring.io/
  • Sélectionnez les dépendances Spring Web et Spring Cloud Dependencies
  • Générez le projet et importez-le dans votre IDE préféré (IntelliJ, Eclipse, etc.)

Étape 2: Eureka Server Setup

pom.xml


<?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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.9</version>  <!-- Downgraded Spring Boot to a compatible version -->
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<groupId>com.emsieureka</groupId>
	<artifactId>eurekaserver</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>eurekaserver</name>
	<description>Demo project for Spring Boot Eureka Server</description>

	<properties>
		<java.version>17</java.version>
		<spring-cloud.version>2022.0.1</spring-cloud.version> <!-- Spring Cloud 2022.x release train -->
	</properties>
	
	<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>

	<dependencies>
		<!-- Spring Boot Web Starter -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!-- Eureka Server -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
		</dependency>

		<!-- Spring Boot DevTools -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>

		<!-- Spring Boot Test Starter -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Main Class (EurekaServerApplication.java)

package com.emsieureka.eurekaserver;

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

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication // Indique que c'est une application Spring Boot, activant l'auto-configuration et le scan des composants
@EnableEurekaServer // Active cette application en tant que serveur Eureka, permettant la découverte de services
public class EurekaServerApplication { // Classe principale de l'application serveur Eureka
    public static void main(String[] args) { // Point d'entrée de l'application Java
        SpringApplication.run(EurekaServerApplication.class, args); // Lance l'application Spring
    }
}

application.properties


spring.application.name=eurekaserver
server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

2. Service A: Greeting Service

il faut créer un projet spring Boot appler Service1

pom.xml


<?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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.emsi</groupId>
	<artifactId>serviceA</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>serviceA</name>
	<description>Demo project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
		<spring-cloud.version>2023.0.3</spring-cloud.version>
	</properties>
	
	<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version> <!-- Use property for version -->
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>


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

</project>

Main Class (ServiceAApplication.java)


package com.emsi.serviceA;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication // Indique que c'est une application Spring Boot, activant l'auto-configuration et le scan des composants
@EnableDiscoveryClient
public class ServiceAApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceAApplication.class, args);
    }
}

@RestController
class GreetingController {

    @GetMapping("/greeting")
    public String getGreeting() {
        return "Hello from Service A!";
    }
}

application.properties


spring.application.name=serviceA
server.port=8081


eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

	  

3. Service B: Date Service

il faut créer un projet spring Boot appeler Service2

pom.xml


<?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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.emsi</groupId>
	<artifactId>serviceB</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>serviceB</name>
	<description>Demo project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
		<spring-cloud.version>2023.0.3</spring-cloud.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</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>

</project>

Main Class (ServiceBApplication.java)

package com.emsi.serviceB;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;

@SpringBootApplication // Indique que c'est une application Spring Boot, activant l'auto-configuration et le scan des composants
@EnableDiscoveryClient
public class ServiceBApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceBApplication.class, args);
    }
}

@RestController
class DateController {

    @GetMapping("/date")
    public String getCurrentDate() {
        return "Current Date: " + LocalDate.now();
    }
}

application.properties

server.port=8082

spring.application.name=service-b

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

	  

4. Service C: Aggregator Service

il faut créer un projet spring Boot appeler Service3

pom.xml


<?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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.emsi</groupId>
	<artifactId>serviceC</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>serviceC</name>
	<description>Demo project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
		<spring-cloud.version>2023.0.3</spring-cloud.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>


  

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</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>

</project>


Main Class (ServiceCApplication.java)

package com.emsi.serviceC;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;

@SpringBootApplication // Indique que c'est une application Spring Boot, activant l'auto-configuration et le scan des composants
@EnableDiscoveryClient
@EnableFeignClients // Active l'utilisation des clients Feign pour effectuer des requêtes HTTP vers d'autres services
public class ServiceCApplication { // Classe principale de l'application
    public static void main(String[] args) { // Point d'entrée de l'application Java
        SpringApplication.run(ServiceCApplication.class, args); // Lance l'application Spring
    }
}

@RestController // Indique que cette classe est un contrôleur Spring MVC avec des capacités RESTful
class AggregatorController { // Contrôleur pour gérer les requêtes entrantes et agréger les données

    @Autowired // Injecte le bean GreetingClient
    private GreetingClient greetingClient; // Client Feign pour appeler le Service A

    @Autowired // Injecte le bean DateClient
    private DateClient dateClient; // Client Feign pour appeler le Service B

    @GetMapping("/aggregate") // Mappe les requêtes HTTP GET vers cette méthode à l'endpoint "/aggregate"
    public String getAggregateData() { // Méthode pour agréger les données des deux services
        String greeting = greetingClient.getGreeting(); // Appelle le Service A pour obtenir le message de salutation
        String date = dateClient.getCurrentDate(); // Appelle le Service B pour obtenir la date actuelle
        return greeting + " | " + date; // Retourne la réponse agrégée
    }
}

@FeignClient(name = "service-a") // Déclare un client Feign pour le Service A avec le nom "service-a"
interface GreetingClient {
    @GetMapping("/greeting") // Mappe la requête HTTP GET vers l'endpoint "/greeting" du Service A
    String getGreeting(); // Méthode pour obtenir le message de salutation
}

@FeignClient(name = "service-b") // Déclare un client Feign pour le Service B avec le nom "service-b"
interface DateClient {
    @GetMapping("/date") // Mappe la requête HTTP GET vers l'endpoint "/date" du Service B
    String getCurrentDate(); // Méthode pour obtenir la date actuelle
}

application.properties


server.port=8083

spring.application.name=service-c

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

Run the Application


Start Eureka Server:

Run the Eureka Server application (EurekaServerApplication).
It will start on port 8761 and host the service registry.
Start Service A, Service B, and Service C:

Run each service on their respective ports (8081, 8082, 8083).
These services will automatically register themselves with the Eureka Server.
Test the Setup:

Access the Eureka Server dashboard at http://localhost:8761 to see the registered instances (service-a, service-b, and service-c).
Visit http://localhost:8083/aggregate to trigger Service C's aggregation. This will call Service A for a greeting and Service B for the current date and combine the results.