Como acionar o processamento de eventos do Cloud Storage usando o Eventarc e as funções do Cloud Run

1. Visão geral

Neste laboratório, você vai aprender a usar os eventos de bucket do Cloud Storage e o Eventarc para acionar o processamento de eventos. Você vai usar as funções do Cloud Run para analisar dados e processar imagens. A função vai usar a API Vision do Google e salvar a imagem resultante no bucket do Cloud Storage.

424779013ac38648.png

O que você vai aprender

Como criar um pipeline de processamento de imagens.

  • Configurar buckets do Storage
  • Criar funções do Cloud Run para ler e gravar objetos no Cloud Storage
  • Implantar um gatilho do Eventarc
  • Integrar a API Vision para detectar imagens de alimentos
  • Testar e validar a solução completa

Pré-requisitos

  • Para fazer este laboratório, é preciso saber usar o console do Cloud e ambientes shell.
  • Experiência anterior com o Cloud Storage, as funções do Cloud Run ou a API Vision é útil, mas não é obrigatória.

2. Configuração e requisitos

Configuração do projeto do Cloud

  1. Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • O Nome do projeto é o nome de exibição para os participantes do projeto. É uma string de caracteres não usada pelas APIs do Google e pode ser atualizada quando você quiser.
  • O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser mudado após a definição. O console do Cloud gera automaticamente uma string exclusiva. Em geral, não importa o que seja. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, normalmente identificado como PROJECT_ID. Se você não gostar do ID gerado, crie outro aleatório. Se preferir, teste o seu e confira se ele está disponível. Ele não pode ser mudado após essa etapa e permanece durante o projeto.
  • Para sua informação, há um terceiro valor, um Número do projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
  1. Em seguida, ative o faturamento no console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não vai ser muito cara, se tiver algum custo. Para encerrar os recursos e evitar cobranças além deste tutorial, exclua os recursos criados ou exclua o projeto. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Ativar o Cloud Shell

Ative o Cloud Shell clicando no ícone à direita da barra de pesquisa.

b02c63d9c7632ef8.png

Configuração do ambiente

  1. Crie um projeto e variáveis de ambiente relacionadas a recursos executando os comandos abaixo no terminal do Cloud Shell.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NAME=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export REGION=us-east1 
export UPLOAD_BUCKET_NAME=menu-item-uploads-$PROJECT_ID
export UPLOAD_BUCKET=gs://menu-item-uploads-$PROJECT_ID
export BUCKET_THUMBNAILS=gs://menu-item-thumbnails-$PROJECT_ID
export MENU_SERVICE_NAME=menu-service
export USER_EMAIL=$(gcloud config list account --format "value(core.account)")
  1. Ativar as APIs necessárias para o laboratório
gcloud services enable \
    vision.googleapis.com \
    cloudfunctions.googleapis.com \
    pubsub.googleapis.com \
    cloudbuild.googleapis.com \
    logging.googleapis.com \
    eventarc.googleapis.com \
    artifactregistry.googleapis.com \
    run.googleapis.com \
    --quiet
  1. Clonar o repositório
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/cloud-functions

3. Configurar buckets do Cloud Storage

Criar buckets de armazenamento

Crie buckets do Cloud Storage para uploads e miniaturas no seu pipeline de processamento de imagens.

Use o comando gsutil mb e um nome exclusivo para criar dois buckets:

  1. Bucket de upload onde as imagens serão enviadas primeiro
  2. Bucket de miniaturas para armazenar imagens de miniatura geradas

Crie um bucket para fazer upload de novas imagens:

gsutil mb -p $PROJECT_ID -l $REGION $UPLOAD_BUCKET

Exemplo de saída:

Creating gs://menu-item-uploads-cymbal-eats-8399-3119/...

Crie um bucket para armazenar as miniaturas geradas:

gsutil mb -p $PROJECT_ID -l $REGION $BUCKET_THUMBNAILS

Exemplo de saída:

Creating gs://menu-item-thumbnails-cymbal-eats-8399-3119/...

Atualizar permissões do bucket

Atualize as permissões do bucket de armazenamento para permitir a leitura por usuários.

Use o comando gsutil iam ch para conceder permissão para ler e gravar objetos no seu bucket:

gsutil iam ch allUsers:objectViewer $UPLOAD_BUCKET
gsutil iam ch allUsers:objectViewer $BUCKET_THUMBNAILS

Exemplo de saída

Updated IAM policy for project [cymbal-eats-8399-3119].
[...]

4. Configurar contas de serviço

Crie uma conta de serviço personalizada para o Cloud Function processar miniaturas:

export CF_SERVICE_ACCOUNT=thumbnail-service-sa
gcloud iam service-accounts create ${CF_SERVICE_ACCOUNT}

Conceda o papel artifactregistry.reader para permitir operações de leitura do Artifact Registry:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/artifactregistry.reader"

Conceda o papel storage.objectCreator para permitir o armazenamento de imagens geradas no bucket de miniaturas:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/storage.objectCreator"

Conceda o papel run.invoker para permitir a invocação do serviço do Cloud Run:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/run.invoker"

Conceda o papel eventarc.eventReceiver para permitir a recepção de eventos dos provedores:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/eventarc.eventReceiver"

Conceda o papel pubsub.publisher à conta de serviço do Cloud Storage. Isso permite que a conta de serviço publique eventos quando as imagens são enviadas para o bucket.

GCS_SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)

gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
    --member "serviceAccount:$GCS_SERVICE_ACCOUNT" \
    --role "roles/pubsub.publisher"

5. Visão geral da função de processamento de imagens

Crie uma função para fazer o download de uma imagem do Cloud Storage, redimensionar a imagem e fazer o upload de volta para o Cloud Storage. A função vai chamar a API Vision para atribuir um rótulo de descrição à imagem. A função vai verificar o rótulo da descrição. Se o rótulo identificar a imagem como "Comida", um evento será enviado ao serviço de menu para atualizar a imagem e a miniatura do item do menu.

4c3c3b758dba6a9f.png

Como acionar uma função

As funções do Cloud Storage são baseadas em notificações do Pub/Sub do Cloud Storage e são compatíveis com tipos de eventos semelhantes:

Neste laboratório, você vai implantar e acionar uma função quando um objeto for finalizado no Cloud Storage.

Finalização do objeto

Os eventos de finalização de objeto são acionados quando a "gravação" de um objeto do Cloud Storage é concluída. Especificamente, isso significa que criar um objeto novo ou substituir um objeto existente aciona esse evento. As operações de atualização de metadados e arquivamento são ignoradas por esse acionador.

6. Integrar o Cloud Storage

Ele também serve para o armazenamento de objetos no Google Cloud. Um objeto é um dado imutável composto de um arquivo em qualquer formato. Os objetos são armazenados em contêineres chamados de buckets. Todos os buckets estão associados a um projeto, e é possível agrupar os projetos em uma organização. As bibliotecas de cliente e as APIs facilitam a integração com o Cloud Storage

Neste laboratório, você vai usar a biblioteca de cliente para ler e gravar objetos no Cloud Storage.

Instalar a biblioteca de cliente

As bibliotecas de cliente do Cloud estão disponíveis em muitas linguagens de programação conhecidas. Para começar a usar as bibliotecas, instale a biblioteca de cliente.

Como usar a biblioteca de cliente

Os detalhes da implementação dependem muito da linguagem de programação. Para usar a biblioteca de cliente no seu aplicativo, a primeira etapa é importar as dependências do Cloud Storage. Por exemplo, no projeto Node.js, as importações são adicionadas ao arquivo package.json. O snippet abaixo mostra a notificação do arquivo package.json deste laboratório.

package.json

{
    "name": "thumbnail-service",
    "version": "0.1.0",
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0",
      "@google-cloud/storage": "^5.18.2",
      "@google-cloud/vision": "^2.4.2",
        ...
    }
  }

