Omaha #3275 - moving developer tools to separate repository
Former-commit-id:436ce72db9
[formerly5fd1555ff9
[formerly da96ff215e03ffdad7e7d157f6f5539663ad47ce]] Former-commit-id:5fd1555ff9
Former-commit-id:6c0a7da2a0
This commit is contained in:
parent
42495a5551
commit
875e655efd
187 changed files with 0 additions and 17458 deletions
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
2
MHSEmulator/.gitignore
vendored
2
MHSEmulator/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
out/
|
||||
*.jar
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>MHSEmulator</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,12 +0,0 @@
|
|||
#Thu Mar 24 14:25:46 CDT 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
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
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project default="build.all" name="Create Runnable Jar for Project MockMHS">
|
||||
|
||||
<target name="build.all">
|
||||
<antcall target="create_server" />
|
||||
<antcall target="create_client" />
|
||||
</target>
|
||||
<target name="create_server">
|
||||
<jar destfile="out/SocketServer.jar" filesetmanifest="mergewithoutmain">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="mhs.core.SocketSrv" />
|
||||
<attribute name="Class-Path" value="." />
|
||||
</manifest>
|
||||
<fileset dir="bin" />
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="create_client">
|
||||
<jar destfile="out/SocketClient.jar" filesetmanifest="mergewithoutmain">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="mhs.core.SocketClient" />
|
||||
<attribute name="Class-Path" value="." />
|
||||
</manifest>
|
||||
<fileset dir="bin" />
|
||||
</jar>
|
||||
</target>
|
||||
</project>
|
|
@ -1,7 +0,0 @@
|
|||
11 /awips2/GFESuite/bin/iscDataRec %MSGID %SUBJECT %ENCLIST
|
||||
20 /bin/mv %ENCLOSE(1) %CENTRAL_SERVER/%SUBJECT
|
||||
21 msg_send -e %CENTRAL_SERVER/%SUBJECT -a %SENDER -c 22
|
||||
22 /awips2/GFESuite/ServiceBackup/scripts/receive_configuration %ENCLIST
|
||||
23 msg_send -e %CENTRAL_SERVER/%SUBJECT -a %SENDER -c 24
|
||||
24 /awips2/GFESuite/ServiceBackup/scripts/receive_grids %ENCLIST
|
||||
25 /awips2/GFESuite/ServiceBackup/scripts/receive_grids_from_backup_site %ENCLOSE(1)
|
|
@ -1,26 +0,0 @@
|
|||
# The port that the socket communication will take place on
|
||||
SERVER_PORT=2000
|
||||
|
||||
# The directory the mock rsync process will look in for exporting grids
|
||||
EXPORT_GRIDS=/awips2/GFESuite/exportgrids/
|
||||
|
||||
# The directory to be used for transferring data files
|
||||
DATA_FOLDER=/awipscm/mhsTest/mhs/received/
|
||||
|
||||
# The directory acting as the central server repository for
|
||||
# configurations and grids used by GFE service backup
|
||||
CENTRAL_SERVER=/awipscm/mhsTest/mhs/central_server/
|
||||
|
||||
# Directory containing the socket server and client logs
|
||||
LOG_DIR=/awipscm/mhsTest/mhs/logs/
|
||||
|
||||
# Bin directory containing helper functions
|
||||
UTIL_DIR=/awipscm/mhsTest/mhs/util/
|
||||
|
||||
# The IP address of the server acting as the test NCF server
|
||||
TNCF=155.157.61.163
|
||||
|
||||
# Place the MHSID and server IPs of the servers participating in
|
||||
# ISC communcation below. A comma separated list of IPS may be
|
||||
# used if a cluster
|
||||
# Example: LWX=255.255.99.1,255.255.99.2
|
|
@ -1,138 +0,0 @@
|
|||
package mhs.core;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Library module for MHS emulator.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ??? ?? ???? bphillip Initial creation
|
||||
* Jul 15, 2013 #2099 dgilling Use safer exception handling for file I/O.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MhsUtil {
|
||||
|
||||
public static final SimpleDateFormat logDateFormat = new SimpleDateFormat(
|
||||
"yyyyMMdd");
|
||||
|
||||
public static final SimpleDateFormat logMsgFormat = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss :: ");
|
||||
|
||||
public static final String END_TOKEN = "------!!!!END!!!!------";
|
||||
|
||||
public static final File MY_MHS_FILE = new File("/awips2/.myMHS");
|
||||
|
||||
public static final File MSG_ID_FILE = new File("/awips2/.msgCount");
|
||||
|
||||
private MhsUtil() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static String getMsgId() throws IOException {
|
||||
if (MSG_ID_FILE.createNewFile()) {
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(MSG_ID_FILE));
|
||||
out.write("0");
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferedReader in = null;
|
||||
int newMsgNumber;
|
||||
try {
|
||||
in = new BufferedReader(new FileReader(MSG_ID_FILE));
|
||||
String msgId = in.readLine().trim();
|
||||
newMsgNumber = Integer.parseInt(msgId) + 1;
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(MSG_ID_FILE));
|
||||
out.write(String.valueOf(newMsgNumber));
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
NumberFormat formatter = new DecimalFormat("000000");
|
||||
return formatter.format(newMsgNumber);
|
||||
}
|
||||
|
||||
public static int byteArrayToInt(byte[] b, int offset) {
|
||||
int value = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int shift = (4 - 1 - i) * 8;
|
||||
value += (b[i + offset] & 0x000000FF) << shift;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static byte[] intToByteArray(int value) {
|
||||
byte[] b = new byte[4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int offset = (b.length - 1 - i) * 8;
|
||||
b[i] = (byte) ((value >>> offset) & 0xFF);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public static void logMsg(String logDir, String mode, Object... msg) {
|
||||
String message = "";
|
||||
File logFile = null;
|
||||
|
||||
try {
|
||||
logFile = new File(logDir
|
||||
+ InetAddress.getLocalHost().getCanonicalHostName() + "-"
|
||||
+ mode + "-" + MhsUtil.logDateFormat.format(new Date()));
|
||||
logFile.createNewFile();
|
||||
|
||||
message += MhsUtil.logMsgFormat.format(new Date());
|
||||
for (Object obj : msg) {
|
||||
message += obj.toString() + " ";
|
||||
}
|
||||
message += "\n";
|
||||
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(logFile, true));
|
||||
out.write(message.trim());
|
||||
out.write("\n");
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
package mhs.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ??? ?? ???? bphillip Initial creation
|
||||
* Jul 15, 2013 #2099 dgilling Modify to support recursive file listing
|
||||
* since export grids dir structure uses
|
||||
* multiple folders.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RsyncThread implements Runnable {
|
||||
|
||||
private static final Map<String, Long> fileVersion = new HashMap<String, Long>();
|
||||
|
||||
private Properties props;
|
||||
|
||||
public RsyncThread(Properties props) {
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String exportGridsDir = props.getProperty("EXPORT_GRIDS");
|
||||
String centralServerDir = props.getProperty("CENTRAL_SERVER");
|
||||
String packScriptDir = props.getProperty("UTIL_DIR");
|
||||
|
||||
Collection<File> fileList = listCdfFiles(new File(exportGridsDir));
|
||||
for (File file : fileList) {
|
||||
if (file.isFile()) {
|
||||
String currentFilePath = file.getPath();
|
||||
|
||||
boolean copy = true;
|
||||
if ((fileVersion.containsKey(currentFilePath))
|
||||
&& (fileVersion.get(currentFilePath) >= file
|
||||
.lastModified())) {
|
||||
copy = false;
|
||||
}
|
||||
|
||||
if (copy) {
|
||||
String[] copyCmd = new String[] {
|
||||
packScriptDir + "/packageFile", currentFilePath,
|
||||
packScriptDir, file.getName().substring(0, 3),
|
||||
centralServerDir };
|
||||
try {
|
||||
Runtime.getRuntime().exec(copyCmd);
|
||||
fileVersion.put(currentFilePath, file.lastModified());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<File> listCdfFiles(File path) {
|
||||
Collection<File> fileList = new LinkedList<File>();
|
||||
FileFilter cdfFilter = new FileFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return (pathname.isDirectory() || pathname.getName().endsWith(
|
||||
".netcdf"));
|
||||
}
|
||||
};
|
||||
innerListFiles(path, fileList, cdfFilter);
|
||||
return fileList;
|
||||
}
|
||||
|
||||
private void innerListFiles(File path, Collection<File> fileList,
|
||||
FileFilter filter) {
|
||||
try {
|
||||
File[] matchingFiles = path.listFiles(filter);
|
||||
for (File file : matchingFiles) {
|
||||
if (file.isDirectory()) {
|
||||
innerListFiles(file, fileList, filter);
|
||||
} else if (file.isFile()) {
|
||||
fileList.add(file);
|
||||
}
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
package mhs.core;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class SocketClient {
|
||||
|
||||
private Map<String, String> parameters = new HashMap<String, String>();
|
||||
|
||||
private Properties serverProps;
|
||||
|
||||
private String myMHS;
|
||||
|
||||
private String propertiesFile;
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
new SocketClient(parseArgs(args)).msg_send();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String> parseArgs(String[] args) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
args[i] = args[i].trim();
|
||||
if (args[i].equals("-s")) {
|
||||
params.put("-s", args[i + 1]);
|
||||
} else if (args[i].equals("-a")) {
|
||||
params.put("-a", args[i + 1]);
|
||||
} else if (args[i].equals("-i")) {
|
||||
params.put("-i", args[i + 1]);
|
||||
} else if (args[i].equals("-c")) {
|
||||
params.put("-c", args[i + 1]);
|
||||
} else if (args[i].equals("-p")) {
|
||||
params.put("-p", args[i + 1]);
|
||||
} else if (args[i].equals("-e")) {
|
||||
params.put("-e", args[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
private SocketClient(Map<String, String> params) throws Exception {
|
||||
this.getMhsAndProperties();
|
||||
this.parameters = params;
|
||||
loadProperties();
|
||||
}
|
||||
|
||||
private void getMhsAndProperties() throws Exception {
|
||||
BufferedReader in = null;
|
||||
in = new BufferedReader(new FileReader(MhsUtil.MY_MHS_FILE));
|
||||
myMHS = in.readLine().trim();
|
||||
propertiesFile = in.readLine().trim();
|
||||
in.close();
|
||||
}
|
||||
|
||||
private void loadProperties() throws Exception {
|
||||
serverProps = new Properties();
|
||||
FileInputStream fis = new FileInputStream(new File(propertiesFile));
|
||||
serverProps.load(fis);
|
||||
fis.close();
|
||||
}
|
||||
|
||||
private InetAddress getDest(String recipient) throws Exception {
|
||||
log("Getting destination of: " + recipient);
|
||||
InetAddress address = null;
|
||||
String addrs = serverProps.getProperty(recipient);
|
||||
if (addrs.contains(",")) {
|
||||
address = InetAddress.getByName(addrs.split(",")[0].trim());
|
||||
} else {
|
||||
address = InetAddress.getByName(addrs);
|
||||
}
|
||||
log("Address resolved to: " + address);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
private void msg_send() {
|
||||
String error = "";
|
||||
try {
|
||||
loadProperties();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
error = e.getLocalizedMessage();
|
||||
}
|
||||
String[] recipients = getRecipientAddresses();
|
||||
String msg_id = "";
|
||||
try {
|
||||
msg_id = MhsUtil.getMsgId();
|
||||
} catch (Exception e1) {
|
||||
log(e1.getLocalizedMessage());
|
||||
}
|
||||
for (String recipient : recipients) {
|
||||
try {
|
||||
log("Connecting to Site: " + recipient);
|
||||
if (serverProps.getProperty(recipient) == null) {
|
||||
log("Unknown MHS: " + recipient);
|
||||
continue;
|
||||
}
|
||||
InetAddress addr = getDest(recipient);
|
||||
int port = Integer.parseInt(serverProps
|
||||
.getProperty("SERVER_PORT"));
|
||||
|
||||
// This constructor will block until the connection succeeds
|
||||
Socket socket = new Socket(addr, port);
|
||||
|
||||
try {
|
||||
OutputStream wr = socket.getOutputStream();
|
||||
|
||||
log("Sending Message...");
|
||||
|
||||
// send the msg id
|
||||
sendMsg(wr, "-MSGID");
|
||||
sendMsg(wr, msg_id);
|
||||
|
||||
// Send the subject
|
||||
if (parameters.containsKey("-s")) {
|
||||
sendMsg(wr, "-s");
|
||||
sendMsg(wr, parameters.get("-s"));
|
||||
}
|
||||
|
||||
// Send the WFO
|
||||
if (parameters.containsKey("-i")) {
|
||||
sendMsg(wr, "-i");
|
||||
sendMsg(wr, parameters.get("-i"));
|
||||
}
|
||||
|
||||
// Send the priority
|
||||
if (parameters.containsKey("-p")) {
|
||||
sendMsg(wr, "-p");
|
||||
sendMsg(wr, parameters.get("-p"));
|
||||
}
|
||||
|
||||
// Send the priority
|
||||
if (parameters.containsKey("-c")) {
|
||||
sendMsg(wr, "-c");
|
||||
sendMsg(wr, parameters.get("-c"));
|
||||
}
|
||||
|
||||
if (parameters.containsKey("-e")) {
|
||||
String[] files = getEnclosures();
|
||||
for (String file : files) {
|
||||
sendMsg(wr, "-file");
|
||||
sendFile(wr, file);
|
||||
}
|
||||
}
|
||||
|
||||
sendMsg(wr, MhsUtil.END_TOKEN);
|
||||
log("Message Sent!");
|
||||
wr.close();
|
||||
socket.close();
|
||||
log("Disconnecting from Site: " + recipient);
|
||||
} catch (IOException e) {
|
||||
error = e.getLocalizedMessage();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
error = e.getLocalizedMessage();
|
||||
}
|
||||
}
|
||||
if (error.isEmpty()) {
|
||||
try {
|
||||
System.out.println(myMHS + "-" + msg_id);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Unable to get new message id number!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
System.out.println("MHS ERROR: " + error);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String[] getRecipientAddresses() {
|
||||
String[] retVal = new String[] {};
|
||||
if (parameters.containsKey("-a")) {
|
||||
retVal = parameters.get("-a").split(",");
|
||||
for (int i = 0; i < retVal.length; i++) {
|
||||
retVal[i] = retVal[i].toUpperCase().trim();
|
||||
if (retVal[i].contains("TNCF")) {
|
||||
retVal[i] = "TNCF";
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private String[] getEnclosures() {
|
||||
String[] retVal = new String[] {};
|
||||
if (parameters.containsKey("-e")) {
|
||||
retVal = parameters.get("-e").split(",");
|
||||
for (int i = 0; i < retVal.length; i++) {
|
||||
retVal[i] = retVal[i].trim();
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private void sendFile(OutputStream wr, String file) throws Exception {
|
||||
byte[] fileBytes = readFile(file);
|
||||
wr.write(MhsUtil.intToByteArray(fileBytes.length));
|
||||
wr.write(fileBytes);
|
||||
wr.flush();
|
||||
}
|
||||
|
||||
private void sendMsg(OutputStream wr, String msg) throws Exception {
|
||||
wr.write(MhsUtil.intToByteArray(msg.getBytes().length));
|
||||
wr.write(msg.getBytes());
|
||||
wr.flush();
|
||||
}
|
||||
|
||||
private byte[] readFile(String fileName) throws Exception {
|
||||
File theFile = new File(fileName);
|
||||
byte[] fileContents = new byte[(int) theFile.length()];
|
||||
FileInputStream fis = new FileInputStream(theFile);
|
||||
BufferedInputStream bis = new BufferedInputStream(fis);
|
||||
bis.read(fileContents, 0, fileContents.length);
|
||||
return fileContents;
|
||||
}
|
||||
|
||||
private void log(Object... msg) {
|
||||
MhsUtil.logMsg(serverProps.getProperty("LOG_DIR"), "client", msg);
|
||||
}
|
||||
}
|
|
@ -1,426 +0,0 @@
|
|||
package mhs.core;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ??? ?? ???? bphillip Initial creation
|
||||
* Jul 15, 2013 #2009 dgilling Code cleanup.
|
||||
* Jul 23, 2013 #2009 dgilling Fix NullPointerException on start up.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SocketSrv {
|
||||
|
||||
private File propertiesFile;
|
||||
|
||||
private boolean runRsync;
|
||||
|
||||
private String myMHS;
|
||||
|
||||
private Properties serverProps;
|
||||
|
||||
private ExecutorService mhsRequestHandler;
|
||||
|
||||
private ScheduledExecutorService rsyncThread;
|
||||
|
||||
private int fileIndex = 0;
|
||||
|
||||
private String fileBase;
|
||||
|
||||
private String configDir;
|
||||
|
||||
private String centralServerDir;
|
||||
|
||||
private String binDir;
|
||||
|
||||
private List<String> files = new ArrayList<String>();
|
||||
|
||||
private Map<Integer, String> commandMap;
|
||||
|
||||
private int serverPort;
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (!System.getProperty("user.name").equals("root")) {
|
||||
System.out
|
||||
.println("Socket Server must be run as root user! Current user: "
|
||||
+ System.getProperty("user.name"));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File propertiesFile = new File(args[0]);
|
||||
String mhsId = args[1];
|
||||
boolean startRsync = Boolean.parseBoolean(args[2]);
|
||||
|
||||
if (!propertiesFile.isFile()) {
|
||||
System.out.println("Specified properties file ["
|
||||
+ propertiesFile.toString() + "] does not exist. Exiting.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
final SocketSrv server = new SocketSrv(propertiesFile, mhsId,
|
||||
startRsync);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
server.shutdown();
|
||||
}
|
||||
});
|
||||
server.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private SocketSrv(File propertiesFile, String mhsId, boolean startRsync)
|
||||
throws UnknownHostException, IOException {
|
||||
System.out.println("Setting up server ("
|
||||
+ InetAddress.getLocalHost().getCanonicalHostName() + ")");
|
||||
|
||||
this.propertiesFile = propertiesFile;
|
||||
this.myMHS = mhsId;
|
||||
this.runRsync = startRsync;
|
||||
|
||||
writeMyMHS(myMHS);
|
||||
|
||||
this.commandMap = new HashMap<Integer, String>();
|
||||
this.configDir = this.propertiesFile.getParent();
|
||||
loadProperties();
|
||||
loadRcvHandlerTable();
|
||||
|
||||
this.fileBase = serverProps.getProperty("DATA_FOLDER");
|
||||
this.centralServerDir = serverProps.getProperty("CENTRAL_SERVER");
|
||||
this.binDir = serverProps.getProperty("UTIL_DIR");
|
||||
this.serverPort = Integer.parseInt(serverProps
|
||||
.getProperty("SERVER_PORT"));
|
||||
|
||||
System.out.println("\tReceived Data directory: " + fileBase);
|
||||
System.out.println("\tCentral Server Data Directory: "
|
||||
+ centralServerDir);
|
||||
System.out.println("\tConfig directory: " + configDir);
|
||||
|
||||
this.mhsRequestHandler = Executors.newSingleThreadExecutor();
|
||||
if (this.runRsync) {
|
||||
System.out.println("Starting Rsync Thread...");
|
||||
this.rsyncThread = Executors.newSingleThreadScheduledExecutor();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
if (rsyncThread != null) {
|
||||
Runnable rsyncJob = new RsyncThread(serverProps);
|
||||
rsyncThread
|
||||
.scheduleWithFixedDelay(rsyncJob, 1, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
ServerSocket socket = new ServerSocket(serverPort);
|
||||
while (!mhsRequestHandler.isShutdown()) {
|
||||
try {
|
||||
log("Waiting for connections...");
|
||||
final Socket conn = socket.accept();
|
||||
Runnable processTask = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
handleRequest(conn);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
mhsRequestHandler.execute(processTask);
|
||||
} catch (RejectedExecutionException e) {
|
||||
if (!mhsRequestHandler.isShutdown()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
mhsRequestHandler.shutdown();
|
||||
if (rsyncThread != null) {
|
||||
rsyncThread.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRequest(Socket connection) throws IOException,
|
||||
InterruptedException {
|
||||
InetSocketAddress client = (InetSocketAddress) connection
|
||||
.getRemoteSocketAddress();
|
||||
log("Connected to client: " + client.getHostName() + " at " + client);
|
||||
|
||||
loadProperties();
|
||||
String sender = getMhsOfSender(client);
|
||||
log("Message is from: " + sender);
|
||||
|
||||
InputStream in = connection.getInputStream();
|
||||
byte[] message = null;
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
String flag = "";
|
||||
while (true) {
|
||||
if (in.available() == 0) {
|
||||
Thread.sleep(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
message = getMessage(in);
|
||||
|
||||
if (!flag.equals("-file")) {
|
||||
String strMessage = new String(message);
|
||||
if (strMessage.equals(MhsUtil.END_TOKEN)) {
|
||||
log("Disconnected from client: " + client);
|
||||
if (params.containsKey("-c")) {
|
||||
executeAction(sender, params);
|
||||
files.clear();
|
||||
params.clear();
|
||||
flag = "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (strMessage.startsWith("-")) {
|
||||
flag = strMessage;
|
||||
} else {
|
||||
params.put(flag, strMessage);
|
||||
}
|
||||
} else {
|
||||
log("File Received of size: " + message.length);
|
||||
files.add(writeToFile(myMHS + "-" + params.get("-MSGID"),
|
||||
message));
|
||||
flag = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMyMHS(String myMHS) throws IOException {
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(MhsUtil.MY_MHS_FILE));
|
||||
out.write(myMHS + "\n");
|
||||
out.write(propertiesFile.getPath());
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadProperties() throws IOException {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(propertiesFile);
|
||||
Properties newProps = new Properties();
|
||||
newProps.load(fis);
|
||||
serverProps = newProps;
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void executeAction(String sender, Map<String, String> params)
|
||||
throws IOException, InterruptedException {
|
||||
int action = Integer.parseInt(params.get("-c"));
|
||||
|
||||
if (!commandMap.containsKey(action)) {
|
||||
log("No action mapped for command: " + action);
|
||||
return;
|
||||
}
|
||||
|
||||
String fileList = "";
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
fileList += files.get(i);
|
||||
if (i != (files.size() - 1)) {
|
||||
fileList += ",";
|
||||
}
|
||||
}
|
||||
String command = commandMap.get(action);
|
||||
|
||||
Pattern pat = Pattern.compile("%ENCLOSE\\(([0-9]{1,5})\\)");
|
||||
Matcher matcher = pat.matcher(command);
|
||||
while (matcher.find()) {
|
||||
int fileNumber = Integer.parseInt(matcher.group(1));
|
||||
String encloseGroup = matcher.group();
|
||||
command = command.replace(encloseGroup, files.get(fileNumber - 1));
|
||||
}
|
||||
|
||||
command = command.replace("%MSGID", myMHS + "-" + params.get("-MSGID"));
|
||||
if (params.containsKey("-s")) {
|
||||
command = command.replace("%SUBJECT", params.get("-s"));
|
||||
}
|
||||
if (!fileList.isEmpty()) {
|
||||
command = command.replace("%ENCLIST", fileList);
|
||||
}
|
||||
command = command.replace("%CENTRAL_SERVER", centralServerDir);
|
||||
command = command.replace("%BIN_DIR", binDir);
|
||||
command = command.replace("%DATA_DIR", fileBase);
|
||||
command = command.replace("%SENDER", sender.toLowerCase());
|
||||
String[] cmdArray = command.split(" ");
|
||||
log("Executing: " + command);
|
||||
|
||||
Process p = null;
|
||||
try {
|
||||
p = Runtime.getRuntime().exec(cmdArray);
|
||||
p.waitFor();
|
||||
} finally {
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getMessage(InputStream in) throws IOException {
|
||||
byte[] sizeBytes = new byte[4];
|
||||
readBytes(in, sizeBytes);
|
||||
int expectedSize = MhsUtil.byteArrayToInt(sizeBytes, 0);
|
||||
byte[] message = new byte[expectedSize];
|
||||
readBytes(in, message);
|
||||
return message;
|
||||
}
|
||||
|
||||
private void readBytes(InputStream in, byte[] bytes) throws IOException {
|
||||
int expectedSize = bytes.length;
|
||||
int bytesRead = 0;
|
||||
int totalBytesRead = 0;
|
||||
while (totalBytesRead < expectedSize) {
|
||||
bytesRead = in.read(bytes, totalBytesRead, expectedSize
|
||||
- totalBytesRead);
|
||||
totalBytesRead += bytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
private String writeToFile(String fileName, byte[] contents)
|
||||
throws IOException, InterruptedException {
|
||||
String fileFQN = fileBase + fileName + "." + getFileIndex();
|
||||
log("Writing file: " + fileFQN);
|
||||
|
||||
BufferedOutputStream out = null;
|
||||
try {
|
||||
out = new BufferedOutputStream(new FileOutputStream(new File(
|
||||
fileFQN)));
|
||||
out.write(contents);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
Process p = null;
|
||||
try {
|
||||
p = Runtime.getRuntime().exec(
|
||||
new String[] { "/bin/chmod", "777", fileFQN });
|
||||
p.waitFor();
|
||||
} finally {
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
}
|
||||
return fileFQN;
|
||||
}
|
||||
|
||||
private String getFileIndex() {
|
||||
fileIndex++;
|
||||
if (fileIndex == 1000) {
|
||||
fileIndex = 0;
|
||||
}
|
||||
|
||||
NumberFormat formatter = new DecimalFormat("000");
|
||||
return formatter.format(fileIndex);
|
||||
}
|
||||
|
||||
private void loadRcvHandlerTable() throws IOException {
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
in = new BufferedReader(new FileReader(configDir + File.separator
|
||||
+ "rcv_handler.tbl"));
|
||||
|
||||
String str = null;
|
||||
while ((str = in.readLine()) != null) {
|
||||
StringBuilder commandBuilder = new StringBuilder();
|
||||
String[] tokens = str.split(" ");
|
||||
for (int i = 1; i < tokens.length; i++) {
|
||||
String cmd = tokens[i].trim();
|
||||
if (!cmd.isEmpty()) {
|
||||
if (i != 1) {
|
||||
commandBuilder.append(' ');
|
||||
}
|
||||
commandBuilder.append(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
String commandString = commandBuilder.toString().trim();
|
||||
commandMap.put(Integer.parseInt(tokens[0]), commandString);
|
||||
}
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getMhsOfSender(InetSocketAddress address) {
|
||||
String hostAddress = address.getAddress().getHostAddress();
|
||||
for (String mhsId : serverProps.stringPropertyNames()) {
|
||||
String value = serverProps.getProperty(mhsId);
|
||||
if (value.contains(",")) {
|
||||
String[] addrs = value.split(",");
|
||||
for (String addr : addrs) {
|
||||
if (addr.contains(hostAddress)) {
|
||||
return mhsId;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (value.contains(hostAddress)) {
|
||||
return mhsId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void log(Object... msg) {
|
||||
MhsUtil.logMsg(serverProps.getProperty("LOG_DIR"), "server", msg);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# $1 = file to copy
|
||||
# $2 = bin directory
|
||||
# $3 = site name
|
||||
# $4 = central server directory
|
||||
|
||||
cd $2
|
||||
cp $1 $2
|
||||
|
||||
echo ${3} > siteID.txt
|
||||
tar cvf ${3}Grd.tar ${3}Grd.netcdf siteID.txt
|
||||
mv ${3}Grd.tar ${3}Grd
|
||||
cp ${3}Grd $4
|
||||
rm -f siteID.txt *.netcdf *.tar
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.edex.archive.feeder.feature</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.FeatureBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.FeatureNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1 +0,0 @@
|
|||
bin.includes = feature.xml
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feature
|
||||
id="com.raytheon.uf.edex.archive.feeder.feature"
|
||||
label="Archive Binary Feeder Feature"
|
||||
version="1.0.0.qualifier"
|
||||
provider-name="RAYTHEON">
|
||||
|
||||
<description url="http://www.example.com/description">
|
||||
Use for testing of archive binary files. Not part of standard EDEX.
|
||||
</description>
|
||||
|
||||
<copyright url="http://www.example.com/copyright">
|
||||
[Enter Copyright Description here.]
|
||||
</copyright>
|
||||
|
||||
<license url="http://www.example.com/license">
|
||||
[Enter License Description here.]
|
||||
</license>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.edex.archive.feeder"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.edex.archive.feeder</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,7 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -1,17 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Utility
|
||||
Bundle-SymbolicName: com.raytheon.uf.edex.archive.feeder
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
||||
com.raytheon.edex.common;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.edex.database;bundle-version="1.0.0",
|
||||
com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.status;bundle-version="1.12.1174",
|
||||
org.apache.camel;bundle-version="1.0.0",
|
||||
com.raytheon.uf.edex.site;bundle-version="1.0.0",
|
||||
com.raytheon.uf.edex.core;bundle-version="1.12.1174",
|
||||
org.apache.commons.beanutils;bundle-version="1.8.3"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ActivationPolicy: lazy
|
|
@ -1,20 +0,0 @@
|
|||
The com.raytheon.uf.edex.archive.feeder plugin is not part of the standard EDEX deploy.
|
||||
It is a tool for debugging the binary files generated for archiving.
|
||||
|
||||
The easiest way to generate this plugin jar is to add the following to
|
||||
com.raytheon.edex.feature.uframe/feature.xml:
|
||||
|
||||
<includes
|
||||
id="com.raytheon.uf.edex.archive.feeder.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
Then run the build.edex deploy-install.xml. This will create the plugin jar file:
|
||||
/awips2/edex/lib/plugins/com.raytheon.uf.edex.archive.feeder.jar
|
||||
|
||||
the needed configuration file:
|
||||
|
||||
/awips2/edex/conf/resources/com.raytheon.uf.edex.archive.feeder.properties
|
||||
|
||||
By placing these two files in the corresponding locations on the desired EDEX server and
|
||||
restarting EDEX will start the clusteredArchiveBinaryFeederProc. You can then drop the
|
||||
binary files into the archive.feeder.directory, default /tmp/archive-feeder.
|
|
@ -1,5 +0,0 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
res/
|
|
@ -1,19 +0,0 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
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">
|
||||
<camelContext id="clusteredArchiveBinaryFeederProc"
|
||||
xmlns="http://camel.apache.org/schema/spring"
|
||||
errorHandlerRef="errorHandler">
|
||||
<endpoint id="abfFileEndpoint"
|
||||
uri="file:${archive.feeder.directory}?delete=true&delay=5000&maxMessagesPerPoll=1000&exclusiveReadLockStrategy=#abfFileChangedStrategy" />
|
||||
|
||||
<route id="abfFileScan">
|
||||
<from ref="abfFileEndpoint" />
|
||||
<bean ref="abfProc" method="processEvent" />
|
||||
</route>
|
||||
</camelContext>
|
||||
|
||||
<bean id="abfFileChangedStrategy" class="com.raytheon.uf.edex.esb.camel.FileChangedExclusiveReadLockStrategy"/>
|
||||
<bean id="abfProc" class="com.raytheon.uf.edex.archive.feeder.ArchiveBinaryFeederIngester"/>
|
||||
</beans>
|
|
@ -1,5 +0,0 @@
|
|||
# When true enables the archive binary feeder
|
||||
archive.feeder.enable=true
|
||||
|
||||
# Directory to check for binary files to ingest.
|
||||
archive.feeder.directory=/tmp/archive-feeder
|
|
@ -1,249 +0,0 @@
|
|||
/**
|
||||
* 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.archive.feeder;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.edex.core.EdexException;
|
||||
import com.raytheon.uf.edex.database.plugin.PluginDao;
|
||||
import com.raytheon.uf.edex.database.plugin.PluginFactory;
|
||||
|
||||
/**
|
||||
* This class used to process binary files created for the archive directory.
|
||||
* Not intended for production. Designed for testing of problems with creating
|
||||
* archive data.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 25, 2014 2838 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ArchiveBinaryFeederIngester {
|
||||
|
||||
protected static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ArchiveBinaryFeederIngester.class);
|
||||
|
||||
/** The ManyToOne fields in a given class. */
|
||||
private final Map<Class<?>, Field[]> manyToOneFieldMap = new HashMap<Class<?>, Field[]>();
|
||||
|
||||
/**
|
||||
* The constructor. if needed attempts to created the drop directory
|
||||
*/
|
||||
public ArchiveBinaryFeederIngester() {
|
||||
String rootName = System.getProperty("archive.feeder.directory");
|
||||
if (rootName != null) {
|
||||
File rootDir = new File(rootName);
|
||||
if (rootDir.exists()) {
|
||||
if (!rootDir.isDirectory()) {
|
||||
if (rootDir.delete()) {
|
||||
rootDir.mkdirs();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rootDir.mkdirs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process archive binary file.
|
||||
*
|
||||
* @param file
|
||||
* @throws EdexException
|
||||
*/
|
||||
public void processEvent(File file) throws EdexException {
|
||||
IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ArchiveBinaryFeederIngester.class);
|
||||
|
||||
boolean enabled = Boolean.getBoolean("archive.feeder.enable");
|
||||
if (!enabled) {
|
||||
if (statusHandler.isPriorityEnabled(Priority.WARN)) {
|
||||
StringBuilder sb = new StringBuilder(
|
||||
ArchiveBinaryFeederIngester.class.getName());
|
||||
sb.setLength(sb.lastIndexOf("."));
|
||||
statusHandler
|
||||
.handle(Priority.WARN,
|
||||
String.format(
|
||||
"file \"%s\" not processed; feeder not enabled consider removing plugin: %s",
|
||||
file, sb.toString()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
ArchiveBinaryReader reader = new ArchiveBinaryReader(file);
|
||||
|
||||
try {
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
statusHandler.handle(
|
||||
Priority.INFO,
|
||||
String.format("Start processing file \"%1$s\".",
|
||||
file.getAbsoluteFile()));
|
||||
}
|
||||
|
||||
Object object = reader.getObject();
|
||||
if (!(object instanceof List<?>)) {
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
statusHandler
|
||||
.info(String
|
||||
.format("file: \"%s\" does not contain a list of PluginDataObjects",
|
||||
file.getAbsolutePath()));
|
||||
}
|
||||
} else {
|
||||
List<?> objects = (List<?>) object;
|
||||
process(objects);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (statusHandler.isPriorityEnabled(Priority.PROBLEM)) {
|
||||
statusHandler.handle(Priority.PROBLEM, String.format(
|
||||
"Problem processing the file: \"%s\", %s",
|
||||
file.getAbsolutePath(), e.getLocalizedMessage()));
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
long time = System.currentTimeMillis() - start;
|
||||
statusHandler.handle(Priority.INFO, String.format(
|
||||
"Finished processing file \"%1$s\" in %2$d msec.",
|
||||
file.getAbsoluteFile(), time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the objects is a list of PluginDataObjects and attempts
|
||||
* use the proper dao to send list to the data base.
|
||||
*
|
||||
* @param objects
|
||||
* @throws PluginException
|
||||
*/
|
||||
private void process(List<?> objects) throws PluginException {
|
||||
if (objects.size() > 0) {
|
||||
Object o = objects.iterator().next();
|
||||
|
||||
if (o instanceof PluginDataObject) {
|
||||
PluginDataObject pdo = (PluginDataObject) o;
|
||||
String pdoName = pdo.getPluginName();
|
||||
|
||||
PluginDao dao = PluginFactory.getInstance().getPluginDao(
|
||||
pdoName);
|
||||
|
||||
processManytoOneFields(objects, pdo.getClass(), dao);
|
||||
|
||||
dao.persistAll(objects);
|
||||
} else {
|
||||
throw new PluginException("Not a list of PluginDataObjects.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the fields in the class that are an instance of the ManyToOne
|
||||
* class. This will always return a non null result.
|
||||
*
|
||||
* @param clazz
|
||||
* @return fields
|
||||
*/
|
||||
private synchronized Field[] getManyToOneFields(Class<?> clazz) {
|
||||
Field[] fields = manyToOneFieldMap.get(clazz);
|
||||
if (fields == null) {
|
||||
List<Field> fieldList = new ArrayList<Field>();
|
||||
Class<?> currentClass = clazz;
|
||||
|
||||
while (currentClass != null) {
|
||||
for (Field field : currentClass.getDeclaredFields()) {
|
||||
if (field.getAnnotation(ManyToOne.class) != null) {
|
||||
fieldList.add(field);
|
||||
}
|
||||
}
|
||||
currentClass = currentClass.getSuperclass();
|
||||
}
|
||||
|
||||
fields = fieldList.toArray(new Field[fieldList.size()]);
|
||||
manyToOneFieldMap.put(clazz, fields);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the Many to one fields of a class so their values are in the data
|
||||
* base prior to attempting to place the objects in the data base.
|
||||
*
|
||||
* @param objects
|
||||
* @param clazz
|
||||
*/
|
||||
private void processManytoOneFields(Collection<?> objects, Class<?> clazz,
|
||||
PluginDao dao) {
|
||||
Field[] fields = getManyToOneFields(clazz);
|
||||
if (fields.length > 0) {
|
||||
Map<Object, Object> foMap = new HashMap<Object, Object>();
|
||||
for (Field field : fields) {
|
||||
for (Object object : objects) {
|
||||
try {
|
||||
Object fieldObject = PropertyUtils.getProperty(object,
|
||||
field.getName());
|
||||
if (fieldObject != null) {
|
||||
Object fo = foMap.get(fieldObject);
|
||||
if (fo == null) {
|
||||
foMap.put(fieldObject, fieldObject);
|
||||
} else {
|
||||
// Set to the instance being sent to the dao.
|
||||
PropertyUtils.setProperty(object,
|
||||
field.getName(), fo);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
Collection<?> fieldObjects = foMap.values();
|
||||
processManytoOneFields(fieldObjects, field.getType(), dao);
|
||||
dao.persistAll(fieldObjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
* 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.archive.feeder;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.raytheon.uf.common.serialization.DynamicSerializationManager;
|
||||
import com.raytheon.uf.common.serialization.DynamicSerializationManager.SerializationType;
|
||||
import com.raytheon.uf.common.serialization.SerializationException;
|
||||
|
||||
/**
|
||||
* This class uses the DynamicSerializationManager to create an instance of the
|
||||
* first serialized object in a file.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 25, 2014 2838 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ArchiveBinaryReader {
|
||||
|
||||
/** File containing the serialized object. */
|
||||
private File binFile;
|
||||
|
||||
/** Instance of the file's serialized object. */
|
||||
Object object;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param binFile
|
||||
* - File containing serialized object.
|
||||
*/
|
||||
public ArchiveBinaryReader(File binFile) {
|
||||
this.binFile = binFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object obtained from the binFile.
|
||||
*
|
||||
* @return object
|
||||
* @throws FileNotFoundException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public Object getObject() throws FileNotFoundException,
|
||||
SerializationException {
|
||||
if (object == null) {
|
||||
object = readObject();
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the file's serialized object.
|
||||
*
|
||||
* @return object
|
||||
* @throws FileNotFoundException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
private Object readObject() throws FileNotFoundException,
|
||||
SerializationException {
|
||||
InputStream inputStream = null;
|
||||
Object object = null;
|
||||
try {
|
||||
DynamicSerializationManager dsm = DynamicSerializationManager
|
||||
.getManager(SerializationType.Thrift);
|
||||
inputStream = new BufferedInputStream(new FileInputStream(binFile));
|
||||
object = dsm.deserialize(inputStream);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
inputStream = null;
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.binlightning"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.bufrmos"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.bufrua"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.edex.plugin.ccfp"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.gfe"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.goessounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.grib"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.ldad"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.ldadhydro"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.ldadmanual"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.ldadprofiler"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.obs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.poessounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.profiler"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.radar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.recco"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.satellite"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.sfcobs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.shef"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.taf"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.textlightning"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.warning"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataaccess"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.acars"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.acarssounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.binlightning"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrascat"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrhdw"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrmthdw"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrncwf"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrquikscat"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrsigwx"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrssmi"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.bufrua"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.cwa"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.cwat"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.ffmp"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.fog"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.fssobs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.gfe"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.goessounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.grid"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.ldadhydro"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.ldadmesonet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.level"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.lsr"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.madis"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.maps"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.modelsounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.npp.crimss"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.npp.nucaps"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.npp.sounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.npp.viirs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.obs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.poessounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.preciprate"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.profiler"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.qc"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.qpf"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.radar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.satellite"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.scan"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.sfcobs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.shef"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.svrwx"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.tcg"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.tcs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.text"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.vaa"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.vil"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.dataplugin.warning"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.mpe"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.nc4"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.ohd"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.pointdata"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.common.sounding"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.airep"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.airmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.atcf"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.aww"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.convsigmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.ffg"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.gempak"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.geomag"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.gpd"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.idft"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.intlsigmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.mcidas"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.ncpafm"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.ncscat"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.ncscd"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.nctaf"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.ncuair"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.nonconvsigmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.ntrans"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.pgen"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.pirep"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.sgwh"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.sgwhv"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.solarimage"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.ssha"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.stormtrack"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.tcm"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.dataplugin.wcp"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.common.staticdata"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.common"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.gempak.jna"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.airep"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.airmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.atcf"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.aww"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.convsigmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ffg"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.gempak"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.geomag"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.gpd"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.idft"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.intlsigmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.mcidas"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.mosaic"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ncgrib"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ncpafm"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ncscat"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ncscd"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.nctaf"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.nctext"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ncuair"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ntrans"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.pgen"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.pirep"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.sgwh"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.sgwhv"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.solarimage"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.ssha"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.stormtrack"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.tcm"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/gov.noaa.nws.ncep.edex.plugin.wcp"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.uf.edex.plugin.redbook"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.docs.datauri</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,7 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
|
@ -1,8 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: DataURI Documenter Tool
|
||||
Bundle-SymbolicName: com.raytheon.uf.docs.datauri
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Require-Bundle: org.reflections;bundle-version="0.9.9"
|
|
@ -1,4 +0,0 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -1,54 +0,0 @@
|
|||
/**
|
||||
* 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.docs.datauri;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||
|
||||
/**
|
||||
* Shamelessly stolen from DataURIUtil.java. I didn't want to change that to be
|
||||
* public since this plugin is only a utility.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 27, 2014 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DataURIAnnotationComparator implements Comparator<Field> {
|
||||
|
||||
@Override
|
||||
public int compare(Field f1, Field f2) {
|
||||
int i1 = f1.getAnnotation(DataURI.class).position();
|
||||
int i2 = f2.getAnnotation(DataURI.class).position();
|
||||
return (i1 < i2 ? -1 : (i1 == i2 ? 0 : 1));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
/**
|
||||
* 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.docs.datauri;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.scanners.SubTypesScanner;
|
||||
import org.reflections.util.ClasspathHelper;
|
||||
import org.reflections.util.ConfigurationBuilder;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||
|
||||
/**
|
||||
* Outputs the dataURI field names related to all plugins by using the
|
||||
* reflections plugin to find subclasses of PluginDataObject.
|
||||
*
|
||||
* If running this on future builds, you need to make sure it has knowledge of
|
||||
* the plugins and packages that a subclass of PluginDataObject might reside in.
|
||||
*
|
||||
* Specifically plugins are added to the Eclipse build path by right clicking
|
||||
* this class's plugin project and editing the build path to include other
|
||||
* projects in the workspace that may contain PluginDataObjects.
|
||||
*
|
||||
* Package names that are scanned within those plugins are in the constant
|
||||
* PKG_NAMES below.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 27, 2014 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DataURIOutputter {
|
||||
|
||||
private static final String[] PKG_NAMES = { "com.raytheon", "gov.noaa" };
|
||||
|
||||
private static final DataURIAnnotationComparator fieldCompare = new DataURIAnnotationComparator();
|
||||
|
||||
protected Writer writer;
|
||||
|
||||
public DataURIOutputter(Writer writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method that actually runs the tool
|
||||
*
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
// could change it to write to a file if we desire
|
||||
StringWriter writer = new StringWriter();
|
||||
DataURIOutputter tool = new DataURIOutputter(writer);
|
||||
tool.run();
|
||||
System.out.println(writer.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds classes that extend PluginDataObject and analyzes their dataURI
|
||||
* annotations to produce output for the writer.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void run() throws IOException {
|
||||
Set<Class<? extends PluginDataObject>> clzSet = findPDOs();
|
||||
List<Class<? extends PluginDataObject>> clzList = new ArrayList<Class<? extends PluginDataObject>>(
|
||||
clzSet);
|
||||
|
||||
List<String> pluginNames = new ArrayList<String>(clzList.size());
|
||||
Map<String, Class<?>> map = new HashMap<String, Class<?>>();
|
||||
for (Class<? extends PluginDataObject> clz : clzList) {
|
||||
if (!Modifier.isAbstract(clz.getModifiers())
|
||||
&& !Modifier.isPrivate(clz.getModifiers()))
|
||||
try {
|
||||
PluginDataObject pdo = clz.newInstance();
|
||||
String pluginName = pdo.getPluginName();
|
||||
pluginNames.add(pluginName);
|
||||
map.put(pluginName, clz);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error instantiating " + clz.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// sort the plugins alphabetically
|
||||
Collections.sort(pluginNames);
|
||||
|
||||
// produce the output
|
||||
for (String plugin : pluginNames) {
|
||||
writer.append(DataURI.SEPARATOR);
|
||||
writer.append(plugin);
|
||||
writer.append(DataURI.SEPARATOR);
|
||||
processFields(findDataUriFields(map.get(plugin)));
|
||||
writer.append("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the classes that extend PluginDataObject
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Set<Class<? extends PluginDataObject>> findPDOs() {
|
||||
ConfigurationBuilder cb = new ConfigurationBuilder();
|
||||
for (String pkg : PKG_NAMES) {
|
||||
cb.addUrls(ClasspathHelper.forPackage(pkg));
|
||||
}
|
||||
cb.setScanners(new SubTypesScanner());
|
||||
Reflections refl = cb.build();
|
||||
return refl.getSubTypesOf(PluginDataObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks up the class inheritance tree and over the class's member variables
|
||||
* looking for @DataURI annotations and returns the corresponding fields in
|
||||
* proper order.
|
||||
*
|
||||
* @param clz
|
||||
* the class to find @DataURI fields
|
||||
* @return
|
||||
*/
|
||||
private List<Field> findDataUriFields(Class<?> clz) {
|
||||
Class<?> superClz = clz.getSuperclass();
|
||||
List<Field> superFields = null;
|
||||
if (!superClz.equals(Object.class)) {
|
||||
superFields = findDataUriFields(superClz);
|
||||
} else {
|
||||
superFields = new ArrayList<Field>();
|
||||
}
|
||||
|
||||
List<Field> thisFields = new ArrayList<Field>();
|
||||
for (Field field : clz.getDeclaredFields()) {
|
||||
if (field.isAnnotationPresent(DataURI.class)) {
|
||||
thisFields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sorting only applies to this particular class, as a position's
|
||||
* numeric value can repeat in a super class
|
||||
*/
|
||||
Collections.sort(thisFields, fieldCompare);
|
||||
|
||||
// super fields always come first
|
||||
superFields.addAll(thisFields);
|
||||
return superFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through the fields and appends corresponding output to the writer
|
||||
*
|
||||
* @param fields
|
||||
* fields that have @DataURI annotations
|
||||
* @throws IOException
|
||||
*/
|
||||
private void processFields(List<Field> fields) throws IOException {
|
||||
Iterator<Field> itr = fields.iterator();
|
||||
while (itr.hasNext()) {
|
||||
Field f = itr.next();
|
||||
DataURI dataURI = f.getAnnotation(DataURI.class);
|
||||
if (!dataURI.embedded()) {
|
||||
writer.append(f.getName());
|
||||
} else {
|
||||
processFields(findDataUriFields(f.getType()));
|
||||
}
|
||||
if (itr.hasNext()) {
|
||||
writer.append(DataURI.SEPARATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.logsrv</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,7 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
|
@ -1,16 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: com.raytheon.uf.logsrv.LogService
|
||||
Class-Path: logback-core-1.0.13.jar logback-classic-1.0.13.jar derby.jar mail.jar slf4j-api-1.7.5.jar quartz-1.8.6.jar commons-lang-2.3.jar
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Logsrv
|
||||
Bundle-SymbolicName: com.raytheon.uf.logsrv
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: ch.qos.logback;bundle-version="1.0.13",
|
||||
org.slf4j;bundle-version="1.7.5",
|
||||
org.apache.derby;bundle-version="10.10.1",
|
||||
javax.mail,
|
||||
org.quartz;bundle-version="1.8.6",
|
||||
org.apache.commons.lang;bundle-version="2.3.0"
|
|
@ -1,149 +0,0 @@
|
|||
##
|
||||
# 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.
|
||||
##
|
||||
|
||||
|
||||
|
||||
Build instructions
|
||||
-----------------------
|
||||
In Eclipse run the build.xml by right clicking on the build.xml file and
|
||||
running it. That will produce a tar.gz with everything you need inside of it.
|
||||
|
||||
|
||||
Install instructions
|
||||
-----------------------
|
||||
Place the tar.gz file where you would like to install it, and run tar -xvf on
|
||||
the tar.gz file. Next go into the conf directory and modify config.xml to
|
||||
the best settings for your cluster. Then open receiver.xml and go to the
|
||||
bottom of the file. Edit the address to the name of the machine where
|
||||
you are installing the log service, and pick a port if you are not happy with
|
||||
the default. Once your config settings are right, run the bin/logsrv.sh
|
||||
script to start the log service.
|
||||
|
||||
|
||||
Setup of Client Processes
|
||||
------------------
|
||||
At this point the log service is running but nothing is reporting to it. You
|
||||
can configure any Java process using logback to report to it, but with the
|
||||
current version that is just EDEX and CAVE. (Note technically you could
|
||||
configure AlertViz to report to the service too, but that is fairly pointless).
|
||||
|
||||
To configure EDEX or CAVE to report to the log service, find the logback
|
||||
config files for those applications. In EDEX they can typically be found at
|
||||
/awips2/edex/conf. If you are not sure which logback file corresponds to
|
||||
which JVM, look at the shell scripts in /awips2/edex/etc. If not explicitly
|
||||
stated in their corresponding shell script, then the JVMs use the logback file
|
||||
specified in default.sh.
|
||||
|
||||
In CAVE the logback config files can typically be found at
|
||||
/awips2/cave/plugins/com.raytheon.uf.viz.core_${VERSION}.
|
||||
|
||||
Once found, use a text editor to open the logback config file corresponding
|
||||
to the process you wish to report to the log service. You need to add two
|
||||
things to the file, an appender and an appender-ref.
|
||||
|
||||
Add an appender like the example below in the appenders section (generally
|
||||
towards the top of the file):
|
||||
|
||||
<appender class="ch.qos.logback.classic.net.SocketAppender" name="remoteLogSrv">
|
||||
<includeCallerData>false</includeCallerData>
|
||||
<port>5477</port>
|
||||
<remoteHost>dev33.oma.us.ray.com</remoteHost>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>WARN</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
Replace the remoteHost address with the machine where you installed the
|
||||
log service. Note that you must have a network route between the two machines
|
||||
as it uses a socket to report the errors. Replace the port with the port you chose
|
||||
in receiver.xml. You can alter the threshold if need be.
|
||||
|
||||
Next you must add your new remoteLogSrv appender to a logger. Note that a
|
||||
logger can have multiple appenders, but any logger with additivity="false" will
|
||||
not go through the root log. For EDEX, the recommendation is to add
|
||||
it to the root logger. For example:
|
||||
|
||||
<root>
|
||||
<level value="INFO"/>
|
||||
<appender-ref ref="asyncConsole"/>
|
||||
<appender-ref ref="remoteLogSrv"/>
|
||||
</root>
|
||||
|
||||
For CAVE, the recommendation is to add it to the CaveLogger. For example:
|
||||
|
||||
<logger name="CaveLogger" additivity="false">
|
||||
<level value="ALL"/>
|
||||
<appender-ref ref="AsyncCaveLogAppender"/>
|
||||
<appender-ref ref="remoteLogSrv"/>
|
||||
</logger>
|
||||
|
||||
Once you save the modified logback config file, you're done. Logback will
|
||||
automatically pick up a changed configuration within a minute or two, and
|
||||
the Java processes you configured will start appending to the socket.
|
||||
|
||||
|
||||
How it works
|
||||
--------------
|
||||
The log service is listening on the socket and will store the messages in a
|
||||
derby database on the filesystem, and then at the scheduled time it will
|
||||
attempt to analyze and consolidate the errors based on the information it has
|
||||
available. Then it will send an email using the configuration, reporting in an order
|
||||
of what errors it thinks are most significant.
|
||||
|
||||
Note that it does not matter if the Java processes have the socket appender
|
||||
configured but the log service is not running. They will try to connect but then
|
||||
go back to normal logging. If the log service is running, they will resume sending
|
||||
log messages through the socket. Therefore, it does not hurt to have
|
||||
everything configured even if the log service or the reporting processes are not
|
||||
running.
|
||||
|
||||
|
||||
Impacts
|
||||
-------------
|
||||
The log service has very little overhead. The appenders, as configured, will be just
|
||||
another appender so the "normal" logs will continue to function as usual. With the
|
||||
threshold configuration, only WARN and ERROR messages are sent to the log
|
||||
service. All of this is done asynchronously so the processing threads that logged
|
||||
a message will not wait for the message to get sent. Messages sent to the
|
||||
service are sent over TCP and are buffered. As long as the network path to
|
||||
the log service is not slower than the rate at which the WARN or ERROR messages
|
||||
are produced, you should not notice any slowdowns or impacts due to processes
|
||||
reporting to the log service.
|
||||
|
||||
Of course, the less an application produces WARN or ERROR messages, the less
|
||||
overhead. And the reporting can always be disabled by undoing the modifications
|
||||
to logback configuration files specified in the setup instructions. Again, if you
|
||||
disable reporting to the log service, you do not need to restart the Java process.
|
||||
|
||||
|
||||
More information
|
||||
--------------
|
||||
For more information about the socket appender, please see
|
||||
http://logback.qos.ch/manual/appenders.html#SocketAppender
|
||||
|
||||
For more information about logback configuration files, please see
|
||||
http://logback.qos.ch/manual/configuration.html#syntax
|
||||
|
||||
|
||||
Bugs and/or Improvements
|
||||
--------------
|
||||
If you encounter a bug with the log service or have an idea of how it can be
|
||||
improved, send an email to nathan.jensen@raytheon.com.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -1,109 +0,0 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<project name="com.raytheon.uf.logsrv" default="dist">
|
||||
|
||||
<property name="corefoss" location="../../../ufcore-foss/lib/"/>
|
||||
<property name="a2foss" location="../../../AWIPS2_foss/lib/"/>
|
||||
<property name="src" location="src"/>
|
||||
<property name="bin" location="bin"/>
|
||||
<property name="qualifier" value="${date}"/>
|
||||
<property name="prefix" value="logsrv"/>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${bin}"/>
|
||||
<tstamp>
|
||||
<format property="date" pattern="yyyyMMdd" />
|
||||
</tstamp>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<javac srcdir="${src}" destdir="${bin}"/>
|
||||
</target>
|
||||
|
||||
<target name="copyManifest" depends="init">
|
||||
<loadproperties srcfile="META-INF/MANIFEST.MF">
|
||||
<filterchain>
|
||||
<linecontainsregexp>
|
||||
<regexp pattern="^Bundle-Version: \d+.\d+.\d+.qualifier$" />
|
||||
</linecontainsregexp>
|
||||
<tokenfilter>
|
||||
<replaceregex pattern="qualifier$" replace="${qualifier}" />
|
||||
</tokenfilter>
|
||||
</filterchain>
|
||||
</loadproperties>
|
||||
<copy file="META-INF/MANIFEST.MF" tofile="${bin}/META-INF/MANIFEST.MF" />
|
||||
<manifest file="${bin}/META-INF/MANIFEST.MF" mode="update">
|
||||
<attribute name="Bundle-Version" value="${Bundle-Version}" />
|
||||
</manifest>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="compile,copyManifest">
|
||||
<jar destfile="${ant.project.name}.jar" basedir="${bin}" manifest="${bin}/META-INF/MANIFEST.MF"/>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${bin}"/>
|
||||
<delete verbose="true">
|
||||
<fileset dir="." includes="${ant.project.name}-*.jar"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target name="tar" depends="build">
|
||||
<tar destfile="${ant.project.name}-${Bundle-Version}.tar.gz" compression="gzip">
|
||||
<tarfileset dir="${corefoss}/org.slf4j" prefix="${prefix}/lib/">
|
||||
<include name="slf4j-api*.jar"/>
|
||||
<exclude name="*sources.jar"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="${corefoss}/ch.qos.logback" prefix="${prefix}/lib/">
|
||||
<include name="logback*.jar"/>
|
||||
<exclude name="*sources.jar"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="${a2foss}/org.apache.derby" prefix="${prefix}/lib/">
|
||||
<include name="derby*.jar"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="${a2foss}/javax.mail" prefix="${prefix}/lib/">
|
||||
<include name="mail.jar"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="${corefoss}/org.quartz" prefix="${prefix}/lib/">
|
||||
<include name="quartz*.jar"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="${corefoss}/org.apache.commons.lang" prefix="${prefix}/lib/">
|
||||
<include name="commons-lang*.jar"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="./" prefix="${prefix}/lib/">
|
||||
<include name="${ant.project.name}.jar"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="conf" prefix="${prefix}/conf/">
|
||||
<include name="*.xml"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="./" prefix="${prefix}/bin/" filemode="754">
|
||||
<include name="*.sh"/>
|
||||
</tarfileset>
|
||||
<tarfileset dir="./" prefix="${prefix}/">
|
||||
<include name="README.txt"/>
|
||||
</tarfileset>
|
||||
</tar>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="tar">
|
||||
<delete file="${ant.project.name}.jar"/>
|
||||
</target>
|
||||
|
||||
</project>
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<logSrvConfig>
|
||||
|
||||
<!-- Config file for the log service and how it produces the reports.
|
||||
Depending on what tags are here vs missing/commented out, the log
|
||||
service can
|
||||
a. email the report
|
||||
b. save the report to a specific directory
|
||||
c. both a and b
|
||||
d. neither a and b (rather pointless to run it then)
|
||||
-->
|
||||
|
||||
<!-- the cluster name, required but only used for the report -->
|
||||
<clusterName>ec-oma</clusterName>
|
||||
|
||||
<!-- Where to keep track of the errors. Required field.
|
||||
how much space you need depends on how many errors the system is throwing
|
||||
-->
|
||||
<databaseDir>/common/njensen/logsrv/</databaseDir>
|
||||
|
||||
<!-- fromAddress, smtpHost, smtpPort, and toAddress are required
|
||||
to send an email. If any of those are commented out then the
|
||||
report will not be emailed.
|
||||
-->
|
||||
|
||||
<!-- How to send the email report -->
|
||||
<fromAddress>Nathan.Jensen@raytheon.com</fromAddress>
|
||||
<smtpHost>mk2-msg10.raymail.ray.com</smtpHost>
|
||||
<smtpPort>143</smtpPort>
|
||||
|
||||
<!-- Where to send the email report, a comma-separated list of addresses -->
|
||||
<toAddress>awipsctl@list.app.ray.com, awipstest@list.app.ray.com, david_j_hladky@raytheon.com</toAddress>
|
||||
|
||||
<!-- Where to save a copy of the report. Note that at present there is
|
||||
no built-in purging of this directory. If this is commented out or
|
||||
missing, the report will not be saved. -->
|
||||
<!--outputDir>/common/njensen/tmp</outputDir-->
|
||||
|
||||
<!-- The time of day to send and/or save the report. Required to be set.
|
||||
The specific time only really matters if you're installing or
|
||||
auto-deploying at a specific time, as you may want to clear out
|
||||
the databaseDir that contains errors from a previous build/install.
|
||||
-->
|
||||
<timeToSend>00:45</timeToSend>
|
||||
|
||||
</logSrvConfig>
|
|
@ -1,48 +0,0 @@
|
|||
<configuration debug="true">
|
||||
|
||||
<appender name="DERBY" class="com.raytheon.uf.logsrv.derby.DerbyAppender">
|
||||
</appender>
|
||||
|
||||
<appender name="InternalLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${logSrvLogs}/logs/logService-internal-%d{yyyyMMdd}.log</fileNamePattern>
|
||||
<maxHistory>7</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%-5p %d [%t] %c{0}: %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-5p %d [%t] %c{0}: %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="asyncConsole" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<appender-ref ref="console" />
|
||||
</appender>
|
||||
|
||||
<appender name="InternalLogAsync" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<appender-ref ref="InternalLog" />
|
||||
</appender>
|
||||
|
||||
|
||||
<logger name="InternalLogger" additivity="false">
|
||||
<level value="INFO"/>
|
||||
<appender-ref ref="asyncConsole" />
|
||||
<appender-ref ref="InternalLogAsync" />
|
||||
</logger>
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="DERBY" />
|
||||
</root>
|
||||
|
||||
<receiver class="ch.qos.logback.classic.net.server.ServerSocketReceiver">
|
||||
<address>dev33.oma.us.ray.com</address>
|
||||
<port>5477</port>
|
||||
</receiver>
|
||||
|
||||
|
||||
|
||||
</configuration>
|
|
@ -1,13 +0,0 @@
|
|||
----------------------------------------------------------------
|
||||
Wed Sep 11 15:37:35 CDT 2013:
|
||||
Booting Derby version The Apache Software Foundation - Apache Derby - 10.10.1.1 - (1458268): instance a816c00e-0141-0ebe-4f2c-000009e7d350
|
||||
on database directory /awips2/edex/data/utility/nate with class loader sun.misc.Launcher$AppClassLoader@4aad3ba4
|
||||
Loaded from file:/common/njensen/git/development/cots/org.apache.derby/derby.jar
|
||||
java.vendor=Sun Microsystems Inc.
|
||||
java.runtime.version=1.6.0_43-b01
|
||||
user.dir=/common/njensen/git/development/javaUtilities/com.raytheon.uf.logsrv
|
||||
os.name=Linux
|
||||
os.arch=amd64
|
||||
os.version=2.6.18-238.el5
|
||||
derby.system.home=null
|
||||
Database Class Loader started - derby.database.classpath=''
|
|
@ -1,29 +0,0 @@
|
|||
#!/bin/bash
|
||||
##
|
||||
# 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.
|
||||
##
|
||||
|
||||
|
||||
path_to_script=`readlink -f $0`
|
||||
binDir=$(dirname $path_to_script)
|
||||
logSrvDir=$(dirname $binDir)
|
||||
export logSrvConf=$logSrvDir/conf/
|
||||
export logSrvLogs=$logSrvDir/logs/
|
||||
|
||||
java -jar ${logSrvDir}/lib/com.raytheon.uf.logsrv.jar
|
|
@ -1,102 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||
|
||||
import com.raytheon.uf.logsrv.config.LogSrvConfig;
|
||||
import com.raytheon.uf.logsrv.derby.DerbyDao;
|
||||
import com.raytheon.uf.logsrv.quartz.JobScheduler;
|
||||
|
||||
/**
|
||||
* The main class of the logging service that loads the config files and
|
||||
* therefore listens for incoming logging events.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 27, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class LogService {
|
||||
|
||||
private static final String LOGBACK_CONFIG = "receiver.xml";
|
||||
|
||||
private static final String SERVICE_CONFIG = "config.xml";
|
||||
|
||||
private static final String ENV_CONF_DIR = "logSrvConf";
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger("InternalLogger");
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
logger.info("Starting log analytics service");
|
||||
String confDir = System.getenv(ENV_CONF_DIR);
|
||||
if (confDir == null) {
|
||||
throw new LogServiceException("Environment variable "
|
||||
+ ENV_CONF_DIR
|
||||
+ " is not set! Unable to find configuration!");
|
||||
}
|
||||
|
||||
JAXBContext context = JAXBContext.newInstance(LogSrvConfig.class);
|
||||
Unmarshaller m = context.createUnmarshaller();
|
||||
LogSrvConfig config = (LogSrvConfig) m.unmarshal(new File(confDir
|
||||
+ SERVICE_CONFIG));
|
||||
config.validate();
|
||||
DerbyDao.getInstance().setConfig(config);
|
||||
logger.info("Logging events from " + config.getClusterName());
|
||||
|
||||
logger.info("Starting socket listener");
|
||||
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
lc.reset();
|
||||
JoranConfigurator configurator = new JoranConfigurator();
|
||||
configurator.setContext(lc);
|
||||
configurator.doConfigure(confDir + LOGBACK_CONFIG);
|
||||
|
||||
logger.info("Scheduling report generation");
|
||||
JobScheduler.scheduleJobs(config);
|
||||
}
|
||||
|
||||
public static Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv;
|
||||
|
||||
/**
|
||||
* An exception in the logging service.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 27, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class LogServiceException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
*
|
||||
*/
|
||||
public LogServiceException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public LogServiceException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
*/
|
||||
public LogServiceException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
*/
|
||||
public LogServiceException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.classic.spi.IThrowableProxy;
|
||||
import ch.qos.logback.classic.spi.StackTraceElementProxy;
|
||||
import ch.qos.logback.classic.spi.ThrowableProxyUtil;
|
||||
|
||||
/**
|
||||
* A translation of a logging event to a POJO that closely resembles what is in
|
||||
* the database.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 27, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class StoredMsg {
|
||||
|
||||
private Date eventTime;
|
||||
|
||||
private String message;
|
||||
|
||||
private String javaClass;
|
||||
|
||||
private int lineNumber;
|
||||
|
||||
// TODO build date or build number? not sure how to get logback to send that
|
||||
// along
|
||||
|
||||
private String stacktrace;
|
||||
|
||||
private String threadName;
|
||||
|
||||
private String machineName;
|
||||
|
||||
private String level;
|
||||
|
||||
public StoredMsg(ILoggingEvent event) {
|
||||
eventTime = new Date(event.getTimeStamp());
|
||||
|
||||
// find the most underlying cause
|
||||
IThrowableProxy cause = event.getThrowableProxy();
|
||||
if (cause != null) {
|
||||
stacktrace = ThrowableProxyUtil.asString(cause);
|
||||
while (cause.getCause() != null) {
|
||||
cause = cause.getCause();
|
||||
}
|
||||
|
||||
message = cause.getMessage();
|
||||
StackTraceElementProxy[] stack = cause
|
||||
.getStackTraceElementProxyArray();
|
||||
if (stack != null && stack.length > 0) {
|
||||
StackTraceElement ste = stack[0].getStackTraceElement();
|
||||
lineNumber = ste.getLineNumber();
|
||||
javaClass = ste.getClassName();
|
||||
}
|
||||
} else {
|
||||
message = event.getMessage();
|
||||
}
|
||||
threadName = event.getThreadName();
|
||||
machineName = event.getLoggerContextVO().getPropertyMap()
|
||||
.get("HOSTNAME");
|
||||
level = event.getLevel().toString();
|
||||
|
||||
}
|
||||
|
||||
public Date getEventTime() {
|
||||
return eventTime;
|
||||
}
|
||||
|
||||
public void setEventTime(Date eventTime) {
|
||||
this.eventTime = eventTime;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getJavaClass() {
|
||||
return javaClass;
|
||||
}
|
||||
|
||||
public void setJavaClass(String javaClass) {
|
||||
this.javaClass = javaClass;
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
public void setLineNumber(int lineNumber) {
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
public String getThreadName() {
|
||||
return threadName;
|
||||
}
|
||||
|
||||
public void setThreadName(String threadName) {
|
||||
this.threadName = threadName;
|
||||
}
|
||||
|
||||
public String getMachineName() {
|
||||
return machineName;
|
||||
}
|
||||
|
||||
public void setMachineName(String machineName) {
|
||||
this.machineName = machineName;
|
||||
}
|
||||
|
||||
public String getStacktrace() {
|
||||
return stacktrace;
|
||||
}
|
||||
|
||||
public void setStacktrace(String stacktrace) {
|
||||
this.stacktrace = stacktrace;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StoredMsg [eventTime=" + eventTime + ", message=" + message
|
||||
+ ", javaClass=" + javaClass + ", lineNumber=" + lineNumber
|
||||
+ ", stacktrace=" + stacktrace + ", threadName=" + threadName
|
||||
+ ", machineName=" + machineName + ", level=" + level + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.config;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.raytheon.uf.logsrv.LogService;
|
||||
|
||||
/**
|
||||
* A configuration for the logging service.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 29, 2013 njensen Initial creation
|
||||
* Jun 11, 2014 2840 njensen Added outputDir
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class LogSrvConfig {
|
||||
|
||||
@XmlElement(required = true)
|
||||
private String clusterName;
|
||||
|
||||
@XmlElement(required = true)
|
||||
private String databaseDir;
|
||||
|
||||
@XmlElement
|
||||
private String fromAddress;
|
||||
|
||||
@XmlElement
|
||||
private String smtpHost;
|
||||
|
||||
@XmlElement
|
||||
private int smtpPort;
|
||||
|
||||
@XmlElement
|
||||
private String toAddress;
|
||||
|
||||
@XmlElement(required = true)
|
||||
private String timeToSend;
|
||||
|
||||
private String outputDir;
|
||||
|
||||
public String getFromAddress() {
|
||||
return fromAddress;
|
||||
}
|
||||
|
||||
public void setFromAddress(String fromAddress) {
|
||||
this.fromAddress = fromAddress;
|
||||
}
|
||||
|
||||
public String getSmtpHost() {
|
||||
return smtpHost;
|
||||
}
|
||||
|
||||
public void setSmtpHost(String smtpHost) {
|
||||
this.smtpHost = smtpHost;
|
||||
}
|
||||
|
||||
public int getSmtpPort() {
|
||||
return smtpPort;
|
||||
}
|
||||
|
||||
public void setSmtpPort(int smtpPort) {
|
||||
this.smtpPort = smtpPort;
|
||||
}
|
||||
|
||||
public String getToAddress() {
|
||||
return toAddress;
|
||||
}
|
||||
|
||||
public void setToAddress(String toAddress) {
|
||||
this.toAddress = toAddress;
|
||||
}
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
||||
public void setClusterName(String clusterName) {
|
||||
this.clusterName = clusterName;
|
||||
}
|
||||
|
||||
public String getTimeToSend() {
|
||||
return timeToSend;
|
||||
}
|
||||
|
||||
public void setTimeToSend(String timeToSend) {
|
||||
this.timeToSend = timeToSend;
|
||||
}
|
||||
|
||||
public String getDatabaseDir() {
|
||||
return databaseDir;
|
||||
}
|
||||
|
||||
public void setDatabaseDir(String databaseDir) {
|
||||
this.databaseDir = databaseDir;
|
||||
}
|
||||
|
||||
public String getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public void setOutputDir(String outputDir) {
|
||||
this.outputDir = outputDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that the config has every value set.
|
||||
*/
|
||||
public void validate() {
|
||||
Validate.notEmpty(clusterName, "Config must include a clusterName");
|
||||
Validate.notEmpty(databaseDir, "Config must include a databaseDir");
|
||||
Validate.notEmpty(timeToSend, "Config must include a timeToSend");
|
||||
if ((outputDir == null)
|
||||
&& (fromAddress == null || toAddress == null
|
||||
|| smtpHost == null || smtpPort == 0)) {
|
||||
LogService
|
||||
.getLogger()
|
||||
.warn("Config appears misconfigured and will not save or email the report!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.derby;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
|
||||
import com.raytheon.uf.logsrv.LogService;
|
||||
import com.raytheon.uf.logsrv.LogServiceException;
|
||||
import com.raytheon.uf.logsrv.StoredMsg;
|
||||
|
||||
/**
|
||||
* A logback appender that stores a logging event to the database.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 27, 2013 njensen Initial creation
|
||||
* Jun 09, 2014 3027 njensen Change shouldStoreMsg() to protected
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DerbyAppender extends AppenderBase<ILoggingEvent> {
|
||||
|
||||
private DerbyDao dao;
|
||||
|
||||
public DerbyAppender() {
|
||||
super();
|
||||
dao = DerbyDao.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent eventObject) {
|
||||
if (shouldStoreMsg(eventObject)) {
|
||||
StoredMsg msg = new StoredMsg(eventObject);
|
||||
try {
|
||||
dao.insert(msg);
|
||||
} catch (LogServiceException e) {
|
||||
LogService.getLogger().error(
|
||||
"Error inserting message into derby database", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not the appender should store the logging event
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
protected boolean shouldStoreMsg(ILoggingEvent event) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,559 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.derby;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import com.raytheon.uf.logsrv.LogService;
|
||||
import com.raytheon.uf.logsrv.LogServiceException;
|
||||
import com.raytheon.uf.logsrv.StoredMsg;
|
||||
import com.raytheon.uf.logsrv.config.LogSrvConfig;
|
||||
import com.raytheon.uf.logsrv.report.data.LogReportContainer;
|
||||
import com.raytheon.uf.logsrv.report.data.LogReportEvent;
|
||||
|
||||
/**
|
||||
* DAO for interacting with the derby database to add rows or create report
|
||||
* objects.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 27, 2013 njensen Initial creation
|
||||
* Jun 09, 2014 3027 njensen Fix reconnect after error logic
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DerbyDao {
|
||||
|
||||
private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||
|
||||
private static final String TABLE = "log";
|
||||
|
||||
private static final int MAX_STR_LEN = 32672;
|
||||
|
||||
private static final String DB_CREATE = "CREATE TABLE " + TABLE
|
||||
+ "(pk INT NOT NULL GENERATED BY DEFAULT AS IDENTITY, "
|
||||
+ "eventTime TIMESTAMP, " + "message VARCHAR(" + MAX_STR_LEN
|
||||
+ "), " + "javaClass VARCHAR(128), " + "lineNumber INT, "
|
||||
+ "stacktrace VARCHAR(" + MAX_STR_LEN + "), "
|
||||
+ "threadName VARCHAR(128), " + "machineName VARCHAR(128), "
|
||||
+ "level VARCHAR(32))";
|
||||
|
||||
private static final String INSERT_PREPARED_STATEMENT = "INSERT INTO "
|
||||
+ TABLE
|
||||
+ "(eventTime, message, javaClass, lineNumber, stacktrace, threadName, machineName, level) "
|
||||
+ "values (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
private static final String PURGE_STATEMENT = "DELETE from " + TABLE;
|
||||
|
||||
private static final String TIME_STATEMENT = "select min(eventTime), max(eventTime) FROM "
|
||||
+ TABLE;
|
||||
|
||||
private static final String COUNT_STATEMENT = "select count(*) from "
|
||||
+ TABLE;
|
||||
|
||||
private PreparedStatement saveStatement;
|
||||
|
||||
private PreparedStatement purgeStatement;
|
||||
|
||||
private PreparedStatement timeStatement;
|
||||
|
||||
private PreparedStatement countStatement;
|
||||
|
||||
private Connection connection;
|
||||
|
||||
private static DerbyDao instance = new DerbyDao();
|
||||
|
||||
private LogSrvConfig config;
|
||||
|
||||
private DerbyDao() {
|
||||
|
||||
}
|
||||
|
||||
public static DerbyDao getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setConfig(LogSrvConfig cfg) {
|
||||
config = cfg;
|
||||
}
|
||||
|
||||
public LogSrvConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a connection to derby
|
||||
*
|
||||
* @return
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
private Connection createConnection() throws LogServiceException {
|
||||
Statement statement = null;
|
||||
boolean errorOccurred = false;
|
||||
Connection connection = null;
|
||||
try {
|
||||
Class.forName(DRIVER).newInstance();
|
||||
connection = DriverManager.getConnection("jdbc:derby:directory:"
|
||||
+ config.getDatabaseDir() + ";create=true");
|
||||
DatabaseMetaData dmd = connection.getMetaData();
|
||||
ResultSet tables = dmd.getTables(null, null, null,
|
||||
new String[] { "TABLE" });
|
||||
boolean needCreation = true;
|
||||
|
||||
while (tables.next()) {
|
||||
String tableName = tables.getString("TABLE_NAME");
|
||||
if (tableName.equalsIgnoreCase(TABLE)) {
|
||||
needCreation = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needCreation) {
|
||||
statement = connection.createStatement();
|
||||
statement.execute(DB_CREATE);
|
||||
}
|
||||
connection.commit();
|
||||
} catch (Exception e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException("Error setting up database", e);
|
||||
} finally {
|
||||
closeStatement(statement);
|
||||
if (errorOccurred) {
|
||||
closeConnection(connection);
|
||||
}
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a StoredMsg as a row in the database table
|
||||
*
|
||||
* @param event
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
public synchronized void insert(StoredMsg event) throws LogServiceException {
|
||||
boolean errorOccurred = false;
|
||||
Connection conn = null;
|
||||
|
||||
try {
|
||||
conn = getConnection();
|
||||
if (saveStatement == null) {
|
||||
saveStatement = conn
|
||||
.prepareStatement(INSERT_PREPARED_STATEMENT);
|
||||
}
|
||||
|
||||
saveStatement.setTimestamp(1, new Timestamp(event.getEventTime()
|
||||
.getTime()));
|
||||
if (event.getMessage() == null
|
||||
|| event.getMessage().length() < MAX_STR_LEN) {
|
||||
saveStatement.setString(2, event.getMessage());
|
||||
} else {
|
||||
saveStatement.setString(2,
|
||||
event.getMessage().substring(0, MAX_STR_LEN - 1));
|
||||
}
|
||||
saveStatement.setString(3, event.getJavaClass());
|
||||
saveStatement.setInt(4, event.getLineNumber());
|
||||
if (event.getStacktrace() == null
|
||||
|| event.getStacktrace().length() < MAX_STR_LEN) {
|
||||
saveStatement.setString(5, event.getStacktrace());
|
||||
} else {
|
||||
saveStatement.setString(5,
|
||||
event.getStacktrace().substring(0, MAX_STR_LEN - 1));
|
||||
}
|
||||
saveStatement.setString(6, event.getThreadName());
|
||||
saveStatement.setString(7, event.getMachineName());
|
||||
saveStatement.setString(8, event.getLevel());
|
||||
int result = saveStatement.executeUpdate();
|
||||
if (result < 1) {
|
||||
errorOccurred = true;
|
||||
LogService.getLogger().error("Insert of logging event failed");
|
||||
} else {
|
||||
conn.commit();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException(
|
||||
"Error inserting event into log database", e);
|
||||
} finally {
|
||||
if (errorOccurred) {
|
||||
closeStatement(saveStatement);
|
||||
saveStatement = null;
|
||||
closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cached connection to the database
|
||||
*
|
||||
* @return
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
private synchronized Connection getConnection() throws LogServiceException {
|
||||
if (connection != null) {
|
||||
try {
|
||||
if (connection.isClosed()) {
|
||||
closeConnection(connection);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new LogServiceException("Error closing connection", e);
|
||||
}
|
||||
}
|
||||
if (connection == null) {
|
||||
try {
|
||||
connection = createConnection();
|
||||
} catch (Exception e) {
|
||||
throw new LogServiceException("Error creating connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a statement
|
||||
*
|
||||
* @param statement
|
||||
*/
|
||||
private void closeStatement(Statement statement) {
|
||||
if (statement != null) {
|
||||
try {
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to the database
|
||||
*
|
||||
* @param connection
|
||||
*/
|
||||
private void closeConnection(Connection connection) {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
// ignore
|
||||
}
|
||||
if (connection.equals(this.connection)) {
|
||||
this.connection = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
DriverManager.getConnection("jdbc:derby:directory:"
|
||||
+ config.getDatabaseDir() + ";shutdown=true");
|
||||
} catch (SQLException e) {
|
||||
// ignore as stop database will always throw an exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a result set
|
||||
*
|
||||
* @param rs
|
||||
*/
|
||||
private void closeResultSet(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
rs.close();
|
||||
} catch (SQLException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for rows that include stacktraces and correlates them into a
|
||||
* LogReportContainer
|
||||
*
|
||||
* @return
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
private LogReportContainer queryEventsWithStacks()
|
||||
throws LogServiceException {
|
||||
Connection conn = null;
|
||||
boolean errorOccurred = false;
|
||||
Statement statement = null;
|
||||
ResultSet rs = null;
|
||||
LogReportContainer container = new LogReportContainer();
|
||||
try {
|
||||
conn = getConnection();
|
||||
statement = conn.createStatement();
|
||||
// line number of 0 indicates that there was no stacktrace with
|
||||
// the error, those will be handled separately
|
||||
rs = statement
|
||||
.executeQuery("select javaClass, lineNumber, machineName, count(*) "
|
||||
+ "from log where lineNumber != 0 "
|
||||
+ "group by javaClass, lineNumber, machineName");
|
||||
conn.commit();
|
||||
while (rs.next()) {
|
||||
String javaClass = rs.getString(1);
|
||||
int lineNumber = rs.getInt(2);
|
||||
String machineName = rs.getString(3);
|
||||
int count = rs.getInt(4);
|
||||
LogReportEvent occ = new LogReportEvent();
|
||||
// errors sent in without a stacktrace will not have a line
|
||||
// number of java class
|
||||
occ.setJavaClass(javaClass);
|
||||
occ.setLineNumber(lineNumber);
|
||||
container.addError(occ, machineName, count);
|
||||
}
|
||||
return container;
|
||||
} catch (SQLException e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException("Error executing query", e);
|
||||
} finally {
|
||||
closeResultSet(rs);
|
||||
closeStatement(statement);
|
||||
if (errorOccurred) {
|
||||
closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through the LogReportContainer's events and queries for sample
|
||||
* stacktraces and messages for them.
|
||||
*
|
||||
* @param container
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
private void addSamples(LogReportContainer container)
|
||||
throws LogServiceException {
|
||||
for (LogReportEvent event : container.getEvents()) {
|
||||
addSamples(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in a LogReportEvent with a sample stacktrace and message
|
||||
*
|
||||
* @param event
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
private void addSamples(LogReportEvent event) throws LogServiceException {
|
||||
Connection conn = null;
|
||||
boolean errorOccurred = false;
|
||||
Statement statement = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
conn = getConnection();
|
||||
statement = conn.createStatement();
|
||||
statement.setFetchSize(1);
|
||||
statement.setMaxRows(1);
|
||||
rs = statement.executeQuery("select message, stacktrace, level "
|
||||
+ "from log where javaClass ='" + event.getJavaClass()
|
||||
+ "' and lineNumber = " + event.getLineNumber());
|
||||
conn.commit();
|
||||
while (rs.next()) {
|
||||
String message = rs.getString(1);
|
||||
String stacktrace = rs.getString(2);
|
||||
String level = rs.getString(3);
|
||||
event.setSampleMessage(message);
|
||||
event.setSampleStacktrace(stacktrace);
|
||||
event.setLevel(level);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException("Error executing query", e);
|
||||
} finally {
|
||||
closeResultSet(rs);
|
||||
closeStatement(statement);
|
||||
if (errorOccurred) {
|
||||
closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for rows that don't have stacktraces and adds them to the
|
||||
* LogReportContainer
|
||||
*
|
||||
* @param container
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
private void addNoStacktraceMessages(LogReportContainer container)
|
||||
throws LogServiceException {
|
||||
Connection conn = null;
|
||||
boolean errorOccurred = false;
|
||||
Statement statement = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
conn = getConnection();
|
||||
statement = conn.createStatement();
|
||||
rs = statement
|
||||
.executeQuery("select message, machineName, level, threadName, count(*) from log "
|
||||
+ "where lineNumber = 0 group by message, machineName, level, threadName");
|
||||
conn.commit();
|
||||
while (rs.next()) {
|
||||
String message = rs.getString(1);
|
||||
String machineName = rs.getString(2);
|
||||
String level = rs.getString(3);
|
||||
String thread = rs.getString(4);
|
||||
int count = rs.getInt(5);
|
||||
LogReportEvent event = new LogReportEvent();
|
||||
event.setSampleMessage(message);
|
||||
event.setLevel(level);
|
||||
event.setThreadName(thread);
|
||||
container.addError(event, machineName, count);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException("Error executing query", e);
|
||||
} finally {
|
||||
closeResultSet(rs);
|
||||
closeStatement(statement);
|
||||
if (errorOccurred) {
|
||||
closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for the earliest and latest time in the database and sets them on
|
||||
* the LogReportContainer
|
||||
*
|
||||
* @param container
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
private void addTimes(LogReportContainer container)
|
||||
throws LogServiceException {
|
||||
boolean errorOccurred = false;
|
||||
Connection conn = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
conn = getConnection();
|
||||
if (timeStatement == null) {
|
||||
timeStatement = conn.prepareStatement(TIME_STATEMENT);
|
||||
}
|
||||
rs = timeStatement.executeQuery();
|
||||
conn.commit();
|
||||
rs.next();
|
||||
container.setEarliestTime(rs.getTimestamp(1));
|
||||
container.setLatestTime(rs.getTimestamp(2));
|
||||
} catch (Exception e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException(
|
||||
"Error determining min and max times", e);
|
||||
} finally {
|
||||
closeResultSet(rs);
|
||||
if (errorOccurred) {
|
||||
closeStatement(timeStatement);
|
||||
timeStatement = null;
|
||||
closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a LogReportContainer that correlates different rows as the same
|
||||
* event, fills in sample stacktraces and messages, and includes the
|
||||
* earliest and latest times of the events.
|
||||
*
|
||||
* @return
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
public LogReportContainer buildReport() throws LogServiceException {
|
||||
LogReportContainer container = queryEventsWithStacks();
|
||||
addSamples(container);
|
||||
addNoStacktraceMessages(container);
|
||||
addTimes(container);
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all rows from the database
|
||||
*
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
public void clearEntries() throws LogServiceException {
|
||||
boolean errorOccurred = false;
|
||||
Connection conn = null;
|
||||
|
||||
try {
|
||||
conn = getConnection();
|
||||
if (purgeStatement == null) {
|
||||
purgeStatement = conn.prepareStatement(PURGE_STATEMENT);
|
||||
}
|
||||
purgeStatement.executeUpdate();
|
||||
conn.commit();
|
||||
} catch (Exception e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException("Error purging message database", e);
|
||||
} finally {
|
||||
if (errorOccurred) {
|
||||
closeStatement(purgeStatement);
|
||||
purgeStatement = null;
|
||||
closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the database to determine the number of rows
|
||||
*
|
||||
* @return
|
||||
* @throws LogServiceException
|
||||
*/
|
||||
public int getCurrentRowCount() throws LogServiceException {
|
||||
boolean errorOccurred = false;
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = getConnection();
|
||||
if (countStatement == null) {
|
||||
countStatement = conn.prepareStatement(COUNT_STATEMENT);
|
||||
}
|
||||
ResultSet rs = countStatement.executeQuery();
|
||||
conn.commit();
|
||||
rs.next();
|
||||
return rs.getInt(1);
|
||||
} catch (Exception e) {
|
||||
errorOccurred = true;
|
||||
throw new LogServiceException("Error determining row count", e);
|
||||
} finally {
|
||||
if (errorOccurred) {
|
||||
closeStatement(countStatement);
|
||||
countStatement = null;
|
||||
closeConnection(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.quartz;
|
||||
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import com.raytheon.uf.logsrv.LogService;
|
||||
import com.raytheon.uf.logsrv.LogServiceException;
|
||||
import com.raytheon.uf.logsrv.derby.DerbyDao;
|
||||
|
||||
/**
|
||||
* A simple quartz job that logs how many log events are currently in the
|
||||
* database.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 5, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class CountRowsJob implements Job {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
|
||||
*/
|
||||
@Override
|
||||
public void execute(JobExecutionContext arg0) throws JobExecutionException {
|
||||
try {
|
||||
int rowCount = DerbyDao.getInstance().getCurrentRowCount();
|
||||
LogService.getLogger()
|
||||
.info("Database currently has " + rowCount
|
||||
+ " messages reported");
|
||||
} catch (LogServiceException e) {
|
||||
LogService.getLogger().error(
|
||||
"Error determining database row count", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.quartz;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import com.raytheon.uf.logsrv.LogService;
|
||||
import com.raytheon.uf.logsrv.LogServiceException;
|
||||
import com.raytheon.uf.logsrv.config.LogSrvConfig;
|
||||
import com.raytheon.uf.logsrv.derby.DerbyDao;
|
||||
import com.raytheon.uf.logsrv.report.data.LogReportContainer;
|
||||
import com.raytheon.uf.logsrv.report.email.HtmlGenerator;
|
||||
import com.raytheon.uf.logsrv.report.email.ReportEmailer;
|
||||
|
||||
/**
|
||||
* A quartz job that queries the database to build report data, transforms the
|
||||
* report data into HTML, emails and/or saves the HTML, and then purges the
|
||||
* database of all logging events that were included in the report.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 30, 2013 njensen Initial creation
|
||||
* Jun 11, 2014 2840 njensen Added save to dir
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class CreateReportJob implements Job {
|
||||
|
||||
private static final SimpleDateFormat SDF = new SimpleDateFormat(
|
||||
"yyyy-MM-dd");
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
|
||||
*/
|
||||
@Override
|
||||
public void execute(JobExecutionContext ctx) throws JobExecutionException {
|
||||
LogService.getLogger().info(
|
||||
"Create report job triggered, preparing report");
|
||||
DerbyDao dao = DerbyDao.getInstance();
|
||||
// synchronize on dao to prevent new log entries from being added
|
||||
// while we're querying and then purging
|
||||
synchronized (dao) {
|
||||
LogReportContainer container = null;
|
||||
try {
|
||||
container = dao.buildReport();
|
||||
} catch (LogServiceException e) {
|
||||
LogService.getLogger().error("Error building report", e);
|
||||
throw new JobExecutionException("Error building report", e);
|
||||
}
|
||||
|
||||
String html = HtmlGenerator.generateHtml(container);
|
||||
LogSrvConfig config = (LogSrvConfig) ctx.getJobDetail()
|
||||
.getJobDataMap().get("config");
|
||||
|
||||
boolean emailed = sendEmail(html, config);
|
||||
boolean saved = saveReport(html, config);
|
||||
boolean processed = emailed || saved;
|
||||
|
||||
/*
|
||||
* Only clear out the database if we at least sent or saved the
|
||||
* report.
|
||||
*
|
||||
* TODO If the service keeps erroring off on the report generation,
|
||||
* then in theory the databaseDir could grow out of control forever
|
||||
* until out of disk space. Should somehow set a configurable upper
|
||||
* limit where the derby db cannot go past a certain number of log
|
||||
* messages.
|
||||
*/
|
||||
if (processed) {
|
||||
LogService.getLogger().info(
|
||||
"Purging database of messages that were just reported");
|
||||
try {
|
||||
dao.clearEntries();
|
||||
} catch (LogServiceException e) {
|
||||
LogService.getLogger().error("Error purging database", e);
|
||||
throw new JobExecutionException("Error purging database", e);
|
||||
}
|
||||
LogService.getLogger().info("Database purging complete");
|
||||
} else {
|
||||
LogService
|
||||
.getLogger()
|
||||
.warn("Did not save or send report, therefore skipping purge of database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the service is configured to send email, and if so sends the
|
||||
* report as configured
|
||||
*
|
||||
* @param report
|
||||
* @param config
|
||||
* @return true if it sent, otherwise false
|
||||
*/
|
||||
protected boolean sendEmail(String report, LogSrvConfig config) {
|
||||
boolean sent = false;
|
||||
if (shouldEmail(config)) {
|
||||
try {
|
||||
ReportEmailer.email(report, config);
|
||||
LogService.getLogger().info(
|
||||
"Report has been sent to: " + config.getToAddress());
|
||||
sent = true;
|
||||
} catch (Exception e) {
|
||||
LogService.getLogger().error("Error emailing report", e);
|
||||
}
|
||||
} else {
|
||||
LogService
|
||||
.getLogger()
|
||||
.info("Skipping email of report"
|
||||
+ ", to enable emailing ensure the log service's config has a fromAddress, toAddress, and smtpHost");
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the configuration indicates that the report should be emailed
|
||||
*
|
||||
* @param cfg
|
||||
* @return
|
||||
*/
|
||||
protected boolean shouldEmail(LogSrvConfig cfg) {
|
||||
return (cfg.getFromAddress() != null) && (cfg.getToAddress() != null)
|
||||
&& (cfg.getSmtpHost() != null) && (cfg.getSmtpPort() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the service is configured to save the reports, and if so, saves
|
||||
* the report
|
||||
*
|
||||
* @param report
|
||||
* @param config
|
||||
* @return true if it saved, otherwise false
|
||||
*/
|
||||
protected boolean saveReport(String report, LogSrvConfig config) {
|
||||
boolean saved = false;
|
||||
if (shouldSaveReport(config)) {
|
||||
File outputDir = new File(config.getOutputDir());
|
||||
if (!outputDir.exists()) {
|
||||
if (!outputDir.mkdirs()) {
|
||||
LogService.getLogger()
|
||||
.error("Error creating outputDir "
|
||||
+ config.getOutputDir());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String filename = config.getClusterName() + "_"
|
||||
+ SDF.format(new Date()) + ".html";
|
||||
String filePath = outputDir.getPath() + File.separator + filename;
|
||||
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(filePath, false);
|
||||
fos.write(report.getBytes());
|
||||
fos.flush();
|
||||
saved = true;
|
||||
} catch (FileNotFoundException e) {
|
||||
LogService.getLogger().error(
|
||||
"Error opening file output stream " + filePath, e);
|
||||
} catch (IOException e) {
|
||||
LogService.getLogger().error(
|
||||
"Error writing to file " + filePath, e);
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LogService
|
||||
.getLogger()
|
||||
.info("Skipping save of report"
|
||||
+ ", to enable saving reports ensure the log service's config has an outputDir");
|
||||
}
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the configuration indicates that the report should be saved
|
||||
*
|
||||
* @param cfg
|
||||
* @return
|
||||
*/
|
||||
protected boolean shouldSaveReport(LogSrvConfig cfg) {
|
||||
return (cfg.getOutputDir() != null);
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.quartz;
|
||||
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.SchedulerFactory;
|
||||
import org.quartz.Trigger;
|
||||
import org.quartz.TriggerUtils;
|
||||
import org.quartz.impl.StdSchedulerFactory;
|
||||
|
||||
import com.raytheon.uf.logsrv.config.LogSrvConfig;
|
||||
|
||||
/**
|
||||
* Schedules the quartz jobs in the main log process so at timed intervals, the
|
||||
* number of logging events in the db are reported and the error report is
|
||||
* generated and emailed.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 30, 2013 njensen Initial creation
|
||||
* Jun 11, 2014 2840 njensen Renamed create report job
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class JobScheduler {
|
||||
|
||||
public static void scheduleJobs(LogSrvConfig config)
|
||||
throws SchedulerException {
|
||||
SchedulerFactory factory = new StdSchedulerFactory();
|
||||
Scheduler sched = factory.getScheduler();
|
||||
sched.start();
|
||||
|
||||
JobDetail job = new JobDetail("Create and Send/Save Report Job",
|
||||
CreateReportJob.class);
|
||||
job.getJobDataMap().put("config", config);
|
||||
String[] split = config.getTimeToSend().split(":");
|
||||
int hour = Integer.parseInt(split[0]);
|
||||
int minute = Integer.parseInt(split[1]);
|
||||
Trigger trigger = TriggerUtils.makeDailyTrigger(hour, minute);
|
||||
trigger.setName("Report Trigger");
|
||||
sched.scheduleJob(job, trigger);
|
||||
|
||||
JobDetail countJob = new JobDetail("Count Rows Job", CountRowsJob.class);
|
||||
Trigger countTrigger = TriggerUtils.makeHourlyTrigger();
|
||||
countTrigger.setName("Count Trigger");
|
||||
sched.scheduleJob(countJob, countTrigger);
|
||||
|
||||
// TODO contemplate a purge job for the outputDir
|
||||
}
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.report;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
|
||||
import com.raytheon.uf.logsrv.config.LogSrvConfig;
|
||||
import com.raytheon.uf.logsrv.derby.DerbyDao;
|
||||
import com.raytheon.uf.logsrv.report.data.LogReportContainer;
|
||||
import com.raytheon.uf.logsrv.report.email.HtmlGenerator;
|
||||
import com.raytheon.uf.logsrv.report.email.ReportEmailer;
|
||||
|
||||
/**
|
||||
* A simple main that generates a report based on the current entries in the
|
||||
* database, emails the report, and then clears the database. Allows skipping
|
||||
* waiting for the once a day email.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 28, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class TestReportOutputter {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
JAXBContext context = JAXBContext.newInstance(LogSrvConfig.class);
|
||||
Unmarshaller m = context.createUnmarshaller();
|
||||
LogSrvConfig config = (LogSrvConfig) m
|
||||
.unmarshal(new File("config.xml"));
|
||||
config.validate();
|
||||
DerbyDao.getInstance().setConfig(config);
|
||||
LogReportContainer container = DerbyDao.getInstance().buildReport();
|
||||
String report = HtmlGenerator.generateHtml(container);
|
||||
ReportEmailer.email(report, config);
|
||||
DerbyDao.getInstance().clearEntries();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.report.data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A container that holds a concept of a report based on the frequency of
|
||||
* occurrences of logging events (ie errors) in the database.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 28, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class LogReportContainer {
|
||||
|
||||
private Map<String, LogReportEvent> map = new HashMap<String, LogReportEvent>();
|
||||
|
||||
private Timestamp earliestTime;
|
||||
|
||||
private Timestamp latestTime;
|
||||
|
||||
public void addError(LogReportEvent event, String machineName,
|
||||
int occurrences) {
|
||||
String key = event.getKey();
|
||||
if (!map.containsKey(key)) {
|
||||
map.put(key, event);
|
||||
}
|
||||
|
||||
LogReportEvent current = map.get(key);
|
||||
Map<String, Integer> machineCount = current.getMachineCount();
|
||||
Integer count = machineCount.get(machineName);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
count += occurrences;
|
||||
machineCount.put(machineName, count);
|
||||
}
|
||||
|
||||
public Collection<LogReportEvent> getEvents() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
public Timestamp getEarliestTime() {
|
||||
return earliestTime;
|
||||
}
|
||||
|
||||
public void setEarliestTime(Timestamp earliestTime) {
|
||||
this.earliestTime = earliestTime;
|
||||
}
|
||||
|
||||
public Timestamp getLatestTime() {
|
||||
return latestTime;
|
||||
}
|
||||
|
||||
public void setLatestTime(Timestamp latestTime) {
|
||||
this.latestTime = latestTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.report.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
|
||||
/**
|
||||
* An event representing a unique error that was originally reported as a
|
||||
* logging event, with a count of occurrences per machine.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 28, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class LogReportEvent implements Comparable<LogReportEvent> {
|
||||
|
||||
private int lineNumber;
|
||||
|
||||
private String javaClass;
|
||||
|
||||
private String sampleStacktrace;
|
||||
|
||||
private Map<String, Integer> machineCount = new HashMap<String, Integer>();
|
||||
|
||||
private String sampleMessage;
|
||||
|
||||
private String level;
|
||||
|
||||
private String threadName;
|
||||
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
public void setLineNumber(int lineNumber) {
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
public String getJavaClass() {
|
||||
return javaClass;
|
||||
}
|
||||
|
||||
public void setJavaClass(String javaClass) {
|
||||
this.javaClass = javaClass;
|
||||
}
|
||||
|
||||
public String getSampleStacktrace() {
|
||||
return sampleStacktrace;
|
||||
}
|
||||
|
||||
public void setSampleStacktrace(String sampleStacktrace) {
|
||||
this.sampleStacktrace = sampleStacktrace;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getMachineCount() {
|
||||
return machineCount;
|
||||
}
|
||||
|
||||
public void setMachineCount(Map<String, Integer> machineCount) {
|
||||
this.machineCount = machineCount;
|
||||
}
|
||||
|
||||
public String getSampleMessage() {
|
||||
return sampleMessage;
|
||||
}
|
||||
|
||||
public void setSampleMessage(String sampleMessage) {
|
||||
this.sampleMessage = sampleMessage;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public boolean receivedStack() {
|
||||
return lineNumber > 0;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
String key = null;
|
||||
if (receivedStack()) {
|
||||
key = javaClass + ":" + lineNumber;
|
||||
} else {
|
||||
key = sampleMessage;
|
||||
if (key == null) {
|
||||
key = "null";
|
||||
} else if (key.length() > 20) {
|
||||
// cut off the key to try and match it to others
|
||||
key = key.substring(0, 20);
|
||||
}
|
||||
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public int getTotalOccurences() {
|
||||
int count = 0;
|
||||
for (Integer i : machineCount.values()) {
|
||||
count += i;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the LogReportEvents to enable sorting. Sort order goes as
|
||||
* follows: warn, no stacktraces, and least number of occurrences error, no
|
||||
* stacktraces, and least number of occurrences stacktrace, warn, and least
|
||||
* number of occurrences stacktrace, error, and least number of occurrences
|
||||
*
|
||||
* For example, the highest/last in the sort would be the ERROR with a
|
||||
* stacktrace that occurred the most.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(LogReportEvent o) {
|
||||
int retVal = 0;
|
||||
if (!this.receivedStack() && o.receivedStack()) {
|
||||
retVal = -1;
|
||||
} else if (this.receivedStack() && !o.receivedStack()) {
|
||||
retVal = 1;
|
||||
} else {
|
||||
// both match on having a stacktrace or not, rank them
|
||||
// based on error or warning
|
||||
Level thisLevel = Level.valueOf(level);
|
||||
Level oLevel = Level.valueOf(o.getLevel());
|
||||
if (thisLevel.toInt() < oLevel.toInt()) {
|
||||
retVal = -1;
|
||||
} else if (thisLevel.toInt() > oLevel.toInt()) {
|
||||
retVal = 1;
|
||||
} else {
|
||||
// both match on having a stacktrace or not, and match
|
||||
// on being WARNs or ERRORs, so rank them on number
|
||||
// of times they occurred
|
||||
int count1 = this.getTotalOccurences();
|
||||
int count2 = o.getTotalOccurences();
|
||||
retVal = (count1 < count2) ? -1 : ((count1 == count2) ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public String getThreadName() {
|
||||
return threadName;
|
||||
}
|
||||
|
||||
public void setThreadName(String threadName) {
|
||||
this.threadName = threadName;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.report.email;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.logsrv.report.data.LogReportContainer;
|
||||
import com.raytheon.uf.logsrv.report.data.LogReportEvent;
|
||||
|
||||
/**
|
||||
* Uses a LogReportContainer to generate an HTML report that can be emailed.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 28, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class HtmlGenerator {
|
||||
|
||||
private static final int MAX_ERRORS = 100;
|
||||
|
||||
private static final String LINE_BREAK = "<BR/>";
|
||||
|
||||
private static final String HR = "<HR/>";
|
||||
|
||||
private static final SimpleDateFormat SDF = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm z");
|
||||
|
||||
/**
|
||||
* Generates an HTML string based on the report container
|
||||
*
|
||||
* @param container
|
||||
* the container of events to generate HTML for
|
||||
* @return an HTML formatted report
|
||||
*/
|
||||
public static String generateHtml(LogReportContainer container) {
|
||||
String report = null;
|
||||
if (container != null) {
|
||||
Collection<LogReportEvent> collection = container.getEvents();
|
||||
LogReportEvent[] array = collection.toArray(new LogReportEvent[0]);
|
||||
Arrays.sort(array, Collections.reverseOrder());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(buildHeader(array.length, container.getEarliestTime(),
|
||||
container.getLatestTime()));
|
||||
sb.append(LINE_BREAK);
|
||||
boolean foundFirstWithoutStacktrace = false;
|
||||
for (int i = 0; i < array.length && i < MAX_ERRORS; i++) {
|
||||
LogReportEvent event = array[i];
|
||||
if (!event.receivedStack() && !foundFirstWithoutStacktrace) {
|
||||
foundFirstWithoutStacktrace = true;
|
||||
sb.append(buildNoStacktraceDisclaimer());
|
||||
}
|
||||
sb.append(HR);
|
||||
sb.append(LINE_BREAK);
|
||||
sb.append(buildEvent(array[i]));
|
||||
sb.append(LINE_BREAK);
|
||||
sb.append(LINE_BREAK);
|
||||
}
|
||||
report = sb.toString();
|
||||
}
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
private static CharSequence buildHeader(int distinctErrors, Date earliest,
|
||||
Date latest) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Auto-generated error report");
|
||||
sb.append(LINE_BREAK);
|
||||
sb.append("Created on ");
|
||||
sb.append(SDF.format(new Date()));
|
||||
sb.append(LINE_BREAK);
|
||||
if (distinctErrors > 0) {
|
||||
sb.append("Timeframe of errors: <span style=\"font-style:italic;\">");
|
||||
sb.append(SDF.format(earliest));
|
||||
sb.append("</span>");
|
||||
sb.append(" to <span style=\"font-style:italic;\">");
|
||||
sb.append(SDF.format(latest));
|
||||
sb.append("</span>");
|
||||
sb.append(LINE_BREAK);
|
||||
}
|
||||
sb.append("Number of distinct errors reported: <span style=\"font-weight:bold;\">");
|
||||
sb.append(distinctErrors);
|
||||
sb.append("</span>");
|
||||
sb.append(LINE_BREAK);
|
||||
if (distinctErrors > MAX_ERRORS) {
|
||||
sb.append("Report truncated to top ");
|
||||
sb.append(MAX_ERRORS);
|
||||
sb.append(" errors/warnings");
|
||||
sb.append(LINE_BREAK);
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
private static CharSequence buildEvent(LogReportEvent event) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<span style=\"font-weight:bold;\">");
|
||||
sb.append(event.getLevel());
|
||||
if (!event.receivedStack()) {
|
||||
// thread name is really only useful if we don't have a stacktrace
|
||||
sb.append(" [");
|
||||
sb.append(event.getThreadName());
|
||||
sb.append("]");
|
||||
}
|
||||
sb.append(" ");
|
||||
sb.append(event.getSampleMessage());
|
||||
sb.append("</span>");
|
||||
sb.append(LINE_BREAK);
|
||||
sb.append("Occurred a total of <span style=\"font-weight:bold;\">");
|
||||
sb.append(event.getTotalOccurences());
|
||||
sb.append("</span> times on the following machines:");
|
||||
sb.append(LINE_BREAK);
|
||||
Map<String, Integer> machineCount = event.getMachineCount();
|
||||
Set<Entry<String, Integer>> set = machineCount.entrySet();
|
||||
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(
|
||||
set);
|
||||
// sort it so the machines with the most errors are listed first
|
||||
Collections.sort(list, new Comparator<Entry<String, Integer>>() {
|
||||
@Override
|
||||
public int compare(Entry<String, Integer> o1,
|
||||
Entry<String, Integer> o2) {
|
||||
int val1 = o1.getValue();
|
||||
int val2 = o2.getValue();
|
||||
return (val2 < val1) ? -1 : ((val1 == val2) ? 0 : 1);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
for (Entry<String, Integer> entry : list) {
|
||||
sb.append("<span style=\"font-style:italic; padding-left: 30px;\">");
|
||||
sb.append(entry.getKey());
|
||||
sb.append("</span>: ");
|
||||
sb.append(entry.getValue());
|
||||
sb.append(" occurrences");
|
||||
sb.append(LINE_BREAK);
|
||||
}
|
||||
sb.append(LINE_BREAK);
|
||||
if (event.receivedStack()) {
|
||||
sb.append(event.getSampleStacktrace().replaceAll("\n", LINE_BREAK));
|
||||
}
|
||||
sb.append(LINE_BREAK);
|
||||
return sb;
|
||||
}
|
||||
|
||||
private static CharSequence buildNoStacktraceDisclaimer() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(LINE_BREAK);
|
||||
sb.append(HR);
|
||||
sb.append("<b>Disclaimer</b>: The following errors were received without stacktraces and...");
|
||||
sb.append("<ul><li>Are estimated/inexact</li>");
|
||||
sb.append("<li>Should be considered for downgrade to INFO or DEBUG messages");
|
||||
sb.append("<li>Should include stacktraces if remaining as ERROR</li></ul>");
|
||||
return sb;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/**
|
||||
* 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.logsrv.report.email;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Message;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Transport;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import com.raytheon.uf.logsrv.config.LogSrvConfig;
|
||||
|
||||
/**
|
||||
* Emails a report using the options specified in the config.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 29, 2013 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ReportEmailer {
|
||||
|
||||
/**
|
||||
* Emails the provided string, using the options from the config.
|
||||
*
|
||||
* @param report
|
||||
* the text to email
|
||||
* @param config
|
||||
* the config of email options
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void email(String report, LogSrvConfig config)
|
||||
throws Exception {
|
||||
Properties props = new Properties();
|
||||
props.put("host", config.getSmtpHost());
|
||||
props.put("mail.smtp.user", config.getFromAddress());
|
||||
props.put("port", config.getSmtpPort());
|
||||
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
MimeMessage message = new MimeMessage(session);
|
||||
message.setFrom(new InternetAddress(config.getFromAddress()));
|
||||
String[] split = config.getToAddress().split(",");
|
||||
for (String to : split) {
|
||||
message.addRecipient(Message.RecipientType.TO, new InternetAddress(
|
||||
to.trim()));
|
||||
}
|
||||
message.setSubject(config.getClusterName() + " error report");
|
||||
message.setContent(report, "text/html; charset=utf-8");
|
||||
Transport transport = session.getTransport("smtp");
|
||||
transport.connect(config.getSmtpHost(), config.getFromAddress(), null);
|
||||
transport.sendMessage(message, message.getAllRecipients());
|
||||
transport.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.topo.utilities</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,7 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -1,11 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Utilities
|
||||
Bundle-SymbolicName: com.raytheon.uf.topo.utilities
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.pypies;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174"
|
|
@ -1,5 +0,0 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
logback.xml
|
|
@ -1,68 +0,0 @@
|
|||
<configuration debug="false" scan="false">
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-5p %d [%t] %c{0}: %m%n</pattern>
|
||||
</encoder>
|
||||
<filter class="com.raytheon.uf.common.status.logback.InvertedThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="errConsole" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<target>System.err</target>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>WARN</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<pattern>%-5p %d [%t] %c{0}: %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="CaveLogger">
|
||||
<level value="ALL"/>
|
||||
</logger>
|
||||
|
||||
<logger name="PerformanceLogger">
|
||||
<level value="ALL"/>
|
||||
</logger>
|
||||
|
||||
<logger name="com.raytheon">
|
||||
<level value="INFO"/>
|
||||
</logger>
|
||||
|
||||
<logger name="com.tc">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="mx4j">
|
||||
<level value="ERROR"/>
|
||||
</logger>
|
||||
<logger name="org.apache">
|
||||
<level value="INFO"/>
|
||||
</logger>
|
||||
<logger name="org.apache.activemq.spring">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.apache.commons.beanutils">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.apache.qpid">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.geotools">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.apache.xbean.spring">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.springframework">
|
||||
<level value="ERROR"/>
|
||||
</logger>
|
||||
<logger name="uk.ltd.getahead">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<root>
|
||||
<level value="INFO"/>
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="errConsole"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -1,536 +0,0 @@
|
|||
/**
|
||||
* 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.topo.utilities;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.opengis.referencing.crs.ProjectedCRS;
|
||||
|
||||
import com.raytheon.uf.common.datastorage.IDataStore;
|
||||
import com.raytheon.uf.common.datastorage.StorageProperties;
|
||||
import com.raytheon.uf.common.datastorage.StorageProperties.Compression;
|
||||
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.LongDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
import com.raytheon.uf.common.pypies.PyPiesDataStore;
|
||||
import com.raytheon.uf.common.pypies.PypiesProperties;
|
||||
|
||||
/**
|
||||
* Import topo data into HDF5
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 22, 2009 #3280 randerso Initial creation
|
||||
* Feb 11, 2014 #2788 randerso Changed to use PyPiesDataStore
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author randerso
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class TopoImporter {
|
||||
|
||||
private static class TopoHdr implements Comparable<TopoHdr> {
|
||||
File file;
|
||||
|
||||
String byteOrder;
|
||||
|
||||
int nRows;
|
||||
|
||||
int nCols;
|
||||
|
||||
int nBits;
|
||||
|
||||
int totalRowBytes;
|
||||
|
||||
long noData;
|
||||
|
||||
double ulXmap;
|
||||
|
||||
double ulYmap;
|
||||
|
||||
double xDim;
|
||||
|
||||
double yDim;
|
||||
|
||||
public TopoHdr(File file) {
|
||||
if (file.getName().endsWith(".HDR")) {
|
||||
readHdrFile(file);
|
||||
} else if (file.getName().endsWith(".ers")) {
|
||||
readErsFile(file);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Unrecognized header file format: "
|
||||
+ file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private void readHdrFile(File file) {
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
this.file = file;
|
||||
in = new BufferedReader(new FileReader(file));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
String[] s = line.split("\\s+");
|
||||
|
||||
if ("BYTEORDER".equals(s[0])) {
|
||||
byteOrder = s[1];
|
||||
} else if ("NROWS".equals(s[0])) {
|
||||
nRows = Integer.parseInt(s[1]);
|
||||
} else if ("NCOLS".equals(s[0])) {
|
||||
nCols = Integer.parseInt(s[1]);
|
||||
} else if ("NBITS".equals(s[0])) {
|
||||
nBits = Integer.parseInt(s[1]);
|
||||
} else if ("TOTALROWBYTES".equals(s[0])) {
|
||||
totalRowBytes = Integer.parseInt(s[1]);
|
||||
} else if ("NODATA".equals(s[0])) {
|
||||
noData = Long.parseLong(s[1]);
|
||||
} else if ("ULXMAP".equals(s[0])) {
|
||||
ulXmap = Double.parseDouble(s[1]);
|
||||
} else if ("ULYMAP".equals(s[0])) {
|
||||
ulYmap = Double.parseDouble(s[1]);
|
||||
} else if ("XDIM".equals(s[0])) {
|
||||
xDim = Double.parseDouble(s[1]);
|
||||
} else if ("YDIM".equals(s[0])) {
|
||||
yDim = Double.parseDouble(s[1]);
|
||||
} else {
|
||||
System.out.println("Unrecognized line in file "
|
||||
+ file.getAbsolutePath() + "\n" + line);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readErsFile(File file) {
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
this.file = file;
|
||||
in = new BufferedReader(new FileReader(file));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
line = line.replace(" = ", " ");
|
||||
String[] s = line.split("\\s+");
|
||||
|
||||
if ("ByteOrder".equals(s[0])) {
|
||||
byteOrder = s[1];
|
||||
} else if ("NrOfLines".equals(s[0])) {
|
||||
nRows = Integer.parseInt(s[1]);
|
||||
} else if ("NrOfCellsPerLine".equals(s[0])) {
|
||||
nCols = Integer.parseInt(s[1]);
|
||||
} else if ("CellType".equals(s[0])) {
|
||||
if (s[1].equals("Signed16BitInteger")) {
|
||||
nBits = 16;
|
||||
} else if (s[1].equals("Signed32BitInteger")) {
|
||||
nBits = 32;
|
||||
} else if (s[1].equals("Signed64BitInteger")) {
|
||||
nBits = 64;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Unrecognized data type: " + s[1]);
|
||||
}
|
||||
} else if ("NullCellValue".equals(s[0])) {
|
||||
noData = Long.parseLong(s[1]);
|
||||
} else if ("Longitude".equals(s[0])) {
|
||||
ulXmap = parseDMS(s[1]);
|
||||
} else if ("Latitude".equals(s[0])) {
|
||||
ulYmap = parseDMS(s[1]);
|
||||
} else if ("Xdimension".equals(s[0])) {
|
||||
xDim = Double.parseDouble(s[1]);
|
||||
} else if ("Ydimension".equals(s[0])) {
|
||||
yDim = Double.parseDouble(s[1]);
|
||||
} else {
|
||||
// TODO: fully recognize the ers header file
|
||||
System.out.println("Unrecognized line in file "
|
||||
+ file.getAbsolutePath() + "\n" + line);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// convert upper left coordinate from corner to
|
||||
// center of cell
|
||||
ulXmap += xDim / 2;
|
||||
ulYmap -= yDim / 2;
|
||||
|
||||
totalRowBytes = (nCols * nBits) / 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double parseDMS(String dms) {
|
||||
// parse a string in degrees:minutes:seconds format into decimal
|
||||
// degrees
|
||||
double degrees = Double.NaN;
|
||||
String[] s = dms.split(":");
|
||||
if (s.length == 3) {
|
||||
try {
|
||||
int deg = Integer.parseInt(s[0]);
|
||||
int min = Integer.parseInt(s[1]);
|
||||
double sec = Double.parseDouble(s[2]);
|
||||
degrees = deg + (min - ((sec / 60.0) / 60.0));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Unable to parse DMS: "
|
||||
+ dms, e);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unable to parse DMS: "
|
||||
+ dms);
|
||||
}
|
||||
return degrees;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(TopoHdr o) {
|
||||
// sort descending in Y, ascending in X
|
||||
int retVal = Double.compare(o.ulYmap, ulYmap);
|
||||
if (retVal == 0) {
|
||||
retVal = Double.compare(ulXmap, o.ulXmap);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
private static final double TOL = 0.0000001;
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
long t0 = System.currentTimeMillis();
|
||||
FilenameFilter filter = new FilenameFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".HDR") || name.endsWith(".ers");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (args.length < 1) {
|
||||
System.out
|
||||
.println("Usage: TopoImporter <topoDir>\n"
|
||||
+ " Where <topoDir> is a directory path containing topo data in *.DEM and *.HDR file pairs.");
|
||||
}
|
||||
|
||||
// read in all the hdr files
|
||||
File dir = new File(args[0]);
|
||||
System.out.println("Importing topo data from " + dir.getAbsolutePath());
|
||||
List<TopoHdr> hdrList = new ArrayList<TopoHdr>();
|
||||
for (File file : dir.listFiles(filter)) {
|
||||
hdrList.add(new TopoHdr(file));
|
||||
}
|
||||
|
||||
if (hdrList.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"No recognized header files found");
|
||||
}
|
||||
|
||||
// sort the hdr files by descending lat/ascending lon
|
||||
Collections.sort(hdrList);
|
||||
|
||||
// verify the files are in the expected order and
|
||||
// determine the total dataset dimensions
|
||||
double startLat = hdrList.get(0).ulYmap;
|
||||
double startLon = hdrList.get(0).ulXmap;
|
||||
double xDim = hdrList.get(0).xDim;
|
||||
double yDim = hdrList.get(0).yDim;
|
||||
|
||||
int last = hdrList.size() - 1;
|
||||
double endLat = hdrList.get(last).ulYmap
|
||||
- ((hdrList.get(last).nRows - 1) * hdrList.get(last).yDim);
|
||||
double endLon = hdrList.get(last).ulXmap
|
||||
+ ((hdrList.get(last).nCols - 1) * hdrList.get(last).xDim);
|
||||
int bits = hdrList.get(0).nBits;
|
||||
|
||||
double expectedLat = startLat;
|
||||
double expectedLon = startLon;
|
||||
int maxRows = 0;
|
||||
int maxCols = 0;
|
||||
int rows = 0;
|
||||
int cols = 0;
|
||||
for (TopoHdr hdr : hdrList) {
|
||||
// is this the expected file ??
|
||||
if (Math.abs(expectedLat - hdr.ulYmap) > TOL) {
|
||||
System.out.println("Bad latitude. Expected: " + expectedLat
|
||||
+ " got: " + hdr.ulYmap);
|
||||
}
|
||||
|
||||
if (Math.abs(expectedLon - hdr.ulXmap) > TOL) {
|
||||
System.out.println("Bad longtude. Expected: " + expectedLat
|
||||
+ " got: " + hdr.ulXmap);
|
||||
}
|
||||
|
||||
// determine expected origin of next file
|
||||
cols += hdr.nCols;
|
||||
maxCols = Math.max(cols, maxCols);
|
||||
|
||||
expectedLat = hdr.ulYmap;
|
||||
expectedLon = hdr.ulXmap + (hdr.nCols * hdr.xDim);
|
||||
if ((expectedLon - startLon) > (360.0 - TOL)) {
|
||||
expectedLon = startLon;
|
||||
expectedLat -= hdr.nRows * hdr.yDim;
|
||||
rows += hdr.nRows;
|
||||
maxRows = Math.max(rows, maxRows);
|
||||
cols = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// create the hdf5 file
|
||||
File hdf = new File("topo" + File.separatorChar
|
||||
+ dir.getName().toLowerCase() + "_unpacked.h5");
|
||||
if (hdf.exists()) {
|
||||
System.out
|
||||
.println(hdf.getAbsolutePath()
|
||||
+ " exists\nIf you wish to recreate, delete this file and try again.");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
PypiesProperties pypiesProps = new PypiesProperties();
|
||||
pypiesProps.setAddress("http://localhost:9582");
|
||||
IDataStore store = new PyPiesDataStore(hdf, true, pypiesProps);
|
||||
|
||||
String dataset = "full";
|
||||
long[] sizes = new long[] { maxCols, maxRows };
|
||||
|
||||
StorageProperties properties = new StorageProperties();
|
||||
properties.setCompression(Compression.NONE);
|
||||
properties.setChunked(true);
|
||||
|
||||
IDataRecord record = null;
|
||||
if (bits <= Byte.SIZE) {
|
||||
record = new ByteDataRecord(dataset, null, null, 2, sizes);
|
||||
record.setFillValue(Byte.MIN_VALUE);
|
||||
} else if (bits <= Short.SIZE) {
|
||||
record = new ShortDataRecord(dataset, null, null, 2, sizes);
|
||||
record.setFillValue(Short.MIN_VALUE);
|
||||
} else if (bits <= Integer.SIZE) {
|
||||
record = new IntegerDataRecord(dataset, null, null, 2, sizes);
|
||||
record.setFillValue(Integer.MIN_VALUE);
|
||||
} else if (bits <= Long.SIZE) {
|
||||
record = new LongDataRecord(dataset, null, null, 2, sizes);
|
||||
record.setFillValue(Long.MIN_VALUE);
|
||||
} else {
|
||||
System.out.println("NBITS > 64");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
double centralMeridian = 0.0;
|
||||
double latOfOrigin = 0.0;
|
||||
|
||||
double cm = (startLon + endLon) / 2;
|
||||
centralMeridian = Math.round(cm);
|
||||
|
||||
ProjectedCRS crs = MapUtil.constructEquidistantCylindrical(
|
||||
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS,
|
||||
centralMeridian, latOfOrigin);
|
||||
|
||||
Map<String, Object> attributes = new LinkedHashMap<String, Object>();
|
||||
attributes.put("Width", maxCols);
|
||||
attributes.put("Height", maxRows);
|
||||
|
||||
// Using arrays to work around serialization "feature" that returns
|
||||
// floats when doubles are stored
|
||||
// H5DataStore created these arrays automatically, Pypies does not
|
||||
attributes.put("xDim", new double[] { xDim });
|
||||
attributes.put("yDim", new double[] { yDim });
|
||||
attributes.put("ulLat", new double[] { startLat });
|
||||
attributes.put("ulLon", new double[] { startLon });
|
||||
attributes.put("lrLat", new double[] { endLat });
|
||||
attributes.put("lrLon", new double[] { endLon });
|
||||
attributes.put("CRS", crs.toWKT());
|
||||
|
||||
record.setProperties(properties);
|
||||
record.setDataAttributes(attributes);
|
||||
|
||||
try {
|
||||
store.createDataset(record);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
rows = 0;
|
||||
cols = 0;
|
||||
for (TopoHdr hdr : hdrList) {
|
||||
String demPath = hdr.file.getAbsolutePath();
|
||||
if (demPath.endsWith(".HDR")) {
|
||||
demPath = demPath.replace(".HDR", ".DEM");
|
||||
} else if (demPath.endsWith(".ers")) {
|
||||
demPath = demPath.replace(".ers", "");
|
||||
}
|
||||
|
||||
File dem = new File(demPath);
|
||||
|
||||
System.out.println(cols + ", " + rows + " " + dem.getName());
|
||||
|
||||
DataInputStream in = null;
|
||||
try {
|
||||
in = new DataInputStream(new FileInputStream(dem));
|
||||
ByteBuffer buffer = ByteBuffer.allocate(hdr.totalRowBytes);
|
||||
|
||||
if (hdr.byteOrder.startsWith("M")) {
|
||||
buffer.order(ByteOrder.BIG_ENDIAN);
|
||||
} else {
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
sizes[0] = hdr.nCols;
|
||||
sizes[1] = 1;
|
||||
record = null;
|
||||
long writeSize = 0;
|
||||
for (int i = 0; i < hdr.nRows; i++) {
|
||||
in.read(buffer.array());
|
||||
buffer.rewind();
|
||||
if (bits <= Byte.SIZE) {
|
||||
byte[] byteData = new byte[hdr.nCols];
|
||||
for (int j = 0; j < byteData.length; j++) {
|
||||
byteData[j] = buffer.get();
|
||||
|
||||
// replace no data flag with 0
|
||||
if (byteData[j] == (byte) hdr.noData) {
|
||||
byteData[j] = Byte.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
record = new ByteDataRecord(dataset, null, null, 2,
|
||||
sizes);
|
||||
record.setMinIndex(new long[] { cols, rows + i });
|
||||
record.setFillValue(Byte.MIN_VALUE);
|
||||
((ByteDataRecord) record).setByteData(buffer.array());
|
||||
} else if (bits <= Short.SIZE) {
|
||||
short[] shortData = new short[hdr.nCols];
|
||||
for (int j = 0; j < shortData.length; j++) {
|
||||
shortData[j] = buffer.getShort();
|
||||
|
||||
// replace no data flag with 0
|
||||
if (shortData[j] == (short) hdr.noData) {
|
||||
shortData[j] = Short.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
record = new ShortDataRecord(dataset, null, null, 2,
|
||||
sizes);
|
||||
record.setMinIndex(new long[] { cols, rows + i });
|
||||
record.setFillValue(Short.MIN_VALUE);
|
||||
((ShortDataRecord) record).setShortData(shortData);
|
||||
} else if (bits <= Integer.SIZE) {
|
||||
int[] intData = new int[hdr.nCols];
|
||||
for (int j = 0; j < intData.length; j++) {
|
||||
intData[j] = buffer.getInt();
|
||||
|
||||
// replace no data flag with 0
|
||||
if (intData[j] == (int) hdr.noData) {
|
||||
intData[j] = Integer.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
record = new IntegerDataRecord(dataset, null, null, 2,
|
||||
sizes);
|
||||
record.setMinIndex(new long[] { cols, rows + i });
|
||||
record.setFillValue(Integer.MIN_VALUE);
|
||||
((IntegerDataRecord) record).setIntData(intData);
|
||||
} else if (bits <= Long.SIZE) {
|
||||
long[] longData = new long[hdr.nCols];
|
||||
for (int j = 0; j < longData.length; j++) {
|
||||
longData[j] = buffer.getLong();
|
||||
|
||||
// replace no data flag with 0
|
||||
if (longData[j] == hdr.noData) {
|
||||
longData[j] = Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
record = new LongDataRecord(dataset, null, null, 2,
|
||||
sizes);
|
||||
record.setMinIndex(new long[] { cols, rows + i });
|
||||
record.setFillValue(Long.MIN_VALUE);
|
||||
((LongDataRecord) record).setLongData(longData);
|
||||
}
|
||||
|
||||
store.addDataRecord(record, properties);
|
||||
writeSize += hdr.totalRowBytes;
|
||||
if (writeSize > (64 * 1024 * 1024)) {
|
||||
store.store();
|
||||
writeSize = 0;
|
||||
}
|
||||
}
|
||||
store.store();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// determine origin of next file
|
||||
cols += hdr.nCols;
|
||||
|
||||
if (cols >= maxCols) {
|
||||
rows += hdr.nRows;
|
||||
cols = 0;
|
||||
}
|
||||
}
|
||||
System.out.println("took " + ((System.currentTimeMillis() - t0) / 1000)
|
||||
+ " seconds");
|
||||
}
|
||||
}
|
|
@ -1,301 +0,0 @@
|
|||
/**
|
||||
* 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.topo.utilities;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferFloat;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBufferShort;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.media.jai.BorderExtender;
|
||||
import javax.media.jai.Interpolation;
|
||||
import javax.media.jai.JAI;
|
||||
import javax.media.jai.ParameterBlockJAI;
|
||||
import javax.media.jai.PlanarImage;
|
||||
import javax.media.jai.RasterFactory;
|
||||
import javax.media.jai.TiledImage;
|
||||
|
||||
import com.raytheon.uf.common.datastorage.IDataStore;
|
||||
import com.raytheon.uf.common.datastorage.Request;
|
||||
import com.raytheon.uf.common.datastorage.StorageProperties;
|
||||
import com.raytheon.uf.common.datastorage.StorageProperties.Compression;
|
||||
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.ShortDataRecord;
|
||||
import com.raytheon.uf.common.pypies.PyPiesDataStore;
|
||||
import com.raytheon.uf.common.pypies.PypiesProperties;
|
||||
|
||||
/**
|
||||
* Interpolator for topo data files
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 26, 2009 randerso Initial creation
|
||||
* Feb 12, 2013 #1608 randerso Remove exlicit references to HDF5DataStore
|
||||
* Added explicit calls to deleteGroups
|
||||
* Feb 11, 2014 #2788 randerso Changed to use PyPiesDataStore
|
||||
* Fixed corner points for interpolated levels
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author randerso
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class TopoInterpolator {
|
||||
private static final int BLOCK_SIZE = 2400;
|
||||
|
||||
private IDataStore dataStore;
|
||||
|
||||
/**
|
||||
* Create a TopoInterpolator instance for the specified hdf file
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
public TopoInterpolator(File hdf) {
|
||||
PypiesProperties pypiesProps = new PypiesProperties();
|
||||
pypiesProps.setAddress("http://localhost:9582");
|
||||
dataStore = new PyPiesDataStore(hdf, true, pypiesProps);
|
||||
}
|
||||
|
||||
public void interpolate(String group, String dataSet) {
|
||||
|
||||
Request request = Request.buildSlab(new int[] { 0, 0 }, new int[] { 1,
|
||||
1 });
|
||||
try {
|
||||
IDataRecord record = dataStore.retrieve(group, dataSet, request);
|
||||
Map<String, Object> attributes = record.getDataAttributes();
|
||||
int width = (Integer) attributes.get("Width");
|
||||
int height = (Integer) attributes.get("Height");
|
||||
|
||||
// These attributes are stored as 1x1 arrays in the file to match
|
||||
// what H5DataStore did
|
||||
// Pypies automatically returns them as scalars
|
||||
double xDim = (Double) attributes.get("xDim");
|
||||
double yDim = (Double) attributes.get("yDim");
|
||||
double startLat = (Double) attributes.get("ulLat");
|
||||
double startLon = (Double) attributes.get("ulLon");
|
||||
double endLat = (Double) attributes.get("lrLat");
|
||||
double endLon = (Double) attributes.get("lrLon");
|
||||
|
||||
int level = 1;
|
||||
String srcGroup = group;
|
||||
String srcDataSet = dataSet;
|
||||
String dstGroup = group
|
||||
+ (group.endsWith("/") ? "interpolated" : "/interpolated");
|
||||
|
||||
// remove existing interpolated datasets
|
||||
if (Arrays.asList(dataStore.getDatasets(srcGroup)).contains(
|
||||
"interpolated")) {
|
||||
dataStore.deleteGroups(dstGroup);
|
||||
}
|
||||
|
||||
StorageProperties properties = new StorageProperties();
|
||||
properties.setCompression(Compression.NONE);
|
||||
properties.setChunked(true);
|
||||
|
||||
long t0 = System.currentTimeMillis();
|
||||
long t1 = t0;
|
||||
while (level < 6) {
|
||||
System.out.print("\nInterpolating " + srcGroup + srcDataSet
|
||||
+ " (" + width + ", " + height + ")");
|
||||
|
||||
int srcWidth = width;
|
||||
int srcHeight = height;
|
||||
|
||||
// compute attributes for new level
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
startLon += xDim / 2;
|
||||
startLat -= yDim / 2;
|
||||
endLon -= xDim / 2;
|
||||
endLat += yDim / 2;
|
||||
xDim *= 2;
|
||||
yDim *= 2;
|
||||
String dstDataSet = "" + level;
|
||||
record.setName(dstDataSet);
|
||||
record.setGroup(dstGroup);
|
||||
record.setSizes(new long[] { width, height });
|
||||
record.setProperties(properties);
|
||||
attributes.put("Width", width);
|
||||
attributes.put("Height", height);
|
||||
attributes.put("xDim", new double[] { xDim });
|
||||
attributes.put("yDim", new double[] { yDim });
|
||||
attributes.put("ulLat", new double[] { startLat });
|
||||
attributes.put("ulLon", new double[] { startLon });
|
||||
attributes.put("lrLat", new double[] { endLat });
|
||||
attributes.put("lrLon", new double[] { endLon });
|
||||
record.setDataAttributes(attributes);
|
||||
|
||||
dataStore.createDataset(record);
|
||||
|
||||
int y = 0;
|
||||
while (y < srcHeight) {
|
||||
System.out.print(".");
|
||||
int h = Math.min(BLOCK_SIZE, srcHeight - y);
|
||||
|
||||
int x = 0;
|
||||
while (x < srcWidth) {
|
||||
int w = Math.min(BLOCK_SIZE, srcWidth - x);
|
||||
request = Request.buildSlab(new int[] { x, y },
|
||||
new int[] { x + w, y + h });
|
||||
record = dataStore.retrieve(srcGroup, srcDataSet,
|
||||
request);
|
||||
|
||||
resize(record, 2);
|
||||
record.setName(dstDataSet);
|
||||
record.setGroup(dstGroup);
|
||||
record.setMinIndex(new long[] { x / 2, y / 2 });
|
||||
|
||||
dataStore.addDataRecord(record);
|
||||
dataStore.store();
|
||||
|
||||
x += BLOCK_SIZE;
|
||||
}
|
||||
y += BLOCK_SIZE;
|
||||
}
|
||||
|
||||
long t2 = System.currentTimeMillis();
|
||||
System.out.print(" took " + ((t2 - t1) / 1000) + " s");
|
||||
t1 = t2;
|
||||
|
||||
srcGroup = dstGroup;
|
||||
srcDataSet = dstDataSet;
|
||||
level++;
|
||||
}
|
||||
System.out.print("\nTotal "
|
||||
+ ((System.currentTimeMillis() - t0) / 1000) + " s");
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected static void resize(IDataRecord rec, int scale) {
|
||||
int w = (int) rec.getSizes()[0];
|
||||
int h = (int) rec.getSizes()[1];
|
||||
|
||||
int len = w * h;
|
||||
java.awt.Point origin = new Point(0, 0);
|
||||
|
||||
// create a sample model
|
||||
DataBuffer dataBuffer = null;
|
||||
int type = 0;
|
||||
|
||||
Object in = rec.getDataObject();
|
||||
|
||||
if (rec instanceof ByteDataRecord) {
|
||||
dataBuffer = new java.awt.image.DataBufferByte((byte[]) in, len);
|
||||
type = DataBuffer.TYPE_BYTE;
|
||||
} else if (rec instanceof ShortDataRecord) {
|
||||
dataBuffer = new java.awt.image.DataBufferShort((short[]) in, len);
|
||||
type = DataBuffer.TYPE_SHORT;
|
||||
} else if (rec instanceof IntegerDataRecord) {
|
||||
dataBuffer = new java.awt.image.DataBufferInt((int[]) in, len);
|
||||
type = DataBuffer.TYPE_INT;
|
||||
} else if (rec instanceof FloatDataRecord) {
|
||||
dataBuffer = new java.awt.image.DataBufferFloat((float[]) in, len);
|
||||
type = DataBuffer.TYPE_FLOAT;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("["
|
||||
+ rec.getClass().getName() + "]"
|
||||
+ " not supported by resize.");
|
||||
}
|
||||
|
||||
SampleModel sampleModel = RasterFactory.createBandedSampleModel(type,
|
||||
w, h, 1);
|
||||
|
||||
// create a TiledImage using the float SampleModel
|
||||
TiledImage tiledImage = new TiledImage(0, 0, w, h, 0, 0, sampleModel,
|
||||
null);
|
||||
|
||||
// create a Raster
|
||||
Raster raster = RasterFactory.createWritableRaster(sampleModel,
|
||||
dataBuffer, origin);
|
||||
|
||||
// set the TiledImage data to that of the Raster
|
||||
tiledImage.setData(raster);
|
||||
|
||||
PlanarImage scaledImg;
|
||||
|
||||
// Interpolate the image using a scale factor and
|
||||
// the copy border extender
|
||||
ParameterBlockJAI param = new ParameterBlockJAI("Scale");
|
||||
param.addSource(tiledImage);
|
||||
param.setParameter("xScale", 1.0f / scale);
|
||||
param.setParameter("yScale", 1.0f / scale);
|
||||
Interpolation interpol = Interpolation
|
||||
.getInstance(Interpolation.INTERP_NEAREST);
|
||||
param.setParameter("interpolation", interpol);
|
||||
RenderingHints hint = new RenderingHints(JAI.KEY_BORDER_EXTENDER,
|
||||
BorderExtender.createInstance(BorderExtender.BORDER_COPY));
|
||||
scaledImg = JAI.create("Scale", param, hint);
|
||||
|
||||
// Get the floats back out
|
||||
DataBuffer newDb = scaledImg.getData().getDataBuffer();
|
||||
|
||||
if (rec instanceof ByteDataRecord) {
|
||||
((ByteDataRecord) rec).setByteData(((DataBufferByte) newDb)
|
||||
.getData());
|
||||
} else if (rec instanceof ShortDataRecord) {
|
||||
((ShortDataRecord) rec).setShortData(((DataBufferShort) newDb)
|
||||
.getData());
|
||||
} else if (rec instanceof IntegerDataRecord) {
|
||||
((IntegerDataRecord) rec).setIntData(((DataBufferInt) newDb)
|
||||
.getData());
|
||||
} else if (rec instanceof FloatDataRecord) {
|
||||
((FloatDataRecord) rec).setFloatData(((DataBufferFloat) newDb)
|
||||
.getData());
|
||||
}
|
||||
|
||||
rec.setSizes(new long[] { w / 2, h / 2 });
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
TopoInterpolator ti;
|
||||
if (args.length < 1) {
|
||||
System.out.println("usage: TopoInterpolator topofile");
|
||||
} else {
|
||||
String fileName = args[0];
|
||||
System.out.println("Interpolating " + fileName);
|
||||
ti = new TopoInterpolator(new File(fileName));
|
||||
|
||||
ti.interpolate("/", "full");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.hprof</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -1,8 +0,0 @@
|
|||
#Wed Sep 07 17:58:19 CDT 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
|
@ -1,15 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: com.raytheon.uf.viz.hprof.CaveExporter
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Viz Hprof Analysis
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.hprof
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.raytheon.hprof,
|
||||
com.raytheon.hprof.data,
|
||||
com.raytheon.hprof.data.heap,
|
||||
com.raytheon.hprof.data.heap.dump,
|
||||
com.raytheon.hprof.data.heap.root,
|
||||
com.raytheon.uf.viz.hprof
|
|
@ -1,4 +0,0 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -1,66 +0,0 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<project name="com.raytheon.uf.viz.hprof" default="dist">
|
||||
|
||||
<property name="src" location="src"/>
|
||||
<property name="bin" location="bin"/>
|
||||
<property name="main" value="com.raytheon.uf.viz.hprof.CaveExporter"/>
|
||||
<property name="qualifier" value="${date}"/>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${bin}"/>
|
||||
<tstamp>
|
||||
<format property="date" pattern="yyyyMMdd" />
|
||||
</tstamp>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<javac target="1.6" srcdir="${src}" destdir="${bin}"/>
|
||||
</target>
|
||||
|
||||
<target name="copyManifest" depends="init">
|
||||
<loadproperties srcfile="META-INF/MANIFEST.MF">
|
||||
<filterchain>
|
||||
<linecontainsregexp>
|
||||
<regexp pattern="^Bundle-Version: \d+.\d+.\d+.qualifier$" />
|
||||
</linecontainsregexp>
|
||||
<tokenfilter>
|
||||
<replaceregex pattern="qualifier$" replace="${qualifier}" />
|
||||
</tokenfilter>
|
||||
</filterchain>
|
||||
</loadproperties>
|
||||
<copy file="META-INF/MANIFEST.MF" tofile="${bin}/META-INF/MANIFEST.MF" />
|
||||
<manifest file="${bin}/META-INF/MANIFEST.MF" mode="update">
|
||||
<attribute name="Bundle-Version" value="${Bundle-Version}" />
|
||||
</manifest>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="compile,copyManifest">
|
||||
<jar destfile="${ant.project.name}-${Bundle-Version}.jar" basedir="${bin}" manifest="${bin}/META-INF/MANIFEST.MF"/>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${bin}"/>
|
||||
<delete verbose="true">
|
||||
<fileset dir="." includes="${ant.project.name}-*.jar"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
</project>
|
|
@ -1,231 +0,0 @@
|
|||
/**
|
||||
* 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.hprof;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
|
||||
/**
|
||||
*
|
||||
* ByteBuffers cannot be used to index more than 2GB of data. Since some hprof
|
||||
* files are larger than that a BigByteBuffer is used to allow long indexing
|
||||
* into a much larger space. BigByteBuffers internally are represented by direct
|
||||
* memory mapped byte buffers that map the contents of a single file.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
* May 20, 2014 3093 bsteffen Allow read/write
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BigByteBuffer {
|
||||
|
||||
private final long chunkSize = 1024 * 1024 * 256;
|
||||
|
||||
private final ByteBuffer[] buffers;
|
||||
|
||||
private final long offset;
|
||||
|
||||
private final long capacity;
|
||||
|
||||
private long mark = -1;
|
||||
|
||||
private long position = 0;
|
||||
|
||||
private long limit;
|
||||
|
||||
public BigByteBuffer(String fileName, boolean readOnly) throws IOException {
|
||||
String mode = readOnly ? "r" : "rw";
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(fileName, mode);
|
||||
FileChannel fileChannel = raf.getChannel();
|
||||
offset = 0;
|
||||
limit = capacity = fileChannel.size();
|
||||
int nBuffers = (int) (capacity / chunkSize);
|
||||
if (nBuffers * chunkSize < capacity) {
|
||||
nBuffers += 1;
|
||||
}
|
||||
buffers = new ByteBuffer[nBuffers];
|
||||
MapMode mapMode = readOnly ? MapMode.READ_ONLY : MapMode.READ_WRITE;
|
||||
for (int i = 0; i < buffers.length; i += 1) {
|
||||
buffers[i] = fileChannel.map(mapMode, i * chunkSize,
|
||||
Math.min(capacity - i * chunkSize, chunkSize));
|
||||
}
|
||||
} finally {
|
||||
if (raf != null) {
|
||||
raf.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected BigByteBuffer(ByteBuffer[] buffers, long offset, long capacity) {
|
||||
this.buffers = buffers;
|
||||
this.offset = offset;
|
||||
this.capacity = capacity;
|
||||
this.limit = capacity;
|
||||
}
|
||||
|
||||
public final long capacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public final long position() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public final BigByteBuffer position(long newPosition) {
|
||||
if ((newPosition > limit) || (newPosition < 0))
|
||||
throw new IllegalArgumentException();
|
||||
position = newPosition;
|
||||
if (mark > position)
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final long limit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public final BigByteBuffer limit(long newLimit) {
|
||||
if ((newLimit > capacity) || (newLimit < 0))
|
||||
throw new IllegalArgumentException();
|
||||
limit = newLimit;
|
||||
if (position > limit)
|
||||
position = limit;
|
||||
if (mark > limit)
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final BigByteBuffer rewind() {
|
||||
position = 0;
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final long remaining() {
|
||||
return limit - position;
|
||||
}
|
||||
|
||||
public final boolean hasRemaining() {
|
||||
return position < limit;
|
||||
}
|
||||
|
||||
public BigByteBuffer slice() {
|
||||
return new BigByteBuffer(buffers, this.position() + offset,
|
||||
this.remaining());
|
||||
}
|
||||
|
||||
public byte get() {
|
||||
return get(nextGetIndex());
|
||||
}
|
||||
|
||||
public byte get(long index) {
|
||||
checkIndex(index);
|
||||
return getBuffer(index).get(bufferIndex(index));
|
||||
}
|
||||
|
||||
public BigByteBuffer put(byte b) {
|
||||
put(nextGetIndex(), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BigByteBuffer put(long index, byte b) {
|
||||
checkIndex(index);
|
||||
getBuffer(index).put(bufferIndex(index), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void get(byte[] dst) {
|
||||
long start = nextGetIndex(dst.length);
|
||||
ByteBuffer buffer = getBuffer(start);
|
||||
buffer.position(bufferIndex(start));
|
||||
int offset = 0;
|
||||
int remaining = dst.length;
|
||||
while (remaining > 0) {
|
||||
int length = Math.min(remaining, buffer.remaining());
|
||||
buffer.get(dst, offset, length);
|
||||
offset += length;
|
||||
remaining -= length;
|
||||
buffer = getBuffer(start + offset);
|
||||
buffer.position(bufferIndex(start + offset));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public short getShort() {
|
||||
byte[] dst = new byte[2];
|
||||
get(dst);
|
||||
return ByteBuffer.wrap(dst).getShort();
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
byte[] dst = new byte[4];
|
||||
get(dst);
|
||||
return ByteBuffer.wrap(dst).getInt();
|
||||
}
|
||||
|
||||
public long getLong() {
|
||||
byte[] dst = new byte[8];
|
||||
get(dst);
|
||||
return ByteBuffer.wrap(dst).getLong();
|
||||
}
|
||||
|
||||
final ByteBuffer getBuffer(long index) {
|
||||
return buffers[(int) ((offset + index) / chunkSize)];
|
||||
}
|
||||
|
||||
final int bufferIndex(long index) {
|
||||
return (int) ((offset + index) % chunkSize);
|
||||
}
|
||||
|
||||
final long nextGetIndex() {
|
||||
if (position >= limit)
|
||||
throw new BufferUnderflowException();
|
||||
return position++;
|
||||
}
|
||||
|
||||
final long nextGetIndex(int nb) {
|
||||
if (limit - position < nb)
|
||||
throw new BufferUnderflowException();
|
||||
long p = position;
|
||||
position += nb;
|
||||
return p;
|
||||
}
|
||||
|
||||
final long checkIndex(long i) {
|
||||
if ((i < 0) || (i >= limit))
|
||||
throw new IndexOutOfBoundsException();
|
||||
return i;
|
||||
}
|
||||
}
|
|
@ -1,216 +0,0 @@
|
|||
/**
|
||||
* 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.hprof;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.raytheon.hprof.data.HeapDumpEndRecord;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
import com.raytheon.hprof.data.HeapDumpSegmentRecord;
|
||||
import com.raytheon.hprof.data.LoadClassRecord;
|
||||
import com.raytheon.hprof.data.MergedHeapDumpSegmentRecord;
|
||||
import com.raytheon.hprof.data.StackFrameRecord;
|
||||
import com.raytheon.hprof.data.StackTraceRecord;
|
||||
import com.raytheon.hprof.data.StringRecord;
|
||||
import com.raytheon.hprof.data.heap.dump.InstanceDump;
|
||||
|
||||
/**
|
||||
*
|
||||
* Root object for an hprof file, description of the data structure can be found
|
||||
* in a java installation at java/demo/jvmti/hprof/src/manual.html.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
* May 20, 2014 3093 bsteffen Allow opening for write.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class HprofFile {
|
||||
|
||||
private HeapDumpRecord heapDump;
|
||||
|
||||
private List<StringRecord> strings = new ArrayList<StringRecord>();
|
||||
|
||||
private List<LoadClassRecord> loadClasses = new ArrayList<LoadClassRecord>();
|
||||
|
||||
/* If these ever get full and cause problems they should be switched to LRU. */
|
||||
private Map<Id, String> usedStrings = new HashMap<Id, String>();
|
||||
|
||||
private Map<Id, String> usedClassnames = new HashMap<Id, String>();
|
||||
|
||||
public HprofFile(String fileName, boolean readOnly) throws IOException {
|
||||
BigByteBuffer buffer = new BigByteBuffer(fileName, readOnly);
|
||||
|
||||
String format = null;
|
||||
|
||||
while (buffer.hasRemaining()) {
|
||||
if (buffer.get() == 0x00) {
|
||||
byte[] formatBytes = new byte[(int) buffer.position() - 1];
|
||||
buffer.rewind();
|
||||
/* reread the string */
|
||||
buffer.get(formatBytes);
|
||||
/* reread the null */
|
||||
buffer.get();
|
||||
format = new String(formatBytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (format == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"This does not appear to be a valid hprof file!");
|
||||
}
|
||||
System.out.println("Hprof format is " + format);
|
||||
int idSize = buffer.getInt();
|
||||
System.out.println("Dump is from " + new Date(buffer.getLong()));
|
||||
|
||||
long segmentStart = 0;
|
||||
|
||||
while (buffer.hasRemaining()) {
|
||||
byte type = buffer.get();
|
||||
switch (type & 0xFF) {
|
||||
case StringRecord.TAG: {
|
||||
strings.add(new StringRecord(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case LoadClassRecord.TAG: {
|
||||
loadClasses.add(new LoadClassRecord(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case StackFrameRecord.TAG: {
|
||||
new StackFrameRecord(buffer, idSize);
|
||||
break;
|
||||
}
|
||||
case StackTraceRecord.TAG: {
|
||||
new StackTraceRecord(buffer, idSize);
|
||||
break;
|
||||
}
|
||||
case HeapDumpRecord.TAG: {
|
||||
heapDump = new HeapDumpRecord(buffer, idSize);
|
||||
break;
|
||||
}
|
||||
case HeapDumpSegmentRecord.TAG: {
|
||||
if (segmentStart == 0) {
|
||||
segmentStart = buffer.position() - 1;
|
||||
}
|
||||
new HeapDumpSegmentRecord(buffer, idSize);
|
||||
break;
|
||||
}
|
||||
case HeapDumpEndRecord.TAG: {
|
||||
long segmentEnd = buffer.position() - 1;
|
||||
buffer.position(segmentStart);
|
||||
BigByteBuffer safeBuffer = buffer.slice();
|
||||
safeBuffer.limit(segmentEnd - segmentStart);
|
||||
heapDump = new MergedHeapDumpSegmentRecord(safeBuffer, idSize);
|
||||
segmentStart = 0;
|
||||
buffer.position(segmentEnd + 1);
|
||||
new HeapDumpEndRecord(buffer, idSize);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Unknown type "
|
||||
+ Integer.toHexString(type & 0xFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Id lookUpClass(String className) {
|
||||
Id classNameId = getStringId(className.replace(".", "/"));
|
||||
for (LoadClassRecord loadClass : loadClasses) {
|
||||
if (loadClass.getClassNameId().equals(classNameId)) {
|
||||
return loadClass.getClassId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public HeapDumpRecord getHeapDump() {
|
||||
return heapDump;
|
||||
}
|
||||
|
||||
public String getString(Id stringId) {
|
||||
if (usedStrings.containsKey(stringId)) {
|
||||
return usedStrings.get(stringId);
|
||||
}
|
||||
for (StringRecord string : strings) {
|
||||
if (string.getId().equals(stringId)) {
|
||||
usedStrings.put(stringId, string.getString());
|
||||
return string.getString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Id getStringId(String string) {
|
||||
for (Entry<Id, String> entry : usedStrings.entrySet()) {
|
||||
if (entry.getValue().equals(string)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
for (StringRecord stringRec : strings) {
|
||||
if (stringRec.getString().equals(string)) {
|
||||
usedStrings.put(stringRec.getId(), stringRec.getString());
|
||||
return stringRec.getId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getClassName(Id classId) {
|
||||
if (usedClassnames.containsKey(classId)) {
|
||||
return usedClassnames.get(classId);
|
||||
}
|
||||
for (LoadClassRecord loadClass : loadClasses) {
|
||||
if (loadClass.getClassId().equals(classId)) {
|
||||
String className = getString(loadClass.getClassNameId())
|
||||
.replace("/", ".");
|
||||
usedClassnames.put(classId, className);
|
||||
return className;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<InstanceDump> getInstances(String className) {
|
||||
Id classId = lookUpClass(className);
|
||||
if (classId == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return heapDump.getInstances(classId);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/**
|
||||
* 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.hprof;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents an Id of an object in an hprof file. The id is generally either 4
|
||||
* or 8 bytes which is essentially an int or a long but the hprof format allows
|
||||
* arbitrary id lengths.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Id implements Comparable<Id> {
|
||||
|
||||
private final byte[] id;
|
||||
|
||||
public Id(BigByteBuffer buffer, int idSize) {
|
||||
id = new byte[idSize];
|
||||
buffer.get(id);
|
||||
}
|
||||
|
||||
public Id(ByteBuffer buffer, int idSize) {
|
||||
id = new byte[idSize];
|
||||
buffer.get(id);
|
||||
}
|
||||
|
||||
public boolean isNull() {
|
||||
for (byte b : id) {
|
||||
if (b != 0x00) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return id.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(id);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Id other = (Id) obj;
|
||||
if (!Arrays.equals(id, other.id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("id=0x");
|
||||
for (byte b : id) {
|
||||
str.append(String.format("%02x", b & 0xFF));
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Id that) {
|
||||
for (int i = 0; i < id.length; i++) {
|
||||
int diff = id[i] - that.id[i];
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,337 +0,0 @@
|
|||
/**
|
||||
* 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.hprof;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
import com.raytheon.hprof.data.heap.BasicType;
|
||||
import com.raytheon.hprof.data.heap.dump.ClassDump;
|
||||
import com.raytheon.hprof.data.heap.dump.InstanceDump;
|
||||
import com.raytheon.hprof.data.heap.dump.ObjectArrayDump;
|
||||
|
||||
/**
|
||||
* Represents an instance of an object within a heap dump. This is an enhanced
|
||||
* version of an {@link InstanceDump} that uses all the information in an
|
||||
* {@link HprofFile} to provide useful introspection.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
* May 05, 2014 3093 bsteffen Make getClassname public
|
||||
* May 21, 2014 3093 bsteffen Add getFloatArray,
|
||||
* toStringKeyedConcurrentHashMap
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SmartInstance {
|
||||
|
||||
private final HprofFile hprof;
|
||||
|
||||
private final Id id;
|
||||
|
||||
private final String className;
|
||||
|
||||
private final Map<String, BasicType> fields = new HashMap<String, BasicType>();
|
||||
|
||||
public SmartInstance(HprofFile hprof, InstanceDump instance) {
|
||||
this.hprof = hprof;
|
||||
this.id = instance.getId();
|
||||
Id classId = instance.getClassId();
|
||||
className = hprof.getClassName(classId);
|
||||
int idSize = classId.size();
|
||||
HeapDumpRecord heapDump = hprof.getHeapDump();
|
||||
ClassDump classDump = heapDump.getClassDump(classId);
|
||||
BigByteBuffer instanceData = instance.getInstanceData();
|
||||
while (classDump != null) {
|
||||
Map<Id, BasicType> id2type = classDump.parseInstanceData(
|
||||
instanceData, idSize);
|
||||
for (Entry<Id, BasicType> entry : id2type.entrySet()) {
|
||||
String fieldName = hprof.getString(entry.getKey());
|
||||
fields.put(fieldName, entry.getValue());
|
||||
}
|
||||
classDump = heapDump.getClassDump(classDump.getSuperId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Id getId(String fieldName) {
|
||||
BasicType type = fields.get(fieldName);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
return type.getObjectId();
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public SmartInstance get(String fieldName) {
|
||||
Id fieldId = getId(fieldName);
|
||||
if (fieldId == null) {
|
||||
return null;
|
||||
}
|
||||
InstanceDump field = hprof.getHeapDump().getInstance(fieldId);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
return new SmartInstance(hprof, field);
|
||||
}
|
||||
|
||||
private BasicType getTypeNotNull(String fieldName) {
|
||||
BasicType type = fields.get(fieldName);
|
||||
if (type == null) {
|
||||
throw new IllegalStateException(fieldName
|
||||
+ " is not a a valid field");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean getBoolean(String fieldName) {
|
||||
return getTypeNotNull(fieldName).getBoolean();
|
||||
}
|
||||
|
||||
public int getInt(String fieldName) {
|
||||
return getTypeNotNull(fieldName).getInt();
|
||||
}
|
||||
|
||||
public long getLong(String fieldName) {
|
||||
return getTypeNotNull(fieldName).getLong();
|
||||
}
|
||||
|
||||
public SmartInstance[] getObjectArray(String fieldName) {
|
||||
BasicType type = fields.get(fieldName);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
HeapDumpRecord heapDump = hprof.getHeapDump();
|
||||
Id fieldId = type.getObjectId();
|
||||
ObjectArrayDump objectArray = heapDump.getObjectArray(fieldId);
|
||||
if (objectArray == null) {
|
||||
return null;
|
||||
}
|
||||
Id[] idArray = objectArray.getArray();
|
||||
SmartInstance[] smartArray = new SmartInstance[idArray.length];
|
||||
for (int i = 0; i < idArray.length; i += 1) {
|
||||
InstanceDump instance = heapDump.getInstance(idArray[i]);
|
||||
if (instance != null) {
|
||||
smartArray[i] = new SmartInstance(hprof, instance);
|
||||
}
|
||||
}
|
||||
return smartArray;
|
||||
}
|
||||
|
||||
public char[] getCharArray(String fieldName) {
|
||||
BasicType type = fields.get(fieldName);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
Id fieldId = type.getObjectId();
|
||||
BasicType[] primArray = hprof.getHeapDump().getPrimitiveArray(fieldId);
|
||||
if (primArray == null) {
|
||||
return null;
|
||||
}
|
||||
char[] charArray = new char[primArray.length];
|
||||
|
||||
for (int i = 0; i < charArray.length; i += 1) {
|
||||
charArray[i] = primArray[i].getChar();
|
||||
}
|
||||
return charArray;
|
||||
}
|
||||
|
||||
public int[] getIntArray(String fieldName) {
|
||||
BasicType type = fields.get(fieldName);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
Id fieldId = type.getObjectId();
|
||||
BasicType[] primArray = hprof.getHeapDump().getPrimitiveArray(fieldId);
|
||||
if (primArray == null) {
|
||||
return null;
|
||||
}
|
||||
int[] intArray = new int[primArray.length];
|
||||
|
||||
for (int i = 0; i < intArray.length; i += 1) {
|
||||
intArray[i] = primArray[i].getInt();
|
||||
}
|
||||
return intArray;
|
||||
}
|
||||
|
||||
public float[] getFloatArray(String fieldName) {
|
||||
BasicType type = fields.get(fieldName);
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
Id fieldId = type.getObjectId();
|
||||
BasicType[] primArray = hprof.getHeapDump().getPrimitiveArray(fieldId);
|
||||
if (primArray == null) {
|
||||
return null;
|
||||
}
|
||||
float[] floatArray = new float[primArray.length];
|
||||
|
||||
for (int i = 0; i < floatArray.length; i += 1) {
|
||||
floatArray[i] = primArray[i].getFloat();
|
||||
}
|
||||
return floatArray;
|
||||
}
|
||||
|
||||
public String getString(String fieldName) {
|
||||
Id fieldId = getId(fieldName);
|
||||
if (fieldId == null) {
|
||||
throw new IllegalStateException(fieldName
|
||||
+ " is not a a valid field");
|
||||
}
|
||||
InstanceDump field = hprof.getHeapDump().getInstance(fieldId);
|
||||
if (field != null) {
|
||||
SmartInstance smartField = new SmartInstance(hprof, field);
|
||||
if (!smartField.getClassName().equals(String.class.getName())) {
|
||||
throw new IllegalStateException(fieldName + " is not a String.");
|
||||
}
|
||||
return smartField.toString();
|
||||
} else if (fieldId.isNull()) {
|
||||
return null;
|
||||
} else {
|
||||
Iterator<ClassDump> classDumps = hprof.getHeapDump()
|
||||
.getClassDumps();
|
||||
while (classDumps.hasNext()) {
|
||||
ClassDump classDump = classDumps.next();
|
||||
for (Entry<Id, BasicType> entry : classDump.getStaticFields()
|
||||
.entrySet()) {
|
||||
BasicType f = entry.getValue();
|
||||
if (f.isObject() && f.getObjectId().equals(fieldId)) {
|
||||
String className = hprof
|
||||
.getClassName(classDump.getId());
|
||||
return "{@link " + shortenClass(className) + "#"
|
||||
+ hprof.getString(entry.getKey()) + "}";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "String (" + fieldId + ")";
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<SmartInstance> toArrayList() {
|
||||
if (!getClassName().equals(ArrayList.class.getName())) {
|
||||
throw new IllegalStateException(this + " is not an ArrayList.");
|
||||
}
|
||||
int size = getInt("size");
|
||||
SmartInstance[] elementData = getObjectArray("elementData");
|
||||
ArrayList<SmartInstance> arrayList = new ArrayList<SmartInstance>(size);
|
||||
for (int i = 0; i < size; i += 1) {
|
||||
arrayList.add(elementData[i]);
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<SmartInstance, SmartInstance> toConcurrentHashMap() {
|
||||
if (!getClassName().equals(ConcurrentHashMap.class.getName())) {
|
||||
throw new IllegalStateException(this
|
||||
+ " is not a ConcurrentHashMap.");
|
||||
}
|
||||
ConcurrentHashMap<SmartInstance, SmartInstance> map = new ConcurrentHashMap<SmartInstance, SmartInstance>();
|
||||
SmartInstance[] segments = getObjectArray("segments");
|
||||
for (SmartInstance segment : segments) {
|
||||
SmartInstance[] table = segment.getObjectArray("table");
|
||||
for (SmartInstance entry : table) {
|
||||
while (entry != null) {
|
||||
map.put(entry.get("key"), entry.get("value"));
|
||||
entry = entry.get("next");
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<String, SmartInstance> toStringKeyedConcurrentHashMap() {
|
||||
if (!getClassName().equals(ConcurrentHashMap.class.getName())) {
|
||||
throw new IllegalStateException(this
|
||||
+ " is not a ConcurrentHashMap.");
|
||||
}
|
||||
ConcurrentHashMap<String, SmartInstance> map = new ConcurrentHashMap<String, SmartInstance>();
|
||||
SmartInstance[] segments = getObjectArray("segments");
|
||||
for (SmartInstance segment : segments) {
|
||||
SmartInstance[] table = segment.getObjectArray("table");
|
||||
for (SmartInstance entry : table) {
|
||||
while (entry != null) {
|
||||
map.put(entry.getString("key"), entry.get("value"));
|
||||
entry = entry.get("next");
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public HashMap<SmartInstance, SmartInstance> toHashMap() {
|
||||
if (!getClassName().equals(HashMap.class.getName())) {
|
||||
throw new IllegalStateException(this + " is not a HashMap.");
|
||||
}
|
||||
HashMap<SmartInstance, SmartInstance> map = new HashMap<SmartInstance, SmartInstance>();
|
||||
SmartInstance[] table = getObjectArray("table");
|
||||
for (SmartInstance entry : table) {
|
||||
while (entry != null) {
|
||||
map.put(entry.get("key"), entry.get("value"));
|
||||
entry = entry.get("next");
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public HashMap<String, SmartInstance> toStringKeyedHashMap() {
|
||||
if (!getClassName().equals(HashMap.class.getName())) {
|
||||
throw new IllegalStateException(this + " is not a HashMap.");
|
||||
}
|
||||
HashMap<String, SmartInstance> map = new HashMap<String, SmartInstance>();
|
||||
SmartInstance[] table = getObjectArray("table");
|
||||
for (SmartInstance entry : table) {
|
||||
while (entry != null) {
|
||||
map.put(entry.getString("key"), entry.get("value"));
|
||||
entry = entry.get("next");
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (className.equals(String.class.getName())) {
|
||||
return "\"" + new String(getCharArray("value")) + "\"";
|
||||
}
|
||||
return shortenClass(className) + " (" + id + ")";
|
||||
}
|
||||
|
||||
private String shortenClass(String className) {
|
||||
int index = className.lastIndexOf('.');
|
||||
return className.substring(index + 1);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base class for the different types of records in an {@link HprofFile}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractHprofRecord {
|
||||
|
||||
protected final int time;
|
||||
|
||||
public AbstractHprofRecord(BigByteBuffer buffer, int idSize) {
|
||||
time = buffer.getInt();
|
||||
long size = buffer.getInt();
|
||||
if (size < 0) {
|
||||
/* size is really an unsigned int. */
|
||||
size = ((int) size) & 0xFFFFFFFFL;
|
||||
}
|
||||
BigByteBuffer safeBuffer = buffer.slice();
|
||||
safeBuffer.limit(size);
|
||||
init(safeBuffer, idSize);
|
||||
buffer.position(buffer.position() + size);
|
||||
}
|
||||
|
||||
protected abstract void init(BigByteBuffer buffer, int idSize);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
|
||||
/**
|
||||
* Object for the heap dump end record in an {@link HprofFile}, this type of
|
||||
* record has no content.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
* @see MergedHeapDumpSegmentRecord
|
||||
*/
|
||||
public class HeapDumpEndRecord extends AbstractHprofRecord {
|
||||
|
||||
public static final int TAG = 0x2c;
|
||||
|
||||
public HeapDumpEndRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
/* This record has no content */
|
||||
}
|
||||
|
||||
}
|
|
@ -1,399 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
import com.raytheon.hprof.Id;
|
||||
import com.raytheon.hprof.data.heap.BasicType;
|
||||
import com.raytheon.hprof.data.heap.dump.ClassDump;
|
||||
import com.raytheon.hprof.data.heap.dump.InstanceDump;
|
||||
import com.raytheon.hprof.data.heap.dump.ObjectArrayDump;
|
||||
import com.raytheon.hprof.data.heap.dump.PrimitiveArrayDump;
|
||||
import com.raytheon.hprof.data.heap.root.AbstractRoot;
|
||||
import com.raytheon.hprof.data.heap.root.RootJNIGlobal;
|
||||
import com.raytheon.hprof.data.heap.root.RootJNILocal;
|
||||
import com.raytheon.hprof.data.heap.root.RootJavaFrame;
|
||||
import com.raytheon.hprof.data.heap.root.RootMonitorUsed;
|
||||
import com.raytheon.hprof.data.heap.root.RootStickyClass;
|
||||
import com.raytheon.hprof.data.heap.root.RootThreadObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* Heap dump Record within an {@link HprofFile}. This object holds most of the
|
||||
* interesting infromation in a hprof file.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
* May 20, 2014 3093 bsteffen Add zeroPrimitiveArrays
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class HeapDumpRecord extends AbstractHprofRecord {
|
||||
|
||||
public static final int TAG = 0x0c;
|
||||
|
||||
protected int idSize;
|
||||
|
||||
protected BigByteBuffer buffer;
|
||||
|
||||
protected List<AbstractRoot> roots;
|
||||
|
||||
protected long[] instancesById;
|
||||
|
||||
protected long[] instancesByClass;
|
||||
|
||||
protected long[] objectArraysById;
|
||||
|
||||
protected long[] primitiveArraysById;
|
||||
|
||||
protected long[] classesById;
|
||||
|
||||
protected Map<Id, ClassDump> usedClasses;
|
||||
|
||||
|
||||
public HeapDumpRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
this.buffer = buffer;
|
||||
this.idSize = idSize;
|
||||
this.roots = new ArrayList<AbstractRoot>();
|
||||
this.usedClasses = new HashMap<Id, ClassDump>();
|
||||
List<Long> instances = new ArrayList<Long>();
|
||||
List<Long> objectArrays = new ArrayList<Long>();
|
||||
List<Long> primitiveArrays = new ArrayList<Long>();
|
||||
List<Long> classes = new ArrayList<Long>();
|
||||
while (buffer.hasRemaining()) {
|
||||
byte type = buffer.get();
|
||||
switch (type & 0xFF) {
|
||||
case RootJNIGlobal.TAG: {
|
||||
roots.add(new RootJNIGlobal(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case RootJNILocal.TAG: {
|
||||
roots.add(new RootJNILocal(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case RootJavaFrame.TAG: {
|
||||
roots.add(new RootJavaFrame(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case RootStickyClass.TAG: {
|
||||
roots.add(new RootStickyClass(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case RootMonitorUsed.TAG: {
|
||||
roots.add(new RootMonitorUsed(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case RootThreadObject.TAG: {
|
||||
roots.add(new RootThreadObject(buffer, idSize));
|
||||
break;
|
||||
}
|
||||
case ClassDump.TAG: {
|
||||
classes.add(buffer.position());
|
||||
new ClassDump(buffer, idSize);
|
||||
break;
|
||||
}
|
||||
case InstanceDump.TAG: {
|
||||
instances.add(buffer.position());
|
||||
new InstanceDump(buffer, idSize);
|
||||
break;
|
||||
}
|
||||
case ObjectArrayDump.TAG: {
|
||||
objectArrays.add(buffer.position());
|
||||
new ObjectArrayDump(buffer, idSize, false);
|
||||
break;
|
||||
}
|
||||
case PrimitiveArrayDump.TAG: {
|
||||
primitiveArrays.add(buffer.position());
|
||||
new PrimitiveArrayDump(buffer, idSize, false);
|
||||
break;
|
||||
}
|
||||
case HeapDumpSegmentRecord.TAG: {
|
||||
buffer.position(buffer.position() + 8);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Unknown heap type "
|
||||
+ Integer.toHexString(type & 0xFF));
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Sorting all objects...");
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
System.out.print("Instances...");
|
||||
Collections.sort(instances, new DumpBufferIndexComparator());
|
||||
System.out.println("Done");
|
||||
System.out.print("Object Arrays...");
|
||||
Collections.sort(objectArrays, new DumpBufferIndexComparator());
|
||||
System.out.println("Done");
|
||||
System.out.print("Primitive Arrays...");
|
||||
Collections.sort(primitiveArrays, new DumpBufferIndexComparator());
|
||||
System.out.println("Done");
|
||||
System.out.print("Classes...");
|
||||
Collections.sort(classes, new DumpBufferIndexComparator());
|
||||
System.out.println("Done");
|
||||
|
||||
this.instancesById = new long[instances.size()];
|
||||
for (int i = 0; i < instances.size(); i++) {
|
||||
this.instancesById[i] = instances.get(i);
|
||||
}
|
||||
|
||||
this.objectArraysById = new long[objectArrays.size()];
|
||||
for (int i = 0; i < objectArrays.size(); i++) {
|
||||
this.objectArraysById[i] = objectArrays.get(i);
|
||||
}
|
||||
|
||||
this.primitiveArraysById = new long[primitiveArrays.size()];
|
||||
for (int i = 0; i < primitiveArrays.size(); i++) {
|
||||
this.primitiveArraysById[i] = primitiveArrays.get(i);
|
||||
}
|
||||
|
||||
this.classesById = new long[classes.size()];
|
||||
for (int i = 0; i < classes.size(); i++) {
|
||||
this.classesById[i] = classes.get(i);
|
||||
}
|
||||
|
||||
System.out.print("Instances By Class...");
|
||||
/* Add one id and one int before the class id */
|
||||
Collections.sort(instances, new DumpBufferIndexComparator(idSize + 4));
|
||||
System.out.println("Done");
|
||||
|
||||
this.instancesByClass = new long[instances.size()];
|
||||
for (int i = 0; i < instances.size(); i++) {
|
||||
this.instancesByClass[i] = instances.get(i);
|
||||
}
|
||||
|
||||
System.out.println("Spent " + (System.currentTimeMillis() - startTime)
|
||||
/ 1000 + " seconds sorting");
|
||||
}
|
||||
|
||||
public ClassDump getClassDump(Id classId) {
|
||||
if (usedClasses.containsKey(classId)) {
|
||||
return usedClasses.get(classId);
|
||||
}
|
||||
long index = binarySearch(classesById, classId);
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
buffer.position(index);
|
||||
ClassDump classDump = new ClassDump(buffer, idSize);
|
||||
usedClasses.put(classId, classDump);
|
||||
return classDump;
|
||||
}
|
||||
|
||||
public InstanceDump getInstance(Id objectId) {
|
||||
long index = binarySearch(instancesById, objectId);
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
buffer.position(index);
|
||||
return new InstanceDump(buffer, idSize);
|
||||
}
|
||||
|
||||
public ObjectArrayDump getObjectArray(Id objectId) {
|
||||
long index = binarySearch(objectArraysById, objectId);
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
buffer.position(index);
|
||||
return new ObjectArrayDump(buffer, idSize, true);
|
||||
}
|
||||
|
||||
public BasicType[] getPrimitiveArray(Id objectId) {
|
||||
long index = binarySearch(primitiveArraysById, objectId);
|
||||
if (index < 0) {
|
||||
return null;
|
||||
}
|
||||
buffer.position(index);
|
||||
return new PrimitiveArrayDump(buffer, idSize, true).getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero out all data for non char primitive arrays in the backing file.
|
||||
*/
|
||||
public void zeroPrimitiveArrays() {
|
||||
for (long index : primitiveArraysById) {
|
||||
buffer.position(index);
|
||||
PrimitiveArrayDump dump = new PrimitiveArrayDump(buffer, idSize,
|
||||
true);
|
||||
BasicType[] array = dump.getArray();
|
||||
if (array.length > 0) {
|
||||
BasicType sample = array[0];
|
||||
if (!sample.isChar()) {
|
||||
int size = sample.getSize() * array.length;
|
||||
buffer.position(buffer.position() - size);
|
||||
for (int i = 0; i < size; i += 1) {
|
||||
buffer.put((byte) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long binarySearch(long[] array, Id objectId) {
|
||||
int low = 0;
|
||||
int high = array.length - 1;
|
||||
while (low <= high) {
|
||||
int mid = (low + high) / 2;
|
||||
buffer.position(array[mid]);
|
||||
Id id = new Id(buffer, idSize);
|
||||
|
||||
int compval = id.compareTo(objectId);
|
||||
if (compval < 0) {
|
||||
low = mid + 1;
|
||||
} else if (compval > 0) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
return array[mid];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public List<InstanceDump> getInstances(Id classId) {
|
||||
int low = 0;
|
||||
int high = instancesByClass.length - 1;
|
||||
int mid = (low + high) / 2;
|
||||
while (low <= high) {
|
||||
mid = (low + high) / 2;
|
||||
buffer.position(instancesByClass[mid] + idSize + 4);
|
||||
Id id = new Id(buffer, idSize);
|
||||
|
||||
int compval = id.compareTo(classId);
|
||||
if (compval < 0) {
|
||||
low = mid + 1;
|
||||
} else if (compval > 0) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (low > high) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<InstanceDump> instances = new ArrayList<InstanceDump>();
|
||||
|
||||
int next = mid;
|
||||
buffer.position(instancesByClass[next--]);
|
||||
InstanceDump instance = new InstanceDump(buffer, idSize);
|
||||
while (instance.getClassId().equals(classId) && next >= 0) {
|
||||
instances.add(instance);
|
||||
buffer.position(instancesByClass[next--]);
|
||||
instance = new InstanceDump(buffer, idSize);
|
||||
}
|
||||
next = mid + 1;
|
||||
buffer.position(instancesByClass[next++]);
|
||||
instance = new InstanceDump(buffer, idSize);
|
||||
while (instance.getClassId().equals(classId)
|
||||
&& next < instancesByClass.length) {
|
||||
instances.add(instance);
|
||||
buffer.position(instancesByClass[next++]);
|
||||
instance = new InstanceDump(buffer, idSize);
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
public Map<Id, BasicType> getInstanceFields(InstanceDump instance) {
|
||||
Map<Id, BasicType> id2type = new HashMap<Id, BasicType>();
|
||||
ClassDump classDump = getClassDump(instance.getClassId());
|
||||
BigByteBuffer instanceData = instance.getInstanceData();
|
||||
while (classDump != null) {
|
||||
id2type.putAll(classDump.parseInstanceData(instanceData, idSize));
|
||||
classDump = getClassDump(classDump.getSuperId());
|
||||
}
|
||||
return id2type;
|
||||
}
|
||||
|
||||
public Iterator<ClassDump> getClassDumps() {
|
||||
return new Iterator<ClassDump>() {
|
||||
|
||||
private int index;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index < classesById.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDump next() {
|
||||
buffer.position(classesById[index]);
|
||||
index += 1;
|
||||
return new ClassDump(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
protected class DumpBufferIndexComparator implements Comparator<Long> {
|
||||
|
||||
private final int indexOffset;
|
||||
|
||||
protected DumpBufferIndexComparator() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
protected DumpBufferIndexComparator(int indexOffset) {
|
||||
this.indexOffset = indexOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Long o1, Long o2) {
|
||||
try {
|
||||
HeapDumpRecord.this.buffer.position(o1 + indexOffset);
|
||||
Id i1 = new Id(HeapDumpRecord.this.buffer,
|
||||
HeapDumpRecord.this.idSize);
|
||||
HeapDumpRecord.this.buffer.position(o2 + indexOffset);
|
||||
Id i2 = new Id(HeapDumpRecord.this.buffer,
|
||||
HeapDumpRecord.this.idSize);
|
||||
return i1.compareTo(i2);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* Object for a segmented heap dump record in an {@link HprofFile}. The segments
|
||||
* are not actually processed seperately, this record is just used as a place
|
||||
* holder until all segments are found and then all segments are processed
|
||||
* together as a {@link MergedHeapDumpSegmentRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
* @see MergedHeapDumpSegmentRecord
|
||||
*/
|
||||
public class HeapDumpSegmentRecord extends AbstractHprofRecord {
|
||||
|
||||
public static final int TAG = 0x1c;
|
||||
|
||||
public HeapDumpSegmentRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
/*
|
||||
* Don't actually process this type of record, it gets processed after
|
||||
* all the segments are found.
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
import com.raytheon.hprof.Id;
|
||||
|
||||
/**
|
||||
*
|
||||
* Record of a loaded class in an {@link HprofFile}. Only really used for
|
||||
* correlating class ids in the dump to their names.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class LoadClassRecord extends AbstractHprofRecord {
|
||||
|
||||
public static final int TAG = 0x02;
|
||||
|
||||
private int classSerialNumber;
|
||||
|
||||
private Id classId;
|
||||
|
||||
private int stackSerialNumber;
|
||||
|
||||
private Id classNameId;
|
||||
|
||||
public LoadClassRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
classSerialNumber = buffer.getInt();
|
||||
classId = new Id(buffer, idSize);
|
||||
stackSerialNumber = buffer.getInt();
|
||||
classNameId = new Id(buffer, idSize);
|
||||
}
|
||||
|
||||
public static int getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
public int getClassSerialNumber() {
|
||||
return classSerialNumber;
|
||||
}
|
||||
|
||||
public Id getClassId() {
|
||||
return classId;
|
||||
}
|
||||
|
||||
public int getStackSerialNumber() {
|
||||
return stackSerialNumber;
|
||||
}
|
||||
|
||||
public Id getClassNameId() {
|
||||
return classNameId;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents all the segments in a {@link HeapDumpSegmentRecord} together so
|
||||
* that all segments can be treeated as a continuous {@link HeapDumpRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MergedHeapDumpSegmentRecord extends HeapDumpRecord {
|
||||
|
||||
public MergedHeapDumpSegmentRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
buffer.position(0);
|
||||
super.init(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
/* This is not the full buffer */
|
||||
}
|
||||
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
import com.raytheon.hprof.Id;
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents a stack frame within an {@link HprofFile}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class StackFrameRecord extends AbstractHprofRecord {
|
||||
|
||||
public static final int TAG = 0x04;
|
||||
|
||||
private Id stackFrameId;
|
||||
|
||||
private Id methodNameId;
|
||||
|
||||
private Id methodSigId;
|
||||
|
||||
private Id sourceFileId;
|
||||
|
||||
private int classSerialNumber;
|
||||
|
||||
private int lineNumber;
|
||||
|
||||
public StackFrameRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
stackFrameId = new Id(buffer, idSize);
|
||||
methodNameId = new Id(buffer, idSize);
|
||||
methodSigId = new Id(buffer, idSize);
|
||||
sourceFileId = new Id(buffer, idSize);
|
||||
classSerialNumber = buffer.getInt();
|
||||
lineNumber = buffer.getInt();
|
||||
}
|
||||
|
||||
public static int getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
public Id getStackFrameId() {
|
||||
return stackFrameId;
|
||||
}
|
||||
|
||||
public Id getMethodNameId() {
|
||||
return methodNameId;
|
||||
}
|
||||
|
||||
public Id getMethodSigId() {
|
||||
return methodSigId;
|
||||
}
|
||||
|
||||
public Id getSourceFileId() {
|
||||
return sourceFileId;
|
||||
}
|
||||
|
||||
public int getClassSerialNumber() {
|
||||
return classSerialNumber;
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
import com.raytheon.hprof.Id;
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents a stack trace within an {@link HprofFile}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class StackTraceRecord extends AbstractHprofRecord {
|
||||
|
||||
public static final int TAG = 0x05;
|
||||
|
||||
private int stackSerialNumber;
|
||||
|
||||
private int threadSerialNumber;
|
||||
|
||||
private Id[] stackFrames;
|
||||
|
||||
public StackTraceRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
stackSerialNumber = buffer.getInt();
|
||||
threadSerialNumber = buffer.getInt();
|
||||
int numberOfFrames = buffer.getInt();
|
||||
if (numberOfFrames < 0) {
|
||||
numberOfFrames = 0;
|
||||
}
|
||||
stackFrames = new Id[numberOfFrames];
|
||||
for (int i = 0; i < numberOfFrames; i++) {
|
||||
stackFrames[i] = new Id(buffer, idSize);
|
||||
}
|
||||
}
|
||||
|
||||
public int getStackSerialNumber() {
|
||||
return stackSerialNumber;
|
||||
}
|
||||
|
||||
public int getThreadSerialNumber() {
|
||||
return threadSerialNumber;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
import com.raytheon.hprof.Id;
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents a string within an {@link HprofFile}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class StringRecord extends AbstractHprofRecord {
|
||||
|
||||
public static final int TAG = 0x01;
|
||||
|
||||
private Id id;
|
||||
|
||||
private String string;
|
||||
|
||||
public StringRecord(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init(BigByteBuffer buffer, int idSize) {
|
||||
id = new Id(buffer, idSize);
|
||||
byte[] string = new byte[(int) buffer.remaining()];
|
||||
buffer.get(string);
|
||||
this.string = new String(string).intern();
|
||||
}
|
||||
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,233 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.Id;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* Represents a basic type within a {@link HeapDumpRecord}. Used primarily for
|
||||
* fields of objects starts with a byte indicating the type of the field and
|
||||
* depending on the bytes holds either the primitive value or an object id.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BasicType {
|
||||
|
||||
private static final byte OBJECT = 2;
|
||||
|
||||
private static final byte BOOLEAN = 4;
|
||||
|
||||
private static final byte CHAR = 5;
|
||||
|
||||
private static final byte FLOAT = 6;
|
||||
|
||||
private static final byte DOUBLE = 7;
|
||||
|
||||
private static final byte BYTE = 8;
|
||||
|
||||
private static final byte SHORT = 9;
|
||||
|
||||
private static final byte INT = 10;
|
||||
|
||||
private static final byte LONG = 11;
|
||||
|
||||
private final byte type;
|
||||
|
||||
private final byte[] data;
|
||||
|
||||
public BasicType(BigByteBuffer buffer, int idSize) {
|
||||
this(buffer, buffer.get(), idSize);
|
||||
}
|
||||
|
||||
public BasicType(BigByteBuffer buffer, byte type, int idSize) {
|
||||
this.type = type;
|
||||
switch (type) {
|
||||
case OBJECT:
|
||||
data = new byte[idSize];
|
||||
break;
|
||||
case FLOAT:
|
||||
case INT:
|
||||
data = new byte[4];
|
||||
break;
|
||||
case BOOLEAN:
|
||||
case BYTE:
|
||||
data = new byte[1];
|
||||
break;
|
||||
case CHAR:
|
||||
case SHORT:
|
||||
data = new byte[2];
|
||||
break;
|
||||
case DOUBLE:
|
||||
case LONG:
|
||||
data = new byte[8];
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown basic type "
|
||||
+ Integer.toHexString(type & 0xFF));
|
||||
}
|
||||
buffer.get(data);
|
||||
}
|
||||
|
||||
public boolean isObject() {
|
||||
return type == OBJECT;
|
||||
}
|
||||
|
||||
public boolean isBoolean() {
|
||||
return type == BOOLEAN;
|
||||
}
|
||||
|
||||
public boolean isChar() {
|
||||
return type == CHAR;
|
||||
}
|
||||
|
||||
public boolean isFloat() {
|
||||
return type == FLOAT;
|
||||
}
|
||||
|
||||
public boolean isDouble() {
|
||||
return type == DOUBLE;
|
||||
}
|
||||
|
||||
public boolean isByte() {
|
||||
return type == BYTE;
|
||||
}
|
||||
|
||||
public boolean isShort() {
|
||||
return type == SHORT;
|
||||
}
|
||||
|
||||
public boolean isInt() {
|
||||
return type == INT;
|
||||
}
|
||||
|
||||
public boolean isLong() {
|
||||
return type == LONG;
|
||||
}
|
||||
|
||||
public Id getObjectId() {
|
||||
if (!isObject()) {
|
||||
throw new IllegalStateException(type + " is not an OBJECT");
|
||||
}
|
||||
return new Id(ByteBuffer.wrap(data), data.length);
|
||||
}
|
||||
|
||||
public boolean getBoolean() {
|
||||
if (!isBoolean()) {
|
||||
throw new IllegalStateException(type + " is not a BOOLEAN");
|
||||
}
|
||||
return ByteBuffer.wrap(data).get() != 0;
|
||||
}
|
||||
|
||||
public char getChar() {
|
||||
if (!isChar()) {
|
||||
throw new IllegalStateException(type + " is not a CHAR");
|
||||
}
|
||||
return ByteBuffer.wrap(data).getChar();
|
||||
}
|
||||
|
||||
public float getFloat() {
|
||||
if (!isFloat()) {
|
||||
throw new IllegalStateException(type + " is not a FLOAT");
|
||||
}
|
||||
return ByteBuffer.wrap(data).getFloat();
|
||||
}
|
||||
|
||||
public double getDouble() {
|
||||
if (!isDouble()) {
|
||||
throw new IllegalStateException(type + " is not a DOUBLE");
|
||||
}
|
||||
return ByteBuffer.wrap(data).getDouble();
|
||||
}
|
||||
|
||||
public byte getByte() {
|
||||
if (!isByte()) {
|
||||
throw new IllegalStateException(type + " is not a BYTE");
|
||||
}
|
||||
return data[0];
|
||||
}
|
||||
|
||||
public short getShort() {
|
||||
if (!isShort()) {
|
||||
throw new IllegalStateException(type + " is not a SHORT");
|
||||
}
|
||||
return ByteBuffer.wrap(data).getShort();
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
if (!isInt()) {
|
||||
throw new IllegalStateException(type + " is not an INT");
|
||||
}
|
||||
return ByteBuffer.wrap(data).getInt();
|
||||
}
|
||||
|
||||
public long getLong() {
|
||||
if (!isLong()) {
|
||||
throw new IllegalStateException(type + " is not a LONG");
|
||||
}
|
||||
return ByteBuffer.wrap(data).getLong();
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (type) {
|
||||
case OBJECT:
|
||||
return "Object: " + getObjectId();
|
||||
case FLOAT:
|
||||
return "Float: " + getFloat();
|
||||
case INT:
|
||||
return "Int: " + getInt();
|
||||
case BOOLEAN:
|
||||
return "Boolean: " + getBoolean();
|
||||
case BYTE:
|
||||
return "Byte: " + getByte();
|
||||
case CHAR:
|
||||
return "Char: " + getChar();
|
||||
case SHORT:
|
||||
return "Short: " + getShort();
|
||||
case DOUBLE:
|
||||
return " Double: " + getDouble();
|
||||
case LONG:
|
||||
return "Long: " + getLong();
|
||||
default:
|
||||
return "Unknown basic type " + Integer.toHexString(type & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.dump;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.Id;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base class for all the types of data dumped into a {@link HeapDumpRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AbstractDump {
|
||||
|
||||
protected final Id id;
|
||||
|
||||
protected final int stackSerialNumber;
|
||||
|
||||
protected AbstractDump(BigByteBuffer buffer, int idSize) {
|
||||
id = new Id(buffer, idSize);
|
||||
stackSerialNumber = buffer.getInt();
|
||||
}
|
||||
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.dump;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.Id;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
import com.raytheon.hprof.data.heap.BasicType;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class data for a single class in a {@link HeapDumpRecord}. This class
|
||||
* contains most of the same information as a {@link Class} object, in a much
|
||||
* more cryptic form.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ClassDump extends AbstractDump {
|
||||
|
||||
public static final int TAG = 0x20;
|
||||
|
||||
private final Id superId;
|
||||
|
||||
private final int instanceSize;
|
||||
|
||||
private final BasicType[] constantPool;
|
||||
|
||||
private final Id[] staticFieldIds;
|
||||
|
||||
private final BasicType[] staticFieldValues;
|
||||
|
||||
private final Id[] instanceFieldIds;
|
||||
|
||||
private final byte[] instanceFieldTypes;
|
||||
|
||||
public ClassDump(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
superId = new Id(buffer, idSize);
|
||||
/* Id classLoaderId = */new Id(buffer, idSize);
|
||||
/* Id signerId = */new Id(buffer, idSize);
|
||||
/* Id protectionDomainId = */new Id(buffer, idSize);
|
||||
/* Id reservedId1 = */new Id(buffer, idSize);
|
||||
/* Id reservedId2 = */new Id(buffer, idSize);
|
||||
instanceSize = buffer.getInt();
|
||||
short constantPoolSize = buffer.getShort();
|
||||
constantPool = new BasicType[constantPoolSize];
|
||||
for (int i = 0; i < constantPoolSize; i++) {
|
||||
/* short constantPoolIndex = */buffer.getShort();
|
||||
constantPool[i] = new BasicType(buffer, idSize);
|
||||
}
|
||||
short numberOfStaticFields = buffer.getShort();
|
||||
staticFieldIds = new Id[numberOfStaticFields];
|
||||
staticFieldValues = new BasicType[numberOfStaticFields];
|
||||
for (int i = 0; i < numberOfStaticFields; i++) {
|
||||
staticFieldIds[i] = new Id(buffer, idSize);
|
||||
staticFieldValues[i] = new BasicType(buffer, idSize);
|
||||
}
|
||||
short numberOfInstanceFields = buffer.getShort();
|
||||
instanceFieldIds = new Id[numberOfInstanceFields];
|
||||
instanceFieldTypes = new byte[numberOfInstanceFields];
|
||||
for (int i = 0; i < numberOfInstanceFields; i++) {
|
||||
instanceFieldIds[i] = new Id(buffer, idSize);
|
||||
instanceFieldTypes[i] = buffer.get();
|
||||
}
|
||||
}
|
||||
|
||||
public Id getSuperId() {
|
||||
return superId;
|
||||
}
|
||||
|
||||
public int getInstanceSize() {
|
||||
return instanceSize;
|
||||
}
|
||||
|
||||
public Map<Id, BasicType> parseInstanceData(BigByteBuffer buffer, int idSize) {
|
||||
Map<Id, BasicType> results = new HashMap<Id, BasicType>();
|
||||
for (int i = 0; i < instanceFieldIds.length; i++) {
|
||||
BasicType type = new BasicType(buffer, instanceFieldTypes[i],
|
||||
idSize);
|
||||
results.put(instanceFieldIds[i], type);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public Map<Id, BasicType> getStaticFields(){
|
||||
Map<Id, BasicType> results = new HashMap<Id, BasicType>(instanceFieldIds.length * 2);
|
||||
for(int i = 0 ; i < staticFieldIds.length ; i += 1){
|
||||
results.put(staticFieldIds[i], staticFieldValues[i]);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.dump;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.Id;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* Data for a single instance of an object in a {@link HeapDumpRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class InstanceDump extends AbstractDump {
|
||||
|
||||
public static final int TAG = 0x21;
|
||||
|
||||
private final Id classId;
|
||||
|
||||
private final BigByteBuffer instanceData;
|
||||
|
||||
public InstanceDump(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
classId = new Id(buffer, idSize);
|
||||
int size = buffer.getInt();
|
||||
instanceData = buffer.slice();
|
||||
instanceData.limit(size);
|
||||
buffer.position(buffer.position() + size);
|
||||
}
|
||||
|
||||
public Id getClassId() {
|
||||
return classId;
|
||||
}
|
||||
|
||||
public BigByteBuffer getInstanceData() {
|
||||
instanceData.rewind();
|
||||
return instanceData;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.dump;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.Id;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* Data for an array of object in a {@link HeapDumpRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
* May 20, 2014 3093 bsteffen Allow creation without reading full array.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ObjectArrayDump extends AbstractDump {
|
||||
|
||||
public static final int TAG = 0x22;
|
||||
|
||||
private final Id arrayClassId;
|
||||
|
||||
private final Id[] array;
|
||||
|
||||
public ObjectArrayDump(BigByteBuffer buffer, int idSize, boolean readArray) {
|
||||
super(buffer, idSize);
|
||||
int numElements = buffer.getInt();
|
||||
arrayClassId = new Id(buffer, idSize);
|
||||
if (readArray) {
|
||||
array = new Id[numElements];
|
||||
for (int i = 0; i < numElements; i++) {
|
||||
array[i] = new Id(buffer, idSize);
|
||||
}
|
||||
} else {
|
||||
array = null;
|
||||
buffer.position(buffer.position() + idSize * numElements);
|
||||
}
|
||||
}
|
||||
|
||||
public Id[] getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public Id getArrayClassId() {
|
||||
return arrayClassId;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.dump;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
import com.raytheon.hprof.data.heap.BasicType;
|
||||
|
||||
/**
|
||||
*
|
||||
* Data for an array of primitives in a {@link HeapDumpRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
* May 20, 2014 3093 bsteffen Allow creation without reading full array.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PrimitiveArrayDump extends AbstractDump {
|
||||
|
||||
public static final int TAG = 0x23;
|
||||
|
||||
private final BasicType[] array;
|
||||
|
||||
public PrimitiveArrayDump(BigByteBuffer buffer, int idSize,
|
||||
boolean readArray) {
|
||||
super(buffer, idSize);
|
||||
int numElements = buffer.getInt();
|
||||
byte type = buffer.get();
|
||||
if (readArray) {
|
||||
array = new BasicType[numElements];
|
||||
for (int i = 0; i < numElements; i++) {
|
||||
array[i] = new BasicType(buffer, type, idSize);
|
||||
}
|
||||
} else {
|
||||
array = null;
|
||||
BasicType tmp = new BasicType(buffer, type, idSize);
|
||||
int skip = (numElements - 1) * tmp.getSize();
|
||||
buffer.position(buffer.position() + skip);
|
||||
}
|
||||
}
|
||||
|
||||
public BasicType[] getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.Id;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base class for all garbage collection(GC) roots in a {@link HeapDumpRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AbstractRoot {
|
||||
|
||||
protected final Id id;
|
||||
|
||||
protected AbstractRoot(BigByteBuffer buffer, int idSize) {
|
||||
id = new Id(buffer, idSize);
|
||||
}
|
||||
|
||||
public Id getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.data.HeapDumpRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base class for all running roots in a {@link HeapDumpRecord}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AbstractRunningRoot extends AbstractRoot {
|
||||
|
||||
protected final int threadSerialNumber;
|
||||
|
||||
protected AbstractRunningRoot(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
threadSerialNumber = buffer.getInt();
|
||||
}
|
||||
|
||||
public int getThreadSerialNumber() {
|
||||
return threadSerialNumber;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.Id;
|
||||
|
||||
/**
|
||||
*
|
||||
* GC Root for a JNI Global.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RootJNIGlobal extends AbstractRoot {
|
||||
public static final int TAG = 0x01;
|
||||
|
||||
private final Id globalRefId;
|
||||
|
||||
public RootJNIGlobal(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
globalRefId = new Id(buffer, idSize);
|
||||
}
|
||||
|
||||
public Id getGlobalRefId() {
|
||||
return globalRefId;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or mimport com.raytheon.hprof.BigByteBuffer;
|
||||
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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* GC Root for a JNI Local.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RootJNILocal extends AbstractRunningRoot {
|
||||
|
||||
public static final int TAG = 0x02;
|
||||
|
||||
private final int frameNumberInStack;
|
||||
|
||||
public RootJNILocal(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
frameNumberInStack = buffer.getInt();
|
||||
}
|
||||
|
||||
public int getFrameNumberInStack() {
|
||||
return frameNumberInStack;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* GC Root for a single java stack frame.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RootJavaFrame extends AbstractRunningRoot {
|
||||
|
||||
public static final int TAG = 0x03;
|
||||
|
||||
private final int frameNumberInStack;
|
||||
|
||||
public RootJavaFrame(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
frameNumberInStack = buffer.getInt();
|
||||
}
|
||||
|
||||
public int getFrameNumberInStack() {
|
||||
return frameNumberInStack;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* A type of root that appears in an {@link HprofFile}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
* @see HprofFile
|
||||
*/
|
||||
public class RootMonitorUsed extends AbstractRoot {
|
||||
public static final int TAG = 0x07;
|
||||
|
||||
public RootMonitorUsed(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* GC Root for a sticky class.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RootStickyClass extends AbstractRoot {
|
||||
public static final int TAG = 0x05;
|
||||
|
||||
public RootStickyClass(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* 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.hprof.data.heap.root;
|
||||
|
||||
import com.raytheon.hprof.BigByteBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* GC Root for a thread object.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RootThreadObject extends AbstractRunningRoot {
|
||||
|
||||
public static final int TAG = 0x08;
|
||||
|
||||
private final int stackTraceSerialNumber;
|
||||
|
||||
public RootThreadObject(BigByteBuffer buffer, int idSize) {
|
||||
super(buffer, idSize);
|
||||
stackTraceSerialNumber = buffer.getInt();
|
||||
}
|
||||
|
||||
public int getStackTraceSerialNumber() {
|
||||
return stackTraceSerialNumber;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/**
|
||||
* 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.viz.hprof;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.hprof.HprofFile;
|
||||
import com.raytheon.hprof.SmartInstance;
|
||||
import com.raytheon.hprof.data.heap.dump.InstanceDump;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base class for objects exporting information from an hprof file. Provides a
|
||||
* framework for creating and commenting a file for output.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 08, 2014 2648 bsteffen Initial doc
|
||||
* May 22, 2014 3093 bsteffen Add printMB, printKB
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractExporter {
|
||||
|
||||
protected final HprofFile hprof;
|
||||
|
||||
private final File outputDirectory;
|
||||
|
||||
private Writer writer;
|
||||
|
||||
public AbstractExporter(HprofFile hprof, File outputDirectory) {
|
||||
this.hprof = hprof;
|
||||
this.outputDirectory = outputDirectory;
|
||||
}
|
||||
|
||||
public void export() {
|
||||
System.out.println(getInfo());
|
||||
try {
|
||||
exportInternal();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
protected abstract String getFileName();
|
||||
|
||||
protected abstract void exportInternal() throws IOException;
|
||||
|
||||
protected String getComment() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getInfo() {
|
||||
return "Generating output for " + getClass().getSimpleName() + "...";
|
||||
}
|
||||
|
||||
protected void print(String output) throws IOException {
|
||||
if (writer == null) {
|
||||
writer = new BufferedWriter(new FileWriter(new File(
|
||||
outputDirectory, getFileName())));
|
||||
String comment = getComment();
|
||||
if (comment != null) {
|
||||
println(comment);
|
||||
}
|
||||
}
|
||||
writer.append(output);
|
||||
}
|
||||
|
||||
protected void println(String output) throws IOException {
|
||||
print(output + "\n");
|
||||
}
|
||||
|
||||
protected void printMB(String desc, long bytes) throws IOException {
|
||||
print(desc + (bytes / 1024 / 1024) + "MB\n");
|
||||
}
|
||||
|
||||
protected void printKB(String desc, long bytes) throws IOException {
|
||||
print(desc + (bytes / 1024) + "KB\n");
|
||||
}
|
||||
|
||||
protected void close() {
|
||||
if (writer != null) {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected List<SmartInstance> getInstances(String className) {
|
||||
List<InstanceDump> instances = hprof.getInstances(className);
|
||||
List<SmartInstance> smartInstances = new ArrayList<SmartInstance>(
|
||||
instances.size());
|
||||
for (InstanceDump instance : instances) {
|
||||
smartInstances.add(new SmartInstance(hprof, instance));
|
||||
}
|
||||
return smartInstances;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue