Notificação de alteração de objetos


Use a notificação de alteração de objetos para informar a um aplicativo que um objeto foi atualizado ou adicionado a um intervalo.

Esse recurso é diferente das notificações do Cloud Pub/Sub para Cloud Storage, que são o método recomendado para monitorar as alterações em objetos de intervalos do Cloud Storage por serem mais rápidas, flexíveis, fáceis de configurar e econômicas.

Como funciona a notificação de alteração de objetos

Um aplicativo cliente pode enviar uma solicitação para monitorar as alterações nos objetos de um determinado intervalo.

Para concluir uma solicitação de monitoramento, é necessário criar um novo canal de notificação. Um canal de notificação é o meio usado para enviar uma mensagem de notificação a um aplicativo que está monitorando um intervalo. Atualmente, há apenas um tipo de canal de notificação compatível, o webhook.

Depois que um canal de notificação é inicializado, o Cloud Storage notifica o aplicativo sempre que um objeto é adicionado, atualizado ou removido do intervalo. Por exemplo, quando você adiciona uma nova imagem a um intervalo, um aplicativo pode ser notificado para criar uma miniatura.

Na figura abaixo é apresentado um exemplo de fluxo de dados para um aplicativo que processa notificações de alteração. Qualquer servidor de aplicativos que possa receber solicitações HTTPS POST pode ser usado para processar notificações de alteração.

Componentes da notificação de alteração de objetos
Componentes da notificação de alteração de objetos

Detalhes da notificação de alteração de objetos

Terminologia

A tabela a seguir contém uma descrição de vários termos usados na documentação da notificação de alteração de objetos:

Termo Descrição
URL do aplicativo O URL do seu aplicativo. É o endereço de destino das notificações que serão enviadas. Ele precisa ser um URL HTTPS. URLs HTTP não são permitidos.
Identificador do canal O identificador do canal de notificação. Ele precisa ser exclusivo dentro do intervalo, ou seja, se houver vários canais de notificação em um único intervalo, cada um precisa ter um identificador diferente. Esse identificador será enviado ao seu aplicativo com cada mensagem de notificação.
Identificador do recurso Um identificador opaco do recurso que está sendo monitorado. O identificador do recurso é necessário para interromper um canal de notificação. É possível recuperar esse identificador na resposta de uma solicitação de monitoramento ou no cabeçalho X-Goog-Resource-Id das mensagens de evento de notificação.
Token do cliente (Opcional) Os tokens do cliente podem ser usados para validar os eventos de notificação. Para fazer isso, defina um token do cliente personalizado na solicitação de monitoramento. As mensagens de notificação incluirão esse token para que você verifique se são autênticas.

Como monitorar um intervalo

Para começar a monitorar eventos de notificação de alteração em um intervalo, use o comando gsutil notification watchbucket:

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

Isso criará um canal de notificação que envia eventos de notificação para o URL do aplicativo definido para esse intervalo. O canal de notificação incluirá o token do cliente personalizado e o identificador do canal, quando especificados.

Para mais informações, execute o comando gsutil help notification watchbucket.

Veja abaixo um exemplo de solicitação POST gerada pela gsutil para monitorar um intervalo:

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

Autorização de notificação

Durante o monitoramento do intervalo, o canal de notificação que está sendo criado será associado ao projeto no Console do Google Cloud Platform correspondente ao aplicativo que iniciou a solicitação de API. Isso significa que, por exemplo, se um usuário conceder acesso a um aplicativo instalado ou da Web por meio de um fluxo OAuth2, o canal de notificação criado pelo aplicativo será associado ao projeto do aplicativo, e não ao projeto que contém o intervalo que será monitorado.

Em um cenário de notificação de alteração de objetos, há três etapas para configurar a autorização:

Como criar uma conta de serviço

Como a conta de serviço está associada ao projeto, usá-la para monitorar um intervalo criará um canal de notificação nesse projeto.

Use uma conta de serviço atual ou crie uma nova e faça o download da chave privada associada a ela.

Como configurar a gsutil para usar a conta de serviço

Para configurar a gsutil para usar a conta de serviço, use o SDK do Google Cloud para adicionar a conta de serviço como uma conta credenciada para trabalhar com recursos do Google Cloud Platform, incluindo a notificação de alteração de objetos. Depois de adicionar as credenciais, todos os comandos subsequentes da gsutil usarão as credenciais da conta de serviço.