Registrar um callback do CloudEvent

Registre um callback do CloudEvent com o Functions Framework que será acionado pelo Cloud Storage quando uma nova imagem for enviada para o bucket.

index.js

functions.cloudEvent('process-thumbnails', async (cloudEvent) => {
    console.log(`Event ID: ${cloudEvent.id}`);
    console.log(`Event Type: ${cloudEvent.type}`);
    ...

Como criar um objeto de referência de armazenamento

Depois que as bibliotecas de cliente forem importadas, você vai precisar criar um novo cliente de armazenamento e buckets com que o aplicativo vai interagir.

index.js

const storage = new Storage();
const bucket = storage.bucket(file.bucket);
const thumbBucket = storage.bucket(process.env.BUCKET_THUMBNAILS);

Fazer o download de objetos do Cloud Storage

index.js

await bucket.file(file.name).download({
            destination: originalFile
        });

Fazer upload de objetos para o Cloud Storage

É possível enviar solicitações de upload para o Cloud Storage de três maneiras: upload de várias partes da API XML, de solicitação única e retomável. Para uploads maiores ou de streaming, use uploads retomáveis. Com a API XML, os arquivos são enviados em partes e montados como um único objeto. Para objetos menores, use uploads de solicitação única.

O código abaixo faz o upload de uma imagem para o armazenamento em nuvem usando um upload de solicitação única.

index.js

const thumbnailImage = await thumbBucket.upload(thumbFile);

7. Integrar a API Vision

Com o Cloud Vision, os desenvolvedores integram facilmente os recursos de detecção de visão nos aplicativos. Isso inclui rotulação de imagens, detecção de rostos e pontos de referência, reconhecimento ótico de caracteres (OCR, na sigla em inglês) e tags em conteúdo explícito.

Instalar a biblioteca de cliente

As bibliotecas de cliente do Cloud estão disponíveis em muitas linguagens de programação conhecidas. Para começar a usar as bibliotecas, instale a biblioteca de cliente.

Criar um cliente do Image Annotator

Para acessar as APIs do Google usando os SDKs de cliente oficiais, é necessário criar um objeto de serviço baseado no documento de descoberta. Ele descreve a API para o SDK. Você vai precisar buscar o documento no serviço de descoberta da API Vision usando suas credenciais.

index.js

const client = new vision.ImageAnnotatorClient();

Criar uma solicitação da API Vision

A API Vision pode realizar a detecção de recursos em um arquivo de imagem enviando o conteúdo do arquivo de imagem como uma string codificada em base64 no corpo da sua solicitação.

Criar uma solicitação usando o recurso de imagens para anotar sua imagem. Uma solicitação para essa API tem a forma de um objeto com uma lista de solicitações. Cada item nela contém duas informações:

  • Os dados de imagem codificados em Base64.
  • Uma lista de recursos que você quer anotar na imagem.

index.js

        const client = new vision.ImageAnnotatorClient();
        const visionRequest = {
            image: { source: { imageUri: `gs://${file.bucket}/${file.name}` } },
            features: [
                { type: 'LABEL_DETECTION' },
            ]
        };
        const visionPromise = client.annotateImage(visionRequest);

8. Implantar funções do Cloud Run

Esse serviço de redimensionamento de imagem faz parte do sistema mais amplo do Cymbal Eats. Nesta seção, você vai implantar apenas os componentes relacionados ao recurso de processamento de imagens. A instalação completa incorpora uma interface para fazer upload da imagem e uma solicitação downstream para armazenar os metadados resultantes. Esses recursos não são instalados como parte deste laboratório.

Os seguintes componentes serão criados durante a implantação da função:

  • Funções do Cloud Run
  • Gatilho do Eventarc
  • Assinatura e tópico do Pub/Sub

No terminal do Cloud Shell, execute o comando abaixo para implantar funções do Cloud Run com um bucket de acionadores no menu-item-uploads-$PROJECT_ID:

Para implantar uma função do Cloud Run diretamente no Cloud Run, primeiro implante a função e, em seguida, crie um acionador para ela.

Implante as funções do Cloud Run:

gcloud beta run deploy process-thumbnails \
      --source=thumbnail \
      --function process-thumbnails \
      --region $REGION \
      --base-image google-22-full/nodejs20 \
      --no-allow-unauthenticated \
      --project=$PROJECT_ID \
--service-account="${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--set-env-vars=BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS,MENU_SERVICE_URL=$MENU_SERVICE_URL \
  --max-instances=1 \
  --quiet

Exemplo de saída:

Done.                                                                                                                                                                                    
Service [process-thumbnails] revision [process-thumbnails-00001-abc] has been deployed and is serving 100 percent of traffic.
Service URL: https://process-thumbnails-000000000.us-east1.run.app

Crie o gatilho:

gcloud eventarc triggers create process-thumbnails-trigger \
     --location=$REGION \
     --destination-run-service=process-thumbnails \
    --destination-run-region=$REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$UPLOAD_BUCKET_NAME" \
     --service-account="${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com"

Exemplo de saída:

Creating trigger [process-thumbnails-trigger] in project [qwiklabs-gcp-02-53f8532696e1], location [us-east1]...done.                                                                     
WARNING: It may take up to 2 minutes for the new trigger to become active.

Se a implantação do acionador falhar devido a um problema de permissão, aguarde a propagação das mudanças do IAM da etapa anterior. Geralmente, leva de 1 a 2 minutos. Tente implantar novamente.

Exemplo de saída de erro:

...If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent...
[...] 

No console do Cloud, analise o serviço do Cloud Run que foi criado para a função:

546c5c951cf0f2f.png

No console do Cloud, analise o gatilho do Eventarc criado para a função:

dec11309016b09ac.png

No console do Cloud, revise o Tópico e a Assinatura do Pub/Sub que foram criados para o gatilho do Eventarc:

affe089c39ae1465.png

a4c41ede2af300db.png

9. Testar e validar a solução completa

Faça upload de uma nova foto no Cloud Storage e monitore o progresso do pipeline à medida que as imagens são analisadas. Você vai testar a solução completa monitorando os registros das funções do Cloud.

Como fazer upload de uma imagem

ab7b43f876f9c3a9.jpeg

  1. Salve esta imagem na sua máquina local.
  2. Renomeie o arquivo 1.jpg.
  3. Abra o console do Cloud Storage.
  4. Clique no bucket menu-item-uploads-....
  5. Clique em ENVIAR ARQUIVOS.
  6. Faça upload de 1.jpg para o bucket de armazenamento
  7. No console do Cloud, acesse o Cloud Run.
  8. Clique em process-thumbails.
  9. Clique na guia LOGS.

fca8e4bafbdf135d.png

  1. Navegue até o bucket menu-item-thumbnails-$PROJECT_ID Cloud Storage.
  2. Verifique se a imagem da miniatura foi criada no bucket de miniaturas

1b6dee72a1fde681.png

Fazer upload de uma imagem que não seja de alimentos

Para verificar se a função funciona corretamente, faça o upload de uma imagem que não contenha um objeto classificado como "Comida".

c76dd525765f66a6.jpeg

  1. Salve esta imagem na sua máquina local.
  2. Renomeie o arquivo 2.jpg.
  3. Abra o console do Cloud Storage.
  4. Clique no bucket menu-item-uploads-....
  5. Clique em ENVIAR ARQUIVOS
  6. Faça upload de 2.jpg para o bucket de armazenamento
  7. No console do Cloud, acesse o Cloud Run.
  8. Clique em process-thumbails.
  9. Clique na guia LOGS.

18b1e30ee78d3955.png

10. Parabéns!

Parabéns, você concluiu o laboratório!

O que vem em seguida:

Conheça outros codelabs da Cymbal Eats:

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto ou mantenha o projeto e exclua cada um dos recursos.

Excluir o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para este tutorial.