0

Im having an issue related to the rehydration process while I'm trying to make a copy of one blob to another account.

I have two different clients, one for the source and other one for the dest:

BlobClient blobMeta = sourceClient.getBlobContainerClient(source.getContainer()).getBlobClient(key);
BlobClient destObject = destClient.getBlobContainerClient(dest.getContainer()).getBlobClient(key);

As I read in the docs, for doing a copy in a different account, you should add the SAS token ("If the source is in another account, the source must either be public or authenticated with a SAS token."), so...

OffsetDateTime sasExpiry = OffsetDateTime.now().plusMinutes(1);
BlobSasPermission permission = new BlobSasPermission().setReadPermission(true);
BlobServiceSasSignatureValues sas = new BlobServiceSasSignatureValues(sasExpiry,permission).setStartTime(OffsetDateTime.now());
String sourceURL = blobMeta.getBlobUrl() + "?" + blobMeta.generateSas(sas);

Once I have the different blobs and the SAS token I continue with the beginCopy operation setting the new options for the rehydration process (from Archive to Cool and the priority):

destObject.beginCopy(sourceURL, blobMeta.getProperties().getMetadata(), AccessTier.COOL, RehydratePriority.STANDARD, null, null, null);

Everything seems working properly but, this line creates directly the files with an 0B of size and there is no waiting time for rehydrate process (obviously is not doing anything, just copying empty info. However, the metadata is properly assigned). For the same account in a different container, everything works fine. Moreover, copying without adding the rehydration info (when the files are not stored in an archive tier) works fine too.

Does someone have any idea about what can be happening here?

Thank you!

I tried what I added above and I expect to copy the data with the correct size and content.

PD: The issue was the different region of the accounts. Begincopy method with the hydration process is not supported yet. For doing this, is necessary setting the tier to Cool / Hot in the original account and then, doing the copy.

  • Hi, @Vicente Montoro Try to add while creating a sas token with list permission like `BlobSasPermission permission = new BlobSasPermission().setReadPermission(true).setListPermission(true); ` – Venkatesan Aug 22 '23 at 03:06
  • Hey @Venkatesan! Thanks for your quick answer. However, the behaviour is the same. I continue having a 0B file with no content. – Vicente Montoro Aug 22 '23 at 08:40
  • Hi @Vicento Montoro I tried with sample code https://i.imgur.com/IgTx3rT.png it copied succesfully with content https://i.imgur.com/4Ecf4Q5.png. – Venkatesan Aug 22 '23 at 08:48
  • Ok, @Venkatesan, ill try it again but... do you have your source as public? When i try to get the archive status: desObject.getProperties().getArchiveStatus(); ArchiveStatus.REHYDRATE_PENDING_TO_COOL.equals(status) I receive a null (thats why its not rehydrating) Thank you again! – Vicente Montoro Aug 22 '23 at 08:59

1 Answers1

0

You can use the below code to copy files with tier from one storage account to another storage account using Java SDK.

Code:

import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.models.AccessTier;
import com.azure.storage.blob.models.RehydratePriority;
import com.azure.storage.blob.sas.BlobSasPermission;
import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;

import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) {
        String sourceConnectionString = "sourceconnect-string";
        String destConnectionString = "destinationconnectstring";
        String sourceContainerName = "test";
        String destContainerName = "test1";
        String sourceBlobName = "sample326.txt";
        String destBlobName = "demo.txt";
        
        // 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);
        
        // Generate SAS token for source blob
        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);
        
        // Set metadata for destination blob
        Map<String, String> metadata = new HashMap<>();
        metadata.put("key", "value");
        
        // Perform the blob copy with rehydration
        destBlobClient.beginCopy(sourceURL, metadata, AccessTier.COOL, RehydratePriority.HIGH, null, null, null);
        
        System.out.println("Blob copy operation initiated with rehydration.");
    }
}

Output:

Blob copy operation initiated with rehydration.

enter image description here

Portal: enter image description here

Reference:

BlobClientBase Class | Microsoft Learn

Venkatesan
  • 3,748
  • 1
  • 3
  • 15
  • I have changed my way of doing it and now im receiving another issue: ERROR: null - Status code 500, "?CannotVerifyCopySourceCould not verify the copy source within the specified time. – Vicente Montoro Aug 22 '23 at 10:16
  • Make the source container public and now try https://stackoverflow.com/questions/73709699/azure-copy-blobs-across-storage-accounts-fails-with-errorcodecannotverifycopyso – Venkatesan Aug 22 '23 at 11:16
  • More updates: I realized that i was using an old version for the azure connection in my first tries. From V2021_02_12 the second error appears. Moreover, my container is private too so thats why i added the SAS token with readPermission true. I continue having the "Could not verify the copy source within the specified time." issue :( Thanks again for the answer! – Vicente Montoro Aug 22 '23 at 13:14
  • This is an example of my SAS route, maybe something missing: "https://accountName.blob.core.windows.net/container/route?sv=2023-01-03&se=2023-08-22T13%3A49%3A10Z&sr=b&sp=rl&sig=signature" – Vicente Montoro Aug 22 '23 at 13:54
  • The destination blob account URL should be in `https://< accountname >.blob.core.windows.net/< container name>/< BlobName >?< SAS-token >` – Venkatesan Aug 22 '23 at 14:41
  • Yep, thats what i have: blobDest.beginCopy(blobMeta.getBlobUrl() + "?" + blobMeta.generateSas(sas) --> "https:// accountName . blob . core . windows . net/container / route ? sv=2023-01-03&se=2023-08-22T13%3A49%3A10Z&sr=b&sp=rl&sig=signature" – Vicente Montoro Aug 22 '23 at 15:05
  • Copy and paste the blob url in the browser and see what you are getting? – Venkatesan Aug 22 '23 at 15:11
  • Have you tried my approach (my code)? – Venkatesan Aug 22 '23 at 15:17
  • i get this lol: BlobArchived This operation is not permitted on an archived blob. RequestId:0e48abe0-601e-0017-2d0b-d53889000000 Time:2023-08-22T15:18:22.5758820Z But i dont know why :S – Vicente Montoro Aug 22 '23 at 15:21
  • Yeah, i tested your code, thats why i realized about the connection's version. Thanks again for your help, by the way :) – Vicente Montoro Aug 22 '23 at 15:24
  • Refer this https://learn.microsoft.com/en-us/azure/storage/blobs/archive-rehydrate-overview – Venkatesan Aug 22 '23 at 15:52
  • 1
    Hey @Venkatesan! i finally found the issue. My accounts where in different region and its not supported for rehydrate begincopy method yet. Thanks for the help! – Vicente Montoro Aug 25 '23 at 08:36