Search code examples
javaazureazure-blob-storageazure-storage

Java Code works to transfer within one Azure Storage Account but not between two Azure Storage Accounts


The following java code works to copy files within one Azure Storage Account, including from one container to another.

    // Create BlobContainerClient for source container
    BlobContainerClient sourceContainerClient = new BlobServiceClientBuilder()
            .connectionString(sourceConnectionString).buildClient().getBlobContainerClient(sourceContainerName);

    // Create BlobContainerClient for destination container
    BlobContainerClient destinationContainerClient = new BlobServiceClientBuilder()
            .connectionString(destinationConnectionString).buildClient()
            .getBlobContainerClient(destinationContainerName);

    //copy file from one container to another
    BlobClient sourceBlobClient = sourceContainerClient.getBlobClient(fileName);
    BlobClient destinationBlobClient = destinationContainerClient.getBlobClient(fileName);
    destinationBlobClient.beginCopy(sourceBlobClient.getBlobUrl(), null);

It does not work between two Azure Storage Accounts, and returns

Exception in thread "main" com.azure.storage.blob.models.BlobStorageException: Status code 401, "<?xml version="1.0" encoding="utf-8"?><Error><Code>CannotVerifyCopySource</Code><Message>Server failed to authenticate the request. Please refer to the information in the www-authenticate header.
RequestId:f54b4ee3-201e-0021-21aa-44577d000000
Time:2024-01-11T16:24:13.9394320Z</Message></Error>"
    at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:728)
    at com.azure.core.implementation.MethodHandleReflectiveInvoker.invokeWithArguments(MethodHandleReflectiveInvoker.java:35)

Any ideas how to fix this? I have two Azure Storage Accounts A and B. It works within A, and within B, but just not between A and B.


Solution

  • I have two Azure Storage Accounts A and B. They work within A, and within B, but just not between A and B.

    You can use the below code to copy a blob from one storage account to another storage account using Azure Java SDK.

    Code:

    import com.azure.storage.blob.BlobServiceClientBuilder;
    import java.time.OffsetDateTime;
    import com.azure.storage.blob.BlobClient;
    import com.azure.storage.blob.sas.BlobSasPermission;
    import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
    
    public class App 
    {
        public static void main( String[] args )
        {
            String sourceConnectionString = "xxx";
            String destConnectionString = "xxxx";
            String sourceContainerName = "block-image";
            String destContainerName = "test";
            String sourceBlobName = "bike.png";
            String destBlobName = "sample.png";
            
            // Initialize source and destination clients
            BlobClient sourceBlobClient = new BlobServiceClientBuilder().connectionString(sourceConnectionString)
                    .buildClient().getBlobContainerClient(sourceContainerName).getBlobClient(sourceBlobName);
            BlobClient destBlobClient = new BlobServiceClientBuilder().connectionString(destConnectionString)
                    .buildClient().getBlobContainerClient(destContainerName).getBlobClient(destBlobName);
    
            OffsetDateTime sasExpiry = OffsetDateTime.now().plusMinutes(1);
            BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
            BlobServiceSasSignatureValues sas = new BlobServiceSasSignatureValues(sasExpiry, permission);
            String sourceURL = sourceBlobClient.getBlobUrl() + "?" + sourceBlobClient.generateSas(sas);
    
            destBlobClient.beginCopy(sourceURL,null);
            
            System.out.println("Blob copied from one storage account to another storage account");
        }
    }
    

    Output:

    Blob copied from one storage account to another storage account
    

    enter image description here

    Portal:

    enter image description here

    Reference: