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