Interim check in of case deletion to allow develop branch merge

This commit is contained in:
Richard Cordovano 2019-03-06 14:11:31 -05:00
parent b2bf617f62
commit 710cfc243f
19 changed files with 252 additions and 288 deletions

View File

@ -148,6 +148,7 @@ public interface MultiUserCaseBrowserCustomizer {
CREATE_DATE(Bundle.MultiUserCaseBrowserCustomizer_column_createTime()), CREATE_DATE(Bundle.MultiUserCaseBrowserCustomizer_column_createTime()),
DIRECTORY(Bundle.MultiUserCaseBrowserCustomizer_column_directory()), DIRECTORY(Bundle.MultiUserCaseBrowserCustomizer_column_directory()),
LAST_ACCESS_DATE(Bundle.MultiUserCaseBrowserCustomizer_column_lastAccessTime()); LAST_ACCESS_DATE(Bundle.MultiUserCaseBrowserCustomizer_column_lastAccessTime());
// RJCTODO: Add properties for deleted items flags
private final String displayName; private final String displayName;

View File

@ -23,59 +23,97 @@ import org.openide.util.Cancellable;
/** /**
* A progress indicator that displays progress using a progress bar in the lower * A progress indicator that displays progress using a progress bar in the lower
* right hand corner of the application main frame, i.e., a NetBean * right hand corner of the application main frame, i.e., a NetBeans
* ProgressHandle. * ProgressHandle.
*/ */
public final class AppProgressBarProgressIndicator implements ProgressIndicator { public final class AppFrameProgressBar implements ProgressIndicator {
private final ProgressHandle progressHandle; private final String displayName;
private Cancellable cancellationBehavior;
private ProgressHandle progressHandle;
private volatile boolean cancelling;
/** /**
* Constructs a progress indicator that displays progress using a progress * Constructs a progress indicator that displays progress using a progress
* bar in the lower right hand corner of the application main frame, i.e., a * bar in the lower right hand corner of the application main frame, i.e., a
* NetBean ProgressHandle. * NetBeans ProgressHandle.
*
* @param displayName The display name for the progress bar (a fixed name
* that appears above the current progress message).
*/ */
public AppProgressBarProgressIndicator(String displayName, Cancellable cancellationAction) { public AppFrameProgressBar(String displayName) {
this.progressHandle = ProgressHandle.createHandle(displayName, cancellationAction); this.displayName = displayName;
}
/**
* Sets the cancellation behavior that should happen when a user clicks on
* the "x" button of the progress bar.
*
* @param cancellationBehavior A org.openide.util.Cancellable that
* implements the desired cancellation behavior.
*/
public void setCancellationBehavior(Cancellable cancellationBehavior) {
this.cancellationBehavior = cancellationBehavior;
} }
@Override @Override
public void start(String message, int totalWorkUnits) { public void start(String message, int totalWorkUnits) {
cancelling = false;
this.progressHandle = ProgressHandle.createHandle(displayName, cancellationBehavior);
progressHandle.start(totalWorkUnits); progressHandle.start(totalWorkUnits);
progressHandle.progress(message); progressHandle.progress(message);
} }
@Override @Override
public void start(String message) { public void start(String message) {
cancelling = false;
this.progressHandle = ProgressHandle.createHandle(displayName, cancellationBehavior);
progressHandle.start(); progressHandle.start();
progressHandle.progress(message); progressHandle.progress(message);
} }
@Override @Override
public void switchToIndeterminate(String message) { public void switchToIndeterminate(String message) {
progressHandle.switchToIndeterminate(); if (!cancelling) {
progressHandle.progress(message); progressHandle.switchToIndeterminate();
progressHandle.progress(message);
}
} }
@Override @Override
public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) { public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits) {
progressHandle.switchToDeterminate(totalWorkUnits); if (!cancelling) {
progressHandle.progress(message, workUnitsCompleted); progressHandle.switchToDeterminate(totalWorkUnits);
progressHandle.progress(message, workUnitsCompleted);
}
} }
@Override @Override
public void progress(String message) { public void progress(String message) {
progressHandle.progress(message); if (!cancelling) {
progressHandle.progress(message);
}
} }
@Override @Override
public void progress(int workUnitsCompleted) { public void progress(int workUnitsCompleted) {
progressHandle.progress(workUnitsCompleted); if (!cancelling) {
progressHandle.progress(workUnitsCompleted);
}
} }
@Override @Override
public void progress(String message, int workUnitsCompleted) { public void progress(String message, int workUnitsCompleted) {
progressHandle.progress(message, workUnitsCompleted); if (!cancelling) {
progressHandle.progress(message, workUnitsCompleted);
}
}
@Override
public void setCancelling(String cancellingMessage) {
cancelling = true;
progressHandle.switchToIndeterminate();
progressHandle.progress(cancellingMessage);
} }
@Override @Override

View File

@ -3,3 +3,4 @@
# and open the template in the editor. # and open the template in the editor.
ProgressPanel.progressMessage.text=Message ProgressPanel.progressMessage.text=Message
TaskCanceller.progress.cancellingMessage=Cancelling...

View File

@ -128,6 +128,7 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
* *
* @param cancellingMessage * @param cancellingMessage
*/ */
@Override
public synchronized void setCancelling(String cancellingMessage) { public synchronized void setCancelling(String cancellingMessage) {
cancelling = true; cancelling = true;
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {

View File

@ -49,7 +49,7 @@ public interface ProgressIndicator {
* *
* @param message The initial progress message. * @param message The initial progress message.
*/ */
public void switchToIndeterminate(String message); void switchToIndeterminate(String message);
/** /**
* Switches the progress indicator to determinate mode (the total number of * Switches the progress indicator to determinate mode (the total number of
@ -59,14 +59,14 @@ public interface ProgressIndicator {
* @param workUnitsCompleted The number of work units completed so far. * @param workUnitsCompleted The number of work units completed so far.
* @param totalWorkUnits The total number of work units to be completed. * @param totalWorkUnits The total number of work units to be completed.
*/ */
public void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits); void switchToDeterminate(String message, int workUnitsCompleted, int totalWorkUnits);
/** /**
* Updates the progress indicator with a progress message. * Updates the progress indicator with a progress message.
* *
* @param message The progress message. * @param message The progress message.
*/ */
public void progress(String message); void progress(String message);
/** /**
* Updates the progress indicator with the number of work units completed so * Updates the progress indicator with the number of work units completed so
@ -75,7 +75,7 @@ public interface ProgressIndicator {
* *
* @param workUnitsCompleted Number of work units completed so far. * @param workUnitsCompleted Number of work units completed so far.
*/ */
public void progress(int workUnitsCompleted); void progress(int workUnitsCompleted);
/** /**
* Updates the progress indicator with a progress message and the number of * Updates the progress indicator with a progress message and the number of
@ -85,7 +85,20 @@ public interface ProgressIndicator {
* @param message The progress message. * @param message The progress message.
* @param workUnitsCompleted Number of work units completed so far. * @param workUnitsCompleted Number of work units completed so far.
*/ */
public void progress(String message, int workUnitsCompleted); void progress(String message, int workUnitsCompleted);
/**
* If the progress indicator supports cancelling the underlying task, sets a
* cancelling message and causes the progress indicator to no longer accept
* updates unless start is called again.
*
* The default implementation assumes that cancelling the underlying task is
* not supported.
*
* @param cancellingMessage The cancelling messages.
*/
default void setCancelling(String cancellingMessage) {
}
/** /**
* Finishes the progress indicator when the task is completed. * Finishes the progress indicator when the task is completed.

View File

@ -30,26 +30,25 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil;
/** /**
* A logger for the case dashboard log. * A logger for the auto ingest dashboard log.
*/ */
final class CaseDashboardLogger { final class AutoIngestDashboardLogger {
private static final int LOG_SIZE = 50000000; // In bytes, zero is unlimited, set to roughly 10mb currently private static final int LOG_SIZE = 50000000; // In bytes, zero is unlimited, set to roughly 10mb currently
private static final int LOG_FILE_COUNT = 10; private static final int LOG_FILE_COUNT = 10;
private static final Logger logger = Logger.getLogger("CaseDashboardLogger"); //NON-NLS private static final Logger logger = Logger.getLogger("AutoIngestDashboardLogger"); //NON-NLS
private static final String NEWLINE = System.lineSeparator(); private static final String NEWLINE = System.lineSeparator();
@GuardedBy("AutoIngestSystemLogger") @GuardedBy("AutoIngestDashboardLogger")
private static boolean configured; private static boolean configured;
/** /**
* Gets a logger for the auto ingest system log, separate from both the case * Gets a logger for the auto ingest dashboard log.
* auto ingest log and the application log.
* *
* @return The logger. * @return The logger.
*/ */
synchronized static Logger getLogger() { synchronized static Logger getLogger() {
if (!configured) { if (!configured) {
Path logFilePath = Paths.get(PlatformUtil.getUserDirectory().getAbsolutePath(), "var", "log", "case_dashboard.log"); Path logFilePath = Paths.get(PlatformUtil.getUserDirectory().getAbsolutePath(), "var", "log", "auto_ingest_dashboard.log"); //NON-NLS
try { try {
FileHandler fileHandler = new FileHandler(logFilePath.toString(), LOG_SIZE, LOG_FILE_COUNT); FileHandler fileHandler = new FileHandler(logFilePath.toString(), LOG_SIZE, LOG_FILE_COUNT);
fileHandler.setEncoding(PlatformUtil.getLogFileEncoding()); fileHandler.setEncoding(PlatformUtil.getLogFileEncoding());
@ -86,7 +85,7 @@ final class CaseDashboardLogger {
/** /**
* Prevents instantiation of this utility class. * Prevents instantiation of this utility class.
*/ */
private CaseDashboardLogger() { private AutoIngestDashboardLogger() {
} }
} }

View File

@ -94,6 +94,10 @@ AutoIngestControlPanel.runningTable.toolTipText=The Running table displays the c
AutoIngestControlPanel.SharedConfigurationDisabled=Shared configuration disabled AutoIngestControlPanel.SharedConfigurationDisabled=Shared configuration disabled
AutoIngestControlPanel.ShowLogFailed.Message=Case log file does not exist AutoIngestControlPanel.ShowLogFailed.Message=Case log file does not exist
AutoIngestControlPanel.ShowLogFailed.Title=Unable to display case log AutoIngestControlPanel.ShowLogFailed.Title=Unable to display case log
# {0} - case db status
# {1} - search svc Status
# {2} - coord svc Status
# {3} - msg broker status
AutoIngestControlPanel.tbServicesStatusMessage.Message=Case databases {0}, keyword search {1}, coordination {2}, messaging {3} AutoIngestControlPanel.tbServicesStatusMessage.Message=Case databases {0}, keyword search {1}, coordination {2}, messaging {3}
AutoIngestControlPanel.tbServicesStatusMessage.Message.Down=down AutoIngestControlPanel.tbServicesStatusMessage.Message.Down=down
AutoIngestControlPanel.tbServicesStatusMessage.Message.Unknown=unknown AutoIngestControlPanel.tbServicesStatusMessage.Message.Unknown=unknown
@ -125,7 +129,6 @@ AutoIngestDashboard.tbServicesStatusMessage.Message.Up=up
AutoIngestDashboard.tbServicesStatusMessage.Message.Down=down AutoIngestDashboard.tbServicesStatusMessage.Message.Down=down
AutoIngestDashboard.tbServicesStatusMessage.Message.Unknown=unknown AutoIngestDashboard.tbServicesStatusMessage.Message.Unknown=unknown
AutoIngestDashboardTopComponent.exceptionMessage.failedToCreateDashboard=Failed to create Auto Ingest Dashboard. AutoIngestDashboardTopComponent.exceptionMessage.failedToCreateDashboard=Failed to create Auto Ingest Dashboard.
AutoIngestJobsDeletionTask.error.failedToGetJobNodes=Failed to get auto ingest job node data from coordination service.
AutoIngestJobsNode.caseName.text=Case Name AutoIngestJobsNode.caseName.text=Case Name
AutoIngestJobsNode.dataSource.text=Data Source AutoIngestJobsNode.dataSource.text=Data Source
AutoIngestJobsNode.hostName.text=Host Name AutoIngestJobsNode.hostName.text=Host Name
@ -140,40 +143,6 @@ AutoIngestJobsNode.status.text=Status
AutoIngestJobsPanel.waitNode.text=Please Wait... AutoIngestJobsPanel.waitNode.text=Please Wait...
AutoIngestMetricsDialog.initReportText=Select a date above and click the 'Generate Metrics Report' button to generate\na metrics report. AutoIngestMetricsDialog.initReportText=Select a date above and click the 'Generate Metrics Report' button to generate\na metrics report.
AutoIngestMetricsDialog.title.text=Auto Ingest Metrics AutoIngestMetricsDialog.title.text=Auto Ingest Metrics
CaseDeletionTask.progress.acquiringCaseDirLock=Acquiring exclusive case directory lock
CaseDeletionTask.progress.acquiringCaseNameLock=Acquiring exclusive case name lock
CaseDeletionTask.progress.acquiringInputDirLocks=Acquiring exclusive input directory locks
CaseDeletionTask.progress.connectingToCoordSvc=Connecting to the coordination service
CaseDeletionTask.progress.deletingCase=Deleting case {0}...
CaseDeletionTask.progress.deletingCaseOutput=Deleting case output
CaseDeletionTask.progress.deletingDirLockNode=Deleting case directory lock node
# {0} - input directory name
CaseDeletionTask.progress.deletingInputDir=Deleting input directory {0}
CaseDeletionTask.progress.deletingInputDirLockNodes=Deleting input directory lock nodes
CaseDeletionTask.progress.deletingInputDirs=Deleting input directory
CaseDeletionTask.progress.deletingJobLogLockNode=Deleting auto ingest job log lock node
CaseDeletionTask.progress.deletingNameLockNode=Deleting case name lock node
CaseDeletionTask.progress.deletingOutput=Deleting case output
CaseDeletionTask.progress.deletingResourcesLockNode=Deleting case resources lock node
CaseDeletionTask.progress.errorConnectingToCoordSvc=Failed to connect to the coordination service (see log for details): {0}.
CaseDeletionTask.progress.errorDeletingInputDir=An error occurred deleting the input directory at {0}
CaseDeletionTask.progress.errorDeletingOutput=An error occurred deleting the case output (see log for details): {0}.
CaseDeletionTask.progress.errorLockingCaseDir=An error occurred while trying to acquire the exclusive directory lock for the case (see log for details): {0}.
CaseDeletionTask.progress.errorLockingCaseName=An error occurred while trying to acquire the exclusive name lock for the case (see log for details): {0}.
CaseDeletionTask.progress.errorlockingInputDir=An error occurred Acquiring the exclusive lock on input directory {0} (see log for details): {1}
CaseDeletionTask.progress.errorReleasingInputDirLock=An error occurred releasing the exclusive lock on input directory {0} (see log for details): {1}.
CaseDeletionTask.progress.errorReleasingInputLock=An error occurred releasing the input directory lock (see log for details): {0}.
CaseDeletionTask.progress.failedToLockCase=Failed to exclusively lock the case, it may be in use, did not delete.
CaseDeletionTask.progress.failedToLockInputDir=Failed to exclusively lock the input directory {0}.
CaseDeletionTask.progress.gettingJobNodeData=Getting node data for auto ingest jobs
CaseDeletionTask.progress.locatingCaseMetadataFile=Locating case metadata file
# {0} - input directory name
CaseDeletionTask.progress.lockingInputDir=Acquiring exclusive lock on input directory {0}
CaseDeletionTask.progress.releasingInputDirLock=Releasing the exclusive lock on input directory {0}
CaseDeletionTask.progress.releasingInputDirLocks=Acquiring exclusive input directory locks
# {0} - manifest file path
CaseDeletionTask.progress.releasingManifestLock=Releasing the exclusive lock on manifest file {0}
CaseDeletionTask.progress.releasingManifestLocks=Acquiring exclusive manifest file locks
ConfirmationDialog.DoNotDelete=Do not delete ConfirmationDialog.DoNotDelete=Do not delete
ConfirmationDialog.Delete=Permanently delete ConfirmationDialog.Delete=Permanently delete
ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case
@ -202,14 +171,41 @@ CTL_CasesDashboardAction=Multi-User Cases Dashboard
CTL_CasesDashboardTopComponent=Cases CTL_CasesDashboardTopComponent=Cases
DataSourceOnCDriveError.noOpenCase.errMsg=Warning: Exception while getting open case. DataSourceOnCDriveError.noOpenCase.errMsg=Warning: Exception while getting open case.
DataSourceOnCDriveError.text=Warning: Path to multi-user data source is on "C:" drive DataSourceOnCDriveError.text=Warning: Path to multi-user data source is on "C:" drive
DeleteCaseInputDirectoriesAction.menuItemText=Delete Input Directories DeleteCaseInputAction.menuItemText=Delete Input
DeleteCasesAction.menuItemText=Delete Case and Jobs DeleteCaseInputAction.progressDisplayName=Delete Input
DeleteCasesForReprocessingAction.menuItemText=Delete for Reprocessing DeleteCaseInputAction.taskName=input
DeleteCaseInputAndOutputAction.menuItemText=Delete Input and Output
DeleteCaseInputAndOutputAction.progressDisplayName=Delete Input and Output
DeleteCaseInputAndOutputAction.taskName=input-and-output
DeleteCaseOutputAction.menuItemText=Delete Output
DeleteCaseOutputAction.progressDisplayName=Delete Output
DeleteCaseOutputAction.taskName=output
DeleteCaseTask.progress.acquiringCaseDirLock=Acquiring exclusive case directory lock
DeleteCaseTask.progress.acquiringCaseNameLock=Acquiring exclusive case name lock
DeleteCaseTask.progress.acquiringInputDirLocks=Acquiring exclusive input directory locks
DeleteCaseTask.progress.connectingToCoordSvc=Connecting to the coordination service
DeleteCaseTask.progress.deletingCaseOutput=Deleting case output
DeleteCaseTask.progress.deletingDirLockNode=Deleting case directory lock node
# {0} - input directory name
DeleteCaseTask.progress.deletingInputDir=Deleting input directory {0}
DeleteCaseTask.progress.deletingInputDirLockNodes=Deleting input directory lock nodes
DeleteCaseTask.progress.deletingInputDirs=Deleting input directory
DeleteCaseTask.progress.deletingJobLogLockNode=Deleting auto ingest job log lock node
DeleteCaseTask.progress.deletingNameLockNode=Deleting case name lock node
DeleteCaseTask.progress.deletingResourcesLockNode=Deleting case resources lock node
DeleteCaseTask.progress.gettingJobNodeData=Getting node data for auto ingest jobs
DeleteCaseTask.progress.locatingCaseMetadataFile=Locating case metadata file
# {0} - input directory name
DeleteCaseTask.progress.lockingInputDir=Acquiring exclusive lock on input directory {0}
# {0} - manifest file path
DeleteCaseTask.progress.releasingManifestLock=Releasing the exclusive lock on manifest file {0}
DeleteCaseTask.progress.releasingManifestLocks=Acquiring exclusive manifest file locks
GeneralFilter.archiveDesc.text=Archive Files (.zip, .rar, .arj, .7z, .7zip, .gzip, .gz, .bzip2, .tar, .tgz) GeneralFilter.archiveDesc.text=Archive Files (.zip, .rar, .arj, .7z, .7zip, .gzip, .gz, .bzip2, .tar, .tgz)
HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-user cases HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-user cases
OpenAutoIngestLogAction.deletedLogErrorMsg=The case auto ingest log has been deleted. OpenAutoIngestLogAction.deletedLogErrorMsg=The case auto ingest log has been deleted.
OpenAutoIngestLogAction.logOpenFailedErrorMsg=Failed to open case auto ingest log. See application log for details. OpenAutoIngestLogAction.logOpenFailedErrorMsg=Failed to open case auto ingest log. See application log for details.
OpenAutoIngestLogAction.menuItemText=Open Auto Ingest Log File OpenAutoIngestLogAction.menuItemText=Open Auto Ingest Log File
# {0} - caseErrorMessage
OpenCaseAction.errorMsg=Failed to open case: {0} OpenCaseAction.errorMsg=Failed to open case: {0}
OpenCaseAction.menuItemText=Open OpenCaseAction.menuItemText=Open
OpenIDE-Module-Long-Description=This module contains features that are being developed by Basis Technology and are not part of the default Autopsy distribution. You can enable this module to use the new features. The features should be stable, but their exact behavior and API are subject to change.\n\nWe make no guarantee that the API of this module will not change, so developers should be careful when relying on it. OpenIDE-Module-Long-Description=This module contains features that are being developed by Basis Technology and are not part of the default Autopsy distribution. You can enable this module to use the new features. The features should be stable, but their exact behavior and API are subject to change.\n\nWe make no guarantee that the API of this module will not change, so developers should be careful when relying on it.
@ -321,7 +317,6 @@ PrioritizationAction.prioritizeJobAction.error=Failed to prioritize job "%s".
PrioritizationAction.prioritizeJobAction.title=Prioritize Job PrioritizationAction.prioritizeJobAction.title=Prioritize Job
PrioritizedIconCellRenderer.notPrioritized.tooltiptext=This job has not been prioritized. PrioritizedIconCellRenderer.notPrioritized.tooltiptext=This job has not been prioritized.
PrioritizedIconCellRenderer.prioritized.tooltiptext=This job has been prioritized. The most recently prioritized job should be processed next. PrioritizedIconCellRenderer.prioritized.tooltiptext=This job has been prioritized. The most recently prioritized job should be processed next.
ShowCaseDeletionStatusAction.menuItemText=Show Deletion Status
SingleUserCaseImporter.NonUniqueOutputFolder=Output folder not unique. Skipping SingleUserCaseImporter.NonUniqueOutputFolder=Output folder not unique. Skipping
SingleUserCaseImporter.WillImport=Will import: SingleUserCaseImporter.WillImport=Will import:
SingleUserCaseImporter.None=None SingleUserCaseImporter.None=None

View File

@ -31,23 +31,26 @@ import org.sleuthkit.autopsy.casemodule.multiusercasesbrowser.MultiUserCaseBrows
*/ */
final class CasesDashboardCustomizer implements MultiUserCaseBrowserCustomizer { final class CasesDashboardCustomizer implements MultiUserCaseBrowserCustomizer {
private final DeleteCaseInputDirectoriesAction deleteCaseInputAction; private final DeleteCaseInputAction deleteCaseInputAction;
private final DeleteCasesForReprocessingAction deleteCaseOutputAction; private final DeleteCaseOutputAction deleteCaseOutputAction;
private final DeleteCasesAction deleteCaseAction; private final DeleteCaseInputAndOutputAction deleteCaseAction;
/** /**
* Constructs a customizer for the multi-user case browser panel used in the * Constructs a customizer for the multi-user case browser panel used in the
* administrative dashboard for auto ingest cases to present a tabular view * administrative dashboard for auto ingest cases to present a tabular view
* of the multi-user cases known to the coordination service. * of the multi-user cases known to the coordination service.
*
* @param executor An executor for tasks for actions that do work in the
* background.
*/ */
CasesDashboardCustomizer() { CasesDashboardCustomizer() {
/* /*
* These actions are shared by all nodes in order to support multiple * These actions are shared by all nodes in order to support multiple
* selection. * selection.
*/ */
deleteCaseInputAction = new DeleteCaseInputDirectoriesAction(); deleteCaseInputAction = new DeleteCaseInputAction();
deleteCaseOutputAction = new DeleteCasesForReprocessingAction(); deleteCaseOutputAction = new DeleteCaseOutputAction();
deleteCaseAction = new DeleteCasesAction(); deleteCaseAction = new DeleteCaseInputAndOutputAction();
} }
@Override @Override
@ -79,7 +82,6 @@ final class CasesDashboardCustomizer implements MultiUserCaseBrowserCustomizer {
actions.add(deleteCaseInputAction); actions.add(deleteCaseInputAction);
actions.add(deleteCaseOutputAction); actions.add(deleteCaseOutputAction);
actions.add(deleteCaseAction); actions.add(deleteCaseAction);
actions.add(new ShowCaseDeletionStatusAction(nodeData));
return actions; return actions;
} }

View File

@ -18,9 +18,6 @@
*/ */
package org.sleuthkit.autopsy.experimental.autoingest; package org.sleuthkit.autopsy.experimental.autoingest;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.explorer.ExplorerManager; import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils; import org.openide.explorer.ExplorerUtils;
@ -56,11 +53,9 @@ import org.sleuthkit.autopsy.coreutils.Logger;
public final class CasesDashboardTopComponent extends TopComponent implements ExplorerManager.Provider { public final class CasesDashboardTopComponent extends TopComponent implements ExplorerManager.Provider {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final String TASK_THREAD_NAME = "Case-dashboard-task-%d";
private static final Logger logger = Logger.getLogger(CasesDashboardTopComponent.class.getName()); private static final Logger logger = Logger.getLogger(CasesDashboardTopComponent.class.getName());
private final ExplorerManager explorerManager; private final ExplorerManager explorerManager;
private final MultiUserCasesBrowserPanel caseBrowserPanel; private final MultiUserCasesBrowserPanel caseBrowserPanel;
private final Executor executor;
/** /**
* Opens a singleton top component that provides an adminstrative dashboard * Opens a singleton top component that provides an adminstrative dashboard
@ -68,7 +63,7 @@ public final class CasesDashboardTopComponent extends TopComponent implements Ex
* mode" defined by the auto ingest jobs top component. * mode" defined by the auto ingest jobs top component.
*/ */
// RJCTODO: Consider moving all of the dashboard code into its own // RJCTODO: Consider moving all of the dashboard code into its own
// admindashboards or dashboards package. // autoingest.dashboard package.
public static void openTopComponent() { public static void openTopComponent() {
CasesDashboardTopComponent topComponent = (CasesDashboardTopComponent) WindowManager.getDefault().findTopComponent("CasesDashboardTopComponent"); // NON-NLS CasesDashboardTopComponent topComponent = (CasesDashboardTopComponent) WindowManager.getDefault().findTopComponent("CasesDashboardTopComponent"); // NON-NLS
if (topComponent == null) { if (topComponent == null) {
@ -104,7 +99,6 @@ public final class CasesDashboardTopComponent extends TopComponent implements Ex
caseBrowserPanel = new MultiUserCasesBrowserPanel(explorerManager, new CasesDashboardCustomizer()); caseBrowserPanel = new MultiUserCasesBrowserPanel(explorerManager, new CasesDashboardCustomizer());
caseBrowserScrollPane.add(caseBrowserPanel); caseBrowserScrollPane.add(caseBrowserPanel);
caseBrowserScrollPane.setViewportView(caseBrowserPanel); caseBrowserScrollPane.setViewportView(caseBrowserPanel);
executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(TASK_THREAD_NAME).build()); // RJCTODO: Need shutdown
} }
@Override @Override

View File

@ -18,13 +18,10 @@
*/ */
package org.sleuthkit.autopsy.experimental.autoingest; package org.sleuthkit.autopsy.experimental.autoingest;
import java.awt.event.ActionEvent; import java.util.concurrent.ExecutorService;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.AbstractAction;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData; import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
import org.sleuthkit.autopsy.progress.ProgressIndicator;
/** /**
* An action that deletes the auto ingest job input directories associated with * An action that deletes the auto ingest job input directories associated with
@ -32,13 +29,8 @@ import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
* ingest jobs are not deleted. This supports the use case where the directories * ingest jobs are not deleted. This supports the use case where the directories
* may need to be directed to reclaim space, but the option to restore the * may need to be directed to reclaim space, but the option to restore the
* directories without having the jobs be reprocessed is retained. * directories without having the jobs be reprocessed is retained.
*
* This cases to delete are discovered by querying the actions global context
* lookup for CaseNodeData objects. See
* https://platform.netbeans.org/tutorials/nbm-selection-1.html and
* https://platform.netbeans.org/tutorials/nbm-selection-2.html for details.
*/ */
final class DeleteCaseInputDirectoriesAction extends AbstractAction { final class DeleteCaseInputAction extends DeleteCaseAction {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -51,26 +43,22 @@ final class DeleteCaseInputDirectoriesAction extends AbstractAction {
* reprocessed is retained. * reprocessed is retained.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"DeleteCaseInputDirectoriesAction.menuItemText=Delete Input Directories" "DeleteCaseInputAction.menuItemText=Delete Input",
"DeleteCaseInputAction.progressDisplayName=Delete Input",
"DeleteCaseInputAction.taskName=input"
}) })
DeleteCaseInputDirectoriesAction() { DeleteCaseInputAction() {
super(Bundle.DeleteCaseInputDirectoriesAction_menuItemText()); super(Bundle.DeleteCaseInputAction_menuItemText(), Bundle.DeleteCaseInputAction_progressDisplayName(), Bundle.DeleteCaseInputAction_taskName());
setEnabled(false); // RJCTODO: Enable when implemented
} }
@Override @Override
public void actionPerformed(ActionEvent event) { DeleteCaseTask getTask(CaseNodeData caseNodeData, ProgressIndicator progress) {
final Collection<CaseNodeData> selectedNodeData = new ArrayList<>(Utilities.actionsGlobalContext().lookupAll(CaseNodeData.class)); return new DeleteCaseInputTask(caseNodeData, progress);
// if (!selectedNodeData.isEmpty()) {
// /*
// * RJCTODO: Create a background task that does the deletion and
// * displays results in a dialog with a scrolling text pane.
// */
// }
} }
@Override @Override
public DeleteCaseInputDirectoriesAction clone() throws CloneNotSupportedException { public DeleteCaseInputAction clone() throws CloneNotSupportedException {
super.clone();
throw new CloneNotSupportedException(); throw new CloneNotSupportedException();
} }

View File

@ -0,0 +1,59 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019-2019 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.experimental.autoingest;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
import org.sleuthkit.autopsy.progress.ProgressIndicator;
/**
* An action that completely deletes one or more multi-user cases, including any
* associated auto ingest job input directories and all coordination service
* nodes.
*/
final class DeleteCaseInputAndOutputAction extends DeleteCaseAction {
private static final long serialVersionUID = 1L;
/**
* Constructs an action that completely deletes one or more multi-user
* cases, including any associated auto ingest job input directories and
* coordination service nodes.
*/
@Messages({
"DeleteCaseInputAndOutputAction.menuItemText=Delete Input and Output",
"DeleteCaseInputAndOutputAction.progressDisplayName=Delete Input and Output",
"DeleteCaseInputAndOutputAction.taskName=input-and-output"
})
DeleteCaseInputAndOutputAction() {
super(Bundle.DeleteCaseInputAndOutputAction_menuItemText(), Bundle.DeleteCaseInputAndOutputAction_progressDisplayName(), Bundle.DeleteCaseInputAndOutputAction_taskName());
}
@Override
DeleteCaseTask getTask(CaseNodeData caseNodeData, ProgressIndicator progress) {
return new DeleteCaseInputAndOutputTask(caseNodeData, progress);
}
@Override
public DeleteCaseInputAndOutputAction clone() throws CloneNotSupportedException {
super.clone();
throw new CloneNotSupportedException();
}
}

View File

@ -24,7 +24,7 @@ import org.sleuthkit.autopsy.progress.ProgressIndicator;
/** /**
* A task that deletes a case produced via auto ingest. * A task that deletes a case produced via auto ingest.
*/ */
final class DeleteAutoIngestCaseTask extends AutoIngestCaseDeletionTask { final class DeleteCaseInputAndOutputTask extends DeleteCaseTask {
/** /**
* Constructs a task that deletes a case produced via auto ingest. * Constructs a task that deletes a case produced via auto ingest.
@ -33,7 +33,7 @@ final class DeleteAutoIngestCaseTask extends AutoIngestCaseDeletionTask {
* data for the case. * data for the case.
* @param progress A progress indicator. * @param progress A progress indicator.
*/ */
DeleteAutoIngestCaseTask(CaseNodeData caseNodeData, ProgressIndicator progress) { DeleteCaseInputAndOutputTask(CaseNodeData caseNodeData, ProgressIndicator progress) {
super(caseNodeData, progress); super(caseNodeData, progress);
} }

View File

@ -28,7 +28,7 @@ import org.sleuthkit.autopsy.progress.ProgressIndicator;
* retaining the option to restore the input directories, effectively restoring * retaining the option to restore the input directories, effectively restoring
* the case. * the case.
*/ */
final class DeleteAutoIngestCaseInputTask extends AutoIngestCaseDeletionTask { final class DeleteCaseInputTask extends DeleteCaseTask {
/** /**
* Constructs a task to delete the auto ingest job input directories for a * Constructs a task to delete the auto ingest job input directories for a
@ -41,7 +41,7 @@ final class DeleteAutoIngestCaseInputTask extends AutoIngestCaseDeletionTask {
* data for the case. * data for the case.
* @param progress A progress indicator. * @param progress A progress indicator.
*/ */
DeleteAutoIngestCaseInputTask(CaseNodeData caseNodeData, ProgressIndicator progress) { DeleteCaseInputTask(CaseNodeData caseNodeData, ProgressIndicator progress) {
super(caseNodeData, progress); super(caseNodeData, progress);
} }

View File

@ -25,6 +25,7 @@ import javax.swing.AbstractAction;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.Utilities; import org.openide.util.Utilities;
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData; import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
import org.sleuthkit.autopsy.progress.ProgressIndicator;
/** /**
* An action that deletes everything except the auto ingest job input * An action that deletes everything except the auto ingest job input
@ -32,13 +33,8 @@ import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
* where a case needs to be reprocessed, so the input directories are not * where a case needs to be reprocessed, so the input directories are not
* deleted even though the coordination service nodes for the auto ingest jobs * deleted even though the coordination service nodes for the auto ingest jobs
* are deleted. * are deleted.
*
* This cases to delete are discovered by querying the actions global context
* lookup for CaseNodeData objects. See
* https://platform.netbeans.org/tutorials/nbm-selection-1.html and
* https://platform.netbeans.org/tutorials/nbm-selection-2.html for details.
*/ */
final class DeleteCasesForReprocessingAction extends AbstractAction { final class DeleteCaseOutputAction extends DeleteCaseAction {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -50,26 +46,22 @@ final class DeleteCasesForReprocessingAction extends AbstractAction {
* ingest jobs are deleted. * ingest jobs are deleted.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"DeleteCasesForReprocessingAction.menuItemText=Delete for Reprocessing" "DeleteCaseOutputAction.menuItemText=Delete Output",
"DeleteCaseOutputAction.progressDisplayName=Delete Output",
"DeleteCaseOutputAction.taskName=output"
}) })
DeleteCasesForReprocessingAction() { DeleteCaseOutputAction() {
super(Bundle.DeleteCasesForReprocessingAction_menuItemText()); super(Bundle.DeleteCaseOutputAction_menuItemText(), Bundle.DeleteCaseOutputAction_progressDisplayName(), Bundle.DeleteCaseOutputAction_taskName());
setEnabled(false); // RJCTODO: Enable when implemented
} }
@Override @Override
public void actionPerformed(ActionEvent event) { DeleteCaseTask getTask(CaseNodeData caseNodeData, ProgressIndicator progress) {
final Collection<CaseNodeData> selectedNodeData = new ArrayList<>(Utilities.actionsGlobalContext().lookupAll(CaseNodeData.class)); return new DeleteCaseOutputTask(caseNodeData, progress);
// if (!selectedNodeData.isEmpty()) {
// /*
// * RJCTODO: Create a background task that does the deletion and
// * displays results in a dialog with a scrolling text pane.
// */
// }
} }
@Override @Override
public DeleteCasesForReprocessingAction clone() throws CloneNotSupportedException { public DeleteCaseOutputAction clone() throws CloneNotSupportedException {
super.clone();
throw new CloneNotSupportedException(); throw new CloneNotSupportedException();
} }

View File

@ -27,7 +27,7 @@ import org.sleuthkit.autopsy.progress.ProgressIndicator;
* input directories intact. The use case is reprocessing a case with a clean * input directories intact. The use case is reprocessing a case with a clean
* slate without having to restore the input directories. * slate without having to restore the input directories.
*/ */
final class DeleteAutoIngestCaseOutputTask extends AutoIngestCaseDeletionTask { final class DeleteCaseOutputTask extends DeleteCaseTask {
/** /**
* Constructs a task to delete the auto ingest job coordination service * Constructs a task to delete the auto ingest job coordination service
@ -40,7 +40,7 @@ final class DeleteAutoIngestCaseOutputTask extends AutoIngestCaseDeletionTask {
* data for the case. * data for the case.
* @param progress A progress indicator. * @param progress A progress indicator.
*/ */
DeleteAutoIngestCaseOutputTask(CaseNodeData caseNodeData, ProgressIndicator progress) { DeleteCaseOutputTask(CaseNodeData caseNodeData, ProgressIndicator progress) {
super(caseNodeData, progress); super(caseNodeData, progress);
} }

View File

@ -45,10 +45,10 @@ import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestJobNodeData.Inval
* A base class for tasks that delete part or all of a case produced via auto * A base class for tasks that delete part or all of a case produced via auto
* ingest. * ingest.
*/ */
abstract class AutoIngestCaseDeletionTask implements Runnable { abstract class DeleteCaseTask implements Runnable {
private static final String RESOURCES_LOCK_SUFFIX = "_resources"; //NON-NLS private static final String RESOURCES_LOCK_SUFFIX = "_resources"; //NON-NLS
private static final Logger logger = CaseDashboardLogger.getLogger(); private static final Logger logger = AutoIngestDashboardLogger.getLogger();
private final CaseNodeData caseNodeData; private final CaseNodeData caseNodeData;
private final ProgressIndicator progress; private final ProgressIndicator progress;
private final List<AutoIngestJobNodeData> nodeDataForAutoIngestJobs; private final List<AutoIngestJobNodeData> nodeDataForAutoIngestJobs;
@ -63,7 +63,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* data for the case to be deleted. * data for the case to be deleted.
* @param progress A progress indicator. * @param progress A progress indicator.
*/ */
AutoIngestCaseDeletionTask(CaseNodeData caseNodeData, ProgressIndicator progress) { DeleteCaseTask(CaseNodeData caseNodeData, ProgressIndicator progress) {
this.caseNodeData = caseNodeData; this.caseNodeData = caseNodeData;
this.progress = progress; this.progress = progress;
this.nodeDataForAutoIngestJobs = new ArrayList<>(); this.nodeDataForAutoIngestJobs = new ArrayList<>();
@ -72,15 +72,15 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
@Override @Override
@NbBundle.Messages({ @NbBundle.Messages({
"CaseDeletionTask.progress.connectingToCoordSvc=Connecting to the coordination service", "DeleteCaseTask.progress.connectingToCoordSvc=Connecting to the coordination service",
"CaseDeletionTask.progress.acquiringCaseNameLock=Acquiring exclusive case name lock", "DeleteCaseTask.progress.acquiringCaseNameLock=Acquiring exclusive case name lock",
"CaseDeletionTask.progress.acquiringCaseDirLock=Acquiring exclusive case directory lock", "DeleteCaseTask.progress.acquiringCaseDirLock=Acquiring exclusive case directory lock",
"CaseDeletionTask.progress.gettingJobNodeData=Getting node data for auto ingest jobs", "DeleteCaseTask.progress.gettingJobNodeData=Getting node data for auto ingest jobs",
"CaseDeletionTask.progress.acquiringInputDirLocks=Acquiring exclusive input directory locks" "DeleteCaseTask.progress.acquiringInputDirLocks=Acquiring exclusive input directory locks"
}) })
public void run() { public void run() {
try { try {
progress.start(Bundle.CaseDeletionTask_progress_connectingToCoordSvc()); progress.start(Bundle.DeleteCaseTask_progress_connectingToCoordSvc());
try { try {
coordinationService = CoordinationService.getInstance(); coordinationService = CoordinationService.getInstance();
} catch (CoordinationService.CoordinationServiceException ex) { } catch (CoordinationService.CoordinationServiceException ex) {
@ -95,7 +95,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* auto ingest nodes from searching for and finding the case * auto ingest nodes from searching for and finding the case
* directory of the case to be deleted. * directory of the case to be deleted.
*/ */
progress.progress(Bundle.CaseDeletionTask_progress_acquiringCaseNameLock()); progress.progress(Bundle.DeleteCaseTask_progress_acquiringCaseNameLock());
logger.log(Level.INFO, String.format("Exclusively locking the case name for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Exclusively locking the case name for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
final String caseNameLockName = TimeStampUtils.removeTimeStamp(caseNodeData.getName()); final String caseNameLockName = TimeStampUtils.removeTimeStamp(caseNodeData.getName());
try (CoordinationService.Lock nameLock = coordinationService.tryGetExclusiveLock(CategoryNode.CASES, caseNameLockName)) { try (CoordinationService.Lock nameLock = coordinationService.tryGetExclusiveLock(CategoryNode.CASES, caseNameLockName)) {
@ -113,7 +113,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* deleted open and prevents another node from trying to open * deleted open and prevents another node from trying to open
* the case as it is being deleted. * the case as it is being deleted.
*/ */
progress.progress(Bundle.CaseDeletionTask_progress_acquiringCaseDirLock()); progress.progress(Bundle.DeleteCaseTask_progress_acquiringCaseDirLock());
logger.log(Level.INFO, String.format("Exclusively locking the case directory for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Exclusively locking the case directory for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
try (CoordinationService.Lock caseLock = CoordinationService.getInstance().tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, caseNodeData.getDirectory().toString())) { try (CoordinationService.Lock caseLock = CoordinationService.getInstance().tryGetExclusiveLock(CoordinationService.CategoryNode.CASES, caseNodeData.getDirectory().toString())) {
if (caseLock == null) { if (caseLock == null) {
@ -121,7 +121,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
return; return;
} }
progress.progress(Bundle.CaseDeletionTask_progress_gettingJobNodeData()); progress.progress(Bundle.DeleteCaseTask_progress_gettingJobNodeData());
logger.log(Level.INFO, String.format("Fetching auto ingest job node data for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Fetching auto ingest job node data for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
try { try {
getAutoIngestJobNodeData(); getAutoIngestJobNodeData();
@ -131,7 +131,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
} }
if (!nodeDataForAutoIngestJobs.isEmpty()) { if (!nodeDataForAutoIngestJobs.isEmpty()) {
progress.progress(Bundle.CaseDeletionTask_progress_acquiringInputDirLocks()); progress.progress(Bundle.DeleteCaseTask_progress_acquiringInputDirLocks());
logger.log(Level.INFO, String.format("Exclusively locking the case directories for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Exclusively locking the case directories for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
getInputDirectoryLocks(); getInputDirectoryLocks();
if (manifestFileLocks.isEmpty()) { if (manifestFileLocks.isEmpty()) {
@ -193,15 +193,15 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* be called when holding all of the exclusive locks for the case. * be called when holding all of the exclusive locks for the case.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"CaseDeletionTask.progress.deletingInputDirs=Deleting input directory", "DeleteCaseTask.progress.deletingInputDirs=Deleting input directory",
"# {0} - input directory name", "CaseDeletionTask.progress.deletingInputDir=Deleting input directory {0}" "# {0} - input directory name", "DeleteCaseTask.progress.deletingInputDir=Deleting input directory {0}"
}) })
protected void deleteInputDirectories() { protected void deleteInputDirectories() {
progress.progress(Bundle.CaseDeletionTask_progress_deletingInputDirs()); progress.progress(Bundle.DeleteCaseTask_progress_deletingInputDirs());
logger.log(Level.INFO, String.format("Deleting input directories for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting input directories for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
for (AutoIngestJobNodeData jobNodeData : nodeDataForAutoIngestJobs) { for (AutoIngestJobNodeData jobNodeData : nodeDataForAutoIngestJobs) {
final Path inputDirPath = jobNodeData.getManifestFilePath().getParent(); final Path inputDirPath = jobNodeData.getManifestFilePath().getParent();
progress.progress(Bundle.CaseDeletionTask_progress_deletingInputDir(inputDirPath)); progress.progress(Bundle.DeleteCaseTask_progress_deletingInputDir(inputDirPath));
logger.log(Level.INFO, String.format("Deleting input directory %s for %s (%s) in %s", inputDirPath, caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting input directory %s for %s (%s) in %s", inputDirPath, caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
if (FileUtil.deleteDir(new File(inputDirPath.toString()))) { if (FileUtil.deleteDir(new File(inputDirPath.toString()))) {
logger.log(Level.WARNING, String.format("Failed to delete the input directory %s for %s (%s) in %s", inputDirPath, caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.WARNING, String.format("Failed to delete the input directory %s for %s (%s) in %s", inputDirPath, caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
@ -216,11 +216,11 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* the case. * the case.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"CaseDeletionTask.progress.locatingCaseMetadataFile=Locating case metadata file", "DeleteCaseTask.progress.locatingCaseMetadataFile=Locating case metadata file",
"CaseDeletionTask.progress.deletingCaseOutput=Deleting case output" "DeleteCaseTask.progress.deletingCaseOutput=Deleting case output"
}) })
protected void deleteCaseOutput() { protected void deleteCaseOutput() {
progress.progress(Bundle.CaseDeletionTask_progress_locatingCaseMetadataFile()); progress.progress(Bundle.DeleteCaseTask_progress_locatingCaseMetadataFile());
logger.log(Level.INFO, String.format("Locating metadata file for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Locating metadata file for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
String metadataFilePath = null; String metadataFilePath = null;
final File caseDirectory = caseNodeData.getDirectory().toFile(); final File caseDirectory = caseNodeData.getDirectory().toFile();
@ -234,7 +234,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
} }
if (metadataFilePath != null) { if (metadataFilePath != null) {
progress.progress(Bundle.CaseDeletionTask_progress_deletingCaseOutput()); progress.progress(Bundle.DeleteCaseTask_progress_deletingCaseOutput());
logger.log(Level.INFO, String.format("Deleting output for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting output for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
try { try {
Case.deleteCase(new CaseMetadata(Paths.get(metadataFilePath)), false, progress); Case.deleteCase(new CaseMetadata(Paths.get(metadataFilePath)), false, progress);
@ -254,13 +254,13 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* locks for all of the input directories for the case. * locks for all of the input directories for the case.
*/ */
@Messages({ @Messages({
"CaseDeletionTask.progress.deletingJobLogLockNode=Deleting auto ingest job log lock node", "DeleteCaseTask.progress.deletingJobLogLockNode=Deleting auto ingest job log lock node",
"CaseDeletionTask.progress.deletingResourcesLockNode=Deleting case resources lock node", "DeleteCaseTask.progress.deletingResourcesLockNode=Deleting case resources lock node",
"CaseDeletionTask.progress.deletingDirLockNode=Deleting case directory lock node", "DeleteCaseTask.progress.deletingDirLockNode=Deleting case directory lock node",
"CaseDeletionTask.progress.deletingNameLockNode=Deleting case name lock node" "DeleteCaseTask.progress.deletingNameLockNode=Deleting case name lock node"
}) })
protected void deleteCaseLockNodes() { protected void deleteCaseLockNodes() {
progress.progress(Bundle.CaseDeletionTask_progress_deletingJobLogLockNode()); progress.progress(Bundle.DeleteCaseTask_progress_deletingJobLogLockNode());
logger.log(Level.INFO, String.format("Deleting case auto ingest job log lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting case auto ingest job log lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
Path logFilePath = AutoIngestJobLogger.getLogPath(caseNodeData.getDirectory()); Path logFilePath = AutoIngestJobLogger.getLogPath(caseNodeData.getDirectory());
try { try {
@ -270,7 +270,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
// RJCTODO: Set delete flags // RJCTODO: Set delete flags
} }
progress.progress(Bundle.CaseDeletionTask_progress_deletingResourcesLockNode()); progress.progress(Bundle.DeleteCaseTask_progress_deletingResourcesLockNode());
logger.log(Level.INFO, String.format("Deleting case resources log lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting case resources log lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
String resourcesLockNodePath = caseNodeData.getDirectory().toString() + RESOURCES_LOCK_SUFFIX; String resourcesLockNodePath = caseNodeData.getDirectory().toString() + RESOURCES_LOCK_SUFFIX;
try { try {
@ -280,7 +280,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
// RJCTODO: Set delete flags // RJCTODO: Set delete flags
} }
progress.progress(Bundle.CaseDeletionTask_progress_deletingDirLockNode()); progress.progress(Bundle.DeleteCaseTask_progress_deletingDirLockNode());
logger.log(Level.INFO, String.format("Deleting case directory lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting case directory lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
final Path caseDirectoryPath = caseNodeData.getDirectory(); final Path caseDirectoryPath = caseNodeData.getDirectory();
try { try {
@ -290,7 +290,7 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
// RJCTODO: Set delete flags // RJCTODO: Set delete flags
} }
progress.progress(Bundle.CaseDeletionTask_progress_deletingNameLockNode()); progress.progress(Bundle.DeleteCaseTask_progress_deletingNameLockNode());
logger.log(Level.INFO, String.format("Deleting case name lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting case name lock node for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
final String caseNameLockName = TimeStampUtils.removeTimeStamp(caseNodeData.getName()); final String caseNameLockName = TimeStampUtils.removeTimeStamp(caseNodeData.getName());
try { try {
@ -306,10 +306,10 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* called after releasing all of the locks for the case. * called after releasing all of the locks for the case.
*/ */
@Messages({ @Messages({
"CaseDeletionTask.progress.deletingInputDirLockNodes=Deleting input directory lock nodes" "DeleteCaseTask.progress.deletingInputDirLockNodes=Deleting input directory lock nodes"
}) })
protected void deleteInputDirectoryLockNodes() { protected void deleteInputDirectoryLockNodes() {
progress.progress(Bundle.CaseDeletionTask_progress_deletingInputDirLockNodes()); progress.progress(Bundle.DeleteCaseTask_progress_deletingInputDirLockNodes());
logger.log(Level.INFO, String.format("Deleting input directory lock nodes for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory())); logger.log(Level.INFO, String.format("Deleting input directory lock nodes for %s (%s) in %s", caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()));
for (AutoIngestJobNodeData jobNodeData : nodeDataForAutoIngestJobs) { for (AutoIngestJobNodeData jobNodeData : nodeDataForAutoIngestJobs) {
try { try {
@ -369,12 +369,12 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* could not be obtained. * could not be obtained.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"# {0} - input directory name", "CaseDeletionTask.progress.lockingInputDir=Acquiring exclusive lock on input directory {0}",}) "# {0} - input directory name", "DeleteCaseTask.progress.lockingInputDir=Acquiring exclusive lock on input directory {0}",})
private void getInputDirectoryLocks() { private void getInputDirectoryLocks() {
for (AutoIngestJobNodeData autoIngestJobNodeData : nodeDataForAutoIngestJobs) { for (AutoIngestJobNodeData autoIngestJobNodeData : nodeDataForAutoIngestJobs) {
final Path inputDirPath = autoIngestJobNodeData.getManifestFilePath().getParent(); final Path inputDirPath = autoIngestJobNodeData.getManifestFilePath().getParent();
try { try {
progress.progress(Bundle.CaseDeletionTask_progress_lockingInputDir(inputDirPath)); progress.progress(Bundle.DeleteCaseTask_progress_lockingInputDir(inputDirPath));
final CoordinationService.Lock inputDirLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.MANIFESTS, autoIngestJobNodeData.getManifestFilePath().toString()); final CoordinationService.Lock inputDirLock = coordinationService.tryGetExclusiveLock(CoordinationService.CategoryNode.MANIFESTS, autoIngestJobNodeData.getManifestFilePath().toString());
if (null != inputDirLock) { if (null != inputDirLock) {
manifestFileLocks.put(autoIngestJobNodeData.getManifestFilePath(), inputDirLock); manifestFileLocks.put(autoIngestJobNodeData.getManifestFilePath(), inputDirLock);
@ -396,17 +396,17 @@ abstract class AutoIngestCaseDeletionTask implements Runnable {
* for the case. * for the case.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"CaseDeletionTask.progress.releasingManifestLocks=Acquiring exclusive manifest file locks", "DeleteCaseTask.progress.releasingManifestLocks=Acquiring exclusive manifest file locks",
"# {0} - manifest file path", "CaseDeletionTask.progress.releasingManifestLock=Releasing the exclusive lock on manifest file {0}" "# {0} - manifest file path", "DeleteCaseTask.progress.releasingManifestLock=Releasing the exclusive lock on manifest file {0}"
}) })
private void releaseInputDirectoryLocks() { private void releaseInputDirectoryLocks() {
if (!manifestFileLocks.isEmpty()) { if (!manifestFileLocks.isEmpty()) {
progress.progress(Bundle.CaseDeletionTask_progress_releasingManifestLocks()); progress.progress(Bundle.DeleteCaseTask_progress_releasingManifestLocks());
for (Map.Entry<Path, CoordinationService.Lock> entry : manifestFileLocks.entrySet()) { for (Map.Entry<Path, CoordinationService.Lock> entry : manifestFileLocks.entrySet()) {
final Path manifestFilePath = entry.getKey(); final Path manifestFilePath = entry.getKey();
final CoordinationService.Lock manifestFileLock = entry.getValue(); final CoordinationService.Lock manifestFileLock = entry.getValue();
try { try {
progress.progress(Bundle.CaseDeletionTask_progress_releasingManifestLock(manifestFilePath)); progress.progress(Bundle.DeleteCaseTask_progress_releasingManifestLock(manifestFilePath));
manifestFileLock.release(); manifestFileLock.release();
} catch (CoordinationServiceException ex) { } catch (CoordinationServiceException ex) {
logger.log(Level.SEVERE, String.format("Error re3leasing exclusive lock on %s for %s (%s) in %s", manifestFilePath, caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()), ex); logger.log(Level.SEVERE, String.format("Error re3leasing exclusive lock on %s for %s (%s) in %s", manifestFilePath, caseNodeData.getDisplayName(), caseNodeData.getName(), caseNodeData.getDirectory()), ex);

View File

@ -1,71 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2019-2019 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.experimental.autoingest;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.AbstractAction;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
/**
* An action that completely deletes one or more multi-user cases, including any
* associated auto ingest job input directories and coordination service nodes.
*
* This cases to delete are discovered by querying the actions global context
* lookup for CaseNodeData objects. See
* https://platform.netbeans.org/tutorials/nbm-selection-1.html and
* https://platform.netbeans.org/tutorials/nbm-selection-2.html for details.
*/
final class DeleteCasesAction extends AbstractAction {
private static final long serialVersionUID = 1L;
/**
* Constructs an action that completely deletes one or more multi-user
* cases, including any associated auto ingest job input directories and
* coordination service nodes.
*/
@NbBundle.Messages({
"DeleteCasesAction.menuItemText=Delete Case and Jobs"
})
DeleteCasesAction() {
super(Bundle.DeleteCasesAction_menuItemText());
setEnabled(false); // RJCTODO: Enable when implemented
}
@Override
public void actionPerformed(ActionEvent event) {
// final Collection<CaseNodeData> selectedNodeData = new ArrayList<>(Utilities.actionsGlobalContext().lookupAll(CaseNodeData.class));
// if (!selectedNodeData.isEmpty()) {
// /*
// * RJCTODO: Create a background task that does the deletion and
// * displays results in a dialog with a scrolling text pane.
// */
// }
}
@Override
public DeleteCasesAction clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}

View File

@ -1,48 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.experimental.autoingest;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
/**
* An action that shows a popup that enumerates the deletion status of the
* various parts of a multi-user case known to the coordination service.
*/
final class ShowCaseDeletionStatusAction extends AbstractAction {
private static final long serialVersionUID = 1L;
// private final CaseNodeData caseNodeData;
/**
* Constructs an action that shows a popup that enumerates the deletion
* status of the various parts of a multi-user case known to the
* coordination service.
*
* @param caseNodeData The coordination service node data for the case.
*/
@NbBundle.Messages({
"ShowCaseDeletionStatusAction.menuItemText=Show Deletion Status"
})
ShowCaseDeletionStatusAction(CaseNodeData caseNodeData) {
super(Bundle.ShowCaseDeletionStatusAction_menuItemText());
// this.caseNodeData = caseNodeData; // RJCTODO: Use
setEnabled(false); // RJCTODO: Enable when implemented
}
@Override
public void actionPerformed(ActionEvent e) {
// RJCTODO: Implement
}
@Override
public ShowCaseDeletionStatusAction clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}

View File

@ -49,7 +49,7 @@ ExtractSafari_Error_Parsing_Bookmark=An error occured while processing Safari Bo
ExtractSafari_Error_Parsing_Cookies=An error occured while processing Safari Cookies files ExtractSafari_Error_Parsing_Cookies=An error occured while processing Safari Cookies files
ExtractSafari_Module_Name=Safari ExtractSafari_Module_Name=Safari
OpenIDE-Module-Display-Category=Ingest Module OpenIDE-Module-Display-Category=Ingest Module
OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\nThe module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web acitivity (sites visited, stored cookies, bookmarked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n\The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web acitivity (sites visited, stored cookies, bookmarked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\n\The module currently supports Windows only disk images.\n\The plugin is also fully functional when deployed on Windows version of Autopsy.
OpenIDE-Module-Name=RecentActivity OpenIDE-Module-Name=RecentActivity
OpenIDE-Module-Short-Description=Recent Activity finder ingest module OpenIDE-Module-Short-Description=Recent Activity finder ingest module
Chrome.moduleName=Chrome Chrome.moduleName=Chrome
@ -178,7 +178,7 @@ SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}.
SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine
SearchEngineURLQueryAnalyzer.engineName.none=NONE SearchEngineURLQueryAnalyzer.engineName.none=NONE
SearchEngineURLQueryAnalyzer.domainSubStr.none=NONE SearchEngineURLQueryAnalyzer.domainSubStr.none=NONE
SearchEngineURLQueryAnalyzer.toString=Name: {0}\nDomain Substring: {1}\ncount: {2}\nSplit Tokens: \n{3} SearchEngineURLQueryAnalyzer.toString=Name: {0}\nDomain Substring: {1}\n\count: {2}\nSplit Tokens: \n{3}
SearchEngineURLQueryAnalyzer.parentModuleName.noSpace=RecentActivity SearchEngineURLQueryAnalyzer.parentModuleName.noSpace=RecentActivity
SearchEngineURLQueryAnalyzer.parentModuleName=Recent Activity SearchEngineURLQueryAnalyzer.parentModuleName=Recent Activity
UsbDeviceIdMapper.parseAndLookup.text=Product: {0} UsbDeviceIdMapper.parseAndLookup.text=Product: {0}