Omaha #3275 - moving developer tools to separate repository

Former-commit-id: 436ce72db9 [formerly da96ff215e03ffdad7e7d157f6f5539663ad47ce]
Former-commit-id: 5fd1555ff9
This commit is contained in:
Steve Harris 2014-06-25 16:16:03 -05:00
parent 7b44d8ad2d
commit 6c0a7da2a0
187 changed files with 0 additions and 17458 deletions

View file

@ -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>

View file

@ -1,2 +0,0 @@
out/
*.jar

View file

@ -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>

View file

@ -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

View file

@ -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>

View file

@ -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)

View file

@ -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

View file

@ -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();
}
}
}

View file

@ -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();
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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>

View file

@ -1 +0,0 @@
bin.includes = feature.xml

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -1,5 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
res/

View file

@ -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&amp;delay=5000&amp;maxMessagesPerPoll=1000&amp;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>

View file

@ -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

View file

@ -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);
}
}
}
}

View file

@ -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;
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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"

View file

@ -1,4 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -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));
}
}

View file

@ -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);
}
}
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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"

View file

@ -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.

View file

@ -1,4 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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=''

View file

@ -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

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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 + "]";
}
}

View file

@ -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!");
}
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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"

View file

@ -1,5 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
logback.xml

View file

@ -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>

View file

@ -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");
}
}

View file

@ -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");
}
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -1,4 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -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>

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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 */
}
}

View file

@ -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);
}
}
};
}

View file

@ -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.
*/
}
}

View file

@ -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;
}
}

View file

@ -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 */
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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