Pic-à-quoi: Atelier 6 – Orchestration avec les workflows

1. Présentation

Dans les ateliers précédents, vous avez créé une version événementielle de l'application Pic-a-daily qui utilisait une fonction Cloud déclenchée par Google Cloud Storage pour le service d'analyse d'images, un conteneur Cloud Run déclenché par GCS via Pub/Sub pour le service de miniatures et Eventarc pour déclencher le service de collecte des déchets d'images sur Cloud Run. Un service de montage déclenché par Cloud Scheduler était également disponible :

d93345bfc235f81e.png

Dans cet atelier, vous allez créer une version orchestrée de l'application. Au lieu d'utiliser différents types d'événements circulant dans le système, vous allez utiliser Workflows pour orchestrer et appeler les services comme suit :

b763efcbf5589747.png

Points abordés

  • App Engine
  • Cloud Firestore
  • Cloud Functions
  • Cloud Run
  • Workflows

2. Préparation

Configuration de l'environnement d'auto-formation

  1. Connectez-vous à la console Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID tout au long de cet atelier de programmation.

  1. Vous devez ensuite activer la facturation dans Cloud Console pour pouvoir utiliser les ressources Google Cloud.

L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Veillez à suivre les instructions de la section "Nettoyer" qui indique comment désactiver les ressources afin d'éviter les frais une fois ce tutoriel terminé. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300$.

Démarrer Cloud Shell

Bien que Google Cloud puisse être utilisé à distance depuis votre ordinateur portable, nous allons nous servir de Google Cloud Shell pour cet atelier de programmation, un environnement de ligne de commande exécuté dans le cloud.

Depuis la console GCP, cliquez sur l'icône Cloud Shell de la barre d'outils située dans l'angle supérieur droit :

bce75f34b2c53987.png

Le provisionnement et la connexion à l'environnement prennent quelques instants seulement. Une fois l'opération terminée, le résultat devrait ressembler à ceci :

f6ef2b5f13479f3a.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser toutes les activités de cet atelier dans un simple navigateur.

3. Présentation des workflows

90fcd42d556e310e.jpeg

Vous pouvez utiliser Workflows pour créer des workflows sans serveur qui associent une série de tâches sans serveur dans un ordre que vous définissez. Vous pouvez combiner la puissance des API Google Cloud, des produits sans serveur tels que Cloud Functions et Cloud Run, et des appels d'API externes pour créer des applications sans serveur flexibles.

Comme vous pouvez vous y attendre d'un orchestrateur, Workflows vous permet de définir le flux de votre logique métier dans un langage de définition de workflow basé sur YAML/JSON et fournit une API Workflows Execution et une UI Workflows pour déclencher ces flux.

Il s'agit de bien plus qu'un simple orchestrateur grâce à ces fonctionnalités intégrées et configurables :

  • Gestion flexible des nouvelles tentatives et des erreurs entre les étapes pour une exécution fiable.
  • Analyse JSON et transmission de variables entre les étapes pour éviter le code de liaison.
  • Les formules d'expression pour les décisions permettent d'exécuter des étapes conditionnelles.
  • Sous-workflows pour des workflows modulaires et réutilisables.
  • La compatibilité avec les services externes permet d'orchestrer des services au-delà de Google Cloud.
  • Prise en charge de l'authentification pour Google Cloud et les services externes afin d'exécuter les étapes de manière sécurisée.
  • Des connecteurs aux services Google Cloud tels que Pub/Sub, Firestore, Tasks et Secret Manager pour une intégration plus facile.

De plus, Workflows est un produit sans serveur entièrement géré. Vous n'avez aucun serveur à configurer ni à mettre à l'échelle, et vous ne payez que ce que vous utilisez.

4. Activer les API

Dans cet atelier, vous allez connecter des services Cloud Functions et Cloud Run avec Workflows. Vous utiliserez également App Engine, Cloud Build, l'API Vision et d'autres services.

Dans Cloud Shell, assurez-vous que tous les services nécessaires sont activés :

gcloud services enable \
  appengine.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  compute.googleapis.com \
  firestore.googleapis.com \
  run.googleapis.com \
  vision.googleapis.com \
  workflows.googleapis.com \

Au bout de quelques minutes, l'opération devrait se terminer correctement :

Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.

5. Obtenir le code

Récupérez le code, si vous ne l'avez pas déjà fait dans les ateliers de programmation précédents :

git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop

Vous disposerez de la structure de dossiers suivante, qui est pertinente pour cet atelier :

frontend
 |
workflows
 |
 ├── functions
 ├── |── trigger-workflow
 ├── |── vision-data-transform
 ├── services
 ├── |── collage
 ├── |── thumbnails
 ├── workflows.yaml

Voici les dossiers concernés :

  • frontend contient le frontend App Engine que nous réutiliserons à partir de l'atelier 4.
  • functions contient les fonctions Cloud Functions créées pour le workflow.
  • services contient les services Cloud Run modifiés pour le workflow.
  • workflows.yaml est le fichier de définition du workflow.

6. Explorer le fichier YAML Workflows

Le fichier workflows.yaml définit le workflow en une série d'étapes. Pour mieux comprendre, examinons-le.

Au début du workflow, certains paramètres sont transmis. Ils seront transmis par deux fonctions Cloud qui déclenchent les workflows. Nous aborderons ces fonctions plus tard, mais voici comment le workflow commence :

d44a5e18aa9d4660.png

Dans YAML, vous pouvez voir que ces paramètres sont attribués à des variables dans l'étape init, telles que les noms de fichier et de bucket qui déclenchent l'événement, ainsi que les URL de certains services Cloud Functions et Cloud Run que Workflows appellera :

main:
  params: [args]
  steps:
    - init:
        assign:
          - file: ${args.file}
          - bucket: ${args.bucket}
          - gsUri: ${"gs://" + bucket + "/" + file}
          - projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
          - urls: ${args.urls}

Workflows vérifie ensuite le type d'événement. Deux types d'événements sont acceptés : object.finalize (émis lorsqu'un fichier est enregistré dans le bucket de stockage cloud) et object.delete (émis lorsqu'un fichier est supprimé). Tout autre événement générera une exception "Événement non pris en charge".

dd1f450983655619.png

Voici l'étape de la définition du workflow YAML où nous vérifions le type d'événement de stockage de fichier :

    - eventTypeSwitch:
        switch:
            - condition: ${args.eventType == "google.storage.object.finalize"}
              next: imageAnalysisCall
            - condition: ${args.eventType == "google.storage.object.delete"}
              next: pictureGarbageCollectionGCS
    - eventTypeNotSupported:
        raise: ${"eventType " + args.eventType + " is not supported"}
        next: end

Notez que Workflows prend en charge les instructions switch et la gestion des exceptions, avec l'instruction switch et ses différentes conditions, ainsi que l'instruction raise pour générer une erreur lorsque l'événement n'est pas reconnu.

Intéressons-nous maintenant à imageAnalysisCall. Il s'agit d'une série d'appels de Workflows à l'API Vision pour analyser l'image, transformer les données de réponse de l'API Vision afin de trier les libellés des éléments reconnus dans l'image, choisir les couleurs dominantes, vérifier si l'image peut être affichée sans risque, puis enregistrer les métadonnées dans Cloud Firestore.

Notez que tout est fait dans Workflows, à l'exception des fonctions Cloud Functions Vision Transform (que nous déploierons plus tard) :

ca2ad16b9cbb436.png

