Notifica di modifica degli oggetti

La notifica di modifica degli oggetti può essere utilizzata per notificare un'applicazione quando un oggetto viene aggiornato o aggiunto a un bucket.

Vuoi usare la notifica di modifica degli oggetti?

In genere, non dovresti utilizzare la notifica di modifica degli oggetti. Lo strumento consigliato per generare notifiche che tengono traccia delle modifiche agli oggetti nei bucket Cloud Storage sono le notifiche Pub/Sub per Cloud Storage, perché è più veloce, più flessibile, più facile da configurare e più conveniente. Per una guida passo passo alla configurazione delle notifiche Pub/Sub per Cloud Storage, consulta Configurazione delle notifiche Pub/Sub per Cloud Storage.

Come funziona la notifica di modifica degli oggetti

Un'applicazione client può inviare una richiesta per controllare le modifiche agli oggetti in un determinato bucket.

Quando completi una richiesta di visualizzazione, viene creato un nuovo canale di notifica. Un canale di notifica è il mezzo tramite il quale un messaggio di notifica viene inviato a un'applicazione che controlla un bucket. Attualmente è supportato un solo tipo di canale di notifica: il web hook.

Dopo l'avvio di un canale di notifica, Cloud Storage invia una notifica all'applicazione ogni volta che un oggetto viene aggiunto, aggiornato o rimosso dal bucket. Ad esempio, quando aggiungi una nuova immagine a un bucket, un'applicazione potrebbe ricevere una notifica per creare una miniatura.

Dettagli notifica di modifica degli oggetti

Terminologia

La tabella seguente contiene una descrizione di diversi termini utilizzati nella documentazione relativa alla notifica di modifica degli oggetti:

Termine Descrizione
URL applicazione L'URL della tua applicazione. Questo è l'indirizzo a cui verranno inviate le notifiche. Tieni presente che deve essere un URL HTTPS; gli URL HTTP non sono consentiti.
Identificatore di canale L'identificatore di un canale di notifica. Deve essere univoco all'interno di un determinato bucket, ovvero se sono presenti più canali di notifica per un singolo bucket, ognuno deve avere un identificatore di canale distinto. Questo identificatore verrà inviato alla tua applicazione insieme a ogni messaggio di notifica.
Identificatore risorsa Un identificatore opaco per la risorsa monitorata. L'identificatore della risorsa è obbligatorio per arrestare un canale di notifica. Puoi recuperare questo identificatore dalla risposta a una richiesta dell'orologio o dall'intestazione X-Goog-Resource-Id dei messaggi degli eventi di notifica.
Token client (Facoltativo) I token client possono essere utilizzati per convalidare gli eventi di notifica. Per farlo, imposta un token client personalizzato con la richiesta dello smartwatch. I messaggi di notifica conterranno questo token, per consentirti di verificare che siano autentici.

Visione di un bucket

Per iniziare a osservare un bucket per gli eventi di notifica delle modifiche, effettua una richiesta watchAll. Viene creato un canale di notifica che invia eventi di notifica al address specificato per il bucket specificato. Il canale di notifica include un token client personalizzato e un identificatore di canale, se specificato.

Esempio di richiesta POST per la visualizzazione di 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"
}

Autorizzazione alle notifiche

Quando controlli un bucket, il canale di notifica che viene creato viene associato al progetto della console Google Cloud dell'applicazione che avvia la richiesta API. Ciò significa, ad esempio, che se un utente concede l'accesso a un'applicazione o a un'applicazione web installata tramite un flusso OAuth2, al progetto dell'applicazione verrà associato un canale di notifica creato dall'applicazione, non al progetto contenente il bucket monitorato.

Poiché un account di servizio è associato a un progetto, se lo utilizzi per controllare un bucket, verrà creato un canale di notifica nel progetto dell'account di servizio.

Rimozione di un canale di notifica

Per interrompere un canale di notifica, devi effettuare una richiesta stop. Questa operazione interrompe tutti gli eventi di notifica per la coppia di identificatore di risorse (resourceId) e identificatore di canale (id) specificata. I canali attivi aggiuntivi per la stessa risorsa non sono interessati. Gli identificatori di risorse e canale sono disponibili nella risposta a una richiesta di visualizzazione o nel corpo dei messaggi degli eventi di notifica.

Esempio di richiesta POST per l'interruzione di un canale:

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

Tipi di messaggi degli eventi di notifica

Sincronizza

Viene inviato un evento di notifica quando viene creato un nuovo canale di notifica dopo l'invio di una richiesta di visualizzazione. Dopo aver ricevuto l'evento di sincronizzazione, tutte le modifiche successive al bucket verranno inviate all'URL dell'applicazione configurato per il canale.

La notifica verrà inviata come richiesta POST all'URL dell'applicazione configurata. La richiesta non contiene alcun corpo. I metadati della notifica di sincronizzazione sono contenuti nelle intestazioni della richiesta. Di seguito è riportato un esempio di richiesta di notifica di sincronizzazione:

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

Aggiunta, aggiornamento o eliminazione di oggetti

Un evento di notifica viene inviato quando un nuovo oggetto viene aggiunto a un bucket, i contenuti o i metadati di un oggetto esistente sono stati modificati oppure un oggetto viene eliminato da un bucket.

