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:2aa9dcb248
[formerlyce1038723d
] [formerlybfde9c37ce
] [formerly2aa9dcb248
[formerlyce1038723d
] [formerlybfde9c37ce
] [formerlyd44c55e976
[formerlybfde9c37ce
[formerly 31c42d161146b0367435c66535d4da700a572f24]]]] Former-commit-id:d44c55e976
Former-commit-id:fb6be670b1
[formerlyab86cda554
] [formerly 1b8f3ce536ab968c6e5e63d5bfe2ffc91722e548 [formerlyd693c07bb4
]] Former-commit-id: 199f3f09805b232480df05d4c222e11bab11f4ce [formerly22d6302151
] Former-commit-id:560f51d226
This commit is contained in:
parent
846d4546bf
commit
05ddcce572
5 changed files with 168 additions and 177 deletions
|
@ -13,6 +13,8 @@
|
|||
<property name="tmp.bin.dir" value="${tmp.dir}/bin" />
|
||||
<property name="tmp.lib.dir" value="${tmp.dir}/lib" />
|
||||
|
||||
<property name="compile.with.debug" value="on" />
|
||||
|
||||
<!-- public static final -->
|
||||
<path id="ant.classpath">
|
||||
<fileset dir="${esb.build.directory}/lib/ant">
|
||||
|
@ -26,8 +28,7 @@
|
|||
<available file="${basedir}/tmp" type="dir" />
|
||||
<then>
|
||||
<delete includeemptydirs="true">
|
||||
<fileset dir="${basedir}"
|
||||
includes="tmp/**" />
|
||||
<fileset dir="${basedir}" includes="tmp/**" />
|
||||
</delete>
|
||||
</then>
|
||||
</if>
|
||||
|
@ -39,8 +40,7 @@
|
|||
<available file="${dataserver.root.directory}/lib" />
|
||||
<then>
|
||||
<delete verbose="true" includeemptydirs="true">
|
||||
<fileset dir="${dataserver.root.directory}/lib"
|
||||
includes="*/**"/>
|
||||
<fileset dir="${dataserver.root.directory}/lib" includes="*/**" />
|
||||
</delete>
|
||||
</then>
|
||||
</if>
|
||||
|
@ -73,8 +73,7 @@
|
|||
<available file="${includes.directory}" type="dir" />
|
||||
<then>
|
||||
<delete verbose="true" includeemptydirs="true">
|
||||
<fileset dir="${includes.directory}"
|
||||
includes="*/**" />
|
||||
<fileset dir="${includes.directory}" includes="*/**" />
|
||||
</delete>
|
||||
</then>
|
||||
</if>
|
||||
|
@ -83,32 +82,15 @@
|
|||
<!-- run includegen -->
|
||||
<echo message="Generating deployment list for feature: ${feature}" />
|
||||
|
||||
<includegen providerfilter="${includegen.filter}"
|
||||
basedirectories="${basedirectories}"
|
||||
featurefile="${feature.file}"
|
||||
cotsout="${includes.directory}/cots.includes"
|
||||
plugsout="${includes.directory}/plugins.includes"
|
||||
coreout="${includes.directory}/core.includes" />
|
||||
<includegen providerfilter="${includegen.filter}" basedirectories="${basedirectories}" featurefile="${feature.file}" cotsout="${includes.directory}/cots.includes" plugsout="${includes.directory}/plugins.includes" coreout="${includes.directory}/core.includes" />
|
||||
|
||||
<!-- copy foss jars to tmp lib folder -->
|
||||
<copyToBuild includes.file="${includes.directory}/cots.includes"
|
||||
source.base="${workspace}/cots"
|
||||
source.suffix=""
|
||||
includes.pattern="*.jar"
|
||||
target.dir="${tmp.lib.dir}" />
|
||||
<copyToBuild includes.file="${includes.directory}/cots.includes" source.base="${workspace}/cots" source.suffix="" includes.pattern="*.jar" target.dir="${tmp.lib.dir}" />
|
||||
|
||||
<!-- copy all uframe source to tmp src folder -->
|
||||
<copyToBuild includes.file="${includes.directory}/core.includes"
|
||||
source.base="${workspace}/edexOsgi"
|
||||
source.suffix="src"
|
||||
includes.pattern="**/*.java"
|
||||
target.dir="${tmp.src.dir}" />
|
||||
<copyToBuild includes.file="${includes.directory}/core.includes" source.base="${workspace}/edexOsgi" source.suffix="src" includes.pattern="**/*.java" target.dir="${tmp.src.dir}" />
|
||||
|
||||
<copyToBuild includes.file="${includes.directory}/plugins.includes"
|
||||
source.base="${workspace}/edexOsgi"
|
||||
source.suffix="src"
|
||||
includes.pattern="**/*.java"
|
||||
target.dir="${tmp.src.dir}" />
|
||||
<copyToBuild includes.file="${includes.directory}/plugins.includes" source.base="${workspace}/edexOsgi" source.suffix="src" includes.pattern="**/*.java" target.dir="${tmp.src.dir}" />
|
||||
|
||||
<copy todir="${tmp.src.dir}" overwrite="true" verbose="true">
|
||||
<fileset dir="src" includes="**/*.java" />
|
||||
|
@ -121,7 +103,7 @@
|
|||
</fileset>
|
||||
</path>
|
||||
<mkdir dir="${tmp.bin.dir}" />
|
||||
<javac destdir="${tmp.bin.dir}">
|
||||
<javac destdir="${tmp.bin.dir}" debug="${compile.with.debug}">
|
||||
<src path="${tmp.src.dir}" />
|
||||
<classpath refid="foss.path" />
|
||||
</javac>
|
||||
|
@ -138,10 +120,8 @@
|
|||
|
||||
<sequential>
|
||||
<echo>@{includes.file}</echo>
|
||||
<loadfile property="@{includes.file}.contents"
|
||||
srcfile="@{includes.file}" />
|
||||
<for param="line" list="${@{includes.file}.contents}"
|
||||
delimiter="${line.separator}">
|
||||
<loadfile property="@{includes.file}.contents" srcfile="@{includes.file}" />
|
||||
<for param="line" list="${@{includes.file}.contents}" delimiter="${line.separator}">
|
||||
<sequential>
|
||||
<if>
|
||||
<available file="@{source.base}/@{line}/@{source.suffix}" type="dir" />
|
||||
|
@ -160,9 +140,6 @@
|
|||
</macrodef>
|
||||
|
||||
<!-- static -->
|
||||
<taskdef name="includegen"
|
||||
classname="com.raytheon.uf.anttasks.includesgen.GenerateIncludesFromFeature"
|
||||
classpathref="ant.classpath" />
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml"
|
||||
classpath="${esb.build.directory}/lib/ant/ant-contrib-1.0b3.jar" />
|
||||
<taskdef name="includegen" classname="com.raytheon.uf.anttasks.includesgen.GenerateIncludesFromFeature" classpathref="ant.classpath" />
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${esb.build.directory}/lib/ant/ant-contrib-1.0b3.jar" />
|
||||
</project>
|
||||
|
|
|
@ -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
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -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<MethodAuthHandler> methods = Arrays.asList(new PutAuthHandler(
|
||||
|
|
|
@ -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
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -213,33 +214,45 @@ 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<UsedLock> 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();
|
||||
}
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of read only file locks for each file from the base to the
|
||||
|
@ -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<UsedLock> 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("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
||||
w.write("<Contents xmlns=\"urn:uf:viz:collaboration\">");
|
||||
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<UsedLock> 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("<!DOCTYPE html>\n");
|
||||
w.write("<html><body>");
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue