Pic-a-daily: Lab 6 – Orchestrierung mit Workflows

1. Übersicht

In den vorherigen Labs haben Sie eine ereignisgesteuerte Version der App „Pic-a-daily“ erstellt, die eine durch Google Cloud Storage ausgelöste Cloud-Funktion für den Bildanalysedienst, einen durch GCS ausgelösten Cloud Run-Container über Pub/Sub für den Miniaturbilddienst und Eventarc zum Auslösen des Bild-Garbage Collector-Dienstes in Cloud Run verwendet. Außerdem gab es einen Collage-Dienst, der von Cloud Scheduler ausgelöst wurde:

d93345bfc235f81e.png

In diesem Lab erstellen Sie eine orchestrierte Version der App. Anstelle von verschiedenen Ereignistypen, die durch das System fließen, verwenden Sie Workflows, um Dienste so zu orchestrieren und aufzurufen:

b763efcbf5589747.png

Lerninhalte

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

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Notieren Sie sich die Projekt-ID, also den projektübergreifend nur einmal vorkommenden Namen eines Google Cloud-Projekts. Der oben angegebene Name ist bereits vergeben und kann leider nicht mehr verwendet werden. Sie wird später in diesem Codelab als PROJECT_ID bezeichnet.

  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Google Cloud-Ressourcen verwenden zu können.

Die Durchführung dieses Codelabs sollte keine oder nur geringe Kosten verursachen. Folgen Sie bitte der Anleitung im Abschnitt „Bereinigen“, in der Sie erfahren, wie Sie Ressourcen herunterfahren können, damit nach Abschluss dieser Anleitung keine Gebühren anfallen. Neue Nutzer von Google Cloud kommen für das Programm für kostenlose Testversionen mit einem Guthaben von 300$ infrage.

Cloud Shell starten

Während Sie Google Cloud von Ihrem Laptop aus per Fernzugriff nutzen können, wird in diesem Codelab Google Cloud Shell verwendet, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Klicken Sie in der GCP Console oben rechts in der Symbolleiste auf das Cloud Shell-Symbol:

bce75f34b2c53987.png

Die Bereitstellung und Verbindung mit der Umgebung sollte nur wenige Augenblicke dauern. Anschließend sehen Sie in etwa Folgendes:

f6ef2b5f13479f3a.png

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Für dieses Lab benötigen Sie lediglich einen Browser.

3. Einführung in Workflows

90fcd42d556e310e.jpeg

Mit Workflows können Sie serverlose Workflows erstellen, die eine Reihe von serverlosen Aufgaben in einer von Ihnen definierten Reihenfolge verknüpfen. Sie können die Leistungsfähigkeit der APIs von Google Cloud, serverlose Produkte wie Cloud Functions und Cloud Run sowie Aufrufe von externen APIs kombinieren, um flexible serverlose Anwendungen zu erstellen.

Wie Sie es von einem Orchestrator erwarten, können Sie mit Workflows den Ablauf Ihrer Geschäftslogik in einer YAML-/JSON-basierten Workflow-Definitionssprache definieren. Außerdem stehen eine Workflows Execution API und eine Workflows-Benutzeroberfläche zum Auslösen dieser Abläufe zur Verfügung.

Dank dieser integrierten und konfigurierbaren Funktionen ist sie mehr als nur ein Orchestrator:

  • Flexible Wiederholungs- und Fehlerbehandlung zwischen Schritten für eine zuverlässige Ausführung von Schritten.
  • JSON-Parsing und Variablenübergabe zwischen Schritten, um Glue-Code zu vermeiden.
  • Ausdrucksformeln für Entscheidungen ermöglichen bedingte Schrittausführungen.
  • Unter-Workflows für modulare und wiederverwendbare Workflows.
  • Durch die Unterstützung externer Dienste können Dienste über Google Cloud hinaus orchestriert werden.
  • Unterstützung der Authentifizierung für Google Cloud- und externe Dienste für die sichere Ausführung von Schritten.
  • Connectors für Google Cloud-Dienste wie Pub/Sub, Firestore, Tasks und Secret Manager für eine einfachere Integration.

Workflows ist ein vollständig verwaltetes serverloses Produkt. Sie müssen keine Server konfigurieren oder skalieren und zahlen nur für die tatsächliche Nutzung.

4. APIs aktivieren

In diesem Lab verbinden Sie Cloud Functions- und Cloud Run-Dienste mit Workflows. Sie verwenden auch App Engine, Cloud Build, die Vision API und andere Dienste.

Prüfen Sie in Cloud Shell, ob alle erforderlichen Dienste aktiviert sind:

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 \

Nach einiger Zeit sollte der Vorgang erfolgreich abgeschlossen sein:

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

5. Code abrufen

Wenn Sie den Code noch nicht in den vorherigen Codelabs erhalten haben, können Sie ihn hier abrufen:

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

Sie haben die folgende Ordnerstruktur, die für dieses Lab relevant ist:

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

Das sind die relevanten Ordner:

  • frontend enthält das App Engine-Frontend, das wir aus Lab 4 wiederverwenden.
  • functions enthält die für den Workflow erstellten Cloud Functions.
  • services enthält die für den Workflow geänderten Cloud Run-Dienste.
  • workflows.yaml ist die Workflow-Definitionsdatei.

6. YAML für Workflows ansehen

In der Datei workflows.yaml wird der Workflow in einer Reihe von Schritten definiert. Sehen wir uns das genauer an.

Zu Beginn des Workflows werden einige Parameter übergeben. Sie werden von zwei Cloud Functions übergeben, die die Workflows auslösen. Wir werden später auf diese Funktionen eingehen, aber so beginnt der Workflow:

d44a5e18aa9d4660.png

In YAML sehen Sie, dass diese Parameter im Schritt init Variablen zugewiesen werden, z. B. den Datei- und Bucket-Namen, die das Ereignis auslösen, und den URLs einiger Cloud Functions- und Cloud Run-Dienste, die von Workflows aufgerufen werden:

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}

Als Nächstes wird der Ereignistyp geprüft. Es werden zwei Ereignistypen unterstützt: object.finalize (wird ausgegeben, wenn eine Datei im Cloud Storage-Bucket gespeichert wird) und object.delete (wird ausgegeben, wenn eine Datei gelöscht wird). Andernfalls wird eine Ausnahme für ein nicht unterstütztes Ereignis ausgelöst.

dd1f450983655619.png

Hier sehen Sie den Schritt in der YAML-Workflowdefinition, in dem wir den Typ des Dateispeicherereignisses prüfen:

    - 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

Workflows unterstützt Switch-Anweisungen und die Ausnahmebehandlung mit der Switch-Anweisung und ihren verschiedenen Bedingungen sowie der Raise-Anweisung, um einen Fehler auszulösen, wenn das Ereignis nicht erkannt wird.

Als Nächstes sehen wir uns die imageAnalysisCall an. Dies ist eine Reihe von Aufrufen von Workflows, um die Vision API aufzurufen, um das Bild zu analysieren, die Antwortdaten der Vision API zu transformieren, um die Labels der im Bild erkannten Elemente zu sortieren, die dominanten Farben auszuwählen, zu prüfen, ob das Bild sicher angezeigt werden kann, und dann die Metadaten in Cloud Firestore zu speichern.

Beachten Sie, dass alles in Workflows erfolgt, mit Ausnahme der Vision Transform Cloud Functions, die wir später bereitstellen:

ca2ad16b9cbb436.png

So sehen die Schritte in YAML aus:

    - 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

Nachdem das Bild analysiert wurde, werden im nächsten Schritt das Thumbnail des Bildes und eine Collage der letzten Bilder erstellt. Dazu werden zwei Cloud Run-Dienste bereitgestellt und in den Schritten thumbnailCall und collageCall aufgerufen:

76f9179323c3144.png

Schritte in 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

Dieser Ausführungszweig endet mit der Rückgabe von Statuscodes von jedem Dienst im Schritt finalizeCompleted:

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

Der andere Zweig der Ausführung ist, wenn eine Datei aus dem Hauptspeicher-Bucket mit den hochauflösenden Versionen der Bilder gelöscht wird. In diesem Branch möchten wir die Miniaturansicht des Bildes im Bucket mit den Miniaturansichten und die zugehörigen Metadaten aus Firestore löschen. Beide Vorgänge werden mit HTTP-Aufrufen von Workflows ausgeführt:

f172379274dcb3c2.png

Schritte in 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

