Notifica di modifica degli oggetti

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

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

Vuoi utilizzare la notifica di modifica degli oggetti?

In genere, non dovresti 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 è la funzionalità Notifiche Pub/Sub per Cloud Storage, che è più veloce, più flessibile, più facile da configurare e più economica. Per una guida passo passo per la 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.

Il completamento di una richiesta di visualizzazione crea un nuovo canale di notifica. Un canale di notifica è il mezzo tramite il quale un messaggio di notifica viene inviato a un'applicazione che guarda un bucket. Attualmente è supportato un solo tipo di canale di notifica, un webhook.

Dopo l'avvio di un canale di notifica, Cloud Storage avvisa l'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 la creazione di una miniatura.

La figura seguente mostra un flusso di dati di esempio per un'applicazione che elabora le notifiche di modifica. Qualsiasi server delle applicazioni in grado di ricevere richieste POST HTTPS può essere utilizzato per elaborare le notifiche di modifica.

Componenti delle notifiche di modifica degli oggetti
Componenti delle notifiche di modifica degli oggetti

Dettagli notifica modifica oggetto

Terminologia

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

Termine Descrizione
URL applicazione L'URL della tua applicazione. Si tratta dell'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, ad esempio, se esistono più canali di notifica per un singolo bucket, ogni canale di notifica deve avere un identificatore canale univoco. Questo identificatore verrà inviato alla tua applicazione insieme a ogni messaggio di notifica.
Identificatore di risorse Un identificatore opaco per la risorsa monitorata. L'identificatore della risorsa è necessario per interrompere un canale di notifica. Puoi recuperare questo identificatore dalla risposta a una richiesta di visualizzazione o dall'intestazione X-Goog-Resource-Id dei messaggi di eventi di notifica.
Token client (Facoltativo) Puoi utilizzare i token client 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 verificarne l'autenticità.

Visione di un bucket

Per iniziare a osservare un bucket per gli eventi di notifica di modifica, puoi usare il comando gsutil notification watchbucket:

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

In questo modo verrà creato un canale di notifica che invia eventi di notifica all'URL dell'applicazione specificato per il bucket in questione. Il canale di notifica includerà il token client personalizzato e l'identificatore del canale, se specificati.

Per ulteriori informazioni su questo comando, esegui il comando gsutil help notification watchbucket.

Esempio di richiesta POST generata da gsutil per guardare 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 delle notifiche

Quando guardi un bucket, il canale di notifica creato viene associato al progetto Google Cloud Console dell'applicazione che avvia la richiesta API. Ciò significa, ad esempio, che se un utente dà accesso a un'applicazione o a un'applicazione web installate tramite un flusso OAuth2, un canale di notifica creato dall'applicazione verrà associato al progetto dell'applicazione, non a quello contenente il bucket controllato.

La configurazione dell'autorizzazione in uno scenario di notifica di modifica degli oggetti prevede due passaggi:

Creazione di un account di servizio

Poiché un account di servizio è associato a un progetto, l'utilizzo di un account di servizio per guardare un bucket creerà un canale di notifica nel progetto dell'account di servizio.

Devi utilizzare un account di servizio esistente o crearne uno nuovo e scaricare la chiave privata associata.

Configurazione di gsutil per l'uso dell'account di servizio

Per configurare gsutil per utilizzare l'account di servizio, puoi utilizzare Google Cloud CLI per aggiungere l'account di servizio come account con credenziali per lavorare con le risorse di Google Cloud, inclusa la notifica di modifica degli oggetti. Dopo aver aggiunto le credenziali, tutti i successivi comandi gsutil utilizzeranno le credenziali dell'account di servizio.

Per creare credenziali basate sull'account di servizio:

  1. Assicurati di avere la versione più recente dell'interfaccia a riga di comando gcloud. Puoi aggiornare i tuoi componenti eseguendo questo comando:
    gcloud components update
    
  2. Utilizza il comando gcloud auth activate-service-account e specifica l'indirizzo email dell'account di servizio e la chiave privata.
    gcloud auth activate-service-account service-account-email --key-file path/to/key.p12
    

    dove:

    • service-account-email è l'indirizzo email dell'account di servizio. Sarà simile a questo: 1234567890123-abcdefghijklmonpqrstuvwxz01234567@developer.gserviceaccount.com.
    • path/to/key.p12 è la chiave che ti è stato chiesto di scaricare quando hai creato l'account di servizio. Se hai perso la chiave, puoi tornare alla pagina Credenziali in Google Cloud Console e generare una nuova chiave.
  3. Conferma che l'account di servizio è l'account con credenziali attive.
    $ gcloud auth list
    Credentialed accounts:
    - 1234567890123-abcdefghijklmonpqrstuvwxz01234567@developer.gserviceaccount.com (active)
    

    Dovresti vedere active in base alle credenziali dell'account di servizio. Qualsiasi comando di notifica dell'oggetto gsutil che esegui utilizza le credenziali dell'account di servizio.

Rimozione di un canale di notifica

