Codzienne zdjęcia: moduł 6 – aranżacja z użyciem Workflows

1. Omówienie

W poprzednich modułach stworzyliśmy opartą na zdarzeniach wersję aplikacji Pic-a-daily, która używała funkcji w Cloud Storage uruchomionej w Cloud Functions dla usługi analizy obrazów, a GCS aktywował kontener Cloud Run przez Pub/Sub dla usługi miniatur, a Eventarc w celu aktywowania usługi Image Garbage Collector w Cloud Run. Istnieje również usługa Kolażu aktywowana przez Cloud Scheduler:

d93345bfc235f81e.png

W tym module utworzysz z administrowaną wersją aplikacji. Zamiast różnych typów zdarzeń przechodzących przez system możesz używać Workflows do administrowania usługami i wywoływać je w ten sposób:

b763efcbf5589747.png

Czego się nauczysz

  • App Engine
  • Cloud Firestore
  • Cloud Functions
  • Cloud Run
  • Przepływy pracy

2. Konfiguracja i wymagania

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Zapamiętaj identyfikator projektu, unikalną nazwę we wszystkich projektach Google Cloud (powyższa nazwa jest już zajęta i nie będzie Ci odpowiadać). W dalszej części tego ćwiczenia w programie będzie ona określana jako PROJECT_ID.

  1. Następnie musisz włączyć płatności w Cloud Console, aby korzystać z zasobów Google Cloud.

Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Postępuj zgodnie z instrukcjami podanymi w sekcji „Czyszczenie” W tym samouczku znajdziesz wskazówki, jak wyłączyć zasoby, aby uniknąć naliczania opłat. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.

Uruchamianie Cloud Shell

Google Cloud można obsługiwać zdalnie z laptopa, ale w ramach tego ćwiczenia z programowania wykorzystasz Google Cloud Shell – środowisko wiersza poleceń działające w Cloud.

W konsoli GCP kliknij ikonę Cloud Shell na górnym pasku narzędzi:

bce75f34b2c53987.png

Uzyskanie dostępu do środowiska i połączenie się z nim powinno zająć tylko kilka chwil. Po zakończeniu powinno pojawić się coś takiego:

f6ef2b5f13479f3a.png

Ta maszyna wirtualna ma wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, znacząco zwiększając wydajność sieci i uwierzytelnianie. Wszystkie zadania w tym module możesz wykonać w przeglądarce.

3. Wprowadzenie do Workflows

90fcd42d556e310e.jpeg

Przepływy pracy umożliwiają tworzenie bezserwerowych przepływów pracy, które łączą serię bezserwerowych zadań w określonej przez Ciebie kolejności. Możesz połączyć możliwości interfejsów API Google Cloud, usług bezserwerowych, takich jak Cloud Functions i Cloud Run, oraz wywołań zewnętrznych interfejsów API, aby tworzyć elastyczne aplikacje bezserwerowe.

Jak możesz oczekiwać od administratora, Workflows umożliwia definiowanie przepływu logiki biznesowej w języku definiowania przepływu pracy opartym na języku YAML/JSON oraz udostępnia interfejs Workflows Execution API i UI Workflows do aktywowania tych przepływów.

Jest czymś więcej niż zwykłym orkiestratorem dzięki wbudowanym i konfigurowalnym funkcjom:

  • Elastyczne ponawianie prób i obsługa błędów między krokami zapewniające niezawodne wykonywanie kroków.
  • Analiza składni JSON i przekazywanie zmiennych między krokami w celu uniknięcia tworzenia kodu typu glue.
  • Formuły wyrażeń używane do podejmowania decyzji umożliwiają wykonywanie kroków warunkowych.
  • Podrzędne przepływy pracy dla modułowych i wielokrotnego użytku przepływów pracy.
  • Obsługa usług zewnętrznych umożliwia administrowanie usługami spoza Google Cloud.
  • Obsługa uwierzytelniania w Google Cloud i usługach zewnętrznych na potrzeby bezpiecznego wykonywania kroków.
  • Łączniki z usługami Google Cloud, takimi jak Pub/Sub, Firestore, Lista zadań czy Secret Manager, co ułatwia integrację.

Należy też wspomnieć, że Workflows to w pełni zarządzana bezserwerowa usługa. Brak serwerów, które trzeba konfigurować lub skalować, i płacisz tylko za to, z czego korzystasz.

4. Włącz interfejsy API

W tym module połączysz usługi Cloud Functions i Cloud Run z Workflows. Będziesz też korzystać z usług App Engine, Cloud Build, Vision API i innych.

W Cloud Shell sprawdź, czy wszystkie niezbędne usługi są włączone:

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 \

Po pewnym czasie operacja powinna się zakończyć:

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

5. Pobierz kod

Pobierz kod, jeśli nie udało Ci się jeszcze ukończyć poprzednich modułów dotyczących kodu:

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

W tym module dostępna będzie taka struktura folderów:

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

Odpowiednie foldery:

  • frontend zawiera frontend App Engine, którego będziemy używać z modułu 4.
  • functions zawiera funkcje w Cloud Functions utworzone dla przepływu pracy.
  • services zawiera usługi Cloud Run zmodyfikowane dla przepływu pracy.
  • workflows.yaml to plik definicji przepływu pracy.

6. Poznawanie pliku YAML Workflows

Plik workflows.yaml definiuje przepływ pracy w serii kroków. Przyjrzyjmy się im dokładniej.

Na początku przepływu pracy są przekazywane pewne parametry. Będą one przekazywane przez 2 funkcje w Cloud Functions aktywujące Workflows. Te funkcje omówimy później, ale przepływy pracy rozpoczną się tak:

d44a5e18aa9d4660.png

W pliku YAML możesz zobaczyć, że te parametry są przypisane do zmiennych w kroku init, takie jak nazwy plików i zasobników wywołujące zdarzenie oraz adresy URL niektórych usług Cloud Functions i Cloud Run wywoływanych przez Workflows:

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}

Następnie przepływy pracy sprawdzają typ zdarzenia. Obsługiwane są 2 typy zdarzeń: object.finalize (wywoływane, gdy plik jest zapisywany w zasobniku Cloud Storage) i object.delete (wywoływane po usunięciu pliku). Każda inna czynność spowoduje zgłoszenie nieobsługiwanego wyjątku.

dd1f450983655619.png

Oto krok w definicji przepływu pracy YAML, w którym sprawdzamy typ zdarzenia dotyczącego przechowywania plików:

    - 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

Zwróć uwagę, że Workflows obsługuje instrukcje Switch i obsługę wyjątków, w tym instrukcje przełącznika i różne jego warunki, a także instrukcje zgłaszania błędu w przypadku nierozpoznanego zdarzenia.

Teraz przyjrzyjmy się imageAnalysisCall. Jest to seria wywołań interfejsu Workflows, które wywołują interfejs Vision API w celu przeanalizowania obrazu, przekształcenia danych odpowiedzi interfejsu Vision API w celu sortowania etykiet obiektów rozpoznawanych na zdjęciu, wybrania dominujących kolorów, sprawdzania, czy obraz jest bezpieczny do wyświetlenia, a następnie zapisywania metadanych w Cloud Firestore.

Zwróć uwagę, że wszystko odbywa się w Workflows, z wyjątkiem funkcji w Cloud Transform Vision (zostaną one wdrożone później):

ca2ad16b9cbb436.png

Tak wyglądają kroki w pliku 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

Kolejne 2 kroki po przeanalizowaniu obrazu to utworzenie jego miniatury oraz kolażu najnowszych zdjęć. W tym celu należy wdrożyć 2 usługi Cloud Run i wywołać je w krokach thumbnailCall i collageCall:

76f9179323c3144.png

Kroki w pliku 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

Ta gałąź wykonania kończy się zwróceniem kodów stanu z każdej usługi w finalizeCompleted kroku:

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

Druga gałąź wykonania to usunięcie z głównego zasobnika pliku zawierającego zdjęcia w wysokiej rozdzielczości. W tej gałęzi chcemy usunąć miniaturę obrazu z zasobnika zawierającego miniatury i usunąć jego metadane z Firestore. Oba te elementy są wykonywane w przypadku wywołań HTTP z Workflows:

f172379274dcb3c2.png

Kroki w pliku 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

Gałąź usuwania kończy się zwróceniem wyników / kodów z każdego kroku:

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

W kolejnych krokach utworzymy wszystkie zewnętrzne zależności Workflows: zasobniki, funkcje w Cloud Functions, usługi Cloud Run i bazę danych Firestore.

7. Tworzenie zasobników

Potrzebujesz 2 zasobników na obrazy: jeden na oryginalne obrazy o wysokiej rozdzielczości, a drugi do zapisywania miniatur obrazów.

Za pomocą narzędzia gsutil utwórz publiczny regionalny zasobnik (w tym przypadku w Europie) z jednolitym dostępem użytkowników do przesyłania zdjęć:

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}

Utwórz kolejny publiczny zasobnik regionalny na miniatury:

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}

Możesz dokładnie sprawdzić, czy zasobniki zostały utworzone i publiczne, otwierając sekcję Cloud Storage w konsoli Cloud:

15063936edd72f06.png

8. Transformacja danych Vision (funkcja w Cloud Functions)

Plik Workflows.yaml rozpoczyna się od kroków init, eventTypeSwitch i eventTypeNotSupported. Dzięki temu zdarzenia pochodzące z zasobników są kierowane do odpowiednich kroków.

W przypadku zdarzenia object.finalize krok imageAnalysisCall wywołuje interfejs Vision API w celu wyodrębnienia metadanych utworzonego obrazu. Wszystkie te czynności są wykonywane w Workflows:

daaed43a22d2b0d3.png

Następnie musimy przekształcić dane zwracane z interfejsu Vision API, zanim zapiszesz je w Firestore. Mówiąc dokładniej, musimy:

  • Wyświetl listę etykiet zwróconych dla obrazu.
  • Pobierz dominujący kolor obrazu.
  • Określ, czy zdjęcie jest bezpieczne.

Odbywa się to w kodzie funkcji w Cloud Functions i Workflows, która wywołuje po prostu tę funkcję:

5e120e70c67779cd.png

Zapoznaj się z kodem

Ta funkcja w Cloud Functions nosi nazwę vision-data-transform. Pełny kod znajdziesz w pliku index.js. Jak widać, jedynym przeznaczeniem tej funkcji jest wykonanie przekształcenia z JSON na JSON, aby w łatwy sposób przechowywać metadane obrazu w Firestore.

Wdrażanie w Cloud Functions

Przejdź do folderu:

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

Ustaw wybrany region:

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

Wdróż funkcję za pomocą:

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

Po wdrożeniu funkcji krok transformImageAnalysisData w Workflows będzie mógł wywołać tę funkcję w celu przeprowadzenia przekształcenia danych interfejsu Vision API.

9. Przygotowywanie bazy danych

Kolejnym krokiem w sekcji Workflows jest sprawdzenie bezpieczeństwa obrazu na podstawie jego danych, a następnie zapisanie informacji o zdjęciu zwróconym przez interfejs Vision API w bazie danych Cloud Firestore – szybkiej, w pełni zarządzanej, bezserwerowej, chmurowej bazie dokumentów NoSQL:

6624c616bc7cd97f.png

Oba te procesy wykonuje się w Workflows, ale do prawidłowego działania musisz utworzyć bazę danych Firestore, w której będą przechowywane metadane.

Najpierw utwórz aplikację App Engine w regionie, w którym chcesz bazy danych Firestore (jest to wymagane w przypadku Firestore):

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

Następnie utwórz bazę danych Firestore w tym samym regionie:

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

Dokumenty zostaną utworzone automatycznie w naszej kolekcji i będą zawierać 4 pola:

  • name (ciąg znaków): nazwa pliku przesłanego zdjęcia, który jest również kluczem do dokumentu.
  • labels (tablica ciągów znaków): etykiety rozpoznawane przez interfejs Vision API
  • color (ciąg znaków): szesnastkowy kod koloru dominującego (np. #ab12ef)
  • created (data): sygnatura czasowa przechowywania metadanych obrazu.
  • thumbnail (wartość logiczna): opcjonalne pole, które będzie obecne i będzie mieć wartość true (prawda), jeśli dla danego zdjęcia wygenerowano obraz miniatury

Będziemy szukać w Firestore zdjęć, które mają dostępne miniatury, i sortujemy według daty utworzenia, więc konieczne będzie utworzenie indeksu wyszukiwania. Indeks możesz utworzyć za pomocą tego polecenia:

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

Tworzenie indeksu może potrwać około 10 minut.

Utworzony indeks możesz zobaczyć w konsoli Cloud:

43af1f5103bf423.png

Krok storeMetadata przepływów pracy umożliwi teraz przechowywanie metadanych obrazu w Firestore.

10. Usługa miniatur (Cloud Run)

Kolejnym etapem łańcucha jest utworzenie miniatury obrazu. Odbywa się to w kodzie w usłudze Cloud Run, a Workflows wywołuje tę usługę w thumbnailCall kroku:

84d987647f082b53.png

Zapoznaj się z kodem

Usługa Cloud Run nosi nazwę thumbnails. Pełny kod znajdziesz w pliku index.js.

Tworzenie i publikowanie obrazu kontenera

Cloud Run uruchamia kontenery, ale najpierw musisz utworzyć obraz kontenera (zdefiniowany w Dockerfile). Za pomocą Google Cloud Build możesz tworzyć obrazy kontenerów, a następnie hostować je w Google Container Registry.

Przejdź do folderu:

cd workflows/services/thumbnails/nodejs

Kompilacja:

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

Po minucie lub 2 minutach kompilacja powinna się zakończyć, a kontener zostanie wdrożony w Google Container Registry.

Wdrażanie w Cloud Run

Ustaw niezbędne zmienne i konfigurację:

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

Wdróż za pomocą tego polecenia:

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}

Po wdrożeniu usługi krok thumbnailCall przepływów pracy będzie mógł ją wywołać.

11. Usługa kolażu (Cloud Run)

Kolejnym elementem łańcucha jest utworzenie kolażu z najnowszych zdjęć. Odbywa się to w kodzie w usłudze Cloud Run, a Workflows wywołuje tę usługę w collageCall kroku:

591e36149066e1ba.png

Zapoznaj się z kodem

Usługa Cloud Run nosi nazwę collage. Pełny kod znajdziesz w pliku index.js.

Tworzenie i publikowanie obrazu kontenera

Cloud Run uruchamia kontenery, ale najpierw musisz utworzyć obraz kontenera (zdefiniowany w Dockerfile). Za pomocą Google Cloud Build możesz tworzyć obrazy kontenerów, a następnie hostować je w Google Container Registry.

Przejdź do folderu:

cd services/collage/nodejs

Kompilacja:

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

Po minucie lub 2 minutach kompilacja powinna się zakończyć, a kontener zostanie wdrożony w Google Container Registry.

Wdrażanie w Cloud Run

Ustaw niezbędne zmienne i konfigurację:

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

Rozlokuj:

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}

Po wdrożeniu usługi możesz sprawdzić, czy obie usługi są uruchomione w sekcji Cloud Run w konsoli Cloud, a krok collageCall przepływów pracy będzie mógł wywołać tę usługę:

3ae9873f4cbbf423.png

12. Wdrażanie przepływów pracy

Wdrożyliśmy wszystkie zewnętrzne zależności Workflows. Pozostałe kroki (finalizeCompleted, pictureGarbageCollectionGCS, pictureGarbageCollectionFirestore, deleteCompleted) można wykonać w samym Workflows.

Pora wdrożyć przepływy pracy.

Przejdź do folderu zawierającego plik workflows.yaml i wdróż go za pomocą:

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

Za kilka sekund przepływ pracy powinien zostać wdrożony i będzie go można zobaczyć w sekcji Przepływy pracy w konsoli Cloud:

94a720149e5df9c5.png

Jeśli chcesz, możesz kliknąć przepływ pracy i edytować go. Podczas edytowania zobaczysz ładną wizualizację przepływu pracy:

55441b158f6027f3.png

Możesz też ręcznie wykonać przepływ pracy z konsoli Cloud przy użyciu odpowiednich parametrów. Zamiast tego uruchomimy go automatycznie w odpowiedzi na zdarzenia Cloud Storage w następnym kroku.

13. Aktywatory przepływów pracy (Cloud Functions)

