Issue #2928: Limit thriftsrv and textdbsrv streams.
Change-Id: I5f59d3ac39f7e776f88d65f3d015862968c3e178 Former-commit-id: 96bf7347434344901965bd4510d14edb9bdcd62a
This commit is contained in:
parent
d8303c10ee
commit
861a7b0cd5
21 changed files with 761 additions and 36 deletions
|
@ -57,6 +57,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
* Aug 18, 2013 #2097 dhladky Allowed extension by OGCJAXBManager
|
||||
* Sep 30, 2013 2361 njensen Refactored for cleanliness
|
||||
* Nov 14, 2013 2361 njensen Added lazy init option, improved unmarshal error message
|
||||
* Apr 16, 2014 2928 rjpeter Updated marshalToStream to not close the stream.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -372,13 +373,22 @@ public class JAXBManager {
|
|||
*/
|
||||
public void marshalToXmlFile(Object obj, String filePath,
|
||||
boolean formattedOutput) throws SerializationException {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
marshalToStream(obj, new FileOutputStream(new File(filePath)),
|
||||
formattedOutput);
|
||||
os = new FileOutputStream(new File(filePath));
|
||||
marshalToStream(obj, os, formattedOutput);
|
||||
} catch (SerializationException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new SerializationException(e);
|
||||
} finally {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,13 +429,6 @@ public class JAXBManager {
|
|||
if ((msh != null) && (marshallers.size() < QUEUE_SIZE)) {
|
||||
marshallers.add(msh);
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ import com.raytheon.uf.common.util.ServiceLoaderUtil;
|
|||
* Aug 06, 2013 2228 njensen More efficient transformFromThrift(Class, byte[])
|
||||
* Aug 13, 2013 2169 bkowal Unzip any gzipped data before applying thrift transformations
|
||||
* Oct 01, 2013 2163 njensen Updated calls to JAXBManager
|
||||
*
|
||||
* Apr 16, 2014 2928 rjpeter Added jaxbMarshalToStream.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -176,6 +176,26 @@ public final class SerializationUtil {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an instance of a class to an XML representation and write XML to
|
||||
* a stream. Uses JAXB.
|
||||
*
|
||||
* @param obj
|
||||
* Object to be marshaled
|
||||
* @param filePath
|
||||
* Path to the output file
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public static void jaxbMarshalToStream(Object obj, OutputStream os)
|
||||
throws SerializationException {
|
||||
try {
|
||||
getJaxbManager().marshalToStream(obj, os);
|
||||
} catch (JAXBException e) {
|
||||
throw new SerializationException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates an object from the XML representation in a File. Uses JAXB.
|
||||
*
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Utility Plug-in
|
||||
Bundle-SymbolicName: com.raytheon.uf.common.util
|
||||
Bundle-Version: 1.12.1174.qualifier
|
||||
Bundle-Version: 1.14.0
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Require-Bundle: org.apache.commons.beanutils;bundle-version="1.8.3",
|
||||
|
@ -18,4 +18,5 @@ Export-Package: com.raytheon.uf.common.util,
|
|||
com.raytheon.uf.common.util.header,
|
||||
com.raytheon.uf.common.util.mapping,
|
||||
com.raytheon.uf.common.util.registry,
|
||||
com.raytheon.uf.common.util.session
|
||||
com.raytheon.uf.common.util.session,
|
||||
com.raytheon.uf.common.util.stream
|
||||
|
|
|
@ -39,12 +39,15 @@ package com.raytheon.uf.common.util;
|
|||
*/
|
||||
|
||||
public class SizeUtil {
|
||||
|
||||
private static final int BYTES_PER = 1024;
|
||||
|
||||
private static final String[] REP_PREFIX = new String[] { "B", "kB", "MB",
|
||||
"GB", "TB", "PB", "EB", "ZB", "YB" };
|
||||
|
||||
public static final long BYTES_PER_KB = BYTES_PER;
|
||||
|
||||
public static final long BYTES_PER_MB = BYTES_PER_KB * BYTES_PER;
|
||||
|
||||
/**
|
||||
* Transforms a number of bytes to a pretty string based on the total number
|
||||
* of bytes, e.g. B, kB, MB, or GB as fitting. For example: 1000 -> 1000B,
|
||||
|
@ -65,7 +68,7 @@ public class SizeUtil {
|
|||
}
|
||||
|
||||
int reps = 0;
|
||||
while (n > BYTES_PER && reps < REP_PREFIX.length - 1) {
|
||||
while ((n > BYTES_PER) && (reps < (REP_PREFIX.length - 1))) {
|
||||
reps++;
|
||||
n /= BYTES_PER;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.util.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Stream that counts the number of bytes that have been read.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 15, 2014 2928 rjpeter Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
* @version 1.0
|
||||
*/
|
||||
public class CountingInputStream extends InputStream {
|
||||
/**
|
||||
* Stream to get data from.
|
||||
*/
|
||||
protected final InputStream wrappedStream;
|
||||
|
||||
/**
|
||||
* Number of bytes that have been read.
|
||||
*/
|
||||
protected long bytesRead = 0;
|
||||
|
||||
/**
|
||||
* Wraps the passed {@code InputStream} counting the bytes that are read
|
||||
* from it.
|
||||
*
|
||||
* @param inputStream
|
||||
*/
|
||||
public CountingInputStream(InputStream inputStream) {
|
||||
this.wrappedStream = inputStream;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#read(byte[])
|
||||
*/
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
int rval = wrappedStream.read(b, off, len);
|
||||
increaseBytesRead(rval);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#skip(long)
|
||||
*/
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
return wrappedStream.skip(n);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#available()
|
||||
*/
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return wrappedStream.available();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying stream. Nothing in this stream needs to be closed
|
||||
* as long as the wrappedStream is closed.
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
wrappedStream.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#mark(int)
|
||||
*/
|
||||
@Override
|
||||
public synchronized void mark(int readlimit) {
|
||||
wrappedStream.mark(readlimit);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#reset()
|
||||
*/
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
wrappedStream.reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#markSupported()
|
||||
*/
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return wrappedStream.markSupported();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
int rval = wrappedStream.read();
|
||||
increaseBytesRead(1);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that updates the internal count of the number of bytes read. Also
|
||||
* useful extension point for special handling based on amount of bytes
|
||||
* read.
|
||||
*
|
||||
* @param bytesRead
|
||||
* @throws IOException
|
||||
*/
|
||||
public void increaseBytesRead(int bytesRead) throws IOException {
|
||||
this.bytesRead += bytesRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bytes read so far.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getBytesRead() {
|
||||
return bytesRead;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.util.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Stream that counts the number of bytes that have been written.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 15, 2014 2928 rjpeter Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
* @version 1.0
|
||||
*/
|
||||
public class CountingOutputStream extends OutputStream {
|
||||
/**
|
||||
* Stream to write data to.
|
||||
*/
|
||||
protected final OutputStream wrappedStream;
|
||||
|
||||
/**
|
||||
* Number of bytes that have been written.
|
||||
*/
|
||||
protected long bytesWritten = 0;
|
||||
|
||||
/**
|
||||
* Wraps the passed {@code OutputStream} counting the bytes that are written
|
||||
* to it.
|
||||
*
|
||||
* @param outputStream
|
||||
*/
|
||||
public CountingOutputStream(OutputStream outputStream) {
|
||||
this.wrappedStream = outputStream;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.OutputStream#write(byte[])
|
||||
*/
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
this.write(b, 0, b.length);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
wrappedStream.write(b, off, len);
|
||||
increaseBytesWritten(len);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
wrappedStream.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying stream. Nothing in this stream needs to be closed
|
||||
* as long as the wrappedStream is closed.
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
wrappedStream.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
wrappedStream.write(b);
|
||||
increaseBytesWritten(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that updates the internal count of the number of bytes written.
|
||||
* Also useful extension point for special handling based on amount of bytes
|
||||
* written.
|
||||
*
|
||||
* @param bytesRead
|
||||
* @throws IOException
|
||||
*/
|
||||
public void increaseBytesWritten(int bytesWritten) throws IOException {
|
||||
this.bytesWritten += bytesWritten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bytes written so far.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getBytesWritten() {
|
||||
return bytesWritten;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.util.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.raytheon.uf.common.util.SizeUtil;
|
||||
|
||||
/**
|
||||
* Stream that limits the number of bytes that can be read. If limit is reached
|
||||
* an IOException is thrown. This does not preclude more bytes being read from
|
||||
* the stream.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 15, 2014 2928 rjpeter Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
* @version 1.0
|
||||
*/
|
||||
public class LimitingInputStream extends CountingInputStream {
|
||||
/**
|
||||
* Maximum number of bytes that can be read from the wrapped stream before
|
||||
* errors are thrown on read.
|
||||
*/
|
||||
protected final long maxBytes;
|
||||
|
||||
/**
|
||||
* Wraps the given {@code InputStream} and will throw IOException once the
|
||||
* specified number of bytes have been read from the stream.
|
||||
*
|
||||
* @param inputStream
|
||||
* @param maxBytes
|
||||
*/
|
||||
public LimitingInputStream(InputStream inputStream, long maxBytes) {
|
||||
super(inputStream);
|
||||
this.maxBytes = maxBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks number of bytes read from wrapped stream. An IOException will be
|
||||
* thrown if number of bytes read exceeds {@code maxBytes}.
|
||||
*
|
||||
* @param bytesRead
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void increaseBytesRead(int bytesRead) throws IOException {
|
||||
super.increaseBytesRead(bytesRead);
|
||||
long curBytes = getBytesRead();
|
||||
if (curBytes > maxBytes) {
|
||||
throw new IOException("Maximum number of bytes ["
|
||||
+ SizeUtil.prettyByteSize(maxBytes)
|
||||
+ "] has been exceeded by stream");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.util.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.raytheon.uf.common.util.SizeUtil;
|
||||
|
||||
/**
|
||||
* Stream that limits the number of bytes that can be written. If limit is
|
||||
* reached an IOException is thrown. This does not preclude more bytes from
|
||||
* being written to the stream.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 15, 2014 2928 rjpeter Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
* @version 1.0
|
||||
*/
|
||||
public class LimitingOutputStream extends CountingOutputStream {
|
||||
/**
|
||||
* Maximum number of bytes that can be written to the wrapped stream before
|
||||
* errors are thrown on write.
|
||||
*/
|
||||
protected final long maxBytes;
|
||||
|
||||
/**
|
||||
* Wraps the given {@code OutputStream} and will throw IOException once the
|
||||
* specified number of bytes have been written to the stream.
|
||||
*
|
||||
* @param inputStream
|
||||
* @param maxBytes
|
||||
*/
|
||||
public LimitingOutputStream(OutputStream outputStream, long maxBytes) {
|
||||
super(outputStream);
|
||||
this.maxBytes = maxBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks number of bytes written to wrapped stream. An IOException will be
|
||||
* thrown if number of bytes written exceeds {@code maxBytes}.
|
||||
*
|
||||
* @param bytesWritten
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void increaseBytesWritten(int bytesWritten) throws IOException {
|
||||
super.increaseBytesWritten(bytesWritten);
|
||||
long curBytes = getBytesWritten();
|
||||
if (curBytes > maxBytes) {
|
||||
throw new IOException("Maximum number of bytes ["
|
||||
+ SizeUtil.prettyByteSize(maxBytes)
|
||||
+ "] has been exceeded by stream");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Auth Plug-in
|
||||
Bundle-SymbolicName: com.raytheon.uf.edex.auth
|
||||
Bundle-Version: 1.12.1174.qualifier
|
||||
Bundle-Version: 1.14.0
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.11.31",
|
||||
|
@ -10,7 +10,8 @@ Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.11.31",
|
|||
com.raytheon.uf.common.auth;bundle-version="1.0.0",
|
||||
com.raytheon.edex.common;bundle-version="1.11.31",
|
||||
com.raytheon.uf.common.status;bundle-version="1.11.31",
|
||||
com.raytheon.uf.common.comm;bundle-version="1.12.1174"
|
||||
com.raytheon.uf.common.comm;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.util
|
||||
Export-Package: com.raytheon.uf.edex.auth,
|
||||
com.raytheon.uf.edex.auth.authentication,
|
||||
com.raytheon.uf.edex.auth.req,
|
||||
|
|
|
@ -2,4 +2,5 @@ source.. = src/
|
|||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
res/
|
||||
res/,\
|
||||
resources/
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
<bean id="routeWrapper" class="com.raytheon.uf.edex.auth.RemoteRequestRouteWrapper">
|
||||
<property name="server" ref="serializeServer" />
|
||||
<property name="byteLimitInMB" value="${thriftService.byteLimitInMB}" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,4 @@
|
|||
# byte limit for input and output streams to the thrift service.
|
||||
# After specified number of bytes, the stream is rejected to
|
||||
# prevent jvm OutOfMemory as the client is doing something wrong.
|
||||
thriftService.byteLimitInMB=100
|
|
@ -19,7 +19,10 @@
|
|||
**/
|
||||
package com.raytheon.uf.edex.auth;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.raytheon.uf.common.auth.AuthException;
|
||||
import com.raytheon.uf.common.auth.resp.AuthServerErrorResponse;
|
||||
|
@ -31,7 +34,10 @@ import com.raytheon.uf.common.serialization.comm.RequestWrapper;
|
|||
import com.raytheon.uf.common.serialization.comm.response.ServerErrorResponse;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.util.ByteArrayOutputStreamPool;
|
||||
import com.raytheon.uf.common.util.SizeUtil;
|
||||
import com.raytheon.uf.common.util.stream.LimitingInputStream;
|
||||
import com.raytheon.uf.common.util.stream.LimitingOutputStream;
|
||||
|
||||
/**
|
||||
* Wrapper for camel route so Serialization exceptions can be caught and
|
||||
|
@ -48,6 +54,7 @@ import com.raytheon.uf.common.util.SizeUtil;
|
|||
* reduce garbage objected generated by
|
||||
* camel doing the auto conversion.
|
||||
* Feb 06, 2014 2672 bsteffen Return error when Stream is not consumed.
|
||||
* Apr 15, 2014 2928 rjpeter Limit data streams read in and written out.
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -55,20 +62,31 @@ import com.raytheon.uf.common.util.SizeUtil;
|
|||
*/
|
||||
|
||||
public class RemoteRequestRouteWrapper {
|
||||
|
||||
private static final IUFStatusHandler thriftSrvLogger = UFStatus
|
||||
.getNamedHandler("ThriftSrvRequestLogger");
|
||||
|
||||
private RemoteRequestServer server;
|
||||
|
||||
private int byteLimitInMB;
|
||||
|
||||
public byte[] executeThrift(InputStream data) {
|
||||
/*
|
||||
* This stream does not need to be closed, Camel will handle closing of
|
||||
* data
|
||||
*/
|
||||
InputStream inputStream = null;
|
||||
OutputStream outStream = null;
|
||||
|
||||
try {
|
||||
long startTime = System.currentTimeMillis();
|
||||
inputStream = new LimitingInputStream(data, byteLimitInMB
|
||||
* SizeUtil.BYTES_PER_MB);
|
||||
Object obj = SerializationUtil.transformFromThrift(Object.class,
|
||||
data);
|
||||
int remaining = data.available();
|
||||
inputStream);
|
||||
|
||||
int remaining = inputStream.available();
|
||||
if (remaining == 1) {
|
||||
int tail = data.read();
|
||||
int tail = inputStream.read();
|
||||
/*
|
||||
* When http proxies are being used there is a single null
|
||||
* character at the end of the message, no need to panic.
|
||||
|
@ -89,7 +107,14 @@ public class RemoteRequestRouteWrapper {
|
|||
request = (IServerRequest) obj;
|
||||
}
|
||||
Object rvalObj = server.handleThriftRequest(request);
|
||||
byte[] rval = SerializationUtil.transformToThrift(rvalObj);
|
||||
|
||||
ByteArrayOutputStream baos = ByteArrayOutputStreamPool
|
||||
.getInstance().getStream();
|
||||
outStream = new LimitingOutputStream(baos, byteLimitInMB
|
||||
* SizeUtil.BYTES_PER_MB);
|
||||
|
||||
SerializationUtil.transformToThriftUsingStream(rvalObj, outStream);
|
||||
byte[] rval = baos.toByteArray();
|
||||
long endTime = System.currentTimeMillis();
|
||||
StringBuilder sb = new StringBuilder(300);
|
||||
sb.append("Handled ").append(obj.toString()).append(" in ")
|
||||
|
@ -119,6 +144,21 @@ public class RemoteRequestRouteWrapper {
|
|||
"Failed to serialize throwable to client", e);
|
||||
return new byte[] {};
|
||||
}
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (outStream != null) {
|
||||
try {
|
||||
outStream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,4 +170,11 @@ public class RemoteRequestRouteWrapper {
|
|||
this.server = server;
|
||||
}
|
||||
|
||||
public int getByteLimitInMB() {
|
||||
return byteLimitInMB;
|
||||
}
|
||||
|
||||
public void setByteLimitInMB(int byteLimitInMB) {
|
||||
this.byteLimitInMB = byteLimitInMB;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#Thu Mar 26 10:32:57 CDT 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
|
|
|
@ -161,7 +161,7 @@ public class Main {
|
|||
m.invoke(null, new Object[0]);
|
||||
}
|
||||
System.exit(0);
|
||||
} catch (ClassNotFoundException e) {
|
||||
} catch (ClassNotFoundException | LinkageError e) {
|
||||
logger.error("Could not load class", e);
|
||||
if (cl != null) {
|
||||
StringBuilder msg = new StringBuilder(1000);
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -75,6 +76,10 @@ public class Executor {
|
|||
public static void start() throws Exception {
|
||||
final long t0 = System.currentTimeMillis();
|
||||
|
||||
Thread.currentThread().setName("EDEXMain");
|
||||
System.setProperty("System.status", "Starting");
|
||||
final AtomicBoolean shutdownContexts = new AtomicBoolean(false);
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -87,7 +92,12 @@ public class Executor {
|
|||
.append("\n* EDEX ESB is shutting down *")
|
||||
.append("\n**************************************************");
|
||||
logger.info(msg.toString());
|
||||
ctxMgr.stopContexts();
|
||||
if (shutdownContexts.get()) {
|
||||
ctxMgr.stopContexts();
|
||||
} else {
|
||||
logger.info("Contexts never started, skipping context shutdown");
|
||||
}
|
||||
|
||||
long t2 = System.currentTimeMillis();
|
||||
msg.setLength(0);
|
||||
msg.append("\n**************************************************");
|
||||
|
@ -102,9 +112,6 @@ public class Executor {
|
|||
}
|
||||
});
|
||||
|
||||
Thread.currentThread().setName("EDEXMain");
|
||||
System.setProperty("System.status", "Starting");
|
||||
|
||||
List<String> xmlFiles = new ArrayList<String>();
|
||||
|
||||
List<File> propertiesFiles = new ArrayList<File>();
|
||||
|
@ -166,6 +173,8 @@ public class Executor {
|
|||
ContextManager ctxMgr = (ContextManager) context
|
||||
.getBean("contextManager");
|
||||
|
||||
shutdownContexts.set(true);
|
||||
|
||||
// start final routes
|
||||
ctxMgr.startContexts();
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ Require-Bundle: com.raytheon.edex.common,
|
|||
org.apache.commons.lang,
|
||||
com.raytheon.uf.edex.decodertools;bundle-version="1.0.0",
|
||||
com.raytheon.uf.common.dataplugin.text,
|
||||
com.raytheon.uf.common.site;bundle-version="1.12.1152"
|
||||
com.raytheon.uf.common.site;bundle-version="1.12.1152",
|
||||
com.raytheon.uf.common.status
|
||||
Export-Package: com.raytheon.uf.edex.services,
|
||||
com.raytheon.uf.edex.services.textdbimpl,
|
||||
com.raytheon.uf.edex.services.textdbsrv
|
||||
|
|
|
@ -2,4 +2,5 @@ source.. = src/
|
|||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
res/
|
||||
res/,\
|
||||
resources/
|
|
@ -3,6 +3,11 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
<bean id="textDbSrvWrapper" class = "com.raytheon.uf.edex.textdbsrv.TextDBSrvWrapper">
|
||||
<property name="textdbSrv" ref="textdbsrv"/>
|
||||
<property name="byteLimitInMB" value="${textdbsrv.byteLimitInMB}"/>
|
||||
</bean>
|
||||
|
||||
<camelContext id="textdbsrv-request-camel" xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="errorHandler">
|
||||
|
||||
<endpoint id="textdbsrvXml_from"
|
||||
|
@ -10,9 +15,7 @@
|
|||
|
||||
<route id="textdbsrvXml">
|
||||
<from uri="ref:textdbsrvXml_from" />
|
||||
<bean ref="serializationUtil" method="unmarshalFromXml" />
|
||||
<bean ref="textdbsrv" method="processMessage" />
|
||||
<bean ref="serializationUtil" method="marshalToXml" />
|
||||
<bean ref="textDbSrvWrapper" method="executeTextDBMessage" />
|
||||
</route>
|
||||
</camelContext>
|
||||
</beans>
|
|
@ -0,0 +1,4 @@
|
|||
# byte limit for input and output streams to the textdb srv.
|
||||
# After specified number of bytes, the stream is rejected to
|
||||
# prevent jvm OutOfMemory as the client is doing something wrong.
|
||||
textdbsrv.byteLimitInMB=10
|
|
@ -0,0 +1,152 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
*/
|
||||
package com.raytheon.uf.edex.textdbsrv;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.raytheon.uf.common.message.Message;
|
||||
import com.raytheon.uf.common.serialization.SerializationUtil;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.util.ByteArrayOutputStreamPool;
|
||||
import com.raytheon.uf.common.util.SizeUtil;
|
||||
import com.raytheon.uf.common.util.stream.LimitingInputStream;
|
||||
import com.raytheon.uf.common.util.stream.LimitingOutputStream;
|
||||
import com.raytheon.uf.edex.services.TextDBSrv;
|
||||
import com.raytheon.uf.edex.services.textdbimpl.CommandExecutor;
|
||||
|
||||
/**
|
||||
* Thin wrapper around TextDBSrv to handle marshalling/unmarshalling and
|
||||
* limiting of the byte stream.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 15, 2014 2928 rjpeter Initial creation.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TextDBSrvWrapper {
|
||||
private final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(TextDBSrvWrapper.class);
|
||||
|
||||
/**
|
||||
* The limit of bytes that we are able to read in without erroring off.
|
||||
*/
|
||||
private long byteLimitInMB;
|
||||
|
||||
/**
|
||||
* TextDbSrv implementation to use.
|
||||
*/
|
||||
private TextDBSrv textdbSrv;
|
||||
|
||||
/**
|
||||
* Unmarshalls the input stream as xml data and sends to textdbsrv for
|
||||
* processing.
|
||||
*
|
||||
* @param is
|
||||
* @return
|
||||
*/
|
||||
public byte[] executeTextDBMessage(InputStream xmlDataStream) {
|
||||
/*
|
||||
* This stream does not need to be closed, Camel will handle closing of
|
||||
* data
|
||||
*/
|
||||
InputStream inputStream = null;
|
||||
Message rval;
|
||||
|
||||
try {
|
||||
inputStream = new LimitingInputStream(xmlDataStream, byteLimitInMB
|
||||
* SizeUtil.BYTES_PER_MB);
|
||||
Message message = SerializationUtil.jaxbUnmarshalFromInputStream(
|
||||
Message.class, inputStream);
|
||||
rval = textdbSrv.processMessage(message);
|
||||
} catch (Throwable e) {
|
||||
statusHandler
|
||||
.error("Error occured processing textDbSrv message", e);
|
||||
rval = CommandExecutor
|
||||
.createErrorMessage("Error occurred during processing: "
|
||||
+ e.getLocalizedMessage());
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OutputStream outStream = null;
|
||||
int tries = 0;
|
||||
|
||||
while (tries < 2) {
|
||||
try {
|
||||
ByteArrayOutputStream baos = ByteArrayOutputStreamPool
|
||||
.getInstance().getStream();
|
||||
outStream = new LimitingOutputStream(baos, byteLimitInMB
|
||||
* SizeUtil.BYTES_PER_MB);
|
||||
SerializationUtil.jaxbMarshalToStream(rval, outStream);
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
statusHandler.error("Error occured marshalling response", e);
|
||||
tries++;
|
||||
rval = CommandExecutor
|
||||
.createErrorMessage("Error occurred during processing: "
|
||||
+ e.getLocalizedMessage());
|
||||
} finally {
|
||||
if (outStream != null) {
|
||||
try {
|
||||
outStream.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getByteLimitInMB() {
|
||||
return byteLimitInMB;
|
||||
}
|
||||
|
||||
public void setByteLimitInMB(long byteLimitInMB) {
|
||||
this.byteLimitInMB = byteLimitInMB;
|
||||
}
|
||||
|
||||
public TextDBSrv getTextdbSrv() {
|
||||
return textdbSrv;
|
||||
}
|
||||
|
||||
public void setTextdbSrv(TextDBSrv textdbSrv) {
|
||||
this.textdbSrv = textdbSrv;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue