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

1. Übersicht

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

d93345bfc235f81e.png

In diesem Lab erstellen Sie eine orchestrierte Version der App. Anstelle verschiedener Arten von Ereignissen, die durch das System fließen, verwenden Sie Workflows, um Dienste wie folgt zu orchestrieren und aufzurufen:

b763efcbf5589747.png

Aufgaben in diesem Lab

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

2. Einrichtung und Anforderungen

Umgebung für das selbstbestimmte 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 in diesem Codelab später als PROJECT_ID bezeichnet.

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

Dieses Codelab sollte ohne großen Aufwand betrieben werden. Folgen Sie der Anleitung im Abschnitt „Bereinigen“, . Hier erfahren Sie, wie Sie Ressourcen herunterfahren, damit Ihnen über dieses Tutorial hinaus keine Kosten entstehen. Neue Google Cloud-Nutzer haben Anspruch auf eine kostenlose Testversion von 300$.

Cloud Shell starten

Sie können Google Cloud zwar von Ihrem Laptop aus aus der Ferne bedienen, in diesem Codelab verwenden Sie jedoch Google Cloud Shell, 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 dauert nur einen Moment. Wenn er abgeschlossen ist, sollten Sie in etwa Folgendes sehen:

f6ef2b5f13479f3a.png

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft auf Google Cloud, wodurch die Netzwerkleistung und Authentifizierung erheblich verbessert werden. Sie können alle Aufgaben in diesem Lab ganz einfach in einem Browser erledigen.

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 miteinander verknüpfen. Sie können die Leistungsfähigkeit der APIs von Google Cloud, serverlose Produkte wie Cloud Functions und Cloud Run sowie Aufrufe externer APIs kombinieren, um flexible, serverlose Anwendungen zu erstellen.

Wie Sie es von einem Orchestrator erwarten können, 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.

Mit diesen integrierten und konfigurierbaren Funktionen ist es mehr als ein bloßer Orchestrator:

  • Flexible Wiederholungs- und Fehlerbehandlung zwischen Schritten für eine zuverlässige Ausführung von Schritten.
  • JSON-Parsing und Übergabe von Variablen zwischen Schritten, um Glue-Code zu vermeiden
  • Ausdrucksformeln für Entscheidungen ermöglichen die Ausführung bedingter Schritte.
  • Untergeordnete Workflows für modulare und wiederverwendbare Workflows.
  • Die Unterstützung externer Dienste ermöglicht die Orchestrierung von Diensten über Google Cloud hinaus.
  • Authentifizierungsunterstützung für Google Cloud und externe Dienste für sichere Schrittausführungen.
  • Connectors zu Google Cloud-Diensten wie Pub/Sub, Firestore, Tasks und Secret Manager für eine einfachere Integration.

Übrigens: 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. Außerdem verwenden Sie die 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

Rufen Sie den Code ab, falls Sie dies noch nicht in den vorherigen Codelabs getan haben:

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

Dies sind die relevanten Ordner:

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

6. YAML für Workflows ansehen

Die Datei workflows.yaml definiert den Workflow in einer Reihe von Schritten. Gehen wir sie durch, um sie besser zu verstehen.

Am Anfang des Workflows werden einige Parameter übergeben. Sie werden von zwei Cloud Functions-Funktionen übergeben, die die Workflows auslösen. Auf diese Funktionen kommen wir später noch, aber so beginnt der Workflow:

d44a5e18aa9d4660.png

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

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 prüfen Workflows den Ereignistyp. 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). Alles andere löst eine Ausnahme vom Typ „Ereignis nicht unterstützt“ aus.

dd1f450983655619.png

Im Folgenden sehen Sie in der YAML-Workflow-Definition den Schritt, 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

Beachten Sie, wie Workflows Switch-Anweisungen und die Ausnahmebehandlung mit der Switch-Anweisung und ihren verschiedenen Bedingungen sowie der Erhöhen-Anweisung zum Auslösen eines Fehlers unterstützen, wenn das Ereignis nicht erkannt wird.

Als Nächstes werfen wir einen Blick auf imageAnalysisCall. Dies ist eine Reihe von Aufrufen aus Workflows, mit denen die Vision API aufgerufen wird, um das Bild zu analysieren, die Antwortdaten der Vision API zu transformieren, um die Beschriftungen der auf dem Bild erkannten Dinge 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 mit Ausnahme der Vision Transform Cloud Functions-Funktionen (die wir später bereitstellen werden) alles in Workflows erledigt wird:

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