Przepływ pracy został wdrożony i gotowy. Teraz musimy aktywować Workflows po utworzeniu lub usunięciu pliku w zasobniku Cloud Storage. To są odpowiednio zdarzenia storage.object.finalize i storage.object.delete.

Przepływy pracy zawierają interfejsy API i biblioteki klienta do tworzenia i wykonywania przepływów pracy oraz zarządzania nimi. W tym przypadku do aktywowania przepływu pracy użyjesz interfejsu Workflows Execution API, a konkretnie jego biblioteki klienta Node.js.

Włączysz przepływy pracy z Cloud Functions do nasłuchiwania zdarzeń Cloud Storage. Ponieważ funkcja w Cloud Functions może nasłuchiwać tylko 1 typu zdarzenia, wdrożysz 2 funkcje w Cloud Functions, aby nasłuchiwać zdarzeń tworzenia i usuwania:

c4d79646de729e4.png

Zapoznaj się z kodem

Ta funkcja w Cloud Functions nosi nazwę trigger-workflow. Pełny kod znajdziesz w pliku index.js.

Wdrażanie w Cloud Functions

Przejdź do folderu:

cd workflows/functions/trigger-workflow/nodejs

Ustaw niezbędne zmienne i konfigurację:

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}

Wdróż funkcję odpowiadającą na finalizowanie zdarzeń:

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}

Wdróż drugą funkcję, która odpowiada na zdarzenia usuwania:

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}

Po zakończeniu wdrażania w konsoli Cloud będą widoczne obie funkcje:

7d60c8b7851f39f5.png

14. Frontend (App Engine)

W tym kroku utworzysz internetowy frontend w Google App Engine na podstawie Pic-a-daily: Lab 4 – utwórz frontend internetowy, który pozwoli użytkownikom przesyłać zdjęcia z aplikacji internetowej oraz przeglądać przesłane obrazy i ich miniatury.

223fb2281614d053.png

Aby dowiedzieć się więcej o App Engine i przeczytać opis kodu, zobacz Pic-a-daily: Lab 4 – Tworzenie internetowego frontendu.

Zapoznaj się z kodem

Aplikacja App Engine nazywa się frontend. Pełny kod znajdziesz w pliku index.js.

Wdrażanie w App Engine

Przejdź do folderu:

cd frontend

Ustaw wybrany region i zastąp plik GOOGLE_CLOUD_PROJECT w pliku app.yaml rzeczywistym identyfikatorem projektu:

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

Rozlokuj:

gcloud app deploy app.yaml -q

Po kilku minutach zobaczysz informację, że aplikacja obsługuje ruch:

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

Możesz też otworzyć sekcję App Engine w konsoli Cloud, aby zobaczyć, czy aplikacja została wdrożona, i poznać funkcje App Engine, takie jak obsługa wersji i dzielenie ruchu:

f4bd5f4de028bd83.png

15. Testowanie przepływów pracy

Aby przetestować, otwórz domyślny URL App Engine aplikacji (https://<YOUR_PROJECT_ID>.appspot.com/). Interfejs frontendu powinien być aktywny.

1649ac060441099.png

Prześlij zdjęcie. Powinno to aktywować przepływy pracy i zobaczyć wykonanie przepływu pracy w stanie Active w konsoli Cloud:

b5a2a3d7a2bc094.png

Po zakończeniu przepływu pracy możesz kliknąć identyfikator wykonania, by wyświetlić dane wyjściowe z różnych usług:

8959df5098c21548.png

Prześlij jeszcze 3 zdjęcia. Powinny też być zaktualizowane miniatury i kolaż obrazów w zasobnikach Cloud Storage i frontendzie App Engine:

d90c786ff664a5dc.png

16. Czyszczenie (opcjonalnie)

Jeśli nie chcesz zachować aplikacji, możesz zwolnić zasoby, aby ograniczyć koszty i zachować zgodność z zasadami dotyczącymi chmury, usuwając cały projekt:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT} 

17. Gratulacje!

Udało Ci się utworzyć administrowaną wersję aplikacji za pomocą Workflows do administrowania usługami i ich wywoływania.

Omówione zagadnienia

  • App Engine
  • Cloud Firestore
  • Cloud Functions
  • Cloud Run
  • Przepływy pracy