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

1. Présentation

Dans les ateliers précédents, vous avez créé une version de l'application Pic-a-daily basée sur des événements. Celle-ci utilisait une fonction Cloud qui a déclenché Google Cloud Storage pour le service d'analyse d'images, un conteneur Cloud Run déclenché par GCS via Pub/Sub pour le service Vignette et Eventarc pour déclencher le service de récupération de mémoire sur Cloud Run. Il existait également un service de montage déclenché par Cloud Scheduler:

d93345bfc235f81e.png

Dans cet atelier, vous allez créer une version ordonnancée de l'application. Au lieu de différents types d'événements circulant dans le système, vous utiliserez 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 gratuite. 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 de Workflows

90fcd42d556e310e.jpeg

Workflows vous permet de 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 à des API externes pour créer des applications sans serveur flexibles.

Comme vous pouvez l'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. Il fournit une API Workflows Execution et une interface utilisateur Workflows pour déclencher ces flux.

Bien plus qu'un simple orchestrateur, il intègre ces fonctionnalités configurables:

  • Gestion flexible des nouvelles tentatives et des erreurs entre les étapes pour une exécution fiable des étapes.
  • Analyse JSON et transmission de variables entre les étapes pour éviter le glue code.
  • Les formules d'expression pour les décisions permettent des exécutions d'étapes conditionnelles.
  • Sous-workflows des workflows modulaires et réutilisables.
  • La prise en charge de services externes permet d'orchestrer des services au-delà de Google Cloud.
  • Authentification nécessaire pour Google Cloud et les services externes pour sécuriser les exécutions d'étapes.
  • Connecteurs vers les services Google Cloud tels que Pub/Sub, Firestore, Tasks et Secret Manager pour une intégration simplifiée

Sans oublier que Workflows est un produit sans serveur entièrement géré. Vous n'avez aucun serveur à configurer ni à faire évoluer, 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 à l'aide de 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 \

Après un certain temps, l'opération doit se terminer correctement:

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

5. Obtenir le code

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

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

La structure de dossiers suivante 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 l'interface App Engine que nous allons réutiliser à partir de l'atelier 4.
  • functions contient les fonctions Cloud 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. Examinons-le pour mieux le comprendre.

Au début du workflow, certains paramètres sont transmis. Ils seront transmis par deux fonctions Cloud qui déclencheront les workflows. Nous aborderons ces fonctions ultérieurement, mais voici comment les Workflows démarrent:

d44a5e18aa9d4660.png

En YAML, vous pouvez voir que ces paramètres sont attribués à des variables à l'étape init, comme les noms des fichiers et des buckets 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}

Ensuite, Workflows vérifie le type d'événement. Deux types d'événements sont acceptés: object.finalize (émis lorsqu'un fichier est enregistré dans le bucket Cloud Storage) et object.delete (émis lorsqu'un fichier est supprimé). Tout autre élément générera une exception d'événement non compatible.

dd1f450983655619.png

Voici l'étape de la définition du workflow YAML, au cours de laquelle nous vérifions le type d'événement de stockage de fichiers:

    - 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 de génération de requêtes pour générer une erreur lorsque l'événement n'est pas reconnu.

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

Notez que tout est fait dans Workflows, à l'exception de la transformation Vision avec Cloud Functions (que nous déploierons plus tard):

ca2ad16b9cbb436.png

Voici à quoi ressemblent ces é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 sa vignette et à créer un montage des images les plus récentes. Pour ce faire, vous déployez deux services Cloud Run et les appelez à 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 consiste à supprimer un fichier du bucket de stockage principal, qui contient les versions haute résolution des images. 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 réalisées à l'aide d'appels HTTP provenant de 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, Cloud Functions, services Cloud Run et base de données Firestore.

7. Créer les buckets

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

Créez un bucket public régional (ici en Europe) avec un accès uniforme permettant aux utilisateurs d'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 vignettes:

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}

Pour vérifier que les buckets sont créés et publics, accédez à la section Cloud Storage de Cloud Console:

15063936edd72f06.png

8. Transformation de données Vision (fonction Cloud)

Le fichier Workflows.yaml commence par les étapes init, eventTypeSwitch et eventTypeNotSupported. Ils garantissent 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 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:

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

Cela s'effectue dans le code d'une fonction Cloud. Workflows appelle simplement la fonction suivante:

5e120e70c67779cd.png

Explorer le code

La fonction Cloud est appelée vision-data-transform. Vous pouvez vérifier l'intégralité du code dans index.js. Comme vous pouvez le voir, l'objectif unique de cette fonction est d'effectuer une transformation JSON en JSON, afin de stocker facilement les métadonnées d'image dans Firestore.

Déployer une application 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 avec:

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 des workflows pourra l'appeler pour effectuer la transformation des données de l'API Vision.

9. Préparer la base de données

L'étape suivante de la section "Workflows" consiste à vérifier la sécurité de l'image à partir des données d'image, puis à stocker les informations sur l'image renvoyée par l'API Vision dans la base de données Cloud Firestore, une base de données de documents NoSQL sans serveur, cloud native, 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 utiliser la base de données Firestore (obligatoire pour Firestore):

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

Ensuite, créez la base de données Firestore dans la même région:

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

Les documents seront créés par programmation 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)
  • créé (date): horodatage du stockage des métadonnées de l'image.
  • thumbnail (valeur booléenne): champ facultatif qui est présent et a la valeur "true" si une vignette a été générée pour cette image.

Comme nous allons rechercher dans Firestore des images pour lesquelles des vignettes sont disponibles, et trier les dates de création, nous devons 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 jusqu'à 10 minutes environ.

Une fois l'index créé, il apparaît dans la console Cloud:

43af1f5103bf423.png

L'étape storeMetadata des workflows peut maintenant stocker les métadonnées de l'image dans Firestore.

10. Service Vignette (Cloud Run)

L'étape suivante consiste à créer la vignette d'une image. Cela s'effectue 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 vérifier l'intégralité du code dans index.js.

Créer et publier l'image de conteneur

Cloud Run exécute les conteneurs, mais vous devez d'abord créer l'image de conteneur (définie dans Dockerfile). Google Cloud Build permet de créer des images de conteneurs, puis de 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}

Après une minute ou deux, la compilation devrait aboutir et le conteneur sera déployé dans Google Container Registry.

Déployer une application 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

Effectuez le déploiement à 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 thumbnailCall de Workflows pourra l'appeler.

11. Service de montage (Cloud Run)

L'étape suivante consiste à créer un montage à partir des images les plus récentes. Cela s'effectue 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 vérifier l'intégralité du code dans index.js.

Créer et publier l'image de conteneur

Cloud Run exécute les conteneurs, mais vous devez d'abord créer l'image de conteneur (définie dans Dockerfile). Google Cloud Build permet de créer des images de conteneurs, puis de 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}

Après une minute ou deux, la compilation devrait aboutir et le conteneur sera déployé dans Google Container Registry.

Déployer une application 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é, vérifiez que les deux services sont en cours d'exécution dans la section Cloud Run de la console Cloud et que l'étape collageCall de Workflows peut appeler ce service:

3ae9873f4cbbf423.png

12. Déploiement de 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 Workflows.

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

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 et s'afficher dans la section "Workflows" de Cloud Console:

94a720149e5df9c5.png

Vous pouvez cliquer sur le flux de travail et le modifier, si vous le souhaitez. Pendant le montage, vous obtenez une belle représentation visuelle du workflow:

55441b158f6027f3.png

Vous pouvez également exécuter le workflow manuellement depuis la console Cloud avec les bons paramètres. À la place, 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 d'événements storage.object.finalize et storage.object.delete.

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

Vous allez déclencher les workflows depuis la fonction Cloud en écoutant 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 vérifier l'intégralité du code dans index.js.

Déployer une application 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 pour finaliser les événements:

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 répondant 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é, les deux fonctions s'affichent dans la console Cloud:

7d60c8b7851f39f5.png

14. Interface (App Engine)

Au cours de cette étape, vous allez créer une interface Web sur Google App Engine à partir de l'atelier Pic-a-daily : atelier 4 : créer une interface Web qui permettra aux utilisateurs d'importer des images à partir de l'application Web et de parcourir les photos importées et leurs vignettes.

223fb2281614d053.png

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

Explorer le code

L'application App Engine s'appelle frontend. Vous pouvez vérifier l'intégralité du code 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 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, un message vous indique 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 consulter la section "App Engine" de Cloud Console pour vérifier que l'application est déployée et explorer les fonctionnalités d'App Engine, telles que la gestion des versions et la répartition du trafic:

f4bd5f4de028bd83.png

15. Tester les workflows

Pour effectuer un test, accédez à l'URL App Engine par défaut de l'application (https://<YOUR_PROJECT_ID>.appspot.com/). L'interface utilisateur doit s'exécuter.

1649ac060441099.png

Importez une image. Cela devrait déclencher les workflows. Vous pouvez voir leur exécution à l'état Active dans Cloud Console:

b5a2a3d7a2bc094.png

Une fois les workflows terminés, vous pouvez cliquer sur l'ID d'exécution et afficher le résultat des différents services:

8959df5098c21548.png

Importez trois autres photos. La vignette et le montage des images des buckets Cloud Storage et de l'interface App Engine devraient également être mis à jour:

d90c786ff664a5dc.png

16. Nettoyer (facultatif)

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

gcloud projects delete ${GOOGLE_CLOUD_PROJECT} 

17. Félicitations !

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

Points abordés

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