package se.kth.hopsworks.rest;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.AccessControlException;
import se.kth.hopsworks.filters.AllowedRoles;
import se.kth.hopsworks.hdfs.fileoperations.DistributedFileSystemOps;
import se.kth.hopsworks.hdfs.fileoperations.DistributedFsService;

@RequestScoped
@TransactionAttribute(TransactionAttributeType.NEVER)
public class DownloadService {

  private static final Logger LOG
          = Logger.getLogger(DownloadService.class.getName());

  @EJB
  private DistributedFsService dfs;

  private String path;
  private String username;

  public DownloadService() {
  }

  public void setPath(String path) {
    this.path = path;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  @GET
  @Produces(MediaType.APPLICATION_OCTET_STREAM)
  @AllowedRoles(roles = {AllowedRoles.DATA_SCIENTIST, AllowedRoles.DATA_OWNER})
  public Response downloadFromHDFS() throws AppException, AccessControlException {
    FSDataInputStream stream;
    DistributedFileSystemOps dfso = null;
    try {
      if (username != null) {
        dfso = dfs.getDfsOps(username);
        stream = dfso.open(new Path(this.path));
      } else {
        dfso = dfs.getDfsOps();
        stream = dfso.open(new Path(this.path));
      }
      Response.ResponseBuilder response = Response.ok((Object) stream);
      response.header("Content-disposition", "attachment;");

      return response.build();
    } catch (AccessControlException ex) {
      throw new AccessControlException(
              "Permission denied: You can not download the file ");
    } catch (IOException ex) {
      LOG.log(Level.SEVERE, null, ex);
      throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
              "File does not exist: " + this.path);
    } 
//    finally {
//      if (dfso != null) {
//        dfso.close();
//      }
//    }
  }
}

@@ -49,24 +49,53 @@
 OException;%0A
+import java.io.OutputStream;%0A
 import java.
@@ -114,16 +114,16 @@
 .Level;%0A
-
 import j
@@ -347,24 +347,68 @@
 s.Produces;%0A
+import javax.ws.rs.WebApplicationException;%0A
 import javax
@@ -464,16 +464,57 @@
 sponse;%0A
+import javax.ws.rs.core.StreamingOutput;%0A
 import o
@@ -1821,16 +1821,20 @@
 %0A      %7D
+    
 %0A      R
@@ -1884,23 +1884,53 @@
 .ok(
-(Object) stream
+buildOutputStream(stream,%0A              dfso)
 );%0A 
@@ -1989,17 +1989,23 @@
 ent;%22);%0A
+      
 %0A
-
       re
@@ -2384,54 +2384,542 @@
  %7D %0A
-//    finally %7B%0A//      if (dfso != null) %7B%0A//
+  %7D%0A  %0A  private StreamingOutput buildOutputStream(final FSDataInputStream stream,%0A          final DistributedFileSystemOps dfso)%7B%0A     StreamingOutput output = new StreamingOutput() %7B%0A        @Override%0A        public void write(OutputStream out) throws IOException,%0A                WebApplicationException %7B%0A          int length;%0A          byte%5B%5D buffer = new byte%5B1024%5D;%0A          while((length = stream.read(buffer)) != -1) %7B%0A            out.write(buffer, 0, length);%0A          %7D%0A          out.flush();%0A          stream.close();%0A  
     
@@ -2940,25 +2940,54 @@
 ();%0A
-//
+ 
       
+ 
 %7D%0A
-//
+  
     %7D
+;%0A      %0A      return output;
 %0A  %7D

Change download function to close the stream and the file system object when the download is finished.