Nach der Analyse des Bilds besteht die nächste zwei Schritte darin, eine Miniaturansicht des Bildes und eine Collage der neuesten Bilder zu erstellen. Dazu stellen Sie zwei Cloud Run-Dienste bereit und rufen diese in den Schritten thumbnailCall und collageCall auf:

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 Zweig der Ausführung endet mit der Rückgabe von Statuscodes der einzelnen Dienste im Schritt finalizeCompleted:

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

Der andere Zweig der Ausführung ist das Löschen einer Datei aus dem Haupt-Storage-Bucket, die die hochauflösenden Versionen der Bilder enthält. In diesem Zweig löschen wir die Miniaturansicht des Bildes im Bucket mit den Miniaturansichten und löschen die Metadaten aus Firestore. Beides erfolgt mit HTTP-Aufrufen aus Workflows:

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öschzweig endet mit der Rückgabe von Ergebnissen / Codes aus jedem Schritt:

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

In den folgenden Schritten erstellen Sie 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 hochauflösenden Originalbildern 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, auf den Nutzer Bilder hochladen können:

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 Miniaturansichten:

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. Rufen Sie dazu den Cloud Storage-Bereich der Cloud Console auf:

15063936edd72f06.png

8. Vision-Datentransformation (Cloud Functions-Funktion)

Workflows.yaml beginnt mit init, eventTypeSwitch, eventTypeNotSupported Schritten. Damit wird sichergestellt, dass die aus Buckets stammenden Ereignisse an die richtigen Schritte weitergeleitet werden.

Für das Ereignis object.finalize ruft der Schritt imageAnalysisCall die Vision API auf, um Metadaten des erstellten Bilds 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:

  • Listet die für das Bild zurückgegebenen Labels auf.
  • Rufen Sie die Hauptfarbe des Bildes ab.
  • Prüfen Sie, ob das Bild unbedenklich ist.

Dies erfolgt im Code in einer Cloud Functions-Funktion und Workflows ruft einfach diese Funktion 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, besteht der einzige Zweck dieser Funktion darin, 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 bereit mit:

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

Sobald die Funktion bereitgestellt ist, kann der Schritt transformImageAnalysisData von Workflows diese Funktion aufrufen, um die Vision API-Datentransformation durchzuführen.

9. Datenbank vorbereiten

Als Nächstes wird in den Workflows die Sicherheit des Bildes anhand der Bilddaten geprüft. Anschließend speichern Sie die Informationen zu dem Bild, das von der Vision API zurückgegeben wird, in der Cloud Firestore-Datenbank, einer schnellen, vollständig verwalteten, serverlosen, cloudnativen NoSQL-Dokumentendatenbank:

6624c616bc7cd97f.png

Beides erfolgt in Workflows, aber Sie müssen die Firestore-Datenbank erstellen, damit Metadaten gespeichert werden können.

Erstellen Sie zuerst eine App Engine-Anwendung in der Region, in der Sie die Firestore-Datenbank benötigen (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 Bilds, der auch der Schlüssel des Dokuments ist
  • labels (Array von Strings): die Labels erkannter Elemente von der Vision API
  • color (String): der hexadezimale Farbcode der dominanten Farbe (d. h. #ab12ef).
  • created (Datum): der Zeitstempel, der angibt, wann die Metadaten dieses Images gespeichert wurden
  • thumbnail (boolesch): ein optionales Feld, das angezeigt wird und „true“ ist, wenn eine Miniaturansicht für dieses Bild generiert wurde

Da wir in Firestore nach Bildern suchen, für die Miniaturansichten verfügbar sind, 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

Die Indexerstellung kann bis zu 10 Minuten dauern.

Nachdem der Index erstellt wurde, wird er in der Cloud Console angezeigt:

43af1f5103bf423.png

Im storeMetadata-Schritt des Workflows können die Image-Metadaten jetzt in Firestore gespeichert werden.

10. Miniaturansichtsdienst (Cloud Run)

Als Nächstes wird eine Miniaturansicht eines Bildes erstellt. Dies erfolgt im Code eines Cloud Run-Dienstes und 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

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

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 bis zwei Minuten sollte der Build erfolgreich sein und der Container wird in Google Container Registry bereitgestellt.

In Cloud Run bereitstellen

Legen Sie einige erforderliche Variablen und die Konfiguration 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 Bereitstellung 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 des Workflows diesen Dienst aufrufen.

11. Collage-Dienst (Cloud Run)

Als Nächstes besteht die Möglichkeit, eine Collage aus den neuesten Bildern zu erstellen. Dies erfolgt im Code eines Cloud Run-Dienstes und 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

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

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 bis zwei Minuten sollte der Build erfolgreich sein und der Container wird in Google Container Registry bereitgestellt.

In Cloud Run bereitstellen

Legen Sie einige erforderliche Variablen und die Konfiguration 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 im Bereich „Cloud Run“ der Cloud Console prüfen, ob beide Dienste ausgeführt werden. Der collageCall-Schritt „Workflows“ kann diesen Dienst aufrufen:

3ae9873f4cbbf423.png

12. Workflows-Bereitstellung

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

Es ist an der Zeit, die Workflows bereitzustellen!

Rufen Sie den Ordner auf, der die Datei workflows.yaml enthält, und stellen Sie sie bereit:

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

Der Workflow sollte in wenigen Sekunden bereitgestellt werden. Sie können ihn im Bereich „Workflows“ der Cloud Console sehen:

94a720149e5df9c5.png

Sie können auf den Arbeitsablauf klicken und ihn bearbeiten, wenn Sie möchten. Während der Bearbeitung wird der Workflow visuell ansprechend 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 ist bereitgestellt und bereit. Jetzt müssen wir die Workflows auslösen, wenn eine Datei in einem Cloud Storage-Bucket erstellt oder gelöscht wird. Dies sind storage.object.finalize- bzw. storage.object.delete-Ereignisse.

Workflows bieten 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 die Cloud Functions-Funktion aus, die Cloud Storage-Ereignisse überwacht. Da eine Cloud Functions-Funktion nur einen Ereignistyp überwachen kann, stellen Sie zwei Cloud Functions-Funktionen bereit, die sowohl Create- als auch Delete-Ereignisse überwachen:

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 die Konfiguration 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 zum Abschließen von Ereignissen antwortet:

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}

Wenn die Bereitstellung abgeschlossen ist, werden in der Cloud Console beide Funktionen angezeigt:

7d60c8b7851f39f5.png

14. Front-End (App Engine)

In diesem Schritt erstellen Sie anhand von Pic-a-daily: Lab 4 – Web-Front-End in Google App Engine ein Web-Front-End, mit dem Nutzer Bilder aus der Webanwendung hochladen und in den hochgeladenen Bildern und deren Miniaturansichten suchen können.

223fb2281614d053.png

Weitere Informationen zu App Engine und die Codebeschreibung finden Sie unter Pic-a-daily: Lab 4 – Web-Front-End erstellen.

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 bis 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, ob die Anwendung bereitgestellt wurde, und sich Funktionen von App Engine wie Versionsverwaltung und Traffic-Aufteilung anzusehen:

f4bd5f4de028bd83.png

15. Workflows testen

Rufen Sie zum Testen die standardmäßige App Engine-URL für die Anwendung (https://<YOUR_PROJECT_ID>.appspot.com/) auf. Sie sollten nun die Frontend-Benutzeroberfläche sehen und ausführen können.

1649ac060441099.png

Laden Sie ein Bild hoch. Dadurch sollten die Workflows ausgelöst werden und Sie können die Workflowausführung im Status Active in der Cloud Console sehen:

b5a2a3d7a2bc094.png

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

8959df5098c21548.png

Lade noch drei weitere Bilder hoch. Auch die Miniaturansicht und die Collage der Bilder in den Cloud Storage-Buckets und im App Engine-Frontend sollten aktualisiert werden:

d90c786ff664a5dc.png

16. Bereinigen (optional)

Wenn Sie die Anwendung nicht behalten möchten, können Sie Ressourcen bereinigen, um Kosten zu sparen und die Cloud insgesamt einwandfrei zu gestalten, indem Sie das gesamte Projekt löschen:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT} 

17. Glückwunsch!

Sie haben mithilfe von Workflows eine orchestrierte Version der App erstellt, um Dienste zu orchestrieren und aufzurufen.

Behandelte Themen

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