I am new to Azure Blob, I am trying to copy files in a folder and once the copy is done, delete the files in Async. I can list the files and URL but copy and delete fails.
What am I missing here.
BlobServiceClientBuilder blobServiceClientBuilder = new BlobServiceClientBuilder()
.endpoint(endpoint)
.sasToken(sharedAccessSignatures);
ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
// List files in the source folder
List<String> sourceFiles = listFiles(blobServiceClientBuilder.buildClient(), sourceFolderPath, containerName);
// Check if there are files to process
if (sourceFiles.isEmpty()) {
System.out.println("No files found in the source folder. Exiting.");
return;
}
// Asynchronously copy and delete each file
List<CompletableFuture<Void>> futures = sourceFiles.stream()
.map(file -> CompletableFuture.runAsync(() -> copyAndDeleteFile(blobServiceClientBuilder.buildClient(), file), executorService))
.collect(Collectors.toList());
// Wait for all asynchronous operations to complete
CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
allOf.join();
} finally {
// Shutdown the executor service
executorService.shutdown();
}
System.out.println("All copy operations completed. Exiting.");
}
private static List<String> listFiles(BlobServiceClient blobServiceClient, String folderPath, String containerName) {
try {
List<String> filePaths = blobServiceClient.getBlobContainerClient(containerName)
.listBlobs()
.stream()
.filter(blobItem -> !blobItem.getName().endsWith("/") && blobItem.getName().startsWith(folderPath))
.map(blobItem -> blobItem.getName())
.collect(Collectors.toList());
if (filePaths.isEmpty()) {
System.out.println("No files found in the source folder: " + folderPath);
} else {
System.out.println("File Paths: " + filePaths);
}
return filePaths;
} catch (Exception e) {
System.err.println("Error listing files: " + e.getMessage());
return Collections.emptyList();
}
}
private static void copyAndDeleteFile(BlobServiceClient blobServiceClient, String filePath) {
try {
String fileName = Paths.get(filePath).getFileName().toString();
System.out.println("FileName: " + fileName);
String sourceBlobName = sourceFolderPath + "/" + fileName;
String destBlobName = destFolderPath + "/" + fileName;
System.out.println("SourceBlobName: " + sourceBlobName);
System.out.println("DestinationBlobName: " + destBlobName);
var sourceBlobClient = blobServiceClient.getBlobContainerClient(containerName)
.getBlobClient(sourceBlobName);
var destBlobClient = blobServiceClient.getBlobContainerClient(containerName)
.getBlobClient(destBlobName);
System.out.println("Source Blob URL: " + sourceBlobClient.getBlobUrl());
System.out.println("Destination Blob URL: " + destBlobClient.getBlobUrl());
// Ensure source blob exists before copying
if (!sourceBlobClient.exists()) {
throw new RuntimeException("Source blob does not exist: " + sourceBlobName);
}
// Copy the file asynchronously
CopyStatusType copyInfo = ((BlobCopyInfo) destBlobClient.beginCopy(sourceBlobClient.getBlobUrl(), null)).getCopyStatus();
// Wait for the copy to complete
while (copyInfo.equals(CopyStatusType.PENDING)) {
Thread.sleep(1000);
copyInfo = destBlobClient.getProperties().getCopyStatus();
}
// Check if the copy was successful
if (copyInfo.equals(CopyStatusType.SUCCESS)) {
// Delete the source blob
sourceBlobClient.delete();
System.out.println("Blob copy and delete completed successfully.");
} else {
throw new RuntimeException("Copy operation failed.");
}
} catch (Exception e) {
System.err.println("Error copying and deleting file: " + e.getMessage());
}
}
Error:
Error copying and deleting file: Status code 401, "
CannotVerifyCopySourceServer failed to authenticate the request. Please refer to the information in the www-authenticate header. RequestId:c902d7e8-201e-004b-2954-2d97e4000000 Time:2023-12-12T23:37:19.1311821Z"
The above error occurs when you don't have proper permission in the
SAStoken to delete the source folder.In my environment, I have two folders named
sampleanddemostored in my Azure Blob storageGenerated sas token through the portal with permission
read,write,list and delete.Portal:
Now, Using the below code I can able to copy from the source folder[sample] to the destination folder[demo] and also able to delete the folder.
Code:
Output:
Portal: