GSP644
Présentation
Il y a 12 ans, Lily a créé une chaîne de cliniques vétérinaires appelée
Pet Theory. Actuellement, Pet Theory envoie des factures au format DOCX à ses
clients, mais de nombreux clients se sont plaints de ne pas pouvoir les
ouvrir. Afin d'améliorer la satisfaction client, Lily a demandé à Patrick, du
service informatique, d'étudier une alternative pour améliorer la situation
actuelle.
L'équipe de développement de Pet Theory étant composée d'une seule personne,
elle souhaite investir dans une solution rentable qui ne nécessite pas
beaucoup de maintenance. Après avoir analysé les différentes options de
traitement, Patrick décide d'utiliser
Cloud Run.
Cloud Run fonctionne sans serveur. Cela permet d'éliminer toute la gestion de
l'infrastructure et de se concentrer sur la création de l'application sans se
soucier des coûts. En tant que produit Google sans serveur, il peut faire
l'objet d'un scaling à zéro instance, ce qui signifie qu'il n'entraîne aucuns
frais lorsqu'il n'est pas utilisé. Il vous permet également d'utiliser des
packages binaires personnalisés basés sur des conteneurs. Vous pouvez donc
désormais créer des artefacts isolés et cohérents.
Dans cet atelier, vous allez créer une application Web de conversion en PDF
sur Cloud Run, qui convertit automatiquement les fichiers stockés dans
Cloud Storage en PDF stockés dans des dossiers séparés.
Architecture
Ce schéma présente les services que vous allez utiliser et la manière dont ils
se connectent les uns aux autres :

