I am using Node.js and the Azure SDK v12. I want to copy an existing blob with access tier==='Archive. To do so, I want to copy the blob and write it to the same container with a different blob name and a changed (rehydrated) access tier.
I could change the access tier of the existing 'Archived" blob directly, but that is not my goal. I want to keep the blob with access tier "Archive" and create a new blob with access tier==="Cool" || "Hot".
I am proceeding as per the documentation (https://learn.microsoft.com/en-us/azure/storage/blobs/archive-rehydrate-overview).
The below code works if the blob has access tier==='Cool' || 'Hot'. It fails for blobs with access tier==='Archive', though.
Aside: I think for SDK 'syncCopyFromUrl' and 'beginCopyFromUrl' do not work for copying blobs with access tier==='Archive'. I get the following errors if I try that: for 'syncCopyFromUrl' it gives me: "This operation is not permitted on an archived blob." For 'beginCopyFromUrl" it gives me: "Copy source blob has been modified" - when I check, the blob has not been modified (I check the last modification date and it is in the past).
How do I copy the archived blob and save a new blob in the same container with a different access type
const { BlobServiceClient,generateBlobSASQueryParameters, BlobSASPermissions } = require("@azure/storage-blob");
export default async (req, res) => {
if (req.method === 'POST') {
const connectionString = 'DefaultEndpointsProtocol=...'
const containerName = 'container';
const srcFile='filename' // this is the filename as it appears on Azure portal (i.e. the blob name)
async function getSignedUrl(blobClient, options={}){
options.permissions = options.permissions || "racwd"
const expiry = 3600;
const startsOn = new Date();
const expiresOn = new Date(new Date().valueOf() + expiry * 1000);
const token = await generateBlobSASQueryParameters(
{
containerName: blobClient.containerName,
blobName: blobClient.name,
permissions: BlobSASPermissions.parse(options.permissions),
startsOn, // Required
expiresOn, // Optional
},
blobClient.credential,
);
return `${blobClient.url}?${token.toString()}`;
}
(async () => {
try {
const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = blobServiceClient.getContainerClient(containerName);
const sourceBlobClient = containerClient.getBlockBlobClient(srcFile);
const targetBlobClient = containerClient.getBlockBlobClient('targetFileName');
const url = await getSignedUrl(sourceBlobClient);
console.log(`source: ${url}`);
const result = await targetBlobClient.syncCopyFromURL(url);
// const result = await targetBlobClient.beginCopyFromURL(url);
console.log(result)
} catch (e) {
console.log(e);
}
})();
}
}
export const config = {
api: {
bodyParser: {
sizeLimit: '1gb',
},
},
}