Skip to content

Commit 91eaf88

Browse files
committed
Catching and handling exceptions caused by bad ZK node data so that they don't stop input folder scans
1 parent 5eefb7a commit 91eaf88

File tree

3 files changed

+99
-57
lines changed

3 files changed

+99
-57
lines changed

Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestJob.java

Lines changed: 84 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -89,30 +89,34 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
8989
*
9090
* @param manifest The manifest for an automated ingest job.
9191
*/
92-
AutoIngestJob(Manifest manifest) {
93-
/*
94-
* Version 0 fields.
95-
*/
96-
this.manifest = manifest;
97-
this.nodeName = "";
98-
this.caseDirectoryPath = "";
99-
this.priority = DEFAULT_PRIORITY;
100-
this.stage = Stage.PENDING;
101-
this.stageStartDate = manifest.getDateFileCreated();
102-
this.dataSourceProcessor = null;
103-
this.ingestJob = null;
104-
this.cancelled = false;
105-
this.completed = false;
106-
this.completedDate = new Date(0);
107-
this.errorsOccurred = false;
108-
109-
/*
110-
* Version 1 fields.
111-
*/
112-
this.version = CURRENT_VERSION;
113-
this.processingStatus = ProcessingStatus.PENDING;
114-
this.numberOfCrashes = 0;
115-
this.stageDetails = this.getProcessingStageDetails();
92+
AutoIngestJob(Manifest manifest) throws AutoIngestJobException {
93+
try {
94+
/*
95+
* Version 0 fields.
96+
*/
97+
this.manifest = manifest;
98+
this.nodeName = "";
99+
this.caseDirectoryPath = "";
100+
this.priority = DEFAULT_PRIORITY;
101+
this.stage = Stage.PENDING;
102+
this.stageStartDate = manifest.getDateFileCreated();
103+
this.dataSourceProcessor = null;
104+
this.ingestJob = null;
105+
this.cancelled = false;
106+
this.completed = false;
107+
this.completedDate = new Date(0);
108+
this.errorsOccurred = false;
109+
110+
/*
111+
* Version 1 fields.
112+
*/
113+
this.version = CURRENT_VERSION;
114+
this.processingStatus = ProcessingStatus.PENDING;
115+
this.numberOfCrashes = 0;
116+
this.stageDetails = this.getProcessingStageDetails();
117+
} catch (Exception ex) {
118+
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
119+
}
116120
}
117121

118122
/**
@@ -122,30 +126,34 @@ public final class AutoIngestJob implements Comparable<AutoIngestJob>, Serializa
122126
* @param nodeData The coordination service node data for an automated
123127
* ingest job.
124128
*/
125-
AutoIngestJob(AutoIngestJobNodeData nodeData) {
126-
/*
127-
* Version 0 fields.
128-
*/
129-
this.manifest = new Manifest(nodeData.getManifestFilePath(), nodeData.getManifestFileDate(), nodeData.getCaseName(), nodeData.getDeviceId(), nodeData.getDataSourcePath(), Collections.emptyMap());
130-
this.nodeName = nodeData.getProcessingHostName();
131-
this.caseDirectoryPath = nodeData.getCaseDirectoryPath().toString();
132-
this.priority = nodeData.getPriority();
133-
this.stage = nodeData.getProcessingStage();
134-
this.stageStartDate = nodeData.getProcessingStageStartDate();
135-
this.dataSourceProcessor = null; // Transient data not in node data.
136-
this.ingestJob = null; // Transient data not in node data.
137-
this.cancelled = false; // Transient data not in node data.
138-
this.completed = false; // Transient data not in node data.
139-
this.completedDate = nodeData.getCompletedDate();
140-
this.errorsOccurred = nodeData.getErrorsOccurred();
141-
142-
/*
143-
* Version 1 fields.
144-
*/
145-
this.version = CURRENT_VERSION;
146-
this.processingStatus = nodeData.getProcessingStatus();
147-
this.numberOfCrashes = nodeData.getNumberOfCrashes();
148-
this.stageDetails = this.getProcessingStageDetails();
129+
AutoIngestJob(AutoIngestJobNodeData nodeData) throws AutoIngestJobException {
130+
try {
131+
/*
132+
* Version 0 fields.
133+
*/
134+
this.manifest = new Manifest(nodeData.getManifestFilePath(), nodeData.getManifestFileDate(), nodeData.getCaseName(), nodeData.getDeviceId(), nodeData.getDataSourcePath(), Collections.emptyMap());
135+
this.nodeName = nodeData.getProcessingHostName();
136+
this.caseDirectoryPath = nodeData.getCaseDirectoryPath().toString();
137+
this.priority = nodeData.getPriority();
138+
this.stage = nodeData.getProcessingStage();
139+
this.stageStartDate = nodeData.getProcessingStageStartDate();
140+
this.dataSourceProcessor = null; // Transient data not in node data.
141+
this.ingestJob = null; // Transient data not in node data.
142+
this.cancelled = false; // Transient data not in node data.
143+
this.completed = false; // Transient data not in node data.
144+
this.completedDate = nodeData.getCompletedDate();
145+
this.errorsOccurred = nodeData.getErrorsOccurred();
146+
147+
/*
148+
* Version 1 fields.
149+
*/
150+
this.version = CURRENT_VERSION;
151+
this.processingStatus = nodeData.getProcessingStatus();
152+
this.numberOfCrashes = nodeData.getNumberOfCrashes();
153+
this.stageDetails = this.getProcessingStageDetails();
154+
} catch (Exception ex) {
155+
throw new AutoIngestJobException(String.format("Error creating automated ingest job"), ex);
156+
}
149157
}
150158

151159
/**
@@ -622,5 +630,33 @@ Date getStartDate() {
622630
}
623631

624632
}
633+
634+
/**
635+
* Exception thrown when there is a problem creating auto ingest job.
636+
*/
637+
final static class AutoIngestJobException extends Exception {
625638

639+
private static final long serialVersionUID = 1L;
640+
641+
/**
642+
* Constructs an exception to throw when there is a problem creating
643+
* auto ingest job.
644+
*
645+
* @param message The exception message.
646+
*/
647+
private AutoIngestJobException(String message) {
648+
super(message);
649+
}
650+
651+
/**
652+
* Constructs an exception to throw when there is a problem creating
653+
* auto ingest job.
654+
*
655+
* @param message The exception message.
656+
* @param cause The cause of the exception, if it was an exception.
657+
*/
658+
private AutoIngestJobException(String message, Throwable cause) {
659+
super(message, cause);
660+
}
661+
}
626662
}

Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import javax.annotation.concurrent.GuardedBy;
6262
import javax.annotation.concurrent.Immutable;
6363
import javax.annotation.concurrent.ThreadSafe;
64+
import org.openide.util.Exceptions;
6465
import org.openide.util.Lookup;
6566
import org.sleuthkit.autopsy.casemodule.Case;
6667
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
@@ -93,6 +94,7 @@
9394
import org.sleuthkit.autopsy.experimental.configuration.SharedConfiguration.SharedConfigurationException;
9495
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
9596
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException;
97+
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestJob.AutoIngestJobException;
9698
import org.sleuthkit.autopsy.ingest.IngestJob;
9799
import org.sleuthkit.autopsy.ingest.IngestJob.CancellationReason;
98100
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
@@ -759,7 +761,7 @@ CaseDeletionResult deleteCase(String caseName, Path caseDirectoryPath) {
759761
AutoIngestJob deletedJob = new AutoIngestJob(nodeData);
760762
deletedJob.setProcessingStatus(AutoIngestJob.ProcessingStatus.DELETED);
761763
this.updateCoordinationServiceNode(deletedJob);
762-
} catch (AutoIngestJobNodeData.InvalidDataException ex) {
764+
} catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) {
763765
SYS_LOGGER.log(Level.WARNING, String.format("Invalid auto ingest job node data for %s", manifestPath), ex);
764766
return CaseDeletionResult.PARTIALLY_DELETED;
765767
} catch (InterruptedException | CoordinationServiceException ex) {
@@ -1088,11 +1090,15 @@ public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) throw
10881090
SYS_LOGGER.log(Level.SEVERE, "Unknown ManifestNodeData.ProcessingStatus");
10891091
break;
10901092
}
1091-
} catch (AutoIngestJobNodeData.InvalidDataException ex) {
1092-
SYS_LOGGER.log(Level.WARNING, String.format("Invalid auto ingest job node data for %s", manifestPath), ex);
1093+
} catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJobException ex) {
1094+
SYS_LOGGER.log(Level.SEVERE, String.format("Invalid auto ingest job node data for %s", manifestPath), ex);
10931095
}
10941096
} else {
1095-
addNewPendingJob(manifest);
1097+
try {
1098+
addNewPendingJob(manifest);
1099+
} catch (AutoIngestJobException ex) {
1100+
SYS_LOGGER.log(Level.SEVERE, String.format("Invalid manifest data for %s", manifestPath), ex);
1101+
}
10961102
}
10971103
} catch (CoordinationServiceException ex) {
10981104
SYS_LOGGER.log(Level.SEVERE, String.format("Error transmitting node data for %s", manifestPath), ex);
@@ -1122,7 +1128,7 @@ public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) throw
11221128
* blocked, i.e., if auto ingest is
11231129
* shutting down.
11241130
*/
1125-
private void addPendingJob(Manifest manifest, AutoIngestJobNodeData nodeData) throws InterruptedException {
1131+
private void addPendingJob(Manifest manifest, AutoIngestJobNodeData nodeData) throws InterruptedException, AutoIngestJobException {
11261132
AutoIngestJob job;
11271133
if (nodeData.getVersion() == AutoIngestJobNodeData.getCurrentVersion()) {
11281134
job = new AutoIngestJob(nodeData);
@@ -1176,7 +1182,7 @@ private void addPendingJob(Manifest manifest, AutoIngestJobNodeData nodeData) th
11761182
* blocked, i.e., if auto ingest is
11771183
* shutting down.
11781184
*/
1179-
private void addNewPendingJob(Manifest manifest) throws InterruptedException {
1185+
private void addNewPendingJob(Manifest manifest) throws InterruptedException, AutoIngestJobException {
11801186
/*
11811187
* Create the coordination service node data for the job. Note that
11821188
* getting the lock will create the node for the job (with no data)
@@ -1218,7 +1224,7 @@ private void addNewPendingJob(Manifest manifest) throws InterruptedException {
12181224
* blocked, i.e., if auto ingest is
12191225
* shutting down.
12201226
*/
1221-
private void doRecoveryIfCrashed(Manifest manifest, AutoIngestJobNodeData nodeData) throws InterruptedException {
1227+
private void doRecoveryIfCrashed(Manifest manifest, AutoIngestJobNodeData nodeData) throws InterruptedException, AutoIngestJobException {
12221228
/*
12231229
* Try to get an exclusive lock on the coordination service node for
12241230
* the job. If the lock cannot be obtained, another host in the auto
@@ -1314,7 +1320,7 @@ private void doRecoveryIfCrashed(Manifest manifest, AutoIngestJobNodeData nodeDa
13141320
* @throws CoordinationServiceException
13151321
* @throws InterruptedException
13161322
*/
1317-
private void addCompletedJob(Manifest manifest, AutoIngestJobNodeData nodeData) throws CoordinationServiceException, InterruptedException {
1323+
private void addCompletedJob(Manifest manifest, AutoIngestJobNodeData nodeData) throws CoordinationServiceException, InterruptedException, AutoIngestJobException {
13181324
Path caseDirectoryPath = PathUtils.findCaseDirectory(rootOutputDirectory, manifest.getCaseName());
13191325
if (null != caseDirectoryPath) {
13201326
AutoIngestJob job;

Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestMonitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ private JobsSnapshot queryCoordinationService() {
265265
}
266266
} catch (InterruptedException ex) {
267267
LOGGER.log(Level.SEVERE, String.format("Unexpected interrupt while retrieving coordination service node data for '%s'", node), ex);
268-
} catch (AutoIngestJobNodeData.InvalidDataException ex) {
268+
} catch (AutoIngestJobNodeData.InvalidDataException | AutoIngestJob.AutoIngestJobException ex) {
269269
LOGGER.log(Level.SEVERE, String.format("Unable to use node data for '%s'", node), ex);
270270
}
271271
}

0 commit comments

Comments
 (0)