Der Löschvorgang endet mit der Rückgabe von Ergebnissen / Codes aus jedem Schritt:

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

In den folgenden Schritten erstellen wir alle externen Abhängigkeiten der Workflows: Buckets, Cloud Functions, Cloud Run-Dienste und Firestore-Datenbank.

7. Buckets erstellen

Sie benötigen zwei Buckets für Bilder: einen zum Speichern von Originalbildern in hoher Auflösung und einen zum Speichern von Miniaturansichten von Bildern.

Erstellen Sie mit dem gsutil-Tool einen öffentlichen regionalen Bucket (in diesem Fall in Europa) mit einheitlichem Zugriff für Nutzer zum Hochladen von Bildern:

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}

Erstellen Sie einen weiteren öffentlichen regionalen Bucket für Thumbnails:

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}

Sie können prüfen, ob Buckets erstellt und öffentlich sind, indem Sie den Cloud Storage-Bereich der Cloud Console aufrufen:

15063936edd72f06.png

8. Vision Data Transform (Cloud-Funktion)

Workflows.yaml beginnt mit den Schritten init, eventTypeSwitch und eventTypeNotSupported. So wird dafür gesorgt, dass die Ereignisse aus den Buckets an die richtigen Schritte weitergeleitet werden.

Für das Ereignis object.finalize wird im Schritt imageAnalysisCall die Vision API aufgerufen, um Metadaten des erstellten Bildes zu extrahieren. Alle diese Schritte werden in Workflows ausgeführt:

daaed43a22d2b0d3.png

Als Nächstes müssen wir die von der Vision API zurückgegebenen Daten transformieren, bevor wir sie in Firestore speichern können. Konkret müssen wir Folgendes tun:

  • Liste der für das Bild zurückgegebenen Labels.
  • Die dominante Farbe des Bildes abrufen.
  • Ermitteln, ob das Bild sicher ist.

Dies geschieht im Code in einer Cloud Functions-Funktion. Workflows ruft diese Funktion einfach auf:

5e120e70c67779cd.png

Code ansehen

Die Cloud Functions-Funktion heißt vision-data-transform. Den vollständigen Code finden Sie in index.js. Wie Sie sehen, dient diese Funktion ausschließlich dazu, eine JSON-zu-JSON-Transformation durchzuführen, um die Bildmetadaten bequem in Firestore zu speichern.

In Cloud Functions bereitstellen

Rufen Sie den Ordner auf:

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

Legen Sie die gewünschte Region fest:

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

Stellen Sie die Funktion mit folgendem Befehl bereit:

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

Nachdem die Funktion bereitgestellt wurde, kann im Schritt transformImageAnalysisData von Workflows diese Funktion aufgerufen werden, um die Vision API-Daten zu transformieren.

9. Datenbank vorbereiten

Als Nächstes wird in den Workflows die Sicherheit des Bildes anhand der Bilddaten geprüft. Anschließend werden die von der Vision API zurückgegebenen Informationen zum Bild in der Cloud Firestore-Datenbank gespeichert. Cloud Firestore ist eine schnelle, vollständig verwaltete, serverlose, cloudnative NoSQL-Dokumentendatenbank:

6624c616bc7cd97f.png

Beide Schritte werden in Workflows ausgeführt. Sie müssen jedoch die Firestore-Datenbank für die Speicherung von Metadaten erstellen, damit sie funktionieren.

Erstellen Sie zuerst eine App Engine-Anwendung in der Region, in der Sie die Firestore-Datenbank haben möchten (eine Voraussetzung für Firestore):

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

Erstellen Sie als Nächstes die Firestore-Datenbank in derselben Region:

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

Die Dokumente werden programmatisch in unserer Sammlung erstellt und enthalten vier Felder:

  • name (String): Der Dateiname des hochgeladenen Bildes, der auch der Schlüssel des Dokuments ist.
  • labels (Array von Strings): die Labels der von der Vision API erkannten Elemente
  • color (String): Der hexadezimale Farbcode der dominanten Farbe (z. B. #ab12ef)
  • created (Datum): Der Zeitstempel, wann die Metadaten dieses Bildes gespeichert wurden.
  • thumbnail (boolescher Wert): Ein optionales Feld, das vorhanden ist und „true“ enthält, wenn für dieses Bild eine Miniaturansicht generiert wurde.

Da wir in Firestore nach Bildern mit verfügbaren Thumbnails suchen und nach dem Erstellungsdatum sortieren, müssen wir einen Suchindex erstellen. Sie können den Index mit dem folgenden Befehl erstellen:

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

Das Erstellen des Index kann bis zu 10 Minuten dauern.

Nachdem der Index erstellt wurde, können Sie ihn in der Cloud Console ansehen:

43af1f5103bf423.png

Im storeMetadata-Schritt von Workflows können die Bildmetadaten jetzt in Firestore gespeichert werden.

10. Thumbnail-Dienst (Cloud Run)

Als Nächstes in der Kette wird eine Miniaturansicht eines Bildes erstellt. Dies geschieht im Code in einem Cloud Run-Dienst. Workflows ruft diesen Dienst im Schritt thumbnailCall auf:

84d987647f082b53.png

Code ansehen

Der Cloud Run-Dienst heißt thumbnails. Den vollständigen Code finden Sie in index.js.

Container-Image erstellen und veröffentlichen

In Cloud Run werden Container ausgeführt, aber Sie müssen zuerst das Container-Image erstellen (definiert in Dockerfile). Mit Google Cloud Build können Sie Container-Images erstellen und dann in Google Container Registry hosten.

Rufen Sie den Ordner auf:

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}

Nach ein oder zwei Minuten sollte der Build erfolgreich sein und der Container wird in der Google Container Registry bereitgestellt.

In Cloud Run bereitstellen

Legen Sie einige erforderliche Variablen und Konfigurationen fest:

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

Stellen Sie die Funktion mit dem folgenden Befehl bereit:

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}

Sobald der Dienst bereitgestellt wurde, kann der thumbnailCall-Schritt in Workflows diesen Dienst aufrufen.

11. Collage-Dienst (Cloud Run)

Als Nächstes in der Kette wird eine Collage aus den neuesten Bildern erstellt. Dies geschieht im Code in einem Cloud Run-Dienst. Workflows ruft diesen Dienst im Schritt collageCall auf:

591e36149066e1ba.png

Code ansehen

Der Cloud Run-Dienst heißt collage. Den vollständigen Code finden Sie in index.js.

Container-Image erstellen und veröffentlichen

In Cloud Run werden Container ausgeführt, aber Sie müssen zuerst das Container-Image erstellen (definiert in Dockerfile). Mit Google Cloud Build können Sie Container-Images erstellen und dann in Google Container Registry hosten.

Rufen Sie den Ordner auf:

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}

Nach ein oder zwei Minuten sollte der Build erfolgreich sein und der Container wird in der Google Container Registry bereitgestellt.

In Cloud Run bereitstellen

Legen Sie einige erforderliche Variablen und Konfigurationen fest:

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

Bereitstellung:

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}

Sobald der Dienst bereitgestellt wurde, können Sie prüfen, ob beide Dienste im Cloud Run-Bereich der Cloud Console ausgeführt werden. Der Schritt „Workflows“ collageCall kann diesen Dienst aufrufen:

3ae9873f4cbbf423.png

12. Workflows bereitstellen

Wir haben alle externen Abhängigkeiten von Workflows bereitgestellt. Alle verbleibenden Schritte (finalizeCompleted, pictureGarbageCollectionGCS, pictureGarbageCollectionFirestore, deleteCompleted) können von Workflows selbst ausgeführt werden.

Jetzt ist es an der Zeit, die Workflows bereitzustellen.

Gehen Sie zum Ordner mit der Datei workflows.yaml und stellen Sie sie mit folgendem Befehl bereit:

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

Nach einigen Sekunden sollte der Workflow bereitgestellt werden. Sie können ihn dann im Abschnitt „Workflows“ der Cloud Console aufrufen:

94a720149e5df9c5.png

Sie können auf den Workflow klicken und ihn bearbeiten. Während der Bearbeitung wird der Workflow visuell dargestellt:

55441b158f6027f3.png

Sie können den Workflow auch manuell über die Cloud Console mit den richtigen Parametern ausführen. Stattdessen wird sie im nächsten Schritt automatisch als Reaktion auf Cloud Storage-Ereignisse ausgeführt.

13. Workflows-Trigger (Cloud Functions)

