Notification de modification d'objets

La fonctionnalité de notification de modification d'objet permet de notifier une application lorsqu'un objet est mis à jour ou ajouté à un bucket.

Faut-il utiliser la notification de modification d'objet ?

D'une manière générale, vous ne devez pas utiliser la notification de modification d'objet. Les notifications Pub/Sub pour Cloud Storage sont recommandées pour suivre les modifications apportées aux objets de vos buckets Cloud Storage, car elles sont plus rapides, plus flexibles, plus faciles à configurer et plus économiques. Pour suivre un guide par étapes sur la configuration des notifications Pub/Sub pour Cloud Storage, consultez la page Configurer les notifications Pub/Sub pour Cloud Storage.

Fonctionnement de la notification de modification d'objet

Une application cliente peut émettre une requête lui permettant de surveiller les modifications apportées aux objets d'un bucket particulier.

L'émission d'une telle requête crée un nouveau canal de notification. Un canal de notification est le moyen par lequel un message de notification est envoyé à une application surveillant un bucket. À l'heure actuelle, un seul canal de notification, le Webhook, est compatible.

Une fois qu'un canal de notification est mis en place, Cloud Storage notifie l'application chaque fois qu'un objet est ajouté, mis à jour ou supprimé du bucket. Par exemple, lorsque vous ajoutez une image à un bucket, une application peut être notifiée pour créer une vignette.

Détails de la notification de modification d'objet

Terminologie

Le tableau suivant contient une description de plusieurs termes utilisés tout au long de la documentation relative aux notifications de modification d'objet :

Terme Description
URL de l'application URL de votre application. Il s'agit de l'adresse à laquelle les notifications seront envoyées. Notez qu'il doit s'agir d'une URL HTTPS. Les URL HTTP ne sont pas autorisées.
Identifiant de canal Identifiant d'un canal de notification. Cette valeur doit être unique dans un bucket particulier. S'il existe plusieurs canaux de notification pour un même bucket, chaque canal doit avoir un identifiant de canal distinct. Cet identifiant sera envoyé à l'application avec chaque message de notification.
Identifiant de ressource Identifiant opaque pour la ressource surveillée. L'identifiant de ressource est requis pour l'arrêt d'un canal de notification. Vous pouvez extraire cet identifiant de la réponse à une requête de surveillance ou de l'en-tête X-Goog-Resource-Id des messages d'événements de notification.
Jeton Client (facultatif) Les jetons client peuvent être utilisés pour valider les événements de notification. Pour ce faire, définissez un jeton client personnalisé avec votre requête de surveillance. Les messages de notification contiendront ce jeton afin que vous puissiez vérifier leur authenticité.

Surveiller un bucket

Pour commencer à surveiller les événements des notifications de modification dans un bucket, vous devez envoyer une requête watchAll. Cela crée un canal de notification qui envoie des événements de notification à la address donnée pour le bucket donné. Le canal de notification inclut un jeton client personnalisé et un identifiant de canal, le cas échéant.

Voici un exemple de requête POST pour surveiller un bucket :

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

Autorisation de notification

Lors de la surveillance d'un bucket, le canal de notification en cours de création sera associé au projet Google Cloud Console de l'application à l'origine de la requête API. Cela signifie, par exemple, que si un utilisateur accorde l'accès à une application installée ou à une application Web via un flux OAuth2, un canal de notification créé par l'application sera associé au projet de cette application et non au projet contenant le bucket surveillé.

Un compte de service étant associé à un projet, si vous l'utilisez pour surveiller un bucket, un canal de notification sera créé dans le projet du compte de service.

Supprimer un canal de notification

Pour arrêter un canal de notification, vous devez effectuer une requête stop. Cela arrête tous les événements de notification pour la paire identifiant de ressource (resourceId) et identifiant de canal (id) spécifiée. Les canaux actifs supplémentaires pour la même ressource ne sont pas affectés. Les identifiants de ressource et de canal peuvent se trouver dans la réponse à une requête de surveillance ou dans le corps des messages d'événements de notification.

Exemple de requête POST permettant d'arrêter 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"
}

Types de messages d'événements de notification

Synchroniser

Un événement de notification est envoyé lorsqu'un nouveau canal de notification est créé suite à l'envoi d'une requête de surveillance. Une fois l'événement de synchronisation reçu, toutes les modifications ultérieures apportées au bucket seront envoyées à l'URL de l'application configurée pour le canal.

La notification sera envoyée sous la forme d'une requête POST à l'URL d'application configurée. La requête ne présente pas de corps. Par conséquent, les métadonnées de notification de synchronisation sont contenues dans les en-têtes de la requête. Voici un exemple de requête de notification de synchronisation :

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

Ajout, mise à jour ou suppression d'objet

Un événement de notification est envoyé lorsqu'un nouvel objet est ajouté à un bucket, que le contenu ou les métadonnées d'un objet existant sont modifiés ou qu'un objet est supprimé d'un bucket.