Para criar credenciais baseadas na conta de serviço:

  1. Verifique se você tem a versão mais recente do SDK do Cloud. Para atualizar os componentes, execute:
    gcloud components update
    
  2. Use o comando gcloud auth activate-service-account e especifique o endereço de e-mail e a chave privada da conta de serviço.
    gcloud auth activate-service-account service-account-email --key-file path/to/key.p12
    

    em que:

    • service-account-email é o endereço de e-mail da conta de serviço, Você verá algo parecido com: 1234567890123-abcdefghijklmonpqrstuvwxz01234567@developer.gserviceaccount.com;
    • path/to/key.p12 é a chave que você foi solicitado a fazer o download quando criou a conta de serviço. Se você perdeu a chave, volte para a página Credenciais no Console do Google Cloud Platform e gere uma nova.
  3. Confirme se a conta de serviço é a conta credenciada ativa.
    $ gcloud auth list
    Credentialed accounts:
    - 1234567890123-abcdefghijklmonpqrstuvwxz01234567@developer.gserviceaccount.com (active)
    

    Você verá active ao lado das credenciais da conta de serviço. Agora, todos os comandos de notificação de objetos da gsutil que forem executados usarão as credenciais da conta de serviço.

Como identificar um domínio para receber notificações

As solicitações de observação só funcionarão se o URL de notificação for um domínio permitido pelo projeto do canal de notificação.

Para colocar um domínio na lista de permissões:

  1. Verifique se você é proprietário do domínio usando o processo de verificação do Search Console.
  2. No Console do GCP, acesse a guia Confirmação de domínio, na página Credenciais.

    Acessar a página Credenciais

  3. Clique em Adicionar domínio.
  4. Na caixa de diálogo Configurar notificações de webhook, digite o domínio a ser verificado.

    Caixa de diálogo "Configurar notificações de webhook"

  5. Clique em Adicionar domínio.

    Para resolver problemas com a confirmação de domínio:

    • O domínio precisa estar registrado no Search Console com um URL https:// ou ter sido confirmado com o método de confirmação Provedor de nome de domínio.
    • Verifique se você é proprietário ou editor do projeto do Console do GCP (consulte Membros e permissões do projeto), além de ser o proprietário do site no domínio que receberá notificações. Se você não é proprietário do site, entre em contato com o proprietário do domínio para ser adicionado como proprietário verificado. Consulte Adicionar ou remover proprietários.
    • É possível usar APIs Explorer do Google para Ferramentas do Google para webmasters a fim de listar sites no domínio e, principalmente, ver se a propriedade siteUrl do domínio começa com https://.

Como remover um canal de notificação

Para interromper um canal de notificação, use o comando gsutil notification stopchannel:

gsutil notification stopchannel ChannelId ResourceId

Isso interromperá todos os eventos de notificação para o par de identificadores do recurso e do canal especificados. Outros canais ativos do mesmo recurso não serão afetados. Os identificadores do recurso e do canal estão na resposta da solicitação de monitoramento ou no corpo das mensagens de evento de notificação.

Para mais informações, execute o comando gsutil help notification stopchannel.

Veja abaixo um exemplo de solicitação POST gerada pela gsutil para interromper um 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 mensagem de evento de notificação

Sincronização

Após a emissão de uma solicitação de monitoramento, um canal de notificação novo é criado e um evento de notificação é enviado. Depois de receber o evento de sincronização, todas as alterações posteriores no intervalo serão enviadas ao URL do aplicativo configurado para o canal.

A notificação será enviada ao URL configurado para o aplicativo como uma solicitação POST. A solicitação não tem corpo. Os metadados da notificação de sincronização estão contidos nos cabeçalhos da solicitação. Veja abaixo um exemplo de solicitação de notificação de sincronização:

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
Adição, atualização ou exclusão de objetos

Um evento de notificação é enviado quando um objeto novo é adicionado a um intervalo, quando o conteúdo ou os metadados de um objeto atual são modificados ou quando um objeto é excluído de um intervalo.

A notificação será enviada ao URL configurado para o aplicativo como uma solicitação POST. O corpo da solicitação contém uma mensagem em código JSON, conforme mostrado na solicitação de notificação a seguir:

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="
}
em que ResourceState é:
  • exists: para adições e atualizações de objetos;
  • not_exists: para exclusões de objetos.

O conteúdo da mensagem JSON incluirá a representação atual do objeto, conforme descrito na descrição do recurso Object.

Entrega confiável

