Las notificaciones de cambios de objetos se pueden usar para avisar a una aplicación cuando se añade, actualiza o elimina un objeto de un contenedor.
¿Deberías usar la notificación de cambios en objetos?
Por lo general, no deberías usar la notificación de cambios en objetos. La herramienta recomendada para generar notificaciones que hagan un seguimiento de los cambios en los objetos de tus segmentos de Cloud Storage son las notificaciones de Pub/Sub para Cloud Storage, ya que son más rápidas, flexibles, fáciles de configurar y rentables. Para obtener una guía paso a paso sobre cómo configurar las notificaciones de Pub/Sub para Cloud Storage, consulta Configurar notificaciones de Pub/Sub para Cloud Storage.
Si actualmente usas la notificación de cambio de objeto, te recomendamos que migres a las notificaciones de Pub/Sub. Para obtener información sobre cómo migrar a las notificaciones de Pub/Sub, consulta Migrar de las notificaciones de cambio de objeto a las notificaciones de Pub/Sub.
Cómo funciona la notificación de cambios en objetos
Una aplicación cliente puede enviar una solicitud para monitorizar los cambios en los objetos de un determinado contenedor.
Cuando se completa una solicitud de vigilancia, se crea un canal de notificaciones. Un canal de notificaciones es el medio por el que se envía un mensaje de notificación a una aplicación que monitoriza un segmento. Actualmente, solo se admite un tipo de canal de notificación: un webhook.
Una vez que se crea un canal de notificaciones, Cloud Storage notifica a la aplicación cada vez que se añade, actualiza o elimina un objeto del segmento. Por ejemplo, cuando añades una imagen a un contenedor, se puede notificar a una aplicación para que cree una miniatura.
Detalles de la notificación de cambios en objetos
Terminología
En la siguiente tabla se incluye una descripción de varios términos que se usan en la documentación de notificaciones de cambios de objetos:
Término | Descripción |
---|---|
URL de la aplicación | La URL de tu aplicación. Esta es la dirección a la que se enviarán las notificaciones. Ten en cuenta que debe ser una URL HTTPS, ya que no se permiten las URLs HTTP. |
Identificador de canal | Identificador de un canal de notificaciones. Debe ser único en un segmento concreto. Es decir, si hay varios canales de notificación para un mismo segmento, cada canal de notificación debe tener un identificador de canal distinto. Este identificador se enviará a tu aplicación junto con cada mensaje de notificación. |
Identificador de recurso |
Identificador opaco del recurso que se está monitorizando.
El identificador de recurso es obligatorio para detener un canal de notificaciones.
Puedes obtener este identificador de la respuesta a una solicitud de reloj o del encabezado X-Goog-Resource-Id de los mensajes de eventos de notificación.
|
Token de cliente | (opcional) Los tokens de cliente se pueden usar para validar eventos de notificación. Para ello, define un token de cliente personalizado con tu solicitud de reloj. Los mensajes de notificación contendrán este token para que puedas verificar que son auténticos. |
Crear un canal de notificaciones
Para empezar a monitorizar un contenedor en busca de eventos de notificación de cambios, debes enviar una solicitud watchAll
. De esta forma, se crea un canal de notificaciones que envía eventos de notificación al address
proporcionado para el segmento en cuestión. El canal de notificaciones incluye un token de cliente personalizado y un identificador de canal, si se han especificado.
Ejemplo de solicitud POST para monitorizar un contenedor:
POST /storage/v1/b/BucketName/o/watch?alt=json HTTP/1.1 Host: storage.googleapis.com Content-Length: 200 User-Agent: google-api-python-client/1.0 Content-Type: application/json Authorization: Bearer oauth2_token { "token": "ClientToken", "type": "web_hook", "id": "ChannelId", "address": "ApplicationUrl" }
Autorización de notificaciones
Cuando se monitoriza un segmento, el canal de notificaciones que se crea se asocia al proyecto de consola Google Cloud de la aplicación que inicia la solicitud a la API. Por ejemplo, si un usuario da acceso a una aplicación instalada o a una aplicación web a través de un flujo de OAuth2, el canal de notificaciones creado por la aplicación se asociará al proyecto de la aplicación, no al proyecto que contiene el segmento que se está monitorizando.
Como una cuenta de servicio está asociada a un proyecto, si usas una cuenta de servicio para monitorizar un segmento, se creará un canal de notificaciones en el proyecto de la cuenta de servicio.
Detener un canal de notificaciones
Si detienes un canal de notificaciones de cambios en objetos, se dejarán de publicar notificaciones de cambios en objetos en la URL de la aplicación asociada. Para detener correctamente un canal de notificaciones de cambios de objetos, debe conocer los siguientes parámetros:
- El identificador de recurso del canal de notificación de cambios en objetos (
RESOURCE_ID
) - Identificador del canal de notificación de cambios en objetos (
CHANNEL_ID
) - El usuario o la cuenta de servicio que ha creado el canal de notificaciones de cambios en objetos. Solo el creador del canal puede detenerlo.
Línea de comandos
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
- Instala gsutil.
- Para encontrar todos los canales de notificaciones de cambios de objetos activos y enumerar sus detalles para identificar el
CHANNEL_ID
, elRESOURCE_ID
y la cuenta de servicio que creó el canal, usa el comandogsutil notification list
:gsutil notification list -o gs://BUCKET_NAME
Donde:
BUCKET_NAME
es el nombre de tu segmento. Por ejemplo,my-bucket
.Si la solicitud se realiza correctamente, el comando devuelve un resultado similar al siguiente mensaje:
Notification channel 1: Channel identifier: test_channel Resource identifier: htopjgdthsgdt Application URL: url=https://examplepetstore.com/notifications Created by: examplepetstore@xyz.com Creation time: 2020-01-01 00:00:00.764000
- Si la cuenta de servicio creó el canal, tendrás que suplantar la identidad de esa cuenta para asegurarte de que tienes los permisos necesarios.
gcloud config set auth/impersonate_service_account CHANNEL_CREATOR
Donde:
CHANNEL_CREATOR
es la cuenta de servicio que ha creado el canal. - Detén el canal de notificaciones de cambios en objetos del cubo con los valores
CHANNEL_ID
yRESOURCE_ID
identificados.gsutil notification stopchannel CHANNEL_ID RESOURCE_ID
Donde:
CHANNEL_ID
es el identificador del canal de notificación de cambios en objetos.RESOURCE_ID
es el identificador de recurso del canal de notificaciones de cambios en objetos.
APIs REST
API JSON
Para detener un canal de notificaciones, debes hacer una solicitud stop
. Dejará de enviar todos los eventos de notificación publicados en el par de identificadores de recursos (resourceId
) y de canales (id
) especificado. Los canales adicionales del mismo recurso no se verán afectados.
Los identificadores de recursos y canales se pueden encontrar en la respuesta de una solicitud watch o en el cuerpo de los mensajes de eventos de notificación.
Ejemplo de solicitud POST para detener un canal:
POST /storage/v1/channels/stop HTTP/1.1 Host: storage.googleapis.com Content-Length: 200 User-Agent: google-api-python-client/1.0 Content-Type: application/json Authorization: Bearer oauth2_token { "resourceId": "ResourceId", "id": "ChannelId" }
Tipos de mensajes de eventos de notificación
Sincronizar
Se envía un evento de notificación cuando se crea un nuevo canal de notificaciones después de emitir una solicitud de vigilancia. Después de recibir el evento de sincronización, todos los cambios posteriores que se hagan en el segmento se enviarán a la URL de la aplicación configurada para el canal.
La notificación se enviará como una solicitud POST a la URL de la aplicación configurada. No hay ningún cuerpo en la solicitud. Los metadatos de la notificación de sincronización se incluyen en los encabezados de la solicitud. A continuación, se muestra un ejemplo de solicitud de notificación sync:
POST /ApplicationUrlPath Accept: */* Content-Type: application/json; charset="utf-8" Content_Length: 0 Host: ApplicationUrlHost X-Goog-Channel-Id: ChannelId X-Goog-Channel-Token: ClientToken X-Goog-Resource-Id: ResourceId X-Goog-Resource-State: sync X-Goog-Resource-Uri: https://storage.googleapis.com/storage/v1/b/BucketName/o?alt=json
Adición, actualización o eliminación de objetos
Se envía un evento de notificación cuando se añade un objeto a un segmento, se modifica el contenido o los metadatos de un objeto o se elimina un objeto de un segmento.
La notificación se enviará como una solicitud POST a la URL de la aplicación configurada. El cuerpo de la solicitud contiene un mensaje codificado con JSON, como se muestra en la siguiente solicitud de notificación:
POST /ApplicationUrlPath Accept: */* Content-Length: 1097 Content-Type: application/json; charset="utf-8" Host: ApplicationUrlHost X-Goog-Channel-Id: ChannelId X-Goog-Channel-Token: ClientToken X-Goog-Resource-Id: ResourceId X-Goog-Resource-State: ResourceState X-Goog-Resource-Uri: https://storage.googleapis.com/storage/v1/b/BucketName/o?alt=json { "kind": "storage#object", "id": "BucketName/ObjectName", "selfLink": "https://www.googleapis.com/storage/v1/b/BucketName/o/ObjectName", "name": "ObjectName", "bucket": "BucketName", "generation": "1367014943964000", "metageneration": "1", "contentType": "application/octet-stream", "updated": "2013-04-26T22:22:23.832Z", "size": "10", "md5Hash": "xHZY0QLVuYng2gnOQD90Yw==", "mediaLink": "https://content-storage.googleapis.com/storage/v1/b/BucketName/o/ObjectName?generation=1367014943964000&alt=media", "owner": { "entity": "user-jeffersonloveshiking@gmail.com" }, "crc32c": "C7+82w==", "etag": "COD2jMGv6bYCEAE=" }
exists
: para añadir y actualizar objetos.not_exists
: para eliminaciones de objetos.
y donde el contenido del mensaje JSON contiene la representación actual del objeto, tal como se describe en Descripción de recursos de objetos.
Entrega fiable
La notificación de cambios en objetos intentará enviar notificaciones a tu aplicación de forma fiable. Sin embargo, ten en cuenta que las notificaciones pueden retrasarse indefinidamente y no se garantiza que lleguen a tiempo. Como es posible que tu aplicación no siempre esté disponible, se siguen las siguientes reglas al enviar notificaciones:
- Si falla un intento de entrega de una notificación, se harán más intentos. El intervalo entre intentos de entrega adicionales se determina mediante un algoritmo de tiempo de espera exponencial que empieza con un reintento 30 segundos después del fallo inicial. Los intentos de entrega posteriores se realizan en intervalos cada vez mayores, hasta un intervalo máximo de 90 minutos. Ten en cuenta que los intervalos de reintento posteriores se aleatorizan ligeramente para que no se produzcan en valores exponenciales exactos. Una vez que se alcanza el intervalo máximo de reintentos de 90 minutos, los reintentos posteriores se siguen realizando cada 90 minutos durante 7 días. Si la notificación no se puede enviar en ese tiempo, se elimina.
-
Si no se puede acceder a tu aplicación después de 20 segundos o si responde con uno de los siguientes códigos de respuesta HTTP, el intento de envío de la notificación se considera un error y se vuelve a intentar:
- 500 Internal Server Error (Error interno del servidor)
- 502 Bad Gateway (Puerta de enlace no válida)
- 503 Service Unavailable (Servicio no disponible)
- 504 Gateway Timeout (Tiempo de espera agotado para la puerta de enlace)
-
Si tu aplicación responde con uno de los siguientes códigos de respuesta HTTP, la notificación se tratará como entregada correctamente:
- 102 - Procesando
- 200 OK
- 201 Created
- 202 Accepted
- 204 No Content
- Cualquier otro código de respuesta HTTP devuelto por tu aplicación se trata como un error permanente y no se vuelve a intentar.
Ejemplo de aplicación cliente
En esta sección se explica cómo crear una aplicación cliente de App Engine que procese eventos de notificación de cambios.
La aplicación de ejemplo contiene una clase llamada MainPage
.
Cuando el usuario actualiza o añade un objeto al contenedor, la clase MainPage
procesa el evento de notificación.
Para simplificar, el método post
, que es el que realiza el procesamiento, solo registra un mensaje con la hora en la que se recibió la notificación. Este código se puede sustituir con la lógica de procesamiento real. Si aún no te sientes cómodo desarrollando aplicaciones de App Engine, prueba a desplegar una aplicación de ejemplo o sigue un tutorial antes de continuar.
- Configurar la aplicación
Crea el archivo de configuraciónapp.yaml
para especificar la aplicación cliente que gestiona los eventos de notificación de cambios del bucket.application: APPLICATION version: 1 runtime: python38 api_version: 1 threadsafe: true handlers: - url: /.* script: change_notification_client.app
- Crear la aplicación
En el siguiente ejemplo se implementa una aplicación cliente para gestionar los eventos de notificación de cambios de un contenedor. Asigna el nombrechange_notification_client.py
y, a continuación, despliega la aplicación:"""Notification handling for Google Cloud Storage.""" import json import logging import webapp2 class MainPage(webapp2.RequestHandler): """Process notification events.""" def get(self): logging.info("Get request to notification page.") self.response.write("Welcome to the notification app.") def post(self): # pylint: disable-msg=C6409 """Process the notification event. This method is invoked when the notification channel is first created with a sync event, and then subsequently every time an object is added to the bucket, updated (both content and metadata) or removed. It records the notification message in the log. """ logging.debug( '%s\n\n%s', '\n'.join(['%s: %s' % x for x in self.request.headers.iteritems()]), self.request.body) # The following code is for demonstration. Replace # it with your own notification processing code. if 'X-Goog-Resource-State' in self.request.headers: resource_state = self.request.headers['X-Goog-Resource-State'] if resource_state == 'sync': logging.info('Sync message received.') else: an_object = json.loads(self.request.body) bucket = an_object['bucket'] object_name = an_object['name'] logging.info('%s/%s %s', bucket, object_name, resource_state) else: logging.info("Other post.") logging.getLogger().setLevel(logging.DEBUG) app = webapp2.WSGIApplication([('/', MainPage)], debug=True)
- Asignación del permiso de acceso de la aplicación al depósito
Si el segmento es propiedad de una cuenta de servicio distinta de la de tu aplicación de App Engine, concede a la aplicación acceso de PROPIETARIO al segmento. - Empieza a monitorizar el bucket para detectar cambios en los objetos.
Crea un canal de notificaciones para tu aplicación monitorizando el bucket mediante una solicitudwatchAll
con eladdress
de la URL de tu aplicación de App Engine, por ejemplo:https://ApplicationId.appspot.com/
. - Probar la aplicación.
Para comprobar si la aplicación funciona correctamente, sigue estos pasos:-
Para asegurarte de que la aplicación se ha implementado y funciona correctamente, ejecuta el siguiente comando
curl
: Si has usado tu propio nombre de dominio para implementar la aplicación, úsalo en lugar decurl -X Post https://APPLICATIONID.appspot.com
appspot.com
en el comando anterior. - Ve a la página Registro de tu proyecto. Si es necesario, actualiza la lista de mensajes registrados. Verifica que se haya registrado el mensaje de registro emitido por la aplicación.
- Añade un objeto al depósito. Cloud Storage notifica a la aplicación, que registra un mensaje.
- Ve a la <a href="https://console.cloud.google.com/project//logs">página de registro de tu proyecto. Actualiza la lista de mensajes registrados y busca el mensaje de la copia del objeto.
- Detener el canal de notificaciones
Detén el canal de notificaciones especificando el canal y los identificadores de recursos que se devolvieron cuando enviaste el comando de notificación para crear un canal de notificaciones.
</ol>
-
Para asegurarte de que la aplicación se ha implementado y funciona correctamente, ejecuta el siguiente comando