mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 11:07:43 +00:00
Merge remote-tracking branch 'upstream/collaborative' into caseImporter
Conflicts: Core/src/org/sleuthkit/autopsy/casemodule/CollaborationMonitor.java
This commit is contained in:
commit
54d822d1e0
@ -188,6 +188,7 @@
|
|||||||
<package>org.sleuthkit.autopsy.casemodule.services</package>
|
<package>org.sleuthkit.autopsy.casemodule.services</package>
|
||||||
<package>org.sleuthkit.autopsy.contentviewers</package>
|
<package>org.sleuthkit.autopsy.contentviewers</package>
|
||||||
<package>org.sleuthkit.autopsy.core</package>
|
<package>org.sleuthkit.autopsy.core</package>
|
||||||
|
<package>org.sleuthkit.autopsy.core.events</package>
|
||||||
<package>org.sleuthkit.autopsy.corecomponentinterfaces</package>
|
<package>org.sleuthkit.autopsy.corecomponentinterfaces</package>
|
||||||
<package>org.sleuthkit.autopsy.corecomponents</package>
|
<package>org.sleuthkit.autopsy.corecomponents</package>
|
||||||
<package>org.sleuthkit.autopsy.coreutils</package>
|
<package>org.sleuthkit.autopsy.coreutils</package>
|
||||||
|
@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.actions;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.Utilities;
|
import org.openide.util.Utilities;
|
||||||
@ -61,21 +62,26 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addTag(TagName tagName, String comment) {
|
protected void addTag(TagName tagName, String comment) {
|
||||||
Collection<? extends BlackboardArtifact> selectedArtifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
|
final Collection<? extends BlackboardArtifact> selectedArtifacts = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class);
|
||||||
for (BlackboardArtifact artifact : selectedArtifacts) {
|
|
||||||
try {
|
new Thread(() -> {
|
||||||
Case.getCurrentCase().getServices().getTagsManager().addBlackboardArtifactTag(artifact, tagName, comment);
|
for (BlackboardArtifact artifact : selectedArtifacts) {
|
||||||
|
try {
|
||||||
|
Case.getCurrentCase().getServices().getTagsManager().addBlackboardArtifactTag(artifact, tagName, comment);
|
||||||
|
}
|
||||||
|
catch (TskCoreException ex) {
|
||||||
|
Logger.getLogger(AddBlackboardArtifactTagAction.class.getName()).log(Level.SEVERE, "Error tagging result", ex); //NON-NLS
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddBlackboardArtifactTagAction.unableToTag.msg",
|
||||||
|
artifact.getDisplayName()),
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddBlackboardArtifactTagAction.taggingErr"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (TskCoreException ex) {
|
}).start();
|
||||||
Logger.getLogger(AddBlackboardArtifactTagAction.class.getName()).log(Level.SEVERE, "Error tagging result", ex); //NON-NLS
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"AddBlackboardArtifactTagAction.unableToTag.msg",
|
|
||||||
artifact.getDisplayName()),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"AddBlackboardArtifactTagAction.taggingErr"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.Utilities;
|
import org.openide.util.Utilities;
|
||||||
@ -64,81 +65,98 @@ public class AddContentTagAction extends AddTagAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addTag(TagName tagName, String comment) {
|
protected void addTag(TagName tagName, String comment) {
|
||||||
Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
final Collection<? extends AbstractFile> selectedFiles = Utilities.actionsGlobalContext().lookupAll(AbstractFile.class);
|
||||||
for (AbstractFile file : selectedFiles) {
|
|
||||||
try {
|
new Thread(() -> {
|
||||||
// Handle the special cases of current (".") and parent ("..") directory entries.
|
for (AbstractFile file : selectedFiles) {
|
||||||
if (file.getName().equals(".")) {
|
try {
|
||||||
Content parentFile = file.getParent();
|
// Handle the special cases of current (".") and parent ("..") directory entries.
|
||||||
if (parentFile instanceof AbstractFile) {
|
if (file.getName().equals(".")) {
|
||||||
file = (AbstractFile)parentFile;
|
Content parentFile = file.getParent();
|
||||||
}
|
|
||||||
else {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"AddContentTagAction.unableToTag.msg",
|
|
||||||
parentFile.getName()),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"AddContentTagAction.cannotApplyTagErr"),
|
|
||||||
JOptionPane.WARNING_MESSAGE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (file.getName().equals("..")) {
|
|
||||||
Content parentFile = file.getParent();
|
|
||||||
if (parentFile instanceof AbstractFile) {
|
|
||||||
parentFile = (AbstractFile)((AbstractFile)parentFile).getParent();
|
|
||||||
if (parentFile instanceof AbstractFile) {
|
if (parentFile instanceof AbstractFile) {
|
||||||
file = (AbstractFile)parentFile;
|
file = (AbstractFile)parentFile;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JOptionPane.showMessageDialog(null,
|
SwingUtilities.invokeLater(() -> {
|
||||||
NbBundle.getMessage(this.getClass(),
|
JOptionPane.showMessageDialog(null,
|
||||||
"AddContentTagAction.unableToTag.msg",
|
NbBundle.getMessage(this.getClass(),
|
||||||
parentFile.getName()),
|
"AddContentTagAction.unableToTag.msg",
|
||||||
NbBundle.getMessage(this.getClass(),
|
parentFile.getName()),
|
||||||
"AddContentTagAction.cannotApplyTagErr"),
|
NbBundle.getMessage(this.getClass(),
|
||||||
JOptionPane.WARNING_MESSAGE);
|
"AddContentTagAction.cannotApplyTagErr"),
|
||||||
|
JOptionPane.WARNING_MESSAGE);
|
||||||
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (file.getName().equals("..")) {
|
||||||
|
Content parentFile = file.getParent();
|
||||||
|
if (parentFile instanceof AbstractFile) {
|
||||||
|
parentFile = (AbstractFile)((AbstractFile)parentFile).getParent();
|
||||||
|
if (parentFile instanceof AbstractFile) {
|
||||||
|
file = (AbstractFile)parentFile;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final Content parentFileCopy = parentFile;
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddContentTagAction.unableToTag.msg",
|
||||||
|
parentFileCopy.getName()),
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddContentTagAction.cannotApplyTagErr"),
|
||||||
|
JOptionPane.WARNING_MESSAGE);
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final Content parentFileCopy = parentFile;
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddContentTagAction.unableToTag.msg",
|
||||||
|
parentFileCopy.getName()),
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddContentTagAction.cannotApplyTagErr"),
|
||||||
|
JOptionPane.WARNING_MESSAGE);
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if the same tag is being added for the same abstract file.
|
||||||
|
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
|
||||||
|
List<ContentTag> contentTagList = tagsManager.getContentTagsByContent(file);
|
||||||
|
for (ContentTag contentTag : contentTagList) {
|
||||||
|
if (contentTag.getName().getDisplayName().equals(tagName.getDisplayName())) {
|
||||||
|
AbstractFile fileCopy = file;
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddContentTagAction.tagExists",
|
||||||
|
fileCopy.getName(), tagName.getDisplayName()),
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"AddContentTagAction.cannotApplyTagErr"),
|
||||||
|
JOptionPane.WARNING_MESSAGE);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tagsManager.addContentTag(file, tagName, comment);
|
||||||
|
}
|
||||||
|
catch (TskCoreException ex) {
|
||||||
|
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error tagging result", ex); //NON-NLS
|
||||||
|
AbstractFile fileCopy = file;
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
JOptionPane.showMessageDialog(null,
|
JOptionPane.showMessageDialog(null,
|
||||||
NbBundle.getMessage(this.getClass(),
|
NbBundle.getMessage(this.getClass(),
|
||||||
"AddContentTagAction.unableToTag.msg",
|
"AddContentTagAction.unableToTag.msg2",
|
||||||
parentFile.getName()),
|
fileCopy.getName()),
|
||||||
NbBundle.getMessage(this.getClass(),
|
NbBundle.getMessage(this.getClass(), "AddContentTagAction.taggingErr"),
|
||||||
"AddContentTagAction.cannotApplyTagErr"),
|
JOptionPane.ERROR_MESSAGE);
|
||||||
JOptionPane.WARNING_MESSAGE);
|
});
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// check if the same tag is being added for the same abstract file.
|
|
||||||
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
|
|
||||||
List<ContentTag> contentTagList = tagsManager.getContentTagsByContent(file);
|
|
||||||
for (ContentTag contentTag : contentTagList) {
|
|
||||||
if (contentTag.getName().getDisplayName().equals(tagName.getDisplayName())) {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"AddContentTagAction.tagExists",
|
|
||||||
file.getName(), tagName.getDisplayName()),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"AddContentTagAction.cannotApplyTagErr"),
|
|
||||||
JOptionPane.WARNING_MESSAGE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tagsManager.addContentTag(file, tagName, comment);
|
|
||||||
}
|
}
|
||||||
catch (TskCoreException ex) {
|
}).start();
|
||||||
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error tagging result", ex); //NON-NLS
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"AddContentTagAction.unableToTag.msg2",
|
|
||||||
file.getName()),
|
|
||||||
NbBundle.getMessage(this.getClass(), "AddContentTagAction.taggingErr"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,6 +23,7 @@ import java.util.Collection;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
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.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
@ -55,22 +56,26 @@ public class DeleteBlackboardArtifactTagAction extends AbstractAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent event) {
|
public void actionPerformed(ActionEvent event) {
|
||||||
Collection<? extends BlackboardArtifactTag> selectedTags = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifactTag.class);
|
final Collection<? extends BlackboardArtifactTag> selectedTags = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifactTag.class);
|
||||||
for (BlackboardArtifactTag tag : selectedTags) {
|
new Thread(() -> {
|
||||||
try {
|
for (BlackboardArtifactTag tag : selectedTags) {
|
||||||
Case.getCurrentCase().getServices().getTagsManager().deleteBlackboardArtifactTag(tag);
|
try {
|
||||||
|
Case.getCurrentCase().getServices().getTagsManager().deleteBlackboardArtifactTag(tag);
|
||||||
|
}
|
||||||
|
catch (TskCoreException ex) {
|
||||||
|
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error deleting tag", ex); //NON-NLS
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"DeleteBlackboardArtifactTagAction.unableToDelTag.msg",
|
||||||
|
tag.getName()),
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"DeleteBlackboardArtifactTagAction.tagDelErr"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (TskCoreException ex) {
|
}).start();
|
||||||
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error deleting tag", ex); //NON-NLS
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"DeleteBlackboardArtifactTagAction.unableToDelTag.msg",
|
|
||||||
tag.getName()),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"DeleteBlackboardArtifactTagAction.tagDelErr"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import java.util.Collection;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
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.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
@ -55,20 +56,24 @@ public class DeleteContentTagAction extends AbstractAction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
Collection<? extends ContentTag> selectedTags = Utilities.actionsGlobalContext().lookupAll(ContentTag.class);
|
final Collection<? extends ContentTag> selectedTags = Utilities.actionsGlobalContext().lookupAll(ContentTag.class);
|
||||||
for (ContentTag tag : selectedTags) {
|
new Thread(() -> {
|
||||||
try {
|
for (ContentTag tag : selectedTags) {
|
||||||
Case.getCurrentCase().getServices().getTagsManager().deleteContentTag(tag);
|
try {
|
||||||
|
Case.getCurrentCase().getServices().getTagsManager().deleteContentTag(tag);
|
||||||
|
}
|
||||||
|
catch (TskCoreException ex) {
|
||||||
|
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error deleting tag", ex); //NON-NLS
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"DeleteContentTagAction.unableToDelTag.msg",
|
||||||
|
tag.getName()),
|
||||||
|
NbBundle.getMessage(this.getClass(), "DeleteContentTagAction.tagDelErr"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (TskCoreException ex) {
|
}).start();
|
||||||
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error deleting tag", ex); //NON-NLS
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"DeleteContentTagAction.unableToDelTag.msg",
|
|
||||||
tag.getName()),
|
|
||||||
NbBundle.getMessage(this.getClass(), "DeleteContentTagAction.tagDelErr"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,9 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
// get the selected DSProcessor
|
// get the selected DSProcessor
|
||||||
dsProcessor = dataSourcePanel.getComponent().getCurrentDSProcessor();
|
dsProcessor = dataSourcePanel.getComponent().getCurrentDSProcessor();
|
||||||
|
|
||||||
Case.getCurrentCase().notifyAddingNewDataSource(dataSourceId);
|
new Thread(() -> {
|
||||||
|
Case.getCurrentCase().notifyAddingNewDataSource(dataSourceId);
|
||||||
|
}).start();
|
||||||
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback () {
|
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback () {
|
||||||
@Override
|
@Override
|
||||||
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
|
||||||
@ -258,8 +260,10 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
* Cancels the data source processing - in case the users presses 'Cancel'
|
* Cancels the data source processing - in case the users presses 'Cancel'
|
||||||
*/
|
*/
|
||||||
private void cancelDataSourceProcessing(UUID dataSourceId) {
|
private void cancelDataSourceProcessing(UUID dataSourceId) {
|
||||||
Case.getCurrentCase().notifyFailedAddingNewDataSource(dataSourceId);
|
new Thread(() -> {
|
||||||
dsProcessor.cancel();
|
Case.getCurrentCase().notifyFailedAddingNewDataSource(dataSourceId);
|
||||||
|
}).start();
|
||||||
|
dsProcessor.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -307,11 +311,13 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
|||||||
newContents.addAll(contents);
|
newContents.addAll(contents);
|
||||||
|
|
||||||
//notify the UI of the new content added to the case
|
//notify the UI of the new content added to the case
|
||||||
if (!newContents.isEmpty()) {
|
new Thread(() -> {
|
||||||
Case.getCurrentCase().notifyNewDataSource(newContents.get(0), dataSourceId);
|
if (!newContents.isEmpty()) {
|
||||||
} else {
|
Case.getCurrentCase().notifyNewDataSource(newContents.get(0), dataSourceId);
|
||||||
Case.getCurrentCase().notifyFailedAddingNewDataSource(dataSourceId);
|
} else {
|
||||||
}
|
Case.getCurrentCase().notifyFailedAddingNewDataSource(dataSourceId);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
|
||||||
// Start ingest if we can
|
// Start ingest if we can
|
||||||
|
@ -242,14 +242,6 @@ LocalFilesPanel.errorLabel.text=Error Label
|
|||||||
NewCaseVisualPanel1.errorLabel.text=Error Label
|
NewCaseVisualPanel1.errorLabel.text=Error Label
|
||||||
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
|
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
|
||||||
CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
|
CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
|
||||||
CollaborationMonitor.failedService.notify.title=Collaboration Service Failed
|
|
||||||
CollaborationMonitor.failedDbService.notify.msg=Lost connection to database server
|
|
||||||
CollaborationMonitor.failedSolrService.notify.msg=Lost connection to keyword search server
|
|
||||||
CollaborationMonitor.failedMessageService.notify.msg=Lost connection to messaging server
|
|
||||||
CollaborationMonitor.restoredService.notify.title=Collaboration Service Restored
|
|
||||||
CollaborationMonitor.restoredDbService.notify.msg=Connection to database server restored
|
|
||||||
CollaborationMonitor.restoredSolrService.notify.msg=Connection to keyword search server restored
|
|
||||||
CollaborationMonitor.restoredMessageService.notify.msg=Connection to messaging server restored
|
|
||||||
MissingImageDialog.lbWarning.text=
|
MissingImageDialog.lbWarning.text=
|
||||||
MissingImageDialog.lbWarning.toolTipText=
|
MissingImageDialog.lbWarning.toolTipText=
|
||||||
CaseConverter.AlreadyMultiUser=Case is already multi-user!
|
CaseConverter.AlreadyMultiUser=Case is already multi-user!
|
||||||
|
@ -44,6 +44,7 @@ import java.util.logging.Level;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
import org.openide.util.actions.SystemAction;
|
import org.openide.util.actions.SystemAction;
|
||||||
@ -329,7 +330,9 @@ public class Case {
|
|||||||
currentCase = newCase;
|
currentCase = newCase;
|
||||||
Logger.setLogDirectory(currentCase.getLogDirectoryPath());
|
Logger.setLogDirectory(currentCase.getLogDirectoryPath());
|
||||||
doCaseChange(currentCase);
|
doCaseChange(currentCase);
|
||||||
RecentCases.getInstance().addRecentCase(currentCase.name, currentCase.configFilePath); // update the recent cases
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
RecentCases.getInstance().addRecentCase(currentCase.name, currentCase.configFilePath); // update the recent cases
|
||||||
|
});
|
||||||
if (CaseType.MULTI_USER_CASE == newCase.getCaseType()) {
|
if (CaseType.MULTI_USER_CASE == newCase.getCaseType()) {
|
||||||
try {
|
try {
|
||||||
/**
|
/**
|
||||||
@ -524,20 +527,24 @@ public class Case {
|
|||||||
String dbPath = caseDir + File.separator + "autopsy.db"; //NON-NLS
|
String dbPath = caseDir + File.separator + "autopsy.db"; //NON-NLS
|
||||||
db = SleuthkitCase.openCase(dbPath);
|
db = SleuthkitCase.openCase(dbPath);
|
||||||
if (null != db.getBackupDatabasePath()) {
|
if (null != db.getBackupDatabasePath()) {
|
||||||
JOptionPane.showMessageDialog(null,
|
SwingUtilities.invokeLater(() -> {
|
||||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg",
|
JOptionPane.showMessageDialog(null,
|
||||||
db.getBackupDatabasePath()),
|
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg",
|
||||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
|
db.getBackupDatabasePath()),
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
|
||||||
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
db = SleuthkitCase.openCase(xmlcm.getDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), caseDir);
|
db = SleuthkitCase.openCase(xmlcm.getDatabaseName(), UserPreferences.getDatabaseConnectionInfo(), caseDir);
|
||||||
if (null != db.getBackupDatabasePath()) {
|
if (null != db.getBackupDatabasePath()) {
|
||||||
JOptionPane.showMessageDialog(null,
|
SwingUtilities.invokeLater(() -> {
|
||||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg",
|
JOptionPane.showMessageDialog(null,
|
||||||
db.getBackupDatabasePath()),
|
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.msg",
|
||||||
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
|
db.getBackupDatabasePath()),
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
NbBundle.getMessage(Case.class, "Case.open.msgDlg.updated.title"),
|
||||||
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,6 +654,8 @@ public class Case {
|
|||||||
* Notifies case event subscribers (property change listeners) that a data
|
* Notifies case event subscribers (property change listeners) that a data
|
||||||
* source is being added to the case database.
|
* source is being added to the case database.
|
||||||
*
|
*
|
||||||
|
* This should not be called from the event dispatch thread (EDT)
|
||||||
|
*
|
||||||
* @param dataSourceId A unique identifier for the data source. This UUID
|
* @param dataSourceId A unique identifier for the data source. This UUID
|
||||||
* should be used to call notifyNewDataSource() after the
|
* should be used to call notifyNewDataSource() after the
|
||||||
* data source is added.
|
* data source is added.
|
||||||
@ -659,6 +668,8 @@ public class Case {
|
|||||||
* Notifies case event subscribers (property change listeners) that a data
|
* Notifies case event subscribers (property change listeners) that a data
|
||||||
* source failed to be added to the case database.
|
* source failed to be added to the case database.
|
||||||
*
|
*
|
||||||
|
* This should not be called from the event dispatch thread (EDT)
|
||||||
|
*
|
||||||
* @param dataSourceId A unique identifier for the data source.
|
* @param dataSourceId A unique identifier for the data source.
|
||||||
*/
|
*/
|
||||||
public void notifyFailedAddingNewDataSource(UUID dataSourceId) {
|
public void notifyFailedAddingNewDataSource(UUID dataSourceId) {
|
||||||
@ -669,6 +680,8 @@ public class Case {
|
|||||||
* Notifies case event subscribers (property change listeners) that a data
|
* Notifies case event subscribers (property change listeners) that a data
|
||||||
* source is being added to the case database.
|
* source is being added to the case database.
|
||||||
*
|
*
|
||||||
|
* This should not be called from the event dispatch thread (EDT)
|
||||||
|
*
|
||||||
* @param newDataSource New data source added.
|
* @param newDataSource New data source added.
|
||||||
* @param dataSourceId A unique identifier for the data source. Should be
|
* @param dataSourceId A unique identifier for the data source. Should be
|
||||||
* the same UUID used to call notifyAddingNewDataSource() when the process
|
* the same UUID used to call notifyAddingNewDataSource() when the process
|
||||||
@ -681,6 +694,8 @@ public class Case {
|
|||||||
/**
|
/**
|
||||||
* Notifies the UI that a new ContentTag has been added.
|
* Notifies the UI that a new ContentTag has been added.
|
||||||
*
|
*
|
||||||
|
* This should not be called from the event dispatch thread (EDT)
|
||||||
|
*
|
||||||
* @param newTag new ContentTag added
|
* @param newTag new ContentTag added
|
||||||
*/
|
*/
|
||||||
public void notifyContentTagAdded(ContentTag newTag) {
|
public void notifyContentTagAdded(ContentTag newTag) {
|
||||||
@ -690,6 +705,8 @@ public class Case {
|
|||||||
/**
|
/**
|
||||||
* Notifies the UI that a ContentTag has been deleted.
|
* Notifies the UI that a ContentTag has been deleted.
|
||||||
*
|
*
|
||||||
|
* This should not be called from the event dispatch thread (EDT)
|
||||||
|
*
|
||||||
* @param deletedTag ContentTag deleted
|
* @param deletedTag ContentTag deleted
|
||||||
*/
|
*/
|
||||||
public void notifyContentTagDeleted(ContentTag deletedTag) {
|
public void notifyContentTagDeleted(ContentTag deletedTag) {
|
||||||
@ -699,6 +716,8 @@ public class Case {
|
|||||||
/**
|
/**
|
||||||
* Notifies the UI that a new BlackboardArtifactTag has been added.
|
* Notifies the UI that a new BlackboardArtifactTag has been added.
|
||||||
*
|
*
|
||||||
|
* This should not be called from the event dispatch thread (EDT)
|
||||||
|
*
|
||||||
* @param newTag new BlackboardArtifactTag added
|
* @param newTag new BlackboardArtifactTag added
|
||||||
*/
|
*/
|
||||||
public void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag) {
|
public void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag) {
|
||||||
@ -706,7 +725,9 @@ public class Case {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the UI that a BlackboardArtifactTag has been.
|
* Notifies the UI that a BlackboardArtifactTag has been deleted.
|
||||||
|
*
|
||||||
|
* This should not be called from the event dispatch thread (EDT)
|
||||||
*
|
*
|
||||||
* @param deletedTag BlackboardArtifactTag deleted
|
* @param deletedTag BlackboardArtifactTag deleted
|
||||||
*/
|
*/
|
||||||
@ -776,6 +797,8 @@ public class Case {
|
|||||||
/**
|
/**
|
||||||
* Updates the case name.
|
* Updates the case name.
|
||||||
*
|
*
|
||||||
|
* This should not be called from the EDT.
|
||||||
|
*
|
||||||
* @param oldCaseName the old case name that wants to be updated
|
* @param oldCaseName the old case name that wants to be updated
|
||||||
* @param oldPath the old path that wants to be updated
|
* @param oldPath the old path that wants to be updated
|
||||||
* @param newCaseName the new case name
|
* @param newCaseName the new case name
|
||||||
@ -785,9 +808,15 @@ public class Case {
|
|||||||
try {
|
try {
|
||||||
xmlcm.setCaseName(newCaseName); // set the case
|
xmlcm.setCaseName(newCaseName); // set the case
|
||||||
name = newCaseName; // change the local value
|
name = newCaseName; // change the local value
|
||||||
RecentCases.getInstance().updateRecentCase(oldCaseName, oldPath, newCaseName, newPath); // update the recent case
|
|
||||||
eventPublisher.publish(new AutopsyEvent(Events.NAME.toString(), oldCaseName, newCaseName));
|
eventPublisher.publish(new AutopsyEvent(Events.NAME.toString(), oldCaseName, newCaseName));
|
||||||
updateMainWindowTitle(newCaseName);
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try{
|
||||||
|
RecentCases.getInstance().updateRecentCase(oldCaseName, oldPath, newCaseName, newPath); // update the recent case
|
||||||
|
updateMainWindowTitle(newCaseName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", e); //NON-NLS
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseName.exception.msg"), e);
|
throw new CaseActionException(NbBundle.getMessage(this.getClass(), "Case.updateCaseName.exception.msg"), e);
|
||||||
}
|
}
|
||||||
@ -796,6 +825,8 @@ public class Case {
|
|||||||
/**
|
/**
|
||||||
* Updates the case examiner
|
* Updates the case examiner
|
||||||
*
|
*
|
||||||
|
* This should not be called from the EDT.
|
||||||
|
*
|
||||||
* @param oldExaminer the old examiner
|
* @param oldExaminer the old examiner
|
||||||
* @param newExaminer the new examiner
|
* @param newExaminer the new examiner
|
||||||
*/
|
*/
|
||||||
@ -812,6 +843,8 @@ public class Case {
|
|||||||
/**
|
/**
|
||||||
* Updates the case number
|
* Updates the case number
|
||||||
*
|
*
|
||||||
|
* This should not be called from the EDT.
|
||||||
|
*
|
||||||
* @param oldCaseNumber the old case number
|
* @param oldCaseNumber the old case number
|
||||||
* @param newCaseNumber the new case number
|
* @param newCaseNumber the new case number
|
||||||
*/
|
*/
|
||||||
@ -1468,44 +1501,61 @@ public class Case {
|
|||||||
|
|
||||||
if (IngestManager.getInstance().isRunningInteractively()) {
|
if (IngestManager.getInstance().isRunningInteractively()) {
|
||||||
// enable these menus
|
// enable these menus
|
||||||
CallableSystemAction.get(AddImageAction.class).setEnabled(true);
|
SwingUtilities.invokeLater(() -> {
|
||||||
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
|
CallableSystemAction.get(AddImageAction.class).setEnabled(true);
|
||||||
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
|
CallableSystemAction.get(CaseCloseAction.class).setEnabled(true);
|
||||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
|
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(true);
|
||||||
|
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(true); // Delete Case menu
|
||||||
|
});
|
||||||
|
|
||||||
if (toChangeTo.hasData()) {
|
if (toChangeTo.hasData()) {
|
||||||
// open all top components
|
// open all top components
|
||||||
CoreComponentControl.openCoreWindows();
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
CoreComponentControl.openCoreWindows();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// close all top components
|
// close all top components
|
||||||
CoreComponentControl.closeCoreWindows();
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
CoreComponentControl.closeCoreWindows();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IngestManager.getInstance().isRunningInteractively()) {
|
if (IngestManager.getInstance().isRunningInteractively()) {
|
||||||
updateMainWindowTitle(currentCase.name);
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
updateMainWindowTitle(currentCase.name);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Frame f = WindowManager.getDefault().getMainWindow();
|
SwingUtilities.invokeLater(() -> {
|
||||||
f.setTitle(Case.getAppName()); // set the window name to just application name
|
Frame f = WindowManager.getDefault().getMainWindow();
|
||||||
|
f.setTitle(Case.getAppName()); // set the window name to just application name
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // case is closed
|
} else { // case is closed
|
||||||
if (IngestManager.getInstance().isRunningInteractively()) {
|
if (IngestManager.getInstance().isRunningInteractively()) {
|
||||||
// close all top components first
|
|
||||||
CoreComponentControl.closeCoreWindows();
|
|
||||||
|
|
||||||
// disable these menus
|
SwingUtilities.invokeLater(() -> {
|
||||||
CallableSystemAction.get(AddImageAction.class).setEnabled(false); // Add Image menu
|
// close all top components first
|
||||||
CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); // Case Close menu
|
CoreComponentControl.closeCoreWindows();
|
||||||
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); // Case Properties menu
|
|
||||||
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); // Delete Case menu
|
// disable these menus
|
||||||
|
CallableSystemAction.get(AddImageAction.class).setEnabled(false); // Add Image menu
|
||||||
|
CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); // Case Close menu
|
||||||
|
CallableSystemAction.get(CasePropertiesAction.class).setEnabled(false); // Case Properties menu
|
||||||
|
CallableSystemAction.get(CaseDeleteAction.class).setEnabled(false); // Delete Case menu
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear pending notifications
|
//clear pending notifications
|
||||||
MessageNotifyUtil.Notify.clear();
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
MessageNotifyUtil.Notify.clear();
|
||||||
|
});
|
||||||
|
|
||||||
Frame f = WindowManager.getDefault().getMainWindow();
|
SwingUtilities.invokeLater(() -> {
|
||||||
f.setTitle(Case.getAppName()); // set the window name to just application name
|
Frame f = WindowManager.getDefault().getMainWindow();
|
||||||
|
f.setTitle(Case.getAppName()); // set the window name to just application name
|
||||||
|
});
|
||||||
|
|
||||||
//try to force gc to happen
|
//try to force gc to happen
|
||||||
System.gc();
|
System.gc();
|
||||||
|
@ -27,6 +27,7 @@ import java.util.logging.Level;import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
import org.openide.util.HelpCtx;
|
import org.openide.util.HelpCtx;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.actions.CallableSystemAction;
|
import org.openide.util.actions.CallableSystemAction;
|
||||||
@ -70,19 +71,24 @@ import org.openide.util.actions.Presenter;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Case result = Case.getCurrentCase();
|
new SwingWorker<Void, Void>() {
|
||||||
try {
|
|
||||||
result.closeCase();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.getLogger(CaseCloseAction.class.getName()).log(Level.SEVERE, "Error closing case.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
|
|
||||||
EventQueue.invokeLater(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
protected Void doInBackground() throws Exception {
|
||||||
|
try{
|
||||||
|
Case result = Case.getCurrentCase();
|
||||||
|
result.closeCase();
|
||||||
|
} catch (CaseActionException | IllegalStateException ex){
|
||||||
|
Logger.getLogger(CaseCloseAction.class.getName()).log(Level.SEVERE, "Error closing case.", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
StartupWindowProvider.getInstance().open();
|
StartupWindowProvider.getInstance().open();
|
||||||
}
|
}
|
||||||
});
|
}.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,9 +23,12 @@ import java.awt.Window;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
import javax.swing.filechooser.FileFilter;
|
import javax.swing.filechooser.FileFilter;
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
@ -76,7 +79,7 @@ public final class CaseOpenAction implements ActionListener {
|
|||||||
int retval = fc.showOpenDialog(WindowManager.getDefault().getMainWindow());
|
int retval = fc.showOpenDialog(WindowManager.getDefault().getMainWindow());
|
||||||
|
|
||||||
if (retval == JFileChooser.APPROVE_OPTION) {
|
if (retval == JFileChooser.APPROVE_OPTION) {
|
||||||
String path = fc.getSelectedFile().getPath();
|
final String path = fc.getSelectedFile().getPath();
|
||||||
String dirPath = fc.getSelectedFile().getParent();
|
String dirPath = fc.getSelectedFile().getParent();
|
||||||
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, dirPath.substring(0, dirPath.lastIndexOf(File.separator)));
|
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, PROP_BASECASE, dirPath.substring(0, dirPath.lastIndexOf(File.separator)));
|
||||||
// check if the file exists
|
// check if the file exists
|
||||||
@ -96,20 +99,27 @@ public final class CaseOpenAction implements ActionListener {
|
|||||||
// no need to show the error message to the user.
|
// no need to show the error message to the user.
|
||||||
logger.log(Level.WARNING, "Error closing startup window.", ex); //NON-NLS
|
logger.log(Level.WARNING, "Error closing startup window.", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
Case.open(path); // open the case
|
|
||||||
} catch (CaseActionException ex) {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"CaseOpenAction.msgDlg.cantOpenCase.msg", path,
|
|
||||||
ex.getMessage()),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"CaseOpenAction.msgDlg.cantOpenCase.title"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
logger.log(Level.WARNING, "Error opening case in folder " + path, ex); //NON-NLS
|
|
||||||
|
|
||||||
StartupWindowProvider.getInstance().open();
|
new Thread(() -> {
|
||||||
}
|
// Create case.
|
||||||
|
try{
|
||||||
|
Case.open(path);
|
||||||
|
} catch (CaseActionException ex) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"CaseOpenAction.msgDlg.cantOpenCase.msg", path,
|
||||||
|
ex.getMessage()),
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"CaseOpenAction.msgDlg.cantOpenCase.title"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
|
||||||
|
|
||||||
|
StartupWindowProvider.getInstance().open();
|
||||||
|
});
|
||||||
|
logger.log(Level.WARNING, "Error opening case in folder " + path, ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -36,46 +34,36 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.jms.Connection;
|
|
||||||
import javax.jms.JMSException;
|
|
||||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
|
||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||||
import org.sleuthkit.autopsy.events.MessageServiceConnectionInfo;
|
|
||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent;
|
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent;
|
||||||
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisStartedEvent;
|
import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisStartedEvent;
|
||||||
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
|
||||||
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collaboration monitor listens to local events and translates them into
|
* A collaboration monitor listens to local events and translates them into
|
||||||
* collaboration tasks that are broadcast to collaborating nodes, informs the
|
* collaboration tasks that are broadcast to collaborating nodes and informs the
|
||||||
* user of collaboration tasks on other nodes using progress bars, and monitors
|
* user of collaboration tasks on other nodes using progress bars.
|
||||||
* the health of key collaboration services.
|
|
||||||
*/
|
*/
|
||||||
final class CollaborationMonitor {
|
final class CollaborationMonitor {
|
||||||
|
|
||||||
private static final String EVENT_CHANNEL_NAME = "%s-Collaboration-Monitor-Events";
|
private static final String EVENT_CHANNEL_NAME = "%s-Collaboration-Monitor-Events";
|
||||||
private static final String COLLABORATION_MONITOR_EVENT = "COLLABORATION_MONITOR_EVENT";
|
private static final String COLLABORATION_MONITOR_EVENT = "COLLABORATION_MONITOR_EVENT";
|
||||||
private static final Set<String> CASE_EVENTS_OF_INTEREST = new HashSet<>(Arrays.asList(new String[]{Case.Events.ADDING_DATA_SOURCE.toString(), Case.Events.DATA_SOURCE_ADDED.toString(), Case.Events.ADDING_DATA_SOURCE_FAILED.toString()}));
|
private static final Set<String> CASE_EVENTS_OF_INTEREST = new HashSet<>(Arrays.asList(new String[]{Case.Events.ADDING_DATA_SOURCE.toString(), Case.Events.DATA_SOURCE_ADDED.toString(), Case.Events.ADDING_DATA_SOURCE_FAILED.toString()}));
|
||||||
private static final int NUMBER_OF_PERIODIC_TASK_THREADS = 3;
|
private static final int NUMBER_OF_PERIODIC_TASK_THREADS = 2;
|
||||||
private static final String PERIODIC_TASK_THREAD_NAME = "collab-monitor-periodic-tasks-%d";
|
private static final String PERIODIC_TASK_THREAD_NAME = "collab-monitor-periodic-tasks-%d";
|
||||||
private static final long HEARTBEAT_INTERVAL_MINUTES = 1;
|
private static final long HEARTBEAT_INTERVAL_MINUTES = 1;
|
||||||
private static final long MAX_MISSED_HEARTBEATS = 5;
|
private static final long MAX_MISSED_HEARTBEATS = 5;
|
||||||
private static final long STALE_TASKS_DETECTION_INTERVAL_MINUTES = 2;
|
private static final long STALE_TASKS_DETECTION_INTERVAL_MINUTES = 2;
|
||||||
private static final long CRASH_DETECTION_INTERVAL_MINUTES = 2;
|
|
||||||
private static final long EXECUTOR_TERMINATION_WAIT_SECS = 30;
|
private static final long EXECUTOR_TERMINATION_WAIT_SECS = 30;
|
||||||
private static final Logger logger = Logger.getLogger(CollaborationMonitor.class.getName());
|
private static final Logger logger = Logger.getLogger(CollaborationMonitor.class.getName());
|
||||||
private final String hostName;
|
private final String hostName;
|
||||||
@ -130,12 +118,10 @@ final class CollaborationMonitor {
|
|||||||
*
|
*
|
||||||
* 1. Send heartbeats to collaboration monitors on other nodes.<br>
|
* 1. Send heartbeats to collaboration monitors on other nodes.<br>
|
||||||
* 2. Check for stale remote tasks.<br>
|
* 2. Check for stale remote tasks.<br>
|
||||||
* 3. Check the availability of key collaboration services.<br>
|
|
||||||
*/
|
*/
|
||||||
periodicTasksExecutor = new ScheduledThreadPoolExecutor(NUMBER_OF_PERIODIC_TASK_THREADS, new ThreadFactoryBuilder().setNameFormat(PERIODIC_TASK_THREAD_NAME).build());
|
periodicTasksExecutor = new ScheduledThreadPoolExecutor(NUMBER_OF_PERIODIC_TASK_THREADS, new ThreadFactoryBuilder().setNameFormat(PERIODIC_TASK_THREAD_NAME).build());
|
||||||
periodicTasksExecutor.scheduleAtFixedRate(new HeartbeatTask(), HEARTBEAT_INTERVAL_MINUTES, HEARTBEAT_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
periodicTasksExecutor.scheduleAtFixedRate(new HeartbeatTask(), HEARTBEAT_INTERVAL_MINUTES, HEARTBEAT_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
||||||
periodicTasksExecutor.scheduleAtFixedRate(new StaleTaskDetectionTask(), STALE_TASKS_DETECTION_INTERVAL_MINUTES, STALE_TASKS_DETECTION_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
periodicTasksExecutor.scheduleAtFixedRate(new StaleTaskDetectionTask(), STALE_TASKS_DETECTION_INTERVAL_MINUTES, STALE_TASKS_DETECTION_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
||||||
periodicTasksExecutor.scheduleAtFixedRate(new CrashDetectionTask(), CRASH_DETECTION_INTERVAL_MINUTES, CRASH_DETECTION_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -497,80 +483,6 @@ final class CollaborationMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A Runnable task that periodically checks the availability of
|
|
||||||
* collaboration resources (PostgreSQL server, Solr server, Active MQ
|
|
||||||
* message broker) and reports status to the user in case of a gap in
|
|
||||||
* service.
|
|
||||||
*/
|
|
||||||
private final static class CrashDetectionTask implements Runnable {
|
|
||||||
|
|
||||||
private static boolean dbServerIsRunning = true;
|
|
||||||
private static boolean solrServerIsRunning = true;
|
|
||||||
private static boolean messageServerIsRunning = true;
|
|
||||||
private static final Object lock = new Object();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Monitor the availability of collaboration resources
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
synchronized (lock) {
|
|
||||||
CaseDbConnectionInfo dbInfo = UserPreferences.getDatabaseConnectionInfo();
|
|
||||||
if (dbInfo.canConnect()) {
|
|
||||||
if (!dbServerIsRunning) {
|
|
||||||
dbServerIsRunning = true;
|
|
||||||
logger.log(Level.INFO, "Connection to PostgreSQL server restored"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.info(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.restoredService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.restoredDbService.notify.msg"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (dbServerIsRunning) {
|
|
||||||
dbServerIsRunning = false;
|
|
||||||
logger.log(Level.SEVERE, "Failed to connect to PostgreSQL server"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedDbService.notify.msg"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KeywordSearchService kwsService = Case.getCurrentCase().getServices().getKeywordSearchService();
|
|
||||||
|
|
||||||
if (kwsService.canConnectToRemoteSolrServer()) {
|
|
||||||
if (!solrServerIsRunning) {
|
|
||||||
solrServerIsRunning = true;
|
|
||||||
logger.log(Level.INFO, "Connection to Solr server restored"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.info(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.restoredService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.restoredSolrService.notify.msg"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (solrServerIsRunning) {
|
|
||||||
solrServerIsRunning = false;
|
|
||||||
logger.log(Level.SEVERE, "Failed to connect to Solr server"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedSolrService.notify.msg"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageServiceConnectionInfo msgInfo = UserPreferences.getMessageServiceConnectionInfo();
|
|
||||||
try {
|
|
||||||
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(msgInfo.getUserName(), msgInfo.getPassword(), msgInfo.getURI());
|
|
||||||
Connection connection = connectionFactory.createConnection();
|
|
||||||
connection.start();
|
|
||||||
connection.close();
|
|
||||||
if (!messageServerIsRunning) {
|
|
||||||
messageServerIsRunning = true;
|
|
||||||
logger.log(Level.INFO, "Connection to ActiveMQ server restored"); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.info(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.restoredService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.restoredMessageService.notify.msg"));
|
|
||||||
}
|
|
||||||
} catch (URISyntaxException | JMSException ex) {
|
|
||||||
if (messageServerIsRunning) {
|
|
||||||
messageServerIsRunning = false;
|
|
||||||
logger.log(Level.SEVERE, "Failed to connect to ActiveMQ server", ex); //NON-NLS
|
|
||||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedMessageService.notify.msg"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Autopsy event to be sent in event messages to the collaboration
|
* An Autopsy event to be sent in event messages to the collaboration
|
||||||
* monitors on other Autopsy nodes.
|
* monitors on other Autopsy nodes.
|
||||||
|
@ -24,7 +24,10 @@ import java.awt.Dialog;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import org.openide.DialogDescriptor;
|
import org.openide.DialogDescriptor;
|
||||||
import org.openide.DialogDisplayer;
|
import org.openide.DialogDisplayer;
|
||||||
import org.openide.NotifyDescriptor;
|
import org.openide.NotifyDescriptor;
|
||||||
@ -81,7 +84,7 @@ import org.sleuthkit.datamodel.TskData.DbType;
|
|||||||
* The method to perform new case creation
|
* The method to perform new case creation
|
||||||
*/
|
*/
|
||||||
private void newCaseAction() {
|
private void newCaseAction() {
|
||||||
WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels());
|
final WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels());
|
||||||
// {0} will be replaced by WizardDesriptor.Panel.getComponent().getName()
|
// {0} will be replaced by WizardDesriptor.Panel.getComponent().getName()
|
||||||
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
|
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
|
||||||
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text"));
|
wizardDescriptor.setTitle(NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.newCase.windowTitle.text"));
|
||||||
@ -89,45 +92,72 @@ import org.sleuthkit.datamodel.TskData.DbType;
|
|||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
dialog.toFront();
|
dialog.toFront();
|
||||||
|
|
||||||
|
if(wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION){
|
||||||
|
new SwingWorker<Void, Void>() {
|
||||||
|
|
||||||
boolean finished = wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION; // check if it finishes (it's not cancelled)
|
@Override
|
||||||
boolean isCancelled = wizardDescriptor.getValue() == WizardDescriptor.CANCEL_OPTION; // check if the "Cancel" button is pressed
|
protected Void doInBackground() throws Exception {
|
||||||
|
// Create case.
|
||||||
|
|
||||||
// if the finish button is pressed (not cancelled)
|
String caseNumber = (String) wizardDescriptor.getProperty("caseNumber"); //NON-NLS
|
||||||
if (finished) {
|
String examiner = (String) wizardDescriptor.getProperty("caseExaminer"); //NON-NLS
|
||||||
// now start the 'Add Image' wizard
|
final String caseName = (String) wizardDescriptor.getProperty("caseName"); //NON-NLS
|
||||||
//TODO fix for local
|
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
|
||||||
CaseType currentCaseType = CaseType.fromString(ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, ModuleSettings.CURRENT_CASE_TYPE));
|
CaseType caseType = CaseType.values()[(int)wizardDescriptor.getProperty("caseType")]; //NON-NLS
|
||||||
CaseDbConnectionInfo info = UserPreferences.getDatabaseConnectionInfo();
|
|
||||||
if ((currentCaseType==CaseType.SINGLE_USER_CASE) || ((info.getDbType() != DbType.SQLITE) && info.canConnect())) {
|
Case.create(createdDirectory, caseName, caseNumber, examiner, caseType);
|
||||||
AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
|
return null;
|
||||||
addImageAction.actionPerformed(null);
|
}
|
||||||
} else {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
@Override
|
||||||
NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.databaseProblem1.text"),
|
protected void done() {
|
||||||
NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.databaseProblem2.text"),
|
try {
|
||||||
JOptionPane.ERROR_MESSAGE);
|
get();
|
||||||
isCancelled = true;
|
CaseType currentCaseType = CaseType.values()[(int)wizardDescriptor.getProperty("caseType")]; //NON-NLS
|
||||||
}
|
CaseDbConnectionInfo info = UserPreferences.getDatabaseConnectionInfo();
|
||||||
|
if ((currentCaseType==CaseType.SINGLE_USER_CASE) || ((info.getDbType() != DbType.SQLITE) && info.canConnect())) {
|
||||||
|
AddImageAction addImageAction = SystemAction.get(AddImageAction.class);
|
||||||
|
addImageAction.actionPerformed(null);
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.databaseProblem1.text"),
|
||||||
|
NbBundle.getMessage(this.getClass(), "NewCaseWizardAction.databaseProblem2.text"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
doFailedCaseCleanup(wizardDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
final String caseName = (String) wizardDescriptor.getProperty("caseName"); //NON-NLS
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(),
|
||||||
|
"CaseCreateAction.msgDlg.cantCreateCase.msg")+" "+caseName,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"CaseOpenAction.msgDlg.cantOpenCase.title"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
});
|
||||||
|
doFailedCaseCleanup(wizardDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
new Thread(() -> {
|
||||||
|
doFailedCaseCleanup(wizardDescriptor);
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if Cancel button is pressed
|
|
||||||
if (isCancelled) {
|
|
||||||
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
|
|
||||||
// if there's case opened, close the case
|
|
||||||
if (Case.existsCurrentCase()) {
|
|
||||||
// close the previous case if there's any
|
|
||||||
CaseCloseAction closeCase = SystemAction.get(CaseCloseAction.class);
|
|
||||||
closeCase.actionPerformed(null);
|
|
||||||
}
|
|
||||||
if (createdDirectory != null) {
|
|
||||||
logger.log(Level.INFO, "Deleting a created case directory due to isCancelled set, dir: " + createdDirectory); //NON-NLS
|
|
||||||
Case.deleteCaseDirectory(new File(createdDirectory));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panels = null; // reset the panel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doFailedCaseCleanup(WizardDescriptor wizardDescriptor){
|
||||||
|
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
|
||||||
|
|
||||||
|
if (createdDirectory != null) {
|
||||||
|
logger.log(Level.INFO, "Deleting a created case directory due to an error, dir: " + createdDirectory); //NON-NLS
|
||||||
|
Case.deleteCaseDirectory(new File(createdDirectory));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize panels representing individual wizard's steps and sets
|
* Initialize panels representing individual wizard's steps and sets
|
||||||
* various properties for them influencing wizard appearance.
|
* various properties for them influencing wizard appearance.
|
||||||
|
@ -171,33 +171,12 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void storeSettings(WizardDescriptor settings) {
|
public void storeSettings(WizardDescriptor settings) {
|
||||||
|
NewCaseVisualPanel2 currentComponent = getComponent();
|
||||||
|
settings.putProperty("caseNumber", currentComponent.getCaseNumber());
|
||||||
|
settings.putProperty("caseExaminer", currentComponent.getExaminer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate() throws WizardValidationException {
|
public void validate() throws WizardValidationException {
|
||||||
|
|
||||||
NewCaseVisualPanel2 currentComponent = getComponent();
|
|
||||||
final String caseNumber = currentComponent.getCaseNumber();
|
|
||||||
final String examiner = currentComponent.getExaminer();
|
|
||||||
try {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Case.create(createdDirectory, caseName, caseNumber, examiner, caseType);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
JOptionPane.showMessageDialog(null, NbBundle.getMessage(this.getClass(),
|
|
||||||
"CaseCreateAction.msgDlg.cantCreateCase.msg")+" "+caseName,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"CaseOpenAction.msgDlg.cantOpenCase.title"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new WizardValidationException(this.getComponent(),
|
|
||||||
NbBundle.getMessage(this.getClass(), "NewCaseWizardPanel2.validate.errCreateCase.msg"), null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,12 @@ import java.awt.EventQueue;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
@ -187,8 +190,8 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
logger.log(Level.INFO, "No Case paths exist, cannot open the case"); //NON-NLS
|
logger.log(Level.INFO, "No Case paths exist, cannot open the case"); //NON-NLS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String casePath = casePaths[imagesTable.getSelectedRow()];
|
final String casePath = casePaths[imagesTable.getSelectedRow()];
|
||||||
String caseName = caseNames[imagesTable.getSelectedRow()];
|
final String caseName = caseNames[imagesTable.getSelectedRow()];
|
||||||
if (!casePath.equals("")) {
|
if (!casePath.equals("")) {
|
||||||
// Close the startup menu
|
// Close the startup menu
|
||||||
try {
|
try {
|
||||||
@ -198,34 +201,39 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
|
|||||||
logger.log(Level.WARNING, "Error: couldn't open case: " + caseName, ex); //NON-NLS
|
logger.log(Level.WARNING, "Error: couldn't open case: " + caseName, ex); //NON-NLS
|
||||||
}
|
}
|
||||||
// Open the recent cases
|
// Open the recent cases
|
||||||
try {
|
if (caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())) {
|
||||||
if (caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())) {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"OpenRecentCasePanel.openCase.msgDlg.caseDoesntExist.msg",
|
|
||||||
caseName),
|
|
||||||
NbBundle.getMessage(this.getClass(),
|
|
||||||
"OpenRecentCasePanel.openCase.msgDlg.err"),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
|
|
||||||
|
|
||||||
//if case is not opened, open the start window
|
|
||||||
if (Case.isCaseOpen() == false) {
|
|
||||||
StartupWindowProvider.getInstance().open();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Case.open(casePath); // open the case
|
|
||||||
}
|
|
||||||
} catch (CaseActionException ex) {
|
|
||||||
JOptionPane.showMessageDialog(null,
|
JOptionPane.showMessageDialog(null,
|
||||||
NbBundle.getMessage(this.getClass(),
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"OpenRecentCasePanel.openCase.msgDlg.caseDoesntExist.msg",
|
||||||
|
caseName),
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
|
"OpenRecentCasePanel.openCase.msgDlg.err"),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
|
||||||
|
|
||||||
|
//if case is not opened, open the start window
|
||||||
|
if (Case.isCaseOpen() == false) {
|
||||||
|
StartupWindowProvider.getInstance().open();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
new Thread(() -> {
|
||||||
|
// Create case.
|
||||||
|
try{
|
||||||
|
Case.open(casePath);
|
||||||
|
} catch (CaseActionException ex) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(),
|
||||||
"CaseOpenAction.msgDlg.cantOpenCase.msg", caseName,
|
"CaseOpenAction.msgDlg.cantOpenCase.msg", caseName,
|
||||||
ex.getMessage()),
|
ex.getMessage()),
|
||||||
NbBundle.getMessage(this.getClass(),
|
NbBundle.getMessage(this.getClass(),
|
||||||
"CaseOpenAction.msgDlg.cantOpenCase.title"),
|
"CaseOpenAction.msgDlg.cantOpenCase.title"),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
logger.log(Level.WARNING, "Error: couldn't open case: " + caseName, ex); //NON-NLS
|
});
|
||||||
|
logger.log(Level.WARNING, "Error: couldn't open case: " + caseName, ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,12 @@ import java.awt.EventQueue;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
|
||||||
@ -35,8 +38,8 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
*/
|
*/
|
||||||
class RecentItems implements ActionListener {
|
class RecentItems implements ActionListener {
|
||||||
|
|
||||||
String caseName;
|
final String caseName;
|
||||||
String casePath;
|
final String casePath;
|
||||||
private JPanel caller; // for error handling
|
private JPanel caller; // for error handling
|
||||||
|
|
||||||
/** the constructor */
|
/** the constructor */
|
||||||
@ -76,15 +79,20 @@ class RecentItems implements ActionListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
new Thread(() -> {
|
||||||
Case.open(casePath); // open the case
|
// Create case.
|
||||||
} catch (CaseActionException ex) {
|
try{
|
||||||
JOptionPane.showMessageDialog(null,
|
Case.open(casePath);
|
||||||
|
} catch (CaseActionException ex) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.msg", casePath,
|
NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.msg", casePath,
|
||||||
ex.getMessage()), NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
|
ex.getMessage()), NbBundle.getMessage(this.getClass(), "CaseOpenAction.msgDlg.cantOpenCase.title"),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
Logger.getLogger(RecentItems.class.getName()).log(Level.WARNING, "Error: Couldn't open recent case at " + casePath, ex); //NON-NLS
|
});
|
||||||
}
|
Logger.getLogger(RecentItems.class.getName()).log(Level.WARNING, "Error: Couldn't open recent case at " + casePath, ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,3 +12,12 @@ org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xm
|
|||||||
Services/AutoupdateType/org_sleuthkit_autopsy_core_update_center.settings=Autopsy Update Center
|
Services/AutoupdateType/org_sleuthkit_autopsy_core_update_center.settings=Autopsy Update Center
|
||||||
Installer.errorInitJavafx.msg=Error initializing JavaFX.
|
Installer.errorInitJavafx.msg=Error initializing JavaFX.
|
||||||
Installer.errorInitJavafx.details=\ Some features will not be available. Check that you have the right JRE installed (Oracle JRE > 1.7.10).
|
Installer.errorInitJavafx.details=\ Some features will not be available. Check that you have the right JRE installed (Oracle JRE > 1.7.10).
|
||||||
|
ServicesMonitor.failedService.notify.title=Service Failed
|
||||||
|
ServicesMonitor.failedService.notify.msg=Lost connection to {0}
|
||||||
|
ServicesMonitor.restoredService.notify.title=Service Restored
|
||||||
|
ServicesMonitor.restoredService.notify.msg=Connection to {0} restored
|
||||||
|
ServicesMonitor.statusChange.notify.title=Service Status Update
|
||||||
|
ServicesMonitor.statusChange.notify.msg=Status for {0} is {1}
|
||||||
|
ServicesMonitor.nullServiceName.excepton.txt=Requested service name is null
|
||||||
|
ServicesMonitor.nullStatusOrDetails.excepton.txt=Status or details string is null
|
||||||
|
ServicesMonitor.unknownServiceName.excepton.txt=Requested service name {0} is unknown
|
383
Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java
Normal file
383
Core/src/org/sleuthkit/autopsy/core/ServicesMonitor.java
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 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.core;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.core.events.ServiceEvent;
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.openide.util.Lookup;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
|
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||||
|
import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class periodically checks availability of collaboration resources -
|
||||||
|
* remote database, remote keyword search server, messaging service - and
|
||||||
|
* reports status updates to the user in case of a gap in service.
|
||||||
|
*/
|
||||||
|
public class ServicesMonitor {
|
||||||
|
|
||||||
|
private AutopsyEventPublisher eventPublisher;
|
||||||
|
private static final Logger logger = Logger.getLogger(ServicesMonitor.class.getName());
|
||||||
|
private final ScheduledThreadPoolExecutor periodicTasksExecutor;
|
||||||
|
|
||||||
|
private static final String PERIODIC_TASK_THREAD_NAME = "services-monitor-periodic-task-%d";
|
||||||
|
private static final int NUMBER_OF_PERIODIC_TASK_THREADS = 1;
|
||||||
|
private static final long CRASH_DETECTION_INTERVAL_MINUTES = 2;
|
||||||
|
|
||||||
|
private static final Set<String> servicesList = Stream.of(ServicesMonitor.Service.values())
|
||||||
|
.map(Service::toString)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The service monitor maintains a mapping of each service to it's last
|
||||||
|
* status update.
|
||||||
|
*/
|
||||||
|
private final ConcurrentHashMap<String, String> statusByService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call constructor on start-up so that the first check of services is done
|
||||||
|
* as soon as possible.
|
||||||
|
*/
|
||||||
|
private static ServicesMonitor instance = new ServicesMonitor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of services that are being monitored. The service names should be
|
||||||
|
* representative of the service functionality and readable as they get
|
||||||
|
* logged when service outage occurs.
|
||||||
|
*/
|
||||||
|
public enum Service {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property change event fired when remote case database service status
|
||||||
|
* changes. New value is set to updated ServiceStatus, old value is
|
||||||
|
* null.
|
||||||
|
*/
|
||||||
|
REMOTE_CASE_DATABASE("Multi-user case database service"),
|
||||||
|
/**
|
||||||
|
* Property change event fired when remote keyword search service status
|
||||||
|
* changes. New value is set to updated ServiceStatus, old value is
|
||||||
|
* null.
|
||||||
|
*/
|
||||||
|
REMOTE_KEYWORD_SEARCH("Multi-user keyword search service"),
|
||||||
|
/**
|
||||||
|
* Property change event fired when messaging service status changes.
|
||||||
|
* New value is set to updated ServiceStatus, old value is null.
|
||||||
|
*/
|
||||||
|
MESSAGING("Messaging service");
|
||||||
|
|
||||||
|
private final String displayName;
|
||||||
|
|
||||||
|
private Service(String name) {
|
||||||
|
this.displayName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of possible service statuses.
|
||||||
|
*/
|
||||||
|
public enum ServiceStatus {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service is currently up.
|
||||||
|
*/
|
||||||
|
UP,
|
||||||
|
/**
|
||||||
|
* Service is currently down.
|
||||||
|
*/
|
||||||
|
DOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
public synchronized static ServicesMonitor getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new ServicesMonitor();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServicesMonitor() {
|
||||||
|
|
||||||
|
this.eventPublisher = new AutopsyEventPublisher();
|
||||||
|
this.statusByService = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// First check is triggered immediately on current thread.
|
||||||
|
checkAllServices();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start periodic task that check the availability of key collaboration
|
||||||
|
* services.
|
||||||
|
*/
|
||||||
|
periodicTasksExecutor = new ScheduledThreadPoolExecutor(NUMBER_OF_PERIODIC_TASK_THREADS, new ThreadFactoryBuilder().setNameFormat(PERIODIC_TASK_THREAD_NAME).build());
|
||||||
|
periodicTasksExecutor.scheduleAtFixedRate(new CrashDetectionTask(), CRASH_DETECTION_INTERVAL_MINUTES, CRASH_DETECTION_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates service status and publishes the service status update if it is
|
||||||
|
* different from previous status. Event is published locally. Logs status
|
||||||
|
* changes.
|
||||||
|
*
|
||||||
|
* @param service Name of the service.
|
||||||
|
* @param status Updated status for the service.
|
||||||
|
* @param details Details of the event.
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException
|
||||||
|
* Thrown if either of input parameters is null.
|
||||||
|
*/
|
||||||
|
public void setServiceStatus(String service, String status, String details) throws ServicesMonitorException {
|
||||||
|
|
||||||
|
if (service == null) {
|
||||||
|
logger.log(Level.SEVERE, "Call to setServiceStatus() with null service name"); //NON-NLS
|
||||||
|
throw new ServicesMonitorException(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.nullServiceName.excepton.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == null || details == null) {
|
||||||
|
logger.log(Level.SEVERE, "Call to setServiceStatus() with null status or details"); //NON-NLS
|
||||||
|
throw new ServicesMonitorException(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.nullStatusOrDetails.excepton.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the status update is for an existing service who's status hasn't changed - do nothing.
|
||||||
|
if (statusByService.containsKey(service) && status.equals(statusByService.get(service))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new service or status has changed - identify service's display name
|
||||||
|
String serviceDisplayName;
|
||||||
|
try {
|
||||||
|
serviceDisplayName = ServicesMonitor.Service.valueOf(service).getDisplayName();
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
// custom service that is not listed in ServicesMonitor.Service enum. Use service name as display name.
|
||||||
|
serviceDisplayName = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.equals(ServiceStatus.UP.toString())) {
|
||||||
|
logger.log(Level.INFO, "Connection to {0} restored", serviceDisplayName); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.title"),
|
||||||
|
NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.restoredService.notify.msg", serviceDisplayName));
|
||||||
|
} else if (status.equals(ServiceStatus.DOWN.toString())) {
|
||||||
|
logger.log(Level.SEVERE, "Failed to connect to {0}", serviceDisplayName); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.error(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.title"),
|
||||||
|
NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.failedService.notify.msg", serviceDisplayName));
|
||||||
|
} else {
|
||||||
|
logger.log(Level.INFO, "Status for {0} is {1}", new Object[]{serviceDisplayName, status}); //NON-NLS
|
||||||
|
MessageNotifyUtil.Notify.info(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.statusChange.notify.title"),
|
||||||
|
NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.statusChange.notify.msg", new Object[]{serviceDisplayName, status}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// update and publish new status
|
||||||
|
statusByService.put(service, status);
|
||||||
|
eventPublisher.publishLocally(new ServiceEvent(service, status, details));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get last status update for a service.
|
||||||
|
*
|
||||||
|
* @param service Name of the service.
|
||||||
|
* @return ServiceStatus Status for the service.
|
||||||
|
* @throws
|
||||||
|
* org.sleuthkit.autopsy.core.ServicesMonitor.ServicesMonitorException
|
||||||
|
* Thrown if service name is null or service doesn't exist.
|
||||||
|
*/
|
||||||
|
public String getServiceStatus(String service) throws ServicesMonitorException {
|
||||||
|
|
||||||
|
if (service == null) {
|
||||||
|
throw new ServicesMonitorException(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.nullServiceName.excepton.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
String status = statusByService.get(service);
|
||||||
|
if (status == null) {
|
||||||
|
// no such service
|
||||||
|
throw new ServicesMonitorException(NbBundle.getMessage(ServicesMonitor.class, "ServicesMonitor.unknownServiceName.excepton.txt", service));
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs service availability status check.
|
||||||
|
*
|
||||||
|
* @param service Name of the service.
|
||||||
|
*/
|
||||||
|
private void checkServiceStatus(String service) {
|
||||||
|
if (service.equals(Service.REMOTE_CASE_DATABASE.toString())) {
|
||||||
|
checkDatabaseConnectionStatus();
|
||||||
|
} else if (service.equals(Service.REMOTE_KEYWORD_SEARCH.toString())) {
|
||||||
|
checkKeywordSearchServerConnectionStatus();
|
||||||
|
} else if (service.equals(Service.MESSAGING.toString())) {
|
||||||
|
checkMessagingServerConnectionStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs case database service availability status check.
|
||||||
|
*/
|
||||||
|
private void checkDatabaseConnectionStatus() {
|
||||||
|
try {
|
||||||
|
if (UserPreferences.getDatabaseConnectionInfo().canConnect()) {
|
||||||
|
setServiceStatus(Service.REMOTE_CASE_DATABASE.toString(), ServiceStatus.UP.toString(), "");
|
||||||
|
} else {
|
||||||
|
setServiceStatus(Service.REMOTE_CASE_DATABASE.toString(), ServiceStatus.DOWN.toString(), "");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while checking database connection status", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs keyword search service availability status check.
|
||||||
|
*/
|
||||||
|
private void checkKeywordSearchServerConnectionStatus() {
|
||||||
|
try {
|
||||||
|
KeywordSearchService kwsService = Lookup.getDefault().lookup(KeywordSearchService.class);
|
||||||
|
if (kwsService != null && kwsService.canConnectToRemoteSolrServer()) {
|
||||||
|
setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.UP.toString(), "");
|
||||||
|
} else {
|
||||||
|
setServiceStatus(Service.REMOTE_KEYWORD_SEARCH.toString(), ServiceStatus.DOWN.toString(), "");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while checking keyword search server connection status", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs messaging service availability status check.
|
||||||
|
*/
|
||||||
|
private void checkMessagingServerConnectionStatus() {
|
||||||
|
try {
|
||||||
|
if (UserPreferences.getMessageServiceConnectionInfo().canConnect()) {
|
||||||
|
setServiceStatus(Service.MESSAGING.toString(), ServiceStatus.UP.toString(), "");
|
||||||
|
} else {
|
||||||
|
setServiceStatus(Service.MESSAGING.toString(), ServiceStatus.DOWN.toString(), "");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while checking messaging server connection status", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an event subscriber to this publisher. Subscriber will be subscribed
|
||||||
|
* to all events from this publisher.
|
||||||
|
*
|
||||||
|
* @param subscriber The subscriber to add.
|
||||||
|
*/
|
||||||
|
public void addSubscriber(PropertyChangeListener subscriber) {
|
||||||
|
eventPublisher.addSubscriber(servicesList, subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an event subscriber to this publisher.
|
||||||
|
*
|
||||||
|
* @param eventNames The events the subscriber is interested in.
|
||||||
|
* @param subscriber The subscriber to add.
|
||||||
|
*/
|
||||||
|
public void addSubscriber(Set<String> eventNames, PropertyChangeListener subscriber) {
|
||||||
|
eventPublisher.addSubscriber(eventNames, subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an event subscriber to this publisher.
|
||||||
|
*
|
||||||
|
* @param eventName The event the subscriber is interested in.
|
||||||
|
* @param subscriber The subscriber to add.
|
||||||
|
*/
|
||||||
|
public void addSubscriber(String eventName, PropertyChangeListener subscriber) {
|
||||||
|
eventPublisher.addSubscriber(eventName, subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an event subscriber from this publisher.
|
||||||
|
*
|
||||||
|
* @param eventNames The events the subscriber is no longer interested in.
|
||||||
|
* @param subscriber The subscriber to remove.
|
||||||
|
*/
|
||||||
|
public void removeSubscriber(Set<String> eventNames, PropertyChangeListener subscriber) {
|
||||||
|
eventPublisher.removeSubscriber(eventNames, subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an event subscriber from this publisher.
|
||||||
|
*
|
||||||
|
* @param eventName The event the subscriber is no longer interested in.
|
||||||
|
* @param subscriber The subscriber to remove.
|
||||||
|
*/
|
||||||
|
public void removeSubscriber(String eventName, PropertyChangeListener subscriber) {
|
||||||
|
eventPublisher.removeSubscriber(eventName, subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an event subscriber to this publisher. Subscriber will be removed
|
||||||
|
* from all event notifications from this publisher.
|
||||||
|
*
|
||||||
|
* @param subscriber The subscriber to remove.
|
||||||
|
*/
|
||||||
|
public void removeSubscriber(PropertyChangeListener subscriber) {
|
||||||
|
eventPublisher.removeSubscriber(servicesList, subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies connectivity to all services.
|
||||||
|
*/
|
||||||
|
private void checkAllServices() {
|
||||||
|
for (String service : servicesList) {
|
||||||
|
checkServiceStatus(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Runnable task that periodically checks the availability of
|
||||||
|
* collaboration resources (remote database, remote keyword search service,
|
||||||
|
* message broker) and reports status to the user in case of a gap in
|
||||||
|
* service.
|
||||||
|
*/
|
||||||
|
private final class CrashDetectionTask implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor the availability of collaboration resources
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
checkAllServices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when service status query results in an error.
|
||||||
|
*/
|
||||||
|
public class ServicesMonitorException extends Exception {
|
||||||
|
|
||||||
|
public ServicesMonitorException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServicesMonitorException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
Core/src/org/sleuthkit/autopsy/core/events/ServiceEvent.java
Normal file
49
Core/src/org/sleuthkit/autopsy/core/events/ServiceEvent.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 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.core.events;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class for events to be published to registered subscribers of Service
|
||||||
|
* Monitor on this Autopsy node. The class extends PropertyChangeEvent (via
|
||||||
|
* AutopsyEvent) to integrate with legacy use of JavaBeans PropertyChangeEvents
|
||||||
|
* and PropertyChangeListeners as an application event system, and implements
|
||||||
|
* Serializable to allow it to be published over a network in serialized form.
|
||||||
|
*/
|
||||||
|
public final class ServiceEvent extends AutopsyEvent implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final String details;
|
||||||
|
|
||||||
|
public ServiceEvent(String serviceName, String status, String details) {
|
||||||
|
super(serviceName, null, status);
|
||||||
|
this.details = details;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets details string passed as input to ServiceEvent constructor.
|
||||||
|
*
|
||||||
|
* @return String Details of the event.
|
||||||
|
*/
|
||||||
|
public String getDetails() {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
}
|
@ -24,10 +24,12 @@ import java.util.Collection;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UIManager.LookAndFeelInfo;
|
import javax.swing.UIManager.LookAndFeelInfo;
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
import org.netbeans.spi.sendopts.OptionProcessor;
|
import org.netbeans.spi.sendopts.OptionProcessor;
|
||||||
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
|
import org.netbeans.swing.tabcontrol.plaf.DefaultTabbedContainerUI;
|
||||||
import org.openide.modules.ModuleInstall;
|
import org.openide.modules.ModuleInstall;
|
||||||
@ -74,13 +76,18 @@ public class Installer extends ModuleInstall {
|
|||||||
for (OptionProcessor processor : processors) {
|
for (OptionProcessor processor : processors) {
|
||||||
if (processor instanceof OpenFromArguments) {
|
if (processor instanceof OpenFromArguments) {
|
||||||
OpenFromArguments argsProcessor = (OpenFromArguments) processor;
|
OpenFromArguments argsProcessor = (OpenFromArguments) processor;
|
||||||
String caseFile = argsProcessor.getDefaultArg();
|
final String caseFile = argsProcessor.getDefaultArg();
|
||||||
if (caseFile != null && !caseFile.equals("") && caseFile.endsWith(".aut") && new File(caseFile).exists()) { //NON-NLS
|
if (caseFile != null && !caseFile.equals("") && caseFile.endsWith(".aut") && new File(caseFile).exists()) { //NON-NLS
|
||||||
try {
|
|
||||||
Case.open(caseFile);
|
new Thread(() -> {
|
||||||
return;
|
// Create case.
|
||||||
} catch (Exception e) {
|
try{
|
||||||
}
|
Case.open(caseFile);
|
||||||
|
} catch(Exception ex){
|
||||||
|
logger.log(Level.WARNING, "Error opening case. ", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,13 +106,15 @@ public class Installer extends ModuleInstall {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
new Thread(() -> {
|
||||||
if (Case.isCaseOpen())
|
try {
|
||||||
Case.getCurrentCase().closeCase();
|
if (Case.isCaseOpen())
|
||||||
}
|
Case.getCurrentCase().closeCase();
|
||||||
catch (CaseActionException ex) {
|
}
|
||||||
logger.log(Level.WARNING, "Error closing case. ", ex); //NON-NLS
|
catch (CaseActionException | IllegalStateException ex) {
|
||||||
}
|
logger.log(Level.WARNING, "Error closing case. ", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupLAF() {
|
private void setupLAF() {
|
||||||
|
@ -567,8 +567,10 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
|
|||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
Case.getCurrentCase();
|
Case.getCurrentCase();
|
||||||
CoreComponentControl.openCoreWindows();
|
SwingUtilities.invokeLater(() -> {
|
||||||
SwingUtilities.invokeLater(this::componentOpened);
|
CoreComponentControl.openCoreWindows();
|
||||||
|
componentOpened();
|
||||||
|
});
|
||||||
} catch (IllegalStateException notUsed) {
|
} catch (IllegalStateException notUsed) {
|
||||||
/**
|
/**
|
||||||
* Case is closed, do nothing.
|
* Case is closed, do nothing.
|
||||||
|
@ -62,7 +62,7 @@ public class AutopsyEvent extends PropertyChangeEvent implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Gets the source type (local or remote).
|
* Gets the source type (local or remote).
|
||||||
*
|
*
|
||||||
* @param sourceType The source type of the event, local or remote.
|
* @return SourceType The source type of the event, local or remote.
|
||||||
*/
|
*/
|
||||||
public SourceType getSourceType() {
|
public SourceType getSourceType() {
|
||||||
return sourceType;
|
return sourceType;
|
||||||
|
@ -120,7 +120,7 @@ public final class AutopsyEventPublisher {
|
|||||||
/**
|
/**
|
||||||
* Removes an event subscriber from this publisher.
|
* Removes an event subscriber from this publisher.
|
||||||
*
|
*
|
||||||
* @param eventNames The event the subscriber is no longer interested in.
|
* @param eventName The event the subscriber is no longer interested in.
|
||||||
* @param subscriber The subscriber to remove.
|
* @param subscriber The subscriber to remove.
|
||||||
*/
|
*/
|
||||||
public void removeSubscriber(String eventName, PropertyChangeListener subscriber) {
|
public void removeSubscriber(String eventName, PropertyChangeListener subscriber) {
|
||||||
|
@ -21,6 +21,10 @@ package org.sleuthkit.autopsy.events;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
import javax.jms.Connection;
|
||||||
|
import javax.jms.JMSException;
|
||||||
|
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||||
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection info for a Java Message Service (JMS) provider. Thread-safe.
|
* Connection info for a Java Message Service (JMS) provider. Thread-safe.
|
||||||
@ -99,4 +103,20 @@ public final class MessageServiceConnectionInfo {
|
|||||||
return new URI(String.format(MESSAGE_SERVICE_URI, host, port));
|
return new URI(String.format(MESSAGE_SERVICE_URI, host, port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies connection to messaging service.
|
||||||
|
*
|
||||||
|
* @return True if connection can be established, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean canConnect() {
|
||||||
|
try {
|
||||||
|
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(getUserName(), getPassword(), getURI());
|
||||||
|
Connection connection = connectionFactory.createConnection();
|
||||||
|
connection.start();
|
||||||
|
connection.close();
|
||||||
|
return true;
|
||||||
|
} catch (URISyntaxException | JMSException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,9 @@ final class RemoteEventPublisher {
|
|||||||
if (object instanceof AutopsyEvent) {
|
if (object instanceof AutopsyEvent) {
|
||||||
AutopsyEvent event = (AutopsyEvent) object;
|
AutopsyEvent event = (AutopsyEvent) object;
|
||||||
event.setSourceType(AutopsyEvent.SourceType.REMOTE);
|
event.setSourceType(AutopsyEvent.SourceType.REMOTE);
|
||||||
localPublisher.publish(event);
|
new Thread(() -> {
|
||||||
|
localPublisher.publish(event);
|
||||||
|
}).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -103,3 +103,5 @@ IngestJobSettingsPanel.jButtonSelectAll.text=Select All
|
|||||||
IngestJobSettingsPanel.jButtonDeselectAll.text=Deselect All
|
IngestJobSettingsPanel.jButtonDeselectAll.text=Deselect All
|
||||||
IngestJobSettingsPanel.processUnallocCheckbox.toolTipText=Processes unallocated space, such as deleted files. Produces more complete results, but it may take longer to process on large images.
|
IngestJobSettingsPanel.processUnallocCheckbox.toolTipText=Processes unallocated space, such as deleted files. Produces more complete results, but it may take longer to process on large images.
|
||||||
IngestJobSettingsPanel.processUnallocCheckbox.text=Process Unallocated Space
|
IngestJobSettingsPanel.processUnallocCheckbox.text=Process Unallocated Space
|
||||||
|
IngestManager.cancellingIngest.msgDlg.text=Cancelling all currently running ingest jobs
|
||||||
|
IngestManager.serviceIsDown.msgDlg.text={0} is down
|
||||||
|
@ -26,6 +26,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -44,6 +45,7 @@ import org.netbeans.api.progress.ProgressHandleFactory;
|
|||||||
import org.openide.util.Cancellable;
|
import org.openide.util.Cancellable;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.core.ServicesMonitor;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
@ -151,6 +153,12 @@ public class IngestManager {
|
|||||||
*/
|
*/
|
||||||
private volatile boolean runInteractively;
|
private volatile boolean runInteractively;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ingest manager subscribes to service outage notifications. If key services are down,
|
||||||
|
* ingest manager cancels all ingest jobs in progress.
|
||||||
|
*/
|
||||||
|
private final ServicesMonitor servicesMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ingest job events.
|
* Ingest job events.
|
||||||
*/
|
*/
|
||||||
@ -265,6 +273,9 @@ public class IngestManager {
|
|||||||
this.jobsById = new ConcurrentHashMap<>();
|
this.jobsById = new ConcurrentHashMap<>();
|
||||||
this.ingestJobStarters = new ConcurrentHashMap<>();
|
this.ingestJobStarters = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
this.servicesMonitor = ServicesMonitor.getInstance();
|
||||||
|
subscribeToServiceMonitorEvents();
|
||||||
|
|
||||||
this.startDataSourceIngestThread();
|
this.startDataSourceIngestThread();
|
||||||
|
|
||||||
numberOfFileIngestThreads = UserPreferences.numberOfFileIngestThreads();
|
numberOfFileIngestThreads = UserPreferences.numberOfFileIngestThreads();
|
||||||
@ -314,6 +325,56 @@ public class IngestManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe ingest manager to service monitor events. Cancels ingest
|
||||||
|
* if one of services it's subscribed to goes down.
|
||||||
|
*/
|
||||||
|
private void subscribeToServiceMonitorEvents() {
|
||||||
|
PropertyChangeListener propChangeListener = new PropertyChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
if (evt.getNewValue().equals(ServicesMonitor.ServiceStatus.DOWN.toString())) {
|
||||||
|
|
||||||
|
// check whether a milti-user case is currently being processed
|
||||||
|
try {
|
||||||
|
if (!Case.isCaseOpen() || Case.getCurrentCase().getCaseType() != Case.CaseType.MULTI_USER_CASE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (IllegalStateException ignore) {
|
||||||
|
// thorown by Case.getCurrentCase() when no case is open
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// one of the services we subscribed to went down
|
||||||
|
String serviceDisplayName = ServicesMonitor.Service.valueOf(evt.getPropertyName()).getDisplayName();
|
||||||
|
logger.log(Level.SEVERE, "Service {0} is down! Cancelling all running ingest jobs", serviceDisplayName); //NON-NLS
|
||||||
|
|
||||||
|
// display notification if running interactively
|
||||||
|
if (isIngestRunning() && isRunningInteractively()) {
|
||||||
|
EventQueue.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
JOptionPane.showMessageDialog(null,
|
||||||
|
NbBundle.getMessage(this.getClass(), "IngestManager.cancellingIngest.msgDlg.text"),
|
||||||
|
NbBundle.getMessage(this.getClass(), "IngestManager.serviceIsDown.msgDlg.text", serviceDisplayName),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel ingest if running
|
||||||
|
cancelAllIngestJobs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// subscribe to services of interest
|
||||||
|
Set<String> servicesList = new HashSet<>();
|
||||||
|
servicesList.add(ServicesMonitor.Service.REMOTE_CASE_DATABASE.toString());
|
||||||
|
servicesList.add(ServicesMonitor.Service.REMOTE_KEYWORD_SEARCH.toString());
|
||||||
|
this.servicesMonitor.addSubscriber(servicesList, propChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
synchronized void handleCaseOpened() {
|
synchronized void handleCaseOpened() {
|
||||||
this.jobCreationIsEnabled = true;
|
this.jobCreationIsEnabled = true;
|
||||||
clearIngestMessageBox();
|
clearIngestMessageBox();
|
||||||
@ -361,6 +422,7 @@ public class IngestManager {
|
|||||||
* The ingest manager can be directed to forgo use of message boxes, the
|
* The ingest manager can be directed to forgo use of message boxes, the
|
||||||
* ingest message box, NetBeans progress handles, etc. Running interactively
|
* ingest message box, NetBeans progress handles, etc. Running interactively
|
||||||
* is the default.
|
* is the default.
|
||||||
|
* @return true if running interactively, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isRunningInteractively() {
|
public boolean isRunningInteractively() {
|
||||||
return this.runInteractively;
|
return this.runInteractively;
|
||||||
|
@ -53,9 +53,13 @@ public class SolrSearchService implements KeywordSearchService {
|
|||||||
if (artifactId > 0)
|
if (artifactId > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Case currentCase = Case.getCurrentCase();
|
Case currentCase;
|
||||||
if (currentCase == null)
|
try {
|
||||||
|
currentCase = Case.getCurrentCase();
|
||||||
|
} catch (IllegalStateException ignore) {
|
||||||
|
// thorown by Case.getCurrentCase() if currentCase is null
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SleuthkitCase sleuthkitCase = currentCase.getSleuthkitCase();
|
SleuthkitCase sleuthkitCase = currentCase.getSleuthkitCase();
|
||||||
if (sleuthkitCase == null)
|
if (sleuthkitCase == null)
|
||||||
@ -153,6 +157,9 @@ public class SolrSearchService implements KeywordSearchService {
|
|||||||
try {
|
try {
|
||||||
String host = UserPreferences.getIndexingServerHost();
|
String host = UserPreferences.getIndexingServerHost();
|
||||||
String port = UserPreferences.getIndexingServerPort();
|
String port = UserPreferences.getIndexingServerPort();
|
||||||
|
if (host.isEmpty() || port.isEmpty()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
HttpSolrServer solrServer = new HttpSolrServer("http://" + host + ":" + port + "/solr"); //NON-NLS;
|
HttpSolrServer solrServer = new HttpSolrServer("http://" + host + ":" + port + "/solr"); //NON-NLS;
|
||||||
KeywordSearch.getServer().connectToSolrServer(solrServer);
|
KeywordSearch.getServer().connectToSolrServer(solrServer);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Thu, 25 Jun 2015 13:09:21 -0400
|
#Thu, 23 Jul 2015 09:29:40 -0400
|
||||||
LBL_splash_window_title=Starting Autopsy
|
LBL_splash_window_title=Starting Autopsy
|
||||||
SPLASH_HEIGHT=314
|
SPLASH_HEIGHT=314
|
||||||
SPLASH_WIDTH=538
|
SPLASH_WIDTH=538
|
||||||
@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18
|
|||||||
SplashRunningTextColor=0x0
|
SplashRunningTextColor=0x0
|
||||||
SplashRunningTextFontSize=19
|
SplashRunningTextFontSize=19
|
||||||
|
|
||||||
currentVersion=Autopsy 3.1.2
|
currentVersion=Autopsy 3.1.3
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#Updated by build script
|
#Updated by build script
|
||||||
#Thu, 25 Jun 2015 13:09:21 -0400
|
#Thu, 23 Jul 2015 09:29:40 -0400
|
||||||
|
|
||||||
CTL_MainWindow_Title=Autopsy 3.1.2
|
CTL_MainWindow_Title=Autopsy 3.1.3
|
||||||
CTL_MainWindow_Title_No_Project=Autopsy 3.1.2
|
CTL_MainWindow_Title_No_Project=Autopsy 3.1.3
|
||||||
|
Loading…
x
Reference in New Issue
Block a user