Foto do dia: laboratório 5: limpeza após a exclusão da imagem

Foto do dia:
laboratório 5:
limpeza após a exclusão da imagem

Sobre este codelab

subjectÚltimo out. 7, 2021 atualizado
account_circleEscrito por Mete Atamel

1. Visão geral

Neste codelab, você vai criar um novo serviço do Cloud Run, o coletor de lixo de imagem, que será acionado pelo Eventarc, um novo serviço para receber eventos no Cloud Run. Quando uma imagem é excluída do bucket de imagens, o serviço recebe um evento do Eventarc. Depois, ele exclui a imagem do bucket de miniaturas e da coleção de imagens do Firestore.

d93345bfc235f81e.png

O que você vai aprender

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc

2. Configuração e requisitos

Configuração de ambiente autoguiada

  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.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • O Nome do projeto é o nome de exibição para os participantes do projeto. Ele é uma string de caracteres que não é usada pelas APIs do Google e pode ser atualizada a qualquer momento.
  • O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser alterado após a definição. O Console do Cloud gera automaticamente uma string única, geralmente não importa o que seja. Na maioria dos codelabs, você precisará fazer referência ao ID do projeto, que geralmente é identificado como PROJECT_ID. Então, se você não gostar dele, gere outro ID aleatório ou crie um próprio e veja se ele está disponível. Em seguida, ele fica "congelado" depois que o projeto é criado.
  • Há um terceiro valor, um Número de projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
  1. Em seguida, você precisará ativar o faturamento no Console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não será muito cara, se tiver algum custo. Para encerrar os recursos e não gerar cobranças além deste tutorial, siga as instruções de "limpeza" encontradas no final do codelab. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Inicie o Cloud Shell

Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.

No Console do GCP, clique no ícone do Cloud Shell na barra de ferramentas localizada no canto superior direito:

bce75f34b2c53987.png

O provisionamento e a conexão com o ambiente levarão apenas alguns instantes para serem concluídos: Quando o processamento for concluído, você verá algo como:

f6ef2b5f13479f3a.png

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Todo o trabalho neste laboratório pode ser feito apenas com um navegador.

3. Introdução ao Eventarc

O Eventarc facilita a conexão de serviços do Cloud Run com eventos de várias fontes. Ele cuida da ingestão, da entrega, da segurança, da autorização e do tratamento de erros de eventos para você.

776ed63706ca9683.png

É possível criar eventos de fontes do Google Cloud e aplicativos personalizados publicados no Cloud Pub/Sub e enviá-los aos coletores do Google Cloud Run.

Eventos de diversas fontes do Google Cloud são entregues com os Registros de auditoria do Cloud. A latência e a disponibilidade da entrega de eventos dessas origens estão vinculadas às dos Registros de auditoria do Cloud. Sempre que um evento de uma origem do Google Cloud é disparado, uma entrada do registro de auditoria do Cloud correspondente é criada.

Os aplicativos personalizados publicados no Cloud Pub/Sub podem publicar mensagens em um tópico do Pub/Sub especificado em qualquer formato.

Os acionadores de eventos são o mecanismo de filtragem usado para especificar quais eventos serão enviados a cada coletor.

Todos os eventos são entregues no formato CloudEvents v1.0 para interoperabilidade entre serviços.

4. Antes de começar

Ativar APIs

Você vai precisar do serviço do Eventarc para acionar o serviço do Cloud Run. Verifique se ele está ativado:

gcloud services enable eventarc.googleapis.com

Você verá que a operação será concluída com sucesso:

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

Configurar contas de serviço

A conta de serviço padrão do Compute vai ser usada em gatilhos. Conceda o papel eventarc.eventReceiver à conta de serviço padrão do Compute:

PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format='value(projectNumber)')

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
    --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
    --role roles/eventarc.eventReceiver

Conceda o papel pubsub.publisher à conta de serviço do Cloud Storage. Isso é necessário para o gatilho do Cloud Storage do Eventarc:

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

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

Se você ativou a conta de serviço do Pub/Sub até 8 de abril de 2021, conceda o papel iam.serviceAccountTokenCreator à conta de serviço do Pub/Sub:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
  --role roles/iam.serviceAccountTokenCreator