Voici à quoi ressemblent les étapes en YAML :

    - imageAnalysisCall:
        call: http.post
        args:
          url: https://vision.googleapis.com/v1/images:annotate
          headers:
            Content-Type: application/json
          auth:
            type: OAuth2
          body:
            requests:
            - image:
                source:
                  gcsImageUri: ${gsUri}
              features:
              - type: LABEL_DETECTION
              - type: SAFE_SEARCH_DETECTION
              - type: IMAGE_PROPERTIES
        result: imageAnalysisResponse
    - transformImageAnalysisData:
        call: http.post
        args:
          url: ${urls.VISION_DATA_TRANSFORM_URL}
          auth:
            type: OIDC
          body: ${imageAnalysisResponse.body}
        result: imageMetadata
    - checkSafety:
        switch:
          - condition: ${imageMetadata.body.safe == true}
            next: storeMetadata
        next: end
    - storeMetadata:
        call: http.request
        args:
          url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file + "?updateMask.fieldPaths=color&updateMask.fieldPaths=labels&updateMask.fieldPaths=created"}
          auth:
            type: OAuth2
          method: PATCH
          body:
            name: ${"projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
            fields:
              color:
                stringValue: ${imageMetadata.body.color}
              created:
                timestampValue: ${imageMetadata.body.created}
              labels:
                arrayValue:
                  values: ${imageMetadata.body.labels}
        result: storeMetadataResponse

Une fois l'image analysée, les deux étapes suivantes consistent à créer la miniature de l'image et un montage des images les plus récentes. Pour ce faire, déployez deux services Cloud Run et appelez-les à partir des étapes thumbnailCall et collageCall :

76f9179323c3144.png

Étapes en YAML :

   - thumbnailCall:
        call: http.post
        args:
          url: ${urls.THUMBNAILS_URL}
          auth:
            type: OIDC
          body:
              gcsImageUri: ${gsUri}
        result: thumbnailResponse
    - collageCall:
        call: http.get
        args:
          url: ${urls.COLLAGE_URL}
          auth:
            type: OIDC
        result: collageResponse

Cette branche de l'exécution se termine en renvoyant les codes d'état de chaque service à l'étape finalizeCompleted :

    - finalizeCompleted:
        return:
          imageAnalysis: ${imageAnalysisResponse.code}
          storeMetadata: ${storeMetadataResponse.code}
          thumbnail: ${thumbnailResponse.code}
          collage: ${collageResponse.code}

L'autre branche de l'exécution se produit lorsqu'un fichier est supprimé du bucket de stockage principal, qui contient les versions haute résolution des photos. Dans cette branche, nous voulons supprimer la vignette de l'image dans le bucket contenant les vignettes et supprimer ses métadonnées de Firestore. Ces deux opérations sont effectuées à l'aide d'appels HTTP depuis Workflows :

f172379274dcb3c2.png

Étapes en YAML :

    - pictureGarbageCollectionGCS:
        try:
          call: http.request
          args:
            url: ${"https://storage.googleapis.com/storage/v1/b/thumbnails-" + projectId + "/o/" + file}
            auth:
              type: OAuth2
            method: DELETE
          result: gcsDeletionResult
        except:
          as: e
          steps:
              - dummyResultInOutVar:
                  assign:
                      - gcsDeletionResult:
                          code: 200
                          body: "Workaround for empty body response"
    - pictureGarbageCollectionFirestore:
        call: http.request
        args:
          url: ${"https://firestore.googleapis.com/v1/projects/" + projectId + "/databases/(default)/documents/pictures/" + file}
          auth:
            type: OAuth2
          method: DELETE
        result: firestoreDeletionResult

La branche de suppression se termine en renvoyant les résultats / codes de chaque étape :

    - deleteCompleted:
        return:
          gcsDeletion: ${gcsDeletionResult}
          firestoreDeletion: ${firestoreDeletionResult.code}

Dans les étapes suivantes, nous allons créer toutes les dépendances externes des workflows : buckets, fonctions Cloud, services Cloud Run et base de données Firestore.

7. Créer les buckets

Vous avez besoin de deux buckets pour les images : un pour enregistrer les images d'origine en haute résolution et un pour enregistrer les miniatures des images.

Créez un bucket public régional (en Europe dans le cas présent) avec un accès uniforme pour que les utilisateurs puissent y importer des photos à l'aide de l'outil gsutil :

export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_PICTURES}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_PICTURES}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_PICTURES}

Créez un autre bucket régional public pour les miniatures :

export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
gsutil mb -l EU gs://${BUCKET_THUMBNAILS}
gsutil uniformbucketlevelaccess set on gs://${BUCKET_THUMBNAILS}
gsutil iam ch allUsers:objectViewer gs://${BUCKET_THUMBNAILS}

Vous pouvez vérifier que les buckets sont créés et publics en accédant à la section Cloud Storage de la console Cloud :

15063936edd72f06.png

8. Transformation des données Vision (fonction Cloud Functions)

Workflows.yaml commence par les étapes init, eventTypeSwitch et eventTypeNotSupported. Ils permettent de s'assurer que les événements provenant des buckets sont acheminés vers les étapes appropriées.

Pour l'événement object.finalize, l'étape imageAnalysisCall appelle l'API Vision pour extraire les métadonnées de l'image créée. Toutes ces étapes sont effectuées dans les workflows :

daaed43a22d2b0d3.png

Nous devons ensuite transformer les données renvoyées par l'API Vision avant de pouvoir les enregistrer dans Firestore. Plus précisément, nous devons :

  • Listez les libellés renvoyés pour l'image.
  • Récupérez la couleur dominante de l'image.
  • Déterminez si l'image est sûre.

Cela se fait dans le code d'une fonction Cloud, et Workflows appelle simplement cette fonction :

5e120e70c67779cd.png

Explorer le code

La fonction Cloud est appelée vision-data-transform. Vous pouvez consulter son code complet dans index.js. Comme vous pouvez le voir, la seule fonction de cette fonction est d'effectuer une transformation JSON en JSON, afin de stocker facilement les métadonnées des images dans Firestore.

Déployer sur Cloud Functions

Accédez au dossier :

cd workflows/functions/vision-data-transform/nodejs

Définissez la région de votre choix :

export REGION=europe-west1
gcloud config set functions/region ${REGION}

Déployez la fonction à l'aide de la commande suivante :

export SERVICE_NAME=vision-data-transform
gcloud functions deploy ${SERVICE_NAME} \
  --source=. \
  --runtime nodejs10 \
  --entry-point=vision_data_transform \
  --trigger-http \
  --allow-unauthenticated

Une fois la fonction déployée, l'étape transformImageAnalysisData de Workflows pourra appeler cette fonction pour effectuer la transformation des données de l'API Vision.

9. Préparer la base de données

L'étape suivante du workflow consiste à vérifier la sécurité de l'image à partir des données d'image, puis à stocker les informations sur l'image renvoyées par l'API Vision dans la base de données Cloud Firestore, une base de données de documents NoSQL cloud native, sans serveur, entièrement gérée et rapide :

6624c616bc7cd97f.png

Ces deux opérations sont effectuées dans Workflows, mais vous devez créer la base de données Firestore pour que le stockage des métadonnées fonctionne.

Commencez par créer une application App Engine dans la région où vous souhaitez créer la base de données Firestore (une exigence pour Firestore) :

export REGION_FIRESTORE=europe-west2
gcloud app create --region=${REGION_FIRESTORE}

Créez ensuite la base de données Firestore dans la même région :

gcloud firestore databases create --region=${REGION_FIRESTORE}

Les documents seront créés de manière programmatique dans notre collection et contiendront quatre champs :

  • name (chaîne) : nom du fichier de l'image importée, qui est également la clé du document
  • labels (tableau de chaînes) : étiquettes des éléments reconnus par l'API Vision
  • color (chaîne) : code hexadécimal de la couleur dominante (par exemple, #ab12ef)
  • created (date) : code temporel indiquant quand les métadonnées de cette image ont été stockées.
  • thumbnail (booléen) : champ facultatif qui est présent et défini sur "true" si une image miniature a été générée pour cette photo.

Comme nous allons effectuer des recherches dans Firestore pour trouver les photos qui ont des miniatures disponibles et les trier par date de création, nous devrons créer un index de recherche. Vous pouvez créer l'index à l'aide de la commande suivante :

gcloud firestore indexes composite create --collection-group=pictures \
  --field-config field-path=thumbnail,order=descending \
  --field-config field-path=created,order=descending

Notez que la création de l'index peut prendre une dizaine de minutes.

Une fois l'index créé, vous pouvez le consulter dans la console Cloud :

43af1f5103bf423.png

L'étape storeMetadata de Workflows peut désormais stocker les métadonnées de l'image dans Firestore.

10. Service de miniatures (Cloud Run)

L'étape suivante consiste à créer une miniature d'une image. Cette opération est effectuée dans le code d'un service Cloud Run, et Workflows appelle ce service à l'étape thumbnailCall :

84d987647f082b53.png

Explorer le code

Le service Cloud Run est appelé thumbnails. Vous pouvez consulter son code complet dans index.js.

Créer et publier l'image de conteneur

Cloud Run exécute des conteneurs, mais vous devez d'abord créer l'image de conteneur (définie dans Dockerfile). Google Cloud Build peut être utilisé pour créer des images de conteneurs, puis les héberger dans Google Container Registry.

Accédez au dossier :

cd workflows/services/thumbnails/nodejs

Build :

export SERVICE_SRC=thumbnails
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
  . \
  --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}

Au bout d'une minute ou deux, la compilation devrait réussir et le conteneur sera déployé sur Google Container Registry.

Déployer sur Cloud Run

Définissez les variables et la configuration nécessaires :

export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed

Déployez la fonction à l'aide de la commande suivante :

gcloud run deploy ${SERVICE_NAME} \
    --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
    --no-allow-unauthenticated \
    --memory=1Gi \
    --update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}

Une fois le service déployé, l'étape Workflows thumbnailCall pourra appeler ce service.

11. Service de collage (Cloud Run)

L'étape suivante de la chaîne consiste à créer un montage à partir des images les plus récentes. Cette opération est effectuée dans le code d'un service Cloud Run, et Workflows appelle ce service à l'étape collageCall :

591e36149066e1ba.png

Explorer le code

Le service Cloud Run est appelé collage. Vous pouvez consulter son code complet dans index.js.

Créer et publier l'image de conteneur

Cloud Run exécute des conteneurs, mais vous devez d'abord créer l'image de conteneur (définie dans Dockerfile). Google Cloud Build peut être utilisé pour créer des images de conteneurs, puis les héberger dans Google Container Registry.

Accédez au dossier :

cd services/collage/nodejs

Build :

export SERVICE_SRC=collage
export SERVICE_NAME=${SERVICE_SRC}-service
gcloud builds submit \
  . \
  --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}

Au bout d'une minute ou deux, la compilation devrait réussir et le conteneur sera déployé sur Google Container Registry.

Déployer sur Cloud Run

Définissez les variables et la configuration nécessaires :

export BUCKET_THUMBNAILS=thumbnails-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
gcloud config set run/region ${REGION}
gcloud config set run/platform managed

Déployer :

gcloud run deploy ${SERVICE_NAME} \
    --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
    --no-allow-unauthenticated \
    --memory=1Gi \
    --update-env-vars BUCKET_THUMBNAILS=${BUCKET_THUMBNAILS}

Une fois le service déployé, vous pouvez vérifier que les deux services s'exécutent dans la section Cloud Run de la console Cloud et que l'étape collageCall des workflows pourra appeler ce service :

3ae9873f4cbbf423.png

12. Déploiement des workflows

Nous avons déployé toutes les dépendances externes de Workflows. Toutes les étapes restantes (finalizeCompleted, pictureGarbageCollectionGCS, pictureGarbageCollectionFirestore, deleteCompleted) peuvent être effectuées par Workflows lui-même.

Il est temps de déployer les workflows.

Accédez au dossier contenant le fichier workflows.yaml et déployez-le avec la commande suivante :

export WORKFLOW_REGION=europe-west4
export WORKFLOW_NAME=picadaily-workflows
gcloud workflows deploy ${WORKFLOW_NAME} \
  --source=workflows.yaml \
  --location=${WORKFLOW_REGION}

En quelques secondes, le workflow devrait se déployer. Vous pouvez le voir dans la section "Workflows" de la console Cloud :

94a720149e5df9c5.png

Vous pouvez cliquer sur le workflow et le modifier si vous le souhaitez. Pendant la modification, vous obtenez une représentation visuelle du workflow :

55441b158f6027f3.png

Vous pouvez également exécuter le workflow manuellement depuis la console Cloud avec les bons paramètres. Au lieu de cela, nous l'exécuterons automatiquement en réponse aux événements Cloud Storage à l'étape suivante.

13. Déclencheurs de workflows (Cloud Functions)

Le workflow est déployé et prêt. Nous devons maintenant déclencher les workflows lorsqu'un fichier est créé ou supprimé dans un bucket Cloud Storage. Il s'agit respectivement des événements storage.object.finalize et storage.object.delete.

Workflows propose des API et des bibliothèques clientes que vous pouvez utiliser pour créer, gérer et exécuter des workflows. Dans ce cas, vous utiliserez l'API Workflows Execution et plus précisément sa bibliothèque cliente Node.js pour déclencher le workflow.

Vous déclencherez les workflows à partir de la fonction Cloud qui écoute les événements Cloud Storage. Étant donné qu'une fonction Cloud ne peut écouter qu'un seul type d'événement, vous allez déployer deux fonctions Cloud pour écouter les événements de création et de suppression :

c4d79646de729e4.png

Explorer le code

La fonction Cloud est appelée trigger-workflow. Vous pouvez consulter son code complet dans index.js.

Déployer sur Cloud Functions

Accédez au dossier :

cd workflows/functions/trigger-workflow/nodejs

Définissez les variables et la configuration nécessaires :

export BUCKET_PICTURES=uploaded-pictures-${GOOGLE_CLOUD_PROJECT}
export REGION=europe-west1
export WORKFLOW_NAME=picadaily-workflows
export WORKFLOW_REGION=europe-west4
export COLLAGE_URL=$(gcloud run services describe collage-service --format 'value(status.url)')
export THUMBNAILS_URL=$(gcloud run services describe thumbnails-service --format 'value(status.url)')
export VISION_DATA_TRANSFORM_URL=$(gcloud functions describe vision-data-transform --format 'value(httpsTrigger.url)')
gcloud config set functions/region ${REGION}

