6161import javax .annotation .concurrent .GuardedBy ;
6262import javax .annotation .concurrent .Immutable ;
6363import javax .annotation .concurrent .ThreadSafe ;
64+ import org .openide .util .Exceptions ;
6465import org .openide .util .Lookup ;
6566import org .sleuthkit .autopsy .casemodule .Case ;
6667import org .sleuthkit .autopsy .casemodule .Case .CaseType ;
9394import org .sleuthkit .autopsy .experimental .configuration .SharedConfiguration .SharedConfigurationException ;
9495import org .sleuthkit .autopsy .datasourceprocessors .AutoIngestDataSourceProcessor ;
9596import org .sleuthkit .autopsy .datasourceprocessors .AutoIngestDataSourceProcessor .AutoIngestDataSourceProcessorException ;
97+ import org .sleuthkit .autopsy .experimental .autoingest .AutoIngestJob .AutoIngestJobException ;
9698import org .sleuthkit .autopsy .ingest .IngestJob ;
9799import org .sleuthkit .autopsy .ingest .IngestJob .CancellationReason ;
98100import 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 ) {
@@ -1015,92 +1017,103 @@ public FileVisitResult preVisitDirectory(Path dirPath, BasicFileAttributes dirAt
10151017 * @return TERMINATE if auto ingest is shutting down, CONTINUE if it has
10161018 * not.
10171019 *
1018- * @throws IOException if an I/O error occurs, but this implementation
1019- * does not throw.
10201020 */
10211021 @ Override
1022- public FileVisitResult visitFile (Path filePath , BasicFileAttributes attrs ) throws IOException {
1022+ public FileVisitResult visitFile (Path filePath , BasicFileAttributes attrs ) {
10231023 if (Thread .currentThread ().isInterrupted ()) {
10241024 return TERMINATE ;
10251025 }
10261026
1027- Manifest manifest = null ;
1028- for (ManifestFileParser parser : Lookup .getDefault ().lookupAll (ManifestFileParser .class )) {
1029- if (parser .fileIsManifest (filePath )) {
1030- try {
1031- manifest = parser .parse (filePath );
1032- break ;
1033- } catch (ManifestFileParserException ex ) {
1034- SYS_LOGGER .log (Level .SEVERE , String .format ("Error attempting to parse %s with parser %s" , filePath , parser .getClass ().getCanonicalName ()), ex );
1027+ try {
1028+ Manifest manifest = null ;
1029+ for (ManifestFileParser parser : Lookup .getDefault ().lookupAll (ManifestFileParser .class )) {
1030+ if (parser .fileIsManifest (filePath )) {
1031+ try {
1032+ manifest = parser .parse (filePath );
1033+ break ;
1034+ } catch (ManifestFileParserException ex ) {
1035+ SYS_LOGGER .log (Level .SEVERE , String .format ("Error attempting to parse %s with parser %s" , filePath , parser .getClass ().getCanonicalName ()), ex );
1036+ }
1037+ }
1038+ if (Thread .currentThread ().isInterrupted ()) {
1039+ return TERMINATE ;
10351040 }
10361041 }
1042+
10371043 if (Thread .currentThread ().isInterrupted ()) {
10381044 return TERMINATE ;
10391045 }
1040- }
1041-
1042- if (Thread .currentThread ().isInterrupted ()) {
1043- return TERMINATE ;
1044- }
10451046
1046- if (null != manifest ) {
1047- /*
1047+ if (null != manifest ) {
1048+ /*
10481049 * Update the mapping of case names to manifest paths that is
10491050 * used for case deletion.
1050- */
1051- String caseName = manifest .getCaseName ();
1052- Path manifestPath = manifest .getFilePath ();
1053- if (casesToManifests .containsKey (caseName )) {
1054- Set <Path > manifestPaths = casesToManifests .get (caseName );
1055- manifestPaths .add (manifestPath );
1056- } else {
1057- Set <Path > manifestPaths = new HashSet <>();
1058- manifestPaths .add (manifestPath );
1059- casesToManifests .put (caseName , manifestPaths );
1060- }
1051+ */
1052+ String caseName = manifest .getCaseName ();
1053+ Path manifestPath = manifest .getFilePath ();
1054+ if (casesToManifests .containsKey (caseName )) {
1055+ Set <Path > manifestPaths = casesToManifests .get (caseName );
1056+ manifestPaths .add (manifestPath );
1057+ } else {
1058+ Set <Path > manifestPaths = new HashSet <>();
1059+ manifestPaths .add (manifestPath );
1060+ casesToManifests .put (caseName , manifestPaths );
1061+ }
10611062
1062- /*
1063+ /*
10631064 * Add a job to the pending jobs queue, the completed jobs list,
10641065 * or do crashed job recovery, as required.
1065- */
1066- try {
1067- byte [] rawData = coordinationService .getNodeData (CoordinationService .CategoryNode .MANIFESTS , manifestPath .toString ());
1068- if (null != rawData && rawData .length > 0 ) {
1069- try {
1070- AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData (rawData );
1071- AutoIngestJob .ProcessingStatus processingStatus = nodeData .getProcessingStatus ();
1072- switch (processingStatus ) {
1073- case PENDING :
1074- addPendingJob (manifest , nodeData );
1075- break ;
1076- case PROCESSING :
1077- doRecoveryIfCrashed (manifest , nodeData );
1078- break ;
1079- case COMPLETED :
1080- addCompletedJob (manifest , nodeData );
1081- break ;
1082- case DELETED :
1083- /*
1066+ */
1067+ try {
1068+ byte [] rawData = coordinationService .getNodeData (CoordinationService .CategoryNode .MANIFESTS , manifestPath .toString ());
1069+ if (null != rawData && rawData .length > 0 ) {
1070+ try {
1071+ AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData (rawData );
1072+ AutoIngestJob .ProcessingStatus processingStatus = nodeData .getProcessingStatus ();
1073+ switch (processingStatus ) {
1074+ case PENDING :
1075+ addPendingJob (manifest , nodeData );
1076+ break ;
1077+ case PROCESSING :
1078+ doRecoveryIfCrashed (manifest , nodeData );
1079+ break ;
1080+ case COMPLETED :
1081+ addCompletedJob (manifest , nodeData );
1082+ break ;
1083+ case DELETED :
1084+ /*
10841085 * Ignore jobs marked as "deleted."
1085- */
1086- break ;
1087- default :
1088- SYS_LOGGER .log (Level .SEVERE , "Unknown ManifestNodeData.ProcessingStatus" );
1089- break ;
1086+ */
1087+ break ;
1088+ default :
1089+ SYS_LOGGER .log (Level .SEVERE , "Unknown ManifestNodeData.ProcessingStatus" );
1090+ break ;
1091+ }
1092+ } catch (AutoIngestJobNodeData .InvalidDataException | AutoIngestJobException ex ) {
1093+ SYS_LOGGER .log (Level .SEVERE , String .format ("Invalid auto ingest job node data for %s" , manifestPath ), ex );
1094+ }
1095+ } else {
1096+ try {
1097+ addNewPendingJob (manifest );
1098+ } catch (AutoIngestJobException ex ) {
1099+ SYS_LOGGER .log (Level .SEVERE , String .format ("Invalid manifest data for %s" , manifestPath ), ex );
10901100 }
1091- } catch (AutoIngestJobNodeData .InvalidDataException ex ) {
1092- SYS_LOGGER .log (Level .WARNING , String .format ("Invalid auto ingest job node data for %s" , manifestPath ), ex );
10931101 }
1094- } else {
1095- addNewPendingJob (manifest );
1102+ } catch (CoordinationServiceException ex ) {
1103+ SYS_LOGGER .log (Level .SEVERE , String .format ("Error transmitting node data for %s" , manifestPath ), ex );
1104+ return CONTINUE ;
1105+ } catch (InterruptedException ex ) {
1106+ Thread .currentThread ().interrupt ();
1107+ return TERMINATE ;
10961108 }
1097- } catch (CoordinationServiceException ex ) {
1098- SYS_LOGGER .log (Level .SEVERE , String .format ("Error transmitting node data for %s" , manifestPath ), ex );
1099- return CONTINUE ;
1100- } catch (InterruptedException ex ) {
1101- Thread .currentThread ().interrupt ();
1102- return TERMINATE ;
11031109 }
1110+
1111+ } catch (Exception ex ) {
1112+ // Catch all unhandled and unexpected exceptions. Otherwise one bad file
1113+ // can stop the entire input folder scanning. Given that the exception is unexpected,
1114+ // I'm hesitant to add logging which requires accessing or de-referencing data.
1115+ SYS_LOGGER .log (Level .SEVERE , "Unexpected exception in file visitor" , ex );
1116+ return CONTINUE ;
11041117 }
11051118
11061119 if (!Thread .currentThread ().isInterrupted ()) {
@@ -1122,7 +1135,7 @@ public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) throw
11221135 * blocked, i.e., if auto ingest is
11231136 * shutting down.
11241137 */
1125- private void addPendingJob (Manifest manifest , AutoIngestJobNodeData nodeData ) throws InterruptedException {
1138+ private void addPendingJob (Manifest manifest , AutoIngestJobNodeData nodeData ) throws InterruptedException , AutoIngestJobException {
11261139 AutoIngestJob job ;
11271140 if (nodeData .getVersion () == AutoIngestJobNodeData .getCurrentVersion ()) {
11281141 job = new AutoIngestJob (nodeData );
@@ -1176,7 +1189,7 @@ private void addPendingJob(Manifest manifest, AutoIngestJobNodeData nodeData) th
11761189 * blocked, i.e., if auto ingest is
11771190 * shutting down.
11781191 */
1179- private void addNewPendingJob (Manifest manifest ) throws InterruptedException {
1192+ private void addNewPendingJob (Manifest manifest ) throws InterruptedException , AutoIngestJobException {
11801193 /*
11811194 * Create the coordination service node data for the job. Note that
11821195 * getting the lock will create the node for the job (with no data)
@@ -1218,7 +1231,7 @@ private void addNewPendingJob(Manifest manifest) throws InterruptedException {
12181231 * blocked, i.e., if auto ingest is
12191232 * shutting down.
12201233 */
1221- private void doRecoveryIfCrashed (Manifest manifest , AutoIngestJobNodeData nodeData ) throws InterruptedException {
1234+ private void doRecoveryIfCrashed (Manifest manifest , AutoIngestJobNodeData nodeData ) throws InterruptedException , AutoIngestJobException {
12221235 /*
12231236 * Try to get an exclusive lock on the coordination service node for
12241237 * the job. If the lock cannot be obtained, another host in the auto
@@ -1314,7 +1327,7 @@ private void doRecoveryIfCrashed(Manifest manifest, AutoIngestJobNodeData nodeDa
13141327 * @throws CoordinationServiceException
13151328 * @throws InterruptedException
13161329 */
1317- private void addCompletedJob (Manifest manifest , AutoIngestJobNodeData nodeData ) throws CoordinationServiceException , InterruptedException {
1330+ private void addCompletedJob (Manifest manifest , AutoIngestJobNodeData nodeData ) throws CoordinationServiceException , InterruptedException , AutoIngestJobException {
13181331 Path caseDirectoryPath = PathUtils .findCaseDirectory (rootOutputDirectory , manifest .getCaseName ());
13191332 if (null != caseDirectoryPath ) {
13201333 AutoIngestJob job ;
0 commit comments