La notifica verrà inviata come richiesta POST all'URL dell'applicazione configurata. Il corpo della richiesta contiene un messaggio con codifica JSON, come mostrato nella seguente richiesta di notifica:

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="
}
dove ResourceState è:
  • exists per aggiunte e aggiornamenti di oggetti.
  • not_exists: per l'eliminazione degli oggetti.

e dove i contenuti del messaggio JSON contengono la rappresentazione corrente dell'oggetto come descritto in Descrizione della risorsa dell'oggetto.

Consegna affidabile

La notifica di modifica degli oggetti tenterà di inviare notifiche alla tua applicazione in modo affidabile. Tuttavia, tieni presente che le notifiche possono essere ritardate a tempo indeterminato e che la tempestività non è garantita. Poiché la tua applicazione potrebbe non essere sempre disponibile, quando invii le notifiche vengono applicate le seguenti regole:

  • Se un tentativo di consegna delle notifiche non va a buon fine, verranno effettuati altri tentativi. L'intervallo tra i tentativi di consegna aggiuntivi è determinato da un algoritmo di backoff esponenziale che inizia con un nuovo tentativo 30 secondi dopo l'errore iniziale. I tentativi di caricamento successivi vengono effettuati a intervalli crescenti, fino a un massimo di 90 minuti. Tieni presente che gli intervalli tra i tentativi successivi sono leggermente casuali, quindi non si verificano a valori esponenziali esatti. Una volta raggiunto l'intervallo massimo di tentativi di 90 minuti, i tentativi successivi continuano ogni 90 minuti per 7 giorni. Se nel frattempo non è possibile recapitarla, la notifica viene eliminata definitivamente.
  • Se l'applicazione non può essere raggiunta dopo 20 secondi o se l'applicazione risponde con uno dei seguenti codici di risposta HTTP, il tentativo di consegna delle notifiche viene considerato come un errore e viene ripetuto:
    • errore interno del server (500)
    • gateway non valido (502)
    • servizio non disponibile (503)
    • timeout del gateway (504)
  • Se la tua applicazione risponde con uno dei seguenti codici di risposta HTTP, la notifica viene considerata consegnata correttamente:
    • 102 Elaborazione
    • 200 OK
    • 201 creati
    • 202 Accettato
    • 204 Nessun contenuto
  • Eventuali altri codici di risposta HTTP restituiti dall'applicazione vengono trattati come errori permanenti e non vengono tentati nuovamente.

Esempio di applicazione client

Questa sezione spiega come creare un'applicazione client App Engine che elabora gli eventi di notifica delle modifiche.

L'applicazione di esempio contiene una classe denominata MainPage. Quando l'utente aggiorna o aggiunge un oggetto al bucket, la classe MainPage elabora l'evento di notifica. Per semplicità, il metodo post che esegue l'elaborazione effettiva registra solo un messaggio con l'ora in cui è stata ricevuta la notifica. Puoi sostituire questo codice con la logica di elaborazione effettiva. Se non hai ancora dimestichezza con lo sviluppo di applicazioni App Engine, prova a eseguire il deployment di un'app di esempio o segui un tutorial prima di continuare.

  1. Configurare l'applicazione.
    Crea il file di configurazione app.yaml per specificare l'applicazione client che gestisce gli eventi di notifica di modifica del bucket.
    application: APPLICATION
    version: 1
    runtime: python38
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: change_notification_client.app
    
  2. Creazione dell'applicazione.
    Nell'esempio seguente viene implementata un'applicazione client per la gestione degli eventi di notifica delle modifiche di un bucket. Assegna il nome change_notification_client.py, quindi esegui il deployment della tua app:
    """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. Assegnazione dell'autorizzazione di accesso dell'applicazione al bucket.
    Se il bucket è di proprietà di un account di servizio diverso da quello dell'app App Engine, concedi all'applicazione l'accesso OWNER (proprietario).
  4. Inizia a controllare il bucket per le modifiche agli oggetti.
    Crea un canale di notifica per la tua applicazione guardando il bucket tramite una richiesta watchAll con address dell'URL della tua applicazione App Engine, ad esempio https://ApplicationId.appspot.com/.
  5. Test dell'applicazione.
    Per verificare se l'applicazione funziona come previsto, segui questi passaggi:
    1. Per assicurarti che il deployment dell'applicazione sia stato eseguito e che funzioni correttamente, esegui il seguente comando curl:
      curl -X Post https://APPLICATION_ID.appspot.com
      
      Se hai utilizzato il tuo nome di dominio per eseguire il deployment dell'applicazione, utilizzalo al posto di appspot.com nel comando precedente.
    2. Vai alla pagina Logging del tuo progetto. Se necessario, aggiorna l'elenco dei messaggi registrati. Verifica che il messaggio di log inviato dall'applicazione sia registrato.
    3. Aggiungi un oggetto al bucket. Cloud Storage invia una notifica all'applicazione, quindi registra un messaggio.
    4. Vai alla pagina Logging del tuo progetto. Aggiorna l'elenco dei messaggi registrati e individua il messaggio per la copia dell'oggetto.
  6. Rimuovi il canale di notifica
    Rimuovi il canale di notifica specificando il canale e gli identificatori della risorsa restituiti quando hai inviato il comando di notifica per guardare il bucket.