Search code examples
springspring-bootapache-camelspring-restcontrollercamel-http

Unable to process large files in camel using http4


A scenario, need to consume a rest webservice which provides a huge file as a stream output and vice versa need to handle the stream and directly write to a file rather memory. Service :

@RequestMapping(value = "downloadFile", method = RequestMethod.GET)
public StreamingResponseBody getSteamingFile(HttpServletResponse response) throws IOException {
    response.setContentType("application/octet-stream");
    InputStream inputStream = new FileInputStream(new File("data\\test_big.txt"));
    return outputStream -> {
        int nRead;
        byte[] data = new byte[1024];
        System.out.println("Writing some bytes..");
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            outputStream.write(data, 0, nRead);
        }
        System.out.println("Completed #####");  
        outputStream.flush();
        outputStream.close();
        response.flushBuffer();
    };

}

Consumer Route:

.to("http4://localhost:8080/downloadFile")
        .process(new Processor() {
            public void process(Exchange exchange) throws Exception {
                InputStream is = exchange.getIn().getBody(InputStream.class);
                File ret = File.createTempFile("loadTest", "tmp");
                FileOutputStream fos = new FileOutputStream(ret);
                StreamUtils.copy(is, fos);
                System.out.println("File Name "+ ret.getName());
                is.close();
                fos.flush();
                fos.close();
            }
        });

256 JVM is going out of Memory when processing 300 MB which treats my route is not performing streaming to file.


Solution

  • .to("http4://localhost:8080/downloadFile?disableStreamCache=true")

    disableStreamCache: Determines whether or not the raw input stream from Servlet is cached or not (Camel will read the stream into a in memory/overflow to file, Stream caching) cache. By default Camel will cache the Servlet input stream to support reading it multiple times to ensure it Camel can retrieve all data from the stream. However you can set this option to true when you for example need to access the raw stream, such as streaming it directly to a file or other persistent store