mirror of
https://github.com/elisspace/autopsy.git
synced 2026-09-06 02:24:30 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into timeline_ja
This commit is contained in:
@@ -211,7 +211,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
||||
private void startIngest() {
|
||||
if (!newContents.isEmpty() && readyToIngest && !ingested) {
|
||||
ingested = true;
|
||||
IngestManager.getInstance().startIngestJobs(newContents, ingestJobSettingsPanel.getSettings(), true);
|
||||
IngestManager.getInstance().startIngestJob(newContents, ingestJobSettingsPanel.getSettings(), true);
|
||||
progressPanel.setStateFinished();
|
||||
}
|
||||
}
|
||||
|
||||
1072
Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java
Normal file
1072
Core/src/org/sleuthkit/autopsy/ingest/DataSourceIngestJob.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,9 +25,9 @@ import org.netbeans.api.progress.ProgressHandle;
|
||||
*/
|
||||
public class DataSourceIngestModuleProgress {
|
||||
|
||||
private final IngestJob job;
|
||||
private final DataSourceIngestJob job;
|
||||
|
||||
DataSourceIngestModuleProgress(IngestJob job) {
|
||||
DataSourceIngestModuleProgress(DataSourceIngestJob job) {
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,40 +19,66 @@
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
* This class manages a sequence of data source ingest modules. It starts them,
|
||||
* shuts them down, and runs them in sequential order.
|
||||
* This class manages a sequence of data source level ingest modules. It starts
|
||||
* the modules, runs data sources through them, and shuts them down when data
|
||||
* source level ingest is complete.
|
||||
* <p>
|
||||
* This class is not thread-safe.
|
||||
*/
|
||||
final class DataSourceIngestPipeline {
|
||||
|
||||
private static final IngestManager ingestManager = IngestManager.getInstance();
|
||||
private final IngestJob job;
|
||||
private final List<DataSourceIngestModuleDecorator> modules = new ArrayList<>();
|
||||
private final DataSourceIngestJob job;
|
||||
private final List<PipelineModule> modules = new ArrayList<>();
|
||||
private volatile PipelineModule currentModule;
|
||||
|
||||
DataSourceIngestPipeline(IngestJob job, List<IngestModuleTemplate> moduleTemplates) {
|
||||
/**
|
||||
* Constructs an object that manages a sequence of data source level ingest
|
||||
* modules. It starts the modules, runs data sources through them, and shuts
|
||||
* them down when data source level ingest is complete.
|
||||
*
|
||||
* @param job The ingest job to which this pipeline belongs.
|
||||
* @param moduleTemplates The ingest module templates that define the
|
||||
* pipeline.
|
||||
*/
|
||||
DataSourceIngestPipeline(DataSourceIngestJob job, List<IngestModuleTemplate> moduleTemplates) {
|
||||
this.job = job;
|
||||
|
||||
// Create an ingest module instance from each data source ingest module
|
||||
// template.
|
||||
/**
|
||||
* Create a data source level ingest module instance from each ingest
|
||||
* module template.
|
||||
*/
|
||||
for (IngestModuleTemplate template : moduleTemplates) {
|
||||
if (template.isDataSourceIngestModuleTemplate()) {
|
||||
DataSourceIngestModuleDecorator module = new DataSourceIngestModuleDecorator(template.createDataSourceIngestModule(), template.getModuleName());
|
||||
PipelineModule module = new PipelineModule(template.createDataSourceIngestModule(), template.getModuleName());
|
||||
modules.add(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not there are any modules in this pipeline.
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
boolean isEmpty() {
|
||||
return modules.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts up the ingest module in this pipeline.
|
||||
*
|
||||
* @return A list of ingest module startup errors, possibly empty.
|
||||
*/
|
||||
List<IngestModuleError> startUp() {
|
||||
List<IngestModuleError> errors = new ArrayList<>();
|
||||
for (DataSourceIngestModuleDecorator module : modules) {
|
||||
for (PipelineModule module : modules) {
|
||||
try {
|
||||
module.startUp(new IngestJobContext(this.job));
|
||||
} catch (Throwable ex) { // Catch-all exception firewall
|
||||
@@ -62,11 +88,20 @@ final class DataSourceIngestPipeline {
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a data source through the ingest modules in sequential order.
|
||||
*
|
||||
* @param task A data source level ingest task containing a data source to
|
||||
* be processed.
|
||||
* @return A list of ingest module errors, possible empty.
|
||||
*/
|
||||
List<IngestModuleError> process(DataSourceIngestTask task) {
|
||||
List<IngestModuleError> errors = new ArrayList<>();
|
||||
Content dataSource = task.getDataSource();
|
||||
for (DataSourceIngestModuleDecorator module : modules) {
|
||||
for (PipelineModule module : modules) {
|
||||
try {
|
||||
module.setStartTime();
|
||||
this.currentModule = module;
|
||||
String displayName = NbBundle.getMessage(this.getClass(),
|
||||
"IngestJob.progress.dataSourceIngest.displayName",
|
||||
module.getDisplayName(), dataSource.getName());
|
||||
@@ -79,40 +114,97 @@ final class DataSourceIngestPipeline {
|
||||
}
|
||||
if (this.job.isCancelled()) {
|
||||
break;
|
||||
} else if (this.job.currentDataSourceIngestModuleIsCancelled()) {
|
||||
} else if (this.job.currentDataSourceIngestModuleIsCancelled()) {
|
||||
this.job.currentDataSourceIngestModuleCancellationCompleted();
|
||||
}
|
||||
}
|
||||
this.currentModule = null;
|
||||
ingestManager.setIngestTaskProgressCompleted(task);
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static class DataSourceIngestModuleDecorator implements DataSourceIngestModule {
|
||||
/**
|
||||
* Gets the currently running module.
|
||||
*/
|
||||
PipelineModule getCurrentlyRunningModule() {
|
||||
return this.currentModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class decorates a data source level ingest module with a display
|
||||
* name and a start time.
|
||||
*/
|
||||
static class PipelineModule implements DataSourceIngestModule {
|
||||
|
||||
private final DataSourceIngestModule module;
|
||||
private final String displayName;
|
||||
private Date startTime;
|
||||
|
||||
DataSourceIngestModuleDecorator(DataSourceIngestModule module, String displayName) {
|
||||
/**
|
||||
* Constructs an object that decorates a data source level ingest module
|
||||
* with a display name and a running time.
|
||||
*
|
||||
* @param module The data source level ingest module to be decorated.
|
||||
* @param displayName The display name.
|
||||
*/
|
||||
PipelineModule(DataSourceIngestModule module, String displayName) {
|
||||
this.module = module;
|
||||
this.displayName = displayName;
|
||||
this.startTime = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class name of the decorated ingest module.
|
||||
*
|
||||
* @return The class name.
|
||||
*/
|
||||
String getClassName() {
|
||||
return module.getClass().getCanonicalName();
|
||||
return this.module.getClass().getCanonicalName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a module name suitable for display in a UI.
|
||||
*
|
||||
* @return The display name.
|
||||
*/
|
||||
String getDisplayName() {
|
||||
return displayName;
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start time to the current time.
|
||||
*/
|
||||
void setStartTime() {
|
||||
this.startTime = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time the decorated ingest module started processing the data
|
||||
* source.
|
||||
*
|
||||
* @return The start time.
|
||||
*/
|
||||
Date getStartTime() {
|
||||
return this.startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||
module.startUp(context);
|
||||
this.module.startUp(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public IngestModule.ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
|
||||
return module.process(dataSource, statusHelper);
|
||||
this.startTime = new Date();
|
||||
return this.module.process(dataSource, statusHelper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
final class DataSourceIngestTask extends IngestTask {
|
||||
|
||||
DataSourceIngestTask(IngestJob job) {
|
||||
DataSourceIngestTask(DataSourceIngestJob job) {
|
||||
super(job);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,63 +19,108 @@
|
||||
package org.sleuthkit.autopsy.ingest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
|
||||
/**
|
||||
* This class manages a sequence of file ingest modules. It starts them,
|
||||
* shuts them down, and runs a file through them.
|
||||
* This class manages a sequence of file level ingest modules. It starts the
|
||||
* modules, runs files through them, and shuts them down when file level ingest
|
||||
* is complete.
|
||||
* <p>
|
||||
* This class is not thread-safe.
|
||||
*/
|
||||
final class FileIngestPipeline {
|
||||
|
||||
private static final IngestManager ingestManager = IngestManager.getInstance();
|
||||
private final IngestJob job;
|
||||
private final List<FileIngestModuleDecorator> modules = new ArrayList<>();
|
||||
private final DataSourceIngestJob job;
|
||||
private final List<PipelineModule> modules = new ArrayList<>();
|
||||
private Date startTime;
|
||||
private boolean running;
|
||||
|
||||
FileIngestPipeline(IngestJob job, List<IngestModuleTemplate> moduleTemplates) {
|
||||
/**
|
||||
* Constructs an object that manages a sequence of file level ingest
|
||||
* modules. It starts the modules, runs files through them, and shuts them
|
||||
* down when file level ingest is complete.
|
||||
*
|
||||
* @param job The ingest job of which this pipeline is a part.
|
||||
* @param moduleTemplates The ingest module templates that define the
|
||||
* pipeline.
|
||||
*/
|
||||
FileIngestPipeline(DataSourceIngestJob job, List<IngestModuleTemplate> moduleTemplates) {
|
||||
this.job = job;
|
||||
|
||||
// Create an ingest module instance from each file ingest module
|
||||
// template.
|
||||
/**
|
||||
* Create an ingest module instance from each file ingest module
|
||||
* template.
|
||||
*/
|
||||
for (IngestModuleTemplate template : moduleTemplates) {
|
||||
if (template.isFileIngestModuleTemplate()) {
|
||||
FileIngestModuleDecorator module = new FileIngestModuleDecorator(template.createFileIngestModule(), template.getModuleName());
|
||||
PipelineModule module = new PipelineModule(template.createFileIngestModule(), template.getModuleName());
|
||||
modules.add(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether or not this pipeline has been configured with at least
|
||||
* one file level ingest module.
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
boolean isEmpty() {
|
||||
return this.modules.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start up all of the modules in the pipeline.
|
||||
* @return List of errors or empty list if no errors
|
||||
* Starts up all of the modules in the pipeline.
|
||||
*
|
||||
* @return List of start up errors, possibly empty.
|
||||
*/
|
||||
List<IngestModuleError> startUp() {
|
||||
List<IngestModuleError> errors = new ArrayList<>();
|
||||
for (FileIngestModuleDecorator module : this.modules) {
|
||||
if (this.running) {
|
||||
throw new IllegalStateException("Attempt to start up a pipeline that is already running"); //NON-NLS
|
||||
}
|
||||
|
||||
for (PipelineModule module : this.modules) {
|
||||
try {
|
||||
module.startUp(new IngestJobContext(this.job));
|
||||
} catch (Throwable ex) { // Catch-all exception firewall
|
||||
errors.add(new IngestModuleError(module.getDisplayName(), ex));
|
||||
}
|
||||
}
|
||||
this.running = true;
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the file down the pipeline of modules.
|
||||
* Startup must have been called before this is called.
|
||||
*
|
||||
* @param file File to analyze
|
||||
* @return List of errors or empty list if no errors
|
||||
* Returns the start up time of the pipeline.
|
||||
*
|
||||
* @return The file processing start time, may be null.
|
||||
*/
|
||||
Date getStartTime() {
|
||||
return this.startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a file through the ingest modules in sequential order.
|
||||
*
|
||||
* @param task A file level ingest task containing a file to be processed.
|
||||
* @return A list of processing errors, possible empty.
|
||||
*/
|
||||
List<IngestModuleError> process(FileIngestTask task) {
|
||||
if (!this.running) {
|
||||
throw new IllegalStateException("Attempt to process a file with pipeline that is not running"); //NON-NLS
|
||||
}
|
||||
|
||||
if (null == this.startTime) {
|
||||
this.startTime = new Date();
|
||||
}
|
||||
|
||||
List<IngestModuleError> errors = new ArrayList<>();
|
||||
AbstractFile file = task.getFile();
|
||||
for (FileIngestModuleDecorator module : this.modules) {
|
||||
for (PipelineModule module : this.modules) {
|
||||
try {
|
||||
FileIngestPipeline.ingestManager.setIngestTaskProgress(task, module.getDisplayName());
|
||||
module.process(file);
|
||||
@@ -94,9 +139,18 @@ final class FileIngestPipeline {
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down all of the modules in the pipeline.
|
||||
*
|
||||
* @return A list of shut down errors, possibly empty.
|
||||
*/
|
||||
List<IngestModuleError> shutDown() {
|
||||
if (!this.running) {
|
||||
throw new IllegalStateException("Attempt to shut down a pipeline that is not running"); //NON-NLS
|
||||
}
|
||||
|
||||
List<IngestModuleError> errors = new ArrayList<>();
|
||||
for (FileIngestModuleDecorator module : this.modules) {
|
||||
for (PipelineModule module : this.modules) {
|
||||
try {
|
||||
module.shutDown();
|
||||
} catch (Throwable ex) { // Catch-all exception firewall
|
||||
@@ -106,37 +160,77 @@ final class FileIngestPipeline {
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static final class FileIngestModuleDecorator implements FileIngestModule {
|
||||
/**
|
||||
* Queries whether or not this file ingest level pipeline is running.
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
boolean isRunning() {
|
||||
return this.running;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class decorates a file level ingest module with a display name.
|
||||
*/
|
||||
private static final class PipelineModule implements FileIngestModule {
|
||||
|
||||
private final FileIngestModule module;
|
||||
private final String displayName;
|
||||
|
||||
FileIngestModuleDecorator(FileIngestModule module, String displayName) {
|
||||
/**
|
||||
* Constructs an object that decorates a file level ingest module with a
|
||||
* display name.
|
||||
*
|
||||
* @param module The file level ingest module to be decorated.
|
||||
* @param displayName The display name.
|
||||
*/
|
||||
PipelineModule(FileIngestModule module, String displayName) {
|
||||
this.module = module;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class name of the decorated ingest module.
|
||||
*
|
||||
* @return The class name.
|
||||
*/
|
||||
String getClassName() {
|
||||
return module.getClass().getCanonicalName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets display name of the decorated ingest module.
|
||||
*
|
||||
* @return The display name.
|
||||
*/
|
||||
String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||
module.startUp(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public IngestModule.ProcessResult process(AbstractFile file) {
|
||||
return module.process(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void shutDown() {
|
||||
module.shutDown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ final class FileIngestTask extends IngestTask {
|
||||
|
||||
private final AbstractFile file;
|
||||
|
||||
FileIngestTask(IngestJob job, AbstractFile file) {
|
||||
FileIngestTask(DataSourceIngestJob job, AbstractFile file) {
|
||||
super(job);
|
||||
this.file = file;
|
||||
}
|
||||
@@ -53,8 +53,8 @@ final class FileIngestTask extends IngestTask {
|
||||
return false;
|
||||
}
|
||||
FileIngestTask other = (FileIngestTask) obj;
|
||||
IngestJob job = getIngestJob();
|
||||
IngestJob otherJob = other.getIngestJob();
|
||||
DataSourceIngestJob job = getIngestJob();
|
||||
DataSourceIngestJob otherJob = other.getIngestJob();
|
||||
if (job != otherJob && (job == null || !job.equals(otherJob))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -80,13 +80,13 @@ public final class IngestJobConfigurator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches ingest jobs for one or more data sources using the ingest job
|
||||
* Launches ingest job for one or more data sources using the ingest job
|
||||
* settings for the specified context.
|
||||
*
|
||||
* @param dataSources The data sources to ingest.
|
||||
*/
|
||||
@Deprecated
|
||||
public void startIngestJobs(List<Content> dataSources) {
|
||||
IngestManager.getInstance().startIngestJobs(dataSources, this.settings, true);
|
||||
IngestManager.getInstance().startIngestJob(dataSources, this.settings, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.sleuthkit.datamodel.Content;
|
||||
*/
|
||||
public final class IngestJobContext {
|
||||
|
||||
private final IngestJob ingestJob;
|
||||
private final DataSourceIngestJob ingestJob;
|
||||
|
||||
IngestJobContext(IngestJob ingestJob) {
|
||||
IngestJobContext(DataSourceIngestJob ingestJob) {
|
||||
this.ingestJob = ingestJob;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,16 +56,15 @@ public class IngestManager {
|
||||
private static IngestManager instance = null;
|
||||
|
||||
/**
|
||||
* The ingest manager assigns a unique ID to each ingest job and maintains a
|
||||
* mapping of job IDs to jobs.
|
||||
* The ingest manager maintains a mapping of ingest job IDs to ingest jobs.
|
||||
*/
|
||||
private final AtomicLong nextJobId = new AtomicLong(0L);
|
||||
private final ConcurrentHashMap<Long, IngestJob> jobsById = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Each runnable/callable task the ingest manager farms out to a thread pool
|
||||
* is given a unique thread/task ID.
|
||||
* Each runnable/callable task the ingest manager submits to its thread
|
||||
* pools is given a unique thread/task ID.
|
||||
*/
|
||||
// TODO: It is no longer necessary to have multiple thread pools.
|
||||
private final AtomicLong nextThreadId = new AtomicLong(0L);
|
||||
|
||||
/**
|
||||
@@ -214,14 +213,15 @@ public class IngestManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an ingest job, i.e., processing by ingest modules, for each data
|
||||
* source in a collection of data sources.
|
||||
* Starts an ingest job for a collection of data sources.
|
||||
*
|
||||
* @param dataSources The data sources to be processed.
|
||||
* @param settings The ingest job settings.
|
||||
* @param doMessageBoxes Whether or not to display message boxes for errors.
|
||||
* @param doUI Whether or not to support user interaction, e.g., showing
|
||||
* message boxes and reporting progress through the NetBeans Progress API.
|
||||
* @return The ingest job that was started
|
||||
*/
|
||||
public synchronized void startIngestJobs(Collection<Content> dataSources, IngestJobSettings settings, boolean doMessageBoxes) {
|
||||
public synchronized void startIngestJob(Collection<Content> dataSources, IngestJobSettings settings, boolean doUI) {
|
||||
if (!isIngestRunning()) {
|
||||
clearIngestMessageBox();
|
||||
}
|
||||
@@ -230,9 +230,17 @@ public class IngestManager {
|
||||
ingestMonitor.start();
|
||||
}
|
||||
|
||||
long taskId = nextThreadId.incrementAndGet();
|
||||
Future<Void> task = startIngestJobsThreadPool.submit(new IngestJobsStarter(taskId, dataSources, settings, doMessageBoxes));
|
||||
ingestJobStarters.put(taskId, task);
|
||||
if (doUI) {
|
||||
/**
|
||||
* Assume request is from code running on the EDT and dispatch to a
|
||||
* worker thread.
|
||||
*/
|
||||
long taskId = nextThreadId.incrementAndGet();
|
||||
Future<Void> task = startIngestJobsThreadPool.submit(new IngestJobStarter(taskId, dataSources, settings, doUI));
|
||||
ingestJobStarters.put(taskId, task);
|
||||
} else {
|
||||
this.startJob(dataSources, settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,6 +249,8 @@ public class IngestManager {
|
||||
* @return True or false.
|
||||
*/
|
||||
public boolean isIngestRunning() {
|
||||
// RJCTODO: This may return the wrong answer if an IngestJobStarter has
|
||||
// been dispatched to the startIngestJobsThreadPool.
|
||||
return !this.jobsById.isEmpty();
|
||||
}
|
||||
|
||||
@@ -405,19 +415,19 @@ public class IngestManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an ingest job for a data source.
|
||||
* Starts an ingest job for a collection of data sources.
|
||||
*
|
||||
* @param dataSource The data source to ingest.
|
||||
* @param dataSource The data sources to ingest.
|
||||
* @param settings The settings for the job.
|
||||
* @return A collection of ingest module start up errors, empty on success.
|
||||
*/
|
||||
private List<IngestModuleError> startJob(Content dataSource, IngestJobSettings settings) {
|
||||
private List<IngestModuleError> startJob(Collection<Content> dataSources, IngestJobSettings settings) {
|
||||
List<IngestModuleError> errors = new ArrayList<>();
|
||||
if (this.jobCreationIsEnabled) {
|
||||
long jobId = this.nextJobId.incrementAndGet();
|
||||
IngestJob job = new IngestJob(jobId, dataSource, settings);
|
||||
IngestJob job = new IngestJob(dataSources, settings);
|
||||
long jobId = job.getId();
|
||||
this.jobsById.put(jobId, job);
|
||||
errors = job.start(settings.getEnabledIngestModuleTemplates());
|
||||
errors = job.start();
|
||||
if (errors.isEmpty() && job.hasIngestPipeline()) {
|
||||
this.fireIngestJobStarted(jobId);
|
||||
IngestManager.logger.log(Level.INFO, "Ingest job {0} started", jobId);
|
||||
@@ -627,19 +637,18 @@ public class IngestManager {
|
||||
*
|
||||
* @return A list of ingest job state snapshots.
|
||||
*/
|
||||
List<IngestJob.IngestJobSnapshot> getIngestJobSnapshots() {
|
||||
List<IngestJob.IngestJobSnapshot> snapShots = new ArrayList<>();
|
||||
List<DataSourceIngestJob.Snapshot> getIngestJobSnapshots() {
|
||||
List<DataSourceIngestJob.Snapshot> snapShots = new ArrayList<>();
|
||||
for (IngestJob job : this.jobsById.values()) {
|
||||
snapShots.add(job.getSnapshot());
|
||||
snapShots.addAll(job.getDetailedSnapshot());
|
||||
}
|
||||
return snapShots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and starts an ingest job, i.e., processing by ingest modules, for
|
||||
* each data source in a collection of data sources.
|
||||
* Creates and starts an ingest job for a collection of data sources.
|
||||
*/
|
||||
private final class IngestJobsStarter implements Callable<Void> {
|
||||
private final class IngestJobStarter implements Callable<Void> {
|
||||
|
||||
private final long threadId;
|
||||
private final Collection<Content> dataSources;
|
||||
@@ -647,7 +656,7 @@ public class IngestManager {
|
||||
private final boolean doStartupErrorsMsgBox;
|
||||
private ProgressHandle progress;
|
||||
|
||||
IngestJobsStarter(long threadId, Collection<Content> dataSources, IngestJobSettings settings, boolean doMessageDialogs) {
|
||||
IngestJobStarter(long threadId, Collection<Content> dataSources, IngestJobSettings settings, boolean doMessageDialogs) {
|
||||
this.threadId = threadId;
|
||||
this.dataSources = dataSources;
|
||||
this.settings = settings;
|
||||
@@ -683,61 +692,35 @@ public class IngestManager {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
progress.start(dataSources.size());
|
||||
progress.start();
|
||||
|
||||
/**
|
||||
* Try to start the ingest jobs.
|
||||
* Try to start the ingest job.
|
||||
*/
|
||||
int workUnitsCompleted = 0;
|
||||
for (Content dataSource : this.dataSources) {
|
||||
|
||||
/**
|
||||
* Cancellation check.
|
||||
*/
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
return null;
|
||||
List<IngestModuleError> errors = IngestManager.this.startJob(this.dataSources, this.settings);
|
||||
if (!errors.isEmpty() && this.doStartupErrorsMsgBox) {
|
||||
StringBuilder moduleStartUpErrors = new StringBuilder();
|
||||
for (IngestModuleError error : errors) {
|
||||
String moduleName = error.getModuleDisplayName();
|
||||
moduleStartUpErrors.append(moduleName);
|
||||
moduleStartUpErrors.append(": ");
|
||||
moduleStartUpErrors.append(error.getModuleError().getLocalizedMessage());
|
||||
moduleStartUpErrors.append("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a "subtitle" to the display name of the progress bar
|
||||
* to indicate an ingest job is being started for this data
|
||||
* source.
|
||||
*/
|
||||
String progressMessage = NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.progressingDisplayName",
|
||||
dataSource.getName());
|
||||
progress.progress(progressMessage);
|
||||
|
||||
/**
|
||||
* Start an ingest job for this data source.
|
||||
*/
|
||||
List<IngestModuleError> errors = IngestManager.this.startJob(dataSource, this.settings);
|
||||
if (!errors.isEmpty() && this.doStartupErrorsMsgBox) {
|
||||
StringBuilder moduleStartUpErrors = new StringBuilder();
|
||||
for (IngestModuleError error : errors) {
|
||||
String moduleName = error.getModuleDisplayName();
|
||||
moduleStartUpErrors.append(moduleName);
|
||||
moduleStartUpErrors.append(": ");
|
||||
moduleStartUpErrors.append(error.getModuleError().getLocalizedMessage());
|
||||
moduleStartUpErrors.append("\n");
|
||||
}
|
||||
StringBuilder notifyMessage = new StringBuilder();
|
||||
notifyMessage.append(NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg"));
|
||||
notifyMessage.append("\n");
|
||||
notifyMessage.append(NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution"));
|
||||
notifyMessage.append("\n");
|
||||
notifyMessage.append(NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList",
|
||||
moduleStartUpErrors.toString()));
|
||||
notifyMessage.append("\n\n");
|
||||
JOptionPane.showMessageDialog(null, notifyMessage.toString(),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
progress.progress(progressMessage, ++workUnitsCompleted);
|
||||
StringBuilder notifyMessage = new StringBuilder();
|
||||
notifyMessage.append(NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg"));
|
||||
notifyMessage.append("\n");
|
||||
notifyMessage.append(NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution"));
|
||||
notifyMessage.append("\n");
|
||||
notifyMessage.append(NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList",
|
||||
moduleStartUpErrors.toString()));
|
||||
notifyMessage.append("\n\n");
|
||||
JOptionPane.showMessageDialog(null, notifyMessage.toString(),
|
||||
NbBundle.getMessage(this.getClass(),
|
||||
"IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -37,8 +37,7 @@ public final class IngestProgressSnapshotDialog extends JDialog {
|
||||
|
||||
private static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestProgressSnapshotDialog.title.text");
|
||||
private static final Dimension DIMENSIONS = new Dimension(500, 300);
|
||||
private JDialog pseudoOwner = null;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a non-modal instance of the dialog with its own frame.
|
||||
*/
|
||||
@@ -54,8 +53,8 @@ public final class IngestProgressSnapshotDialog extends JDialog {
|
||||
*/
|
||||
public IngestProgressSnapshotDialog(Container owner, Boolean shouldBeModal) {
|
||||
super((Window) owner, TITLE, ModalityType.MODELESS);
|
||||
if (shouldBeModal) { // if called from a modal dialog, manipulate the parent be just under this in z order, and not modal.
|
||||
pseudoOwner = (JDialog) owner;
|
||||
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;
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) { // Put it back to how it was before we manipulated it.
|
||||
|
||||
@@ -163,7 +163,7 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
|
||||
private final String[] columnNames = {"Job ID",
|
||||
"Data Source", "Start", "Num Processed", "Files/Sec", "In Progress", "Files Queued", "Dir Queued", "Root Queued", "DS Queued"};
|
||||
private List<IngestJob.IngestJobSnapshot> jobSnapshots;
|
||||
private List<DataSourceIngestJob.Snapshot> jobSnapshots;
|
||||
|
||||
private IngestJobTableModel() {
|
||||
refresh();
|
||||
@@ -191,7 +191,7 @@ public class IngestProgressSnapshotPanel extends javax.swing.JPanel {
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
IngestJob.IngestJobSnapshot snapShot = jobSnapshots.get(rowIndex);
|
||||
DataSourceIngestJob.Snapshot snapShot = jobSnapshots.get(rowIndex);
|
||||
Object cellValue;
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
|
||||
@@ -23,15 +23,15 @@ import org.sleuthkit.datamodel.Content;
|
||||
abstract class IngestTask {
|
||||
|
||||
private final static long NOT_SET = Long.MIN_VALUE;
|
||||
private final IngestJob job;
|
||||
private final DataSourceIngestJob job;
|
||||
private long threadId;
|
||||
|
||||
IngestTask(IngestJob job) {
|
||||
IngestTask(DataSourceIngestJob job) {
|
||||
this.job = job;
|
||||
threadId = NOT_SET;
|
||||
}
|
||||
|
||||
IngestJob getIngestJob() {
|
||||
DataSourceIngestJob getIngestJob() {
|
||||
return job;
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ final class IngestTasksScheduler {
|
||||
* @throws InterruptedException if the calling thread is blocked due to a
|
||||
* full tasks queue and is interrupted.
|
||||
*/
|
||||
synchronized void scheduleIngestTasks(IngestJob job) {
|
||||
synchronized void scheduleIngestTasks(DataSourceIngestJob job) {
|
||||
// Scheduling of both a data source ingest task and file ingest tasks
|
||||
// for a job must be an atomic operation. Otherwise, the data source
|
||||
// task might be completed before the file tasks are scheduled,
|
||||
@@ -163,7 +163,7 @@ final class IngestTasksScheduler {
|
||||
*
|
||||
* @param job The job for which the tasks are to be scheduled.
|
||||
*/
|
||||
synchronized void scheduleDataSourceIngestTask(IngestJob job) {
|
||||
synchronized void scheduleDataSourceIngestTask(DataSourceIngestJob job) {
|
||||
DataSourceIngestTask task = new DataSourceIngestTask(job);
|
||||
this.tasksInProgress.add(task);
|
||||
try {
|
||||
@@ -183,7 +183,7 @@ final class IngestTasksScheduler {
|
||||
*
|
||||
* @param job The job for which the tasks are to be scheduled.
|
||||
*/
|
||||
synchronized void scheduleFileIngestTasks(IngestJob job) {
|
||||
synchronized void scheduleFileIngestTasks(DataSourceIngestJob job) {
|
||||
// Get the top level files for the data source associated with this job
|
||||
// and add them to the root directories priority queue.
|
||||
List<AbstractFile> topLevelFiles = getTopLevelFiles(job.getDataSource());
|
||||
@@ -203,7 +203,7 @@ final class IngestTasksScheduler {
|
||||
* @param job The job for which the tasks are to be scheduled.
|
||||
* @param file The file to be associated with the task.
|
||||
*/
|
||||
synchronized void scheduleFileIngestTask(IngestJob job, AbstractFile file) {
|
||||
synchronized void scheduleFileIngestTask(DataSourceIngestJob job, AbstractFile file) {
|
||||
FileIngestTask task = new FileIngestTask(job, file);
|
||||
if (IngestTasksScheduler.shouldEnqueueFileTask(task)) {
|
||||
this.tasksInProgress.add(task);
|
||||
@@ -228,7 +228,7 @@ final class IngestTasksScheduler {
|
||||
* @param job The job for which the query is to be performed.
|
||||
* @return True or false.
|
||||
*/
|
||||
synchronized boolean tasksForJobAreCompleted(IngestJob job) {
|
||||
synchronized boolean tasksForJobAreCompleted(DataSourceIngestJob job) {
|
||||
for (IngestTask task : tasksInProgress) {
|
||||
if (task.getIngestJob().getId() == job.getId()) {
|
||||
return false;
|
||||
@@ -245,7 +245,7 @@ final class IngestTasksScheduler {
|
||||
*
|
||||
* @param job The job for which the tasks are to to canceled.
|
||||
*/
|
||||
synchronized void cancelPendingTasksForIngestJob(IngestJob job) {
|
||||
synchronized void cancelPendingTasksForIngestJob(DataSourceIngestJob job) {
|
||||
long jobId = job.getId();
|
||||
this.removeTasksForJob(this.rootDirectoryTasks, jobId);
|
||||
this.removeTasksForJob(this.directoryTasks, jobId);
|
||||
|
||||
@@ -199,7 +199,7 @@ public final class RunIngestModulesDialog extends JDialog {
|
||||
ingestJobSettings.save();
|
||||
showWarnings(ingestJobSettings);
|
||||
if (startIngestJob) {
|
||||
IngestManager.getInstance().startIngestJobs(RunIngestModulesDialog.this.dataSources, ingestJobSettings, true);
|
||||
IngestManager.getInstance().startIngestJob(RunIngestModulesDialog.this.dataSources, ingestJobSettings, true);
|
||||
}
|
||||
setVisible(false);
|
||||
dispose();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Updated by build script
|
||||
#Fri, 31 Oct 2014 17:10:10 -0400
|
||||
#Mon, 15 Dec 2014 16:14:04 -0500
|
||||
LBL_splash_window_title=Starting Autopsy
|
||||
SPLASH_HEIGHT=314
|
||||
SPLASH_WIDTH=538
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Updated by build script
|
||||
#Fri, 31 Oct 2014 12:13:36 -0400
|
||||
#Mon, 15 Dec 2014 16:14:04 -0500
|
||||
|
||||
CTL_MainWindow_Title=Autopsy 3.1.1
|
||||
CTL_MainWindow_Title_No_Project=Autopsy 3.1.1
|
||||
|
||||
Reference in New Issue
Block a user