Objectifs
Dans cet atelier, vous allez apprendre à :
- convertir une application Node.js vers un conteneur ;
- créer des conteneurs avec Google Cloud Build ;
-
créer un service Cloud Run qui convertit des fichiers en PDF dans le cloud ;
- utiliser le traitement des événements avec Cloud Storage.
Prérequis
Il s'agit d'un atelier de niveau intermédiaire recommandé aux
personnes qui maîtrisent déjà la console et les environnements de shell.
Connaître Firebase est utile, mais n'est pas obligatoire. Avant de commencer
cet atelier, il est recommandé d'avoir suivi les ateliers Google Skills
suivants :
Lorsque vous êtes prêt, faites défiler la page vers le bas et suivez les
indications pour passer à la configuration de l'environnement de votre
atelier.
Préparation
Avant de cliquer sur le bouton "Démarrer l'atelier"
Lisez ces instructions. Les ateliers sont minutés, et vous ne pouvez pas les mettre en pause. Le minuteur, qui démarre lorsque vous cliquez sur Démarrer l'atelier, indique combien de temps les ressources Google Cloud resteront accessibles.
Cet atelier pratique vous permet de suivre les activités dans un véritable environnement cloud, et non dans un environnement de simulation ou de démonstration. Des identifiants temporaires vous sont fournis pour vous permettre de vous connecter à Google Cloud le temps de l'atelier.
Pour réaliser cet atelier :
- Vous devez avoir accès à un navigateur Internet standard (nous vous recommandons d'utiliser Chrome).
Remarque : Ouvrez une fenêtre de navigateur en mode incognito (recommandé) ou de navigation privée pour effectuer cet atelier. Vous éviterez ainsi les conflits entre votre compte personnel et le compte temporaire de participant, qui pourraient entraîner des frais supplémentaires facturés sur votre compte personnel.
- Vous disposez d'un temps limité. N'oubliez pas qu'une fois l'atelier commencé, vous ne pouvez pas le mettre en pause.
Remarque : Utilisez uniquement le compte de participant pour cet atelier. Si vous utilisez un autre compte Google Cloud, des frais peuvent être facturés à ce compte.
Démarrer l'atelier et se connecter à la console Google Cloud
-
Cliquez sur le bouton Démarrer l'atelier. Si l'atelier est payant, une boîte de dialogue s'affiche pour vous permettre de sélectionner un mode de paiement.
Sur la droite, vous trouverez le panneau Préparation et accès à l'atelier, qui contient les éléments suivants :
- Le bouton Ouvrir la console Google Cloud
- Les identifiants temporaires (nom d'utilisateur et mot de passe) que vous devez utiliser pour cet atelier
- Des informations complémentaires vous permettant d'effectuer l'atelier, si nécessaire
Notez que le minuteur de l'atelier se trouve en haut de la page et indique le temps restant.
-
Cliquez sur Ouvrir la console Google Cloud (ou effectuez un clic droit et sélectionnez Ouvrir le lien dans une fenêtre en navigation privée si vous utilisez Chrome).
L'atelier lance les ressources, puis ouvre la page "Se connecter" dans un nouvel onglet.
Conseil : Réorganisez les onglets dans des fenêtres distinctes, placées côte à côte.
Remarque : Si la boîte de dialogue Sélectionner un compte s'affiche, cliquez sur Utiliser un autre compte.
-
Si nécessaire, copiez le nom d'utilisateur ci-dessous et collez-le dans la boîte de dialogue Se connecter.
{{{user_0.username | "Username"}}}
Vous trouverez également le nom d'utilisateur dans le panneau Préparation et accès à l'atelier.
-
Cliquez sur Suivant.
-
Copiez le mot de passe ci-dessous et collez-le dans la boîte de dialogue Bienvenue.
{{{user_0.password | "Password"}}}
Vous trouverez également le mot de passe dans le panneau Préparation et accès à l'atelier.
-
Cliquez sur Suivant.
Important : Vous devez utiliser les identifiants fournis pour l'atelier. N'utilisez pas les identifiants de votre compte Google Cloud.
Remarque : Si vous utilisez votre propre compte Google Cloud pour cet atelier, des frais supplémentaires pourront vous être facturés.
-
Accédez aux pages suivantes :
- Acceptez les conditions d'utilisation.
- N'ajoutez pas d'options de récupération ni d'authentification à deux facteurs (ce compte est temporaire).
- Ne vous inscrivez pas à des essais sans frais.
Après quelques instants, la console Cloud s'ouvre dans cet onglet.
Remarque : Pour accéder aux produits et services Google Cloud, cliquez sur le menu de navigation ou saisissez le nom du service ou du produit dans le champ Recherche.
Activer Cloud Shell
Cloud Shell est une machine virtuelle qui contient de nombreux outils pour les développeurs. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud. Cloud Shell vous permet d'accéder via une ligne de commande à vos ressources Google Cloud.
-
Cliquez sur Activer Cloud Shell
en haut de la console Google Cloud.
-
Passez les fenêtres suivantes :
- Accédez à la fenêtre d'informations de Cloud Shell.
- Autorisez Cloud Shell à utiliser vos identifiants pour effectuer des appels d'API Google Cloud.
Une fois connecté, vous êtes en principe authentifié et le projet est défini sur votre ID_PROJET : . Le résultat contient une ligne qui déclare l'ID_PROJET pour cette session :
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud est l'outil de ligne de commande pour Google Cloud. Il est préinstallé sur Cloud Shell et permet la complétion par tabulation.
- (Facultatif) Vous pouvez lister les noms des comptes actifs à l'aide de cette commande :
gcloud auth list
- Cliquez sur Autoriser.
Résultat :
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (Facultatif) Vous pouvez lister les ID de projet à l'aide de cette commande :
gcloud config list project
Résultat :
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
Remarque : Pour consulter la documentation complète sur gcloud, dans Google Cloud, accédez au guide de présentation de la gcloud CLI.
Tâche 1 : Comprendre la tâche
Pet Theory voudrait convertir ses factures en PDF pour avoir s'assurer que les
clients puissent les ouvrir. L'équipe veut réaliser cette conversion
automatiquement pour minimiser la charge de travail de Lisa, la responsable
des services administratifs.
Ruby, la consultante en informatique de Pet Theory, reçoit un message de
Patrick, du service informatique...
|
Patrick, Administrateur informatique
|
Bonjour Ruby,
J'ai fait quelques recherches et j'ai trouvé que
LibreOffice
est efficace pour convertir de nombreux formats de fichiers différents
en PDF.
Serait-il possible de faire fonctionner LibreOffice dans le cloud sans
avoir à gérer les serveurs ?
Patrick
|
|
Ruby, Consultante en logiciels
|
Bonjour Patrick,
Je pense que j'ai ce qu'il faut pour ce genre de situation.
Je viens de regarder sur YouTube une vidéo très intéressante de
Next 2019 sur
Cloud Run. Il semble que nous puissions faire fonctionner LibreOffice dans un
environnement sans serveur avec Cloud Run. Aucune maintenance du serveur
n'est nécessaire !
Je vais vous envoyer des ressources qui vous aideront à le mettre en
place.
Ruby
|
Aidez Patrick à mettre en place et à déployer Cloud Run.
Tâche 2 : Activer l'API Cloud Run
-
Ouvrez le menu de navigation (
), puis cliquez sur API et services >
Bibliothèque. Dans la barre de recherche, saisissez
"Cloud Run" et sélectionnez l'API Cloud Run Admin dans la
liste des résultats.
-
Si l'API n'est pas déjà activée, cliquez sur Activer,
puis deux fois sur le bouton "Retour" de votre navigateur. La
page doit se présenter comme suit :
Tâche 3 : Déployer un service Cloud Run simple
Ruby a développé un prototype de Cloud Run et aimerait que Patrick le déploie
sur Google Cloud. Aidez maintenant Patrick à mettre en place le service PDF
Cloud Run pour Pet Theory.
-
Ouvrez une nouvelle session Cloud Shell et exécutez la commande suivante
pour cloner le dépôt de Pet Theory :
git clone https://github.com/rosera/pet-theory.git
- Changez ensuite votre répertoire de travail actuel en lab03 :
cd pet-theory/lab03
-
Modifiez
package.json avec l'éditeur de code Cloud Shell ou
votre éditeur de texte préféré. Dans la section "scripts", ajoutez
"start": "node index.js",, comme indiqué ci-dessous :
...
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
...
-
Exécutez maintenant les commandes suivantes dans Cloud Shell pour installer
les packages que votre script de conversion utilisera :
npm install express
npm install body-parser
npm install child_process
npm install @google-cloud/storage
-
Ouvrez maintenant le fichier
lab03/index.js et vérifiez le
code.
L'application sera déployée comme un service Cloud Run qui accepte les POST
HTTP. Si la requête POST est une notification Pub/Sub concernant un fichier
importé, le service écrit les détails du fichier dans le journal. Sinon, le
service renvoie simplement la chaîne "OK".
- Examinez le fichier nommé
lab03/Dockerfile.
Le fichier ci-dessus est appelé un manifeste et fournit une recette pour la
commande Docker pour créer une image. Chaque ligne commence par une commande
qui indique à Docker comment traiter les informations suivantes :
-
La première ligne indique que l'image de base doit utiliser le nœud comme
modèle pour l'image à créer.
-
La dernière ligne indique la commande à exécuter, qui dans ce cas fait
référence à "npm start".
-
Pour créer et déployer l'API REST, utilisez Google Cloud Build. Exécutez
cette commande pour lancer le processus de compilation :
gcloud builds submit \
--tag gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter
La commande construit un conteneur avec votre code et le place dans
l'Artifact Registry de votre projet.
-
Revenez à la console Cloud, puis dans le
menu de navigation (
), cliquez sur Afficher tous les produits. Dans la
section CI/CD, sélectionnez
Artifact Registry > Dépôts. Vous devriez
voir votre conteneur hébergé :
-
Ouvrez le dépôt gcr.io. Vous devriez voir votre conteneur
hébergé :
Tester la tâche terminée
Cliquez sur Vérifier ma progression pour vérifier que vous
avez correctement effectué la tâche ci-dessus.
Créer une API REST simple
-
Retournez à votre onglet d'éditeur de code et, dans Cloud Shell, exécutez la
commande suivante pour déployer votre application :
gcloud run deploy pdf-converter \
--image gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter \
--region {{{ project_0.default_region | Region }}} \
--no-allow-unauthenticated \
--max-instances=1
Une fois le déploiement terminé, un message de ce type s'affiche :
Service [pdf-converter] revision [pdf-converter-00001] has been deployed and is serving 100 percent of traffic at https://pdf-converter-[hash].a.run.app
-
Créez la variable d'environnement
$SERVICE_URL pour
l'application afin de pouvoir y accéder facilement :
SERVICE_URL=$(gcloud run services describe pdf-converter --region {{{ project_0.default_region | Lab Region }}} --format="value(status.url)")
echo $SERVICE_URL
Tester la tâche terminée
Cliquez sur Vérifier ma progression pour vérifier que vous
avez correctement effectué la tâche ci-dessus.
Créer une révision pour Cloud Run
- Effectuez une requête POST anonyme à votre nouveau service :
curl -X POST $SERVICE_URL
Cela entraînera un message d'erreur indiquant
"Your client does not have permission to get the URL" ("Votre
client n'a pas la permission d'obtenir l'URL"). En effet, vous ne voulez pas
que le service puisse être appelé par des utilisateurs anonymes.
-
Essayez maintenant d'appeler le service en tant qu'utilisateur autorisé :
curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" $SERVICE_URL
Si vous obtenez la réponse "OK", vous avez correctement déployé
un service Cloud Run. Félicitations !
Tâche 4 : Déclencher votre service Cloud Run lorsqu'un nouveau fichier est
importé
Maintenant que le service Cloud Run a été correctement déployé, Ruby aimerait
que Patrick crée une zone de préproduction pour les données à convertir. Le
bucket Cloud Storage va utiliser un déclencheur d'événement pour notifier
l'application lorsqu'un fichier a été importé et doit être traité.
-
Exécutez la commande suivante pour créer un bucket dans Cloud Storage pour
les documents importés :
gcloud storage buckets create gs://$GOOGLE_CLOUD_PROJECT-upload
- Et un autre bucket pour les PDF traités :
gcloud storage buckets create gs://$GOOGLE_CLOUD_PROJECT-processed
-
Revenez maintenant à l'onglet de la console Cloud, ouvrez le
menu de navigation et sélectionnez
Cloud Storage > Buckets. Vérifiez que les buckets ont été
créés (il y aura également d'autres buckets utilisés par la plate-forme).
Tester la tâche terminée
Cliquez sur Vérifier ma progression pour vérifier que vous
avez correctement effectué la tâche ci-dessus.
Créer deux buckets Cloud Storage
-
Dans Cloud Shell, exécutez la commande suivante pour indiquer à
Cloud Storage d'envoyer une notification Pub/Sub chaque fois qu'un nouveau
fichier a fini d'être importé dans le bucket de documents :
gcloud storage buckets notifications create -t new-doc -f json -e OBJECT_FINALIZE gs://$GOOGLE_CLOUD_PROJECT-upload
Les notifications seront étiquetées avec le sujet "new-doc".
Tester la tâche terminée
Cliquez sur Vérifier ma progression pour vérifier que vous
avez correctement effectué la tâche ci-dessus.
Créer un sujet Pub/Sub pour gérer les notifications provenant du bucket de
stockage
-
Créez ensuite un nouveau compte de service que Pub/Sub utilisera pour
déclencher les services Cloud Run :
gcloud iam service-accounts create pubsub-cloud-run-invoker --display-name "PubSub Cloud Run Invoker"
-
Donnez au nouveau compte de service l'autorisation d'appeler le service de
convertisseur PDF :
gcloud run services add-iam-policy-binding pdf-converter --member=serviceAccount:pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com --role=roles/run.invoker --region {{{ project_0.default_region | Lab Region }}}
- Trouvez votre numéro de projet en exécutant cette commande :
gcloud projects list
Cherchez le projet dont le nom commence par "qwiklabs-gcp-". Vous utiliserez
la valeur du numéro de projet dans la prochaine commande.
-
Créez une variable d'environnement
PROJECT_NUMBER, en
remplaçant [numéro de projet] par le numéro de projet de la dernière
commande :
PROJECT_NUMBER=[project number]
-
Activez l'API Cloud Pub/Sub en exécutant cette commande :
gcloud services enable pubsub.googleapis.com --project={{{ project_0.project_id | Project }}}
-
Ensuite, activez votre projet pour créer des jetons d'authentification Cloud
Pub/Sub :
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com --role=roles/iam.serviceAccountTokenCreator
-
Enfin, créez un abonnement Pub/Sub pour que le convertisseur PDF fonctionne
à chaque fois qu'un message est publié dans le sujet "new-doc".
gcloud beta pubsub subscriptions create pdf-conv-sub --topic new-doc --push-endpoint=$SERVICE_URL --push-auth-service-account=pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
Tester la tâche terminée
Cliquez sur Vérifier ma progression pour vérifier que vous
avez correctement effectué la tâche ci-dessus.
Créer un abonnement Pub/Sub
Tâche 5 : Vérifier si le service Cloud Run est déclenché lorsque les fichiers
sont importés dans Cloud Storage
Pour vérifier que l'application fonctionne comme prévu, Ruby demande à Patrick
d'importer quelques données de test dans le bucket de stockage nommé, puis
d'accéder à Cloud Logging.
- Copiez des fichiers de test dans votre bucket d'importation :
gcloud storage -m cp gs://spls/gsp644/* gs://$GOOGLE_CLOUD_PROJECT-upload
-
Une fois l'importation terminée, revenez à l'onglet de la console Cloud,
ouvrez le menu de navigation et cliquez sur
AFFICHER TOUS LES PRODUITS. Sélectionnez
Journalisation dans la section "Observabilité".
-
Dans le menu déroulant Toutes les ressources, appliquez
le filtre Révision dans Cloud Run, puis cliquez sur
Appliquer. Cliquez ensuite sur
Exécuter la requête.
-
Dans les résultats de la requête, recherchez une entrée
de journal qui commence par file:, puis cliquez dessus. Elle
affiche un vidage des données du fichier que Pub/Sub envoie à votre
service Cloud Run lorsqu'un nouveau fichier est importé.
-
Pouvez-vous trouver le nom du fichier que vous avez importé dans cet
objet ?

Remarque :
Si vous ne voyez aucune entrée de journal qui commence par "file", essayez de cliquer sur le bouton permettant de charger des journaux plus récents vers le bas de la page.
-
Retournez ensuite à l'onglet de l'éditeur de code et exécutez la commande
suivante dans Cloud Shell pour nettoyer votre répertoire
upload en supprimant les fichiers qu'il contient :
gcloud storage -m rm gs://$GOOGLE_CLOUD_PROJECT-upload/*
Tâche 6 : Conteneurs
Patrick doit convertir des factures en attente en PDF pour que tous les
clients puissent les ouvrir. Il envoie un e-mail à Ruby pour obtenir de
l'aide...
|
Patrick, Administrateur informatique
|
Bonjour Ruby,
Sur la base de vos conclusions, je pense que nous pouvons automatiser ce
processus et passer à l'utilisation du format PDF comme format de
facture.
J'ai passé un peu de temps hier à coder une solution et j'ai construit
un script Node.js pour faire ce dont nous avons besoin. Pourriez-vous y
jeter un coup d'œil ?
Patrick
|
Patrick envoie à Ruby le fragment de code qu'il a écrit pour produire un PDF à
partir d'un fichier :
const {promisify} = require('util');
const exec = promisify(require('child_process').exec);
const cmd = 'libreoffice --headless --convert-to pdf --outdir ' +
`/tmp "/tmp/${fileName}"`;
const { stdout, stderr } = await exec(cmd);
if (stderr) {
throw stderr;
}
Ruby répond à Patrick...
|
Ruby, Consultante en logiciels
|
Bonjour Patrick,
Cloud Run utilise des conteneurs, nous devons donc fournir votre
application dans ce format. Pour l'étape suivante, nous devons créer un
fichier manifeste Dockerfile
pour l'application.
Votre code utilise LibreOffice. Pourriez-vous m'envoyer la commande
d'installation de ce logiciel ? Je vais devoir l'inclure dans le
conteneur.
Ruby
|
|
Patrick, Administrateur informatique
|
Bonjour Ruby,
Génial, voici comment j'installe habituellement LibreOffice sur les
serveurs du bureau :
apt-get update -y && apt-get install -y libreoffice
&& apt-get clean
N'hésitez pas à me contacter si vous avez d'autres questions.
Patrick
|
La construction du conteneur nécessitera l'intégration d'un certain nombre de
composants :
Mettre à jour le fichier manifeste
Une fois tous les fichiers identifiés, le fichier manifeste peut maintenant
être créé. Aidez Ruby à mettre en place et à déployer le conteneur.
Le package pour LibreOffice n'était pas inclus dans le conteneur auparavant,
ce qui signifie qu'il doit maintenant être ajouté. Patrick a déjà fourni les
commandes qu'il utilise pour construire son application, Ruby les ajoutera en
tant que commande RUN dans le Dockerfile.
Déployer la nouvelle version du service de convertisseur PDF
-
Ouvrez le fichier index.js et ajoutez les exigences de
package suivantes en haut du fichier :
const {promisify} = require('util');
const {Storage} = require('@google-cloud/storage');
const exec = promisify(require('child_process').exec);
const storage = new Storage();
-
Remplacez app.post('/', async (req, res) par
le code suivant :
app.post('/', async (req, res) => {
try {
const file = decodeBase64Json(req.body.message.data);
await downloadFile(file.bucket, file.name);
const pdfFileName = await convertFile(file.name);
await uploadFile(process.env.PDF_BUCKET, pdfFileName);
await deleteFile(file.bucket, file.name);
}
catch (ex) {
console.log(`Error: ${ex}`);
}
res.set('Content-Type', 'text/plain');
res.send('\n\nOK\n\n');
})
-
Ajoutez maintenant le code suivant qui traite les documents LibreOffice au
bas du fichier :
// Helper function to check file existence (using fs.promises for async)
async function fileExists(filePath) {
try {
await fs.promises.access(filePath); // Throws an error if the file doesn't exist
return true;
} catch (err) {
return false;
}
}
async function downloadFile(bucketName, fileName) {
// 1. Check if the file exists
const fileExistsLocally = await fileExists(`/tmp/${fileName}`);
// 2. Delete if present
if (fileExistsLocally) {
console.log(`File exists locally. Deleting: ${fileName}`);
await fs.promises.unlink(`/tmp/${fileName}`); // Use fs.promises for async file operations
console.log(`File deleted.`);
} else {
console.log(`File does not exist locally: ${fileName}`);
}
// 3. Download from the storage bucket
const options = { destination: `/tmp/${fileName}` };
await storage.bucket(bucketName).file(fileName).download(options);
console.log(`File downloaded: ${fileName}`);
}
async function convertFile(fileName) {
const cmd = 'libreoffice --headless --convert-to pdf --outdir /tmp ' +
`"/tmp/${fileName}"`;
console.log(cmd);
const { stdout, stderr } = await exec(cmd);
if (stderr) {
throw stderr;
}
console.log(stdout);
pdfFileName = fileName.replace(/\.\w+$/, '.pdf');
return pdfFileName;
}
async function deleteFile(bucketName, fileName) {
await storage.bucket(bucketName).file(fileName).delete();
}
async function uploadFile(bucketName, fileName) {
await storage.bucket(bucketName).upload(`/tmp/${fileName}`);
}
-
Assurez-vous que votre fichier index.js ressemble à ce qui
suit :
Remarque :
Pour éviter les erreurs de formatage, nous vous recommandons de remplacer tout le code contenu dans votre fichier index.js par cet exemple de code.
const {promisify} = require('util');
const {Storage} = require('@google-cloud/storage');
const exec = promisify(require('child_process').exec);
const storage = new Storage();
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log('Listening on port', port);
});
app.post('/', async (req, res) => {
try {
const file = decodeBase64Json(req.body.message.data);
await downloadFile(file.bucket, file.name);
const pdfFileName = await convertFile(file.name);
await uploadFile(process.env.PDF_BUCKET, pdfFileName);
await deleteFile(file.bucket, file.name);
}
catch (ex) {
console.log(`Error: ${ex}`);
}
res.set('Content-Type', 'text/plain');
res.send('\n\nOK\n\n');
})
function decodeBase64Json(data) {
return JSON.parse(Buffer.from(data, 'base64').toString());
}
// Helper function to check file existence (using fs.promises for async)
async function fileExists(filePath) {
try {
await fs.promises.access(filePath); // Throws an error if the file doesn't exist
return true;
} catch (err) {
return false;
}
}
async function downloadFile(bucketName, fileName) {
// 1. Check if the file exists
const fileExistsLocally = await fileExists(`/tmp/${fileName}`);
// 2. Delete if present
if (fileExistsLocally) {
console.log(`File exists locally. Deleting: ${fileName}`);
await fs.promises.unlink(`/tmp/${fileName}`); // Use fs.promises for async file operations
console.log(`File deleted.`);
} else {
console.log(`File does not exist locally: ${fileName}`);
}
// 3. Download from the storage bucket
const options = { destination: `/tmp/${fileName}` };
await storage.bucket(bucketName).file(fileName).download(options);
console.log(`File downloaded: ${fileName}`);
}
async function convertFile(fileName) {
const cmd = 'libreoffice --headless --convert-to pdf --outdir /tmp ' +
`"/tmp/${fileName}"`;
console.log(cmd);
const { stdout, stderr } = await exec(cmd);
if (stderr) {
console.log(`Conversion Failed: ${stderr}`);
throw stderr;
}
console.log(`Conversion Success: ${stdout}`);
pdfFileName = fileName.replace(/\.\w+$/, '.pdf');
return pdfFileName;
}
async function deleteFile(bucketName, fileName) {
await storage.bucket(bucketName).file(fileName).delete();
}
async function uploadFile(bucketName, fileName) {
await storage.bucket(bucketName).upload(`/tmp/${fileName}`);
}
Chaque fois qu'un fichier est importé, ce service est déclenché. Il effectue
ces tâches, une par ligne de la fonction ci-dessus :
- Il extrait les détails du fichier de la notification Pub/Sub.
-
Il télécharge le fichier du Cloud Storage sur le disque dur local. Il ne
s'agit pas d'un disque physique, mais d'une section de mémoire virtuelle qui
se comporte comme un disque.
- Il convertit le fichier téléchargé en PDF.
-
Il importe le fichier PDF sur Cloud Storage. La variable d'environnement
process.env.PDF_BUCKET contient le nom du bucket Cloud Storage
dans lequel enregistrer des PDF. Vous attribuerez une valeur à cette
variable lorsque vous déploierez le service ci-dessous.
- Il supprime le fichier original de Cloud Storage.
Le reste du fichier index.js implémente les fonctions appelées
par ce code de haut niveau.
Il est temps de déployer le service, et de définir la variable d'environnement
PDF_BUCKET. Il est aussi conseillé d'octroyer à LibreOffice 2 Go
de RAM pour travailler (consultez la ligne avec l'option
--memory).
-
Exécutez la commande suivante pour créer le conteneur :
gcloud builds submit \
--tag gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter
Remarque :
Saisissez Y si une fenêtre s'affiche pour vous demander d'activer l'API Cloud Build.
Tester la tâche terminée
Cliquez sur Vérifier ma progression pour vérifier que vous
avez correctement effectué la tâche ci-dessus.
Créer un autre build de l'API REST
-
Déployez maintenant la dernière version de votre application :
gcloud run deploy pdf-converter \
--image gcr.io/$GOOGLE_CLOUD_PROJECT/pdf-converter \
--region {{{ project_0.default_region | Lab Region }}} \
--memory=2Gi \
--no-allow-unauthenticated \
--max-instances=1 \
--set-env-vars PDF_BUCKET=$GOOGLE_CLOUD_PROJECT-processed
Avec la partie LibreOffice du conteneur, cette compilation prendra plus de
temps que la précédente. C'est le bon moment pour marquer une pause.
Cliquez sur Vérifier ma progression pour valider l'objectif.
Créer une révision
Tâche 7 : Tester le service de convertisseur PDF
-
Une fois les commandes de déploiement terminées, assurez-vous que le
service a été déployé correctement en exécutant :
curl -X POST -H "Authorization: Bearer $(gcloud auth print-identity-token)" $SERVICE_URL
-
Si vous obtenez la réponse "OK", vous avez réussi à déployer
le service Cloud Run mis à jour. LibreOffice peut convertir de nombreux
types de fichiers en PDF : DOCX, XLSX, JPG, PNG, GIF, etc.
-
Créez un script pour effectuer l'importation.
cat <<'EOF' > copy_files.sh
#!/bin/bash
SOURCE_BUCKET="gs://spls/gsp644"
DESTINATION_BUCKET="gs://${GOOGLE_CLOUD_PROJECT}-upload" # Replace with your actual bucket name
DELAY=5
# Get a list of files in the source bucket
files=$(gcloud storage ls "$SOURCE_BUCKET")
# Loop through the files
for file in $files; do
# Construct the full path of the source file
source_file_path="$file"
# Copy the file to the destination bucket
gcloud storage cp "$source_file_path" "$DESTINATION_BUCKET"
# Check if the copy was successful
if [ $? -eq 0 ]; then # $? is the exit status of the previous command
echo "Copied: $source_file_path to $DESTINATION_BUCKET"
else
echo "Failed to copy: $source_file_path"
fi
# Sleep for 5 seconds
sleep $DELAY
done
echo "All files copied!"
EOF
-
Exécutez la commande suivante pour télécharger quelques fichiers
d'exemple :
bash copy_files.sh
-
Revenez à la console Cloud, ouvrez le menu de navigation,
puis sélectionnez Cloud Storage > Buckets. Ouvrez le
bucket -upload et cliquez sur le bouton
Actualiser plusieurs fois pour voir comment les fichiers
sont supprimés, un par un, au fur et à mesure qu'ils sont convertis en
PDF.
-
Cliquez ensuite sur Buckets dans le menu de gauche, et
sur le bucket dont le nom se termine par "-processed". Il doit contenir
les versions PDF de tous les fichiers. N'hésitez pas à ouvrir les fichiers
PDF pour vous assurer qu'ils ont été correctement convertis :
Remarque :
Si vous ne voyez pas tous les fichiers PDF convertis dans le bucket -processed, réexécutez la commande.
Félicitations !
Pet Theory dispose désormais d'un système pour convertir ses archives
d'anciens fichiers en PDF. En important simplement les anciens fichiers dans
le bucket "upload", le service de convertisseur PDF les convertit et les
enregistre en PDF dans le bucket "processed".
Poursuivez votre apprentissage en suivant le cours
Développer des applications sans serveur sur Cloud Run. Vous découvrirez un scénario métier fondé sur une entreprise fictive et
aiderez les protagonistes à migrer vers une technologie sans serveur.
Formations et certifications Google Cloud
Les formations et certifications Google Cloud vous aident à tirer pleinement parti des technologies Google Cloud. Nos cours portent sur les compétences techniques et les bonnes pratiques à suivre pour être rapidement opérationnel et poursuivre votre apprentissage. Nous proposons des formations pour tous les niveaux, à la demande, en salle et à distance, pour nous adapter aux emplois du temps de chacun. Les certifications vous permettent de valider et de démontrer vos compétences et votre expérience en matière de technologies Google Cloud.
Dernière mise à jour du manuel : 4 février 2026
Dernier test de l'atelier : 4 février 2026
Copyright 2026 Google LLC. Tous droits réservés. Google et le logo Google sont des marques de Google LLC. Tous les autres noms d'entreprises et de produits peuvent être des marques des entreprises auxquelles ils sont associés.