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;
58 this.displayName = displayName;
75 private final static AtomicLong
nextId =
new AtomicLong(0L);
76 private final long id;
78 private final List<AbstractFile>
files =
new ArrayList<>();
95 this.ingestJobPipelines =
new ConcurrentHashMap<>();
96 this.ingestMode = Mode.BATCH;
97 this.dataSources.addAll(dataSources);
98 incompleteJobsCount =
new AtomicInteger(dataSources.size());
112 this(Arrays.asList(dataSource),
settings);
113 this.files.addAll(files);
122 IngestJob(Content dataSource, Mode ingestMode, IngestJobSettings settings) {
123 this.
id = IngestJob.nextId.getAndIncrement();
124 this.ingestJobPipelines =
new ConcurrentHashMap<>();
125 this.dataSources.add(dataSource);
128 incompleteJobsCount =
new AtomicInteger(1);
148 boolean hasIngestPipeline() {
149 return (!settings.getEnabledIngestModuleTemplates().isEmpty());
157 void addStreamingIngestFiles(List<Long> fileObjIds) {
158 if (ingestJobPipelines.isEmpty()) {
159 logger.log(Level.SEVERE,
"Attempted to add streaming ingest files with no IngestJobPipeline");
163 IngestJobPipeline streamingIngestPipeline = ingestJobPipelines.values().iterator().next();
164 streamingIngestPipeline.addStreamedFiles(fileObjIds);
170 void processStreamingIngestDataSource() {
171 if (ingestJobPipelines.isEmpty()) {
172 logger.log(Level.SEVERE,
"Attempted to start data source ingest with no IngestJobPipeline");
176 IngestJobPipeline streamingIngestPipeline = ingestJobPipelines.values().iterator().next();
177 streamingIngestPipeline.addStreamedDataSource();
186 List<IngestModuleError> start() throws InterruptedException {
191 if (files.isEmpty()) {
192 for (Content dataSource : dataSources) {
193 IngestJobPipeline ingestJobPipeline =
new IngestJobPipeline(
this, dataSource, settings);
194 ingestJobPipelines.put(ingestJobPipeline.getId(), ingestJobPipeline);
197 IngestJobPipeline ingestJobPipeline =
new IngestJobPipeline(
this, dataSources.get(0),
files,
settings);
198 ingestJobPipelines.put(ingestJobPipeline.getId(), ingestJobPipeline);
200 incompleteJobsCount.set(ingestJobPipelines.size());
205 List<IngestModuleError> errors =
new ArrayList<>();
206 for (IngestJobPipeline ingestJobPipeline : ingestJobPipelines.values()) {
207 errors.addAll(ingestJobPipeline.startUp());
208 if (errors.isEmpty() ==
false) {
216 if (errors.isEmpty()) {
217 for (IngestJobPipeline ingestJobPipeline : ingestJobPipelines.values()) {
218 IngestManager.getInstance().fireDataSourceAnalysisStarted(
id, ingestJobPipeline.getId(), ingestJobPipeline.getDataSource());
221 cancel(CancellationReason.INGEST_MODULES_STARTUP_FAILED);
232 Mode getIngestMode() {
262 List<Snapshot> getDataSourceIngestJobSnapshots() {
263 List<Snapshot> snapshots =
new ArrayList<>();
264 this.ingestJobPipelines.values().stream().forEach((dataSourceJob) -> {
265 snapshots.add(dataSourceJob.getSnapshot(
true));
292 cancellationReason = reason;
303 this.ingestJobPipelines.values().stream().forEach((job) -> {
334 void notifyIngestPipelineShutDown(IngestJobPipeline ingestJobPipeline) {
336 if (!ingestJobPipeline.isCancelled()) {
337 ingestManager.fireDataSourceAnalysisCompleted(
id, ingestJobPipeline.getId(), ingestJobPipeline.getDataSource());
339 IngestManager.getInstance().fireDataSourceAnalysisCancelled(
id, ingestJobPipeline.getId(), ingestJobPipeline.getDataSource());
341 if (incompleteJobsCount.decrementAndGet() == 0) {
342 ingestManager.finishIngestJob(
this);
377 return snapshot.getDataSource();
387 return snapshot.isCancelled();
396 return snapshot.getCancellationReason();
407 return snapshot.getCancelledDataSourceIngestModules();
416 dataSourceModule = null;
417 fileIngestRunning =
false;
418 fileIngestStartTime = null;
419 dataSourceProcessingSnapshots =
new ArrayList<>();
420 for (IngestJobPipeline pipeline : ingestJobPipelines.values()) {
421 Snapshot snapshot = pipeline.getSnapshot(getIngestTasksSnapshot);
423 if (null == dataSourceModule) {
424 DataSourceIngestPipeline.DataSourcePipelineModule module = snapshot.getDataSourceLevelIngestModule();
425 if (null != module) {
429 if (snapshot.getFileIngestIsRunning()) {
430 fileIngestRunning =
true;
432 Date childFileIngestStartTime = snapshot.getFileIngestStartTime();
433 if (null != childFileIngestStartTime && (null == fileIngestStartTime || childFileIngestStartTime.before(fileIngestStartTime))) {
434 fileIngestStartTime = childFileIngestStartTime;
467 return new Date(this.fileIngestStartTime.getTime());
495 return Collections.unmodifiableList(this.dataSourceProcessingSnapshots);
508 private final DataSourceIngestPipeline.DataSourcePipelineModule
module;
523 this.cancelled = ingestJobPipeline.currentDataSourceIngestModuleIsCancelled();
533 return this.
module.getDisplayName();
543 return this.
module.getProcessingStartTime();
573 if (this.ingestJobPipeline.getCurrentDataSourceIngestModule() == this.
module) {
574 this.ingestJobPipeline.cancelCurrentDataSourceIngestModule();
List< String > getCancelledDataSourceIngestModules()
static synchronized IngestManager getInstance()
CancellationReason(String displayName)
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
DataSourceIngestModuleHandle(IngestJobPipeline ingestJobPipeline, DataSourceIngestPipeline.DataSourcePipelineModule module)
ProgressSnapshot getSnapshot()
final List< Content > dataSources
INGEST_MODULES_STARTUP_FAILED
final List< AbstractFile > files
final DataSourceIngestPipeline.DataSourcePipelineModule module
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