I need to download very large file via REST and store it to an Azure Blobstorage. I am facing quite some Problems.
For all examples, I use this call to get to the Data
var flux = this.webClient
.get()
.uri(urlToAssert)
.accept(MediaType.APPLICATION_OCTET_STREAM)
.exchangeToFlux(clientResponse ->
clientResponse.body(BodyExtractors.toDataBuffers()));
This code works for file with Size 50MB, 1GB, 5GB. Note is write directly the Files into the file system.
try (OutputStream outputStream = new FileOutputStream(targetFile.resolve("testData.zip").toAbsolutePath().toString(), false)) {
DataBufferUtils.write(flux, outputStream).map(DataBufferUtils::release).blockLast(Duration.ofHours(22));
} catch (Exception e) {
throw new IllegalStateException(e);
}
So i know the Stream handling is ok. Now i use AzureBlob Storage OutputStream. The 50mb works. The 1GB is also present in the Blobstorage, but the method keep hanging somewhere in the "try"
try (OutputStream outputStream = this.blob.getOutputStreamParallel(destination, this.blob.getParallelTransferOptions())) {
DataBufferUtils.write(flux, outputStream).map(DataBufferUtils::release).blockLast(Duration.ofHours(22));
outputStream.flush();
} catch (IOException e) {
throw new IllegalStateException(e);
}
public OutputStream getOutputStreamParallel(Path path, ParallelTransferOptions parallelTransferOptions) {
var blobClientTarget = this.containerClient.getBlobClient(relativePathUnix(path));
return blobClientTarget.getBlockBlobClient().getBlobOutputStream(parallelTransferOptions, null, null, null, null);
}
this.parallelTransferOptions = new ParallelTransferOptions()
.setBlockSizeLong(40 * Constants.MB)
.setMaxConcurrency(5)
.setProgressListener(bytesTransferred -> {
log.info("write bytes, bytes transferred '{}'", bytesTransferred);
});
In the log i see the following strange thing
Does somebody see my error? Or is the Azure BlobStorage broken?
2
Answers
The Problem was that I used the
BlobContainerClient
and not theBlobContainerAsyncClient
. TheBlobContainerAsyncClient
has special API's to handle the Flux-"Stuff"Hear is the code that I use now:
And Here is the Example repo with solution https://github.com/git9999999/azure-blob-large-file-upload-problem
Here the Ticket that solve the Problem: https://github.com/Azure/azure-sdk-for-java/issues/35477
With below spring boot code, I can able to download very large file via REST and store it to an Azure Blobstorage.
Code:
Output:
with the output port, I can able to download very large file via REST and upload 10gb blob to container in my storage account,
I successfully uploaded 10gb blob to my container in my storage account in Azure Portal,