A notificação de alteração de objeto tentará enviar notificações para seu aplicativo de maneira confiável. No entanto, as notificações podem sofrer atrasos indefinidamente e a pontualidade não é garantida. Como seu aplicativo talvez nem sempre estará disponível, as regras a seguir determinam como ocorre a entrega de notificações:

  • Se a tentativa de entrega de uma notificação falhar, serão feitas novas tentativas. O intervalo entre as novas tentativas de entrega é determinado por um algoritmo de espera exponencial, que começa com uma nova tentativa 30 segundos após a falha inicial. As demais tentativas de entrega subsequentes são feitas em intervalos crescentes, até o máximo de 90 minutos. Observe que os intervalos entre novas tentativas são um pouco aleatórios. Portanto, eles não ocorrem em valores exponenciais exatos. Depois que for atingido o intervalo máximo de 90 minutos, as tentativas subsequentes serão feitas a cada 90 minutos por sete dias. Se não for possível entregar a notificação nesse período, ela será limpa.
  • Caso não seja possível se comunicar com seu aplicativo após 20 segundos ou se ele responder com um dos códigos de resposta HTTP a seguir, a tentativa de entrega de notificação será tratada como uma falha e uma nova tentativa será feita:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Se seu aplicativo responder com um dos códigos de resposta HTTP a seguir, a notificação será tratada como entregue:
    • 102 Processing
    • 200 OK
    • 201 Created
    • 202 Accepted
    • 204 No Content
  • Quaisquer outros códigos de resposta HTTP retornados pelo aplicativo são tratados como falhas permanentes. Nesses casos, não são feitas novas tentativas.

Exemplo de aplicativo cliente

Nesta seção, explicamos como criar um aplicativo cliente do App Engine que processa eventos de notificação de alteração.

A figura a seguir mostra a linha do tempo dos eventos básicos envolvidos no recebimento de uma notificação, desde a criação de um intervalo até o processamento dos eventos de notificação de alteração relacionados:

Linha do tempo da notificação de alteração de objetos
Linha do tempo da notificação de alteração de objetos

O aplicativo do exemplo contém uma classe chamada MainPage. Quando o usuário atualiza ou adiciona um objeto ao intervalo, a classe MainPage processa o evento de notificação. Para simplificar, o método post que faz o processamento real registra uma mensagem com o horário em que a notificação foi recebida. É possível substituir esse código pela lógica de processamento que você de fato usa. Caso você ainda não se sinta à vontade para desenvolver aplicativos do App Engine, tente implantar uma amostra de aplicativo ou seguir um tutorial antes de continuar.

  1. Configurar o aplicativo
    Crie o arquivo de configuração app.yaml para especificar o aplicativo cliente que processa os eventos de notificação de alteração do intervalo.
    application: <ApplicationId>
    version: 1
    runtime: python27
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: change_notification_client.app
    
  2. Como criar o aplicativo.
    Veja no exemplo a seguir como implementar um aplicativo cliente para o processamento de eventos de notificação de alteração de um intervalo. Dê a ele o nome de change_notification_client.py e implante-o:
    """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. Como atribuir a permissão de acesso do aplicativo ao intervalo.
    Se seu intervalo pertencer a uma conta de serviço diferente do seu aplicativo do App Engine, execute o comando a seguir para conceder ao intervalo o acesso de PROPRIETÁRIO do aplicativo:
    gsutil acl ch -u ApplicationId@appspot.gserviceaccount.com:OWNER gs://BucketName
    
  4. Como começar a monitorar alterações de objetos do intervalo
    Monitore o intervalo com a gsutil para criar um canal de notificação para seu aplicativo:
    gsutil notification watchbucket ApplicationUrl gs://BucketName
    
    em que ApplicationUrl é o URL do seu aplicativo do App Engine. Por exemplo, https://ApplicationId.appspot.com/.
  5. Como testar o aplicativo
    Para ver se o aplicativo funciona conforme esperado, execute estas etapas:
    1. Para garantir que o aplicativo foi implantado e funciona corretamente, execute o comando curl a seguir:
      curl -X Post https://<ApplicationId>.appspot.com
      
      Caso você tenha usado seu próprio nome de domínio para implantar o aplicativo, use-o em vez de appspot.com no comando anterior.
    2. Acesse a página do Stackdriver Logging do seu projeto. Atualize a lista das mensagens registradas, se necessário. Verifique se a mensagem de registro emitida pelo aplicativo foi registrada.
    3. Adicione um objeto ao intervalo. Você pode usar a ferramenta gsutil da seguinte maneira:
      gsutil cp ObjectName gs://BucketName/
      
      O Cloud Storage notifica o aplicativo que, em seguida, registra uma mensagem.
    4. Acesse a página do Stackdriver Logging do seu projeto. Atualize a lista de mensagens registradas e encontre aquela referente à cópia do objeto.
  6. Como remover o canal de notificação
    Remova o canal de notificação especificando os identificadores do canal e do recurso que foram retornados quando você emitiu o comando de notificação para monitorar intervalo.
    gsutil notification stopchannel <channel_id> <resource_identifier>
    

Voltar ao início

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.