question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] BlobAsyncClient.download() corrupts the file

See original GitHub issue

Describe the bug

BlobAsyncClient.download() returns a corrupted data stream.

To Reproduce Upload a file to azure storage and download it via the Java Async client.

Demo-Spring application to reproduce the problem (see also screeenshot how to use) azure-dl.zip

In order to launch configure azure.endpoint either via commandline, application.properties or environment variable AZURE_ENDPOINT=, needs to be complete blob service URL including SAS token.

Note: to change the azure container name use azure.container, it defaults to test.

Code Snippet

@RestController
public class WebEndpoint {
    private final WebClient webClient;
    private final BlobContainerAsyncClient azureClient;

    public WebEndpoint(WebClient.Builder webClient,
                       BlobServiceAsyncClient azureClient,
                       @Value("${azure.container:test}") String container) {
        this.webClient = webClient.build();
        this.azureClient = azureClient.getBlobContainerAsyncClient(container);
    }

    @GetMapping("/download")
    public ResponseEntity<Flux<ByteBuffer>> download(
        @RequestParam("file") String filename,
        @RequestParam(value = "wc", defaultValue = "false") boolean useWebClient
    ) {
        return ResponseEntity.ok()
            .body(useWebClient ? webClientDownload(filename) : azureClientDownload(filename));
    }

    private Flux<ByteBuffer> webClientDownload(String filename) {
        return this.webClient.get()
            .uri(this.azureClient.getBlobAsyncClient(filename).getBlobUrl())
            .exchange()
            .flatMapMany(c -> c.body(BodyExtractors.toDataBuffers()))
            .map(DataBuffer::asByteBuffer);
    }

    private Flux<ByteBuffer> azureClientDownload(String filename) {
        return this.azureClient.getBlobAsyncClient(filename).download();
    }
}

Expected behavior The file is not corrupt

Screenshots Running the code above:

image

image

Part of the corrupted file (in the middle): image

Additional Info

This does also not work when using a different event loop as outlined in #7910

Buffering the whole flux before sending it doesn’t change anything:

            .map(ByteBufferBackedInputStream::new)
            .buffer()
            .map(data -> new SequenceInputStream(Collections.enumeration(data)))
            .map(data -> {
                try {
                    return ByteBuffer.wrap(data.readAllBytes());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            })

Also neither delaySequence nor delayElements have an effect.

Setup (please complete the following information):

  • OS: Archlinux
  • IDE : IntelliJ
  • Azure Client: 12.3.0

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:21 (19 by maintainers)

github_iconTop GitHub Comments

3reactions
Dav1ddecommented, Feb 7, 2020

@anuchandy sure - happy to help, thanks for looking into it. For now I’ll stick to Spring’s WebClient.

Personally it would be nice if the Azure client “just” worked with Spring, but I can see how this is a hard problem to solve (API wise). Probably best to have a simple interface which returns unpooled (or copied) data, while having a more advanced API that requires the user to free/release the buffers explicitly and automatically integrates into Spring (if possible).

Just my two cents, you guys are gonna figure it out, especially with the Spring/Reactor people on your side 😉

0reactions
JonathanGilescommented, Feb 16, 2020

One such fix would be what @Dav1dde has proposed at #8057, which is pending his successful signing of the CLA.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Corrupted files when downloading from azure storageblob
Recently, I have begun to have issues with corrupted files after downloading. If I download straight from azure, the file is still valid....
Read more >
When taking BLOB file, it showing file is corrupted.
hi, I am using JDEVELOPER 11g. I have a problem while taking back BLOB file. when i reading the file ,it show ing...
Read more >
corrupted files during uploading with azure portal
I use archieve storage to backup my personal media files from my HDDs. I would like to know if there is possibility of...
Read more >
MS Excel corrupt after upload into Azure Blob Storage
I am able to upload the file. It is successful. But the Problem is, that the uploaded file is corrupted after upload. When...
Read more >
Random corruption of pdf files when saved to a BLO...
The corrupted files can be opened after the save occurs, but not after the reconcile and post. Adobe Acrobat states that there is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found