mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 01:07:42 +00:00
Merge pull request #795 from rcordovano/snapshots_improvements
Snapshots improvements
This commit is contained in:
commit
b3d1f71a65
@ -20,8 +20,6 @@ package org.sleuthkit.autopsy.actions;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import org.openide.awt.ActionID;
|
||||
import org.openide.awt.ActionReference;
|
||||
import org.openide.awt.ActionRegistration;
|
||||
@ -29,7 +27,6 @@ import org.openide.util.HelpCtx;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.util.actions.SystemAction;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
|
||||
|
||||
@ActionID(
|
||||
@ -46,16 +43,6 @@ public final class ShowIngestProgressSnapshotAction extends SystemAction impleme
|
||||
|
||||
private static final String ACTION_NAME = NbBundle.getMessage(ShowIngestProgressSnapshotAction.class, "ShowIngestProgressSnapshotAction.actionName.text");
|
||||
|
||||
public ShowIngestProgressSnapshotAction() {
|
||||
setEnabled(false);
|
||||
IngestManager.getInstance().addIngestJobEventListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
setEnabled(IngestManager.getInstance().isIngestRunning());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
IngestProgressSnapshotDialog dialog = new IngestProgressSnapshotDialog();
|
||||
|
@ -68,12 +68,14 @@ IngestJobConfigurator.createModuleSettingsFolderForContext.exception.title=Inges
|
||||
IngestJobConfigurator.saveJobSettings.usermsg=Failed to save ingest job settings for {0} module.
|
||||
IngestJobConfigurator.saveJobSettings.usermsg.title=Ingest Job Settings
|
||||
IngestJobConfigurationPanel.descriptionLabel.text=
|
||||
IngestProgressSnapshotDialog.title.text=Ingest Task Progress Snapshots
|
||||
IngestProgressSnapshotDialog.title.text=Ingest Progress Snapshot
|
||||
IngestProgressSnapshotPanel.refreshButton.text=Refresh
|
||||
IngestProgressSnapshotPanel.closeButton.text=Close
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.threadID=Thread ID
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.dataSource=Data Source
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.ingestModule=Ingest Module
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity=Activity
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.file=File
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.startTime=Start Time
|
||||
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.elapsedTime=Elapsed Time (H\:M\:S)
|
||||
IngestProgressSnapshotPanel.fileProcessedPerSecondLabel.text=Files/Sec: {0}
|
||||
IngestManager.IngestThreadActivitySnapshot.idleThread=IDLE
|
||||
|
@ -32,6 +32,7 @@ import org.sleuthkit.datamodel.Content;
|
||||
*/
|
||||
final class DataSourceIngestPipeline {
|
||||
|
||||
private static final IngestManager ingestManager = IngestManager.getInstance();
|
||||
private final IngestJobContext context;
|
||||
private List<DataSourceIngestModuleDecorator> modules = new ArrayList<>();
|
||||
|
||||
@ -90,7 +91,7 @@ final class DataSourceIngestPipeline {
|
||||
progress.setDisplayName(NbBundle.getMessage(this.getClass(),
|
||||
"IngestJob.progress.dataSourceIngest.displayName",
|
||||
module.getDisplayName(), dataSource.getName()));
|
||||
task.updateProgressStatus(module.getDisplayName(), null);
|
||||
ingestManager.setIngestTaskProgress(task, module.getDisplayName());
|
||||
module.process(dataSource, new DataSourceIngestModuleProgress(progress));
|
||||
} catch (Exception ex) { // Catch-all exception firewall
|
||||
errors.add(new IngestModuleError(module.getDisplayName(), ex));
|
||||
@ -99,6 +100,7 @@ final class DataSourceIngestPipeline {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ingestManager.setIngestTaskProgressCompleted(task);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
@ -18,21 +18,15 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
final class DataSourceIngestTask extends IngestTask {
|
||||
|
||||
DataSourceIngestTask(IngestJob job, ProgressSnapshots snapshots) {
|
||||
super(job, snapshots);
|
||||
}
|
||||
|
||||
Content getDataSource() {
|
||||
return getIngestJob().getDataSource();
|
||||
DataSourceIngestTask(IngestJob job) {
|
||||
super(job);
|
||||
}
|
||||
|
||||
@Override
|
||||
void execute(long threadId) throws InterruptedException {
|
||||
super.execute(threadId);
|
||||
super.setThreadId(threadId);
|
||||
getIngestJob().process(this);
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,9 @@ import org.sleuthkit.datamodel.AbstractFile;
|
||||
*/
|
||||
final class FileIngestPipeline {
|
||||
|
||||
private static final IngestManager ingestManager = IngestManager.getInstance();
|
||||
private final IngestJobContext context;
|
||||
private List<FileIngestModuleDecorator> modules = new ArrayList<>();
|
||||
private final List<FileIngestModuleDecorator> modules = new ArrayList<>();
|
||||
|
||||
FileIngestPipeline(IngestJobContext context, List<IngestModuleTemplate> moduleTemplates) {
|
||||
this.context = context;
|
||||
@ -96,7 +97,7 @@ final class FileIngestPipeline {
|
||||
AbstractFile file = task.getFile();
|
||||
for (FileIngestModuleDecorator module : modules) {
|
||||
try {
|
||||
task.updateProgressStatus(module.getDisplayName(), file);
|
||||
ingestManager.setIngestTaskProgress(task, module.getDisplayName());
|
||||
module.process(file);
|
||||
} catch (Exception ex) { // Catch-all exception firewall
|
||||
errors.add(new IngestModuleError(module.getDisplayName(), ex));
|
||||
@ -109,6 +110,7 @@ final class FileIngestPipeline {
|
||||
if (!context.isJobCancelled()) {
|
||||
IngestManager.getInstance().fireFileIngestDone(file.getId());
|
||||
}
|
||||
ingestManager.setIngestTaskProgressCompleted(task);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,8 @@ final class FileIngestTask extends IngestTask {
|
||||
|
||||
private final AbstractFile file;
|
||||
|
||||
FileIngestTask(IngestJob job, AbstractFile file, ProgressSnapshots snapshots) {
|
||||
super(job, snapshots);
|
||||
FileIngestTask(IngestJob job, AbstractFile file) {
|
||||
super(job);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ final class FileIngestTask extends IngestTask {
|
||||
|
||||
@Override
|
||||
void execute(long threadId) throws InterruptedException {
|
||||
super.execute(threadId);
|
||||
super.setThreadId(threadId);
|
||||
getIngestJob().process(this);
|
||||
}
|
||||
|
||||
|
@ -180,10 +180,7 @@ final class IngestJob {
|
||||
* @return True or false.
|
||||
*/
|
||||
boolean hasDataSourceIngestPipeline() {
|
||||
if (dataSourceIngestPipeline.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (dataSourceIngestPipeline.isEmpty() == false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,10 +189,7 @@ final class IngestJob {
|
||||
* @return True or false.
|
||||
*/
|
||||
boolean hasFileIngestPipeline() {
|
||||
if (fileIngestPipelines.peek().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (fileIngestPipelines.peek().isEmpty() == false);
|
||||
}
|
||||
|
||||
void process(DataSourceIngestTask task) throws InterruptedException {
|
||||
@ -206,7 +200,7 @@ final class IngestJob {
|
||||
logIngestModuleErrors(errors);
|
||||
}
|
||||
}
|
||||
if (dataSourceIngestProgress != null) {
|
||||
if (null != dataSourceIngestProgress) {
|
||||
dataSourceIngestProgress.finish();
|
||||
// This is safe because this method will be called at most once per
|
||||
// ingest job and finish() will not be called while that single
|
||||
|
@ -21,6 +21,8 @@ package org.sleuthkit.autopsy.ingest;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -40,6 +42,7 @@ import org.sleuthkit.datamodel.Content;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* Manages the execution of ingest jobs.
|
||||
@ -63,13 +66,16 @@ public class IngestManager {
|
||||
private final ConcurrentHashMap<Long, Future<Void>> startIngestJobThreads = new ConcurrentHashMap<>(); // Maps thread ids to cancellation handles.
|
||||
private final ConcurrentHashMap<Long, Future<?>> dataSourceIngestThreads = new ConcurrentHashMap<>(); // Maps thread ids to cancellation handles.
|
||||
private final ConcurrentHashMap<Long, Future<?>> fileIngestThreads = new ConcurrentHashMap<>(); // Maps thread ids to cancellation handles.
|
||||
private final ConcurrentHashMap<Long, IngestThreadActivitySnapshot> ingestThreadActivitySnapshots = new ConcurrentHashMap<>(); // Maps ingest thread ids to progress ingestThreadActivitySnapshots.
|
||||
private final Object processedFilesSnapshotLock = new Object();
|
||||
private ProcessedFilesSnapshot processedFilesSnapshot = new ProcessedFilesSnapshot();
|
||||
private volatile IngestMessageTopComponent ingestMessageBox;
|
||||
private int numberOfFileIngestThreads = DEFAULT_NUMBER_OF_FILE_INGEST_THREADS;
|
||||
|
||||
/**
|
||||
* Gets the ingest manager.
|
||||
*
|
||||
* @returns A singleton IngestManager object.
|
||||
* @return A singleton IngestManager object.
|
||||
*/
|
||||
public synchronized static IngestManager getInstance() {
|
||||
if (instance == null) {
|
||||
@ -113,14 +119,17 @@ public class IngestManager {
|
||||
/**
|
||||
* Gets the number of data source ingest threads the ingest manager will
|
||||
* use.
|
||||
*
|
||||
* @return The number of data source ingest threads.
|
||||
*/
|
||||
public int getNumberOfDataSourceIngestThreads() {
|
||||
return DEFAULT_NUMBER_OF_DATA_SOURCE_INGEST_THREADS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum number of file ingest threads the ingest manager will
|
||||
* use.
|
||||
* Gets the number of file ingest threads the ingest manager will use.
|
||||
*
|
||||
* @return The number of file ingest threads.
|
||||
*/
|
||||
public int getNumberOfFileIngestThreads() {
|
||||
return numberOfFileIngestThreads;
|
||||
@ -134,6 +143,7 @@ public class IngestManager {
|
||||
long threadId = nextThreadId.incrementAndGet();
|
||||
Future<?> handle = dataSourceIngestThreadPool.submit(new ExecuteIngestTasksThread(threadId, IngestScheduler.getInstance().getDataSourceIngestTaskQueue()));
|
||||
dataSourceIngestThreads.put(threadId, handle);
|
||||
ingestThreadActivitySnapshots.put(threadId, new IngestThreadActivitySnapshot(threadId));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,6 +154,7 @@ public class IngestManager {
|
||||
long threadId = nextThreadId.incrementAndGet();
|
||||
Future<?> handle = fileIngestThreadPool.submit(new ExecuteIngestTasksThread(threadId, IngestScheduler.getInstance().getFileIngestTaskQueue()));
|
||||
fileIngestThreads.put(threadId, handle);
|
||||
ingestThreadActivitySnapshots.put(threadId, new IngestThreadActivitySnapshot(threadId));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,8 +214,36 @@ public class IngestManager {
|
||||
return IngestScheduler.getInstance().ingestJobsAreRunning();
|
||||
}
|
||||
|
||||
List<IngestTask.ProgressSnapshot> getIngestTaskProgressSnapshots() {
|
||||
return IngestScheduler.getInstance().getIngestTaskProgressSnapshots();
|
||||
void setIngestTaskProgress(DataSourceIngestTask task, String ingestModuleDisplayName) {
|
||||
ingestThreadActivitySnapshots.put(task.getThreadId(), new IngestThreadActivitySnapshot(task.getThreadId(), ingestModuleDisplayName, task.getDataSource()));
|
||||
}
|
||||
|
||||
void setIngestTaskProgress(FileIngestTask task, String ingestModuleDisplayName) {
|
||||
ingestThreadActivitySnapshots.put(task.getThreadId(), new IngestThreadActivitySnapshot(task.getThreadId(), ingestModuleDisplayName, task.getDataSource(), task.getFile()));
|
||||
}
|
||||
|
||||
void setIngestTaskProgressCompleted(DataSourceIngestTask task) {
|
||||
ingestThreadActivitySnapshots.put(task.getThreadId(), new IngestThreadActivitySnapshot(task.getThreadId()));
|
||||
}
|
||||
|
||||
void setIngestTaskProgressCompleted(FileIngestTask task) {
|
||||
ingestThreadActivitySnapshots.put(task.getThreadId(), new IngestThreadActivitySnapshot(task.getThreadId()));
|
||||
synchronized (processedFilesSnapshotLock) {
|
||||
processedFilesSnapshot.incrementProcessedFilesCount();
|
||||
}
|
||||
}
|
||||
|
||||
List<IngestThreadActivitySnapshot> getIngestThreadActivitySnapshots() {
|
||||
return new ArrayList(ingestThreadActivitySnapshots.values());
|
||||
}
|
||||
|
||||
ProcessedFilesSnapshot getProcessedFilesSnapshot() {
|
||||
ProcessedFilesSnapshot snapshot;
|
||||
synchronized (processedFilesSnapshotLock) {
|
||||
snapshot = processedFilesSnapshot;
|
||||
processedFilesSnapshot = new ProcessedFilesSnapshot();
|
||||
}
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
public void cancelAllIngestJobs() {
|
||||
@ -494,7 +533,7 @@ public class IngestManager {
|
||||
notifyMessage.append("\n\n");
|
||||
JOptionPane.showMessageDialog(null, notifyMessage.toString(),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle"), JOptionPane.ERROR_MESSAGE);
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
progress.progress(++dataSourceProcessed);
|
||||
|
||||
@ -502,11 +541,14 @@ public class IngestManager {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
// Reset interrupted status.
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
progress.finish();
|
||||
startIngestJobThreads.remove(threadId);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -578,4 +620,80 @@ public class IngestManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class IngestThreadActivitySnapshot {
|
||||
|
||||
private final long threadId;
|
||||
private final Date startTime;
|
||||
private final String activity;
|
||||
private final String dataSourceName;
|
||||
private final String fileName;
|
||||
|
||||
IngestThreadActivitySnapshot(long threadId) {
|
||||
this.threadId = threadId;
|
||||
startTime = new Date();
|
||||
this.activity = NbBundle.getMessage(this.getClass(), "IngestManager.IngestThreadActivitySnapshot.idleThread");
|
||||
this.dataSourceName = "";
|
||||
this.fileName = "";
|
||||
}
|
||||
|
||||
IngestThreadActivitySnapshot(long threadId, String activity, Content dataSource) {
|
||||
this.threadId = threadId;
|
||||
startTime = new Date();
|
||||
this.activity = activity;
|
||||
this.dataSourceName = dataSource.getName();
|
||||
this.fileName = "";
|
||||
}
|
||||
|
||||
IngestThreadActivitySnapshot(long threadId, String activity, Content dataSource, AbstractFile file) {
|
||||
this.threadId = threadId;
|
||||
startTime = new Date();
|
||||
this.activity = activity;
|
||||
this.dataSourceName = dataSource.getName();
|
||||
this.fileName = file.getName();
|
||||
}
|
||||
|
||||
long getThreadId() {
|
||||
return threadId;
|
||||
}
|
||||
|
||||
Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
String getActivity() {
|
||||
return activity;
|
||||
}
|
||||
|
||||
String getDataSourceName() {
|
||||
return dataSourceName;
|
||||
}
|
||||
|
||||
String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
|
||||
static final class ProcessedFilesSnapshot {
|
||||
|
||||
private final Date startTime;
|
||||
private long processedFilesCount;
|
||||
|
||||
ProcessedFilesSnapshot() {
|
||||
this.startTime = new Date();
|
||||
this.processedFilesCount = 0;
|
||||
}
|
||||
|
||||
void incrementProcessedFilesCount() {
|
||||
++processedFilesCount;
|
||||
}
|
||||
|
||||
Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
long getProcessedFilesCount() {
|
||||
return processedFilesCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,10 @@
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="snapshotsScrollPane" max="32767" attributes="0"/>
|
||||
<Component id="snapshotsScrollPane" pref="881" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="0" pref="733" max="32767" attributes="0"/>
|
||||
<Component id="fileProcessedPerSecondLabel" min="-2" pref="173" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="refreshButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="closeButton" linkSize="1" min="-2" max="-2" attributes="0"/>
|
||||
@ -40,6 +41,7 @@
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="refreshButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="closeButton" linkSize="2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="fileProcessedPerSecondLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -54,7 +56,7 @@
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="snapshotsTable">
|
||||
<Component class="javax.swing.JTable" name="threadActivitySnapshotsTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="0" rowCount="0"/>
|
||||
@ -89,5 +91,12 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="closeButtonActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="fileProcessedPerSecondLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestProgressSnapshotPanel.fileProcessedPerSecondLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -18,8 +18,6 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.swing.JDialog;
|
||||
@ -27,47 +25,40 @@ import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableColumn;
|
||||
import org.apache.commons.lang3.time.DurationFormatUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
|
||||
private final JDialog parent;
|
||||
private final SnapshotsTableModel tableModel;
|
||||
private final IngestThreadActivitySnapshotsTableModel threadActivityTableModel;
|
||||
|
||||
IngestProgressSnapshotPanel(JDialog parent) {
|
||||
this.parent = parent;
|
||||
tableModel = new SnapshotsTableModel();
|
||||
threadActivityTableModel = new IngestThreadActivitySnapshotsTableModel();
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
IngestManager.getInstance().addIngestJobEventListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
refreshButton.setEnabled(IngestManager.getInstance().isIngestRunning() == true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void customizeComponents() {
|
||||
snapshotsTable.setModel(tableModel);
|
||||
threadActivitySnapshotsTable.setModel(threadActivityTableModel);
|
||||
|
||||
int width = snapshotsScrollPane.getPreferredSize().width;
|
||||
for (int i = 0; i < snapshotsTable.getColumnCount(); ++i) {
|
||||
TableColumn column = snapshotsTable.getColumnModel().getColumn(i);
|
||||
for (int i = 0; i < threadActivitySnapshotsTable.getColumnCount(); ++i) {
|
||||
TableColumn column = threadActivitySnapshotsTable.getColumnModel().getColumn(i);
|
||||
switch (i) {
|
||||
case 0:
|
||||
column.setPreferredWidth(((int) (width * 0.05)));
|
||||
column.setPreferredWidth(((int) (width * 0.02)));
|
||||
break;
|
||||
case 1:
|
||||
column.setPreferredWidth(((int) (width * 0.15)));
|
||||
column.setPreferredWidth(((int) (width * 0.20)));
|
||||
break;
|
||||
case 2:
|
||||
column.setPreferredWidth(((int) (width * 0.25)));
|
||||
column.setPreferredWidth(((int) (width * 0.15)));
|
||||
break;
|
||||
case 3:
|
||||
column.setPreferredWidth(((int) (width * 0.35)));
|
||||
break;
|
||||
case 4:
|
||||
column.setPreferredWidth(((int) (width * 0.10)));
|
||||
column.setPreferredWidth(((int) (width * 0.18)));
|
||||
break;
|
||||
case 5:
|
||||
column.setPreferredWidth(((int) (width * 0.10)));
|
||||
@ -75,31 +66,34 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
snapshotsTable.setFillsViewportHeight(true);
|
||||
threadActivitySnapshotsTable.setFillsViewportHeight(true);
|
||||
|
||||
fileProcessedPerSecondLabel.setText(NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.fileProcessedPerSecondLabel.text", 0));
|
||||
}
|
||||
|
||||
private class SnapshotsTableModel extends AbstractTableModel {
|
||||
private class IngestThreadActivitySnapshotsTableModel extends AbstractTableModel {
|
||||
|
||||
private final String[] columnNames = {NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.threadID"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.dataSource"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.ingestModule"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.file"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.startTime"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.elapsedTime")};
|
||||
private List<IngestTask.ProgressSnapshot> snapshots;
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.threadID"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.dataSource"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.file"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.startTime"),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.elapsedTime")};
|
||||
private List<IngestManager.IngestThreadActivitySnapshot> snapshots;
|
||||
|
||||
private SnapshotsTableModel() {
|
||||
private IngestThreadActivitySnapshotsTableModel() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
snapshots = IngestManager.getInstance().getIngestTaskProgressSnapshots();
|
||||
snapshots = IngestManager.getInstance().getIngestThreadActivitySnapshots();
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
@ -120,25 +114,20 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
IngestTask.ProgressSnapshot snapshot = snapshots.get(rowIndex);
|
||||
IngestManager.IngestThreadActivitySnapshot snapshot = snapshots.get(rowIndex);
|
||||
Object cellValue;
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
cellValue = snapshot.getThreadId();
|
||||
break;
|
||||
case 1:
|
||||
cellValue = snapshot.getDataSource().getName();
|
||||
cellValue = snapshot.getActivity();
|
||||
break;
|
||||
case 2:
|
||||
cellValue = snapshot.getModuleDisplayName();
|
||||
cellValue = snapshot.getDataSourceName();
|
||||
break;
|
||||
case 3:
|
||||
AbstractFile file = snapshot.getFile();
|
||||
if (file != null) {
|
||||
cellValue = file.getName();
|
||||
} else {
|
||||
cellValue = "";
|
||||
}
|
||||
cellValue = snapshot.getFileName();
|
||||
break;
|
||||
case 4:
|
||||
cellValue = snapshot.getStartTime();
|
||||
@ -147,9 +136,6 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
Date now = new Date();
|
||||
long elapsedTime = now.getTime() - snapshot.getStartTime().getTime();
|
||||
cellValue = DurationFormatUtils.formatDurationHMS(elapsedTime);
|
||||
// TODO: Restore when we go to Java 8
|
||||
// long elapsedTime = Duration.between(snapshot.getStartTime(), LocalTime.now()).toMillis();
|
||||
// cellValue = DurationFormatUtils.formatDurationHMS(elapsedTime);
|
||||
break;
|
||||
default:
|
||||
cellValue = null;
|
||||
@ -169,11 +155,12 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
private void initComponents() {
|
||||
|
||||
snapshotsScrollPane = new javax.swing.JScrollPane();
|
||||
snapshotsTable = new javax.swing.JTable();
|
||||
threadActivitySnapshotsTable = new javax.swing.JTable();
|
||||
refreshButton = new javax.swing.JButton();
|
||||
closeButton = new javax.swing.JButton();
|
||||
fileProcessedPerSecondLabel = new javax.swing.JLabel();
|
||||
|
||||
snapshotsTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
threadActivitySnapshotsTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
new Object [][] {
|
||||
|
||||
},
|
||||
@ -181,7 +168,7 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
|
||||
}
|
||||
));
|
||||
snapshotsScrollPane.setViewportView(snapshotsTable);
|
||||
snapshotsScrollPane.setViewportView(threadActivitySnapshotsTable);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(refreshButton, org.openide.util.NbBundle.getMessage(IngestProgressSnapshotPanel.class, "IngestProgressSnapshotPanel.refreshButton.text")); // NOI18N
|
||||
refreshButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@ -197,6 +184,8 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(fileProcessedPerSecondLabel, org.openide.util.NbBundle.getMessage(IngestProgressSnapshotPanel.class, "IngestProgressSnapshotPanel.fileProcessedPerSecondLabel.text")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
@ -204,9 +193,10 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(snapshotsScrollPane)
|
||||
.addComponent(snapshotsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 881, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGap(0, 733, Short.MAX_VALUE)
|
||||
.addComponent(fileProcessedPerSecondLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(refreshButton)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(closeButton)))
|
||||
@ -223,7 +213,8 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(refreshButton)
|
||||
.addComponent(closeButton))
|
||||
.addComponent(closeButton)
|
||||
.addComponent(fileProcessedPerSecondLabel))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
@ -236,14 +227,19 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
}//GEN-LAST:event_closeButtonActionPerformed
|
||||
|
||||
private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
|
||||
if (IngestManager.getInstance().isIngestRunning() == true) {
|
||||
tableModel.refresh();
|
||||
}
|
||||
threadActivityTableModel.refresh();
|
||||
IngestManager.ProcessedFilesSnapshot snapshot = IngestManager.getInstance().getProcessedFilesSnapshot();
|
||||
Date now = new Date();
|
||||
long elapsedTime = now.getTime() - snapshot.getStartTime().getTime();
|
||||
double filesPerSecond = (double) snapshot.getProcessedFilesCount() / (double) elapsedTime * 1000.0;
|
||||
fileProcessedPerSecondLabel.setText(NbBundle.getMessage(this.getClass(),
|
||||
"IngestProgressSnapshotPanel.fileProcessedPerSecondLabel.text", filesPerSecond));
|
||||
}//GEN-LAST:event_refreshButtonActionPerformed
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton closeButton;
|
||||
private javax.swing.JLabel fileProcessedPerSecondLabel;
|
||||
private javax.swing.JButton refreshButton;
|
||||
private javax.swing.JScrollPane snapshotsScrollPane;
|
||||
private javax.swing.JTable snapshotsTable;
|
||||
private javax.swing.JTable threadActivitySnapshotsTable;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ final class IngestScheduler {
|
||||
// private volatile boolean cancellingAllTasks = false; TODO: Uncomment this with related code, if desired
|
||||
private final DataSourceIngestTaskQueue dataSourceTaskDispenser = new DataSourceIngestTaskQueue();
|
||||
private final FileIngestTaskQueue fileTaskDispenser = new FileIngestTaskQueue();
|
||||
private final IngestTask.ProgressSnapshots taskProgressSnapShots = new IngestTask.ProgressSnapshots();
|
||||
// The following five collections lie at the heart of the scheduler.
|
||||
//
|
||||
// The pending tasks queues are used to schedule tasks for an ingest job. If
|
||||
@ -132,7 +131,7 @@ final class IngestScheduler {
|
||||
}
|
||||
|
||||
synchronized private void scheduleDataSourceIngestTask(IngestJob job) throws InterruptedException {
|
||||
DataSourceIngestTask task = new DataSourceIngestTask(job, taskProgressSnapShots);
|
||||
DataSourceIngestTask task = new DataSourceIngestTask(job);
|
||||
tasksInProgress.add(task);
|
||||
try {
|
||||
// Should not block, queue is (theoretically) unbounded.
|
||||
@ -147,7 +146,7 @@ final class IngestScheduler {
|
||||
synchronized private void scheduleFileIngestTasks(IngestJob job) throws InterruptedException {
|
||||
List<AbstractFile> topLevelFiles = getTopLevelFiles(job.getDataSource());
|
||||
for (AbstractFile firstLevelFile : topLevelFiles) {
|
||||
FileIngestTask task = new FileIngestTask(job, firstLevelFile, taskProgressSnapShots);
|
||||
FileIngestTask task = new FileIngestTask(job, firstLevelFile);
|
||||
if (shouldEnqueueFileTask(task)) {
|
||||
tasksInProgress.add(task);
|
||||
pendingRootDirectoryTasks.add(task);
|
||||
@ -223,7 +222,7 @@ final class IngestScheduler {
|
||||
for (Content child : directory.getChildren()) {
|
||||
if (child instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) child;
|
||||
FileIngestTask childTask = new FileIngestTask(directoryTask.getIngestJob(), file, taskProgressSnapShots);
|
||||
FileIngestTask childTask = new FileIngestTask(directoryTask.getIngestJob(), file);
|
||||
if (file.hasChildren()) {
|
||||
// Found a subdirectory, put the task in the
|
||||
// pending directory tasks queue.
|
||||
@ -321,7 +320,7 @@ final class IngestScheduler {
|
||||
|
||||
void scheduleAdditionalFileIngestTask(IngestJob job, AbstractFile file) throws InterruptedException {
|
||||
if (enabled) {
|
||||
FileIngestTask task = new FileIngestTask(job, file, taskProgressSnapShots);
|
||||
FileIngestTask task = new FileIngestTask(job, file);
|
||||
if (shouldEnqueueFileTask(task)) {
|
||||
// Send the file task directly to file tasks queue, no need to
|
||||
// update the pending root directory or pending directory tasks
|
||||
@ -365,10 +364,6 @@ final class IngestScheduler {
|
||||
return !ingestJobsById.isEmpty();
|
||||
}
|
||||
|
||||
List<IngestTask.ProgressSnapshot> getIngestTaskProgressSnapshots() {
|
||||
return taskProgressSnapShots.getSnapshots();
|
||||
}
|
||||
|
||||
synchronized void cancelIngestJob(IngestJob job) {
|
||||
long jobId = job.getId();
|
||||
removeAllPendingTasksForJob(pendingRootDirectoryTasks, jobId);
|
||||
|
@ -18,91 +18,34 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
class IngestTask {
|
||||
abstract class IngestTask {
|
||||
|
||||
private final static long NOT_SET = Long.MIN_VALUE;
|
||||
private final IngestJob job;
|
||||
private final ProgressSnapshots snapshots;
|
||||
private long threadId;
|
||||
|
||||
IngestTask(IngestJob job, ProgressSnapshots snapshots) {
|
||||
IngestTask(IngestJob job) {
|
||||
this.job = job;
|
||||
this.snapshots = snapshots;
|
||||
threadId = NOT_SET;
|
||||
}
|
||||
|
||||
IngestJob getIngestJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
void updateProgressStatus(String ingestModuleDisplayName, AbstractFile file) {
|
||||
snapshots.update(new ProgressSnapshot(threadId, job.getDataSource(), ingestModuleDisplayName, file));
|
||||
Content getDataSource() {
|
||||
return getIngestJob().getDataSource();
|
||||
}
|
||||
|
||||
void execute(long threadId) throws InterruptedException {
|
||||
long getThreadId() {
|
||||
return threadId;
|
||||
}
|
||||
|
||||
void setThreadId(long threadId) {
|
||||
this.threadId = threadId;
|
||||
}
|
||||
|
||||
public static final class ProgressSnapshot {
|
||||
|
||||
private final long threadId;
|
||||
private final Content dataSource;
|
||||
private final String ingestModuleDisplayName;
|
||||
private final AbstractFile file;
|
||||
private final Date startTime;
|
||||
// TODO: Restore when we go to Java 8
|
||||
// private final LocalTime startTime;
|
||||
|
||||
private ProgressSnapshot(long threadId, Content dataSource, String ingestModuleDisplayName, AbstractFile file) {
|
||||
this.threadId = threadId;
|
||||
this.dataSource = dataSource;
|
||||
this.ingestModuleDisplayName = ingestModuleDisplayName;
|
||||
this.file = file;
|
||||
startTime = new Date();
|
||||
// TODO: Restore when we go to Java 8
|
||||
// startTime = LocalTime.now();
|
||||
}
|
||||
|
||||
long getThreadId() {
|
||||
return threadId;
|
||||
}
|
||||
|
||||
Content getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
String getModuleDisplayName() {
|
||||
return ingestModuleDisplayName;
|
||||
}
|
||||
|
||||
AbstractFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
// TODO: Restore when we go to Java 8
|
||||
// LocalTime getStartTime() {
|
||||
// return startTime;
|
||||
// }
|
||||
}
|
||||
|
||||
static final class ProgressSnapshots {
|
||||
|
||||
private final ConcurrentHashMap<Long, IngestTask.ProgressSnapshot> snapshots = new ConcurrentHashMap<>(); // Maps ingest thread ids to progress snapshots.
|
||||
|
||||
void update(ProgressSnapshot snapshot) {
|
||||
snapshots.put(snapshot.getThreadId(), snapshot);
|
||||
}
|
||||
|
||||
List<ProgressSnapshot> getSnapshots() {
|
||||
return new ArrayList(snapshots.values());
|
||||
}
|
||||
}
|
||||
abstract void execute(long threadId) throws InterruptedException;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user