0

I have problem downloading file (getting the input stream) from server (quarkus implementation) in client (quarkus implementation)

I am using 2.9.2.Final version of Quarkus for both client and server, dependency - quarkus-rest-client-reactive-jackson

I have a server which returns InputStream inside Response:

  @Override
  public Response downloadFileById(String id) {
    var inputStream = repo.downloadFileByFileId(id);
    return Response.ok(inputStream, MediaType.APPLICATION_OCTET_STREAM)
        .header("Content-Disposition", "attachment; filename = \"" + fileName + "\"")
        .header("Content-Length", repo.getFileLengthByFileById(id))
        .build();
  }

On client side, I've tried these variations:

This works but loads everything into memory. It uses ByteArrayInputStream inside ClientSendRequestHandler.java from package org.jboss.resteasy.reactive.client.handlers; (see line 340 in https://github.com/quarkusio/quarkus/blob/b0019c087880f9fd1371776b8c23c1b49129dcb3/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSendRequestHandler.java)

var stream = service.downloadFileById(id)
                    .await()
                    .indefinitely()
                    .readEntity(InputStream.class);

I expected this to work but it returns null

var stream = service
              .downloadFileById(id)
              .await()
              .indefinitely()
              .getEntity();

As I am going through following method from the ClientSendRequestHandler.java

private void attachSentHandlers(Future<HttpClientResponse> sent,
        HttpClientRequest httpClientRequest,
        RestClientRequestContext requestContext)

I am wondering, is it not supported? I see cases for Multipart data, File, and an else branch Not sure what am I missing.

dtechlearn
  • 363
  • 2
  • 4
  • 21
  • Have you tried using a `Uni` as a return type? – geoand Jun 10 '22 at 05:15
  • I tried service.downloadFileById(id) .await() .indefinitely() .readEntity(File.class); It is first loaded to memory, than to file... When I am trying this with imperative client (quarkus-rest-client-jackson), it works fine in case downloadFileById does not return Uni. When it does, error occurs, complaining about "Unable to find a MessageBodyReader of content-type application/octet-stream and type interface io.smallrye.mutiny.Uni" – dtechlearn Jun 10 '22 at 07:12
  • My point is that you should not use `Response` in this case. If you use `Uni` things should just work. – geoand Jun 10 '22 at 08:28
  • I have tried scenario where server returns Uni, specifically Uni.createFrom().item(file); client consuming Uni. Sending over 2gb file. here are my observations: - server: memory consumption is increased drastically upon sending to client - client: correctly receiving to tmp file but doesn't get whole file when working with over 2gb, instead I got only fragments(60 mb, another try 3 mb) the client worked ok when I sent smaller file (100 mb). – dtechlearn Jun 20 '22 at 19:09
  • correction here, client gets the tmp file completely... , just the problem with server memory remains – dtechlearn Jun 21 '22 at 11:32

0 Answers0