Streaming data - Heap OOM, JAX-RS

50 Views Asked by At

I am trying to stream data from a JCR (Jackrabbit) workspace. The data I want to stream is a bunch of file chunks stored in jcr nodes (main node - file, subnodes - chunks). The chunks are base64 encoded strings.

I am using Magnolia CMS, that's using jackrabbit under the hood, it's also using JAX-RS.

The issue I am faced with is my heap running out of memory. This issue does not occur with files of smaller sizes (50MB-400MB, atleast these ones I have tested out and there are no issues with them AFAIK), however the moment I try out a file of around 1.2GB I run out of memory. Can somebody point me to the right direction of solving this issue?

    @POST
    @Path("/getFile/{fileId}")
    @Produces({MediaType.APPLICATION_OCTET_STREAM})
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "OK"),
            @ApiResponse(code = 401, message = "ANONYMOUS TRIED TO ACCESS ENDPOINT")
    })
    public Response getFile(@PathParam("fileId") String fileId) {
            AssetsManager assetsManager = new AssetsManager();
            try {
                Node asset = assetsManager.getAssetById(fileId);
                Node assetData = asset.getNode("dataNodes");
                int sliceCount = asset.getProperty("lastSlice").getDecimal().intValue();

                StreamingOutput stream = new StreamingOutput() {
                    @Override
                    public void write(OutputStream output) throws IOException {
                        try {
                            for (int i = 0; i <= sliceCount; i++) {
                                Node sliceNode = assetData.getNode(String.valueOf(i));
                                byte[] decodedBytes = Base64.decodeBase64(sliceNode.getProperty("data").getString());

                                output.write(decodedBytes);
                                output.flush();
                            }
                        } catch (RepositoryException ex) {
                            // Handle RepositoryException appropriately
                        } finally {
                            output.close();
                        }
                    }
                };
                return Response.status(200).entity(stream)
                        .header("Content-Disposition", String.format("attachment; filename=%s", 
                         asset.getProperty("name").getString()))
                        .header("Content-type", "application/octet-stream")
                        .header("Access-Control-Expose-Headers", "Content-Disposition")
                        .type(MediaType.APPLICATION_OCTET_STREAM)
                        .build();
            } catch (Exception ex) {
                return Response.status(400).entity(ex).build();
            }
            return Response.status(500).entity(ex).build();
    }
0

There are 0 best solutions below