mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge pull request #3777 from esaunders/3734_ingest_progress
Add ingest progress snapshot support to AID
This commit is contained in:
commit
03764f0891
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.ingest;
|
package org.sleuthkit.autopsy.ingest;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -37,6 +38,9 @@ import org.sleuthkit.autopsy.casemodule.Case;
|
|||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestPipeline.PipelineModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestTasksScheduler.IngestJobTasksSnapshot;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.IngestJobInfo;
|
import org.sleuthkit.datamodel.IngestJobInfo;
|
||||||
@ -51,7 +55,7 @@ import org.sleuthkit.autopsy.modules.interestingitems.FilesSet;
|
|||||||
* Encapsulates a data source and the ingest module pipelines used to process
|
* Encapsulates a data source and the ingest module pipelines used to process
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
final class DataSourceIngestJob {
|
public final class DataSourceIngestJob {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DataSourceIngestJob.class.getName());
|
private static final Logger logger = Logger.getLogger(DataSourceIngestJob.class.getName());
|
||||||
|
|
||||||
@ -1079,71 +1083,90 @@ final class DataSourceIngestJob {
|
|||||||
* @return An ingest job statistics object.
|
* @return An ingest job statistics object.
|
||||||
*/
|
*/
|
||||||
Snapshot getSnapshot(boolean getIngestTasksSnapshot) {
|
Snapshot getSnapshot(boolean getIngestTasksSnapshot) {
|
||||||
return new Snapshot(getIngestTasksSnapshot);
|
/**
|
||||||
|
* Determine whether file ingest is running at the time of this snapshot
|
||||||
|
* and determine the earliest file ingest level pipeline start time, if
|
||||||
|
* file ingest was started at all.
|
||||||
|
*/
|
||||||
|
boolean fileIngestRunning = false;
|
||||||
|
Date fileIngestStartTime = null;
|
||||||
|
|
||||||
|
for (FileIngestPipeline pipeline : this.fileIngestPipelines) {
|
||||||
|
if (pipeline.isRunning()) {
|
||||||
|
fileIngestRunning = true;
|
||||||
|
}
|
||||||
|
Date pipelineStartTime = pipeline.getStartTime();
|
||||||
|
if (null != pipelineStartTime && (null == fileIngestStartTime || pipelineStartTime.before(fileIngestStartTime))) {
|
||||||
|
fileIngestStartTime = pipelineStartTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long processedFilesCount = 0;
|
||||||
|
long estimatedFilesToProcessCount = 0;
|
||||||
|
long snapShotTime = new Date().getTime();
|
||||||
|
IngestJobTasksSnapshot tasksSnapshot = null;
|
||||||
|
|
||||||
|
if (getIngestTasksSnapshot) {
|
||||||
|
synchronized (fileIngestProgressLock) {
|
||||||
|
processedFilesCount = this.processedFiles;
|
||||||
|
estimatedFilesToProcessCount = this.estimatedFilesToProcess;
|
||||||
|
snapShotTime = new Date().getTime();
|
||||||
|
}
|
||||||
|
tasksSnapshot = DataSourceIngestJob.taskScheduler.getTasksSnapshotForJob(id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Snapshot(this.dataSource.getName(), id, createTime,
|
||||||
|
getCurrentDataSourceIngestModule(), fileIngestRunning, fileIngestStartTime,
|
||||||
|
cancelled, cancellationReason, cancelledDataSourceIngestModules,
|
||||||
|
processedFilesCount, estimatedFilesToProcessCount, snapShotTime, tasksSnapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores basic diagnostic statistics for a data source ingest job.
|
* Stores basic diagnostic statistics for a data source ingest job.
|
||||||
*/
|
*/
|
||||||
final class Snapshot {
|
public static final class Snapshot implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final String dataSource;
|
private final String dataSource;
|
||||||
private final long jobId;
|
private final long jobId;
|
||||||
private final long jobStartTime;
|
private final long jobStartTime;
|
||||||
private final long snapShotTime;
|
private final long snapShotTime;
|
||||||
private final DataSourceIngestPipeline.PipelineModule dataSourceLevelIngestModule;
|
transient private final PipelineModule dataSourceLevelIngestModule;
|
||||||
private boolean fileIngestRunning;
|
private final boolean fileIngestRunning;
|
||||||
private Date fileIngestStartTime;
|
private final Date fileIngestStartTime;
|
||||||
private final long processedFiles;
|
private final long processedFiles;
|
||||||
private final long estimatedFilesToProcess;
|
private final long estimatedFilesToProcess;
|
||||||
private final IngestTasksScheduler.IngestJobTasksSnapshot tasksSnapshot;
|
private final IngestJobTasksSnapshot tasksSnapshot;
|
||||||
private final boolean jobCancelled;
|
transient private final boolean jobCancelled;
|
||||||
private final IngestJob.CancellationReason jobCancellationReason;
|
transient private final CancellationReason jobCancellationReason;
|
||||||
private final List<String> cancelledDataSourceModules;
|
transient private final List<String> cancelledDataSourceModules;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an object to store basic diagnostic statistics for a data
|
* Constructs an object to store basic diagnostic statistics for a data
|
||||||
* source ingest job.
|
* source ingest job.
|
||||||
*/
|
*/
|
||||||
Snapshot(boolean getIngestTasksSnapshot) {
|
Snapshot(String dataSourceName, long jobId, long jobStartTime, PipelineModule dataSourceIngestModule,
|
||||||
this.dataSource = DataSourceIngestJob.this.dataSource.getName();
|
boolean fileIngestRunning, Date fileIngestStartTime,
|
||||||
this.jobId = DataSourceIngestJob.this.id;
|
boolean jobCancelled, CancellationReason cancellationReason, List<String> cancelledModules,
|
||||||
this.jobStartTime = DataSourceIngestJob.this.createTime;
|
long processedFiles, long estimatedFilesToProcess,
|
||||||
this.dataSourceLevelIngestModule = DataSourceIngestJob.this.getCurrentDataSourceIngestModule();
|
long snapshotTime, IngestJobTasksSnapshot tasksSnapshot) {
|
||||||
|
this.dataSource = dataSourceName;
|
||||||
|
this.jobId = jobId;
|
||||||
|
this.jobStartTime = jobStartTime;
|
||||||
|
this.dataSourceLevelIngestModule = dataSourceIngestModule;
|
||||||
|
|
||||||
/**
|
this.fileIngestRunning = fileIngestRunning;
|
||||||
* Determine whether file ingest is running at the time of this
|
this.fileIngestStartTime = fileIngestStartTime;
|
||||||
* snapshot and determine the earliest file ingest level pipeline
|
this.jobCancelled = jobCancelled;
|
||||||
* start time, if file ingest was started at all.
|
|
||||||
*/
|
|
||||||
for (FileIngestPipeline pipeline : DataSourceIngestJob.this.fileIngestPipelines) {
|
|
||||||
if (pipeline.isRunning()) {
|
|
||||||
this.fileIngestRunning = true;
|
|
||||||
}
|
|
||||||
Date pipelineStartTime = pipeline.getStartTime();
|
|
||||||
if (null != pipelineStartTime && (null == this.fileIngestStartTime || pipelineStartTime.before(this.fileIngestStartTime))) {
|
|
||||||
this.fileIngestStartTime = pipelineStartTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.jobCancelled = cancelled;
|
|
||||||
this.jobCancellationReason = cancellationReason;
|
this.jobCancellationReason = cancellationReason;
|
||||||
this.cancelledDataSourceModules = new ArrayList<>(DataSourceIngestJob.this.cancelledDataSourceIngestModules);
|
this.cancelledDataSourceModules = cancelledModules;
|
||||||
|
|
||||||
if (getIngestTasksSnapshot) {
|
this.processedFiles = processedFiles;
|
||||||
synchronized (DataSourceIngestJob.this.fileIngestProgressLock) {
|
this.estimatedFilesToProcess = estimatedFilesToProcess;
|
||||||
this.processedFiles = DataSourceIngestJob.this.processedFiles;
|
this.snapShotTime = snapshotTime;
|
||||||
this.estimatedFilesToProcess = DataSourceIngestJob.this.estimatedFilesToProcess;
|
this.tasksSnapshot = tasksSnapshot;
|
||||||
this.snapShotTime = new Date().getTime();
|
|
||||||
}
|
|
||||||
this.tasksSnapshot = DataSourceIngestJob.taskScheduler.getTasksSnapshotForJob(this.jobId);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.processedFiles = 0;
|
|
||||||
this.estimatedFilesToProcess = 0;
|
|
||||||
this.snapShotTime = new Date().getTime();
|
|
||||||
this.tasksSnapshot = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1190,11 +1213,11 @@ final class DataSourceIngestJob {
|
|||||||
return this.dataSourceLevelIngestModule;
|
return this.dataSourceLevelIngestModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean fileIngestIsRunning() {
|
boolean getFileIngestIsRunning() {
|
||||||
return this.fileIngestRunning;
|
return this.fileIngestRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
Date fileIngestStartTime() {
|
Date getFileIngestStartTime() {
|
||||||
return this.fileIngestStartTime;
|
return this.fileIngestStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,10 +355,10 @@ public final class IngestJob {
|
|||||||
dataSourceModule = new DataSourceIngestModuleHandle(dataSourceJobs.get(snapshot.getJobId()), module);
|
dataSourceModule = new DataSourceIngestModuleHandle(dataSourceJobs.get(snapshot.getJobId()), module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (snapshot.fileIngestIsRunning()) {
|
if (snapshot.getFileIngestIsRunning()) {
|
||||||
fileIngestRunning = true;
|
fileIngestRunning = true;
|
||||||
}
|
}
|
||||||
Date childFileIngestStartTime = snapshot.fileIngestStartTime();
|
Date childFileIngestStartTime = snapshot.getFileIngestStartTime();
|
||||||
if (null != childFileIngestStartTime && (null == fileIngestStartTime || childFileIngestStartTime.before(fileIngestStartTime))) {
|
if (null != childFileIngestStartTime && (null == fileIngestStartTime || childFileIngestStartTime.before(fileIngestStartTime))) {
|
||||||
fileIngestStartTime = childFileIngestStartTime;
|
fileIngestStartTime = childFileIngestStartTime;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -107,7 +108,7 @@ import org.sleuthkit.datamodel.Content;
|
|||||||
* job progress, and ingest module run times.
|
* job progress, and ingest module run times.
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
public class IngestManager {
|
public class IngestManager implements IngestProgressSnapshotProvider {
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(IngestManager.class.getName());
|
private final static Logger logger = Logger.getLogger(IngestManager.class.getName());
|
||||||
private final static String INGEST_JOB_EVENT_CHANNEL_NAME = "%s-Ingest-Job-Events"; //NON-NLS
|
private final static String INGEST_JOB_EVENT_CHANNEL_NAME = "%s-Ingest-Job-Events"; //NON-NLS
|
||||||
@ -756,7 +757,8 @@ public class IngestManager {
|
|||||||
*
|
*
|
||||||
* @return Map of module name to run time (in milliseconds)
|
* @return Map of module name to run time (in milliseconds)
|
||||||
*/
|
*/
|
||||||
Map<String, Long> getModuleRunTimes() {
|
@Override
|
||||||
|
public Map<String, Long> getModuleRunTimes() {
|
||||||
synchronized (ingestModuleRunTimes) {
|
synchronized (ingestModuleRunTimes) {
|
||||||
Map<String, Long> times = new HashMap<>(ingestModuleRunTimes);
|
Map<String, Long> times = new HashMap<>(ingestModuleRunTimes);
|
||||||
return times;
|
return times;
|
||||||
@ -769,7 +771,8 @@ public class IngestManager {
|
|||||||
*
|
*
|
||||||
* @return A collection of ingest manager ingest task snapshots.
|
* @return A collection of ingest manager ingest task snapshots.
|
||||||
*/
|
*/
|
||||||
List<IngestThreadActivitySnapshot> getIngestThreadActivitySnapshots() {
|
@Override
|
||||||
|
public List<IngestThreadActivitySnapshot> getIngestThreadActivitySnapshots() {
|
||||||
return new ArrayList<>(ingestThreadActivitySnapshots.values());
|
return new ArrayList<>(ingestThreadActivitySnapshots.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,7 +781,8 @@ public class IngestManager {
|
|||||||
*
|
*
|
||||||
* @return A list of ingest job state snapshots.
|
* @return A list of ingest job state snapshots.
|
||||||
*/
|
*/
|
||||||
List<DataSourceIngestJob.Snapshot> getIngestJobSnapshots() {
|
@Override
|
||||||
|
public List<DataSourceIngestJob.Snapshot> getIngestJobSnapshots() {
|
||||||
List<DataSourceIngestJob.Snapshot> snapShots = new ArrayList<>();
|
List<DataSourceIngestJob.Snapshot> snapShots = new ArrayList<>();
|
||||||
synchronized (ingestJobsById) {
|
synchronized (ingestJobsById) {
|
||||||
ingestJobsById.values().forEach((job) -> {
|
ingestJobsById.values().forEach((job) -> {
|
||||||
@ -916,7 +920,9 @@ public class IngestManager {
|
|||||||
* running in an ingest thread.
|
* running in an ingest thread.
|
||||||
*/
|
*/
|
||||||
@Immutable
|
@Immutable
|
||||||
static final class IngestThreadActivitySnapshot {
|
public static final class IngestThreadActivitySnapshot implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final long threadId;
|
private final long threadId;
|
||||||
private final Date startTime;
|
private final Date startTime;
|
||||||
|
@ -50,12 +50,14 @@ public final class IngestProgressSnapshotDialog extends JDialog {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance of the dialog with its own frame. Could be modal.
|
* Constructs an instance of the dialog with its own frame. Could be modal.
|
||||||
|
* Uses the given provider as the source of data for the dialog.
|
||||||
*
|
*
|
||||||
* @param owner - the owner of this dialog. If this dialog should be
|
* @param owner - the owner of this dialog. If this dialog should be
|
||||||
* modal, the owner gets set to non modal.
|
* modal, the owner gets set to non modal.
|
||||||
* @param shouldBeModal - true if this should be modal, false otherwise.
|
* @param shouldBeModal - true if this should be modal, false otherwise.
|
||||||
|
* @param provider - the provider to use as the source of data.
|
||||||
*/
|
*/
|
||||||
public IngestProgressSnapshotDialog(Container owner, Boolean shouldBeModal) {
|
public IngestProgressSnapshotDialog(Container owner, Boolean shouldBeModal, IngestProgressSnapshotProvider provider) {
|
||||||
super((Window) owner, TITLE, ModalityType.MODELESS);
|
super((Window) owner, TITLE, ModalityType.MODELESS);
|
||||||
if (shouldBeModal && owner instanceof JDialog) { // if called from a modal dialog, manipulate the parent be just under this in z order, and not modal.
|
if (shouldBeModal && owner instanceof JDialog) { // if called from a modal dialog, manipulate the parent be just under this in z order, and not modal.
|
||||||
final JDialog pseudoOwner = (JDialog) owner;
|
final JDialog pseudoOwner = (JDialog) owner;
|
||||||
@ -82,7 +84,7 @@ public final class IngestProgressSnapshotDialog extends JDialog {
|
|||||||
this.getRootPane().registerKeyboardAction(e -> {
|
this.getRootPane().registerKeyboardAction(e -> {
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||||
add(new IngestProgressSnapshotPanel(this));
|
add(new IngestProgressSnapshotPanel(this, provider));
|
||||||
pack();
|
pack();
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
if (shouldBeModal) { // if called from a modal dialog, become modal, otherwise don't.
|
if (shouldBeModal) { // if called from a modal dialog, become modal, otherwise don't.
|
||||||
@ -90,4 +92,17 @@ public final class IngestProgressSnapshotDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of the dialog with its own frame. Could be modal.
|
||||||
|
* Uses the internal IngestManager instance as the source of data for the
|
||||||
|
* dialog
|
||||||
|
*
|
||||||
|
* @param owner - the owner of this dialog. If this dialog should be
|
||||||
|
* modal, the owner gets set to non modal.
|
||||||
|
* @param shouldBeModal - true if this should be modal, false otherwise.
|
||||||
|
*/
|
||||||
|
public IngestProgressSnapshotDialog(Container owner, Boolean shouldBeModal) {
|
||||||
|
this(owner, shouldBeModal, IngestManager.getInstance());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,15 +33,17 @@ import org.openide.util.NbBundle;
|
|||||||
/**
|
/**
|
||||||
* A panel that displays ingest task progress snapshots.
|
* A panel that displays ingest task progress snapshots.
|
||||||
*/
|
*/
|
||||||
public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
private final JDialog parent;
|
private final JDialog parent;
|
||||||
|
private final IngestProgressSnapshotProvider snapshotProvider;
|
||||||
private final IngestThreadActivitySnapshotsTableModel threadActivityTableModel;
|
private final IngestThreadActivitySnapshotsTableModel threadActivityTableModel;
|
||||||
private final IngestJobTableModel jobTableModel;
|
private final IngestJobTableModel jobTableModel;
|
||||||
private final ModuleTableModel moduleTableModel;
|
private final ModuleTableModel moduleTableModel;
|
||||||
|
|
||||||
IngestProgressSnapshotPanel(JDialog parent) {
|
IngestProgressSnapshotPanel(JDialog parent, IngestProgressSnapshotProvider snapshotProvider) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.snapshotProvider = snapshotProvider;
|
||||||
threadActivityTableModel = new IngestThreadActivitySnapshotsTableModel();
|
threadActivityTableModel = new IngestThreadActivitySnapshotsTableModel();
|
||||||
jobTableModel = new IngestJobTableModel();
|
jobTableModel = new IngestJobTableModel();
|
||||||
moduleTableModel = new ModuleTableModel();
|
moduleTableModel = new ModuleTableModel();
|
||||||
@ -105,7 +107,7 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
snapshots = IngestManager.getInstance().getIngestThreadActivitySnapshots();
|
snapshots = snapshotProvider.getIngestThreadActivitySnapshots();
|
||||||
fireTableDataChanged();
|
fireTableDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +189,7 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
jobSnapshots = IngestManager.getInstance().getIngestJobSnapshots();
|
jobSnapshots = snapshotProvider.getIngestJobSnapshots();
|
||||||
fireTableDataChanged();
|
fireTableDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +301,7 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh() {
|
||||||
Map<String, Long> moduleStatMap = IngestManager.getInstance().getModuleRunTimes();
|
Map<String, Long> moduleStatMap = snapshotProvider.getModuleRunTimes();
|
||||||
moduleStats.clear();
|
moduleStats.clear();
|
||||||
totalTime = 0;
|
totalTime = 0;
|
||||||
for (String k : moduleStatMap.keySet()) {
|
for (String k : moduleStatMap.keySet()) {
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.ingest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface that provides a snapshot of ingest progress.
|
||||||
|
*/
|
||||||
|
public interface IngestProgressSnapshotProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a snapshot of the state of ingest threads.
|
||||||
|
*
|
||||||
|
* @return A list of IngestThreadActivitySnapshot
|
||||||
|
*/
|
||||||
|
List<IngestManager.IngestThreadActivitySnapshot> getIngestThreadActivitySnapshots();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a snapshot of the state of ingest jobs.
|
||||||
|
*
|
||||||
|
* @return A list of ingest job snapshots.
|
||||||
|
*/
|
||||||
|
List<DataSourceIngestJob.Snapshot> getIngestJobSnapshots();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cumulative run times for the ingest module.
|
||||||
|
*
|
||||||
|
* @return Map of module name to run time (in milliseconds)
|
||||||
|
*/
|
||||||
|
Map<String, Long> getModuleRunTimes();
|
||||||
|
}
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.ingest;
|
package org.sleuthkit.autopsy.ingest;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -555,7 +556,11 @@ final class IngestTasksScheduler {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
synchronized IngestJobTasksSnapshot getTasksSnapshotForJob(long jobId) {
|
synchronized IngestJobTasksSnapshot getTasksSnapshotForJob(long jobId) {
|
||||||
return new IngestJobTasksSnapshot(jobId);
|
return new IngestJobTasksSnapshot(jobId, this.dataSourceIngestThreadQueue.countQueuedTasksForJob(jobId),
|
||||||
|
countTasksForJob(this.rootFileTaskQueue, jobId),
|
||||||
|
countTasksForJob(this.pendingFileTaskQueue, jobId),
|
||||||
|
this.fileIngestThreadsQueue.countQueuedTasksForJob(jobId),
|
||||||
|
this.dataSourceIngestThreadQueue.countRunningTasksForJob(jobId) + this.fileIngestThreadsQueue.countRunningTasksForJob(jobId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -825,8 +830,9 @@ final class IngestTasksScheduler {
|
|||||||
/**
|
/**
|
||||||
* A snapshot of ingest tasks data for an ingest job.
|
* A snapshot of ingest tasks data for an ingest job.
|
||||||
*/
|
*/
|
||||||
class IngestJobTasksSnapshot {
|
public static final class IngestJobTasksSnapshot implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private final long jobId;
|
private final long jobId;
|
||||||
private final long dsQueueSize;
|
private final long dsQueueSize;
|
||||||
private final long rootQueueSize;
|
private final long rootQueueSize;
|
||||||
@ -839,13 +845,13 @@ final class IngestTasksScheduler {
|
|||||||
*
|
*
|
||||||
* @param jobId The identifier associated with the job.
|
* @param jobId The identifier associated with the job.
|
||||||
*/
|
*/
|
||||||
IngestJobTasksSnapshot(long jobId) {
|
IngestJobTasksSnapshot(long jobId, long dsQueueSize, long rootQueueSize, long dirQueueSize, long fileQueueSize, long runningListSize) {
|
||||||
this.jobId = jobId;
|
this.jobId = jobId;
|
||||||
this.dsQueueSize = IngestTasksScheduler.this.dataSourceIngestThreadQueue.countQueuedTasksForJob(jobId);
|
this.dsQueueSize = dsQueueSize;
|
||||||
this.rootQueueSize = countTasksForJob(IngestTasksScheduler.this.rootFileTaskQueue, jobId);
|
this.rootQueueSize = rootQueueSize;
|
||||||
this.dirQueueSize = countTasksForJob(IngestTasksScheduler.this.pendingFileTaskQueue, jobId);
|
this.dirQueueSize = dirQueueSize;
|
||||||
this.fileQueueSize = IngestTasksScheduler.this.fileIngestThreadsQueue.countQueuedTasksForJob(jobId);;
|
this.fileQueueSize = fileQueueSize;
|
||||||
this.runningListSize = IngestTasksScheduler.this.dataSourceIngestThreadQueue.countRunningTasksForJob(jobId) + IngestTasksScheduler.this.fileIngestThreadsQueue.countRunningTasksForJob(jobId);
|
this.runningListSize = runningListSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,19 +143,20 @@ final class AutoIngestAdminActions {
|
|||||||
static final class ProgressDialogAction extends AbstractAction {
|
static final class ProgressDialogAction extends AbstractAction {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final AutoIngestJob job;
|
||||||
|
|
||||||
ProgressDialogAction() {
|
ProgressDialogAction(AutoIngestJob job) {
|
||||||
super(Bundle.AutoIngestAdminActions_progressDialogAction_title());
|
super(Bundle.AutoIngestAdminActions_progressDialogAction_title());
|
||||||
|
this.job = job;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
//TODO JIRA-3734
|
|
||||||
final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(AutoIngestDashboardTopComponent.PREFERRED_ID);
|
final AutoIngestDashboardTopComponent tc = (AutoIngestDashboardTopComponent) WindowManager.getDefault().findTopComponent(AutoIngestDashboardTopComponent.PREFERRED_ID);
|
||||||
if (tc != null) {
|
if (tc != null) {
|
||||||
AutoIngestDashboard dashboard = tc.getAutoIngestDashboard();
|
AutoIngestDashboard dashboard = tc.getAutoIngestDashboard();
|
||||||
if (dashboard != null) {
|
if (dashboard != null) {
|
||||||
new IngestProgressSnapshotDialog(dashboard.getTopLevelAncestor(), true);
|
new IngestProgressSnapshotDialog(dashboard.getTopLevelAncestor(), true, job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2017 Basis Technology Corp.
|
* Copyright 2011-2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -25,23 +25,28 @@ import java.time.Instant;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestJob.Snapshot;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestManager.IngestThreadActivitySnapshot;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An automated ingest job, which is an ingest job performed by the automated
|
* An automated ingest job, which is an ingest job performed by the automated
|
||||||
* ingest service.
|
* ingest service.
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
final class AutoIngestJob implements Comparable<AutoIngestJob>, IngestProgressSnapshotProvider, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final int CURRENT_VERSION = 2;
|
private static final int CURRENT_VERSION = 3;
|
||||||
private static final int DEFAULT_PRIORITY = 0;
|
private static final int DEFAULT_PRIORITY = 0;
|
||||||
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
|
private static final String LOCAL_HOST_NAME = NetworkUtils.getLocalHostName();
|
||||||
|
|
||||||
@ -89,6 +94,13 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
|||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private long dataSourceSize;
|
private long dataSourceSize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version 3 fields.
|
||||||
|
*/
|
||||||
|
private List<IngestThreadActivitySnapshot> ingestThreadsSnapshot;
|
||||||
|
private List<Snapshot> ingestJobsSnapshot;
|
||||||
|
private Map<String, Long> moduleRunTimesSnapshot;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new automated ingest job. All job state not specified in the
|
* Constructs a new automated ingest job. All job state not specified in the
|
||||||
* job manifest is set to the default state for a new job.
|
* job manifest is set to the default state for a new job.
|
||||||
@ -125,6 +137,13 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
|||||||
* Version 2 fields.
|
* Version 2 fields.
|
||||||
*/
|
*/
|
||||||
this.dataSourceSize = 0;
|
this.dataSourceSize = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version 3 fields.
|
||||||
|
*/
|
||||||
|
this.ingestThreadsSnapshot = Collections.emptyList();
|
||||||
|
this.ingestJobsSnapshot = Collections.emptyList();
|
||||||
|
this.moduleRunTimesSnapshot = Collections.emptyMap();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
|
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
|
||||||
}
|
}
|
||||||
@ -167,6 +186,13 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
|||||||
* Version 2 fields.
|
* Version 2 fields.
|
||||||
*/
|
*/
|
||||||
this.dataSourceSize = nodeData.getDataSourceSize();
|
this.dataSourceSize = nodeData.getDataSourceSize();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version 3 fields
|
||||||
|
*/
|
||||||
|
this.ingestThreadsSnapshot = Collections.emptyList();
|
||||||
|
this.ingestJobsSnapshot = Collections.emptyList();
|
||||||
|
this.moduleRunTimesSnapshot = Collections.emptyMap();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
|
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
|
||||||
}
|
}
|
||||||
@ -340,6 +366,31 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
|||||||
return this.ingestJob;
|
return this.ingestJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the ingest thread snapshot for the auto ingest job.
|
||||||
|
*
|
||||||
|
* @param snapshot
|
||||||
|
*/
|
||||||
|
synchronized void setIngestThreadSnapshot(List<IngestThreadActivitySnapshot> snapshot) {
|
||||||
|
this.ingestThreadsSnapshot = snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the ingest job snapshot for the auto ingest job.
|
||||||
|
* @param snapshot
|
||||||
|
*/
|
||||||
|
synchronized void setIngestJobsSnapshot(List<Snapshot> snapshot) {
|
||||||
|
this.ingestJobsSnapshot = snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the module run times snapshot for the auto ingest job.
|
||||||
|
* @param snapshot
|
||||||
|
*/
|
||||||
|
synchronized void setModuleRuntimesSnapshot(Map<String, Long> snapshot) {
|
||||||
|
this.moduleRunTimesSnapshot = snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the job.
|
* Cancels the job.
|
||||||
*/
|
*/
|
||||||
@ -541,6 +592,21 @@ final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializable {
|
|||||||
return -this.getManifest().getDateFileCreated().compareTo(otherJob.getManifest().getDateFileCreated());
|
return -this.getManifest().getDateFileCreated().compareTo(otherJob.getManifest().getDateFileCreated());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IngestThreadActivitySnapshot> getIngestThreadActivitySnapshots() {
|
||||||
|
return this.ingestThreadsSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Snapshot> getIngestJobSnapshots() {
|
||||||
|
return this.ingestJobsSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Long> getModuleRunTimes() {
|
||||||
|
return this.moduleRunTimesSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comparator that supports doing a descending sort of jobs based on job
|
* Comparator that supports doing a descending sort of jobs based on job
|
||||||
* completion date.
|
* completion date.
|
||||||
|
@ -260,9 +260,9 @@ final class AutoIngestJobsNode extends AbstractNode {
|
|||||||
actions.add(deprioritizeCaseAction);
|
actions.add(deprioritizeCaseAction);
|
||||||
break;
|
break;
|
||||||
case RUNNING_JOB:
|
case RUNNING_JOB:
|
||||||
actions.add(new AutoIngestAdminActions.ProgressDialogAction());
|
actions.add(new AutoIngestAdminActions.ProgressDialogAction(autoIngestJob));
|
||||||
actions.add(new AutoIngestAdminActions.CancelJobAction(autoIngestJob));
|
actions.add(new AutoIngestAdminActions.CancelJobAction(autoIngestJob));
|
||||||
actions.add(new AutoIngestAdminActions.CancelModuleAction());
|
// actions.add(new AutoIngestAdminActions.CancelModuleAction());
|
||||||
break;
|
break;
|
||||||
case COMPLETED_JOB:
|
case COMPLETED_JOB:
|
||||||
actions.add(new AutoIngestAdminActions.ReprocessJobAction(autoIngestJob));
|
actions.add(new AutoIngestAdminActions.ReprocessJobAction(autoIngestJob));
|
||||||
|
@ -3052,6 +3052,9 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen
|
|||||||
synchronized (jobsLock) {
|
synchronized (jobsLock) {
|
||||||
if (currentJob != null) {
|
if (currentJob != null) {
|
||||||
currentJob.getProcessingStageDetails();
|
currentJob.getProcessingStageDetails();
|
||||||
|
currentJob.setIngestThreadSnapshot(IngestManager.getInstance().getIngestThreadActivitySnapshots());
|
||||||
|
currentJob.setIngestJobsSnapshot(IngestManager.getInstance().getIngestJobSnapshots());
|
||||||
|
currentJob.setModuleRuntimesSnapshot(IngestManager.getInstance().getModuleRunTimes());
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(Event.JOB_STATUS_UPDATED);
|
notifyObservers(Event.JOB_STATUS_UPDATED);
|
||||||
updateCoordinationServiceManifestNode(currentJob);
|
updateCoordinationServiceManifestNode(currentJob);
|
||||||
|
@ -188,7 +188,17 @@ final class AutoIngestMonitor extends Observable implements PropertyChangeListen
|
|||||||
*/
|
*/
|
||||||
AutoIngestJob job = event.getJob();
|
AutoIngestJob job = event.getJob();
|
||||||
jobsSnapshot.removePendingJob(job);
|
jobsSnapshot.removePendingJob(job);
|
||||||
jobsSnapshot.addOrReplaceRunningJob(job);
|
|
||||||
|
// Update the state of the existing job in the running jobs table
|
||||||
|
for (AutoIngestJob runningJob : jobsSnapshot.getRunningJobs()) {
|
||||||
|
if (runningJob.equals(job)) {
|
||||||
|
runningJob.setIngestJobsSnapshot(job.getIngestJobSnapshots());
|
||||||
|
runningJob.setIngestThreadSnapshot(job.getIngestThreadActivitySnapshots());
|
||||||
|
runningJob.setModuleRuntimesSnapshot(job.getModuleRunTimes());
|
||||||
|
runningJob.setProcessingStage(job.getProcessingStage(), job.getProcessingStageStartDate());
|
||||||
|
runningJob.setProcessingStatus(job.getProcessingStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers(jobsSnapshot);
|
notifyObservers(jobsSnapshot);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user