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 eventos de bucket do Cloud Storage e o Eventarc para acionar o processamento de eventos. Você vai usar o Cloud Run functions para analisar dados e processar imagens. A função vai usar a API Vision do Google e salvar a imagem resultante de volta no bucket do Cloud Storage.

424779013ac38648.png

O que você vai aprender

Como criar um pipeline de processamento de imagens.

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

Pré-requisitos

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

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

Clique no ícone à direita da barra de pesquisa para ativar o Cloud Shell.

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. Ative 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 do Cloud Storage

Crie buckets de upload e miniaturas do Cloud Storage para 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 as imagens 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 permissões de leitura aos usuários.

Use o comando gsutil iam ch para conceder permissão de leitura e gravação de 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 Functions 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 a função 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 o recebimento de eventos de 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, redimensioná-la 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 cardápio para atualizar a imagem e a miniatura do item.

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 uma "gravação" de um objeto do Cloud Storage é concluída. Em específico, isso significa que criar um objeto novo ou substituir um atual aciona esse evento. As operações de atualização de metadados e arquivamento são ignoradas por esse gatilho.

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 o aviso 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 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ê precisará criar um novo cliente de armazenamento e os buckets com que seu 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: solicitação única, retomável ou upload de várias partes da API XML. Para uploads maiores ou de streaming, use uploads retomáveis. Com a API XML, os arquivos são enviados em partes e agrupados como um único objeto. Para objetos menores, use uploads de solicitação única.

O código abaixo faz upload de uma imagem para o Cloud Storage 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 óptico de caracteres (OCR) 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ê 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 de API da Vision

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

Para criar uma solicitação usando o recurso "images" 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 imagens faz parte do sistema maior 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:

  • Cloud Run functions
  • Gatilho do Eventarc
  • Tópico e assinatura do Pub/Sub

No terminal do Cloud Shell, execute o comando abaixo para implantar o Cloud Run functions com um bucket de acionamento no menu-item-uploads-$PROJECT_ID:

Para implantar uma função do Cloud Run diretamente no Cloud Run, primeiro implante a função e crie um gatilho 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 gatilho falhar devido a um problema de permissão, aguarde a propagação das mudanças do IAM da etapa anterior. Isso geralmente leva de 1 a 2 minutos. Depois, tente implantar de novo.

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 criado para a função:

546c5c951cf0f2f.png

No console do Cloud, revise 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

Faça upload de uma nova foto para o 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, navegue até Cloud Run.
  8. Clique em process-thumbnails.
  9. Clique na guia REGISTROS.

fca8e4bafbdf135d.png

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

1b6dee72a1fde681.png

Fazer upload de uma imagem que não é de comida

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

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, navegue até Cloud Run.
  8. Clique em process-thumbnails.
  9. Clique na guia REGISTROS.

18b1e30ee78d3955.png

10. Parabéns!

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

Qual é a próxima etapa?

Confira outros codelabs do 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.