Per interrompere un canale di notifica, puoi utilizzare il comando gsutil notification stopchannel:

gsutil notification stopchannel ChannelId ResourceId

Questa operazione interromperà l'invio di tutti gli eventi di notifica alla coppia specificata di identificatore della risorsa e identificatore del canale. I canali attivi aggiuntivi per la stessa risorsa non saranno interessati. Gli identificatori di risorse e canali sono disponibili nella risposta a una richiesta di visualizzazione o nel corpo dei messaggi di eventi di notifica.

Per ulteriori informazioni su questo comando, esegui il comando gsutil help notification stopchannel.

Un esempio di richiesta POST generata da gsutil 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 per eventi 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 configurata. Non c'è alcun corpo nella richiesta. I metadati della notifica di sincronizzazione sono contenuti nelle intestazioni della richiesta. Di seguito è riportato un esempio di richiesta 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

Quando viene aggiunto un nuovo oggetto a un bucket, viene modificato il contenuto o i metadati di un oggetto esistente o viene eliminato un oggetto da un bucket, viene inviato un evento di notifica.

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://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 le aggiunte e gli aggiornamenti degli oggetti.
  • not_exists, per le eliminazioni di oggetti.

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

Consegna affidabile

La notifica di modifica degli oggetti proverà a inviare le 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é l'applicazione potrebbe non essere sempre disponibile, per la ricezione delle notifiche vengono seguite le seguenti regole:

  • Se un tentativo di consegna delle notifiche non riesce, saranno effettuati ulteriori tentativi. L'intervallo tra i tentativi di pubblicazione aggiuntivi è determinato da un algoritmo di backoff esponenziale che inizia con un nuovo tentativo 30 secondi dopo l'errore iniziale. Le consegne successive vengono tentate ad intervalli crescenti, fino a un intervallo massimo di 90 minuti. Tieni presente che gli intervalli di tentativi successivi sono leggermente casuali, quindi non si verificano a valori esponenziali esatti. Una volta raggiunto l'intervallo massimo di 90 minuti, i nuovi tentativi continuano ogni 90 minuti per 7 giorni. Se la notifica non può essere consegnata entro tale orario, viene eliminata definitivamente.
  • Se l'applicazione non è raggiungibile dopo 20 secondi o se risponde con uno dei seguenti codici di risposta HTTP, il tentativo di recapito delle notifiche viene considerato come errore e viene riprovato:
    • Errore interno del server 500
    • Gateway non valido 502
    • 503 Servizio non disponibile
    • Timeout gateway 504
  • Se l'applicazione risponde con uno dei seguenti codici di risposta HTTP, la notifica viene considerata come consegnata correttamente:
    • Guida introduttiva
    • 200 OK
    • 201 creata
    • 202 Accettato
    • 204 Nessun contenuto
  • Eventuali altri codici di risposta HTTP restituiti dalla tua applicazione vengono considerati come errori permanenti e non vengono sottoposti a nuovi tentativi.

Esempio di applicazione client

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

La figura seguente mostra la sequenza temporale degli eventi di base coinvolti nella ricezione di una notifica, dalla creazione di un bucket all'elaborazione dei relativi eventi di notifica di modifica:

Sequenza temporale della notifica di modifica degli oggetti
Sequenza temporale della notifica di modifica degli oggetti

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 semplicemente un messaggio con l'ora di ricezione della 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 eseguire il deployment di 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 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 di modifica di un bucket. Assegna al nome change_notification_client.py, quindi 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 all'applicazione al bucket.
    Se il bucket è di proprietà di un account di servizio diverso da quello della tua app App Engine, concedi all'applicazione l'accesso PROPRIETARIO al bucket eseguendo il comando seguente:
    gsutil acl ch -u ApplicationId@appspot.gserviceaccount.com:OWNER gs://BucketName
    
  4. Inizia a controllare il bucket per le modifiche agli oggetti.
    Crea un canale di notifica per la tua applicazione guardando il bucket con gsutil:
    gsutil notification watchbucket ApplicationUrl gs://BucketName
    
    dove ApplicationUrl è l'URL della tua applicazione App Engine, ad esempio https://ApplicationId.appspot.com/.
  5. Testare l'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 questo comando curl:
      curl -X Post https://APPLICATION_ID.appspot.com
      
      Se hai utilizzato il tuo nome di dominio per eseguire il deployment dell'applicazione, usala 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 sia registrato.
    3. Aggiungi un oggetto al bucket. Puoi utilizzare lo strumento gsutil come segue:
      gsutil cp ObjectName gs://BucketName/
      
      Cloud Storage invia una notifica all'applicazione, che registra un messaggio.
    4. Vai alla pagina Logging del progetto. Aggiorna l'elenco dei messaggi registrati e trova il messaggio relativo alla copia dell'oggetto.
  6. Rimuovi il canale di notifica
    Rimuovi il canale di notifica specificando gli identificatori di canale e di risorsa restituiti quando hai inviato il comando di notifica per guardare il bucket.
    gsutil notification stopchannel CHANNEL_ID RESOURCE_IDENTIFIER