From d44c55e97699062fb62e0fc39087a468b2a5d808 Mon Sep 17 00:00:00 2001 From: Brian Clements Date: Tue, 11 Mar 2014 16:44:54 -0500 Subject: [PATCH] Issue #2827 fixed collab dataserver returning empty body with 200 we check if a file exists in and out of the lock when reading if the file is deleted between checks, the inner check attempts to return an error we had already access the output stream from the response object so it is committed to 200 fixed by waiting to get the output stream until after the second check Former-commit-id: 31c42d161146b0367435c66535d4da700a572f24 --- .../collaboration.dataserver/build.xml | 275 ++++++++---------- .../collaboration/dataserver/DataService.java | 11 +- .../dataserver/WebServerRunner.java | 6 +- .../dataserver/XmppServerConnection.java | 5 +- .../dataserver/storage/FileManager.java | 48 +-- 5 files changed, 168 insertions(+), 177 deletions(-) diff --git a/javaUtilities/collaboration.dataserver/build.xml b/javaUtilities/collaboration.dataserver/build.xml index c1687df2a1..31bc9093f1 100644 --- a/javaUtilities/collaboration.dataserver/build.xml +++ b/javaUtilities/collaboration.dataserver/build.xml @@ -1,168 +1,145 @@ - - - - - - + + + + + + - - - - - + + + + + - - - - - - + - - - - - - - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + - + + - - + - - + + - + + - - - + - - - - - - - - - - - - - + + + - - - - - - - + + + + + + + + + + + + + - - @{includes.file} - - - - - - - - - - - - No files found at @{source.base}/@{line}/@{source.suffix} - - - - - - + + + + + + + - - - + + @{includes.file} + + + + + + + + + + + + No files found at @{source.base}/@{line}/@{source.suffix} + + + + + + + + + + diff --git a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/DataService.java b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/DataService.java index 8dd4b17996..e7809757d7 100644 --- a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/DataService.java +++ b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/DataService.java @@ -23,7 +23,6 @@ import java.io.File; import java.io.IOException; import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -44,7 +43,8 @@ import com.raytheon.uf.common.http.AcceptHeaderValue; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Feb 5, 2014 2756 bclement Initial creation + * Feb 05, 2014 2756 bclement Initial creation + * Mar 11, 2014 2827 bclement pass response object to FileManager in doGet * * * @@ -113,18 +113,17 @@ public class DataService extends HttpServlet { throw new RestException(HttpServletResponse.SC_NOT_FOUND, "No Such Resource: " + file.getAbsolutePath()); } - ServletOutputStream out = resp.getOutputStream(); if (file.isDirectory()) { if (acceptsXml(req)) { resp.setContentType(XML_CONTENT_TYPE); - manager.readDirectoryAsXml(file, out); + manager.readDirectoryAsXml(file, resp); } else { resp.setContentType(HTML_CONTENT_TYPE); - manager.readDirectoryAsHtml(file, out); + manager.readDirectoryAsHtml(file, resp); } } else { resp.setContentType(BINARY_CONTENT_TYPE); - manager.readFile(file, out); + manager.readFile(file, resp); } } catch (IOException e) { log.warn("Problem handling GET", e); diff --git a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/WebServerRunner.java b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/WebServerRunner.java index 0adfc9d7fd..778ca4aff6 100644 --- a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/WebServerRunner.java +++ b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/WebServerRunner.java @@ -47,6 +47,7 @@ import com.raytheon.collaboration.dataserver.auth.ServerAuthManager; * ------------ ---------- ----------- -------------------------- * Feb 14, 2014 2756 bclement Initial creation * Feb 28, 2014 2756 bclement added authManager + * Mar 11, 2014 2827 bclement disabled sessions on servlet context handler * * * @@ -72,7 +73,7 @@ public class WebServerRunner implements Runnable { Config.PORT_DEFAULT)); ServletContextHandler context = new ServletContextHandler( - ServletContextHandler.SESSIONS); + ServletContextHandler.NO_SESSIONS); context.setContextPath("/"); server.setHandler(context); @@ -84,8 +85,7 @@ public class WebServerRunner implements Runnable { String datapath = Config.getPath(Config.DATAPATH_KEY, Config.DATAPATH_DEFAULT); - String pathspec = datapath - + "*"; + String pathspec = datapath + "*"; context.addServlet(new ServletHolder(new DataService(base)), pathspec); List methods = Arrays.asList(new PutAuthHandler( diff --git a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/XmppServerConnection.java b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/XmppServerConnection.java index f55f31f78c..5ebf996e1c 100644 --- a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/XmppServerConnection.java +++ b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/XmppServerConnection.java @@ -50,6 +50,7 @@ import com.raytheon.uf.common.xmpp.iq.SecurityToggleProvider; * Feb 14, 2014 2756 bclement Initial creation * Feb 28, 2014 2756 bclement added custom IQ packet support * Mar 04, 2014 2756 bclement added xmpp server retry + * Mar 11, 2014 2827 bclement changed (dis)connect messages from debug to info * * * @@ -97,7 +98,7 @@ public class XmppServerConnection implements Runnable { registerListeners(conn); this.conn.connect(); this.conn.login(user, password); - log.debug("Connected to XMPP server at address: " + xmppServerAddress); + log.info("Connected to XMPP server at address: " + xmppServerAddress); } /** @@ -188,7 +189,7 @@ public class XmppServerConnection implements Runnable { * disconnect from XMPP server */ public void disconnect() { - log.debug("Disconnecting from XMPP server"); + log.info("Disconnecting from XMPP server"); conn.disconnect(); } diff --git a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/storage/FileManager.java b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/storage/FileManager.java index 38fa32808b..06da743f0b 100644 --- a/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/storage/FileManager.java +++ b/javaUtilities/collaboration.dataserver/src/com/raytheon/collaboration/dataserver/storage/FileManager.java @@ -25,12 +25,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import com.raytheon.collaboration.dataserver.RestException; @@ -50,6 +50,7 @@ import com.raytheon.uf.common.util.concurrent.KeyLocker; * ------------ ---------- ----------- -------------------------- * Feb 6, 2014 2756 bclement Initial creation * Feb 28, 2014 2756 bclement moved to storage package, made buffer size public + * Mar 11, 2014 2827 bclement read methods take servlet response object * * * @@ -213,31 +214,43 @@ public class FileManager { } /** - * Output file to stream + * Output file to servlet response * * @param file - * @param out + * @param resp * @throws IOException * @throws RestException */ - public void readFile(File file, OutputStream out) throws IOException, + public void readFile(File file, HttpServletResponse resp) + throws IOException, RestException { InputStream in = null; List locks = null; + ServletOutputStream out = null; try { locks = getReadLocks(file); - if ( !file.exists()){ + if ( !file.isFile()){ throw new RestException(HttpServletResponse.SC_NOT_FOUND, "No Such File: " + file.getAbsoluteFile()); } in = new FileInputStream(file); + /* + * We have to wait until we are sure we can read the file before we + * get the outputstream. This is because the act of getting the + * output stream commits to using it with a 200 response. If we + * throw an error, we won't be able to use the response object to + * send an error and we will send a 200 with an empty body + */ + out = resp.getOutputStream(); copy(in, out); } finally { unlock(locks); if (in != null) { in.close(); } - out.close(); + if (out != null) { + out.close(); + } } } @@ -267,25 +280,25 @@ public class FileManager { } /** - * Output contents of directory to stream in XML format + * Output contents of directory to response in XML format * * @param directory - * @param out + * @param resp * @throws IOException * @throws RestException */ - public void readDirectoryAsXml(File directory, OutputStream out) + public void readDirectoryAsXml(File directory, HttpServletResponse resp) throws IOException, RestException { List locks = null; Writer w = null; try { locks = getReadLocks(directory); - if (!directory.exists()) { + if (!directory.isDirectory()) { // someone else modified it while waiting for lock throw new RestException(HttpServletResponse.SC_NOT_FOUND, "No Such Directory: " + directory.getAbsolutePath()); } - w = new OutputStreamWriter(out, "UTF-8"); + w = resp.getWriter(); w.write("\n"); w.write(""); for (File f : directory.listFiles()) { @@ -325,25 +338,25 @@ public class FileManager { } /** - * Output contents of directory to stream in HTML format + * Output contents of directory to response in HTML format * * @param directory - * @param out + * @param resp * @throws IOException * @throws RestException */ - public void readDirectoryAsHtml(File directory, OutputStream out) + public void readDirectoryAsHtml(File directory, HttpServletResponse resp) throws IOException, RestException { List locks = null; Writer w = null; try { locks = getReadLocks(directory); - if (!directory.exists()) { + if (!directory.isDirectory()) { // someone else modified it while waiting for lock throw new RestException(HttpServletResponse.SC_NOT_FOUND, "No Such Directory: " + directory.getAbsolutePath()); } - w = new OutputStreamWriter(out, "UTF-8"); + w = resp.getWriter(); w.write("\n"); w.write(""); for (File f : directory.listFiles()) { @@ -379,7 +392,7 @@ public class FileManager { } /** - * Copy bytes from input to output + * Copy bytes from input to output. Flushes output after writing. * * @param in * @param out @@ -392,6 +405,7 @@ public class FileManager { while ((len = in.read(buff)) != -1) { out.write(buff, 0, len); } + out.flush(); } /**