Merge pull request #958 from rcordovano/ingest_job_configurator_refactor

Ingest job configurator refactor
This commit is contained in:
Richard Cordovano 2014-11-16 17:42:59 -05:00
commit a8f31e199e
10 changed files with 738 additions and 539 deletions

View File

@ -18,8 +18,6 @@
*/
package org.sleuthkit.autopsy.casemodule;
import org.sleuthkit.autopsy.ingest.IngestJobConfigurator;
import org.openide.util.NbBundle;
import java.awt.Color;
import java.awt.Component;
@ -37,6 +35,9 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
* second panel of add image wizard, allows user to configure ingest modules.
*
@ -46,7 +47,8 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDescriptor> {
private static final Logger logger = Logger.getLogger(AddImageWizardIngestConfigPanel.class.getName());
private IngestJobConfigurator ingestConfig;
private IngestJobSettings ingestJobSettings;
/**
* The visual component that displays this panel. If you need to access the
* component from this class, just use getComponent().
@ -60,10 +62,10 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
// task that will clean up the created database file if the wizard is cancelled before it finishes
private AddImageAction.CleanupTask cleanupTask;
private AddImageAction addImageAction;
private final AddImageAction addImageAction;
private AddImageWizardAddingProgressPanel progressPanel;
private AddImageWizardChooseDataSourcePanel dataSourcePanel;
private final AddImageWizardAddingProgressPanel progressPanel;
private final AddImageWizardChooseDataSourcePanel dataSourcePanel;
private DataSourceProcessor dsProcessor;
@ -73,8 +75,8 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
this.progressPanel = proPanel;
this.dataSourcePanel = dsPanel;
ingestConfig = new IngestJobConfigurator(AddImageWizardIngestConfigPanel.class.getCanonicalName());
List<String> messages = ingestConfig.getIngestJobConfigWarnings();
this.ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName());
List<String> messages = this.ingestJobSettings.getWarnings();
if (messages.isEmpty() == false) {
StringBuilder warning = new StringBuilder();
for (String message : messages) {
@ -95,7 +97,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
@Override
public Component getComponent() {
if (component == null) {
component = new AddImageWizardIngestConfigVisual(ingestConfig.getIngestJobConfigPanel());
component = new AddImageWizardIngestConfigVisual(new IngestJobSettingsPanel(this.ingestJobSettings));
}
return component;
}
@ -188,8 +190,16 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
*/
@Override
public void storeSettings(WizardDescriptor settings) {
ingestConfig.saveIngestJobConfig();
this.ingestJobSettings.save();
List<String> messages = this.ingestJobSettings.getWarnings();
if (messages.isEmpty() == false) {
StringBuilder warning = new StringBuilder();
for (String message : messages) {
warning.append(message).append("\n");
}
JOptionPane.showMessageDialog(null, warning.toString());
}
// Start ingest if it hasn't already been started
readyToIngest = true;
startIngest();
@ -202,9 +212,11 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
private void startIngest() {
if (!newContents.isEmpty() && readyToIngest && !ingested) {
ingested = true;
ingestConfig.startIngestJobs(newContents);
IngestManager ingestManager = IngestManager.getInstance();
for (Content content : newContents) {
ingestManager.startIngestJob(content, ingestJobSettings, true);
}
progressPanel.setStateFinished();
}
}

View File

@ -21,8 +21,6 @@ IngestJob.progress.dataSourceIngest.displayName={0} for {1}
IngestJob.progress.fileIngest.displayName=Analyzing files from {0}
IngestJob.progress.cancelling={0} (Cancelling...)
IngestJob.cancellationDialog.title=Cancel Ingest
IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText=Processes unallocated space, such as deleted files. Produces more complete results, but it may take longer to process on large images.
IngestJobConfigurationPanel.processUnallocCheckbox.text=Process Unallocated Space
IngestDialog.title.text=Ingest Modules
IngestDialog.startButton.title=Start
IngestDialog.closeButton.title=Close
@ -50,8 +48,6 @@ IngestMessageTopComponent.displayReport.option.GenRpt=Generate Report
IngestMessageTopComponent.msgDlg.ingestRpt.text=Ingest Report
IngestMonitor.mgrErrMsg.lowDiskSpace.title=Ingest stopped - low disk space on {0}
IngestMonitor.mgrErrMsg.lowDiskSpace.msg=Stopping ingest due to low disk space on disk {0}. \nEnsure the Case drive has at least 1GB free space and restart ingest.
IngestJobConfigurationPanel.advancedButton.text=Advanced
IngestJobConfigurationPanel.advancedButton.actionCommand=Advanced
IngestManager.StartIngestJobsTask.run.displayName=Starting ingest
IngestManager.StartIngestJobsTask.run.cancelling={0} (Cancelling...)
IngestMessagePanel.sortByComboBox.model.time=Time
@ -62,11 +58,11 @@ IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg=Unable to start up one o
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.dlgErrorList=\nErrors\: \n{0}
IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle=Ingest Failure
IngestJobConfigurator.createModuleSettingsFolderForContext.exception.msg=Failed to create ingest module settings folder, cannot save settings.
IngestJobConfigurator.createModuleSettingsFolderForContext.exception.title=Ingest Job Initialization Failure
IngestJobConfigurator.saveJobSettings.usermsg=Failed to save ingest job settings for {0} module.
IngestJobConfigurator.saveJobSettings.usermsg.title=Ingest Job Settings
IngestJobConfigurationPanel.descriptionLabel.text=
IngestJobSettings.createModuleSettingsFolder.warning=Failed to create ingest module settings folder, cannot save settings.
IngestJobSettings.missingModule.warning=Previously loaded {0} module could not be found.
IngestJobSettings.save.warning=Failed to save ingest job settings for {0} module.
IngestJobSettings.moduleSettingsLoad.warning=Error loading ingest job settings for {0} module for {1} context, using defaults.
IngestJobSettings.moduleSettingsSave.warning=Error saving ingest job settings for {0} module for {1} context.
IngestProgressSnapshotDialog.title.text=Ingest Progress Snapshot
IngestProgressSnapshotPanel.refreshButton.text=Refresh
IngestProgressSnapshotPanel.closeButton.text=Close
@ -85,3 +81,8 @@ DataSourceIngestCancellationPanel.cancelCurrentModuleRadioButton.text=Cancel cur
FileIngestCancellationPanel.cancelIngestJobRadioButton.text=Cancel data source ingest and file ingest
FileIngestCancellationPanel.cancelFileIngestRadioButton.text=Cancel file ingest only
DataSourceIngestCancellationPanel.cancelAllModulesRadioButton.text=Cancel all ingest modules
IngestJobSettingsPanel.advancedButton.actionCommand=Advanced
IngestJobSettingsPanel.advancedButton.text=Advanced
IngestJobSettingsPanel.processUnallocCheckbox.toolTipText=Processes unallocated space, such as deleted files. Produces more complete results, but it may take longer to process on large images.
IngestJobSettingsPanel.processUnallocCheckbox.text=Process Unallocated Space
IngestJobSettingsPanel.descriptionLabel.text=

View File

@ -6,10 +6,6 @@ IngestDialog.title.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u
IngestJob.progress.cancelling={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
IngestJob.progress.dataSourceIngest.displayName={1}\u306e{0}
IngestJob.progress.fileIngest.displayName={0}\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u89e3\u6790\u4e2d
IngestJobConfigurationPanel.advancedButton.actionCommand=\u30a2\u30c9\u30d0\u30f3\u30b9
IngestJobConfigurationPanel.advancedButton.text=\u30a2\u30c9\u30d0\u30f3\u30b9
IngestJobConfigurationPanel.processUnallocCheckbox.text=\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\u306e\u51e6\u7406
IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText=\u524a\u9664\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u7b49\u306e\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\u3092\u51e6\u7406\u3002\u3088\u308a\u5b8c\u5168\u306a\u7d50\u679c\u304c\u51fa\u307e\u3059\u304c\u3001\u5927\u304d\u3044\u30a4\u30e1\u30fc\u30b8\u3067\u306f\u51e6\u7406\u6642\u9593\u304c\u9577\u304f\u306a\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
IngestManager.moduleErr=\u30e2\u30b8\u30e5\u30fc\u30eb\u30a8\u30e9\u30fc
IngestManager.moduleErr.errListenToUpdates.msg=Ingest Manager\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d\u306b\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u30a8\u30e9\u30fc\u3092\u8d77\u3053\u3057\u307e\u3057\u305f\u3002\u3069\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u30ed\u30b0\u3067\u78ba\u8a8d\u3057\u3066\u4e0b\u3055\u3044\u3002\u4e00\u90e8\u306e\u30c7\u30fc\u30bf\u304c\u4e0d\u5b8c\u5168\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
IngestManager.StartIngestJobsTask.run.cancelling={0}\uff08\u30ad\u30e3\u30f3\u30bb\u30eb\u4e2d\u2026\uff09
@ -57,10 +53,8 @@ IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList=\n\u30a8\u30e9\u30
IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg=\uff11\u3064\u307e\u305f\u306f\u8907\u6570\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u30b9\u30bf\u30fc\u30c8\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u306f\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f\u3002
IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution=\u5931\u6557\u3057\u305f\u30e2\u30b8\u30e5\u30fc\u30eb\u3092\u7121\u52b9\u5316\u3059\u308b\u304b\u30a8\u30e9\u30fc\u3092\u89e3\u6c7a\u3057\u3001\u305d\u306e\u5f8c\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3001\n\u300c\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u5b9f\u884c\u300d\u3092\u9078\u629e\u3057\u3066\u3001\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3092\u30ea\u30b9\u30bf\u30fc\u30c8\u3057\u3066\u4e0b\u3055\u3044\u3002
IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u5931\u6557
IngestJobConfigurator.createModuleSettingsFolderForContext.exception.msg=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u8a2d\u5b9a\u30d5\u30a9\u30eb\u30c0\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3002
IngestJobConfigurator.createModuleSettingsFolderForContext.exception.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u521d\u671f\u5316\u306e\u5931\u6557
IngestJobConfigurator.saveJobSettings.usermsg={0}\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a\u306e\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
IngestJobConfigurator.saveJobSettings.usermsg.title=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a
IngestJobSettings.createModuleSettingsFolder.warning=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30e2\u30b8\u30e5\u30fc\u30eb\u8a2d\u5b9a\u30d5\u30a9\u30eb\u30c0\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u8a2d\u5b9a\u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3002
IngestJobSettings.save.error={0}\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30b8\u30e7\u30d6\u8a2d\u5b9a\u306e\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
IngestJob.progress.dataSourceIngest.initialDisplayName={0}\u3092\u89e3\u6790\u4e2d
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.dataSource=\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.elapsedTime=\u7d4c\u904e\u6642\u9593\uff08\u6642\uff1a\u5206\uff1a\u79d2\uff09
@ -75,3 +69,7 @@ IngestProgressSnapshotDialog.title.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u30
IngestProgressSnapshotPanel.closeButton.text=\u9589\u3058\u308b
IngestProgressSnapshotPanel.refreshButton.text=\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5
IngestProgressSnapshotPanel.SnapshotsTableModel.colNames.activity=\u30a2\u30af\u30c6\u30a3\u30d3\u30c6\u30a3
IngestJobSettingsPanel.advancedButton.actionCommand=\u30a2\u30c9\u30d0\u30f3\u30b9
IngestJobSettingsPanel.advancedButton.text=\u30a2\u30c9\u30d0\u30f3\u30b9
IngestJobSettingsPanel.processUnallocCheckbox.toolTipText=\u524a\u9664\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u7b49\u306e\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\u3092\u51e6\u7406\u3002\u3088\u308a\u5b8c\u5168\u306a\u7d50\u679c\u304c\u51fa\u307e\u3059\u304c\u3001\u5927\u304d\u3044\u30a4\u30e1\u30fc\u30b8\u3067\u306f\u51e6\u7406\u6642\u9593\u304c\u9577\u304f\u306a\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
IngestJobSettingsPanel.processUnallocCheckbox.text=\u672a\u5272\u308a\u5f53\u3066\u9818\u57df\u306e\u51e6\u7406

View File

@ -141,19 +141,16 @@ final class IngestJob {
* Starts an ingest job for a data source.
*
* @param dataSource The data source to ingest.
* @param ingestModuleTemplates The ingest module templates to use to create
* the ingest pipelines for the job.
* @param processUnallocatedSpace Whether or not the job should include
* processing of unallocated space.
* @param settings The settings for the job.
* @return A collection of ingest module start up errors, empty on success.
*/
static List<IngestModuleError> startJob(Content dataSource, List<IngestModuleTemplate> ingestModuleTemplates, boolean processUnallocatedSpace) {
static List<IngestModuleError> startJob(Content dataSource, IngestJobSettings settings) {
List<IngestModuleError> errors = new ArrayList<>();
if (IngestJob.jobCreationIsEnabled) {
long jobId = nextJobId.incrementAndGet();
IngestJob job = new IngestJob(jobId, dataSource, processUnallocatedSpace);
IngestJob job = new IngestJob(jobId, dataSource, settings.getProcessUnallocatedSpace());
IngestJob.jobsById.put(jobId, job);
errors = job.start(ingestModuleTemplates);
errors = job.start(settings.getEnabledIngestModuleTemplates());
if (errors.isEmpty() && job.hasIngestPipeline()) {
IngestManager.getInstance().fireIngestJobStarted(jobId);
IngestJob.logger.log(Level.INFO, "Ingest job {0} started", jobId);

View File

@ -18,298 +18,78 @@
*/
package org.sleuthkit.autopsy.ingest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.openide.util.NbBundle;
import org.openide.util.io.NbObjectInputStream;
import org.openide.util.io.NbObjectOutputStream;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.datamodel.Content;
/**
* Provides a mechanism for creating and persisting an ingest job configuration
* for a particular context and for launching ingest jobs that process one or
* more data sources using the ingest job configuration.
*
* @deprecated Use the IngestModuleSettings and IngestJobConfigurationPanel
* classes and IngestManager.startIngestJob() instead.
*/
@Deprecated
public final class IngestJobConfigurator {
private static final String ENABLED_INGEST_MODULES_KEY = "Enabled_Ingest_Modules"; //NON-NLS
private static final String DISABLED_INGEST_MODULES_KEY = "Disabled_Ingest_Modules"; //NON-NLS
private static final String PARSE_UNALLOC_SPACE_KEY = "Process_Unallocated_Space"; //NON-NLS
private static final String MODULE_SETTINGS_FOLDER_PATH = new StringBuilder(PlatformUtil.getUserConfigDirectory()).append(File.separator).append("IngestModuleSettings").toString(); //NON-NLS
private static final String MODULE_SETTINGS_FILE_EXT = ".settings"; //NON-NLS
private static final Logger logger = Logger.getLogger(IngestJobConfigurator.class.getName());
private final String launcherContext;
private String moduleSettingsFolderForContext = null;
private final List<String> warnings = new ArrayList<>();
private IngestJobConfigurationPanel ingestConfigPanel = null;
private final IngestJobSettings settings;
private final IngestJobSettingsPanel settingsPanel;
/**
* Constructs an ingest job launcher that creates and persists an ingest job
* configuration for a particular context and launches ingest jobs that
* process one or more data sources using the ingest job configuration.
* Constructs an ingest job launcher that creates and persists ingest job
* settings for a particular context and launches ingest jobs that
* process one or more data sources using the settings.
*
* @param launcherContext The context identifier.
* @param context The context identifier.
*/
public IngestJobConfigurator(String launcherContext) {
this.launcherContext = launcherContext;
createModuleSettingsFolderForContext();
// Get the ingest module factories discovered by the ingest module
// loader.
List<IngestModuleFactory> moduleFactories = IngestModuleFactoryLoader.getIngestModuleFactories();
HashSet<String> loadedModuleNames = new HashSet<>();
for (IngestModuleFactory moduleFactory : moduleFactories) {
loadedModuleNames.add(moduleFactory.getModuleDisplayName());
}
// Get the enabled and disabled ingest modules settings for the current
// context. Observe that the default settings make all loaded ingest
// modules enabled.
HashSet<String> enabledModuleNames = getModulesNamesFromSetting(ENABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(loadedModuleNames));
HashSet<String> disabledModuleNames = getModulesNamesFromSetting(DISABLED_INGEST_MODULES_KEY, "");
// Check for missing modules.
List<String> missingModuleNames = new ArrayList<>();
for (String moduleName : enabledModuleNames) {
if (!loadedModuleNames.contains(moduleName)) {
missingModuleNames.add(moduleName);
}
}
for (String moduleName : disabledModuleNames) {
if (!loadedModuleNames.contains(moduleName)) {
missingModuleNames.add(moduleName);
}
}
for (String moduleName : missingModuleNames) {
enabledModuleNames.remove(moduleName);
disabledModuleNames.remove(moduleName);
warnings.add(String.format("Previously loaded %s module could not be found", moduleName)); //NON-NLS
}
// Create ingest module templates.
List<IngestModuleTemplate> moduleTemplates = new ArrayList<>();
for (IngestModuleFactory moduleFactory : moduleFactories) {
IngestModuleTemplate moduleTemplate = new IngestModuleTemplate(moduleFactory, loadJobSettings(moduleFactory));
String moduleName = moduleTemplate.getModuleName();
if (enabledModuleNames.contains(moduleName)) {
moduleTemplate.setEnabled(true);
} else if (disabledModuleNames.contains(moduleName)) {
moduleTemplate.setEnabled(false);
} else {
// The module factory was loaded, but the module name does not
// appear in the enabled/disabled module settings. Treat the
// module as a new module and enable it by default.
moduleTemplate.setEnabled(true);
enabledModuleNames.add(moduleName);
}
moduleTemplates.add(moduleTemplate);
}
// Update the enabled/disabled ingest module settings to reflect any
// missing modules or newly discovered modules.
ModuleSettings.setConfigSetting(launcherContext, ENABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(enabledModuleNames));
ModuleSettings.setConfigSetting(launcherContext, DISABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(disabledModuleNames));
// Get the process unallocated space flag setting. If the setting does
// not exist yet, default it to true.
if (ModuleSettings.settingExists(launcherContext, PARSE_UNALLOC_SPACE_KEY) == false) {
ModuleSettings.setConfigSetting(launcherContext, PARSE_UNALLOC_SPACE_KEY, "true"); //NON-NLS
}
boolean processUnallocatedSpace = Boolean.parseBoolean(ModuleSettings.getConfigSetting(launcherContext, PARSE_UNALLOC_SPACE_KEY));
// Make the configuration panel for the context.
ingestConfigPanel = new IngestJobConfigurationPanel(moduleTemplates, processUnallocatedSpace);
}
private void createModuleSettingsFolderForContext() {
try {
StringBuilder folderPath = new StringBuilder(MODULE_SETTINGS_FOLDER_PATH);
folderPath.append(File.separator);
folderPath.append(launcherContext);
folderPath.append(File.separator);
File folder = new File(folderPath.toString());
if (!folder.exists()) {
Files.createDirectories(folder.toPath());
}
moduleSettingsFolderForContext = folder.getAbsolutePath();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to create ingest module settings directory", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"IngestJobConfigurator.createModuleSettingsFolderForContext.exception.msg"),
NbBundle.getMessage(this.getClass(),
"IngestJobConfigurator.createModuleSettingsFolderForContext.exception.title"),
JOptionPane.ERROR_MESSAGE);
}
}
private HashSet<String> getModulesNamesFromSetting(String key, String defaultSetting) {
// Get the ingest modules setting from the user's config file.
// If there is no such setting yet, create the default setting.
if (ModuleSettings.settingExists(launcherContext, key) == false) {
ModuleSettings.setConfigSetting(launcherContext, key, defaultSetting);
}
HashSet<String> moduleNames = new HashSet<>();
String modulesSetting = ModuleSettings.getConfigSetting(launcherContext, key);
if (!modulesSetting.isEmpty()) {
String[] settingNames = modulesSetting.split(", ");
for (String name : settingNames) {
// Map some old core module names to the current core module names.
switch (name) {
case "Thunderbird Parser": //NON-NLS
case "MBox Parser": //NON-NLS
moduleNames.add("Email Parser"); //NON-NLS
break;
case "File Extension Mismatch Detection": //NON-NLS
moduleNames.add("Extension Mismatch Detector"); //NON-NLS
break;
case "EWF Verify": //NON-NLS
case "E01 Verify": //NON-NLS
moduleNames.add("E01 Verifier"); //NON-NLS
break;
default:
moduleNames.add(name);
}
}
}
return moduleNames;
}
private IngestModuleIngestJobSettings loadJobSettings(IngestModuleFactory factory) {
IngestModuleIngestJobSettings settings = null;
File settingsFile = new File(getModuleSettingsFilePath(factory));
if (settingsFile.exists()) {
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(settingsFile.getAbsolutePath()))) {
settings = (IngestModuleIngestJobSettings) in.readObject();
} catch (IOException | ClassNotFoundException ex) {
String logMessage = String.format("Error loading ingest job settings for %s module for %s context, using defaults", factory.getModuleDisplayName(), launcherContext); //NON-NLS
logger.log(Level.WARNING, logMessage, ex);
}
}
if (settings == null) {
settings = factory.getDefaultIngestJobSettings();
}
return settings;
}
private void saveJobSettings(IngestModuleFactory factory, IngestModuleIngestJobSettings settings) {
try {
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(getModuleSettingsFilePath(factory)))) {
out.writeObject(settings);
}
} catch (IOException ex) {
String logMessage = String.format("Error saving ingest job settings for %s module for %s context", factory.getModuleDisplayName(), launcherContext); //NON-NLS
logger.log(Level.SEVERE, logMessage, ex);
String userMessage = NbBundle.getMessage(this.getClass(), "IngestJobConfigurator.saveJobSettings.usermsg", factory.getModuleDisplayName());
JOptionPane.showMessageDialog(null, userMessage,
NbBundle.getMessage(this.getClass(),
"IngestJobConfigurator.saveJobSettings.usermsg.title"),
JOptionPane.WARNING_MESSAGE);
}
}
private String getModuleSettingsFilePath(IngestModuleFactory factory) {
StringBuilder filePath = new StringBuilder(this.moduleSettingsFolderForContext);
filePath.append(File.separator);
filePath.append(factory.getClass().getCanonicalName());
filePath.append(MODULE_SETTINGS_FILE_EXT);
return filePath.toString();
@Deprecated
public IngestJobConfigurator(String context) {
this.settings = new IngestJobSettings(context);
this.settingsPanel = new IngestJobSettingsPanel(settings);
}
/**
* Gets any warnings generated when the persisted ingest job configuration
* for the specified context is retrieved and loaded.
* Gets any warnings generated when the persisted ingest job settings
* for the specified context are loaded or saved.
*
* @return A collection of warning messages.
* @return A collection of warning messages, possibly empty.
*/
@Deprecated
public List<String> getIngestJobConfigWarnings() {
return warnings;
return this.settings.getWarnings();
}
/**
* Gets the user interface panel the launcher uses to obtain the user's
* ingest job configuration for the specified context.
* ingest job settings for the specified context.
*
* @return A JPanel with components that can be used to create an ingest job
* configuration.
* @return The panel.
*/
@Deprecated
public JPanel getIngestJobConfigPanel() {
return ingestConfigPanel;
return settingsPanel;
}
/**
* Persists the ingest job configuration for the specified context.
* Persists the ingest job settings for the specified context.
*/
@Deprecated
public void saveIngestJobConfig() {
List<IngestModuleTemplate> moduleTemplates = ingestConfigPanel.getIngestModuleTemplates();
// Save the enabled/disabled ingest module settings for the current context.
HashSet<String> enabledModuleNames = new HashSet<>();
HashSet<String> disabledModuleNames = new HashSet<>();
for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
saveJobSettings(moduleTemplate.getModuleFactory(), moduleTemplate.getModuleSettings());
String moduleName = moduleTemplate.getModuleName();
if (moduleTemplate.isEnabled()) {
enabledModuleNames.add(moduleName);
} else {
disabledModuleNames.add(moduleName);
}
}
ModuleSettings.setConfigSetting(launcherContext, ENABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(enabledModuleNames));
ModuleSettings.setConfigSetting(launcherContext, DISABLED_INGEST_MODULES_KEY, makeCommaSeparatedList(disabledModuleNames));
// Save the process unallocated space setting for the current context.
String processUnalloc = Boolean.toString(ingestConfigPanel.getProcessUnallocSpace());
ModuleSettings.setConfigSetting(launcherContext, PARSE_UNALLOC_SPACE_KEY, processUnalloc);
}
private static String makeCommaSeparatedList(HashSet<String> input) {
if (input == null || input.isEmpty()) {
return "";
}
ArrayList<String> list = new ArrayList<>();
list.addAll(input);
StringBuilder csvList = new StringBuilder();
for (int i = 0; i < list.size() - 1; ++i) {
csvList.append(list.get(i)).append(", ");
}
csvList.append(list.get(list.size() - 1));
return csvList.toString();
this.settings.save();
}
/**
* Launches ingest jobs for one or more data sources using the ingest job
* configuration for the selected context.
* settings for the specified context.
*
* @param dataSources The data sources to ingest.
*/
@Deprecated
public void startIngestJobs(List<Content> dataSources) {
// Filter out the disabled ingest module templates.
List<IngestModuleTemplate> enabledModuleTemplates = new ArrayList<>();
List<IngestModuleTemplate> moduleTemplates = ingestConfigPanel.getIngestModuleTemplates();
for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
if (moduleTemplate.isEnabled()) {
enabledModuleTemplates.add(moduleTemplate);
}
}
if ((!enabledModuleTemplates.isEmpty()) && (dataSources != null) && (!dataSources.isEmpty())) {
IngestManager.getInstance().startIngestJobs(dataSources, enabledModuleTemplates, ingestConfigPanel.getProcessUnallocSpace());
IngestManager ingestManager = IngestManager.getInstance();
for (Content dataSource : dataSources) {
ingestManager.startIngestJob(dataSource, this.settings, true);
}
}
}

View File

@ -0,0 +1,385 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.openide.util.io.NbObjectInputStream;
import org.openide.util.io.NbObjectOutputStream;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Encapsulates the ingest job settings for a particular context such as the Add
* Data Source wizard or the Run Ingest Modules dialog.
*/
public class IngestJobSettings {
private static final String ENABLED_MODULES_KEY = "Enabled_Ingest_Modules"; //NON-NLS
private static final String DISABLED_MODULES_KEY = "Disabled_Ingest_Modules"; //NON-NLS
private static final String PARSE_UNALLOC_SPACE_KEY = "Process_Unallocated_Space"; //NON-NLS
private static final String PROCESS_UNALLOC_SPACE_DEFAULT = "true"; //NON-NLS
private static final String MODULE_SETTINGS_FOLDER = "IngestModuleSettings"; //NON-NLS
private static final String MODULE_SETTINGS_FOLDER_PATH = Paths.get(PlatformUtil.getUserConfigDirectory(), IngestJobSettings.MODULE_SETTINGS_FOLDER).toAbsolutePath().toString();
private static final String MODULE_SETTINGS_FILE_EXT = ".settings"; //NON-NLS
private static final Logger logger = Logger.getLogger(IngestJobSettings.class.getName());
private final String context;
private String moduleSettingsFolderPath;
private final List<IngestModuleTemplate> moduleTemplates;
private boolean processUnallocatedSpace;
private final List<String> warnings;
/**
* Constructs an ingest job settings object for a given context.
*
* @param context The context identifier string.
*/
public IngestJobSettings(String context) {
this.context = context;
this.moduleTemplates = new ArrayList<>();
this.processUnallocatedSpace = Boolean.parseBoolean(IngestJobSettings.PROCESS_UNALLOC_SPACE_DEFAULT);
this.warnings = new ArrayList<>();
this.createSavedModuleSettingsFolder();
this.load();
}
/**
* Saves these ingest job settings.
*/
public void save() {
this.store();
}
/**
* Gets and clears any accumulated warnings associated with these ingest job
* settings.
*
* @return A list of warning messages, possibly empty.
*/
public List<String> getWarnings() {
List<String> warningMessages = new ArrayList<>(this.warnings);
this.warnings.clear();
return warningMessages;
}
/**
* Gets the ingest module templates part of these ingest job settings.
*
* @return The list of ingest module templates.
*/
List<IngestModuleTemplate> getIngestModuleTemplates() {
return Collections.unmodifiableList(this.moduleTemplates);
}
/**
* Gets the enabled ingest module templates part of these ingest job
* settings.
*
* @return The list of enabled ingest module templates.
*/
List<IngestModuleTemplate> getEnabledIngestModuleTemplates() {
List<IngestModuleTemplate> enabledModuleTemplates = new ArrayList<>();
for (IngestModuleTemplate moduleTemplate : this.moduleTemplates) {
if (moduleTemplate.isEnabled()) {
enabledModuleTemplates.add(moduleTemplate);
}
}
return enabledModuleTemplates;
}
/**
* Sets the ingest module templates part of these ingest job settings.
*
* @param moduleTemplates The ingest module templates.
*/
void setIngestModuleTemplates(List<IngestModuleTemplate> moduleTemplates) {
this.moduleTemplates.clear();
this.moduleTemplates.addAll(moduleTemplates);
}
/**
* Gets the process unallocated space flag part of these ingest job
* settings.
*
* @return True or false.
*/
boolean getProcessUnallocatedSpace() {
return this.processUnallocatedSpace;
}
/**
* Sets the process unallocated space flag for these ingest job settings.
*
* @param processUnallocatedSpace True or false.
*/
void setProcessUnallocatedSpace(boolean processUnallocatedSpace) {
this.processUnallocatedSpace = processUnallocatedSpace;
}
/**
* Creates the folder for saving the individual ingest module settings part
* of these ingest job settings.
*/
private void createSavedModuleSettingsFolder() {
try {
Path folder = Paths.get(IngestJobSettings.MODULE_SETTINGS_FOLDER_PATH, context);
Files.createDirectories(folder);
this.moduleSettingsFolderPath = folder.toAbsolutePath().toString();
} catch (IOException | SecurityException ex) {
logger.log(Level.SEVERE, "Failed to create ingest module settings directory " + this.moduleSettingsFolderPath, ex); //NON-NLS
this.warnings.add(NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.createModuleSettingsFolder.warning")); //NON-NLS
}
}
/**
* Loads the saved or default ingest job settings context into memory.
*/
private void load() {
/**
* Get the ingest module factories discovered by the ingest module
* loader.
*/
List<IngestModuleFactory> moduleFactories = IngestModuleFactoryLoader.getIngestModuleFactories();
HashSet<String> loadedModuleNames = new HashSet<>();
for (IngestModuleFactory moduleFactory : moduleFactories) {
loadedModuleNames.add(moduleFactory.getModuleDisplayName());
}
/**
* Get the enabled/disabled ingest modules settings for this context. By
* default, all loaded modules are enabled.
*/
HashSet<String> enabledModuleNames = getModulesNamesFromSetting(IngestJobSettings.ENABLED_MODULES_KEY, makeCommaSeparatedValuesList(loadedModuleNames));
HashSet<String> disabledModuleNames = getModulesNamesFromSetting(IngestJobSettings.DISABLED_MODULES_KEY, ""); //NON-NLS
/**
* Check for missing modules and create warnings if any are found.
*/
List<String> missingModuleNames = new ArrayList<>();
for (String moduleName : enabledModuleNames) {
if (!loadedModuleNames.contains(moduleName)) {
missingModuleNames.add(moduleName);
}
}
for (String moduleName : disabledModuleNames) {
if (!loadedModuleNames.contains(moduleName)) {
missingModuleNames.add(moduleName);
}
}
for (String moduleName : missingModuleNames) {
enabledModuleNames.remove(moduleName);
disabledModuleNames.remove(moduleName);
String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.missingModule.warning", moduleName); //NON-NLS
logger.log(Level.WARNING, warning);
this.warnings.add(warning);
}
/**
* Create ingest module templates. Each template encapsulates a module
* factory, the module settings for this context, and an enabled flag.
*/
for (IngestModuleFactory moduleFactory : moduleFactories) {
IngestModuleTemplate moduleTemplate = new IngestModuleTemplate(moduleFactory, loadModuleSettings(moduleFactory));
String moduleName = moduleTemplate.getModuleName();
if (enabledModuleNames.contains(moduleName)) {
moduleTemplate.setEnabled(true);
} else if (disabledModuleNames.contains(moduleName)) {
moduleTemplate.setEnabled(false);
} else {
// The module factory was loaded, but the module name does not
// appear in the enabled/disabled module settings. Treat the
// module as a new module and enable it by default.
moduleTemplate.setEnabled(true);
enabledModuleNames.add(moduleName);
}
this.moduleTemplates.add(moduleTemplate);
}
/**
* Update the enabled/disabled ingest module settings for this context
* to reflect any missing modules or newly discovered modules.
*/
ModuleSettings.setConfigSetting(this.context, IngestJobSettings.ENABLED_MODULES_KEY, makeCommaSeparatedValuesList(enabledModuleNames));
ModuleSettings.setConfigSetting(this.context, IngestJobSettings.DISABLED_MODULES_KEY, makeCommaSeparatedValuesList(disabledModuleNames));
// Get the process unallocated space flag setting. If the setting does
// not exist yet, default it to true.
if (ModuleSettings.settingExists(this.context, IngestJobSettings.PARSE_UNALLOC_SPACE_KEY) == false) {
ModuleSettings.setConfigSetting(this.context, IngestJobSettings.PARSE_UNALLOC_SPACE_KEY, IngestJobSettings.PROCESS_UNALLOC_SPACE_DEFAULT);
}
this.processUnallocatedSpace = Boolean.parseBoolean(ModuleSettings.getConfigSetting(this.context, IngestJobSettings.PARSE_UNALLOC_SPACE_KEY));
}
/**
* Gets the module names for a given key within these ingest job settings.
*
* @param key The key string.
* @param defaultSetting The default list of module names.
* @return The list of module names associated with the key.
*/
private HashSet<String> getModulesNamesFromSetting(String key, String defaultSetting) {
if (ModuleSettings.settingExists(this.context, key) == false) {
ModuleSettings.setConfigSetting(this.context, key, defaultSetting);
}
HashSet<String> moduleNames = new HashSet<>();
String modulesSetting = ModuleSettings.getConfigSetting(this.context, key);
if (!modulesSetting.isEmpty()) {
String[] settingNames = modulesSetting.split(", ");
for (String name : settingNames) {
// Map some old core module names to the current core module names.
switch (name) {
case "Thunderbird Parser": //NON-NLS
case "MBox Parser": //NON-NLS
moduleNames.add("Email Parser"); //NON-NLS
break;
case "File Extension Mismatch Detection": //NON-NLS
moduleNames.add("Extension Mismatch Detector"); //NON-NLS
break;
case "EWF Verify": //NON-NLS
case "E01 Verify": //NON-NLS
moduleNames.add("E01 Verifier"); //NON-NLS
break;
default:
moduleNames.add(name);
}
}
}
return moduleNames;
}
/**
* Gets the saved or default ingest job settings for a given ingest module
* for these ingest job settings.
*
* @param factory The ingest module factory for an ingest module.
* @return The ingest module settings.
*/
private IngestModuleIngestJobSettings loadModuleSettings(IngestModuleFactory factory) {
IngestModuleIngestJobSettings settings = null;
File settingsFile = new File(getModuleSettingsFilePath(factory));
if (settingsFile.exists()) {
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(settingsFile.getAbsolutePath()))) {
settings = (IngestModuleIngestJobSettings) in.readObject();
} catch (IOException | ClassNotFoundException ex) {
String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsLoad.warning", factory.getModuleDisplayName(), this.context); //NON-NLS
logger.log(Level.WARNING, warning, ex);
this.warnings.add(warning);
}
}
if (settings == null) {
settings = factory.getDefaultIngestJobSettings();
}
return settings;
}
/**
* Returns the absolute path for the ingest job settings file for a given
* ingest module for these ingest job settings.
*
* @param factory The ingest module factory for an ingest module.
* @return The file path.
*/
private String getModuleSettingsFilePath(IngestModuleFactory factory) {
String fileName = factory.getClass().getCanonicalName() + IngestJobSettings.MODULE_SETTINGS_FILE_EXT;
Path path = Paths.get(this.moduleSettingsFolderPath, fileName);
return path.toAbsolutePath().toString();
}
/**
* Saves the ingest job settings for this context.
*/
private void store() {
/**
* Save the enabled/disabled ingest module settings.
*/
HashSet<String> enabledModuleNames = new HashSet<>();
HashSet<String> disabledModuleNames = new HashSet<>();
for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
saveModuleSettings(moduleTemplate.getModuleFactory(), moduleTemplate.getModuleSettings());
String moduleName = moduleTemplate.getModuleName();
if (moduleTemplate.isEnabled()) {
enabledModuleNames.add(moduleName);
} else {
disabledModuleNames.add(moduleName);
}
}
ModuleSettings.setConfigSetting(this.context, ENABLED_MODULES_KEY, makeCommaSeparatedValuesList(enabledModuleNames));
ModuleSettings.setConfigSetting(this.context, DISABLED_MODULES_KEY, makeCommaSeparatedValuesList(disabledModuleNames));
/**
* Save the process unallocated space setting.
*/
String processUnalloc = Boolean.toString(this.processUnallocatedSpace);
ModuleSettings.setConfigSetting(this.context, PARSE_UNALLOC_SPACE_KEY, processUnalloc);
}
/**
* Serializes the ingest job settings for this context for a given ingest
* module.
*
* @param factory The ingest module factory for the module.
* @param settings The ingest job settings for the ingest module
*/
private void saveModuleSettings(IngestModuleFactory factory, IngestModuleIngestJobSettings settings) {
try {
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(getModuleSettingsFilePath(factory)))) {
out.writeObject(settings);
}
} catch (IOException ex) {
String warning = NbBundle.getMessage(IngestJobSettings.class, "IngestJobSettings.moduleSettingsSave.warning", factory.getModuleDisplayName(), this.context); //NON-NLS
logger.log(Level.SEVERE, warning, ex);
this.warnings.add(warning);
}
}
/**
* Makes a comma-separated values list from a hash set of strings.
*
* @param input A hash set of strings.
* @return The contents of the hash set as a single string of
* comma-separated values.
*/
private static String makeCommaSeparatedValuesList(HashSet<String> input) {
if (input == null || input.isEmpty()) {
return "";
}
ArrayList<String> list = new ArrayList<>();
list.addAll(input);
StringBuilder csvList = new StringBuilder();
for (int i = 0; i < list.size() - 1; ++i) {
csvList.append(list.get(i)).append(", ");
}
csvList.append(list.get(list.size() - 1));
return csvList.toString();
}
}

View File

@ -144,10 +144,10 @@
<Component class="javax.swing.JButton" name="advancedButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.advancedButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.advancedButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.advancedButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.advancedButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
@ -160,7 +160,7 @@
<Component class="javax.swing.JLabel" name="descriptionLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.descriptionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.descriptionLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
@ -221,10 +221,10 @@
<Component class="javax.swing.JCheckBox" name="processUnallocCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.processUnallocCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.processUnallocCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/ingest/Bundle.properties" key="IngestJobSettingsPanel.processUnallocCheckbox.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>

View File

@ -35,39 +35,47 @@ import javax.swing.table.TableColumn;
import org.sleuthkit.autopsy.corecomponents.AdvancedConfigurationDialog;
/**
* User interface component to allow a user to set ingest module options and
* enable/disable the modules.
* User interface component to allow a user to make ingest job settings.
*/
class IngestJobConfigurationPanel extends javax.swing.JPanel {
public final class IngestJobSettingsPanel extends javax.swing.JPanel {
private List<IngestModuleModel> modules = new ArrayList<>();
private boolean processUnallocatedSpace = false;
private IngestModuleModel selectedModule = null;
private final IngestJobSettings settings;
private final List<IngestModuleModel> modules;
private IngestModuleModel selectedModule;
IngestJobConfigurationPanel(List<IngestModuleTemplate> moduleTemplates, boolean processUnallocatedSpace) {
for (IngestModuleTemplate moduleTemplate : moduleTemplates) {
modules.add(new IngestModuleModel(moduleTemplate));
/**
* Construct a user interface component to allow a user to make ingest job
* settings.
*
* @param settings The initial settings for the ingest job.
*/
public IngestJobSettingsPanel(IngestJobSettings settings) {
this.settings = settings;
this.modules = new ArrayList<>();
for (IngestModuleTemplate moduleTemplate : settings.getIngestModuleTemplates()) {
this.modules.add(new IngestModuleModel(moduleTemplate));
}
this.processUnallocatedSpace = processUnallocatedSpace;
initComponents();
customizeComponents();
}
List<IngestModuleTemplate> getIngestModuleTemplates() {
/**
* Gets the ingest settings made using this panel.
*
* @return The settings.
*/
IngestJobSettings getSettings() {
List<IngestModuleTemplate> moduleTemplates = new ArrayList<>();
for (IngestModuleModel module : modules) {
IngestModuleTemplate moduleTemplate = module.getIngestModuleTemplate();
if (module.hasModuleSettingsPanel()) {
IngestModuleIngestJobSettings settings = module.getModuleSettingsPanel().getSettings();
moduleTemplate.setModuleSettings(settings);
IngestModuleIngestJobSettings moduleSettings = module.getModuleSettingsPanel().getSettings();
moduleTemplate.setModuleSettings(moduleSettings);
}
moduleTemplates.add(moduleTemplate);
}
return moduleTemplates;
}
boolean getProcessUnallocSpace() {
return processUnallocCheckbox.isSelected();
this.settings.setIngestModuleTemplates(moduleTemplates);
return this.settings;
}
private void customizeComponents() {
@ -113,7 +121,7 @@ class IngestJobConfigurationPanel extends javax.swing.JPanel {
}
});
processUnallocCheckbox.setSelected(processUnallocatedSpace);
processUnallocCheckbox.setSelected(this.settings.getProcessUnallocatedSpace());
}
/**
@ -160,8 +168,8 @@ class IngestJobConfigurationPanel extends javax.swing.JPanel {
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160)));
jPanel1.setPreferredSize(new java.awt.Dimension(338, 257));
advancedButton.setText(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.advancedButton.text")); // NOI18N
advancedButton.setActionCommand(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.advancedButton.actionCommand")); // NOI18N
advancedButton.setText(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.advancedButton.text")); // NOI18N
advancedButton.setActionCommand(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.advancedButton.actionCommand")); // NOI18N
advancedButton.setEnabled(false);
advancedButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -169,7 +177,7 @@ class IngestJobConfigurationPanel extends javax.swing.JPanel {
}
});
descriptionLabel.setText(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.descriptionLabel.text")); // NOI18N
descriptionLabel.setText(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.descriptionLabel.text")); // NOI18N
jScrollPane1.setBorder(null);
jScrollPane1.setPreferredSize(new java.awt.Dimension(250, 180));
@ -208,8 +216,8 @@ class IngestJobConfigurationPanel extends javax.swing.JPanel {
processUnallocPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(160, 160, 160)));
processUnallocCheckbox.setText(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.processUnallocCheckbox.text")); // NOI18N
processUnallocCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(IngestJobConfigurationPanel.class, "IngestJobConfigurationPanel.processUnallocCheckbox.toolTipText")); // NOI18N
processUnallocCheckbox.setText(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.processUnallocCheckbox.text")); // NOI18N
processUnallocCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(IngestJobSettingsPanel.class, "IngestJobSettingsPanel.processUnallocCheckbox.toolTipText")); // NOI18N
processUnallocCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
processUnallocCheckboxActionPerformed(evt);
@ -261,7 +269,7 @@ class IngestJobConfigurationPanel extends javax.swing.JPanel {
}// </editor-fold>//GEN-END:initComponents
private void processUnallocCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processUnallocCheckboxActionPerformed
processUnallocatedSpace = processUnallocCheckbox.isSelected();
this.settings.setProcessUnallocatedSpace(processUnallocCheckbox.isSelected());
}//GEN-LAST:event_processUnallocCheckboxActionPerformed
private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed

View File

@ -46,7 +46,8 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content;
/**
* Manages the execution of ingest jobs.
* Manages the creation and execution of ingest jobs, i.e., processing of data
* sources by ingest modules.
*/
public class IngestManager {
@ -64,7 +65,7 @@ public class IngestManager {
private final ExecutorService fileIngestThreadPool;
private final ExecutorService fireIngestEventsThreadPool = Executors.newSingleThreadExecutor();
private final AtomicLong nextThreadId = new AtomicLong(0L);
private final ConcurrentHashMap<Long, Future<Void>> startIngestJobsTasks = new ConcurrentHashMap<>(); // Maps thread ids to cancellation handles.
private final ConcurrentHashMap<Long, Future<Void>> startIngestJobsCallables = new ConcurrentHashMap<>(); // Maps thread ids to cancellation handles.
private final AtomicLong ingestErrorMessagePosts = new AtomicLong(0L);
private final ConcurrentHashMap<Long, IngestThreadActivitySnapshot> ingestThreadActivitySnapshots = new ConcurrentHashMap<>(); // Maps ingest thread ids to progress ingestThreadActivitySnapshots.
private final ConcurrentHashMap<String, Long> ingestModuleRunTimes = new ConcurrentHashMap<>();
@ -73,6 +74,60 @@ public class IngestManager {
private volatile IngestMessageTopComponent ingestMessageBox;
private int numberOfFileIngestThreads = DEFAULT_NUMBER_OF_FILE_INGEST_THREADS;
/**
* Ingest job events.
*/
public enum IngestJobEvent {
/**
* Property change event fired when an ingest job is started. The old
* value of the PropertyChangeEvent object is set to the ingest job id,
* and the new value is set to null.
*/
STARTED,
/**
* Property change event fired when an ingest job is completed. The old
* value of the PropertyChangeEvent object is set to the ingest job id,
* and the new value is set to null.
*/
COMPLETED,
/**
* Property change event fired when an ingest job is canceled. The old
* value of the PropertyChangeEvent object is set to the ingest job id,
* and the new value is set to null.
*/
CANCELLED,
};
/**
* Ingest module events.
*/
public enum IngestModuleEvent {
/**
* Property change event fired when an ingest module adds new data to a
* case, usually by posting to the blackboard. The old value of the
* PropertyChangeEvent is a ModuleDataEvent object, and the new value is
* set to null.
*/
DATA_ADDED,
/**
* Property change event fired when an ingest module adds new content to
* a case or changes a recorded attribute of existing content. For
* example, if a module adds an extracted or carved file to a case, the
* module should fire this event. The old value of the
* PropertyChangeEvent is a ModuleContentEvent object, and the new value
* is set to null.
*/
CONTENT_CHANGED,
/**
* Property change event fired when the ingest of a file is completed.
* The old value of the PropertyChangeEvent is the Autopsy object ID of
* the file. The new value is the AbstractFile for that ID.
*/
FILE_DONE,
};
/**
* Gets the ingest manager.
*
@ -90,6 +145,123 @@ public class IngestManager {
return instance;
}
/**
* Gets the number of file ingest threads the ingest manager will use to do
* ingest jobs.
*
* @return The number of file ingest threads.
*/
public int getNumberOfFileIngestThreads() {
return numberOfFileIngestThreads;
}
/**
* Starts an ingest job, i.e., processing by ingest modules, for a data
* source.
*
* @param dataSource The data source to be processed.
* @param settings The ingest job settings.
* @param doStartupErrorsMsgBox Whether or not to display ingest module
* startup errors in a message box.
*/
public synchronized void startIngestJob(Content dataSource, IngestJobSettings settings, boolean doStartupErrorsMsgBox) {
if (!isIngestRunning()) {
clearIngestMessageBox();
}
if (!ingestMonitor.isRunning()) {
ingestMonitor.start();
}
long taskId = nextThreadId.incrementAndGet();
Future<Void> task = startIngestJobsThreadPool.submit(new StartIngestJobsCallable(taskId, dataSource, settings, doStartupErrorsMsgBox));
startIngestJobsCallables.put(taskId, task);
}
/**
* Queries whether any ingest jobs are in progress.
*
* @return True or false.
*/
public boolean isIngestRunning() {
return IngestJob.ingestJobsAreRunning();
}
/**
* Cancels all ingest jobs in progress.
*/
public void cancelAllIngestJobs() {
// Stop creating new ingest jobs.
for (Future<Void> handle : startIngestJobsCallables.values()) {
handle.cancel(true);
}
// Cancel all the jobs already created.
IngestJob.cancelAllJobs();
}
/**
* Adds an ingest job event property change listener.
*
* @param listener The PropertyChangeListener to register.
*/
public void addIngestJobEventListener(final PropertyChangeListener listener) {
ingestJobEventPublisher.addPropertyChangeListener(listener);
}
/**
* Removes an ingest job event property change listener.
*
* @param listener The PropertyChangeListener to unregister.
*/
public void removeIngestJobEventListener(final PropertyChangeListener listener) {
ingestJobEventPublisher.removePropertyChangeListener(listener);
}
/**
* Adds an ingest module event property change listener.
*
* @param listener The PropertyChangeListener to register.
*/
public void addIngestModuleEventListener(final PropertyChangeListener listener) {
ingestModuleEventPublisher.addPropertyChangeListener(listener);
}
/**
* Removes an ingest module event property change listener.
*
* @param listener The PropertyChangeListener to unregister.
*/
public void removeIngestModuleEventListener(final PropertyChangeListener listener) {
ingestModuleEventPublisher.removePropertyChangeListener(listener);
}
/**
* Adds an ingest job and ingest module event property change listener.
*
* @param listener The PropertyChangeListener to register.
* @deprecated Use addIngestJobEventListener() and/or
* addIngestModuleEventListener().
*/
@Deprecated
public static void addPropertyChangeListener(final PropertyChangeListener listener) {
instance.ingestJobEventPublisher.addPropertyChangeListener(listener);
instance.ingestModuleEventPublisher.addPropertyChangeListener(listener);
}
/**
* Remove an ingest job and ingest module event property change listener.
*
* @param listener The PropertyChangeListener to unregister.
* @deprecated Use removeIngestJobEventListener() and/or
* removeIngestModuleEventListener().
*/
@Deprecated
public static void removePropertyChangeListener(final PropertyChangeListener listener) {
instance.ingestJobEventPublisher.removePropertyChangeListener(listener);
instance.ingestModuleEventPublisher.removePropertyChangeListener(listener);
}
/**
* Starts the ingest monitor and submits task execution tasks (Callable
* objects) to the data source ingest and file ingest thread pools. The task
@ -97,7 +269,7 @@ public class IngestManager {
* the application runs
*/
private IngestManager() {
startDataSourceIngestTask();
startDataSourceIngestThread();
numberOfFileIngestThreads = UserPreferences.numberOfFileIngestThreads();
if ((numberOfFileIngestThreads < MIN_NUMBER_OF_FILE_INGEST_THREADS) || (numberOfFileIngestThreads > MAX_NUMBER_OF_FILE_INGEST_THREADS)) {
@ -106,7 +278,7 @@ public class IngestManager {
}
fileIngestThreadPool = Executors.newFixedThreadPool(numberOfFileIngestThreads);
for (int i = 0; i < numberOfFileIngestThreads; ++i) {
startFileIngestTask();
startFileIngestThread();
}
}
@ -119,20 +291,11 @@ public class IngestManager {
ingestMessageBox = IngestMessageTopComponent.findInstance();
}
/**
* Gets the number of file ingest threads the ingest manager will use.
*
* @return The number of file ingest threads.
*/
public int getNumberOfFileIngestThreads() {
return numberOfFileIngestThreads;
}
/**
* Submits a ExecuteIngestTasksTask Callable to the data source ingest task
* thread pool.
*/
private void startDataSourceIngestTask() {
private void startDataSourceIngestThread() {
long threadId = nextThreadId.incrementAndGet();
dataSourceIngestThreadPool.submit(new ExecuteIngestTasksRunnable(threadId, IngestTasksScheduler.getInstance().getDataSourceIngestTaskQueue()));
ingestThreadActivitySnapshots.put(threadId, new IngestThreadActivitySnapshot(threadId));
@ -142,22 +305,12 @@ public class IngestManager {
* Submits a ExecuteIngestTasksTask Callable to the data source ingest
* thread pool.
*/
private void startFileIngestTask() {
private void startFileIngestThread() {
long threadId = nextThreadId.incrementAndGet();
fileIngestThreadPool.submit(new ExecuteIngestTasksRunnable(threadId, IngestTasksScheduler.getInstance().getFileIngestTaskQueue()));
ingestThreadActivitySnapshots.put(threadId, new IngestThreadActivitySnapshot(threadId));
}
synchronized void startIngestJobs(final List<Content> dataSources, final List<IngestModuleTemplate> moduleTemplates, boolean processUnallocatedSpace) {
if (!isIngestRunning()) {
clearIngestMessageBox();
}
long taskId = nextThreadId.incrementAndGet();
Future<Void> task = startIngestJobsThreadPool.submit(new StartIngestJobsCallable(taskId, dataSources, moduleTemplates, processUnallocatedSpace));
startIngestJobsTasks.put(taskId, task);
}
private void subscribeToCaseEvents() {
Case.addPropertyChangeListener(new PropertyChangeListener() {
@Override
@ -191,15 +344,6 @@ public class IngestManager {
ingestErrorMessagePosts.set(0);
}
/**
* Test if any ingest jobs are in progress.
*
* @return True if any ingest jobs are in progress, false otherwise.
*/
public boolean isIngestRunning() {
return IngestJob.ingestJobsAreRunning();
}
/**
* Called each time a module in a data source pipeline starts
*
@ -292,132 +436,6 @@ public class IngestManager {
return new ArrayList<>(ingestThreadActivitySnapshots.values());
}
public void cancelAllIngestJobs() {
// Stop creating new ingest jobs.
for (Future<Void> handle : startIngestJobsTasks.values()) {
handle.cancel(true);
}
// Cancel all the jobs already created.
IngestJob.cancelAllJobs();
}
/**
* Ingest job events.
*/
public enum IngestJobEvent {
/**
* Property change event fired when an ingest job is started. The old
* value of the PropertyChangeEvent object is set to the ingest job id,
* and the new value is set to null.
*/
STARTED,
/**
* Property change event fired when an ingest job is completed. The old
* value of the PropertyChangeEvent object is set to the ingest job id,
* and the new value is set to null.
*/
COMPLETED,
/**
* Property change event fired when an ingest job is canceled. The old
* value of the PropertyChangeEvent object is set to the ingest job id,
* and the new value is set to null.
*/
CANCELLED,
};
/**
* Ingest module events.
*/
public enum IngestModuleEvent {
/**
* Property change event fired when an ingest module adds new data to a
* case, usually by posting to the blackboard. The old value of the
* PropertyChangeEvent is a ModuleDataEvent object, and the new value is
* set to null.
*/
DATA_ADDED,
/**
* Property change event fired when an ingest module adds new content to
* a case or changes a recorded attribute of existing content. For
* example, if a module adds an extracted or carved file to a case, the
* module should fire this event. The old value of the
* PropertyChangeEvent is a ModuleContentEvent object, and the new value
* is set to null.
*/
CONTENT_CHANGED,
/**
* Property change event fired when the ingest of a file is completed.
* The old value of the PropertyChangeEvent is the Autopsy object ID of
* the file. The new value is the AbstractFile for that ID.
*/
FILE_DONE,
};
/**
* Add an ingest job event property change listener.
*
* @param listener The PropertyChangeListener to register.
*/
public void addIngestJobEventListener(final PropertyChangeListener listener) {
ingestJobEventPublisher.addPropertyChangeListener(listener);
}
/**
* Remove an ingest job event property change listener.
*
* @param listener The PropertyChangeListener to unregister.
*/
public void removeIngestJobEventListener(final PropertyChangeListener listener) {
ingestJobEventPublisher.removePropertyChangeListener(listener);
}
/**
* Add an ingest module event property change listener.
*
* @param listener The PropertyChangeListener to register.
*/
public void addIngestModuleEventListener(final PropertyChangeListener listener) {
ingestModuleEventPublisher.addPropertyChangeListener(listener);
}
/**
* Remove an ingest module event property change listener.
*
* @param listener The PropertyChangeListener to unregister.
*/
public void removeIngestModuleEventListener(final PropertyChangeListener listener) {
ingestModuleEventPublisher.removePropertyChangeListener(listener);
}
/**
* Add an ingest job and ingest module event property change listener.
*
* @deprecated Use addIngestJobEventListener() and/or
* addIngestModuleEventListener().
* @param listener The PropertyChangeListener to register.
*/
@Deprecated
public static void addPropertyChangeListener(final PropertyChangeListener listener) {
instance.ingestJobEventPublisher.addPropertyChangeListener(listener);
instance.ingestModuleEventPublisher.addPropertyChangeListener(listener);
}
/**
* Remove an ingest job and ingest module event property change listener.
*
* @deprecated Use removeIngestJobEventListener() and/or
* removeIngestModuleEventListener().
* @param listener The PropertyChangeListener to unregister.
*/
@Deprecated
public static void removePropertyChangeListener(final PropertyChangeListener listener) {
instance.ingestJobEventPublisher.removePropertyChangeListener(listener);
instance.ingestModuleEventPublisher.removePropertyChangeListener(listener);
}
/**
* Fire an ingest event signifying an ingest job started.
*
@ -513,26 +531,34 @@ public class IngestManager {
}
/**
* Creates ingest jobs.
* Creates and starts an ingest job, i.e., processing by ingest modules, for
* a data source.
*/
private final class StartIngestJobsCallable implements Callable<Void> {
private final long threadId;
private final List<Content> dataSources;
private final List<IngestModuleTemplate> moduleTemplates;
private final boolean processUnallocatedSpace;
private final Content dataSource;
private final IngestJobSettings settings;
private final boolean doStartupErrorsMsgBox;
private ProgressHandle progress;
StartIngestJobsCallable(long threadId, List<Content> dataSources, List<IngestModuleTemplate> moduleTemplates, boolean processUnallocatedSpace) {
StartIngestJobsCallable(long threadId, Content dataSource, IngestJobSettings settings, boolean doStartupErrorsMsgBox) {
this.threadId = threadId;
this.dataSources = dataSources;
this.moduleTemplates = moduleTemplates;
this.processUnallocatedSpace = processUnallocatedSpace;
this.dataSource = dataSource;
this.settings = settings;
this.doStartupErrorsMsgBox = doStartupErrorsMsgBox;
}
@Override
public Void call() {
try {
if (Thread.currentThread().isInterrupted()) {
return null;
}
/**
* Set up a progress bar.
*/
final String displayName = NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.displayName");
progress = ProgressHandleFactory.createHandle(displayName, new Cancellable() {
@ -543,62 +569,50 @@ public class IngestManager {
"IngestManager.StartIngestJobsTask.run.cancelling",
displayName));
}
Future<?> handle = startIngestJobsTasks.remove(threadId);
Future<?> handle = startIngestJobsCallables.remove(threadId);
handle.cancel(true);
return true;
}
});
progress.start(dataSources.size());
progress.switchToIndeterminate();
progress.start();
if (!ingestMonitor.isRunning()) {
ingestMonitor.start();
}
int dataSourceProcessed = 0;
for (Content dataSource : dataSources) {
if (Thread.currentThread().isInterrupted()) {
break;
}
// Start an ingest job for the data source.
List<IngestModuleError> errors = IngestJob.startJob(dataSource, moduleTemplates, processUnallocatedSpace);
if (!errors.isEmpty()) {
// Report the errors to the user. They have already been logged.
StringBuilder moduleStartUpErrors = new StringBuilder();
for (IngestModuleError error : errors) {
String moduleName = error.getModuleDisplayName();
moduleStartUpErrors.append(moduleName);
moduleStartUpErrors.append(": ");
moduleStartUpErrors.append(error.getModuleError().getLocalizedMessage());
moduleStartUpErrors.append("\n");
}
StringBuilder notifyMessage = new StringBuilder();
notifyMessage.append(NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg"));
notifyMessage.append("\n");
notifyMessage.append(NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution"));
notifyMessage.append("\n");
notifyMessage.append(NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList",
moduleStartUpErrors.toString()));
notifyMessage.append("\n\n");
JOptionPane.showMessageDialog(null, notifyMessage.toString(),
NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle"), JOptionPane.ERROR_MESSAGE);
}
progress.progress(++dataSourceProcessed);
if (!Thread.currentThread().isInterrupted()) {
break;
/**
* Create and start an ingest job for the data source.
*/
List<IngestModuleError> errors = IngestJob.startJob(dataSource, this.settings);
if (!errors.isEmpty() && this.doStartupErrorsMsgBox) {
// Report the errors to the user. They have already been logged.
StringBuilder moduleStartUpErrors = new StringBuilder();
for (IngestModuleError error : errors) {
String moduleName = error.getModuleDisplayName();
moduleStartUpErrors.append(moduleName);
moduleStartUpErrors.append(": ");
moduleStartUpErrors.append(error.getModuleError().getLocalizedMessage());
moduleStartUpErrors.append("\n");
}
StringBuilder notifyMessage = new StringBuilder();
notifyMessage.append(NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgMsg"));
notifyMessage.append("\n");
notifyMessage.append(NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgSolution"));
notifyMessage.append("\n");
notifyMessage.append(NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgErrorList",
moduleStartUpErrors.toString()));
notifyMessage.append("\n\n");
JOptionPane.showMessageDialog(null, notifyMessage.toString(),
NbBundle.getMessage(this.getClass(),
"IngestManager.StartIngestJobsTask.run.startupErr.dlgTitle"), JOptionPane.ERROR_MESSAGE);
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to create ingest job", ex); //NON-NLS
} finally {
progress.finish();
startIngestJobsTasks.remove(threadId);
startIngestJobsCallables.remove(threadId);
}
return null;
}
}
@ -758,4 +772,5 @@ public class IngestManager {
return processedFilesCount;
}
}
}

View File

@ -44,13 +44,13 @@ public final class RunIngestModulesDialog extends JDialog {
private static final String TITLE = NbBundle.getMessage(RunIngestModulesDialog.class, "IngestDialog.title.text");
private static Dimension DIMENSIONS = new Dimension(500, 300);
private List<Content> dataSources = new ArrayList<>();
private IngestJobConfigurator ingestJobLauncher;
private final List<Content> dataSources = new ArrayList<>();
private IngestJobSettings ingestJobSettings;
public RunIngestModulesDialog(JFrame frame, String title, boolean modal) {
super(frame, title, modal);
ingestJobLauncher = new IngestJobConfigurator(RunIngestModulesDialog.class.getCanonicalName());
List<String> messages = ingestJobLauncher.getIngestJobConfigWarnings();
ingestJobSettings = new IngestJobSettings(RunIngestModulesDialog.class.getCanonicalName());
List<String> messages = ingestJobSettings.getWarnings();
if (messages.isEmpty() == false) {
StringBuilder warning = new StringBuilder();
for (String message : messages) {
@ -79,28 +79,31 @@ public final class RunIngestModulesDialog extends JDialog {
// set the location of the popUp Window on the center of the screen
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
add(ingestJobLauncher.getIngestJobConfigPanel(), BorderLayout.PAGE_START);
add(new IngestJobSettingsPanel(ingestJobSettings), BorderLayout.PAGE_START);
JButton startButton = new JButton(NbBundle.getMessage(this.getClass(), "IngestDialog.startButton.title"));
JButton closeButton = new JButton(NbBundle.getMessage(this.getClass(), "IngestDialog.closeButton.title"));
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ingestJobLauncher.saveIngestJobConfig();
ingestJobLauncher.startIngestJobs(dataSources);
ingestJobSettings.save();
IngestManager ingestManager = IngestManager.getInstance();
for (Content dataSource : dataSources) {
ingestManager.startIngestJob(dataSource, ingestJobSettings, true);
}
close();
}
});
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ingestJobLauncher.saveIngestJobConfig();
ingestJobSettings.save();
close();
}
});
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
ingestJobLauncher.saveIngestJobConfig();
ingestJobSettings.save();
close();
}
});