La notification est envoyée sous la forme d'une requête POST à l'URL d'application configurée. Le corps de la requête contient un message codé au format JSON, comme indiqué dans la requête de notification suivante :

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-jane@gmail.com"
 },
 "crc32c": "C7+82w==",
 "etag": "COD2jMGv6bYCEAE="
}
ResourceState correspond à :
  • exists, pour les ajouts et les mises à jour d'objets.
  • not_exists, pour les suppressions d'objets.

et où le contenu du message JSON contient la représentation actuelle de l'objet, telle que définie à la section Description de la ressource d'objet.

Fiabilité

La notification de modification d'objet tente de transmettre des notifications fiables à votre application. Sachez toutefois que les notifications peuvent être retardées indéfiniment et que la rapidité d'exécution n'est pas garantie. Il se peut que l'application ne soit pas toujours disponible, .c'est pourquoi les règles suivantes s'appliquent lors de l'envoi des notifications :

  • Si une tentative d'envoi de notification échoue, des tentatives supplémentaires sont effectuées. L'intervalle entre les tentatives d'envoi supplémentaires est déterminé par un algorithme d'intervalle exponentiel entre les tentatives avec un premier essai 30 secondes après l'échec initial. Les tentatives d'envoi suivantes sont effectuées selon des intervalles croissants, jusqu'à un maximum de 90 minutes. Notez que les intervalles entre les tentatives sont légèrement aléatoires et ne se produisent donc pas à des valeurs exponentielles exactes. Une fois l'intervalle maximum de 90 minutes atteint, les tentatives suivantes continuent toutes les 90 minutes pendant sept jours. Si la notification ne peut pas être transmise dans ce délai, elle est définitivement supprimée.
  • Si la notification ne parvient pas à l'application dans les 20 secondes ou si votre application répond par l'un des codes de réponse HTTP suivants, la tentative d'envoi de notification est traitée comme un échec et fera l'objet d'une nouvelle tentative :
    • 500 Erreur interne au serveur.
    • 502 Passerelle incorrecte
    • 503 Service indisponible.
    • 504 Expiration du délai de la passerelle
  • Si votre application répond avec l'un des codes de réponse HTTP suivants, la tentative de notification est considérée comme réussie :
    • 102 Traitement en cours
    • 200 OK
    • 201 Créée
    • 202 Acceptée
    • 204 Aucun contenu
  • Tout autre code de réponse HTTP renvoyé par l'application est traité comme un échec permanent et ne fait pas l'objet d'une nouvelle tentative.

Exemple d'application cliente

Cette section explique comment créer une application cliente App Engine qui traite les événements de notification de modification.

L'exemple d'application contient une classe appelée MainPage. Lorsque l'utilisateur met à jour ou ajoute un objet au bucket, la classe MainPage traite l'événement de notification. Pour des raisons de simplicité, la méthode post qui effectue réellement le traitement enregistre simplement un message avec l'heure à laquelle la notification a été reçue. Vous pouvez remplacer ce code par votre propre logique de traitement. Si vous n'êtes pas encore à l'aise pour développer des applications App Engine, essayez de déployer un exemple d'application ou de suivre un tutoriel avant de continuer.

  1. Configurer l'application
    Créez le fichier de configuration app.yaml pour spécifier l'application cliente chargée de gérer les événements de notification de modification pour le bucket.
    application: APPLICATION
    version: 1
    runtime: python38
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: change_notification_client.app
    
  2. Créer l'application
    L'exemple suivant met en œuvre une application cliente pour la gestion des événements de notification des modifications pour un bucket. Nommez-la change_notification_client.py, puis déployez votre application :
    """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. Accorder l'autorisation d'accès de l'application au bucket
    Si votre bucket appartient à un compte de service différent de celui de votre application App Engine, accordez au bucket le rôle PROPRIÉTAIRE de l'application.
  4. Commencer à surveiller les modifications d'objets dans le bucket
    Créez un canal de notification pour votre application en surveillant le bucket à l'aide d'une requête watchAll avec le address de l'URL de votre application App Engine, par exemple https://ApplicationId.appspot.com/.
  5. Tester l'application
    Pour voir si l'application fonctionne comme prévu, procédez comme suit :
    1. Pour vous assurer que l'application a été déployée et fonctionne correctement, exécutez la commande curl suivante :
      curl -X Post https://APPLICATION_ID.appspot.com
      
      Si vous avez utilisé votre propre nom de domaine pour déployer l'application, utilisez-le à la place de appspot.com dans la commande précédente.
    2. Accédez à la page de journalisation de votre projet. Actualisez la liste des messages enregistrés, si nécessaire. Vérifiez que le message de journal émis par l'application est enregistré.
    3. Ajoutez un objet au bucket. Cloud Storage notifie l'application, qui enregistre ensuite un message.
    4. Accédez à la page de journalisation de votre projet. Actualisez la liste des messages enregistrés et recherchez le message correspondant à la copie d'objet.
  6. Supprimer le canal de notification
    Supprimez le canal de notification en indiquant les identifiants de canal et de ressource renvoyés lorsque vous avez utilisé la commande de notification pour surveiller le bucket.