Notifica di modifica degli oggetti

La notifica della modifica degli oggetti può essere utilizzata per avvisare un'applicazione quando un oggetto viene aggiunto, aggiornato o eliminato da un bucket.

Devi utilizzare la notifica di modifica degli oggetti?

In genere, non devi utilizzare la notifica di modifica degli oggetti. Lo strumento consigliato per generare notifiche che tengano traccia delle modifiche apportate agli oggetti nei bucket Cloud Storage è 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.

Se attualmente utilizzi la notifica di modifica degli oggetti, ti consigliamo di eseguire la migrazione alle notifiche Pub/Sub. Per informazioni su come eseguire la migrazione alle notifiche Pub/Sub, consulta Eseguire la migrazione dalle notifiche di modifica degli oggetti alle notifiche Pub/Sub.

Come funziona la notifica di modifica degli oggetti

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

Il completamento di una richiesta di monitoraggio crea un nuovo canale di notifica. Un canale di notifica è il mezzo con cui un messaggio di notifica viene inviato a un'applicazione che monitora un bucket. Al momento è supportato un solo tipo di canale di notifica, un webhook.

Una volta creato 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 della notifica di modifica degli oggetti

Terminologia

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

Termine Descrizione
URL dell'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 del canale L'identificatore di un canale di notifica. Deve essere univoco all'interno di un determinato bucket, ovvero se esistono più canali di notifica per un singolo bucket, ogni canale di notifica deve avere un identificatore di canale distinto. Questo identificatore verrà inviato alla tua applicazione insieme a ogni messaggio di notifica.
Identificatore di risorse Un identificatore opaco per la risorsa visualizzata. L'identificatore della risorsa è obbligatorio per interrompere un canale di notifica. Puoi recuperare questo identificatore dalla risposta a una richiesta di monitoraggio o dall'intestazione X-Goog-Resource-Id dei messaggi di 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 di visualizzazione. I messaggi di notifica conterranno questo token per consentirti di verificare che siano autentici.

Creazione di un canale di notifica

Per iniziare a monitorare un bucket per gli eventi di notifica delle modifiche, devi inviare una richiesta watchAll. In questo modo viene creato un canale di notifica che invia eventi di notifica al address specificato per il bucket indicato. Il canale di notifica include un token client personalizzato e un identificatore del canale, se specificati.

Un esempio di richiesta POST per il monitoraggio 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 osservi un bucket, il canale di notifica creato verrà 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 installata o a un'applicazione web tramite un flusso OAuth2, un canale di notifica creato dall'applicazione verrà associato al progetto dell'applicazione, non al progetto contenente il bucket monitorato.

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

Interrompere un canale di notifica

L'interruzione di un canale di notifica di modifica degli oggetti impedisce la pubblicazione delle notifiche di modifica degli oggetti nell'URL dell'applicazione associato. Per interrompere correttamente un canale di notifica delle modifiche agli oggetti, devi conoscere i seguenti parametri:

  • L'identificatore della risorsa del canale di notifica di modifica degli oggetti (RESOURCE_ID)
  • L'identificatore del canale di notifica di modifica degli oggetti (CHANNEL_ID)
  • L'utente o l'account di servizio che ha creato il canale di notifica delle modifiche agli oggetti. Solo il creator del canale può interromperlo.

Riga di comando

  1. In the Google Cloud console, activate Cloud Shell.

    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.

  2. Installa gsutil.
  3. Per trovare tutti i canali di notifica delle modifiche agli oggetti attivi ed elencarne i dettagli per identificare CHANNEL_ID, RESOURCE_ID e l'account di servizio che ha creato il canale, utilizza il comando gsutil notification list:
      gsutil notification list -o gs://BUCKET_NAME
      

    Dove:

    BUCKET_NAME è il nome del tuo bucket. Ad esempio, my-bucket.

    Se la richiesta riesce, il comando restituisce un output simile al seguente messaggio:

    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
  4. Se il canale è stato creato da un account di servizio, devi impersonare il creatore del account di servizio per assicurarti di disporre delle autorizzazioni necessarie.
    gcloud config set auth/impersonate_service_account CHANNEL_CREATOR

    Dove:

    CHANNEL_CREATOR è il account di servizio che ha creato il canale.
  5. Interrompi il canale di notifica di modifica degli oggetti dal bucket utilizzando CHANNEL_ID e RESOURCE_ID identificati.
    gsutil notification stopchannel CHANNEL_ID RESOURCE_ID

    Dove:

    • CHANNEL_ID è l'identificatore del canale di notifica di modifica degli oggetti.
    • RESOURCE_ID è l'identificatore della risorsa del canale di notifica di modifica degli oggetti.

API REST

API JSON

