Copy a blob with asynchronous scheduling using Java
This article shows how to copy a blob with asynchronous scheduling using the Azure Storage client library for Java. You can copy a blob from a source within the same storage account, from a source in a different storage account, or from any accessible object retrieved via HTTP GET request on a given URL. You can also abort a pending copy operation.
The client library methods covered in this article use the Copy Blob REST API operation, and can be used when you want to perform a copy with asynchronous scheduling. For most copy scenarios where you want to move data into a storage account and have a URL for the source object, see Copy a blob from a source object URL with Java.
Prerequisites
- Azure subscription - create one for free
- Azure storage account - create a storage account
- Java Development Kit (JDK) version 8 or later (we recommend version 17 for the best experience)
- Apache Maven is used for project management in this example
Set up your environment
If you don't have an existing project, this section shows you how to set up a project to work with the Azure Blob Storage client library for Java. For more information, see Get started with Azure Blob Storage and Java.
To work with the code examples in this article, follow these steps to set up your project.
Note
This article uses the Maven build tool to build and run the example code. Other build tools, such as Gradle, also work with the Azure SDK for Java.
Install packages
Open the pom.xml
file in your text editor. Install the packages by including the BOM file, or including a direct dependency.
Add import statements
Add the following import
statements:
import com.azure.core.util.polling.*;
import com.azure.storage.blob.*;
import com.azure.storage.blob.models.*;
import com.azure.storage.blob.options.*;
import com.azure.storage.blob.sas.BlobSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
import com.azure.storage.blob.specialized.*;
import java.time.*;
import java.util.*;
Authorization
The authorization mechanism must have the necessary permissions to perform a copy operation, or to abort a pending copy. For authorization with Microsoft Entra ID (recommended), the least privileged Azure RBAC built-in role varies based on several factors. To learn more, see the authorization guidance for Copy Blob (REST API) or Abort Copy Blob (REST API).
Create a client object
To connect an app to Blob Storage, create an instance of BlobServiceClient.
The following example uses BlobServiceClientBuilder to build a BlobServiceClient
object using DefaultAzureCredential
, and shows how to create container and blob clients, if needed:
// Azure SDK client builders accept the credential as a parameter
// TODO: Replace <storage-account-name> with your actual storage account name
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<storage-account-name>.blob.core.windows.net/")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
// If needed, you can create a BlobContainerClient object from the BlobServiceClient
BlobContainerClient containerClient = blobServiceClient
.getBlobContainerClient("<container-name>");
// If needed, you can create a BlobClient object from the BlobContainerClient
BlobClient blobClient = containerClient
.getBlobClient("<blob-name>");
To learn more about creating and managing client objects, see Create and manage client objects that interact with data resources.
About copying blobs with asynchronous scheduling
The Copy Blob
operation can finish asynchronously and is performed on a best-effort basis, which means that the operation isn't guaranteed to start immediately or complete within a specified time frame. The copy operation is scheduled in the background and performed as the server has available resources. The operation can complete synchronously if the copy occurs within the same storage account.
A Copy Blob
operation can perform any of the following actions:
- Copy a source blob to a destination blob with a different name. The destination blob can be an existing blob of the same blob type (block, append, or page), or it can be a new blob created by the copy operation.
- Copy a source blob to a destination blob with the same name, which replaces the destination blob. This type of copy operation removes any uncommitted blocks and overwrites the destination blob's metadata.
- Copy a source file in the Azure File service to a destination blob. The destination blob can be an existing block blob, or can be a new block blob created by the copy operation. Copying from files to page blobs or append blobs isn't supported.
- Copy a snapshot over its base blob. By promoting a snapshot to the position of the base blob, you can restore an earlier version of a blob.
- Copy a snapshot to a destination blob with a different name. The resulting destination blob is a writeable blob and not a snapshot.
To learn more about the Copy Blob
operation, including information about properties, index tags, metadata, and billing, see Copy Blob remarks.
Copy a blob with asynchronous scheduling
This section gives an overview of methods provided by the Azure Storage client library for Java to perform a copy operation with asynchronous scheduling.
The following method wraps the Copy Blob REST API operation, and begins an asynchronous copy of data from the source blob:
The beginCopy
method returns a SyncPoller to poll the progress of the copy operation. The poll response type is BlobCopyInfo. The beginCopy
method is used when you want asynchronous scheduling for a copy operation.
Copy a blob from a source within Azure
If you're copying a blob within the same storage account, the operation can complete synchronously. Access to the source blob can be authorized via Microsoft Entra ID, a shared access signature (SAS), or an account key. For an alterative synchronous copy operation, see Copy a blob from a source object URL with Java.
If the copy source is a blob in a different storage account, the operation can complete asynchronously. The source blob must either be public or authorized via SAS token. The SAS token needs to include the Read ('r') permission. To learn more about SAS tokens, see Delegate access with shared access signatures.
The following example shows a scenario for copying a source blob from a different storage account with asynchronous scheduling. In this example, we create a source blob URL with an appended user delegation SAS token. The example shows how to generate the SAS token using the client library, but you can also provide your own. The example also shows how to lease the source blob during the copy operation to prevent changes to the blob from a different client. The Copy Blob
operation saves the ETag
value of the source blob when the copy operation starts. If the ETag
value is changed before the copy operation finishes, the operation fails.
public void copyBlobAcrossStorageAccounts(BlobClient sourceBlob, BlockBlobClient destinationBlob) {
// Lease the source blob during copy to prevent other clients from modifying it
BlobLeaseClient lease = new BlobLeaseClientBuilder()
.blobClient(sourceBlob)
.buildClient();
// Create a SAS token for the source blob or use an existing one
String sasToken = generateUserDelegationSAS(
sourceBlob.getContainerClient().getServiceClient(),
sourceBlob);
// Get the source blob URL and append the SAS token
String sourceBlobSasURL = sourceBlob.getBlobUrl() + "?" + sasToken;
try {
// Specifying -1 creates an infinite lease
lease.acquireLease(-1);
// Start the copy operation and wait for it to complete
final SyncPoller<BlobCopyInfo, Void> poller = destinationBlob.beginCopy(
sourceBlobSasURL,
Duration.ofSeconds(2));
PollResponse<BlobCopyInfo> response = poller.waitUntil(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED);
} finally {
// Release the lease once the copy operation completes
lease.releaseLease();
}
}
public String generateUserDelegationSAS(BlobServiceClient blobServiceClient, BlobClient sourceBlob) {
// Get a user delegation key
OffsetDateTime delegationKeyStartTime = OffsetDateTime.now();
OffsetDateTime delegationKeyExpiryTime = OffsetDateTime.now().plusDays(1);
UserDelegationKey key = blobServiceClient.getUserDelegationKey(
delegationKeyStartTime,
delegationKeyExpiryTime);
// Create a SAS token that's valid for one day, as an example
OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
// Set the Read (r) permission on the SAS token
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues sasValues = new BlobServiceSasSignatureValues(expiryTime, permission)
.setStartTime(OffsetDateTime.now());
// Create a SAS token that's valid for one day
String sasToken = sourceBlob.generateUserDelegationSas(sasValues, key);
return sasToken;
}
Note
User delegation SAS tokens offer greater security, as they're signed with Microsoft Entra credentials instead of an account key. To create a user delegation SAS token, the Microsoft Entra security principal needs appropriate permissions. For authorization requirements, see Get User Delegation Key.
Copy a blob from a source outside of Azure
You can perform a copy operation on any source object that can be retrieved via HTTP GET request on a given URL, including accessible objects outside of Azure. The following example shows a scenario for copying a blob from an accessible source object URL.
public void copyFromExternalSourceAsyncScheduling(String sourceURL, BlockBlobClient destinationBlob) {
// Start the copy operation and wait for it to complete
final SyncPoller<BlobCopyInfo, Void> poller = destinationBlob.beginCopy(
sourceURL,
Duration.ofSeconds(2));
PollResponse<BlobCopyInfo> response = poller.waitUntil(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED);
}
Check the status of a copy operation
To check the status of a Copy Blob
operation, you can call getCopyStatus on the BlobCopyInfo object returned by SyncPoller
.
The following code example shows how to check the status of a copy operation:
public void checkCopyStatus(BlobCopyInfo copyInfo) {
// Check the status of the copy operation
System.out.printf("Copy status", copyInfo.getCopyStatus());
}
Abort a copy operation
Aborting a pending Copy Blob
operation results in a destination blob of zero length. However, the metadata for the destination blob has the new values copied from the source blob or set explicitly during the copy operation. To keep the original metadata from before the copy, make a snapshot of the destination blob before calling one of the copy methods.
To abort a pending copy operation, call the following method:
This method wraps the Abort Copy Blob REST API operation, which cancels a pending Copy Blob
operation. The following code example shows how to abort a pending Copy Blob
operation:
public void abortCopy(BlobCopyInfo copyInfo, BlobClient destinationBlob) {
// Check the copy status and abort if pending
if (copyInfo.getCopyStatus() == CopyStatusType.PENDING) {
destinationBlob.abortCopyFromUrl(copyInfo.getCopyId());
System.out.printf("Copy operation %s has been aborted%n", copyInfo.getCopyId());
}
}
Resources
To learn more about copying blobs using the Azure Blob Storage client library for Java, see the following resources.
Code samples
REST API operations
The Azure SDK for Java contains libraries that build on top of the Azure REST API, allowing you to interact with REST API operations through familiar Java paradigms. The client library methods covered in this article use the following REST API operations:
- Copy Blob (REST API)
- Abort Copy Blob (REST API)
Client library resources
Related content
- This article is part of the Blob Storage developer guide for Java. To learn more, see the full list of developer guide articles at Build your Java app.