diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/CaseNodeData.java b/Core/src/org/sleuthkit/autopsy/casemodule/CaseNodeData.java new file mode 100755 index 0000000000..f4308e8954 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/casemodule/CaseNodeData.java @@ -0,0 +1,141 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.casemodule; + +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; + +/** + * An object that converts case data for a case directory coordination service + * node to and from byte arrays. + */ +public final class CaseNodeData { + + private static final int CURRENT_VERSION = 0; + + private int version; + private boolean errorsOccurred; + + /** + * Gets the current version of the case directory coordination service node + * data. + * + * @return The version number. + */ + public static int getCurrentVersion() { + return CaseNodeData.CURRENT_VERSION; + } + + /** + * Uses coordination service node data to construct an object that converts + * case data for a case directory coordination service node to and from byte + * arrays. + * + * @param nodeData The raw bytes received from the coordination service. + * + * @throws InvalidDataException If the node data buffer is smaller than + * expected. + */ + public CaseNodeData(byte[] nodeData) throws InvalidDataException { + if(nodeData == null || nodeData.length == 0) { + this.version = CURRENT_VERSION; + this.errorsOccurred = false; + } else { + /* + * Get fields from node data. + */ + ByteBuffer buffer = ByteBuffer.wrap(nodeData); + try { + if (buffer.hasRemaining()) { + this.version = buffer.getInt(); + + /* + * Flags bit format: 76543210 + * 0-6 --> reserved for future use + * 7 --> errorsOccurred + */ + byte flags = buffer.get(); + this.errorsOccurred = (flags < 0); + } + } catch (BufferUnderflowException ex) { + throw new InvalidDataException("Node data is incomplete", ex); + } + } + } + + /** + * Gets whether or not any errors occurred during the processing of the job. + * + * @return True or false. + */ + public boolean getErrorsOccurred() { + return this.errorsOccurred; + } + + /** + * Sets whether or not any errors occurred during the processing of job. + * + * @param errorsOccurred True or false. + */ + public void setErrorsOccurred(boolean errorsOccurred) { + this.errorsOccurred = errorsOccurred; + } + + /** + * Gets the node data version number. + * + * @return The version number. + */ + public int getVersion() { + return this.version; + } + + /** + * Gets the node data as a byte array that can be sent to the coordination + * service. + * + * @return The node data as a byte array. + */ + public byte[] toArray() { + ByteBuffer buffer = ByteBuffer.allocate(5); + + buffer.putInt(this.version); + buffer.put((byte)(this.errorsOccurred ? 0x80 : 0)); + + // Prepare the array + byte[] array = new byte[buffer.position()]; + buffer.rewind(); + buffer.get(array, 0, array.length); + + return array; + } + + public final static class InvalidDataException extends Exception { + + private static final long serialVersionUID = 1L; + + private InvalidDataException(String message) { + super(message); + } + + private InvalidDataException(String message, Throwable cause) { + super(message, cause); + } + } +} \ No newline at end of file diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.form b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.form index cec9d21492..f00e28374c 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.form +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.form @@ -17,46 +17,22 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - + + + + + + + + + @@ -73,8 +49,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -99,9 +103,9 @@ - + - + @@ -135,16 +139,13 @@ - - - - - - - - - - + + + + + + + @@ -169,6 +170,7 @@ + @@ -192,6 +194,7 @@ + @@ -215,6 +218,7 @@ + @@ -231,6 +235,15 @@ + + + + + + + + + @@ -244,6 +257,15 @@ + + + + + + + + + @@ -287,6 +309,15 @@ + + + + + + + + + @@ -300,6 +331,15 @@ + + + + + + + + + @@ -313,6 +353,15 @@ + + + + + + + + + @@ -327,6 +376,15 @@ + + + + + + + + + @@ -340,6 +398,15 @@ + + + + + + + + + @@ -353,6 +420,15 @@ + + + + + + + + + @@ -366,6 +442,15 @@ + + + + + + + + + @@ -379,6 +464,15 @@ + + + + + + + + + @@ -419,6 +513,15 @@ + + + + + + + + + @@ -453,20 +556,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java index 7b893ae0b9..8024fbf93a 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestControlPanel.java @@ -73,6 +73,7 @@ import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog; * one such panel per node. */ @Messages({ + "AutoIngestControlPanel.bnClusterMetrics.text=Cluster Metrics", "AutoIngestControlPanel.bnPause.text=Pause", "AutoIngestControlPanel.bnPause.paused=Paused", "AutoIngestControlPanel.bnPause.running=Running", @@ -116,7 +117,7 @@ import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog; "AutoIngestControlPanel.bnPrioritizeJob.actionCommand=", "AutoIngestControlPanel.lbServicesStatus.text=Services Status:", "AutoIngestControlPanel.tbServicesStatusMessage.text=", - "AutoIngestControlPanel.bnOpenLogDir.text=Open System Logs Directory", + "AutoIngestControlPanel.bnOpenLogDir.text=Open System Logs Folder", "AutoIngestControlPanel.bnReprocessJob.text=Reprocess Job", "AutoIngestControlPanel.bnPrioritizeFolder.label=", "AutoIngestControlPanel.Cancelling=Cancelling...", @@ -1198,10 +1199,12 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { lbServicesStatus = new javax.swing.JLabel(); tbServicesStatusMessage = new javax.swing.JTextField(); bnOpenLogDir = new javax.swing.JButton(); + bnClusterMetrics = new javax.swing.JButton(); bnReprocessJob = new javax.swing.JButton(); pendingTable.setModel(pendingTableModel); pendingTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.pendingTable.toolTipText")); // NOI18N + pendingTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS); pendingTable.setRowHeight(20); pendingTable.setSelectionModel(new DefaultListSelectionModel() { private static final long serialVersionUID = 1L; @@ -1219,6 +1222,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { runningTable.setModel(runningTableModel); runningTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.runningTable.toolTipText")); // NOI18N + runningTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS); runningTable.setRowHeight(20); runningTable.setSelectionModel(new DefaultListSelectionModel() { private static final long serialVersionUID = 1L; @@ -1236,6 +1240,7 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { completedTable.setModel(completedTableModel); completedTable.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.completedTable.toolTipText")); // NOI18N + completedTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS); completedTable.setRowHeight(20); completedTable.setSelectionModel(new DefaultListSelectionModel() { private static final long serialVersionUID = 1L; @@ -1253,6 +1258,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnCancelJob, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnCancelJob.text")); // NOI18N bnCancelJob.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnCancelJob.toolTipText")); // NOI18N + bnCancelJob.setMaximumSize(new java.awt.Dimension(162, 23)); + bnCancelJob.setMinimumSize(new java.awt.Dimension(162, 23)); + bnCancelJob.setPreferredSize(new java.awt.Dimension(162, 23)); bnCancelJob.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnCancelJobActionPerformed(evt); @@ -1261,6 +1269,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnDeleteCase, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnDeleteCase.text")); // NOI18N bnDeleteCase.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnDeleteCase.toolTipText")); // NOI18N + bnDeleteCase.setMaximumSize(new java.awt.Dimension(162, 23)); + bnDeleteCase.setMinimumSize(new java.awt.Dimension(162, 23)); + bnDeleteCase.setPreferredSize(new java.awt.Dimension(162, 23)); bnDeleteCase.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnDeleteCaseActionPerformed(evt); @@ -1278,6 +1289,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnRefresh, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnRefresh.text")); // NOI18N bnRefresh.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnRefresh.toolTipText")); // NOI18N + bnRefresh.setMaximumSize(new java.awt.Dimension(162, 23)); + bnRefresh.setMinimumSize(new java.awt.Dimension(162, 23)); + bnRefresh.setPreferredSize(new java.awt.Dimension(162, 23)); bnRefresh.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnRefreshActionPerformed(evt); @@ -1286,6 +1300,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnCancelModule, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnCancelModule.text")); // NOI18N bnCancelModule.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnCancelModule.toolTipText")); // NOI18N + bnCancelModule.setMaximumSize(new java.awt.Dimension(162, 23)); + bnCancelModule.setMinimumSize(new java.awt.Dimension(162, 23)); + bnCancelModule.setPreferredSize(new java.awt.Dimension(162, 23)); bnCancelModule.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnCancelModuleActionPerformed(evt); @@ -1294,6 +1311,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnExit, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnExit.text")); // NOI18N bnExit.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnExit.toolTipText")); // NOI18N + bnExit.setMaximumSize(new java.awt.Dimension(162, 23)); + bnExit.setMinimumSize(new java.awt.Dimension(162, 23)); + bnExit.setPreferredSize(new java.awt.Dimension(162, 23)); bnExit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnExitActionPerformed(evt); @@ -1303,6 +1323,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnOptions, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnOptions.text")); // NOI18N bnOptions.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnOptions.toolTipText")); // NOI18N bnOptions.setEnabled(false); + bnOptions.setMaximumSize(new java.awt.Dimension(162, 23)); + bnOptions.setMinimumSize(new java.awt.Dimension(162, 23)); + bnOptions.setPreferredSize(new java.awt.Dimension(162, 23)); bnOptions.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnOptionsActionPerformed(evt); @@ -1311,6 +1334,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnShowProgress, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnShowProgress.text")); // NOI18N bnShowProgress.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnShowProgress.toolTipText")); // NOI18N + bnShowProgress.setMaximumSize(new java.awt.Dimension(162, 23)); + bnShowProgress.setMinimumSize(new java.awt.Dimension(162, 23)); + bnShowProgress.setPreferredSize(new java.awt.Dimension(162, 23)); bnShowProgress.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnShowProgressActionPerformed(evt); @@ -1319,6 +1345,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnPause, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnPause.text")); // NOI18N bnPause.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnPause.toolTipText")); // NOI18N + bnPause.setMaximumSize(new java.awt.Dimension(162, 23)); + bnPause.setMinimumSize(new java.awt.Dimension(162, 23)); + bnPause.setPreferredSize(new java.awt.Dimension(162, 23)); bnPause.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnPauseActionPerformed(evt); @@ -1327,6 +1356,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnPrioritizeCase, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnPrioritizeCase.text")); // NOI18N bnPrioritizeCase.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnPrioritizeCase.toolTipText")); // NOI18N + bnPrioritizeCase.setMaximumSize(new java.awt.Dimension(162, 23)); + bnPrioritizeCase.setMinimumSize(new java.awt.Dimension(162, 23)); + bnPrioritizeCase.setPreferredSize(new java.awt.Dimension(162, 23)); bnPrioritizeCase.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnPrioritizeCaseActionPerformed(evt); @@ -1335,6 +1367,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnShowCaseLog, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnShowCaseLog.text")); // NOI18N bnShowCaseLog.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnShowCaseLog.toolTipText")); // NOI18N + bnShowCaseLog.setMaximumSize(new java.awt.Dimension(162, 23)); + bnShowCaseLog.setMinimumSize(new java.awt.Dimension(162, 23)); + bnShowCaseLog.setPreferredSize(new java.awt.Dimension(162, 23)); bnShowCaseLog.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnShowCaseLogActionPerformed(evt); @@ -1352,6 +1387,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { org.openide.awt.Mnemonics.setLocalizedText(bnPrioritizeJob, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnPrioritizeJob.text")); // NOI18N bnPrioritizeJob.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnPrioritizeJob.toolTipText")); // NOI18N bnPrioritizeJob.setActionCommand(org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnPrioritizeJob.actionCommand")); // NOI18N + bnPrioritizeJob.setMaximumSize(new java.awt.Dimension(162, 23)); + bnPrioritizeJob.setMinimumSize(new java.awt.Dimension(162, 23)); + bnPrioritizeJob.setPreferredSize(new java.awt.Dimension(162, 23)); bnPrioritizeJob.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnPrioritizeJobActionPerformed(evt); @@ -1367,13 +1405,29 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { tbServicesStatusMessage.setBorder(null); org.openide.awt.Mnemonics.setLocalizedText(bnOpenLogDir, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnOpenLogDir.text")); // NOI18N + bnOpenLogDir.setMaximumSize(new java.awt.Dimension(162, 23)); + bnOpenLogDir.setMinimumSize(new java.awt.Dimension(162, 23)); + bnOpenLogDir.setPreferredSize(new java.awt.Dimension(162, 23)); bnOpenLogDir.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnOpenLogDirActionPerformed(evt); } }); + org.openide.awt.Mnemonics.setLocalizedText(bnClusterMetrics, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnClusterMetrics.text")); // NOI18N + bnClusterMetrics.setMaximumSize(new java.awt.Dimension(162, 23)); + bnClusterMetrics.setMinimumSize(new java.awt.Dimension(162, 23)); + bnClusterMetrics.setPreferredSize(new java.awt.Dimension(162, 23)); + bnClusterMetrics.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnClusterMetricsActionPerformed(evt); + } + }); + org.openide.awt.Mnemonics.setLocalizedText(bnReprocessJob, org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "AutoIngestControlPanel.bnReprocessJob.text")); // NOI18N + bnReprocessJob.setMaximumSize(new java.awt.Dimension(162, 23)); + bnReprocessJob.setMinimumSize(new java.awt.Dimension(162, 23)); + bnReprocessJob.setPreferredSize(new java.awt.Dimension(162, 23)); bnReprocessJob.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnReprocessJobActionPerformed(evt); @@ -1387,38 +1441,20 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(lbPending, javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pendingScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(bnPrioritizeCase, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(bnPrioritizeJob, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(bnPause) - .addGap(18, 18, 18) - .addComponent(bnRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(bnOptions) - .addGap(18, 18, 18) - .addComponent(bnOpenLogDir) - .addGap(18, 18, 18) - .addComponent(bnExit, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(completedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 920, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(bnPause, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(bnCancelJob, javax.swing.GroupLayout.PREFERRED_SIZE, 117, Short.MAX_VALUE) - .addComponent(bnShowProgress, javax.swing.GroupLayout.PREFERRED_SIZE, 116, Short.MAX_VALUE) - .addComponent(bnCancelModule, javax.swing.GroupLayout.PREFERRED_SIZE, 117, Short.MAX_VALUE) - .addComponent(bnDeleteCase, javax.swing.GroupLayout.PREFERRED_SIZE, 117, Short.MAX_VALUE) - .addComponent(bnShowCaseLog, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(bnReprocessJob, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(bnRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(bnOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(bnOpenLogDir, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(bnClusterMetrics, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(bnExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addComponent(lbStatus) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -1429,11 +1465,32 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { .addComponent(lbServicesStatus) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(tbServicesStatusMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 861, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lbPending) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 1021, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(completedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 1021, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(bnCancelJob, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnShowProgress, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnCancelModule, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnDeleteCase, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnShowCaseLog, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnReprocessJob, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(layout.createSequentialGroup() + .addComponent(pendingScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 1021, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(bnPrioritizeCase, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(bnPrioritizeJob, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) ); - layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnCancelJob, bnCancelModule, bnDeleteCase, bnExit, bnOpenLogDir, bnOptions, bnPause, bnRefresh, bnShowProgress}); + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {bnCancelJob, bnCancelModule, bnDeleteCase, bnShowProgress}); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -1453,48 +1510,47 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { .addComponent(pendingScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addGap(82, 82, 82) - .addComponent(bnPrioritizeCase) + .addComponent(bnPrioritizeCase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnPrioritizeJob))) + .addComponent(bnPrioritizeJob, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lbRunning) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(34, 34, 34) - .addComponent(bnShowProgress) + .addComponent(bnShowProgress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnCancelJob) + .addComponent(bnCancelJob, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnCancelModule)) + .addComponent(bnCancelModule, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(runningScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(68, 68, 68) - .addComponent(bnReprocessJob) + .addComponent(bnReprocessJob, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnDeleteCase) + .addComponent(bnDeleteCase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(bnShowCaseLog)) + .addComponent(bnShowCaseLog, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lbCompleted) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(completedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnExit) - .addComponent(bnOpenLogDir)) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(bnPause) - .addComponent(bnRefresh) - .addComponent(bnOptions))))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(bnPause, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnOpenLogDir, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnClusterMetrics, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addContainerGap()) ); - layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {bnCancelJob, bnCancelModule, bnDeleteCase, bnExit, bnOpenLogDir, bnOptions, bnRefresh, bnShowProgress}); + layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {bnCancelJob, bnCancelModule, bnClusterMetrics, bnDeleteCase, bnExit, bnOpenLogDir, bnOptions, bnPrioritizeCase, bnPrioritizeJob, bnRefresh, bnShowProgress}); }// //GEN-END:initComponents @@ -1523,11 +1579,11 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { "AutoIngestControlPanel.DeletionFailed=Deletion failed for job" }) private void bnDeleteCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDeleteCaseActionPerformed - if (completedTable.getModel().getRowCount() < 0 || completedTable.getSelectedRow() < 0) { + if (completedTableModel.getRowCount() < 0 || completedTable.getSelectedRow() < 0) { return; } - String caseName = (String) completedTable.getModel().getValueAt(completedTable.convertRowIndexToModel(completedTable.getSelectedRow()), JobsTableModelColumns.CASE.ordinal()); + String caseName = (String) completedTable.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal()); Object[] options = { org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "ConfirmationDialog.Delete"), org.openide.util.NbBundle.getMessage(AutoIngestControlPanel.class, "ConfirmationDialog.DoNotDelete") @@ -1544,8 +1600,8 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { if (reply == JOptionPane.YES_OPTION) { bnDeleteCase.setEnabled(false); bnShowCaseLog.setEnabled(false); - if (completedTable.getModel().getRowCount() > 0 && completedTable.getSelectedRow() >= 0) { - Path caseDirectoryPath = (Path) completedTable.getModel().getValueAt(completedTable.convertRowIndexToModel(completedTable.getSelectedRow()), JobsTableModelColumns.CASE_DIRECTORY_PATH.ordinal()); + if (completedTableModel.getRowCount() > 0 && completedTable.getSelectedRow() >= 0) { + Path caseDirectoryPath = (Path) completedTableModel.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.CASE_DIRECTORY_PATH.ordinal()); completedTable.clearSelection(); this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); CaseDeletionResult result = manager.deleteCase(caseName, caseDirectoryPath); @@ -1691,10 +1747,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { */ @Messages({"AutoIngestControlPanel.casePrioritization.errorMessage=An error occurred when prioritizing the case. Some or all jobs may not have been prioritized."}) private void bnPrioritizeCaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeCaseActionPerformed - if (pendingTable.getModel().getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) { + if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - - String caseName = (pendingTable.getModel().getValueAt(pendingTable.convertRowIndexToModel(pendingTable.getSelectedRow()), JobsTableModelColumns.CASE.ordinal())).toString(); + String caseName = (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.CASE.ordinal())).toString(); try { manager.prioritizeCase(caseName); } catch (AutoIngestManager.AutoIngestManagerException ex) { @@ -1720,9 +1775,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { }) private void bnShowCaseLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnShowCaseLogActionPerformed try { - int selectedRow = completedTable.convertRowIndexToModel(completedTable.getSelectedRow()); + int selectedRow = completedTable.getSelectedRow(); if (selectedRow != -1) { - Path caseDirectoryPath = (Path) completedTable.getModel().getValueAt(selectedRow, JobsTableModelColumns.CASE_DIRECTORY_PATH.ordinal()); + Path caseDirectoryPath = (Path) completedTableModel.getValueAt(selectedRow, JobsTableModelColumns.CASE_DIRECTORY_PATH.ordinal()); if (null != caseDirectoryPath) { Path pathToLog = AutoIngestJobLogger.getLogPath(caseDirectoryPath); if (pathToLog.toFile().exists()) { @@ -1751,9 +1806,9 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { @Messages({"AutoIngestControlPanel.jobPrioritization.errorMessage=An error occurred when prioritizing the job."}) private void bnPrioritizeJobActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnPrioritizeJobActionPerformed - if (pendingTable.getModel().getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) { + if (pendingTableModel.getRowCount() > 0 && pendingTable.getSelectedRow() >= 0) { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - Path manifestFilePath = (Path) (pendingTable.getModel().getValueAt(pendingTable.convertRowIndexToModel(pendingTable.getSelectedRow()), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal())); + Path manifestFilePath = (Path) (pendingTableModel.getValueAt(pendingTable.getSelectedRow(), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal())); try { manager.prioritizeJob(manifestFilePath); } catch (AutoIngestManager.AutoIngestManagerException ex) { @@ -1780,19 +1835,28 @@ public final class AutoIngestControlPanel extends JPanel implements Observer { }//GEN-LAST:event_bnOpenLogDirActionPerformed private void bnReprocessJobActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnReprocessJobActionPerformed - if (completedTable.getModel().getRowCount() < 0 || completedTable.getSelectedRow() < 0) { + if (completedTableModel.getRowCount() < 0 || completedTable.getSelectedRow() < 0) { return; } this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - Path manifestPath = (Path) completedTable.getModel().getValueAt(completedTable.convertRowIndexToModel(completedTable.getSelectedRow()), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal()); + Path manifestPath = (Path) completedTableModel.getValueAt(completedTable.getSelectedRow(), JobsTableModelColumns.MANIFEST_FILE_PATH.ordinal()); manager.reprocessJob(manifestPath); refreshTables(); AutoIngestControlPanel.this.setCursor(Cursor.getDefaultCursor()); }//GEN-LAST:event_bnReprocessJobActionPerformed + private void bnClusterMetricsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnClusterMetricsActionPerformed + try { + new AutoIngestMetricsDialog(this.getTopLevelAncestor()); + } catch (AutoIngestMetricsDialog.AutoIngestMetricsDialogException ex) { + MessageNotifyUtil.Message.error(ex.getMessage()); + } + }//GEN-LAST:event_bnClusterMetricsActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton bnCancelJob; private javax.swing.JButton bnCancelModule; + private javax.swing.JButton bnClusterMetrics; private javax.swing.JButton bnDeleteCase; private javax.swing.JButton bnExit; private javax.swing.JButton bnOpenLogDir; diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java index d53503a72f..421b1f92f0 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestDashboard.java @@ -873,7 +873,11 @@ final class AutoIngestDashboard extends JPanel implements Observer { }//GEN-LAST:event_prioritizeCaseButtonActionPerformed private void clusterMetricsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clusterMetricsButtonActionPerformed - new AutoIngestMetricsDialog(this.getTopLevelAncestor(), autoIngestMonitor); + try { + new AutoIngestMetricsDialog(this.getTopLevelAncestor()); + } catch (AutoIngestMetricsDialog.AutoIngestMetricsDialogException ex) { + MessageNotifyUtil.Message.error(ex.getMessage()); + } }//GEN-LAST:event_clusterMetricsButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 1cbe9af5a6..2ce6e2cba8 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -64,7 +64,7 @@ import org.sleuthkit.autopsy.casemodule.Case.CaseType; import org.sleuthkit.autopsy.casemodule.CaseActionException; import org.sleuthkit.autopsy.casemodule.CaseDetails; import org.sleuthkit.autopsy.casemodule.CaseMetadata; -import org.sleuthkit.autopsy.coordinationservice.CaseNodeData; +import org.sleuthkit.autopsy.casemodule.CaseNodeData; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException; import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock; @@ -498,7 +498,6 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } SYS_LOGGER.log(Level.INFO, "Starting input scan of {0}", rootInputDirectory); InputDirScanner scanner = new InputDirScanner(); - scanner.scan(); SYS_LOGGER.log(Level.INFO, "Completed input scan of {0}", rootInputDirectory); } @@ -554,12 +553,10 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (!prioritizedJobs.isEmpty()) { ++maxPriority; for (AutoIngestJob job : prioritizedJobs) { - int oldPriority = job.getPriority(); - job.setPriority(maxPriority); try { this.updateCoordinationServiceManifestNode(job); + job.setPriority(maxPriority); } catch (CoordinationServiceException | InterruptedException ex) { - job.setPriority(oldPriority); throw new AutoIngestManagerException("Error updating case priority", ex); } } @@ -610,14 +607,12 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ if (null != prioritizedJob) { ++maxPriority; - int oldPriority = prioritizedJob.getPriority(); - prioritizedJob.setPriority(maxPriority); try { this.updateCoordinationServiceManifestNode(prioritizedJob); } catch (CoordinationServiceException | InterruptedException ex) { - prioritizedJob.setPriority(oldPriority); throw new AutoIngestManagerException("Error updating job priority", ex); } + prioritizedJob.setPriority(maxPriority); } Collections.sort(pendingJobs, new AutoIngestJob.PriorityComparator()); @@ -872,9 +867,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen /** * Sets the coordination service manifest node. * - * Note that a new auto ingest job node data object will be created from the - * job passed in. Thus, if the data version of the node has changed, the - * node will be "upgraded" as well as updated. + * Note that a new auto ingest job node data object will be created from + * the job passed in. Thus, if the data version of the node has changed, + * the node will be "upgraded" as well as updated. * * @param job The auto ingest job. */ @@ -884,19 +879,14 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen byte[] rawData = nodeData.toArray(); coordinationService.setNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestNodePath, rawData); } - + /** - * Sets the error flag for case node data given a case directory path. + * Sets the coordination service case node. * - * @param caseDirectoryPath The case directory path. - * - * @throws CoordinationService.CoordinationServiceException - * @throws InterruptedException - * @throws CaseNodeData.InvalidDataException + * @param caseNodeData The case node data. + * @param caseDirectoryPath The case directory. */ - private void setCaseNodeDataErrorsOccurred(Path caseDirectoryPath) throws CoordinationServiceException, InterruptedException, CaseNodeData.InvalidDataException { - CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); - caseNodeData.setErrorsOccurred(true); + void updateCoordinationServiceCaseNode(CaseNodeData caseNodeData, Path caseDirectoryPath) throws CoordinationServiceException, InterruptedException { byte[] rawData = caseNodeData.toArray(); coordinationService.setNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString(), rawData); } @@ -1062,8 +1052,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (null != manifest) { /* - * Update the mapping of case names to manifest paths that - * is used for case deletion. + * Update the mapping of case names to manifest paths that is + * used for case deletion. */ String caseName = manifest.getCaseName(); Path manifestPath = manifest.getFilePath(); @@ -1077,8 +1067,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } /* - * Add a job to the pending jobs queue, the completed jobs - * list, or do crashed job recovery, as required. + * Add a job to the pending jobs queue, the completed jobs list, + * or do crashed job recovery, as required. */ try { byte[] rawData = coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, manifestPath.toString()); @@ -1098,7 +1088,7 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen break; case DELETED: /* - * Ignore jobs marked as "deleted." + * Ignore jobs marked as "deleted." */ break; default: @@ -1208,8 +1198,8 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen private void addNewPendingJob(Manifest manifest) throws InterruptedException, AutoIngestJobException { /* * Create the coordination service manifest node data for the job. - * Note that getting the lock will create the node for the job (with - * no data) if it does not already exist. + * Note that getting the lock will create the node for the job + * (with no data) if it does not already exist. * * An exclusive lock is obtained before creating the node data * because another host may have already found the job, obtained an @@ -1239,15 +1229,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen * the node that was processing the job crashed and the processing * status was not updated. * - * @param manifest The manifest for upgrading the node. + * @param manifest The manifest for upgrading the node. * @param jobNodeData The auto ingest job node data. * - * @throws InterruptedException if the thread running the input - * directory scan task is interrupted - * while blocked, i.e., if auto ingest is - * shutting down. - * @throws AutoIngestJobException if there is an issue creating a new - * AutoIngestJob object. + * @throws InterruptedException if the thread running the input + * directory scan task is interrupted while + * blocked, i.e., if auto ingest is + * shutting down. */ private void doRecoveryIfCrashed(Manifest manifest, AutoIngestJobNodeData jobNodeData) throws InterruptedException, AutoIngestJobException { /* @@ -1260,35 +1248,51 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (null != manifestLock) { SYS_LOGGER.log(Level.SEVERE, "Attempting crash recovery for {0}", manifestPath); try { - Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName()); - /* * Create the recovery job. */ AutoIngestJob job = new AutoIngestJob(jobNodeData); int numberOfCrashes = job.getNumberOfCrashes(); - if (numberOfCrashes <= AutoIngestUserPreferences.getMaxNumTimesToProcessImage()) { - ++numberOfCrashes; - job.setNumberOfCrashes(numberOfCrashes); - if (numberOfCrashes <= AutoIngestUserPreferences.getMaxNumTimesToProcessImage()) { - job.setCompletedDate(new Date(0)); - } else { - job.setCompletedDate(Date.from(Instant.now())); - } - } - + ++numberOfCrashes; + job.setNumberOfCrashes(numberOfCrashes); + job.setCompletedDate(new Date(0)); + Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName()); if (null != caseDirectoryPath) { job.setCaseDirectoryPath(caseDirectoryPath); job.setErrorsOccurred(true); - try { - setCaseNodeDataErrorsOccurred(caseDirectoryPath); - } catch (CaseNodeData.InvalidDataException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to get case node data for %s", caseDirectoryPath), ex); - } } else { job.setErrorsOccurred(false); } + /* + * Update the coordination service manifest node for + * the job. If this fails, leave the recovery to + * another host. + */ + try { + updateCoordinationServiceManifestNode(job); + if (numberOfCrashes <= AutoIngestUserPreferences.getMaxNumTimesToProcessImage()) { + newPendingJobsList.add(job); + } else { + newCompletedJobsList.add(new AutoIngestJob(jobNodeData)); + } + } catch (CoordinationServiceException ex) { + SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifestPath), ex); + return; + } + + /* + * Update the case node data and do the logging. + */ + if (null != caseDirectoryPath) { + try { + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); + } catch (CaseNodeData.InvalidDataException ex) { + SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to get case node data for %s", caseDirectoryPath), ex); + } + } if (numberOfCrashes <= AutoIngestUserPreferences.getMaxNumTimesToProcessImage()) { job.setProcessingStatus(AutoIngestJob.ProcessingStatus.PENDING); if (null != caseDirectoryPath) { @@ -1302,32 +1306,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen job.setProcessingStatus(AutoIngestJob.ProcessingStatus.COMPLETED); if (null != caseDirectoryPath) { try { - new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), caseDirectoryPath).logCrashRecoveryNoRetry(); + new AutoIngestJobLogger(manifest.getFilePath(), manifest.getDataSourceFileName(), jobNodeData.getCaseDirectoryPath()).logCrashRecoveryNoRetry(); } catch (AutoIngestJobLoggerException ex) { SYS_LOGGER.log(Level.SEVERE, String.format("Error creating case auto ingest log entry for crashed job for %s", manifestPath), ex); } } } - /* - * Update the coordination service node for the job. If - * this fails, leave the recovery to another host. - */ - try { - updateCoordinationServiceManifestNode(job); - } catch (CoordinationServiceException ex) { - SYS_LOGGER.log(Level.SEVERE, String.format("Error attempting to set node data for %s", manifestPath), ex); - return; - } - - jobNodeData = new AutoIngestJobNodeData(job); - - if (numberOfCrashes <= AutoIngestUserPreferences.getMaxNumTimesToProcessImage()) { - newPendingJobsList.add(job); - } else { - newCompletedJobsList.add(new AutoIngestJob(jobNodeData)); - } - } finally { try { manifestLock.release(); @@ -1382,10 +1367,11 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen /* * Try to upgrade/update the coordination service manifest - * node data for the job. It is possible that two hosts will - * both try to obtain the lock to do the upgrade operation - * at the same time. If this happens, the host that is - * holding the lock will complete the upgrade operation. + * node data for the job. It is possible that two hosts + * will both try to obtain the lock to do the upgrade + * operation at the same time. If this happens, the host + * that is holding the lock will complete the upgrade + * operation. */ try (Lock manifestLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.MANIFESTS, manifest.getFilePath().toString())) { if (null != manifestLock) { @@ -1967,7 +1953,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (currentJob.isCanceled()) { Path caseDirectoryPath = currentJob.getCaseDirectoryPath(); if (null != caseDirectoryPath) { - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); AutoIngestJobLogger jobLogger = new AutoIngestJobLogger(manifestPath, currentJob.getManifest().getDataSourceFileName(), caseDirectoryPath); jobLogger.logJobCancelled(); } @@ -2292,7 +2280,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (!dataSource.exists()) { SYS_LOGGER.log(Level.SEVERE, "Missing data source for {0}", manifestPath); currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logMissingDataSource(); return null; } @@ -2340,7 +2330,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen // did we find a data source processor that can process the data source if (validDataSourceProcessorsMap.isEmpty()) { // This should never happen. We should add all unsupported data sources as logical files. - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); currentJob.setErrorsOccurred(true); jobLogger.logFailedToIdentifyDataSource(); SYS_LOGGER.log(Level.WARNING, "Unsupported data source {0} for {1}", new Object[]{dataSource.getPath(), manifestPath}); // NON-NLS @@ -2366,7 +2358,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen // Log that the current DSP failed and set the error flag. We consider it an error // if a DSP fails even if a later one succeeds since we expected to be able to process // the data source which each DSP on the list. - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); currentJob.setErrorsOccurred(true); jobLogger.logDataSourceProcessorError(selectedProcessor.getDataSourceType()); SYS_LOGGER.log(Level.SEVERE, "Exception while processing {0} with data source processor {1}", new Object[]{dataSource.getPath(), selectedProcessor.getDataSourceType()}); @@ -2410,7 +2404,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen jobLogger.logDataSourceAdded(); if (dataSource.getContent().isEmpty()) { currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logNoDataSourceContent(); } break; @@ -2422,7 +2418,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen jobLogger.logDataSourceAdded(); if (dataSource.getContent().isEmpty()) { currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logNoDataSourceContent(); } break; @@ -2432,7 +2430,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen SYS_LOGGER.log(Level.SEVERE, "Critical error running data source processor for {0}: {1}", new Object[]{manifestPath, errorMessage}); } currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logFailedToAddDataSource(); break; } @@ -2446,7 +2446,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen */ SYS_LOGGER.log(Level.WARNING, "Cancellation while waiting for data source processor for {0}", manifestPath); currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logDataSourceProcessorCancelled(); } } @@ -2500,7 +2502,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen if (!cancelledModules.isEmpty()) { SYS_LOGGER.log(Level.WARNING, String.format("Ingest module(s) cancelled for %s", manifestPath)); currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); for (String module : snapshot.getCancelledDataSourceIngestModules()) { SYS_LOGGER.log(Level.WARNING, String.format("%s ingest module cancelled for %s", module, manifestPath)); jobLogger.logIngestModuleCancelled(module); @@ -2510,7 +2514,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } else { currentJob.setProcessingStage(AutoIngestJob.Stage.CANCELLING, Date.from(Instant.now())); currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logAnalysisCancelled(); CancellationReason cancellationReason = snapshot.getCancellationReason(); if (CancellationReason.NOT_CANCELLED != cancellationReason && CancellationReason.USER_CANCELLED != cancellationReason) { @@ -2523,13 +2529,17 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen SYS_LOGGER.log(Level.SEVERE, String.format("%s ingest module startup error for %s", error.getModuleDisplayName(), manifestPath), error.getThrowable()); } currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logIngestModuleStartupErrors(); throw new AnalysisStartupException(String.format("Error(s) during ingest module startup for %s", manifestPath)); } else { SYS_LOGGER.log(Level.SEVERE, String.format("Ingest manager ingest job start error for %s", manifestPath), ingestJobStartResult.getStartupException()); currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logAnalysisStartupError(); throw new AnalysisStartupException("Ingest manager error starting job", ingestJobStartResult.getStartupException()); } @@ -2538,7 +2548,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen SYS_LOGGER.log(Level.SEVERE, "Ingest job settings error for {0}: {1}", new Object[]{manifestPath, warning}); } currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logIngestJobSettingsErrors(); throw new AnalysisStartupException("Error(s) in ingest job settings"); } @@ -2581,7 +2593,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } catch (FileExportException ex) { SYS_LOGGER.log(Level.SEVERE, String.format("Error doing file export for %s", manifestPath), ex); currentJob.setErrorsOccurred(true); - setCaseNodeDataErrorsOccurred(caseDirectoryPath); + CaseNodeData caseNodeData = new CaseNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.CASES, caseDirectoryPath.toString())); + caseNodeData.setErrorsOccurred(true); + updateCoordinationServiceCaseNode(caseNodeData, caseDirectoryPath); jobLogger.logFileExportError(); } } @@ -2924,7 +2938,6 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen PARTIALLY_DELETED, FULLY_DELETED } - static final class AutoIngestManagerException extends Exception { private static final long serialVersionUID = 1L; @@ -2939,4 +2952,4 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen } -} +} \ No newline at end of file diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsCollector.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsCollector.java new file mode 100755 index 0000000000..9567b70470 --- /dev/null +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsCollector.java @@ -0,0 +1,160 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2017 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.experimental.autoingest; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException; +import org.sleuthkit.autopsy.coreutils.Logger; + +/** + * Collects metrics for an auto ingest cluster. + */ +final class AutoIngestMetricsCollector { + + private static final Logger LOGGER = Logger.getLogger(AutoIngestMetricsCollector.class.getName()); + private CoordinationService coordinationService; + + /** + * Creates an instance of the AutoIngestMetricsCollector. + * + * @throws AutoIngestMetricsCollector.AutoIngestMetricsCollectorException + */ + AutoIngestMetricsCollector() throws AutoIngestMetricsCollectorException { + try { + coordinationService = CoordinationService.getInstance(); + } catch (CoordinationServiceException ex) { + throw new AutoIngestMetricsCollectorException("Failed to get coordination service", ex); //NON-NLS + } + } + + /** + * Gets a new metrics snapshot from the coordination service for an auto + * ingest cluster. + * + * @return The metrics snapshot. + */ + MetricsSnapshot queryCoordinationServiceForMetrics() { + try { + MetricsSnapshot newMetricsSnapshot = new MetricsSnapshot(); + List nodeList = coordinationService.getNodeList(CoordinationService.CategoryNode.MANIFESTS); + for (String node : nodeList) { + try { + AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, node)); + if (nodeData.getVersion() < 1) { + /* + * Ignore version '0' nodes that have not been + * "upgraded" since they don't carry enough data. + */ + continue; + } + AutoIngestJob job = new AutoIngestJob(nodeData); + AutoIngestJob.ProcessingStatus processingStatus = nodeData.getProcessingStatus(); + switch (processingStatus) { + case PENDING: + case PROCESSING: + case DELETED: + /* + * These are not jobs we care about for metrics, so + * we will ignore them. + */ + break; + case COMPLETED: + newMetricsSnapshot.addCompletedJobDate(job.getCompletedDate()); + break; + default: + LOGGER.log(Level.SEVERE, "Unknown AutoIngestJobData.ProcessingStatus"); + break; + } + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, String.format("Unexpected interrupt while retrieving coordination service node data for '%s'", node), ex); + } catch (AutoIngestJobNodeData.InvalidDataException ex) { + LOGGER.log(Level.SEVERE, String.format("Unable to use node data for '%s'", node), ex); + } catch (AutoIngestJob.AutoIngestJobException ex) { + LOGGER.log(Level.SEVERE, String.format("Failed to create a job for '%s'", node), ex); + } + } + + return newMetricsSnapshot; + + } catch (CoordinationService.CoordinationServiceException ex) { + LOGGER.log(Level.SEVERE, "Failed to get node list from coordination service", ex); + return new MetricsSnapshot(); + } + } + + /** + * A snapshot of metrics for an auto ingest cluster. + */ + static final class MetricsSnapshot { + + private final List completedJobDates = new ArrayList<>(); + + /** + * Gets a list of completed job dates, formatted in milliseconds. + * + * @return The completed job dates, formatted in milliseconds. + */ + List getCompletedJobDates() { + return new ArrayList<>(completedJobDates); + } + + /** + * Adds a new date to the list of completed job dates. + * + * @param date The date to be added. + */ + void addCompletedJobDate(java.util.Date date) { + completedJobDates.add(date.getTime()); + } + } + + /** + * Exception type thrown when there is an error completing an auto ingest + * metrics collector operation. + */ + static final class AutoIngestMetricsCollectorException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructs an instance of the exception type thrown when there is an + * error completing an auto ingest metrics collector operation. + * + * @param message The exception message. + */ + private AutoIngestMetricsCollectorException(String message) { + super(message); + } + + /** + * Constructs an instance of the exception type thrown when there is an + * error completing an auto ingest metrics collector operation. + * + * @param message The exception message. + * @param cause A Throwable cause for the error. + */ + private AutoIngestMetricsCollectorException(String message, Throwable cause) { + super(message, cause); + } + + } +} \ No newline at end of file diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java index 66c6d28581..80bcb6958b 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMetricsDialog.java @@ -29,27 +29,30 @@ import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; /** - * Display basic metrics for a cluster. + * Displays auto ingest metrics for a cluster. */ final class AutoIngestMetricsDialog extends javax.swing.JDialog { - private final AutoIngestMonitor autoIngestMonitor; + private final AutoIngestMetricsCollector autoIngestMetricsCollector; /** - * Creates new form AutoIngestMetricsDialog + * Creates an instance of AutoIngestMetricsDialog * * @param parent The parent container. - * @param autoIngestMonitor The auto ingest monitor. */ @Messages({ "AutoIngestMetricsDialog.title.text=Auto Ingest Cluster Metrics", "AutoIngestMetricsDialog.initReportText=Select a date below and click the 'Get Metrics Since...' button to generate\na metrics report." }) - AutoIngestMetricsDialog(Container parent, AutoIngestMonitor autoIngestMonitor) { + AutoIngestMetricsDialog(Container parent) throws AutoIngestMetricsDialogException { super((Window) parent, NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.title.text"), ModalityType.MODELESS); + try { + autoIngestMetricsCollector = new AutoIngestMetricsCollector(); + } catch (AutoIngestMetricsCollector.AutoIngestMetricsCollectorException ex) { + throw new AutoIngestMetricsDialogException("Error starting up the auto ingest metrics dialog.", ex); + } initComponents(); reportTextArea.setText(NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.initReportText")); - this.autoIngestMonitor = autoIngestMonitor; setModal(true); setSize(getPreferredSize()); setLocationRelativeTo(parent); @@ -64,7 +67,7 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { return; } - AutoIngestMonitor.MetricsSnapshot metricsSnapshot = autoIngestMonitor.getMetricsSnapshot(); + AutoIngestMetricsCollector.MetricsSnapshot metricsSnapshot = autoIngestMetricsCollector.queryCoordinationServiceForMetrics(); Object[] completedJobDates = metricsSnapshot.getCompletedJobDates().toArray(); int count = 0; long pickedDate = datePicker.getDate().atStartOfDay().toEpochSecond(ZoneOffset.UTC) * 1000; @@ -82,6 +85,37 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { count )); } + + /** + * Exception type thrown when there is an error completing an auto ingest + * metrics dialog operation. + */ + static final class AutoIngestMetricsDialogException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructs an instance of the exception type thrown when there is an + * error completing an auto ingest metrics dialog operation. + * + * @param message The exception message. + */ + private AutoIngestMetricsDialogException(String message) { + super(message); + } + + /** + * Constructs an instance of the exception type thrown when there is an + * error completing an auto ingest metrics dialog operation. + * + * @param message The exception message. + * @param cause A Throwable cause for the error. + */ + private AutoIngestMetricsDialogException(String message, Throwable cause) { + super(message, cause); + } + + } /** * This method is called from within the constructor to initialize the form. @@ -175,4 +209,4 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog { private javax.swing.JButton metricsButton; private javax.swing.JTextArea reportTextArea; // End of variables declaration//GEN-END:variables -} +} \ No newline at end of file diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java index 37c635b9f0..e46a5e43c0 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java @@ -23,12 +23,10 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Observable; import java.util.Set; -import java.util.TreeSet; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -282,71 +280,6 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen } } - /** - * Gets a new metrics snapshot from the coordination service for an auto - * ingest cluster. - * - * @return The metrics snapshot. - */ - private MetricsSnapshot queryCoordinationServiceForMetrics() { - try { - MetricsSnapshot newMetricsSnapshot = new MetricsSnapshot(); - List nodeList = coordinationService.getNodeList(CoordinationService.CategoryNode.MANIFESTS); - for (String node : nodeList) { - try { - AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, node)); - if (nodeData.getVersion() < 1) { - /* - * Ignore version '0' nodes that have not been - * "upgraded" since they don't carry enough data. - */ - continue; - } - AutoIngestJob job = new AutoIngestJob(nodeData); - ProcessingStatus processingStatus = nodeData.getProcessingStatus(); - switch (processingStatus) { - case PENDING: - case PROCESSING: - case DELETED: - /* - * These are not jobs we care about for metrics, so - * we will ignore them. - */ - break; - case COMPLETED: - newMetricsSnapshot.addCompletedJobDate(job.getCompletedDate()); - break; - default: - LOGGER.log(Level.SEVERE, "Unknown AutoIngestJobData.ProcessingStatus"); - break; - } - } catch (InterruptedException ex) { - LOGGER.log(Level.SEVERE, String.format("Unexpected interrupt while retrieving coordination service node data for '%s'", node), ex); - } catch (AutoIngestJobNodeData.InvalidDataException ex) { - LOGGER.log(Level.SEVERE, String.format("Unable to use node data for '%s'", node), ex); - } catch (AutoIngestJob.AutoIngestJobException ex) { - LOGGER.log(Level.SEVERE, String.format("Failed to create a job for '%s'", node), ex); - } - } - - return newMetricsSnapshot; - - } catch (CoordinationServiceException ex) { - LOGGER.log(Level.SEVERE, "Failed to get node list from coordination service", ex); - return new MetricsSnapshot(); - } - } - - /** - * Gets a new metrics snapshot. The jobs snapshot will also be updated in - * effect. - * - * @return The metrics snapshot. - */ - public MetricsSnapshot getMetricsSnapshot() { - return queryCoordinationServiceForMetrics(); - } - /** * Bumps the priority of all pending ingest jobs for a specified case. * @@ -593,32 +526,6 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen } - /** - * A snapshot of metrics for an auto ingest cluster. - */ - public static final class MetricsSnapshot { - - private final List completedJobDates = new ArrayList<>(); - - /** - * Gets a list of completed job dates, formatted in milliseconds. - * - * @return The completed job dates, formatted in milliseconds. - */ - List getCompletedJobDates() { - return new ArrayList<>(completedJobDates); - } - - /** - * Adds a new date to the list of completed job dates. - * - * @param date The date to be added. - */ - void addCompletedJobDate(Date date) { - completedJobDates.add(date.getTime()); - } - } - /** * Exception type thrown when there is an error completing an auto ingest * monitor operation. @@ -649,4 +556,4 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen } } -} +} \ No newline at end of file