Autopsy  4.4
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  System.out.println("\n##### Finished sleeping\n");
252  if (incompleteJobsCount.decrementAndGet() == 0) {
253  ingestManager.finishIngestJob(this);
254  }
255  }
256 
260  public final class ProgressSnapshot {
261 
262  private final List<DataSourceProcessingSnapshot> dataSourceProcessingSnapshots;
264  private boolean fileIngestRunning;
265  private Date fileIngestStartTime;
266  private final boolean jobCancelled;
268 
273  public final class DataSourceProcessingSnapshot {
274 
275  private final DataSourceIngestJob.Snapshot snapshot;
276 
277  private DataSourceProcessingSnapshot(DataSourceIngestJob.Snapshot snapshot) {
278  this.snapshot = snapshot;
279  }
280 
287  public String getDataSource() {
288  return snapshot.getDataSource();
289  }
290 
297  public boolean isCancelled() {
298  return snapshot.isCancelled();
299  }
300 
307  return snapshot.getCancellationReason();
308  }
309 
317  public List<String> getCancelledDataSourceIngestModules() {
318  return snapshot.getCancelledDataSourceIngestModules();
319  }
320 
321  }
322 
326  private ProgressSnapshot(boolean getIngestTasksSnapshot) {
327  dataSourceModule = null;
328  fileIngestRunning = false;
329  fileIngestStartTime = null;
330  dataSourceProcessingSnapshots = new ArrayList<>();
331  for (DataSourceIngestJob dataSourceJob : dataSourceJobs.values()) {
332  DataSourceIngestJob.Snapshot snapshot = dataSourceJob.getSnapshot(getIngestTasksSnapshot);
333  dataSourceProcessingSnapshots.add(new DataSourceProcessingSnapshot(snapshot));
334  if (null == dataSourceModule) {
335  DataSourceIngestPipeline.PipelineModule module = snapshot.getDataSourceLevelIngestModule();
336  if (null != module) {
337  dataSourceModule = new DataSourceIngestModuleHandle(dataSourceJobs.get(snapshot.getJobId()), module);
338  }
339  }
340  if (snapshot.fileIngestIsRunning()) {
341  fileIngestRunning = true;
342  }
343  Date childFileIngestStartTime = snapshot.fileIngestStartTime();
344  if (null != childFileIngestStartTime && (null == fileIngestStartTime || childFileIngestStartTime.before(fileIngestStartTime))) {
345  fileIngestStartTime = childFileIngestStartTime;
346  }
347  }
348  this.jobCancelled = isCancelled();
350  }
351 
359  return this.dataSourceModule;
360  }
361 
368  public boolean fileIngestIsRunning() {
369  return this.fileIngestRunning;
370  }
371 
377  public Date fileIngestStartTime() {
378  return new Date(this.fileIngestStartTime.getTime());
379  }
380 
387  public boolean isCancelled() {
388  return this.jobCancelled;
389  }
390 
397  return this.jobCancellationReason;
398  }
399 
405  public List<DataSourceProcessingSnapshot> getDataSourceSnapshots() {
406  return Collections.unmodifiableList(this.dataSourceProcessingSnapshots);
407  }
408 
409  }
410 
416  public static class DataSourceIngestModuleHandle {
417 
418  private final DataSourceIngestJob job;
419  private final DataSourceIngestPipeline.PipelineModule module;
420  private final boolean cancelled;
421 
431  private DataSourceIngestModuleHandle(DataSourceIngestJob job, DataSourceIngestPipeline.PipelineModule module) {
432  this.job = job;
433  this.module = module;
434  this.cancelled = job.currentDataSourceIngestModuleIsCancelled();
435  }
436 
443  public String displayName() {
444  return this.module.getDisplayName();
445  }
446 
453  public Date startTime() {
454  return this.module.getProcessingStartTime();
455  }
456 
463  public boolean isCancelled() {
464  return this.cancelled;
465  }
466 
472  public void cancel() {
484  if (this.job.getCurrentDataSourceIngestModule() == this.module) {
485  this.job.cancelCurrentDataSourceIngestModule();
486  }
487  }
488 
489  }
490 
491 }
DataSourceIngestModuleHandle(DataSourceIngestJob job, DataSourceIngestPipeline.PipelineModule module)
Definition: IngestJob.java:431
static synchronized IngestManager getInstance()
final DataSourceIngestPipeline.PipelineModule module
Definition: IngestJob.java:419
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:358
List< DataSourceProcessingSnapshot > getDataSourceSnapshots()
Definition: IngestJob.java:405
final IngestJob.CancellationReason jobCancellationReason
Definition: IngestJob.java:267
CancellationReason getCancellationReason()
Definition: IngestJob.java:224
static final AtomicLong nextId
Definition: IngestJob.java:65
ProgressSnapshot(boolean getIngestTasksSnapshot)
Definition: IngestJob.java:326
volatile CancellationReason cancellationReason
Definition: IngestJob.java:69
ProgressSnapshot getSnapshot(boolean getIngestTasksSnapshot)
Definition: IngestJob.java:173
final List< DataSourceProcessingSnapshot > dataSourceProcessingSnapshots
Definition: IngestJob.java:262

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