5. Clonar o código

Clone o código, caso ainda não tenha feito isso no codelab anterior:

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

Acesse o diretório que contém o serviço:

cd serverless-photosharing-workshop/services/garbage-collector/nodejs

Você terá o seguinte layout de arquivo para o serviço:

services
 |
 ├── garbage-collector
      |
      ├── nodejs
           |
           ├── index.js
           ├── package.json

Dentro da pasta, você tem três arquivos:

  • index.js contém o código Node.js.
  • package.json define as dependências da biblioteca.

6. Explorar o código

Dependências

O arquivo package.json define as dependências de biblioteca necessárias:

{
 
"name": "garbage_collector_service",
 
"version": "0.0.1",
 
"main": "index.js",
 
"scripts": {
   
"start": "node index.js"
 
},
 
"dependencies": {
   
"cloudevents": "^4.0.1",
   
"express": "^4.17.1",
   
"@google/events": "^3.1.0",
   
"@google-cloud/firestore": "^4.9.9",
   
"@google-cloud/storage": "^5.8.3"
 
}
}

Nós dependemos da biblioteca do Cloud Storage para excluir imagens no Cloud Storage. Declaramos uma dependência no Cloud Firestore para excluir também metadados de imagens armazenados anteriormente. Além disso, dependemos do SDK do CloudEvents e das bibliotecas de eventos do Google para ler os CloudEvents enviados pelo Eventarc. Express é um framework da Web JavaScript / Node. O Bluebird é usado para processar promessas.

index.js

Vamos analisar melhor o código index.js:

const express = require('express');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const { HTTP } = require("cloudevents");
const {toStorageObjectData} = require('@google/events/cloud/storage/v1/StorageObjectData');

Precisamos das várias dependências necessárias para que nosso programa seja executado: o Express é o framework da Web do Node que vamos usar, o Bluebird é uma biblioteca para lidar com promessas de JavaScript, o Storage e o Firestore servem para trabalhar, respectivamente, com o Google Cloud Storage (nossos buckets de imagens) e o repositório de dados do Cloud Firestore. Além disso, exigimos que o CloudEvent leia o CloudEvent enviado pelo StoreObjectData do Eventarc da biblioteca de eventos do Google para ler o corpo do evento do Cloud Storage do CloudEvent.

const app = express();
app
.use(express.json());

app
.post('/', async (req, res) => {
   
try {
       
const cloudEvent = HTTP.toEvent({ headers: req.headers, body: req.body });
        console
.log(cloudEvent);


       
/* ... */

   
} catch (err) {
        console
.log(`Error: ${err}`);
        res
.status(500).send(err);
   
}
});

Acima, temos a estrutura do nosso gerenciador de nós: nosso aplicativo responde a solicitações POST HTTP. Ele lê o CloudEvent da solicitação HTTP e estamos fazendo uma pequena parte do tratamento de erros caso algo dê errado. Agora, vamos ver o que há dentro dessa estrutura.

A próxima etapa é recuperar e analisar o corpo do CloudEvent e recuperar o nome do objeto:

const storageObjectData = toStorageObjectData(cloudEvent.data);
console
.log(storageObjectData);

const objectName = storageObjectData.name;

Assim que soubermos o nome da imagem, podemos excluí-la do bucket de miniaturas:

try {
    await storage
.bucket(bucketThumbnails).file(objectName).delete();
    console
.log(`Deleted '${objectName}' from bucket '${bucketThumbnails}'.`);
}
catch(err) {
    console
.log(`Failed to delete '${objectName}' from bucket '${bucketThumbnails}': ${err}.`);
}

Como última etapa, exclua também os metadados das imagens da coleção do Firestore:

try {
   
const pictureStore = new Firestore().collection('pictures');
   
const docRef = pictureStore.doc(objectName);
    await docRef
.delete();

    console
.log(`Deleted '${objectName}' from Firestore collection 'pictures'`);
}
catch(err) {
    console
.log(`Failed to delete '${objectName}' from Firestore: ${err}.`);
}

