19 package org.sleuthkit.autopsy.ingest;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Date;
26 import java.util.List;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.atomic.AtomicInteger;
30 import java.util.concurrent.atomic.AtomicLong;
31 import java.util.logging.Level;
32 import org.openide.util.NbBundle;
59 this.displayName = displayName;
76 private final static AtomicLong
nextId =
new AtomicLong(0L);
77 private final long id;
79 private final List<AbstractFile>
files =
new ArrayList<>();
96 this.ingestJobPipelines =
new ConcurrentHashMap<>();
97 this.ingestMode = Mode.BATCH;
98 this.dataSources.addAll(dataSources);
99 incompleteJobsCount =
new AtomicInteger(dataSources.size());
113 this(Arrays.asList(dataSource),
settings);
114 this.files.addAll(files);
123 IngestJob(DataSource dataSource, Mode ingestMode, IngestJobSettings settings) {
124 this.
id = IngestJob.nextId.getAndIncrement();
125 this.ingestJobPipelines =
new ConcurrentHashMap<>();
126 this.dataSources.add(dataSource);
129 incompleteJobsCount =
new AtomicInteger(1);
149 boolean hasIngestPipeline() {
150 return (!settings.getEnabledIngestModuleTemplates().isEmpty());
158 void addStreamingIngestFiles(List<Long> fileObjIds) {
159 if (ingestJobPipelines.isEmpty()) {
160 logger.log(Level.SEVERE,
"Attempted to add streaming ingest files with no IngestJobPipeline");
164 IngestJobPipeline streamingIngestPipeline = ingestJobPipelines.values().iterator().next();
165 streamingIngestPipeline.addStreamingIngestFiles(fileObjIds);
171 void processStreamingIngestDataSource() {
172 if (ingestJobPipelines.isEmpty()) {
173 logger.log(Level.SEVERE,
"Attempted to start data source ingest with no IngestJobPipeline");
177 IngestJobPipeline streamingIngestPipeline = ingestJobPipelines.values().iterator().next();
178 streamingIngestPipeline.processStreamingIngestDataSource();
187 List<IngestModuleError> start() {
192 if (files.isEmpty()) {
193 for (Content dataSource : dataSources) {
194 IngestJobPipeline ingestJobPipeline =
new IngestJobPipeline(
this, dataSource, settings);
195 this.ingestJobPipelines.put(ingestJobPipeline.getId(), ingestJobPipeline);
198 IngestJobPipeline ingestJobPipeline =
new IngestJobPipeline(
this, dataSources.get(0),
files,
settings);
199 this.ingestJobPipelines.put(ingestJobPipeline.getId(), ingestJobPipeline);
201 incompleteJobsCount.set(ingestJobPipelines.size());
211 List<IngestModuleError> errors =
new ArrayList<>();
212 for (IngestJobPipeline ingestJobPipeline : this.ingestJobPipelines.values()) {
213 errors.addAll(ingestJobPipeline.start());
214 if (errors.isEmpty() ==
false) {
222 if (errors.isEmpty()) {
223 for (IngestJobPipeline dataSourceJob : this.ingestJobPipelines.values()) {
224 IngestManager.getInstance().fireDataSourceAnalysisStarted(
id, dataSourceJob.getId(), dataSourceJob.getDataSource());
227 cancel(CancellationReason.INGEST_MODULES_STARTUP_FAILED);
238 Mode getIngestMode() {
268 List<Snapshot> getDataSourceIngestJobSnapshots() {
269 List<Snapshot> snapshots =
new ArrayList<>();
270 this.ingestJobPipelines.values().stream().forEach((dataSourceJob) -> {
271 snapshots.add(dataSourceJob.getSnapshot(
true));
298 this.cancellationReason = reason;
299 this.ingestJobPipelines.values().stream().forEach((job) -> {
329 void ingestJobPipelineFinished(IngestJobPipeline ingestJobPipeline) {
331 if (!ingestJobPipeline.isCancelled()) {
332 ingestManager.fireDataSourceAnalysisCompleted(
id, ingestJobPipeline.getId(), ingestJobPipeline.getDataSource());
334 IngestManager.getInstance().fireDataSourceAnalysisCancelled(
id, ingestJobPipeline.getId(), ingestJobPipeline.getDataSource());
336 if (incompleteJobsCount.decrementAndGet() == 0) {
337 ingestManager.finishIngestJob(
this);
372 return snapshot.getDataSource();
382 return snapshot.isCancelled();
391 return snapshot.getCancellationReason();
402 return snapshot.getCancelledDataSourceIngestModules();
411 dataSourceModule = null;
412 fileIngestRunning =
false;
413 fileIngestStartTime = null;
414 dataSourceProcessingSnapshots =
new ArrayList<>();
415 for (IngestJobPipeline pipeline : ingestJobPipelines.values()) {
416 Snapshot snapshot = pipeline.getSnapshot(getIngestTasksSnapshot);
418 if (null == dataSourceModule) {
419 DataSourceIngestPipeline.PipelineModule module = snapshot.getDataSourceLevelIngestModule();
420 if (null != module) {
424 if (snapshot.getFileIngestIsRunning()) {
425 fileIngestRunning =
true;
427 Date childFileIngestStartTime = snapshot.getFileIngestStartTime();
428 if (null != childFileIngestStartTime && (null == fileIngestStartTime || childFileIngestStartTime.before(fileIngestStartTime))) {
429 fileIngestStartTime = childFileIngestStartTime;
462 return new Date(this.fileIngestStartTime.getTime());
490 return Collections.unmodifiableList(this.dataSourceProcessingSnapshots);
503 private final DataSourceIngestPipeline.PipelineModule
module;
517 this.cancelled = ingestJobPipeline.currentDataSourceIngestModuleIsCancelled();
527 return this.
module.getDisplayName();
537 return this.
module.getProcessingStartTime();
567 if (this.ingestJobPipeline.getCurrentDataSourceIngestModule() == this.
module) {
568 this.ingestJobPipeline.cancelCurrentDataSourceIngestModule();
DataSourceIngestModuleHandle(IngestJobPipeline ingestJobPipeline, DataSourceIngestPipeline.PipelineModule module)
List< String > getCancelledDataSourceIngestModules()
static synchronized IngestManager getInstance()
CancellationReason(String displayName)
final DataSourceIngestPipeline.PipelineModule module
final boolean jobCancelled
boolean fileIngestIsRunning()
final AtomicInteger incompleteJobsCount
static final Logger logger
void cancel(CancellationReason reason)
final IngestJobPipeline ingestJobPipeline
DataSourceIngestModuleHandle runningDataSourceIngestModule()
List< DataSourceProcessingSnapshot > getDataSourceSnapshots()
final IngestJob.CancellationReason jobCancellationReason
CancellationReason getCancellationReason()
final Map< Long, IngestJobPipeline > ingestJobPipelines
ProgressSnapshot getSnapshot()
final List< Content > dataSources
INGEST_MODULES_STARTUP_FAILED
final List< AbstractFile > files
static final AtomicLong nextId
DataSourceProcessingSnapshot(Snapshot snapshot)
boolean fileIngestRunning
ProgressSnapshot(boolean getIngestTasksSnapshot)
volatile CancellationReason cancellationReason
synchronized static Logger getLogger(String name)
ProgressSnapshot getSnapshot(boolean getIngestTasksSnapshot)
CancellationReason getCancellationReason()
Date fileIngestStartTime()
CancellationReason getCancellationReason()
final IngestJobSettings settings
DataSourceIngestModuleHandle dataSourceModule
final List< DataSourceProcessingSnapshot > dataSourceProcessingSnapshots