Activa el procesamiento de eventos desde Cloud Storage mediante Eventarc y Cloud Functions (2a gen.)

1. Descripción general

En este lab, aprenderás a usar los eventos de buckets de Cloud Storage y Eventarc para activar el procesamiento de eventos. Usarás Cloud Functions (2nd gen) para analizar datos y procesar imágenes. La función usará la API de Vision de Google y guardará la imagen resultante de nuevo en el bucket de Cloud Storage.

4756e4c218d84e26.png

Qué aprenderás

Cómo compilar una canalización de procesamiento de imágenes

  • Configura buckets de Storage
  • Crea una Cloud Function para leer y escribir objetos en Cloud Storage
  • Integrar la API de Vision para detectar imágenes de comida
  • Implementa una Cloud Function
  • Implementa un activador de Eventarc
  • Prueba y valida la solución de extremo a extremo

Requisitos previos

  • Para este lab, se da por sentado que el usuario tiene conocimientos previos sobre los entornos de shell y la consola de Cloud.
  • Es útil tener experiencia previa en Cloud Storage, Cloud Functions o la API de Vision, pero no es obligatoria.

2. Configuración y requisitos

Configuración del proyecto de Cloud

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla en cualquier momento.
  • El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. por lo general, no te importa qué es. En la mayoría de los codelabs, deberás hacer referencia al ID del proyecto (por lo general, se identifica como PROJECT_ID). Si no te gusta el ID generado, puedes generar otro aleatorio. También puedes probar el tuyo propio y ver si está disponible. No se puede cambiar después de este paso y se mantendrá mientras dure el proyecto.
  • Para tu información, hay un tercer valor, un número de proyecto que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Para cerrar recursos y evitar que se te facture más allá de este instructivo, puedes borrar los recursos que creaste o borrar todo el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.

Activar Cloud Shell

Para activar Cloud Shell, haz clic en el ícono que se encuentra a la derecha de la barra de búsqueda.

8613854df02635a3.png

Configuración del entorno

  1. Crea un proyecto y variables de entorno relacionadas con los recursos ejecutando los siguientes comandos en la terminal de 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=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. Habilita las APIs necesarias para el lab
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. Habilita las APIs necesarias para el lab. (paso específico de Qwiklabs)
gcloud services disable cloudfunctions.googleapis.com
gcloud services enable cloudfunctions.googleapis.com
  1. Clona el repositorio
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/cloud-functions

3. Configura buckets de Cloud Storage

Crea buckets de almacenamiento

Crear buckets de Cloud Storage de carga y miniaturas para tu canalización de procesamiento de imágenes

Usa el comando gsutil mb y un nombre único para crear dos buckets:

  1. Sube el bucket en el que se subirán primero las imágenes
  2. Bucket de miniaturas para almacenar imágenes de miniaturas generadas

Crea un bucket para subir imágenes nuevas:

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

Resultado de ejemplo:

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

Crea un bucket para almacenar las miniaturas generadas:

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

Resultado de ejemplo:

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

Actualiza los permisos del bucket

Actualiza los permisos del bucket de almacenamiento para otorgar permisos de lectura a los usuarios.

Usa el comando gsutil iam ch a fin de otorgar permiso para leer y escribir objetos en tu bucket:

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

Resultado de ejemplo

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

4. Configurar cuentas de servicio

Crea una cuenta de servicio personalizada para que Cloud Function procese las miniaturas:

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

Otorga el rol artifactregistry.reader para permitir operaciones de lectura de Artifact Registry:

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

Otorga el rol storage.objectCreator para permitir el almacenamiento de imágenes generadas en el 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"

Otorga el rol run.invoker para permitir la invocación de servicios de Cloud Run:

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

Otorga el rol eventarc.eventReceiver para permitir la recepción de eventos de proveedores:

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

Otorga el rol pubsub.publisher a la cuenta de servicio de Cloud Storage. Esto permitirá que la cuenta de servicio publique eventos cuando se suban imágenes al 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. Descripción general de la función de procesamiento de imágenes

