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é



Zuul

Zuul

Zuul is an edge service that acts as an API gateway, handling routing, monitoring, and security in a microservice architecture.

  1. Dynamic routing of incoming requests
  2. Acts as an API Gateway
  3. Provides load balancing and rate limiting
  4. Enhances security through authentication and authorization

Example zuul +Eureka

Route configuration examples



# Route requests with /service1/** to http://localhost:8081/
zuul.routes.service1.path=/service1/**
zuul.routes.service1.url=http://localhost:8081

# Route requests with /service2/** to http://localhost:8082/
zuul.routes.service2.path=/service2/**
zuul.routes.service2.url=http://localhost:8082

# Dynamic routing based on Eureka (if using Eureka)
# Enables service discovery
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka
zuul.routes.service3.path=/service3/**
zuul.routes.service3.serviceId=SERVICE3   # Eureka service ID

Eureka Discovery server


package com.emsi.discoveryserver1;

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

@SpringBootApplication
public class Discoveryserver1Application {

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

}

Eureka Discovery server:application.properties


	 #Port for Registry service
server.port=8761
#Service should not register with itself
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#Managing the logging
logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF
	 

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>discoveryserver1</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>discoveryserver1</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-server</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>


	 

Client :microserviceA :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>microserviceclient1</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>microserviceclient1</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


	package com.emsi.microserviceclient1;

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

@SpringBootApplication
public class Microserviceclient1Application {

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

}


	 

application.properties


	 
	# Server Config
server.port=8081

# Spring Application Name
spring.application.name=microserviceclient1

# Eureka Client Config
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/


Test Rest


	

package com.emsi.microserviceclient1.controllers;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestC {
	@GetMapping("/test")
	public String hi()
	{
		return "hi";
	}
}
 

Zuul gateway

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>2.1.9.RELEASE</version> <!-- Spring Boot 2.1.x -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.emsi</groupId>
    <artifactId>zuulgateway1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>zuulgateway1</name>
    <description>Zuul Gateway for Spring Boot</description>

    <properties>
        <java.version>11</java.version> <!-- Use Java 11 -->
        <spring-cloud.version>Greenwich.SR6</spring-cloud.version> <!-- Spring Cloud Greenwich for Zuul -->
    </properties>

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

        <!-- Zuul Starter -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

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

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

        <!-- Spring Boot Test -->
        <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>


 

Application.properties


	 
# Server Port
server.port=8086

# Application Name
spring.application.name=zuulgateway1

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

# Zuul Routes
zuul.routes.hello.path=/hello/**
zuul.routes.hello.serviceId=microserviceclient1

Main


	 
	package com.emsi.zuulgateway1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
public class Zuulgateway1Application {

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

}

	 

Main


	 http://localhost:8086/hello/test
	 

Filter


	package com.emsi.zuulgateway1.filter;


import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@Component
public class CustomZuulFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return "pre"; // This filter will execute before routing the request
    }

    @Override
    public int filterOrder() {
        return 1; // Lower values are executed first
    }

    public boolean shouldFilter() {
        return true; // This filter will apply for all requests
    }

    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        // Example 1: Log Request Method and URL
        System.out.println("Request Method: " + request.getMethod());
        System.out.println("Request URL: " + request.getRequestURL().toString());

        // Example 2: Authentication Check
        String authToken = request.getHeader("Authorization");
        if (authToken == null || !isValidToken(authToken)) {
            ctx.setResponseStatusCode(401); // Unauthorized
            ctx.setResponseBody("Unauthorized access - token is missing or invalid.");
            ctx.setSendZuulResponse(false); // Prevent routing the request
            return null; // Early exit from filter
        }

        // Example 3: Modify Request Headers
        ctx.addZuulRequestHeader("X-Custom-Header", "CustomValue");

        // Example 4: Rate Limiting (Basic Example)
        Integer requestCount = (Integer) ctx.get("requestCount");
        if (requestCount == null) {
            requestCount = 0;
        }
        requestCount++;
        ctx.set("requestCount", requestCount);
        
        // Assuming a simple rate limit of 100 requests
        if (requestCount > 100) {
            ctx.setResponseStatusCode(429); // Too Many Requests
            ctx.setResponseBody("Rate limit exceeded - please try again later.");
            ctx.setSendZuulResponse(false); // Prevent routing the request
            return null; // Early exit from filter
        }

        // Example 5: Add Request Time to Header
        long startTime = System.currentTimeMillis();
        ctx.addZuulRequestHeader("X-Request-Time", String.valueOf(startTime));

        // Example 6: Validate Request Parameters
        String requiredParam = request.getParameter("requiredParam");
        if (requiredParam == null || requiredParam.isEmpty()) {
            ctx.setResponseStatusCode(400); // Bad Request
            ctx.setResponseBody("Missing required parameter: requiredParam");
            ctx.setSendZuulResponse(false); // Prevent routing the request
            return null; // Early exit from filter
        }

        // Example 7: IP Whitelisting
        List allowedIPs = Arrays.asList("192.168.1.100", "192.168.1.101"); // Example IPs
        String clientIP = request.getRemoteAddr();
        if (!allowedIPs.contains(clientIP)) {
            ctx.setResponseStatusCode(403); // Forbidden
            ctx.setResponseBody("Forbidden access - your IP is not allowed.");
            ctx.setSendZuulResponse(false); // Prevent routing the request
            return null; // Early exit from filter
        }

        // Example 8: Service Discovery and Redirection (Custom Logic)
        String serviceId = "microserviceclient1";
        if (serviceId.equals(request.getParameter("serviceId"))) {
            ctx.set("serviceId", serviceId); // Optionally set serviceId in context
        }

        // Example 9: Modify Request URL Path
        String newPath = "/modified-path" + request.getRequestURI();
        ctx.set("requestURI", newPath); // Modify the request URI
        ctx.set("requestPath", newPath); // Optionally set modified request path in context

        return null; // Returning null means no additional processing
    }

    // Method to validate the token (placeholder logic)
    private boolean isValidToken(String token) {
        return "valid-token".equals(token); // Replace with actual validation logic
    }
}