Der Workflow wird bereitgestellt und ist einsatzbereit. Nun müssen wir die Workflows auslösen, wenn eine Datei in einem Cloud Storage-Bucket erstellt oder gelöscht wird. Das sind die Ereignisse storage.object.finalize und storage.object.delete.

Workflows haben APIs und Clientbibliotheken zum Erstellen, Verwalten und Ausführen von Workflows, die Sie verwenden können. In diesem Fall verwenden Sie die Workflows Execution API und insbesondere die Node.js-Clientbibliothek, um den Workflow auszulösen.

Sie lösen die Workflows über eine Cloud-Funktion aus, die auf Cloud Storage-Ereignisse wartet. Da eine Cloud Functions-Funktion nur auf einen Ereignistyp reagieren kann, stellen Sie zwei Cloud Functions-Funktionen bereit, um sowohl auf Erstellungs- als auch auf Löschereignisse zu reagieren:

c4d79646de729e4.png

Code ansehen

Die Cloud Functions-Funktion heißt trigger-workflow. Den vollständigen Code finden Sie in index.js.

In Cloud Functions bereitstellen

Rufen Sie den Ordner auf:

cd workflows/functions/trigger-workflow/nodejs

Legen Sie einige erforderliche Variablen und Konfigurationen fest:

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}

Stellen Sie die Funktion bereit, die auf Finalize-Ereignisse reagiert:

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}

Stellen Sie die zweite Funktion bereit, die auf Löschereignisse reagiert:

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}

Nach Abschluss der Bereitstellung können Sie beide Funktionen in der Cloud Console sehen:

7d60c8b7851f39f5.png

14. Frontend (App Engine)

In diesem Schritt erstellen Sie ein Web-Front-End in Google App Engine aus Pic-a-daily: Lab 4—Create a web frontend, mit dem Nutzer Bilder aus der Webanwendung hochladen und die hochgeladenen Bilder und ihre Miniaturansichten durchsuchen können.

223fb2281614d053.png

Weitere Informationen zu App Engine und eine Beschreibung des Codes finden Sie unter Pic-a-daily: Lab 4—Create a web frontend.

Code ansehen

Die App Engine-Anwendung heißt frontend. Den vollständigen Code finden Sie in index.js.

In App Engine bereitstellen

Rufen Sie den Ordner auf:

cd frontend

Legen Sie die gewünschte Region fest und ersetzen Sie GOOGLE_CLOUD_PROJECT in app.yaml durch Ihre tatsächliche Projekt-ID:

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

Bereitstellung:

gcloud app deploy app.yaml -q

Nach ein oder zwei Minuten wird Ihnen mitgeteilt, dass die Anwendung Traffic verarbeitet:

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

Sie können auch den App Engine-Bereich der Cloud Console aufrufen, um zu sehen, dass die App bereitgestellt wurde, und App Engine-Funktionen wie Versionsverwaltung und Trafficaufteilung zu nutzen:

f4bd5f4de028bd83.png

15. Workflows testen

Rufen Sie zum Testen die standardmäßige App Engine-URL für die App (https://<YOUR_PROJECT_ID>.appspot.com/) auf. Die Frontend-Benutzeroberfläche sollte jetzt funktionieren.

1649ac060441099.png

Laden Sie ein Bild hoch. Dadurch sollte der Workflow ausgelöst werden. Die Workflow-Ausführung wird in der Cloud Console im Status Active angezeigt:

b5a2a3d7a2bc094.png

Wenn der Workflow abgeschlossen ist, können Sie auf die Ausführungs-ID klicken, um die Ausgabe der verschiedenen Dienste aufzurufen:

8959df5098c21548.png

Laden Sie drei weitere Bilder hoch. Die Miniaturansicht und die Collage der Bilder sollten auch in den Cloud Storage-Buckets und im App Engine-Frontend aktualisiert werden:

d90c786ff664a5dc.png

16. Bereinigen (optional)

Wenn Sie die App nicht behalten möchten, können Sie Ressourcen bereinigen, um Kosten zu sparen und nicht mehr benötigte Ressourcen für andere freizugeben. Löschen Sie dazu das gesamte Projekt:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT} 

17. Glückwunsch!

Sie haben eine orchestrierte Version der App erstellt, in der Workflows zum Orchestrieren und Aufrufen von Diensten verwendet werden.

Behandelte Themen

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