Notificación de cambio de objeto


La notificación de cambio de objeto se puede usar para notificar a una aplicación sobre la actualización o adición de un objeto a un depósito.

Ten en cuenta que esta característica es diferente de las notificaciones de Cloud Pub/Sub para Cloud Storage. Recomendamos usar las notificaciones de Cloud Pub/Sub para realizar un seguimiento de los cambios en los objetos en tus depósitos de Cloud Storage debido a que son más rápidas, más flexibles, más fáciles de configurar y más rentables.

Cómo funciona la notificación de cambio de objeto

Una aplicación cliente puede enviar una solicitud para observar cambios en los objetos en un depósito en particular.

Cuando completas una solicitud de observación, se crea un canal de notificación nuevo. Un canal de notificación es el medio por el que un mensaje de notificación se envía a una aplicación que observa un depósito. En la actualidad, el único tipo de canal de notificación que se admite es un webhook.

Después de que se inicia un canal de notificación, Cloud Storage notifica a la aplicación cada vez que se agrega, actualiza o quita un objeto del depósito. Por ejemplo, cuando agregas una foto nueva a un depósito, se puede notificar a una aplicación a fin de crear una miniatura.

En la figura a continuación, se muestra un ejemplo del flujo de datos para una aplicación que procesa notificaciones de cambios. Cualquier servidor de aplicaciones que puede recibir solicitudes POST de HTTPS se puede usar para procesar notificaciones de cambios.

Componentes de notificación de cambio de objeto
Componentes de notificación de cambio de objeto

Detalles de la notificación de cambio de objeto

Terminología

En la tabla siguiente, se encuentra la descripción de varios términos usados en toda la documentación de notificación de cambio de objeto:

Término Descripción
URL de la aplicación La URL de tu aplicación. Esta es la dirección a donde se enviarán las notificaciones. Ten en cuenta que esta debe ser una URL HTTPS; ya que las URL HTTP no están permitidas.
Identificador de canal El identificador para un canal de notificación debe ser único en un depósito específico, es decir, si existen varios canales de notificación para un solo depósito, 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 recursos Un identificador opaco para el recurso que se observa. El identificador de recursos es necesario para detener un canal de notificación. Puedes recuperar este identificador desde la respuesta para una solicitud de observación o desde el encabezado X-Goog-Resource-Id de mensajes de eventos de notificación.
Token cliente (opcional) Se pueden usar los tokens cliente para validar los eventos de notificaciones. Para ello, establece un token cliente personalizado con tu solicitud de observación. Los mensajes de notificación contendrán este token para que puedas verificar que son auténticos.

Observa un depósito

Si deseas comenzar a observar un depósito para los eventos de notificación de cambios, puedes usar el comando gsutil notification watchbucket:

gsutil notification watchbucket [-i ChannelId] [-t ClientToken] ApplicationUrl gs://BucketName

Esto creará un canal de notificación que envía los eventos de notificación a la URL de la aplicación especificada para el depósito en cuestión. El canal de notificación incluirá el token cliente personalizado y el identificador de canal, si se especifica.

Para obtener más información sobre este comando, ejecuta el comando gsutil help notification watchbucket.

Esta es una solicitud POST de ejemplo generada por gsutil para observar un depósito:

POST /storage/v1/b/BucketName/o/watch?alt=json HTTP/1.1
Host: www.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 notificación

Cuando observas un depósito, el canal de notificación que se crea se asociará con el proyecto de la aplicación de Google Cloud Platform Console que inicia la solicitud de la API. Esto significa que, por ejemplo, si un usuario otorga acceso a una aplicación instalada o a una aplicación web a través de un flujo de OAuth2, un canal de notificación creado por la aplicación se asociará al proyecto de la aplicación, y no al proyecto que contiene el depósito que se observa.

Existen tres pasos para configurar la autorización en una situación de notificación de cambio de objeto:

Crea una cuenta de servicio

Dado que una cuenta de servicio está asociada a un proyecto, usarla para observar un depósito creará un canal de notificación en el proyecto de la cuenta de servicio.

Debes usar una cuenta de servicio existente o crear una nueva y descargar la clave privada asociada.

Configura gsutil para usar una cuenta de servicio

Si deseas configurar gsutil a fin de usar la cuenta de servicio, puedes usar el SDK de Google Cloud para agregar la cuenta de servicio como una cuenta certificada a fin de que funcione con los recursos de Google Cloud Platform, incluida la notificación de cambio de objeto. Luego de agregar las credenciales, todos los comandos gsutil posteriores usarán las credenciales de la cuenta de servicio.

Para crear credenciales basadas en la cuenta de servicio, sigue estos pasos:

  1. Asegúrate de tener la versión más reciente del SDK de Cloud. Puedes actualizar tus componentes mediante la ejecución de este comando:
    gcloud components update
    
  2. Usa el comando gcloud auth activate-service-account y especifica la dirección de correo electrónico y la clave privada de la cuenta de servicio.
    gcloud auth activate-service-account service-account-email --key-file path/to/key.p12
    

    donde:

    • service-account-email es la dirección de correo electrónico de la cuenta de servicio. Tendrá un aspecto similar a este: 1234567890123-abcdefghijklmonpqrstuvwxz01234567@developer.gserviceaccount.com.
    • path/to/key.p12 es la clave que se te solicitó descargar cuando creaste la cuenta de servicio. Si perdiste la clave, puedes volver a la página Credenciales en Google Cloud Platform Console y generar una clave nueva.
  3. Confirma que la cuenta de servicio es la cuenta con credenciales activas.
    $ gcloud auth list
    Credentialed accounts:
    - 1234567890123-abcdefghijklmonpqrstuvwxz01234567@developer.gserviceaccount.com (active)
    

    Debes ver active para las credenciales de la cuenta de servicio. Ahora, cualquier comando de notificación de objeto gsutil que ejecutes usa las credenciales de la cuenta de servicio.

Identifica un dominio para recibir notificaciones

Las solicitudes de observación solo se realizarán de forma correcta si la URL de la notificación es un dominio perteneciente a la lista blanca del proyecto del canal de notificación.

Para incluir un dominio en la lista blanca:

  1. Verifica que eres el propietario del dominio mediante el proceso de verificación de Search Console.
  2. En GCP Console, dirígete a la pestaña Verificación del dominio en la página Credenciales.

    Ir a la página Credenciales

  3. Haz clic en Add domain (Agregar dominio).
  4. En el cuadro de diálogo Configure webhook notifications (Configura notificaciones de webhook), ingresa el dominio que deseas verificar.

    Configura el cuadro de diálogo de notificaciones de webhook

  5. Haz clic en Add domain.

    Para solucionar problemas sobre la verificación de dominios, haz lo siguiente:

    • El dominio debe estar registrado en Search Console con una URL https:// o estar verificado con el método Proveedor del nombre de dominio.
    • Asegúrate de que eres el propietario o editor del proyecto de GCP Console (consulta Miembros del proyecto y permisos) y eres el propietario del sitio del dominio que recibirá notificaciones. Si no eres el propietario del sitio del dominio, comunícate con el propietario del dominio para que te agregue como propietario verificado (consulta Agregar o quitar propietarios).
    • Puedes usar la API de Explorer de Google a fin de compilar una lista de sitios en el dominio mediante las Herramientas para webmaster de Google y, en particular, con el fin de ver si la propiedad siteUrl del dominio comienza con https://.

Quita un canal de notificación

Para detener un canal de notificación, puedes usar el comando gsutil notification stopchannel:

gsutil notification stopchannel ChannelId ResourceId

Esto detendrá todos los eventos de notificación del identificador de recursos especificados y la sincronización del identificador de canal. Los canales activos adicionales para el mismo recurso no se verán afectados. Los identificadores de recursos y de canales se pueden encontrar en la respuesta de una solicitud de observación o en el cuerpo de los mensajes de eventos de notificación.

Para obtener más información sobre este comando, ejecuta el comando gsutil help notification stopchannel.

Esta es una solicitud POST de ejemplo generada por gsutil para detener un canal:

POST /storage/v1/channels/stop HTTP/1.1
Host: www.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

Sincronización

Un evento de notificación se envía cuando se crea un canal de notificación nuevo luego del envío de una solicitud de observación. Después de recibir el evento de sincronización, todos los cambios posteriores en el depósito se enviarán a la URL de la aplicación configurada para el canal.

Se enviará la notificación como una solicitud POST a la URL de la aplicación configurada. No hay cuerpo en la solicitud. Los metadatos de la notificación de sincronización están en los encabezados de la solicitud. El siguiente es un ejemplo de la solicitud de notificación de sincronización:

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://www.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 agrega un objeto nuevo a un depósito, cuando se modifica el contenido o los metadatos de un objeto existente o cuando se borra un objeto de un depósito.

Se enviará la notificación como una solicitud POST a la URL de la aplicación configurada. El cuerpo de la solicitud contiene un mensaje codificado en JSON como se muestra en la solicitud de notificación siguiente:

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://www.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://www.googleapis.com/storage/v1/b/BucketName/o/ObjectName?generation=1367014943964000&alt=media",
 "owner": {
  "entity": "user-jane@gmail.com"
 },
 "crc32c": "C7+82w==",
 "etag": "COD2jMGv6bYCEAE="
}
donde ResourceState es el siguiente:
  • exists: para las adiciones y actualizaciones de objetos
  • not_exists: para borrar objetos

y donde el contenido del mensaje de JSON incluya la representación actual del objeto como se describe en Descripción del recurso de objeto.

Entrega confiable

La notificación de cambio de objeto intentará enviar notificaciones a tu aplicación de manera confiable. Sin embargo, ten en cuenta que las notificaciones se pueden retrasar de forma indefinida y no se garantiza su puntualidad. Dado que tu aplicación puede que no esté siempre disponible, se siguen las reglas siguientes cuando se envían las notificaciones:

  • Si el intento de entrega de una notificación falla, se realizarán más intentos. El intervalo entre los intentos de entrega adicionales se determina mediante un algoritmo de retirada exponencial que comienza con un reintento de 30 segundos después de la falla inicial. Se intentan entregas posteriores en intervalos mayores, hasta un intervalo máximo de 90 minutos. Ten en cuenta que los intervalos de reintento posteriores son levemente aleatorios por lo que no se producen en valores exponenciales exactos. Después de que se alcanza el intervalo máximo de reintentos de 90 minutos, continúan reintentos posteriores cada 90 minutos durante 7 días. Si no se puede entregar la notificación en esa hora, se borra de forma definitiva.
  • Si no puedes acceder a tu aplicación después de 20 segundos o si tu aplicación responde con uno de los códigos de respuesta HTTP siguientes, el intento de entrega de notificación se considera un error y se reintenta:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Si tu aplicación responde con uno de los códigos de respuesta HTTP siguientes, se considera que la notificación se entregó de forma correcta:
    • 102 Processing
    • 200 OK
    • 201 Created
    • 202 Accepted
    • 204 No Content
  • Cualquier otro código de respuesta HTTP que muestra tu aplicación se considera un error permanente y no se reintenta.

Ejemplo de aplicación cliente

En esta sección, se explica cómo crear una aplicación cliente de App Engine que procesa eventos de notificación de cambio.

En la figura siguiente, se muestra el cronograma de los eventos básicos que intervienen para recibir una notificación, desde la creación de un depósito hasta el procesamiento de eventos de notificación de cambio relacionados.

Cronograma de la notificación de cambio de objeto
Cronograma de la notificación de cambio de objeto

La aplicación de ejemplo contiene una clase llamada MainPage. Cuando el usuario actualiza o agrega un objeto al depósito, la clase MainPage procesa el evento de notificación. Para simplificar, el método post que realiza el procesamiento real solo registra un mensaje con la hora en que se recibió la notificación. Puedes reemplazar este código con tu lógica de procesamiento real. Si aún no te sientes cómodo con el desarrollo de aplicaciones de App Engine, intenta implementar una aplicación de muestra o sigue un instructivo antes de continuar.

  1. Configura la aplicación.
    Crea el archivo de configuración app.yaml para especificar la aplicación cliente que controla los eventos de notificación de cambio del depósito.
    application: <ApplicationId>
    version: 1
    runtime: python27
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: change_notification_client.app
    
  2. Crea la aplicación.
    En el ejemplo siguiente, se implementa una aplicación cliente para controlar los eventos de notificación de cambio de un depósito. Otórgale el nombre change_notification_client.py y, a continuación, implementa tu 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)
    
  3. Asigna el permiso de acceso de la aplicación al depósito.
    Si tu depósito pertenece a una cuenta de servicio diferente a tu app de App Engine, otorga a la aplicación el acceso de PROPIETARIO al depósito mediante la ejecución del comando siguiente:
    gsutil acl ch -u ApplicationId@appspot.gserviceaccount.com:OWNER gs://BucketName
    
  4. Comienza a observar el depósito en busca de cambios de objetos.
    Crea un canal de notificación para tu aplicación mediante la observación del depósito con gsutil:
    gsutil notification watchbucket ApplicationUrl gs://BucketName
    
    donde ApplicationUrl es la URL de tu aplicación de App Engine, p. ej., https://ApplicationId.appspot.com/.
  5. Prueba la aplicación.
    Para ver si la aplicación funciona como se esperaba, realiza los pasos siguientes:
    1. Para asegurarse de que la aplicación se implementó y funciona de forma correcta, ejecuta el comando siguiente curl:
      curl -X Post https://<ApplicationId>.appspot.com
      
      Si usaste tu propio nombre de dominio para implementar la aplicación, úsalo en lugar de appspot.com en el comando anterior.
    2. Ve a la página Registro de tu proyecto. Actualiza la lista de los mensajes registrados, si es necesario. Verifica que el mensaje de registro que envía la aplicación esté registrado.
    3. Agrega un objeto al depósito. Puedes usar la herramienta de gsutil de la manera siguiente:
      gsutil cp ObjectName gs://BucketName/
      
      Cloud Storage notifica a la aplicación, que luego registra un mensaje.
    4. Ve a la página Registro de tu proyecto. Actualiza la lista de los mensajes registrados y busca el mensaje para la copia del objeto.
  6. Quita el canal de notificación
    Quita el canal de notificación mediante la especificación de los identificadores del canal y de los recursos que se muestran cuando envías el comando de notificación para observar el depósito.
    gsutil notification stopchannel <channel_id> <resource_identifier>
    

Volver al principio

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Si necesitas ayuda, visita nuestra página de asistencia.