Autopsy  4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
IngestJob.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2016 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.ingest;
20 
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.concurrent.ConcurrentHashMap;
28 import java.util.concurrent.atomic.AtomicInteger;
29 import java.util.concurrent.atomic.AtomicLong;
30 
31 import org.openide.util.NbBundle;
32 import org.sleuthkit.datamodel.Content;
33 
40 public final class IngestJob {
41 
42  /*
43  * An ingest job can be cancelled for various reasons.
44  */
45  public enum CancellationReason {
46 
47  NOT_CANCELLED(NbBundle.getMessage(IngestJob.class, "IngestJob.cancelReason.notCancelled.text")),
48  USER_CANCELLED(NbBundle.getMessage(IngestJob.class, "IngestJob.cancelReason.cancelledByUser.text")),
49  INGEST_MODULES_STARTUP_FAILED(NbBundle.getMessage(IngestJob.class, "IngestJob.cancelReason.ingestModStartFail.text")),
50  OUT_OF_DISK_SPACE(NbBundle.getMessage(IngestJob.class, "IngestJob.cancelReason.outOfDiskSpace.text")),
51  SERVICES_DOWN(NbBundle.getMessage(IngestJob.class, "IngestJob.cancelReason.servicesDown.text")),
52  CASE_CLOSED(NbBundle.getMessage(IngestJob.class, "IngestJob.cancelReason.caseClosed.text"));
53 
54  private final String displayName;
55 
56  private CancellationReason(String displayName) {
57  this.displayName = displayName;
58  }
59 
60  public String getDisplayName() {
61  return displayName;
62  }
63  }
64 
65  private final static AtomicLong nextId = new AtomicLong(0L);
66  private final long id;
67  private final Map<Long, DataSourceIngestJob> dataSourceJobs;
68  private final AtomicInteger incompleteJobsCount;
70 
80  IngestJob(Collection<Content> dataSources, IngestJobSettings settings, boolean doUI) {
81  this.id = IngestJob.nextId.getAndIncrement();
82  this.dataSourceJobs = new ConcurrentHashMap<>();
83  for (Content dataSource : dataSources) {
84  DataSourceIngestJob dataSourceIngestJob = new DataSourceIngestJob(this, dataSource, settings, doUI);
85  this.dataSourceJobs.put(dataSourceIngestJob.getId(), dataSourceIngestJob);
86  }
87  incompleteJobsCount = new AtomicInteger(dataSourceJobs.size());
88  cancellationReason = CancellationReason.NOT_CANCELLED;
89  }
90 
96  public long getId() {
97  return this.id;
98  }
99 
107  boolean hasIngestPipeline() {
114  for (DataSourceIngestJob dataSourceJob : this.dataSourceJobs.values()) {
115  if (dataSourceJob.hasIngestPipeline()) {
116  return true;
117  }
118  }
119  return false;
120  }
121 
128  List<IngestModuleError> start() {
129  /*
130  * Try to start each data source ingest job. Note that there is a not
131  * unwarranted assumption here that if there is going to be a module
132  * startup failure, it will be for the first data source ingest job.
133  *
134  * TODO (RC): Consider separating module start up from pipeline startup
135  * so that no processing is done if this assumption is false.
136  */
137  List<IngestModuleError> errors = new ArrayList<>();
138  for (DataSourceIngestJob dataSourceJob : this.dataSourceJobs.values()) {
139  errors.addAll(dataSourceJob.start());
140  if (errors.isEmpty() == false) {
141  break;
142  }
143  }
144 
145  /*
146  * Handle start up success or failure.
147  */
148  if (errors.isEmpty()) {
149  for (DataSourceIngestJob dataSourceJob : this.dataSourceJobs.values()) {
150  IngestManager.getInstance().fireDataSourceAnalysisStarted(id, dataSourceJob.getId(), dataSourceJob.getDataSource());
151  }
152  } else {
153  cancel(CancellationReason.INGEST_MODULES_STARTUP_FAILED);
154  }
155 
156  return errors;
157  }
158 
165  return new ProgressSnapshot(true);
166  }
167 
173  public ProgressSnapshot getSnapshot(boolean getIngestTasksSnapshot) {
174  return new ProgressSnapshot(getIngestTasksSnapshot);
175  }
176 
183  List<DataSourceIngestJob.Snapshot> getDataSourceIngestJobSnapshots() {
184  List<DataSourceIngestJob.Snapshot> snapshots = new ArrayList<>();
185  this.dataSourceJobs.values().stream().forEach((dataSourceJob) -> {
186  snapshots.add(dataSourceJob.getSnapshot(true));
187  });
188  return snapshots;
189  }
190 
199  @Deprecated
200  public void cancel() {
202  }
203 
212  public void cancel(CancellationReason reason) {
213  this.cancellationReason = reason;
214  this.dataSourceJobs.values().stream().forEach((job) -> {
215  job.cancel(reason);
216  });
217  }
218 
225  return this.cancellationReason;
226  }
227 
234  public boolean isCancelled() {
235  return (CancellationReason.NOT_CANCELLED != this.cancellationReason);
236  }
237 
244  void dataSourceJobFinished(DataSourceIngestJob job) {
245  IngestManager ingestManager = IngestManager.getInstance();
246  if (!job.isCancelled()) {
247  ingestManager.fireDataSourceAnalysisCompleted(id, job.getId(), job.getDataSource());
248  } else {
249  IngestManager.getInstance().fireDataSourceAnalysisCancelled(id, job.getId(), job.getDataSource());
250  }
251  if (incompleteJobsCount.decrementAndGet() == 0) {
252  ingestManager.finishIngestJob(this);
253  }
254  }
255 
259  public final class ProgressSnapshot {
260 
261  private final List<DataSourceProcessingSnapshot> dataSourceProcessingSnapshots;
263  private boolean fileIngestRunning;
264  private Date fileIngestStartTime;
265  private final boolean jobCancelled;
267 
272  public final class DataSourceProcessingSnapshot {
273 
274  private final DataSourceIngestJob.Snapshot snapshot;
275 
276  private DataSourceProcessingSnapshot(DataSourceIngestJob.Snapshot snapshot) {
277  this.snapshot = snapshot;
278  }
279 
286  public String getDataSource() {
287  return snapshot.getDataSource();
288  }
289 
296  public boolean isCancelled() {
297  return snapshot.isCancelled();
298  }
299 
306  return snapshot.getCancellationReason();
307  }
308 
316  public List<String> getCancelledDataSourceIngestModules() {
317  return snapshot.getCancelledDataSourceIngestModules();
318  }
319 
320  }
321 
325  private ProgressSnapshot(boolean getIngestTasksSnapshot) {
326  dataSourceModule = null;
327  fileIngestRunning = false;
328  fileIngestStartTime = null;
329  dataSourceProcessingSnapshots = new ArrayList<>();
330  for (DataSourceIngestJob dataSourceJob : dataSourceJobs.values()) {
331  DataSourceIngestJob.Snapshot snapshot = dataSourceJob.getSnapshot(getIngestTasksSnapshot);
332  dataSourceProcessingSnapshots.add(new DataSourceProcessingSnapshot(snapshot));
333  if (null == dataSourceModule) {
334  DataSourceIngestPipeline.PipelineModule module = snapshot.getDataSourceLevelIngestModule();
335  if (null != module) {
336  dataSourceModule = new DataSourceIngestModuleHandle(dataSourceJobs.get(snapshot.getJobId()), module);
337  }
338  }
339  if (snapshot.fileIngestIsRunning()) {
340  fileIngestRunning = true;
341  }
342  Date childFileIngestStartTime = snapshot.fileIngestStartTime();
343  if (null != childFileIngestStartTime && (null == fileIngestStartTime || childFileIngestStartTime.before(fileIngestStartTime))) {
344  fileIngestStartTime = childFileIngestStartTime;
345  }
346  }
347  this.jobCancelled = isCancelled();
349  }
350 
358  return this.dataSourceModule;
359  }
360 
367  public boolean fileIngestIsRunning() {
368  return this.fileIngestRunning;
369  }
370 
376  public Date fileIngestStartTime() {
377  return new Date(this.fileIngestStartTime.getTime());
378  }
379 
386  public boolean isCancelled() {
387  return this.jobCancelled;
388  }
389 
396  return this.jobCancellationReason;
397  }
398 
404  public List<DataSourceProcessingSnapshot> getDataSourceSnapshots() {
405  return Collections.unmodifiableList(this.dataSourceProcessingSnapshots);
406  }
407 
408  }
409 
415  public static class DataSourceIngestModuleHandle {
416 
417  private final DataSourceIngestJob job;
418  private final DataSourceIngestPipeline.PipelineModule module;
419  private final boolean cancelled;
420 
430  private DataSourceIngestModuleHandle(DataSourceIngestJob job, DataSourceIngestPipeline.PipelineModule module) {
431  this.job = job;
432  this.module = module;
433  this.cancelled = job.currentDataSourceIngestModuleIsCancelled();
434  }
435 
442  public String displayName() {
443  return this.module.getDisplayName();
444  }
445 
452  public Date startTime() {
453  return this.module.getProcessingStartTime();
454  }
455 
462  public boolean isCancelled() {
463  return this.cancelled;
464  }
465 
471  public void cancel() {
483  if (this.job.getCurrentDataSourceIngestModule() == this.module) {
484  this.job.cancelCurrentDataSourceIngestModule();
485  }
486  }
487 
488  }
489 
490 }
DataSourceIngestModuleHandle(DataSourceIngestJob job, DataSourceIngestPipeline.PipelineModule module)
Definition: IngestJob.java:430
static synchronized IngestManager getInstance()
final DataSourceIngestPipeline.PipelineModule module
Definition: IngestJob.java:418
final AtomicInteger incompleteJobsCount
Definition: IngestJob.java:68
void cancel(CancellationReason reason)
Definition: IngestJob.java:212
final Map< Long, DataSourceIngestJob > dataSourceJobs
Definition: IngestJob.java:67
DataSourceIngestModuleHandle runningDataSourceIngestModule()
Definition: IngestJob.java:357
List< DataSourceProcessingSnapshot > getDataSourceSnapshots()
Definition: IngestJob.java:404
final IngestJob.CancellationReason jobCancellationReason
Definition: IngestJob.java:266
CancellationReason getCancellationReason()
Definition: IngestJob.java:224
static final AtomicLong nextId
Definition: IngestJob.java:65
ProgressSnapshot(boolean getIngestTasksSnapshot)
Definition: IngestJob.java:325
volatile CancellationReason cancellationReason
Definition: IngestJob.java:69
ProgressSnapshot getSnapshot(boolean getIngestTasksSnapshot)
Definition: IngestJob.java:173
final List< DataSourceProcessingSnapshot > dataSourceProcessingSnapshots
Definition: IngestJob.java:261

Copyright © 2012-2016 Basis Technology. Generated on: Mon Jan 2 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.