res
.status(200).send(`Processed '${objectName}'.`);

Agora é hora de fazer o script do Node detectar as solicitações recebidas. Verifique também se as variáveis de ambiente necessárias estão definidas:

app.listen(PORT, () => {
   
if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
    console
.log(`Started service on port ${PORT}`);
});

7. Testar localmente

Teste o código localmente para garantir que ele funciona antes de implantá-lo na nuvem.

Dentro da pasta garbage-collector/nodejs, instale as dependências de npm e inicie o servidor:

export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT

npm install; npm start

Se tudo tiver dado certo, ele deverá iniciar o servidor na porta 8080:

Started service on port 8080

Use CTRL-C para sair.

8. Criar e implantar no Cloud Run

Antes de implantar no Cloud Run, defina a região do Cloud Run como uma das regiões e plataformas compatíveis como managed:

REGION=europe-west1
gcloud config set run/region $REGION
gcloud config set run/platform managed

Verifique se a configuração foi definida:

gcloud config list

...
[run]
platform = managed
region = europe-west1

Em vez de criar e publicar a imagem do contêiner usando o Cloud Build manualmente, também é possível confiar no Cloud Run para criar a imagem do contêiner usando o Google Cloud Buildpacks.

Execute o comando a seguir para criar a imagem do contêiner usando Google Cloud Buildpacks e, em seguida, implantar a imagem do contêiner no Cloud Run:

SERVICE_NAME=garbage-collector-service

gcloud run deploy $SERVICE_NAME \
    --source . \
    --no-allow-unauthenticated \
    --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS

Observe a sinalização –-source. Isso sinaliza o Cloud Run para usar os Buildpacks do Google Cloud para criar a imagem do contêiner sem um Dockerfile.. A sinalização --no-allow-unauthenticated torna o serviço do Cloud Run um serviço interno que será acionado apenas por contas de serviço específicas. Depois, você vai criar um gatilho com a conta de serviço padrão do Compute que tem o papel run.invoker para chamar serviços internos do Cloud Run.

9. Criar um gatilho

No Eventarc, um gatilho define qual serviço precisa receber quais tipos de eventos. Nesse caso, você quer que o serviço receba eventos quando um arquivo for excluído em um bucket.

Defina o local do gatilho na mesma região do bucket de imagens enviadas:

gcloud config set eventarc/location eu

Crie um gatilho AuditLog para filtrar eventos storage.objects.delete e enviar ao serviço Cloud Run:

BUCKET_IMAGES=uploaded-pictures-$GOOGLE_CLOUD_PROJECT

gcloud eventarc triggers create trigger-$SERVICE_NAME \
  --destination-run-service=$SERVICE_NAME \
  --destination-run-region=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.deleted" \
  --event-filters="bucket=$BUCKET_IMAGES" \
  --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

Para confirmar se o gatilho foi criado, use este comando:

gcloud eventarc triggers list

10. Testar o serviço

Para testar se o serviço está funcionando, acesse o bucket uploaded-pictures e exclua uma das imagens. Nos registros do serviço, você verá que ele excluiu a imagem relevante no bucket thumbnails e também excluiu o documento da coleção pictures do Firestore.

519abf90e7ea4d12.png

11. Limpeza (opcional)

Se você não pretende continuar com os outros laboratórios da série, limpe os recursos para economizar custos e ser um bom cidadão da nuvem. É possível limpar recursos individualmente da seguinte maneira.

Exclua o serviço:

gcloud run services delete $SERVICE_NAME -q

Exclua o gatilho do Eventarc:

gcloud eventarc triggers delete trigger-$SERVICE_NAME -q

Se preferir, exclua todo o projeto:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

12. Parabéns!

Parabéns! Você criou um serviço do Cloud Run, um coletor de lixo de imagem, que é acionado pelo Eventarc, um novo serviço para receber eventos no Cloud Run. Quando uma imagem é excluída do bucket de imagens, o serviço recebe um evento do Eventarc. Depois, ele exclui a imagem do bucket de miniaturas e da coleção de imagens do Firestore.

O que vimos

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc