From 360c0a293d899e8a2409f25fa09db45c38ec10bc Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 12 Nov 2019 17:12:39 -0500 Subject: [PATCH] Integrate and update data src deletion --- .../casemodule/Bundle.properties-MERGED | 5 +- .../sleuthkit/autopsy/casemodule/Case.java | 36 ++++--- .../casemodule/DeleteDataSourceAction.java | 93 ++++++++++++------- .../netbeans/core/startup/Bundle.properties | 2 +- .../core/windows/view/ui/Bundle.properties | 2 +- 5 files changed, 88 insertions(+), 50 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index e8e65080af..9605ec34ad 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -2,7 +2,6 @@ AddImageWizardIngestConfigPanel.name.text=Configure Ingest Modules AddImageWizardSelectDspVisual.multiUserWarning.text=This type of Data Source Processor is not available in multi-user mode # {0} - exception message Case.closeException.couldNotCloseCase=Error closing case: {0} -Case.creationException.couldNotAcquireDirLock=Failed to get lock on case directory Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources Case.deleteCaseConfirmationDialog.message=Are you sure you want to close and delete the current case? Case.deleteCaseConfirmationDialog.title=Delete Current Case? @@ -53,6 +52,8 @@ Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}. Case.exceptionMessage.metadataUpdateError=Failed to update case metadata # {0} - exception message Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}. +Case.lockingException.couldNotAcquireExclusiveLock=Failed to get a shared lock on the case +Case.lockingException.couldNotAcquireSharedLock=Failed to get an exclusive lock on the case Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User. Case.progressIndicatorCancelButton.label=Cancel Case.progressIndicatorTitle.closingCase=Closing Case @@ -127,8 +128,8 @@ DeleteDataSourceAction.confirmationDialog.message=Are you sure you want to remov DeleteDataSourceAction.exceptionMessage.couldNotReopenCase=Failed to re-open the case:\n{0}\nPlease see the application log for details. # {0} - exception message DeleteDataSourceAction.exceptionMessage.dataSourceDeletionError=An error occurred while removing the data source:\n{0}\nPlease see the application log for details. +DeleteDataSourceAction.ingestRunningWarningDialog.message=Data sources cannot be removed from a case when ingest is running. DeleteDataSourceAction.name.text=Remove Data Source -DeleteDataSourceAction.warningDialog.message=Data sources cannot be removed from a case when ingest is running. EditOptionalCasePropertiesPanel.cancelButton.text=Cancel EditOptionalCasePropertiesPanel.saveButton.text=Save GeneralFilter.encaseImageDesc.text=Encase Images (*.e01) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index 9ff55cdb3b..a2f5d1d966 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -1932,10 +1932,10 @@ public class Case { } catch (CaseActionException ex) { /* - * Cancellation or failure. The sleep is a little hack - * to clear the interrupted flag for this thread if this is a - * cancellation scenario, so that the clean up can run to completion - * in the current thread. + * Cancellation or failure. The sleep is a little hack to clear the + * interrupted flag for this thread if this is a cancellation + * scenario, so that the clean up can run to completion in the + * current thread. */ try { Thread.sleep(1); @@ -1981,10 +1981,10 @@ public class Case { } catch (CaseActionException ex) { /* - * Cancellation or failure. The sleep is a little hack - * to clear the interrupted flag for this thread if this is a - * cancellation scenario, so that the clean up can run to completion - * in the current thread. + * Cancellation or failure. The sleep is a little hack to clear the + * interrupted flag for this thread if this is a cancellation + * scenario, so that the clean up can run to completion in the + * current thread. */ try { Thread.sleep(1); @@ -2013,8 +2013,7 @@ public class Case { "Case.progressMessage.deletingDataSource=Removing the data source from the case...", "Case.exceptionMessage.dataSourceNotFound=The data source was not found.", "Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=An error occurred while removing the data source from the case database.", - "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.", - }) + "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.",}) Void deleteDataSource(ProgressIndicator progressIndicator, Object additionalParams) throws CaseActionException { assert (additionalParams instanceof Long); open(progressIndicator, null); @@ -2652,7 +2651,10 @@ public class Case { * * @throws CaseActionException If the lock cannot be acquired. */ - @Messages({"Case.creationException.couldNotAcquireDirLock=Failed to get lock on case directory"}) + @Messages({ + "Case.lockingException.couldNotAcquireSharedLock=Failed to get an exclusive lock on the case", + "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get a shared lock on the case" + }) private void acquireCaseLock(CaseLockType lockType) throws CaseActionException { String caseDir = metadata.getCaseDirectory(); try { @@ -2661,10 +2663,18 @@ public class Case { ? coordinationService.tryGetSharedLock(CategoryNode.CASES, caseDir, SHARED_CASE_LOCK_TIMEOUT_SECONDS, TimeUnit.SECONDS) : coordinationService.tryGetExclusiveLock(CategoryNode.CASES, caseDir, EXCLUSIVE_CASE_LOCK_TIMEOUT_MINS, TimeUnit.MINUTES); if (caseLock == null) { - throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireDirLock()); + if (lockType == CaseLockType.SHARED) { + throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock()); + } else { + throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock()); + } } } catch (InterruptedException | CoordinationServiceException ex) { - throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireDirLock(), ex); + if (lockType == CaseLockType.SHARED) { + throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock(), ex); + } else { + throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock(), ex); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/DeleteDataSourceAction.java b/Core/src/org/sleuthkit/autopsy/casemodule/DeleteDataSourceAction.java index f4b03b1b41..e603b4045f 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/DeleteDataSourceAction.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/DeleteDataSourceAction.java @@ -69,42 +69,69 @@ public final class DeleteDataSourceAction extends AbstractAction { } if (MessageNotifyUtil.Message.confirm(Bundle.DeleteDataSourceAction_confirmationDialog_message())) { - new SwingWorker() { - - @Override - protected Void doInBackground() throws Exception { - /* - * Save the case metadata file path so the case can be - * reopened if something goes wrong and the case ends up - * closed. - */ - caseMetadataFilePath = Case.getCurrentCase().getMetadata().getFilePath(); - Case.deleteDataSourceFromCurrentCase(dataSourceObjectID); - return null; - } - - @Override - protected void done() { - try { - get(); - } catch (InterruptedException | ExecutionException ex) { - logger.log(Level.SEVERE, String.format("Error deleting data source (obj_id=%d)", dataSourceObjectID), ex); - MessageNotifyUtil.Message.show(Bundle.DeleteDataSourceAction_exceptionMessage_dataSourceDeletionError(ex.getLocalizedMessage()), MessageNotifyUtil.MessageType.ERROR); - if (!Case.isCaseOpen()) { - try { - Case.openAsCurrentCase(caseMetadataFilePath.toString()); - } catch (CaseActionException ex2) { - logger.log(Level.SEVERE, "Failed to reopen the case after data source deletion error", ex2); - MessageNotifyUtil.Message.show(Bundle.DeleteDataSourceAction_exceptionMessage_couldNotReopenCase(ex.getLocalizedMessage()), MessageNotifyUtil.MessageType.ERROR); - StartupWindowProvider.getInstance().open(); - } - } - } - } - }.execute(); + new DataSourceDeletionWorker().execute(); } } + /** + * A SwingWorker to do the data source deletion. + */ + private class DataSourceDeletionWorker extends SwingWorker { + + @Override + protected Void doInBackground() throws Exception { + /* + * Save the case metadata file path so the case can be reopened if + * something goes wrong and the case ends up closed. + */ + caseMetadataFilePath = Case.getCurrentCase().getMetadata().getFilePath(); + Case.deleteDataSourceFromCurrentCase(dataSourceObjectID); + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException | ExecutionException ex) { + logger.log(Level.SEVERE, String.format("Error deleting data source (obj_id=%d)", dataSourceObjectID), ex); + MessageNotifyUtil.Message.show(Bundle.DeleteDataSourceAction_exceptionMessage_dataSourceDeletionError(ex.getLocalizedMessage()), MessageNotifyUtil.MessageType.ERROR); + if (!Case.isCaseOpen()) { + new CaseReopeningWorker().execute(); + } + } + } + + } + + /** + * A SwingWorker to attempt to re-open the case after a data source deletion + * exception. + */ + private class CaseReopeningWorker extends SwingWorker { + + @Override + protected Void doInBackground() throws Exception { + Case.openAsCurrentCase(caseMetadataFilePath.toString()); + return null; + } + + @Override + protected void done() { + try { + get(); + } catch (InterruptedException ex) { + logger.log(Level.WARNING, String.format("Interrupted reopening case after error deleting data source (obj_id=%d)", dataSourceObjectID), ex); + + } catch (ExecutionException ex) { + logger.log(Level.SEVERE, String.format("Error reopening case after error deleting data source (obj_id=%d)", dataSourceObjectID), ex); + MessageNotifyUtil.Message.show(Bundle.DeleteDataSourceAction_exceptionMessage_dataSourceDeletionError(ex.getCause().getLocalizedMessage()), MessageNotifyUtil.MessageType.ERROR); + StartupWindowProvider.getInstance().open(); + } + } + + } + @Override public DeleteDataSourceAction clone() throws CloneNotSupportedException { DeleteDataSourceAction clonedObject = ((DeleteDataSourceAction) super.clone()); diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index cd78d5c461..cd55f492ea 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Fri, 08 Nov 2019 16:32:05 -0500 +#Tue, 12 Nov 2019 16:58:46 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 721ab292cd..06565e185c 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Fri, 08 Nov 2019 16:32:05 -0500 +#Tue, 12 Nov 2019 16:58:46 -0500 CTL_MainWindow_Title=Autopsy 4.13.0 CTL_MainWindow_Title_No_Project=Autopsy 4.13.0