Durant cette période de la crise du Corona virus, j’ai décidé de développer une application web qui offre la visualisation en temps réel de statistiques sur le nombre de cas confirmés, de morts, et de rétablis par rapport à chaque pays. Il est ainsi possible de visualiser l’évolution de cette pandémie à travers le monde. Cette application offre également une option de souscription par e-mail pour recevoir toutes les heures une version à jour des données.

L’application est visible depuis cette adresse : http://d2k4kmhlb161h9.cloudfront.net/index.html

Architecture utilisée

Pour bien comprendre le fonctionnement de l’application, nous allons commencer par une présentation de l’architecture utilisée.

Comme présenté dans l’architecture ci-dessus il y’a deux API :

  • Covid 19-API : qui permet de récolter les données sur le virus.
  • Mailing-API : qui permet d’envoyer des mails aux utilisateurs inscrits dans la base de données.

Notre page web communique avec les deux API.

Services cloud utilisés

Pour le déploiement de l’application j’ai utilisé 3 services offert par AWS qui sont :

  • Amazon s3
  • Amazon CloudFront
  • Amazon EC2

Amazon S3

Amazon Simple Storage Service (Amazon S3) est un service de stockage d’objet offrant une scalabilité, une disponibilité des données, une sécurité et des performances de pointe. Ce service est utilisé afin de stocker et protéger n’importe quelle quantité de données pour un large éventail de cas d’utilisation comme des sites web, des applications mobiles, la sauvegarde et la restauration, l’archivage, des applications d’entreprise, des appareils IoT et des analyses du Big Data.

Dans mon cas je l’ai utilisé pour le stockage du frontend de l’application développé en Angular que vous allez voir par la suite.

Amazon CloudFront

Pour fournir du contenu aux utilisateurs finaux avec une latence plus faible, Amazon CloudFront exploite un réseau mondial de 216 points de présence (205 emplacements périphériques et 11 caches périphériques régionaux) dans 84 villes de 42 pays.

Amazon EC2

Amazon Elastic Compute Cloud (Amazon EC2) est un service Web qui fournit une capacité de calcul sécurisée et redimensionnable dans le Cloud. Destiné aux développeurs, il est conçu pour faciliter l’accès aux ressources de Cloud Computing à l’échelle du Web.

Ce service a été utilisé pour déployer l’API du mailing que nous allons aborder de suite.

Mailing API

Avant de continuer la lecture, je vous invite à récupérer le code source de cette API sur : https://github.com/INGENIANCE/Covid-19-RT-Statistics-BackEnd

Cette API est sous forme d’un micro service développé en Java et utilisant le framework Spring Boot. Ce dernier permet d’ajouter des adresses e-mails à la base de données et de planifier des envois de mailing.

La planification de l’envoi des emails est faite par le scheduler qui est un processus d’exécution des tâches pour la période de temps spécifique. Spring Boot fournit un bon support pour écrire un planificateur sur les applications Spring.

Extrait du code du Scheduler

@Component
public class Scheduler {

    @Autowired
    private IDao daoService;

    private Cases cases=Cases.getInstence();

    @Scheduled(fixedRate = 100000)
    public String sendMail() throws JsonProcessingException {
        final String uri = "https://coronavirus-monitor.p.rapidapi.com/coronavirus/cases_by_country.php";

        final HttpHeaders headers = new HttpHeaders();
        headers.set("x-rapidapi-host","coronavirus-monitor.p.rapidapi.com");
        headers.set("x-rapidapi-key", "6356e62fc7msh27272757a761a13p18e27cjsn8d58dbbf0f26");

        // HttpEntity<String>: To get result as String.
        HttpEntity<String> entity = new HttpEntity<String>(headers);

        // RestTemplate
        RestTemplate restTemplate = new RestTemplate();

        // Send request with GET method, and Headers.
        ResponseEntity<String> response = restTemplate.exchange(uri,
                HttpMethod.GET, entity, String.class);

        String result = response.getBody();

        ObjectMapper objectMapper=new ObjectMapper();
        JSONObject jsonObject=objectMapper.readValue(result,JSONObject.class);
        System.out.println(jsonObject.countries_stat.length);
        System.out.println(result);

        StringBuilder message=new StringBuilder();
        message.append("Updates : ( new informations ) !!\n\n");

        boolean sendMessage=false;

        for (Country country : jsonObject.countries_stat) {
            if(cases.add(country.country_name,country.cases,country.deaths,country.total_recovered)) {
                message.append(country.country_name + " ====> Cases : " + country.cases +
                ",   Deaths : " + country.deaths + ",   Total Recovered : " + country.total_recovered +
                ",   (New cases : " + country.new_cases + ",   New Deaths : " + country.new_deaths + 
                ",   Serious/critical : " + country.serious_critical + ",    Active Cases : " + country.active_cases + ") \n\n");
                sendMessage = true;
            }
        }

        if(sendMessage){
            message.append("\n LastUpdates : "+jsonObject.statistic_taken_at);

            Mail email=new Mail(null,message.toString(),"Covid Updates !! ");
            System.out.println("Exec............................");
            return daoService.sendEmail(email.getText(),email.getSubject());
        }

        return "No updates";
    }
}

Déploiement du Mailing API

Comme évoqué plus haut, j’ai utilisé le service EC2 pour le déploiement du service de mailing. Et pour faciliter la construction de l’architecture j’ai donc utilisé docker-compose qui est un fichier texte que docker sera capable de lire et interpréter en exécutant la commande suivante depuis une fenêtre Bash :

docker-compose up

Comme dans le schéma ci-dessus j’ai utilisé deux images docker :

  • L’image MySQL que j’ai tiré à partir de docker hub.
  • L’image Spring Boot contenant l’API de mailing que j’ai créé.

Pour créer l’image Spring Boot je suis passé par le Dockerfile suivant qui contient deux étapes : une étape de build et une autre d’exécution.

# Build stage

FROM maven AS BUILD_STAGE
WORKDIR /app
COPY . .
RUN ["mvn", "clean", "install", "-DskipTests"]

# Run stage

FROM openjdk:11.0.6-jre-slim
WORKDIR /app
COPY --from=BUILD_STAGE /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-Dspring.profiles.active=container", "-jar", "app.jar"]

après avoir ces deux images il ne reste plus qu’à écrire le fichier docker-compose.yml.

version: "3"

services:

  db:
    image: mysql
    restart: on-failure
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: db_name

  web:
    build: .
    restart: on-failure
    depends_on:
      - db
    ports:
      - "8080:8080"

Vous pouvez vous passer de l’utilisation du docker-compose (mais vous perdez l’avantage de l’orchestration ) en lançant les deux conteneurs séparément en tapant les commandes suivantes :

# lancement du conteneur MySQL
docker container run --network covid19 --name db --network-alias db -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=db_name -d mysql

# Création de l'image de l'api
docker build -t api .

# Lancement du conteneur de l'api
docker container run --name api --network covid19 -p 80:8080 -d api

Frontend de l’application

Le FrontEnd a été développé en Angular 9 ( l’un des framework JavaScript les plus utilisé de nos jours ) que vous pouvez récupérer sur : https://github.com/INGENIANCE/Covid-19-RT-Statistics-FrontEnd

Le front se base principalement sur les deux API pour la récupération des données et l’envoi des adresses e-mails des utilisateurs à la base de données. Vous trouvez ci-dessous un extrait du code qui consomme l’API Covid-19 et l’API de mailing :

import { Injectable } from '@angular/core';
import {Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  constructor() { }

  public getData(): Observable<any>{
    
    return Observable.create(observer=>{
      let headers = new Headers({
        "Content-Type": "text/plain",
        "x-rapidapi-host": "coronavirus-monitor.p.rapidapi.com",
        "x-rapidapi-key": "6356e62fc7msh27272757a761a13p18e27cjsn8d58dbbf0f26",
      });
      
      
      let request = new Request('https://coronavirus-monitor.p.rapidapi.com/coronavirus/cases_by_country.php',
        { method: 'GET',
          headers: headers,
          mode: 'cors',
          cache: 'default'
        }
      );

      
      fetch(request)
      .then(response=>response.json())
      .then(data=>{
        observer.next(data.countries_stat);
        observer.complete();
      })
      .catch(function(err) {
        // Error :(
      });
    });
    
  }

}
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MailingService {

  constructor() {}

  public addEmail(email: string){
    fetch('http://ec2-18-222-10-165.us-east-2.compute.amazonaws.com/api/addUser?email='+email, {
        mode: 'no-cors',
        method:'GET',
        headers: {
        'Accept': '*/*',
        }
      });
  }
}

Deploiement du FrontEnd

Pour le déploiement du FrontEnd, la solution était d’utiliser les services Amazon S3 et Amazon CloudFront comme précisé plus haut, vu la faible latence proposée. Ainsi l’utilisateur ne peut pas accéder directement au Bucket S3, il doit impérativement passer par Amazon CloudFront comme le montre la figure ci-dessous.

Avantage de l’utilisation du CloudFront

  • Augmenter la disponibilité de l’application : mettre en cache les contenus dans les emplacements périphériques de CloudFront dans le monde entier et réduire la charge de travail sur le point d’origine.
  • Rentable : avec le paiement à l’utilisation d’Amazon CloudFront, on ne paye que ce qu’on utilise. Sans oublier que si on utilise les services d’origine AWS tels qu’Amazon S3, Amazon EC2 ou Elastic Load Balancing, on ne paye pas les données transférées entre ces services et CloudFront.

Conclusion

La crise est un moment propice pour se lancer dans le développement de nouvelles idées et d’applications, en mettant en œuvre les nouvelles technologies.

Références

Catégories : Software technology

0 commentaire

Laisser un commentaire

Avatar placeholder

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Covid-19 : Afficher des données statistiques avec Angular

par Zakaria M. temps de lecture : 6 min
0