From 0cfd04727a0a1d87c918e290d05ceb40b66b8c89 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Sun, 7 Apr 2019 23:59:21 -0400 Subject: [PATCH] Add progress messages to orphan case znode cleanup --- .../autoingest/Bundle.properties-MERGED | 16 ++++ .../autoingest/CaseNodesCleanupAction.java | 9 ++ .../autoingest/CaseNodesCleanupTask.java | 91 +++++++++++-------- 3 files changed, 79 insertions(+), 37 deletions(-) diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED index 88015ce287..75029eb497 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties-MERGED @@ -89,6 +89,10 @@ AutoIngestControlPanel.runningTable.toolTipText=The Running table displays the c AutoIngestControlPanel.SharedConfigurationDisabled=Shared configuration disabled AutoIngestControlPanel.ShowLogFailed.Message=Case log file does not exist 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.Down=down AutoIngestControlPanel.tbServicesStatusMessage.Message.Unknown=unknown @@ -135,6 +139,12 @@ AutoIngestJobsPanel.waitNode.text=Please Wait... AutoIngestMetricsDialog.initReportText=Select a date above and click the 'Generate Metrics Report' button to generate\na metrics report. AutoIngestMetricsDialog.title.text=Auto Ingest Metrics CaseNodesCleanupAction.progressDisplayName=Cleanup Case Znodes +CaseNodesCleanupTask.progress.connectingToCoordSvc=Connecting to the coordination service... +# {0} - node path +CaseNodesCleanupTask.progress.deletingOrphanedCaseNode=Deleting orphaned case node {0}... +CaseNodesCleanupTask.progress.gettingCaseNodesListing=Querying coordination service for case nodes... +CaseNodesCleanupTask.progress.lockingManifest=Deleting orphaned case node {0}... +CaseNodesCleanupTask.progress.startMessage=Starting deletion... ConfirmationDialog.DoNotDelete=Do not delete ConfirmationDialog.Delete=Permanently delete ConfirmationDialog.DeleteAreYouSure=The entire case will be removed. Are you sure you want to delete case @@ -183,17 +193,23 @@ DeleteCaseTask.progress.acquiringManifestLocks=Acquiring exclusive manifest file DeleteCaseTask.progress.connectingToCoordSvc=Connecting to the coordination service... DeleteCaseTask.progress.deletingCaseDirCoordSvcNode=Deleting case directory znode... DeleteCaseTask.progress.deletingCaseNameCoordSvcNode=Deleting case name znode... +# {0} - data source path DeleteCaseTask.progress.deletingDataSource=Deleting data source {0}... DeleteCaseTask.progress.deletingJobLogLockNode=Deleting case auto ingest log znode... +# {0} - manifest file path DeleteCaseTask.progress.deletingManifest=Deleting manifest file {0}... +# {0} - manifest file path DeleteCaseTask.progress.deletingManifestFileNode=Deleting the manifest file znode for {0}... DeleteCaseTask.progress.deletingResourcesLockNode=Deleting case resources znode... DeleteCaseTask.progress.gettingManifestPaths=Getting manifest file paths... +# {0} - manifest file path DeleteCaseTask.progress.lockingManifest=Locking manifest file {0}... DeleteCaseTask.progress.Manifest=Deleting manifest file {0}... DeleteCaseTask.progress.openingCaseDatabase=Opening the case database... DeleteCaseTask.progress.openingCaseMetadataFile=Opening case metadata file... +# {0} - manifest file path DeleteCaseTask.progress.parsingManifest=Parsing manifest file {0}... +# {0} - manifest file path DeleteCaseTask.progress.releasingManifestLock=Releasing lock on the manifest file {0}... DeleteCaseTask.progress.startMessage=Starting deletion... HINT_CasesDashboardTopComponent=This is an adminstrative dashboard for multi-user cases diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupAction.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupAction.java index 2763ba2138..e655eb2473 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupAction.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupAction.java @@ -19,8 +19,10 @@ package org.sleuthkit.autopsy.experimental.autoingest; import java.awt.event.ActionEvent; +import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import javax.swing.AbstractAction; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.progress.AppFrameProgressBar; import org.sleuthkit.autopsy.progress.TaskCancellable; @@ -46,6 +48,13 @@ final class CaseNodesCleanupAction extends AbstractAction { final FutureTask future = new FutureTask<>(task, null); taskCanceller.setFuture(future); new Thread(future).start(); + try { + future.get(); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } catch (ExecutionException ex) { + Exceptions.printStackTrace(ex); + } } @Override diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupTask.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupTask.java index 7cdb29711d..60bd7e5c37 100755 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupTask.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/CaseNodesCleanupTask.java @@ -21,8 +21,8 @@ package org.sleuthkit.autopsy.experimental.autoingest; import java.io.File; import java.nio.file.Path; import java.util.List; -import java.util.concurrent.Callable; import java.util.logging.Level; +import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData; import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeDataCollector; import org.sleuthkit.autopsy.casemodule.multiusercases.CoordinationServiceUtils; @@ -50,50 +50,62 @@ final class CaseNodesCleanupTask implements Runnable { } @Override + @NbBundle.Messages({ + "CaseNodesCleanupTask.progress.connectingToCoordSvc=Connecting to the coordination service...", + "CaseNodesCleanupTask.progress.gettingCaseNodesListing=Querying coordination service for case nodes..." + }) public void run() { - CoordinationService coordinationService; try { - coordinationService = CoordinationService.getInstance(); - } catch (CoordinationService.CoordinationServiceException ex) { - logger.log(Level.WARNING, "Error connecting to the coordination service", ex); // NON-NLS - return; - } + progress.progress(Bundle.CaseNodesCleanupTask_progress_connectingToCoordSvc()); + logger.log(Level.INFO, "Connecting to the coordination service for orphan case node clean up"); // NON-NLS + CoordinationService coordinationService; + try { + coordinationService = CoordinationService.getInstance(); + } catch (CoordinationService.CoordinationServiceException ex) { + logger.log(Level.WARNING, "Error connecting to the coordination service", ex); // NON-NLS + return; + } - List nodeDataList; - try { - nodeDataList = CaseNodeDataCollector.getNodeData(); - } catch (CoordinationService.CoordinationServiceException ex) { - logger.log(Level.WARNING, "Error collecting case node data", ex); // NON-NLS - return; - } catch (InterruptedException ex) { - logger.log(Level.WARNING, "Unexpected interrupt while collecting case node data", ex); // NON-NLS - return; - } + progress.progress(Bundle.CaseNodesCleanupTask_progress_gettingCaseNodesListing()); + logger.log(Level.INFO, "Querying coordination service for case nodes for orphan case node clean up"); // NON-NLS + List nodeDataList; + try { + nodeDataList = CaseNodeDataCollector.getNodeData(); + } catch (CoordinationService.CoordinationServiceException ex) { + logger.log(Level.WARNING, "Error collecting case node data", ex); // NON-NLS + return; + } catch (InterruptedException ex) { + logger.log(Level.WARNING, "Unexpected interrupt while collecting case node data", ex); // NON-NLS + return; + } - for (CaseNodeData nodeData : nodeDataList) { - final Path caseDirectoryPath = nodeData.getDirectory(); - final File caseDirectory = caseDirectoryPath.toFile(); - if (!caseDirectory.exists()) { - String caseName = nodeData.getDisplayName(); - String nodePath = ""; // NON-NLS - try { - nodePath = CoordinationServiceUtils.getCaseNameNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); + for (CaseNodeData nodeData : nodeDataList) { + final Path caseDirectoryPath = nodeData.getDirectory(); + final File caseDirectory = caseDirectoryPath.toFile(); + if (!caseDirectory.exists()) { + String caseName = nodeData.getDisplayName(); + String nodePath = ""; // NON-NLS + try { + nodePath = CoordinationServiceUtils.getCaseNameNodePath(caseDirectoryPath); + deleteNode(coordinationService, caseName, nodePath); - nodePath = CoordinationServiceUtils.getCaseResourcesNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); + nodePath = CoordinationServiceUtils.getCaseResourcesNodePath(caseDirectoryPath); + deleteNode(coordinationService, caseName, nodePath); - nodePath = CoordinationServiceUtils.getCaseAutoIngestLogNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); + nodePath = CoordinationServiceUtils.getCaseAutoIngestLogNodePath(caseDirectoryPath); + deleteNode(coordinationService, caseName, nodePath); - nodePath = CoordinationServiceUtils.getCaseDirectoryNodePath(caseDirectoryPath); - deleteNode(coordinationService, caseName, nodePath); + nodePath = CoordinationServiceUtils.getCaseDirectoryNodePath(caseDirectoryPath); + deleteNode(coordinationService, caseName, nodePath); - } catch (InterruptedException ex) { - logger.log(Level.WARNING, String.format("Unexpected interrupt while deleting znode %s for %s", nodePath, caseName), ex); // NON-NLS - return; + } catch (InterruptedException ex) { + logger.log(Level.WARNING, String.format("Unexpected interrupt while deleting znode %s for %s", nodePath, caseName), ex); // NON-NLS + return; + } } } + } finally { + progress.finish(); } } @@ -107,12 +119,17 @@ final class CaseNodesCleanupTask implements Runnable { * @throws InterruptedException If the thread executing this task is * interrupted during the delete operation. */ - private static void deleteNode(CoordinationService coordinationService, String caseName, String nodePath) throws InterruptedException { + @NbBundle.Messages({ + "# {0} - node path", "CaseNodesCleanupTask.progress.deletingOrphanedCaseNode=Deleting orphaned case node {0}..." + }) + private void deleteNode(CoordinationService coordinationService, String caseName, String nodePath) throws InterruptedException { try { + progress.progress(Bundle.CaseNodesCleanupTask_progress_deletingOrphanedCaseNode(nodePath)); + logger.log(Level.INFO, String.format("Deleting orphaned case node %s for %s", nodePath, caseName)); // NON-NLS coordinationService.deleteNode(CoordinationService.CategoryNode.CASES, nodePath); } catch (CoordinationService.CoordinationServiceException ex) { if (!DeleteCaseUtils.isNoNodeException(ex)) { - logger.log(Level.SEVERE, String.format("Error deleting %s znode for %s", nodePath, caseName), ex); // NON-NLS + logger.log(Level.SEVERE, String.format("Error deleting orphaned case node %s for %s", nodePath, caseName), ex); // NON-NLS } } }