Déployez la fonction qui répond aux événements de finalisation :

export SERVICE_NAME=trigger-workflow-on-finalize
gcloud functions deploy ${SERVICE_NAME} \
  --source=. \
  --runtime nodejs10 \
  --entry-point=trigger_workflow \
  --trigger-resource=${BUCKET_PICTURES} \
  --trigger-event=google.storage.object.finalize \
  --allow-unauthenticated \
  --set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}

Déployez la deuxième fonction qui répond aux événements de suppression :

export SERVICE_NAME=trigger-workflow-on-delete
gcloud functions deploy ${SERVICE_NAME} \
  --source=. \
  --runtime nodejs10 \
  --entry-point=trigger_workflow \
  --trigger-resource=${BUCKET_PICTURES} \
  --trigger-event=google.storage.object.delete \
  --allow-unauthenticated \
  --set-env-vars GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT},WORKFLOW_REGION=${WORKFLOW_REGION},WORKFLOW_NAME=${WORKFLOW_NAME},THUMBNAILS_URL=${THUMBNAILS_URL},COLLAGE_URL=${COLLAGE_URL},VISION_DATA_TRANSFORM_URL=${VISION_DATA_TRANSFORM_URL}

Une fois le déploiement terminé, vous pouvez voir les deux fonctions dans la console Cloud :

7d60c8b7851f39f5.png

14. Interface (App Engine)

Dans cette étape, vous allez créer une interface Web sur Google App Engine à partir de Pic-a-daily : atelier 4 – Créer une interface Web, qui permettra aux utilisateurs d'importer des images depuis l'application Web, ainsi que de parcourir les images importées et leurs miniatures.

223fb2281614d053.png

Pour en savoir plus sur App Engine et lire la description du code, consultez Pic-a-daily : atelier 4 – Créer une interface Web.

Explorer le code

L'application App Engine s'appelle frontend. Vous pouvez consulter son code complet dans index.js.

Déployer dans App Engine

Accédez au dossier :

cd frontend

Définissez la région de votre choix et remplacez également GOOGLE_CLOUD_PROJECT dans app.yaml par l'ID réel de votre projet :

export REGION=europe-west1
gcloud config set compute/region ${REGION}
sed -i -e "s/GOOGLE_CLOUD_PROJECT/${GOOGLE_CLOUD_PROJECT}/" app.yaml

Déployer :

gcloud app deploy app.yaml -q

Au bout d'une ou deux minutes, vous serez informé que l'application diffuse du trafic :

Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 8 files to Google Cloud Storage                ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://GOOGLE_CLOUD_PROJECT.appspot.com]
You can stream logs from the command line by running:
  $ gcloud app logs tail -s default
To view your application in the web browser run:
  $ gcloud app browse

Vous pouvez également accéder à la section App Engine de la console Cloud pour vérifier que l'application est déployée et explorer les fonctionnalités d'App Engine, comme le versionnage et la répartition du trafic :

f4bd5f4de028bd83.png

15. Tester les workflows

Pour tester l'application, accédez à l'URL App Engine par défaut (https://<YOUR_PROJECT_ID>.appspot.com/) et vous devriez voir l'interface utilisateur frontend en cours d'exécution.

1649ac060441099.png

Importez une photo. Cela devrait déclencher les workflows. Vous pouvez voir l'exécution du workflow à l'état Active dans la console Cloud :

b5a2a3d7a2bc094.png

Une fois le workflow terminé, vous pouvez cliquer sur l'ID d'exécution et afficher la sortie des différents services :

8959df5098c21548.png

Importez trois autres photos. Vous devriez également voir la vignette et le collage des images dans les buckets Cloud Storage et l'interface App Engine mis à jour :

d90c786ff664a5dc.png

16. Nettoyer (facultatif)

Si vous n'avez pas l'intention de conserver l'application, vous pouvez nettoyer les ressources pour réduire les coûts et utiliser le cloud de manière raisonnée en supprimant l'intégralité du projet :

gcloud projects delete ${GOOGLE_CLOUD_PROJECT} 

17. Félicitations !

Vous avez créé une version orchestrée de l'application à l'aide de Workflows pour orchestrer et appeler des services.

Points abordés

  • App Engine
  • Cloud Firestore
  • Cloud Functions
  • Cloud Run
  • Workflows