Per interrompere un canale di notifica, devi inviare una richiesta di stop. In questo modo vengono interrotti tutti gli eventi di notifica pubblicati nella coppia di identificatori di risorse (resourceId) e identificatori di canali (id) specificata. Gli altri canali per la stessa risorsa non sono interessati. Gli identificatori di risorse e canali si trovano nella risposta a una richiesta di visualizzazione o nel corpo dei messaggi di eventi di notifica.

Esempio di richiesta POST per interrompere 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 di eventi di notifica

Sincronizza

Un evento di notifica viene inviato quando viene creato un nuovo canale di notifica dopo l'emissione 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 configurato. Non è presente alcun corpo nella richiesta. I metadati di notifica della 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, quando i contenuti o i metadati di un oggetto esistente sono stati modificati o quando un oggetto viene eliminato da un bucket.

La notifica verrà inviata come richiesta POST all'URL dell'applicazione configurato. Il corpo della richiesta contiene un messaggio codificato in formato 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-jeffersonloveshiking@gmail.com"
 },
 "crc32c": "C7+82w==",
 "etag": "COD2jMGv6bYCEAE="
}
dove ResourceState è:
  • exists: per aggiunte e aggiornamenti di oggetti.
  • not_exists: per le eliminazioni di oggetti.

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

Distribuzione affidabile

La notifica di modifica degli oggetti tenterà di inviare le notifiche alla tua applicazione in modo affidabile. Tuttavia, tieni presente che le notifiche possono subire ritardi indefiniti e la tempestività non è garantita. Poiché l'applicazione potrebbe non essere sempre disponibile, per l'invio delle notifiche vengono seguite le seguenti regole:

  • Se un tentativo di invio della notifica 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 consegna successivi vengono eseguiti a intervalli sempre più lunghi, fino a un intervallo massimo di 90 minuti. Tieni presente che gli intervalli di nuovi tentativi successivi sono leggermente randomizzati, 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 la notifica non può essere inviata entro questo periodo di tempo, viene eliminata.
  • Se non è possibile raggiungere la tua applicazione dopo 20 secondi o se la tua applicazione risponde con uno dei seguenti codici di risposta HTTP, il tentativo di invio della notifica viene considerato non riuscito e viene riprovato:
    • 500 - Errore interno del server
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Timeout gateway
  • Se la tua applicazione risponde con uno dei seguenti codici di risposta HTTP, la notifica viene considerata consegnata correttamente:
    • 102 Elaborazione
    • 200 OK
    • 201 Created
    • 202 Accepted
    • 204 No Content
  • Qualsiasi altro codice di risposta HTTP restituito dall'applicazione viene trattato come errore permanente e non viene ritentato.

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 chiamata 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 familiarità con lo sviluppo di applicazioni App Engine, prova a deployare un'app di esempio o a seguire un tutorial prima di continuare.

  1. Configurazione dell'applicazione
    Crea il file di configurazione app.yaml per specificare l'applicazione client che gestisce gli eventi di notifica delle modifiche del bucket.
    application: APPLICATION
    version: 1
    runtime: python38
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: change_notification_client.app
  2. Creazione dell'applicazione
    Il seguente esempio implementa un'applicazione client per la gestione degli eventi di notifica delle modifiche di un bucket. Assegna il nome change_notification_client.py, poi esegui il deployment dell'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 dalla tua app App Engine, concedi all'applicazione l'accesso OWNER al bucket.
  4. Inizia a monitorare il bucket per rilevare le modifiche agli oggetti.
    Crea un canale di notifica per la tua applicazione osservando il bucket utilizzando una richiesta watchAll con il address dell'URL per la tua applicazione App Engine, ad esempio: https://ApplicationId.appspot.com/.
  5. Testare l'applicazione.
    Per verificare che l'applicazione funzioni come previsto, segui questi passaggi:
    1. Per assicurarti che l'applicazione sia stata implementata e funzioni correttamente, esegui questo comando curl:
      curl -X Post https://APPLICATIONID.appspot.com
      Se hai utilizzato il tuo nome di dominio per il deployment dell'applicazione, utilizzalo al posto di appspot.com nel comando precedente.
    2. Vai alla pagina Logging del progetto. Aggiorna l'elenco dei messaggi registrati, se necessario. Verifica che il messaggio di log emesso dall'applicazione venga registrato.
    3. Aggiungi un oggetto al bucket. Cloud Storage invia una notifica all'applicazione, che quindi registra un messaggio.
    4. Vai alla <a href="https://console.cloud.google.com/project//logs">pagina Logging del tuo progetto. Aggiorna l'elenco dei messaggi registrati e trova il messaggio per la copia dell'oggetto.
    5. </ol>
      

    6. Interrompi il canale di notifica
      Interrompi il canale di notifica specificando gli identificatori di canale e risorsa restituiti quando hai inviato il comando di notifica per creare un canale di notifica.