Copiar um blob com agendamento assíncrono usando Go

Este artigo mostra como copiar um blob com agendamento assíncrono usando o módulo de cliente do Armazenamento do Azure para Go. Você pode copiar um blob de uma fonte dentro da mesma conta de armazenamento, de uma fonte em uma conta de armazenamento diferente ou de qualquer objeto acessível recuperado via solicitação HTTP GET em uma determinada URL. Você também pode abortar uma operação de cópia pendente.

Os métodos abordados neste artigo usam a operação Copy Blob REST API e podem ser usados quando você deseja executar uma cópia com agendamento assíncrono. Para a maioria dos cenários de cópia em que você deseja mover dados para uma conta de armazenamento e ter uma URL para o objeto de origem, consulte Copiar um blob de uma URL de objeto de origem com Go.

Pré-requisitos

Configurar o ambiente

Se você não tiver um projeto existente, esta seção mostra como configurar um projeto para trabalhar com o módulo de cliente de Armazenamento de Blob do Azure para Go. As etapas incluem a instalação do módulo, a adição de import caminhos e a criação de um objeto de cliente autorizado. Para obter detalhes, consulte Introdução ao Armazenamento de Blobs do Azure e Go.

Instalar módulos

Instale o módulo azblob usando o seguinte comando:

go get github.com/Azure/azure-sdk-for-go/sdk/storage/azblob

Para autenticar com o Microsoft Entra ID (recomendado), instale o azidentity módulo usando o seguinte comando:

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

Adicionar caminhos de importação

No arquivo de código, adicione os seguintes caminhos de importação:

import (
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

Esses caminhos de importação representam o mínimo necessário para começar. Alguns exemplos de código neste artigo podem exigir caminhos de importação adicionais. Para obter detalhes específicos e exemplos de uso, consulte Exemplos de código.

Criar um objeto cliente

Para conectar um aplicativo ao Armazenamento de Blob, crie um objeto cliente usando azblob. NewClient. O exemplo a seguir mostra como criar um objeto cliente usando DefaultAzureCredential para autorização:

func getServiceClientTokenCredential(accountURL string) *azblob.Client {
    // Create a new service client with token credential
    credential, err := azidentity.NewDefaultAzureCredential(nil)
    handleError(err)

    client, err := azblob.NewClient(accountURL, credential, nil)
    handleError(err)

    return client
}

Autorização

O mecanismo de autorização deve ter as permissões necessárias para executar uma operação de cópia ou para anular uma cópia pendente. Para autorização com o Microsoft Entra ID (recomendado), você precisa da função interna do RBAC do Azure RBAC Storage Blob Data Contributor ou superior. Para saber mais, consulte as diretrizes de autorização para Copiar Blob ou Abortar Blob de Cópia.

Sobre a cópia de blobs com agendamento assíncrono

A Copy Blob operação pode ser concluída de forma assíncrona e é executada com base no melhor esforço, o que significa que não é garantido que a operação comece imediatamente ou seja concluída dentro de um período de tempo especificado. A operação de cópia é agendada em segundo plano e executada à medida que o servidor tem recursos disponíveis. A operação pode ser concluída de forma síncrona se a cópia ocorrer na mesma conta de armazenamento.

Uma Copy Blob operação pode executar qualquer uma das seguintes ações:

  • Copie um blob de origem para um blob de destino com um nome diferente. O blob de destino pode ser um blob existente do mesmo tipo de blob (bloco, acréscimo ou página), ou pode ser um novo blob criado pela operação de cópia.
  • Copie um blob de origem para um blob de destino com o mesmo nome, que substitui o blob de destino. Esse tipo de operação de cópia remove quaisquer blocos não confirmados e substitui os metadados do blob de destino.
  • Copie um arquivo de origem no serviço de Arquivo do Azure para um blob de destino. O blob de destino pode ser um blob de bloco existente ou pode ser um novo blob de bloco criado pela operação de cópia. Não há suporte para copiar de arquivos para blobs de página ou acrescentar blobs.
  • Copie um instantâneo sobre seu blob base. Ao promover um instantâneo para a posição do blob base, você pode restaurar uma versão anterior de um blob.
  • Copie um instantâneo para um blob de destino com um nome diferente. O blob de destino resultante é um blob gravável e não um instantâneo.

O blob de origem para uma operação de cópia pode ser um dos seguintes tipos: blob de bloco, blob de acréscimo, blob de página, instantâneo de blob ou versão de blob. A operação de cópia sempre copia todo o blob ou arquivo de origem. Não há suporte para copiar um intervalo de bytes ou um conjunto de blocos.

Se o blob de destino já existir, ele deverá ser do mesmo tipo de blob que o blob de origem e o blob de destino existente será substituído. O blob de destino não pode ser modificado enquanto uma operação de cópia estiver em andamento, e um blob de destino só pode ter uma operação de cópia pendente.

Para saber mais sobre a Copy Blob operação, incluindo informações sobre propriedades, marcas de índice, metadados e cobrança, consulte Copiar comentários de Blob.

Copiar um blob com agendamento assíncrono

Esta seção fornece uma visão geral dos métodos fornecidos pelo módulo de cliente de Armazenamento do Azure para Go para executar uma operação de cópia com agendamento assíncrono.

Os métodos a seguir encapsulam a operação Copy Blob REST API e iniciam uma cópia assíncrona dos dados do blob de origem:

Copiar um blob de uma fonte no Azure

Se você estiver copiando um blob dentro da mesma conta de armazenamento, a operação poderá ser concluída de forma síncrona. O acesso ao blob de origem pode ser autorizado por meio do Microsoft Entra ID (recomendado), uma assinatura de acesso compartilhado (SAS) ou uma chave de conta. Para uma operação de cópia síncrona alterativa, consulte Copiar um blob de uma URL de objeto de origem com Go.

Se a origem da cópia for um blob em uma conta de armazenamento diferente, a operação poderá ser concluída de forma assíncrona. O blob de origem deve ser público ou autorizado via token SAS. O token SAS precisa incluir a permissão Read ('r'). Para saber mais sobre tokens SAS, consulte Delegar acesso com assinaturas de acesso compartilhado.

O exemplo a seguir mostra um cenário para copiar um blob de origem de uma conta de armazenamento diferente com agendamento assíncrono. Neste exemplo, criamos uma URL de blob de origem com um token SAS de delegação de usuário anexado. O exemplo pressupõe que você forneça seu próprio SAS. O exemplo também mostra como conceder o blob de origem durante a operação de cópia para evitar alterações no blob de um cliente diferente. A Copy Blob operação salva o ETag valor do blob de origem quando a operação de cópia é iniciada. Se o ETag valor for alterado antes da conclusão da operação de cópia, a operação falhará. Também definimos a camada de acesso para o blob de destino para Cool usar a estrutura StartCopyFromURLOptions .

func copyFromSourceAsync(srcBlob *blockblob.Client, destBlob *blockblob.Client) {
    // Lease the source blob during copy to prevent other clients from modifying it
    blobLeaseClient, err := lease.NewBlobClient(srcBlob, nil)
    handleError(err)

    _, err = blobLeaseClient.AcquireLease(context.TODO(), int32(60), nil)
    handleError(err)

    // Retrieve the SAS token for the source blob and append it to the URL
    sas := "<sas-token>"
    url := srcBlob.URL() + "?" + sas

    // Set copy options
    copyOptions := blob.StartCopyFromURLOptions{
        Tier: to.Ptr(blob.AccessTierCool),
    }

    // Copy the blob from the source URL to the destination blob
    startCopy, err := destBlob.StartCopyFromURL(context.TODO(), url, &copyOptions)
    handleError(err)

    // If startCopy.CopyStatus returns a status of "pending", the operation has started asynchronously
    // You can optionally add logic to poll the copy status and wait for the operation to complete
    // Example:
    copyStatus := *startCopy.CopyStatus
    for copyStatus == blob.CopyStatusTypePending {
        time.Sleep(time.Second * 2)

        properties, err := destBlob.GetProperties(context.TODO(), nil)
        handleError(err)

        copyStatus = *properties.CopyStatus
    }

    // Release the lease on the source blob
    _, err = blobLeaseClient.ReleaseLease(context.TODO(), nil)
    handleError(err)
}

O exemplo a seguir mostra o uso de exemplo:

// TODO: replace <storage-account-name> placeholders with actual storage account names
srcURL := "https://<src-storage-account-name>.blob.core.windows.net/"
destURL := "https://<dest-storage-account-name>.blob.core.windows.net/"

credential, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

srcClient, err := azblob.NewClient(srcURL, credential, nil)
handleError(err)
destClient, err := azblob.NewClient(destURL, credential, nil)
handleError(err)

srcBlob := srcClient.ServiceClient().NewContainerClient("source-container").NewBlockBlobClient("source-blob")
destBlob := destClient.ServiceClient().NewContainerClient("destination-container").NewBlockBlobClient("destination-blob-1")

copyFromSourceAsync(srcBlob, destBlob)

Nota

Os tokens SAS de delegação de usuários oferecem maior segurança, pois são assinados com credenciais do Microsoft Entra em vez de uma chave de conta. Para criar um token SAS de delegação de usuário, a entidade de segurança do Microsoft Entra precisa de permissões apropriadas. Para obter os requisitos de autorização, consulte Obter chave de delegação de usuário.

Copiar um blob de uma fonte fora do Azure

Você pode executar uma operação de cópia em qualquer objeto de origem que possa ser recuperado por meio da solicitação HTTP GET em uma determinada URL, incluindo objetos acessíveis fora do Azure. O exemplo a seguir mostra um cenário para copiar um blob de uma URL de objeto de origem acessível:

func copyFromExternalSourceAsync(srcURL string, destBlob *blockblob.Client) {
    // Set copy options
    copyOptions := blob.StartCopyFromURLOptions{
        Tier: to.Ptr(blob.AccessTierCool),
    }

    // Copy the blob from the source URL to the destination blob
    startCopy, err := destBlob.StartCopyFromURL(context.TODO(), srcURL, &copyOptions)
    handleError(err)

    // If startCopy.CopyStatus returns a status of "pending", the operation has started asynchronously
    // You can optionally add logic to poll the copy status and wait for the operation to complete
    // Example:
    copyStatus := *startCopy.CopyStatus
    for copyStatus == blob.CopyStatusTypePending {
        time.Sleep(time.Second * 2)

        properties, err := destBlob.GetProperties(context.TODO(), nil)
        handleError(err)

        copyStatus = *properties.CopyStatus
    }
}

O exemplo a seguir mostra o uso de exemplo:

externalURL := "<source-url>"

destBlob = destClient.ServiceClient().NewContainerClient("destination-container").NewBlockBlobClient("destination-blob-2")

copyFromExternalSourceAsync(externalURL, destBlob)

Verificar o status de uma operação de cópia

Para verificar o status de uma operação assíncrona Copy Blob , você pode sondar o método GetProperties e verificar o status da cópia.

O exemplo de código a seguir mostra como verificar o status de uma operação de cópia:

func checkCopyStatus(destBlob *blockblob.Client) {
    // Retrieve the properties from the destination blob
    properties, err := destBlob.GetProperties(context.TODO(), nil)
    handleError(err)

    copyID := *properties.CopyID
    copyStatus := *properties.CopyStatus

    fmt.Printf("Copy operation %s is %s\n", copyID, copyStatus)
}

Anular uma operação de cópia

Abortar uma operação pendente Copy Blob resulta em um blob de destino de comprimento zero. No entanto, os metadados para o blob de destino têm os novos valores copiados do blob de origem ou definidos explicitamente durante a operação de cópia. Para manter os metadados originais de antes da cópia, faça um instantâneo do blob de destino antes de chamar um dos métodos de cópia.

Para anular uma operação de cópia pendente, chame a seguinte operação:

Esse método encapsula a operação Abort Copy Blob REST API, que cancela uma operação pendente Copy Blob . O exemplo de código a seguir mostra como abortar uma operação pendente Copy Blob :

func abortCopy(destBlob *blockblob.Client) {
    // Retrieve the copy ID from the destination blob
    properties, err := destBlob.GetProperties(context.TODO(), nil)
    handleError(err)

    copyID := *properties.CopyID
    copyStatus := *properties.CopyStatus

    // Abort the copy operation if it's still pending
    if copyStatus == blob.CopyStatusTypePending {
        _, err := destBlob.AbortCopyFromURL(context.TODO(), copyID, nil)
        handleError(err)

        fmt.Printf("Copy operation %s aborted\n", copyID)
    }
}

Recursos

Para saber mais sobre como copiar blobs com agendamento assíncrono usando o módulo de cliente de Armazenamento de Blobs do Azure para Go, consulte os recursos a seguir.

Amostras de código

Operações da API REST

O SDK do Azure para Go contém bibliotecas que se baseiam na API REST do Azure, permitindo que você interaja com operações da API REST por meio de paradigmas Go familiares. Os métodos abordados neste artigo usam as seguintes operações de API REST:

Recursos do módulo cliente

  • Este artigo faz parte do guia do desenvolvedor do Blob Storage para Go. Para saber mais, consulte a lista completa de artigos do guia do desenvolvedor em Crie seu aplicativo Go.