Crear una función para descargar una imagen de Cloud Storage, cambiar el tamaño de la imagen y subirla de nuevo a Cloud Storage La función llamará a la API de Vision para asignar una etiqueta de descripción a la imagen. La función verificará la etiqueta de descripción. Si la etiqueta identifica la imagen como “Comida” se enviará un evento al servicio de menú para actualizar la imagen y la miniatura del elemento de menú.

4c3c3b758dba6a9f.png

Activa una función

Las funciones de Cloud Storage se basan en las notificaciones de Pub/Sub desde Cloud Storage y admiten tipos de eventos similares:

En este lab, implementarás y activarás una función cuando se finalice un objeto en Cloud Storage.

Finalización del objeto

Los eventos de finalización del objeto se activan cuando se activa de un objeto de Cloud Storage se finaliza correctamente. En particular, esto significa que crear un objeto nuevo o reemplazar uno existente activa este evento. Este activador ignora las operaciones de actualización de archivo y metadatos.

6. Integra Cloud Storage

como tus objetos, en Google Cloud. Un objeto es un dato inmutable que consta de un archivo de cualquier formato. Los objetos se almacenan en contenedores llamados buckets. Todos los buckets están asociados a un proyecto que, a su vez, se pueden agrupar en una organización. Las bibliotecas cliente y las APIs se integran en Cloud Storage

En este lab, usarás la biblioteca cliente para leer y escribir objetos en Cloud Storage.

Instala la biblioteca cliente

Las bibliotecas cliente de Cloud están disponibles en muchos lenguajes de programación populares. Para comenzar a usar las bibliotecas, debes instalar la biblioteca cliente.

Usa la biblioteca cliente

Los detalles de la implementación en gran medida dependen del lenguaje de programación. Para usar la biblioteca cliente en tu aplicación, el primer paso es importar las dependencias de Cloud Storage. Por ejemplo, en el proyecto Node.js, las importaciones se agregan en el archivo package.json. En el siguiente fragmento, se muestra la notificación del archivo package.json del lab.

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",
        ...
    }
  }

Registra una devolución de llamada de CloudEvent

Registra una devolución de llamada de CloudEvent con Functions Framework que Cloud Storage activará cuando se suba una imagen nueva al bucket.

index.js

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

Crea un objeto de referencia de almacenamiento

Después de importar las bibliotecas cliente, deberás crear un nuevo cliente de almacenamiento y los buckets con los que interactuará tu aplicación.

index.js

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

Descarga objetos de Cloud Storage

index.js

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

Sube objetos a Cloud Storage

Puedes enviar solicitudes de carga a Cloud Storage de tres maneras: solicitud única, reanudable o carga multiparte por parte de la API de XML. Para cargas más grandes o de transmisión, usa cargas reanudables. Con los archivos XML API se suben por partes y se ensamblan como un único objeto. Para objetos más pequeños, usa cargas de solicitud única.

El siguiente código permite subir una imagen a Cloud Storage mediante una carga de solicitud única.

index.js

const thumbnailImage = await thumbBucket.upload(thumbFile);

7. Integra la API de Vision

Cloud Vision permite que los desarrolladores integren fácilmente funciones de detección de visión en las aplicaciones, como etiquetado de imágenes, detección de rostros y puntos de referencia, reconocimiento óptico de caracteres (OCR) y etiquetado de contenido explícito.

Instala la biblioteca cliente

Las bibliotecas cliente de Cloud están disponibles en muchos lenguajes de programación populares. Para comenzar a usar las bibliotecas, debes instalar la biblioteca cliente.

Crea un cliente de anotación de imágenes

Para acceder a las APIs de Google con los SDKs de cliente oficiales, debes crear un objeto de servicio basado en el documento de descubrimiento de la API, que describe la API al SDK. Deberás recuperarlos del servicio de descubrimiento de la API de Vision con tus credenciales.

index.js

const client = new vision.ImageAnnotatorClient();

Compila una solicitud a la API de Vision

Para realizar la detección de características en un archivo de imagen, la API de Vision puede enviar el contenido del archivo de imagen como una string codificada en base64 en el cuerpo de la solicitud.

Para compilar una solicitud usando el recurso de imágenes a fin de anotar tu imagen. Una solicitud a esta API toma la forma de un objeto con una lista de solicitudes. Todos los elementos de esta lista incluyen dos tipos de información:

  • Los datos de la imagen codificados en base64
  • Una lista de características para las que querrías tener anotaciones respecto de la imagen

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. Implementa Cloud Function

Este servicio para cambiar el tamaño de imágenes forma parte del sistema más grande de Cymbal Eats. En esta sección, implementarás solo los componentes relacionados con la función de procesamiento de imágenes. La instalación completa incorpora una IU para subir la imagen y una solicitud descendente para almacenar los metadatos resultantes. Esas funciones no están instaladas como parte de este lab.

Se crearán los siguientes componentes durante la implementación de la función:

  • Cloud Function
  • Servicio de Cloud Run
  • Activador de Eventarc
  • Tema y suscripción de Pub/Sub

En la terminal de cloudshell, ejecuta el siguiente comando para implementar Cloud Function con un bucket activador en menu-item-uploads-$PROJECT_ID:

gcloud functions deploy process-thumbnails \
  --gen2 \
  --runtime=nodejs16 \
  --source=thumbnail \
  --region=$REGION \
  --project=$PROJECT_ID \
  --entry-point=process-thumbnails \
  --trigger-bucket=$UPLOAD_BUCKET \
  --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

Si la implementación falla debido a un problema de permisos en el bucket de almacenamiento de carga, espera a que se propaguen los cambios de IAM del paso anterior. Por lo general, tarda entre 1 y 2 minutos y, luego, se vuelve a intentar la implementación.

Resultado de ejemplo

Deploying function (may take a while - up to 2 minutes)...done.
[...] 

En la consola de Cloud, revisa la Cloud Function creada:

8148dd29e6757603.png

En la consola de Cloud, revisa el servicio de Cloud Run que se creó para la función:

42e970cdd48cae76.png

En la consola de Cloud, revisa el activador de Eventarc que se creó para la función:

9441995a5cc62e38.png

En la consola de Cloud, revisa el Tema y la Suscripción de Pub/Sub que se crearon para el activador de Eventarc:

affe089c39ae1465.png

a4c41ede2af300db.png

9. Prueba y valida la solución de extremo a extremo

Subir una foto nueva a Cloud Storage y supervisar el progreso de la canalización mientras se analizan las imágenes Supervisarás los registros de Cloud Functions para probar la solución de extremo a extremo.

Cómo subir una imagen adecuada

2fdd13b63d6148f4.jpeg

  1. Guarda esta imagen en tu máquina local
  2. Cambia el nombre del archivo a 1.jpg.
  3. Abre la consola de Cloud Storage.
  4. Haz clic en el bucket menu-item-uploads-....
  5. Haz clic en SUBIR ARCHIVOS.
  6. Sube 1.jpg al bucket de almacenamiento
  7. En la consola de Cloud, navega a Cloud Functions.
  8. Haz clic en process-thumbails.
  9. Haz clic en la pestaña REGISTROS.

7ab4e783e474c90d.png

  1. Navega al bucket de Cloud Storage menu-item-thumbnails-$PROJECT_ID
  2. Verifica que la imagen en miniatura se haya creado en el bucket de miniaturas.

84d8023782eb3e0c.png

Subir una imagen no alimentaria

Para verificar si la función se ejecuta correctamente, debe subir una imagen que no contenga un objeto que se clasificaría como "Comida". elemento.

3226a24251084b28.jpeg

  1. Guarda esta imagen en tu máquina local
  2. Cambia el nombre del archivo a 2.jpg.
  3. Abre la consola de Cloud Storage.
  4. Haz clic en el bucket menu-item-uploads-....
  5. Haz clic en SUBIR ARCHIVOS.
  6. Sube 2.jpg al bucket de almacenamiento
  7. En la consola de Cloud, navega a Cloud Functions.
  8. Haz clic en process-thumbails.
  9. Haz clic en la pestaña REGISTROS.

421c36c342fceea8.png

10. ¡Felicitaciones!

¡Felicitaciones! Terminaste el lab.

¿Qué sigue?

Explora otros codelabs de Cymbal Eats:

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Borra el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.