diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobStartResult.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobStartResult.java new file mode 100755 index 0000000000..ac8f7a0e99 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobStartResult.java @@ -0,0 +1,77 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2013-2015 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.ingest; + +import java.util.ArrayList; +import java.util.List; + +public class IngestJobStartResult { + + private IngestJob job; // may be null + private IngestManagerException startupException; // may be null + private List moduleErrors; // may be empty + + public IngestJobStartResult() { + job = null; + startupException = null; + moduleErrors = new ArrayList<>(); + } + + /** + * @return the job + */ + public IngestJob getJob() { + return job; + } + + /** + * @param job the job to set + */ + public void setJob(IngestJob job) { + this.job = job; + } + + /** + * @return the startupException + */ + public IngestManagerException getStartupException() { + return startupException; + } + + /** + * @param startupException the startupException to set + */ + public void setStartupException(IngestManagerException startupException) { + this.startupException = startupException; + } + + /** + * @return the moduleErrors + */ + public List getModuleErrors() { + return moduleErrors; + } + + /** + * @param moduleErrors the moduleErrors to set + */ + public void setModuleErrors(List moduleErrors) { + this.moduleErrors = moduleErrors; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java index 550db98dce..10414ad6d6 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -66,7 +66,6 @@ import org.sleuthkit.datamodel.Content; * data sources by ingest modules. */ @NbBundle.Messages({ - "IngestAborted=Ingest Aborted.", "# {0} - error message", "IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList=\nErrors: \n{0}", "IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution=Please disable the failed modules or fix the errors and then restart ingest \nby right clicking on the data source and selecting Run Ingest Modules.", "IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg=Unable to start up one or more ingest modules, ingest job cancelled.", @@ -496,23 +495,19 @@ public class IngestManager { * * @param dataSources The data sources to process. * @param settings The settings for the ingest job. - * @param errors Out parameter. This is a list of errors encountered. * - * @return The ingest job that was started on success or null on failure. + * @return The IngestJobStartResult describing the results of attempting to + * start the ingest job. */ - public synchronized IngestJob beginIngestJob(Collection dataSources, IngestJobSettings settings, List errors) { + public synchronized IngestJobStartResult beginIngestJob(Collection dataSources, IngestJobSettings settings) { + IngestJobStartResult ingestJobStartResult = new IngestJobStartResult(); if (this.jobCreationIsEnabled) { IngestJob job = new IngestJob(dataSources, settings, RuntimeProperties.coreComponentsAreActive()); if (job.hasIngestPipeline()) { - errors.addAll(this.startIngestJob(job)); // capture any errors - if (errors.isEmpty()) { - return job; - } else { - return null; - } + ingestJobStartResult = this.startIngestJob(job); // Start job } } - return null; + return ingestJobStartResult; } /** @@ -527,8 +522,7 @@ public class IngestManager { */ @Deprecated public synchronized IngestJob startIngestJob(Collection dataSources, IngestJobSettings settings) { - List ignored = new ArrayList<>(); - return beginIngestJob(dataSources, settings, ignored); + return beginIngestJob(dataSources, settings).getJob(); } /** @@ -536,9 +530,12 @@ public class IngestManager { * * @param job The ingest job to start. * - * @return A list of errors, empty if the job was successfully started + * @return The IngestJobStartResult describing the results of attempting to + * start the ingest job. */ - private List startIngestJob(IngestJob job) { + private IngestJobStartResult startIngestJob(IngestJob job) { + IngestJobStartResult ingestJobStartResult = new IngestJobStartResult(); + ingestJobStartResult.setJob(job); if (this.jobCreationIsEnabled) { // multi-user cases must have multi-user database service running if (Case.getCurrentCase().getCaseType() == Case.CaseType.MULTI_USER_CASE) { @@ -558,10 +555,12 @@ public class IngestManager { }); } // abort ingest - return Collections.emptyList(); + ingestJobStartResult.setStartupException(new IngestManagerException("Ingest aborted.", new Exception("Remote database is down"))); // KDM + return ingestJobStartResult; } - } catch (ServicesMonitor.ServicesMonitorException ignore) { - return Collections.emptyList(); + } catch (ServicesMonitor.ServicesMonitorException ex) { + ingestJobStartResult.setStartupException(new IngestManagerException("Ingest aborted.", ex)); + return ingestJobStartResult; } } @@ -572,15 +571,15 @@ public class IngestManager { synchronized (jobsById) { jobsById.put(job.getId(), job); } - List errors = job.start(); - if (errors.isEmpty()) { + ingestJobStartResult.setModuleErrors(job.start()); + if (ingestJobStartResult.getModuleErrors().isEmpty()) { this.fireIngestJobStarted(job.getId()); IngestManager.logger.log(Level.INFO, "Ingest job {0} started", job.getId()); //NON-NLS } else { synchronized (jobsById) { this.jobsById.remove(job.getId()); } - for (IngestModuleError error : errors) { + for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) { logger.log(Level.SEVERE, String.format("Error starting %s ingest module for job %d", error.getModuleDisplayName(), job.getId()), error.getModuleError()); //NON-NLS } IngestManager.logger.log(Level.SEVERE, "Ingest job {0} could not be started", job.getId()); //NON-NLS @@ -589,7 +588,7 @@ public class IngestManager { @Override public void run() { StringBuilder moduleStartUpErrors = new StringBuilder(); - for (IngestModuleError error : errors) { + for (IngestModuleError error : ingestJobStartResult.getModuleErrors()) { String moduleName = error.getModuleDisplayName(); moduleStartUpErrors.append(moduleName); moduleStartUpErrors.append(": "); @@ -608,9 +607,9 @@ public class IngestManager { }); } } - return errors; + } - return Collections.emptyList(); + return ingestJobStartResult; } synchronized void finishIngestJob(IngestJob job) { diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestManagerException.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestManagerException.java new file mode 100755 index 0000000000..3b72b8cfbe --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestManagerException.java @@ -0,0 +1,42 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2016 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.ingest; + +/** + * Encapsulates an exception thrown by an ingest module during an operation such + * as startup or shut down with an exception object for the error that occurred. + */ +public final class IngestManagerException { + + private final String message; + private final Throwable cause; + + IngestManagerException(String message, Throwable cause) { + this.message = message; + this.cause = cause; + } + + public String getMessage() { + return this.message; + } + + public Throwable getCause() { + return this.cause; + } +}