---
# System prepended metadata

title: Minio High PerformanceObject Storage
tags: [' minio', backend, ' support']

---

---
title: Minio High PerformanceObject Storage
tags: backend, minio, support
robots: noindex, nofollow
author: Julien Noyer
---

# Minio : High PerformanceObject Storage

![](https://i.imgur.com/K7kNY0O.png)

<br>

## Présentation de Minio et du principe de Cloud Computing

[Minio](https://min.io) est un système de gestion de stockage d'objets permettant de mettre en place des logiques de [Cloud Computing](https://fr.wikipedia.org/wiki/Cloud_computing), qui présente l'avantage d'être Open Source contrairement aux services proposées en ligne comme AWS. Le [Cloud Computing](https://fr.wikipedia.org/wiki/Cloud_computing) est un concept informatique qui défini des méthodes permettant d'automatiser des processus sur des serveurs distants ou non qui prennent la forme de services accessible via des URL.

Avec [Minio](https://min.io) il est possible par exemple de convertir automatiquement des fichier CSV en JSON pour ensuite générer une page HTML qui affiche un graphique correspondant aux données converties ou de d'entrainer un réseau de neurones depuis un fichier JSON ou CSV pour en exporter le modèle et générer une page HTML opur tester le modèle. Il ne s'agit que des deux exemple pour illustrer la quantité de possibilités offertes, la seule limite est votre imagination.

<br><br>

## Installer Minio

Nous utiliserons [Minio](https://min.io) via des lignes de commandes, dans un premier temps il faut suivre les étapes décrite dans les liens suivants : 

1) Télécharger et installer [MINIO SERVER](https://docs.minio.io/docs/minio-quickstart-guide)
2) Télécharger et installer [MINIO CLIENT](https://docs.minio.io/docs/minio-client-quickstart-guide)

> Il est essentiel de suivre les instructions des deux liens

<br>

Une fois l'installation de [MINIO SERVER](https://docs.minio.io/docs/minio-quickstart-guide) et [MINIO CLIENT](https://docs.minio.io/docs/minio-client-quickstart-guide), vous devez créer dans votre ordinateur un dossier dans lequel stocker les données du serveur [Minio](https://min.io) : 

```bash=
mkdir path-to/minio-data
```

<br>

Une fois ce dossier créé, nous pouvons taper la commande qui permet de lancer le serveur [Minio](https://min.io) : 

```bash=
minio server path-to/minio-data
```

<br>

La commande `server` de [Minio](https://min.io) permet de lancer le processus dans le dossier spécifié, il ne faut donc pas fermer la fenêtre utilisée précdemment au risque de couper le serveur [Minio](https://min.io). Le code qui s'affiche dans le terminal sont les `logs` serveur, c'est à dire des messages concernant son utilisation, le premier qui s'affiche ressemble au suivant : 

```bash=
Endpoint:  http://172.20.10.5:9000  http://127.0.0.1:9000          
AccessKey: <YourAccessKey> 
SecretKey: <YourSecretKey> 
SQS ARNs:  arn:minio:sqs::1:mqtt arn:minio:sqs::_:mqtt

Browser Access:
   http://172.20.10.5:9000  http://127.0.0.1:9000          

Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc alias set myminio http://172.20.10.5:9000 <AccessKey> <SecretKey>

Object API (Amazon S3 compatible):
   Go:         https://docs.min.io/docs/golang-client-quickstart-guide
   Java:       https://docs.min.io/docs/java-client-quickstart-guide
   Python:     https://docs.min.io/docs/python-client-quickstart-guide
   JavaScript: https://docs.min.io/docs/javascript-client-quickstart-guide
   .NET:       https://docs.min.io/docs/dotnet-client-quickstart-guide
```

<br>

Pour afficher l'interface serveur dans votre navigateur vous devez taper l'adresse `http://172.20.10.5:9000` dans laquelle il est demandé de rensigner les clefs `AccessKey` et `SecretKey`. 

Pour finir notre installation, nous allons à présent créer trois dossier dans le `minio-data` qui nous serons utiles pour la suite de ce support : 

```bash=
mkdir path-to/minio-data/csv
mkdir path-to/minio-data/json
mkdir path-to/minio-data/models
```

> Une fois ces dossier créé ils sont visible dans l'interface Web.

---

<br><br><br>

# Automatiser les processus en Javascript

![](https://i.imgur.com/Ie7Pxyc.png)

<br>

Le fait d'avoir installé et configuré correctement [Minio](https://min.io), ce n'est pas pour autant que le traitement automatique des inforùmations est faite, bien au contraire. Il reste la partie la plus passionnante du [Cloud Computing](https://fr.wikipedia.org/wiki/Cloud_computing) : définir les processus, construire les algorithmes.

Nous devons donc dans un premier temps définir l'environnement serveur que nous souhaitons utiliser, dans notre cas le Javascript. Parce que c'est écrit dans le titre, mais pas que ! L'avantage du Javascript est que c'est un langage à la fois client et serveur, et nous allons utiliser dans notre projet plusieurs librairies Javascript pour traiter l'information, ce qui place NodeJS en choix logique pour notre environnement serveur.

Nous n'allons pas aborder ici l'installation de NodeJS et NPM mais les techniques spécifiques à l'intégration de [Minio](https://min.io) en NodeJS. 

> Pour voir comment fonctionne NodeJS [cliquer ici](https://hackmd.io/@dws-teach/rkAcePutI).

<br><br>

## Configuration du serveur NodeJS

Dans un premier temps nous allons importer les modules suivants : 

```javascript=
/* 
Imports
*/
    const express = require('express');
    const bodyParser = require('body-parser');
    const ejs = require('ejs');
    const path = require('path');
    const Minio = require('minio')
    const multer = require('multer')
    const fs = require('fs')
    const d3 = require("d3");
    global.fetch = require('node-fetch');
//
```

> Il faut également installer les modules `npm i express bodyParser ejs path Minio fs d3 node-fetch'`.

<br>

Nous allons configurer notre serveur avec une classe afin de le rendre plus simple d'utilisation et mieux structuré : 

```javascript=
/* 
Server class
*/
    class ServerClass{
        constructor(){
            // Set up server
            this.server = express();
            this.port = <PORT-NODE>;

            // Set up Multer storage
            this.storage = multer.diskStorage({
                destination:  (req, file, callback) => {
                    callback(null, './uploads');
                },
                filename:  (req, file, callback) => {
                    callback(null, `${Date.now()}-${file.originalname}`);
                }
            });
        }

        init(){
            // Set CORS middleware
            this.server.use( (req, res, next) => {
                // Allow actions for specific origins
                res.header('Access-Control-Allow-Origin', ['http://127.0.0.1:<PORT-NODE>']);
                res.header('Access-Control-Allow-Credentials', 'true');
                res.header('Access-Control-Allow-Methods', ['GET', 'PUT', 'POST', 'DELETE', 'POST']);
                res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

                // Enable access to specific origins
                next();
            });

            // Set server view engine
            this.server.set( 'view engine', 'ejs' );
            
            // Static path configuration
            this.server.set( 'views', __dirname + '/www' );
            this.server.use( express.static(path.join(__dirname, 'www')) );

            //=> Body-parser
            this.server.use(bodyParser.json({limit: '10mb'}));
            this.server.use(bodyParser.urlencoded({ extended: true }));

            // Start server configuration
            this.config();
        };

        config(){
            // Load Minio object
            const minioClient = new Minio.Client({
                endPoint: <MINIO_URL>,
                port: <MINIO_PORT>,
                accessKey: <MINIO_ACCESS>,
                secretKey: <MINIO_SECRET>,
                secure: false
            });
            
            // Setup Minio Buckets
            const minioBucket = {
                csv: 'csv',
                json: 'json'
            };


            // Launch server
            this.launch();
        };

        launch(){
            // Start server
            this.server.listen(+this.port, () => {
                console.log({
                    node: `http://localhost:${this.port}`
                });
            });
        };
    }
//

/* 
Start server
*/
    const NODEapi_boilerplate = new ServerClass();
    NODEapi_boilerplate.init();
//
```

> Vous devez également créer deux dossiers à la racine du serveur : `uploads` et `www`.

<br>

Pour lancer le serveur NodeJS il suffi de taper la commande suivante dans le terminal : 

```bash=
npm start
```

<br><br>

## Préparer la gestion des processus automatisés

Nous disposons à présent de deux serveurs différents, le serveur [Minio](https://min.io) et le serveur NodeJS, qui sont connectés l'un à l'autre. Il s'agit d'une étape importante car pour mettre en place nos processus d'automatisation nous avons besoin à la fois d'un espace pour nos fonctions, NodeJS, et d'un espace pour nos fichier, [Minio](https://min.io). Le code dans un autre langage serait différents mais la base reste la même, grâce à ces deux serveurs nous pouvons stocker des fichiers et transformer ces fichiers via des fonctions spécifiques.

Nous allons à présent ajouter une nouvelle méthode à notre classe `ServerClass`. Cette fonction aura pour but de définir des routes serveur spécifiques pour chaqun des processus que nous allons mettre en place. Sous la méthode `config` nous ajoutons la suivante : 

```javascript=
setRouter(){
    // Launch server
    this.launch();
}
```

<br>

A la fin de cette méthode nous appellons la méthode `launch` initiallement appelée dans la méthode `config`. Nous devons donc éditer la finla méthode `config` pour y appeler la méthode `setRouter` à la place de `launch` : 

```javascript=
config(){
    ...
    
    // Set router
    this.setRouter();
}
```

---

<br><br><br>

# Créer un processus automatisé

![](https://i.imgur.com/A61StN4.jpg)

<br>

La méthode `setRouter` que nous venons de créer va nous permettre de capter les requêtes HTTP effectuées sur notre serveur NodeJS, ce par ce principe que nous allons pouvoir associer des URL à nos processus de façon de très simple. C'est une fois qu'une requête HTTP sur une des URLs de notre serveur NodeJS que nous déclancherons une fonction spécifique qui s'exécutera a chaque nouvelle requête.

<br><br>

## Stocker un fichier CSV, le convertir en JSON et stocker le nouveau fichier

Le processus que nous allons créer va nous permettre de convertir et de stocker des fichiers dans [Minio](https://min.io). Pour cela nous allons suivre les étapes suivantes : 

1) Créer une route `upload/csv` en méthode `POST`
2) Stocker le fichier sur NodeJS avec `Multer`
3) Convertir le fichier en JSON avec `D3.js`
4) Enregistrer le fichier CSV dans le dossier `csv`
5) Enrigistrer le fichier JSON dans le dossier `json`

<br>

Nous allons donc ajouter dans la méthode `setRouter` le code suivant avant de lancer la méthode `launch` : 

```javascript=

// Set a route to get uploaded files
this.server.post('/upload/csv', (req, res) => {

    // Set upload file
    const upload = multer({ storage : this.storage}).single('csv');

    // Upload file to './upload'
    upload(req, res, (err) => {
        if(err) { return res.render('index') } // Multer error: Upload file
        else{
            //Set variables for Minio
            var multerFile = `./uploads/${req.file.filename}`;
            var uploadName = req.file.filename;

            // Upload CSV file to Minio
            minioClient.fPutObject(minioBucket.csv, uploadName, multerFile, async (err, etag) => {
                if(err) { return res.render('index') } // Minio error: Upload CSV file
                else{
                    // Set variables to vonvert CSV
                    let fileUrl = `${minioClient.protocol}//${minioClient.host}:${minioClient.port}/${minioBucket.csv}/${uploadName}`;

                    // Convert CSV file from Minio to JSON
                    d3.csv(fileUrl)
                    .then( jsonData => {
                        // Upload JSON file to Minio
                        minioClient.putObject(minioBucket.json, jsonFileName, buffer, function(err, etag) {
                            if(err) { return res.render('index') } // Minio error: Upload JSON
                            else{ return res.render('index') };
                    })
                    .catch(err => res.render('index')) // D3js error: conversion fail
                };
        };
    });
});
```
<br>

Une fois la logique serveur finalisée, nous pouvons passer à celle cotés client. Nous devons pour tester notre processus créer une page Web qui contiendra à formualire pour permettre l'upload de fichier, nous allons donc créer un fichier dans le dossier `www` que nous nommons `index.ejs` et dans lequel nous ajoutons le code suivant : 

```htmlmixed=
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Serveur NodeJS/Minio</title>
        
        <!-- [CDN] Milligram CSS -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/milligram/1.4.1/milligram.css">
    </head>
    <body>
        <!-- Create upload file form -->
        <form 
                enctype="multipart/form-data"
                action="/upload/csv"
                method="post"
            >
            <label for="csv">Upload CSV file</label>
            <input type="file" name="csv" />
            <button type="submit">Upload</button>
        </form>
    </body>
</html>
```

> Pour tester le processus il faut ouvrir dans votre navigateur à l'adresse suivante `http://localhost:<PORT-NODE>`.

---

<br><br><br>

# Ressources

![](https://i.imgur.com/WMir0gH.jpg)

Index des liens vers les sujets traités dans ce document :

- **Répertoire du projet** https://github.com/DWS-paris/INGE2000stocker
- **Minio** https://min.io
- **Cloud Computing** https://fr.wikipedia.org/wiki/Cloud_computing
- **Développer une API REST en NodeJS** https://hackmd.io/@dws-teach/rkAcePutI