mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 17:27:43 +00:00
Fixes for Case operation cancellation infrastructure
This commit is contained in:
parent
3ada14c54d
commit
c6c45288f4
@ -43,6 +43,7 @@ import java.util.MissingResourceException;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@ -95,7 +96,6 @@ import org.sleuthkit.autopsy.framework.ModalDialogProgressIndicator;
|
|||||||
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestJob;
|
import org.sleuthkit.autopsy.ingest.IngestJob;
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.RunIngestAction;
|
|
||||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
||||||
import org.sleuthkit.autopsy.timeline.OpenTimelineAction;
|
import org.sleuthkit.autopsy.timeline.OpenTimelineAction;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifactTag;
|
import org.sleuthkit.datamodel.BlackboardArtifactTag;
|
||||||
@ -443,11 +443,11 @@ public class Case {
|
|||||||
* exception.
|
* exception.
|
||||||
*/
|
*/
|
||||||
@Messages({
|
@Messages({
|
||||||
"# {0} - exception message", "Case.creationException.couldNotCreateCase=Could not create case: {0}",
|
"# {0} - exception message", "Case.exceptionMessage.wrapperMessage={0}",
|
||||||
"Case.exceptionMessage.illegalCaseName=Case name contains illegal characters.",
|
"Case.exceptionMessage.illegalCaseName=Case name contains illegal characters.",
|
||||||
"Case.exceptionMessage.lockAcquisitionInterrupted=Acquiring locks was interrupted.",
|
"Case.exceptionMessage.cancelled=Cancelled by user.",
|
||||||
"Case.progressIndicatorTitle.creatingCase=Creating Case",
|
"Case.progressIndicatorTitle.creatingCase=Creating Case",
|
||||||
"Case.progressIndicatorCancelButton.label=Cancel",
|
"Case.progressIndicatorCancelButton.label=Cancelled",
|
||||||
"Case.progressMessage.preparing=Preparing...",
|
"Case.progressMessage.preparing=Preparing...",
|
||||||
"Case.progressMessage.acquiringLocks=Acquiring locks...",
|
"Case.progressMessage.acquiringLocks=Acquiring locks...",
|
||||||
"Case.progressMessage.finshing=Finishing..."
|
"Case.progressMessage.finshing=Finishing..."
|
||||||
@ -482,7 +482,6 @@ public class Case {
|
|||||||
} catch (IllegalCaseNameException ex) {
|
} catch (IllegalCaseNameException ex) {
|
||||||
throw new CaseActionException(Bundle.Case_creationException_couldNotCreateCase(Bundle.Case_exceptionMessage_illegalCaseName()), ex);
|
throw new CaseActionException(Bundle.Case_creationException_couldNotCreateCase(Bundle.Case_exceptionMessage_illegalCaseName()), ex);
|
||||||
}
|
}
|
||||||
logger.log(Level.INFO, "Attempting to create case {0} (display name = {1}) in directory = {2}", new Object[]{caseName, caseDisplayName, caseDir}); //NON-NLS
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up either a GUI progress indicator or a logging progress
|
* Set up either a GUI progress indicator or a logging progress
|
||||||
@ -507,7 +506,6 @@ public class Case {
|
|||||||
* open is released in the same thread in which it was acquired, as is
|
* open is released in the same thread in which it was acquired, as is
|
||||||
* required by the coordination service.
|
* required by the coordination service.
|
||||||
*/
|
*/
|
||||||
try {
|
|
||||||
Future<Case> future = getCaseLockingExecutor().submit(() -> {
|
Future<Case> future = getCaseLockingExecutor().submit(() -> {
|
||||||
if (CaseType.SINGLE_USER_CASE == caseType) {
|
if (CaseType.SINGLE_USER_CASE == caseType) {
|
||||||
newCase.open(caseDir, caseName, caseDisplayName, caseNumber, examiner, caseType, progressIndicator);
|
newCase.open(caseDir, caseName, caseDisplayName, caseNumber, examiner, caseType, progressIndicator);
|
||||||
@ -520,9 +518,9 @@ public class Case {
|
|||||||
try (CoordinationService.Lock nameLock = Case.acquireExclusiveCaseNameLock(caseName)) {
|
try (CoordinationService.Lock nameLock = Case.acquireExclusiveCaseNameLock(caseName)) {
|
||||||
assert (null != nameLock);
|
assert (null != nameLock);
|
||||||
/*
|
/*
|
||||||
* Next, acquire a shared case directory lock that will
|
* Next, acquire a shared case directory lock that will be
|
||||||
* be held as long as this node has this case open. This
|
* held as long as this node has this case open. This will
|
||||||
* will prevent deletion of the case by another node.
|
* prevent deletion of the case by another node.
|
||||||
*/
|
*/
|
||||||
acquireSharedCaseDirLock(caseDir);
|
acquireSharedCaseDirLock(caseDir);
|
||||||
/*
|
/*
|
||||||
@ -536,8 +534,8 @@ public class Case {
|
|||||||
newCase.open(caseDir, caseName, caseDisplayName, caseNumber, examiner, caseType, progressIndicator);
|
newCase.open(caseDir, caseName, caseDisplayName, caseNumber, examiner, caseType, progressIndicator);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
/*
|
/*
|
||||||
* Release the case directory lock immediately
|
* Release the case directory lock immediately if
|
||||||
* if there was a problem opening the case.
|
* there was a problem opening the case.
|
||||||
*/
|
*/
|
||||||
if (CaseType.MULTI_USER_CASE == caseType) {
|
if (CaseType.MULTI_USER_CASE == caseType) {
|
||||||
releaseSharedCaseDirLock(caseName);
|
releaseSharedCaseDirLock(caseName);
|
||||||
@ -549,10 +547,22 @@ public class Case {
|
|||||||
}
|
}
|
||||||
return newCase;
|
return newCase;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If running with a GUI, give the future for the case creation task to
|
||||||
|
* the cancel button listener for the GUI progress indicator and make
|
||||||
|
* the progress indicator visible to the user.
|
||||||
|
*/
|
||||||
if (RuntimeProperties.runningWithGUI()) {
|
if (RuntimeProperties.runningWithGUI()) {
|
||||||
listener.setCaseActionFuture(future);
|
listener.setCaseActionFuture(future);
|
||||||
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(true));
|
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the case creation task to finish.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
logger.log(Level.INFO, "Attempting to create case {0} (display name = {1}) in directory = {2}", new Object[]{caseName, caseDisplayName, caseDir}); //NON-NLS
|
||||||
currentCase = future.get();
|
currentCase = future.get();
|
||||||
logger.log(Level.INFO, "Created case {0} in directory = {1}", new Object[]{caseName, caseDir}); //NON-NLS
|
logger.log(Level.INFO, "Created case {0} in directory = {1}", new Object[]{caseName, caseDir}); //NON-NLS
|
||||||
if (RuntimeProperties.runningWithGUI()) {
|
if (RuntimeProperties.runningWithGUI()) {
|
||||||
@ -560,12 +570,12 @@ public class Case {
|
|||||||
}
|
}
|
||||||
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase));
|
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase));
|
||||||
|
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException ex) {
|
||||||
if (ex instanceof InterruptedException) {
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getMessage()), ex);
|
||||||
throw new CaseActionException(Bundle.Case_creationException_couldNotCreateCase(Bundle.Case_exceptionMessage_lockAcquisitionInterrupted()), ex);
|
} catch (ExecutionException ex) {
|
||||||
} else {
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getCause().getMessage()), ex);
|
||||||
throw new CaseActionException(Bundle.Case_creationException_couldNotCreateCase(ex.getCause().getMessage()), ex);
|
} catch (CancellationException ex) {
|
||||||
}
|
throw new CaseActionException(Bundle.Case_exceptionMessage_cancelled(), ex);
|
||||||
} finally {
|
} finally {
|
||||||
progressIndicator.finish(Bundle.Case_progressMessage_finshing());
|
progressIndicator.finish(Bundle.Case_progressMessage_finshing());
|
||||||
if (RuntimeProperties.runningWithGUI()) {
|
if (RuntimeProperties.runningWithGUI()) {
|
||||||
@ -589,6 +599,7 @@ public class Case {
|
|||||||
"Case.progressIndicatorTitle.openingCase=Opening Case",
|
"Case.progressIndicatorTitle.openingCase=Opening Case",
|
||||||
"Case.exceptionMessage.failedToReadMetadata=Failed to read metadata."
|
"Case.exceptionMessage.failedToReadMetadata=Failed to read metadata."
|
||||||
})
|
})
|
||||||
|
|
||||||
public static void openAsCurrentCase(String caseMetadataFilePath) throws CaseActionException {
|
public static void openAsCurrentCase(String caseMetadataFilePath) throws CaseActionException {
|
||||||
/*
|
/*
|
||||||
* If running with the desktop GUI, this needs to be done before any
|
* If running with the desktop GUI, this needs to be done before any
|
||||||
@ -609,9 +620,12 @@ public class Case {
|
|||||||
closeCurrentCase();
|
closeCurrentCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(Level.INFO, "Opening case with metadata file path {0}", caseMetadataFilePath); //NON-NLS
|
CaseMetadata metadata;
|
||||||
try {
|
try {
|
||||||
CaseMetadata metadata = new CaseMetadata(Paths.get(caseMetadataFilePath));
|
metadata = new CaseMetadata(Paths.get(caseMetadataFilePath));
|
||||||
|
} catch (CaseMetadataException ex) {
|
||||||
|
throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase(Bundle.Case_exceptionMessage_failedToReadMetadata()), ex);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up either a GUI progress indicator or a logging progress
|
* Set up either a GUI progress indicator or a logging progress
|
||||||
@ -630,31 +644,29 @@ public class Case {
|
|||||||
progressIndicator.start(Bundle.Case_progressMessage_preparing());
|
progressIndicator.start(Bundle.Case_progressMessage_preparing());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Opening a case is always done in the same non-UI thread that will
|
* Opening a case is always done in the same non-UI thread that will be
|
||||||
* be used later to close the case. If the case is a multi-user
|
* used later to close the case. If the case is a multi-user case, this
|
||||||
* case, this ensures that case directory lock that is held as long
|
* ensures that case directory lock that is held as long as the case is
|
||||||
* as the case is open is released in the same thread in which it
|
* open is released in the same thread in which it was acquired, as is
|
||||||
* was acquired, as is required by the coordination service.
|
* required by the coordination service.
|
||||||
*/
|
*/
|
||||||
CaseType caseType = metadata.getCaseType();
|
CaseType caseType = metadata.getCaseType();
|
||||||
String caseName = metadata.getCaseName();
|
String caseName = metadata.getCaseName();
|
||||||
try {
|
|
||||||
Future<Case> future = getCaseLockingExecutor().submit(() -> {
|
Future<Case> future = getCaseLockingExecutor().submit(() -> {
|
||||||
if (CaseType.SINGLE_USER_CASE == caseType) {
|
if (CaseType.SINGLE_USER_CASE == caseType) {
|
||||||
caseToOpen.open(metadata, progressIndicator);
|
caseToOpen.open(metadata, progressIndicator);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* First, acquire a shared case directory lock that will
|
* First, acquire a shared case directory lock that will be held
|
||||||
* be held as long as this node has this case open, in
|
* as long as this node has this case open, in order to prevent
|
||||||
* order to prevent deletion of the case by another
|
* deletion of the case by another node.
|
||||||
* node.
|
|
||||||
*/
|
*/
|
||||||
progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks());
|
progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks());
|
||||||
acquireSharedCaseDirLock(metadata.getCaseDirectory());
|
acquireSharedCaseDirLock(metadata.getCaseDirectory());
|
||||||
/*
|
/*
|
||||||
* Next, acquire an exclusive case resources lock to
|
* Next, acquire an exclusive case resources lock to ensure only
|
||||||
* ensure only one node at a time can
|
* one node at a time can create/open/upgrade/close case
|
||||||
* create/open/upgrade/close case resources.
|
* resources.
|
||||||
*/
|
*/
|
||||||
try (CoordinationService.Lock resourcesLock = acquireExclusiveCaseResourcesLock(metadata.getCaseName())) {
|
try (CoordinationService.Lock resourcesLock = acquireExclusiveCaseResourcesLock(metadata.getCaseName())) {
|
||||||
assert (null != resourcesLock);
|
assert (null != resourcesLock);
|
||||||
@ -662,8 +674,8 @@ public class Case {
|
|||||||
caseToOpen.open(metadata, progressIndicator);
|
caseToOpen.open(metadata, progressIndicator);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException ex) {
|
||||||
/*
|
/*
|
||||||
* Release the case directory lock immediately
|
* Release the case directory lock immediately if there
|
||||||
* if there was a problem opening the case.
|
* was a problem opening the case.
|
||||||
*/
|
*/
|
||||||
if (CaseType.MULTI_USER_CASE == caseType) {
|
if (CaseType.MULTI_USER_CASE == caseType) {
|
||||||
releaseSharedCaseDirLock(caseName);
|
releaseSharedCaseDirLock(caseName);
|
||||||
@ -674,32 +686,41 @@ public class Case {
|
|||||||
}
|
}
|
||||||
return caseToOpen;
|
return caseToOpen;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If running with a GUI, give the future for the case opening task to
|
||||||
|
* the cancel button listener for the GUI progress indicator and make
|
||||||
|
* the progress indicator visible to the user.
|
||||||
|
*/
|
||||||
if (RuntimeProperties.runningWithGUI()) {
|
if (RuntimeProperties.runningWithGUI()) {
|
||||||
listener.setCaseActionFuture(future);
|
listener.setCaseActionFuture(future);
|
||||||
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(true));
|
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(true));
|
||||||
}
|
}
|
||||||
future.get();
|
|
||||||
|
/*
|
||||||
|
* Wait for the case opening task to finish.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
logger.log(Level.INFO, "Opening case with metadata file path {0}", caseMetadataFilePath); //NON-NLS
|
||||||
currentCase = future.get();
|
currentCase = future.get();
|
||||||
logger.log(Level.INFO, "Opened case with metadata file path {0}", caseMetadataFilePath); //NON-NLS
|
logger.log(Level.INFO, "Opened case with metadata file path {0}", caseMetadataFilePath); //NON-NLS
|
||||||
if (RuntimeProperties.runningWithGUI()) {
|
if (RuntimeProperties.runningWithGUI()) {
|
||||||
updateGUIForCaseOpened();
|
updateGUIForCaseOpened();
|
||||||
}
|
}
|
||||||
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase));
|
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase));
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
|
||||||
if (ex instanceof ExecutionException) {
|
} catch (InterruptedException ex) {
|
||||||
throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase(ex.getCause().getMessage()), ex);
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getMessage()), ex);
|
||||||
} else {
|
} catch (ExecutionException ex) {
|
||||||
throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase(Bundle.Case_exceptionMessage_lockAcquisitionInterrupted()), ex);
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getCause().getMessage()), ex);
|
||||||
}
|
} catch (CancellationException ex) {
|
||||||
|
throw new CaseActionException(Bundle.Case_exceptionMessage_cancelled(), ex);
|
||||||
} finally {
|
} finally {
|
||||||
progressIndicator.finish(Bundle.Case_progressMessage_finshing());
|
progressIndicator.finish(Bundle.Case_progressMessage_finshing());
|
||||||
if (RuntimeProperties.runningWithGUI()) {
|
if (RuntimeProperties.runningWithGUI()) {
|
||||||
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(false));
|
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (CaseMetadataException ex) {
|
|
||||||
throw new CaseActionException(Bundle.Case_openException_couldNotOpenCase(Bundle.Case_exceptionMessage_failedToReadMetadata()), ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -763,14 +784,12 @@ public class Case {
|
|||||||
listener.setCaseContext(caseContext);
|
listener.setCaseContext(caseContext);
|
||||||
progressIndicator.start(Bundle.Case_progressMessage_preparing());
|
progressIndicator.start(Bundle.Case_progressMessage_preparing());
|
||||||
|
|
||||||
logger.log(Level.INFO, "Closing case with metadata file path {0}", currentCase.getCaseMetadata().getFilePath()); //NON-NLS
|
|
||||||
try {
|
|
||||||
/*
|
/*
|
||||||
* Closing a case is always done in the same non-UI thread that
|
* Closing a case is always done in the same non-UI thread that
|
||||||
* opened/created the case. If the case is a multi-user case, this
|
* opened/created the case. If the case is a multi-user case, this
|
||||||
* ensures that case directory lock that is held as long as the case
|
* ensures that case directory lock that is held as long as the case is
|
||||||
* is open is released in the same thread in which it was acquired,
|
* open is released in the same thread in which it was acquired, as is
|
||||||
* as is required by the coordination service.
|
* required by the coordination service.
|
||||||
*/
|
*/
|
||||||
Future<Void> future = getCaseLockingExecutor().submit(() -> {
|
Future<Void> future = getCaseLockingExecutor().submit(() -> {
|
||||||
if (CaseType.SINGLE_USER_CASE == currentCase.getCaseType()) {
|
if (CaseType.SINGLE_USER_CASE == currentCase.getCaseType()) {
|
||||||
@ -778,8 +797,8 @@ public class Case {
|
|||||||
} else {
|
} else {
|
||||||
String caseName = currentCase.getCaseMetadata().getCaseName();
|
String caseName = currentCase.getCaseMetadata().getCaseName();
|
||||||
/*
|
/*
|
||||||
* Acquire an exclusive case resources lock to ensure only
|
* Acquire an exclusive case resources lock to ensure only one
|
||||||
* one node at a time can create/open/upgrade/close the case
|
* node at a time can create/open/upgrade/close the case
|
||||||
* resources.
|
* resources.
|
||||||
*/
|
*/
|
||||||
progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks());
|
progressIndicator.start(Bundle.Case_progressMessage_acquiringLocks());
|
||||||
@ -788,25 +807,34 @@ public class Case {
|
|||||||
currentCase.close(progressIndicator);
|
currentCase.close(progressIndicator);
|
||||||
} finally {
|
} finally {
|
||||||
/*
|
/*
|
||||||
* Always release the case directory lock that was
|
* Always release the case directory lock that was acquired
|
||||||
* acquired when the case was opened.
|
* when the case was opened.
|
||||||
*/
|
*/
|
||||||
releaseSharedCaseDirLock(caseName);
|
releaseSharedCaseDirLock(caseName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If running with a GUI, give the future for the case closing task to
|
||||||
|
* the cancel button listener for the GUI progress indicator and make
|
||||||
|
* the progress indicator visible to the user.
|
||||||
|
*/
|
||||||
if (RuntimeProperties.runningWithGUI()) {
|
if (RuntimeProperties.runningWithGUI()) {
|
||||||
listener.setCaseActionFuture(future);
|
listener.setCaseActionFuture(future);
|
||||||
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(true));
|
SwingUtilities.invokeLater(() -> ((ModalDialogProgressIndicator) progressIndicator).setVisible(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
logger.log(Level.INFO, "Closing case with metadata file path {0}", currentCase.getCaseMetadata().getFilePath()); //NON-NLS
|
||||||
future.get();
|
future.get();
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException ex) {
|
||||||
if (ex instanceof ExecutionException) {
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getMessage()), ex);
|
||||||
throw new CaseActionException(Bundle.Case_closeException_couldNotCloseCase(ex.getCause().getMessage()), ex);
|
} catch (ExecutionException ex) {
|
||||||
} else {
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getCause().getMessage()), ex);
|
||||||
throw new CaseActionException(Bundle.Case_closeException_couldNotCloseCase(Bundle.Case_exceptionMessage_lockAcquisitionInterrupted()), ex);
|
} catch (CancellationException ex) {
|
||||||
}
|
throw new CaseActionException(Bundle.Case_exceptionMessage_cancelled(), ex);
|
||||||
} finally {
|
} finally {
|
||||||
/*
|
/*
|
||||||
* The case is no longer the current case, even if an exception was
|
* The case is no longer the current case, even if an exception was
|
||||||
@ -865,8 +893,6 @@ public class Case {
|
|||||||
throw new CaseActionException(Bundle.Case_deleteException_couldNotDeleteCase(Bundle.Case_exceptionMessage_cannotDeleteCurrentCase()));
|
throw new CaseActionException(Bundle.Case_deleteException_couldNotDeleteCase(Bundle.Case_exceptionMessage_cannotDeleteCurrentCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(Level.INFO, "Deleting case with metadata file path {0}", metadata.getFilePath()); //NON-NLS
|
|
||||||
try {
|
|
||||||
/*
|
/*
|
||||||
* Set up either a GUI progress indicator or a logging progress
|
* Set up either a GUI progress indicator or a logging progress
|
||||||
* indicator.
|
* indicator.
|
||||||
@ -884,6 +910,7 @@ public class Case {
|
|||||||
progressIndicator = new LoggingProgressIndicator();
|
progressIndicator = new LoggingProgressIndicator();
|
||||||
}
|
}
|
||||||
progressIndicator.start(Bundle.Case_progressMessage_preparing());
|
progressIndicator.start(Bundle.Case_progressMessage_preparing());
|
||||||
|
|
||||||
Future<Void> future = getCaseLockingExecutor().submit(() -> {
|
Future<Void> future = getCaseLockingExecutor().submit(() -> {
|
||||||
if (CaseType.SINGLE_USER_CASE == metadata.getCaseType()) {
|
if (CaseType.SINGLE_USER_CASE == metadata.getCaseType()) {
|
||||||
cleanupDeletedCase(metadata, progressIndicator);
|
cleanupDeletedCase(metadata, progressIndicator);
|
||||||
@ -906,10 +933,9 @@ public class Case {
|
|||||||
|
|
||||||
if (CaseType.MULTI_USER_CASE == metadata.getCaseType()) {
|
if (CaseType.MULTI_USER_CASE == metadata.getCaseType()) {
|
||||||
/*
|
/*
|
||||||
* Delete the case database from the database
|
* Delete the case database from the database server.
|
||||||
* server. The case database for a single-user case
|
* The case database for a single-user case is in the
|
||||||
* is in the case directory and will be deleted whe
|
* case directory and will be deleted whe it is deleted.
|
||||||
* it is deleted.
|
|
||||||
*/
|
*/
|
||||||
progressIndicator.start(Bundle.Case_progressMessage_deletingCaseDatabase());
|
progressIndicator.start(Bundle.Case_progressMessage_deletingCaseDatabase());
|
||||||
CaseDbConnectionInfo db = UserPreferences.getDatabaseConnectionInfo();
|
CaseDbConnectionInfo db = UserPreferences.getDatabaseConnectionInfo();
|
||||||
@ -926,14 +952,17 @@ public class Case {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
logger.log(Level.INFO, "Deleted case with metadata file path {0}", metadata.getFilePath()); //NON-NLS
|
|
||||||
|
try {
|
||||||
|
logger.log(Level.INFO, "Deleting case with metadata file path {0}", metadata.getFilePath()); //NON-NLS
|
||||||
future.get();
|
future.get();
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
logger.log(Level.INFO, "Deleted case with metadata file path {0}", metadata.getFilePath()); //NON-NLS
|
||||||
if (ex instanceof ExecutionException) {
|
} catch (InterruptedException ex) {
|
||||||
throw new CaseActionException(Bundle.Case_deleteException_couldNotDeleteCase(ex.getCause().getMessage()), ex);
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getMessage()), ex);
|
||||||
} else {
|
} catch (ExecutionException ex) {
|
||||||
throw new CaseActionException(Bundle.Case_deleteException_couldNotDeleteCase(Bundle.Case_exceptionMessage_lockAcquisitionInterrupted()), ex);
|
throw new CaseActionException(Bundle.Case_exceptionMessage_wrapperMessage(ex.getCause().getMessage()), ex);
|
||||||
}
|
} catch (CancellationException ex) {
|
||||||
|
throw new CaseActionException(Bundle.Case_exceptionMessage_cancelled(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ import javax.swing.SwingUtilities;
|
|||||||
import org.openide.DialogDescriptor;
|
import org.openide.DialogDescriptor;
|
||||||
import org.openide.DialogDisplayer;
|
import org.openide.DialogDisplayer;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A progress indicator that displays progress using a modal dialog with a
|
* A progress indicator that displays progress using a modal dialog with a
|
||||||
@ -51,6 +50,18 @@ public final class ModalDialogProgressIndicator implements ProgressIndicator {
|
|||||||
dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
|
dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModalDialogProgressIndicator(String title, HelpCtx helpCtx) {
|
||||||
|
progressPanel = new ProgressPanel();
|
||||||
|
DialogDescriptor dialogDescriptor = new DialogDescriptor(
|
||||||
|
progressPanel,
|
||||||
|
title,
|
||||||
|
true,
|
||||||
|
DialogDescriptor.NO_OPTION,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
dialog = DialogDisplayer.getDefault().createDialog(dialogDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
public void setVisible(boolean isVisible) {
|
public void setVisible(boolean isVisible) {
|
||||||
this.dialog.setVisible(isVisible);
|
this.dialog.setVisible(isVisible);
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,10 @@ import org.sleuthkit.autopsy.framework.ProgressIndicator;
|
|||||||
/**
|
/**
|
||||||
* An implementation of the Autopsy service interface used for test purposes.
|
* An implementation of the Autopsy service interface used for test purposes.
|
||||||
*/
|
*/
|
||||||
//@ServiceProvider(service = AutopsyService.class)
|
@ServiceProvider(service = AutopsyService.class)
|
||||||
public class TestAutopsyService implements AutopsyService {
|
public class TestAutopsyService implements AutopsyService {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(TestAutopsyService.class.getName());
|
private static final Logger logger = Logger.getLogger(TestAutopsyService.class.getName());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getServiceName() {
|
public String getServiceName() {
|
||||||
@ -41,41 +41,31 @@ public class TestAutopsyService implements AutopsyService {
|
|||||||
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
|
public void openCaseResources(CaseContext context) throws AutopsyServiceException {
|
||||||
ProgressIndicator progressIndicator = context.getProgressIndicator();
|
ProgressIndicator progressIndicator = context.getProgressIndicator();
|
||||||
try {
|
try {
|
||||||
progressIndicator.start("Doing first task...", 100);
|
logger.log(Level.INFO, "Test Autopsy Service started first task");
|
||||||
|
progressIndicator.start("Test Autopsy Service doing first task...", 100);
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
progressIndicator.progress(10);
|
progressIndicator.progress(20);
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
progressIndicator.progress(10);
|
progressIndicator.progress(40);
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
progressIndicator.progress(10);
|
progressIndicator.progress(60);
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
progressIndicator.progress(10);
|
progressIndicator.progress(80);
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
progressIndicator.progress(10);
|
progressIndicator.progress(100);
|
||||||
Thread.sleep(1000L);
|
progressIndicator.finish("First task completed by Test Autopsy Service.");
|
||||||
progressIndicator.progress(10);
|
logger.log(Level.INFO, "Test Autopsy Service completed first task");
|
||||||
Thread.sleep(1000L);
|
logger.log(Level.INFO, "Test Autopsy Service started second task");
|
||||||
progressIndicator.progress(10);
|
progressIndicator.start("Test Autopsy Service doing second task...");
|
||||||
Thread.sleep(1000L);
|
for (int i = 0; i < 10000; ++i) {
|
||||||
progressIndicator.progress(10);
|
|
||||||
Thread.sleep(1000L);
|
|
||||||
progressIndicator.progress(10);
|
|
||||||
Thread.sleep(1000L);
|
|
||||||
progressIndicator.progress(10);
|
|
||||||
progressIndicator.finish("First task completed.");
|
|
||||||
progressIndicator.start("Doing second task...");
|
|
||||||
Thread.sleep(10000L);
|
|
||||||
progressIndicator.finish("Second task completed.");
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
LOGGER.log(Level.INFO, "Autopsy Test Service caught interrupt while working");
|
|
||||||
if (context.cancelRequested()) {
|
if (context.cancelRequested()) {
|
||||||
progressIndicator.finish("Cancelling...");
|
logger.log(Level.INFO, "Autopsy Test Service cancelled while doing second task, cancel requested = {0}", context.cancelRequested());
|
||||||
try {
|
|
||||||
Thread.sleep(1000L);
|
|
||||||
} catch (InterruptedException ex1) {
|
|
||||||
LOGGER.log(Level.INFO, "Autopsy Test Service caught interrupt while working");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
progressIndicator.finish("Second task completed by Test Autopsy Service.");
|
||||||
|
logger.log(Level.INFO, "Second task completed by Test Autopsy Service");
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
logger.log(Level.INFO, "Autopsy Test Service interrupted (cancelled) while doing first task, cancel requested = {0}", context.cancelRequested());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user