mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-05 08:46:20 +00:00
Complete first implementation of CollaboratinoMonitor
This commit is contained in:
@@ -7,7 +7,6 @@ file.reference.postgresql-9.4-1201-jdbc41.jar=release/modules/ext/postgresql-9.4
|
||||
file.reference.Rejistry-1.0-SNAPSHOT.jar=release/modules/ext/Rejistry-1.0-SNAPSHOT.jar
|
||||
file.reference.sevenzipjbinding-AllPlatforms.jar=release/modules/ext/sevenzipjbinding-AllPlatforms.jar
|
||||
file.reference.sevenzipjbinding.jar=release/modules/ext/sevenzipjbinding.jar
|
||||
file.reference.solr-solrj-4.9.1.jar=release/modules/ext/solr-solrj-4.9.1.jar
|
||||
file.reference.sqlite-jdbc-3.7.15-M1.jar=release/modules/ext/sqlite-jdbc-3.7.15-M1.jar
|
||||
file.reference.StixLib.jar=release/modules/ext/StixLib.jar
|
||||
file.reference.tika-core-1.5.jar=release/modules/ext/tika-core-1.5.jar
|
||||
|
||||
@@ -258,10 +258,6 @@
|
||||
<runtime-relative-path>ext/Tsk_DataModel.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/Tsk_DataModel.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
<class-path-extension>
|
||||
<runtime-relative-path>ext/solr-solrj-4.9.1.jar</runtime-relative-path>
|
||||
<binary-origin>release/modules/ext/solr-solrj-4.9.1.jar</binary-origin>
|
||||
</class-path-extension>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
|
||||
@@ -310,7 +310,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
|
||||
if (!newContents.isEmpty()) {
|
||||
Case.getCurrentCase().notifyNewDataSource(newContents.get(0), dataSourceId);
|
||||
} else {
|
||||
Case.getCurrentCase().notifyNewDataSource(null, dataSourceId); // RJCTODO: Update for null scenario
|
||||
Case.getCurrentCase().notifyFailedAddingNewDataSource(dataSourceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -241,3 +241,7 @@ LocalFilesPanel.errorLabel.text=Error Label
|
||||
NewCaseVisualPanel1.errorLabel.text=Error Label
|
||||
CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source
|
||||
CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1}
|
||||
CollaborationMonitor.failedService.notify.title=Collaboration Failure
|
||||
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
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.openide.util.actions.CallableSystemAction;
|
||||
import org.openide.util.actions.SystemAction;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.services.Services;
|
||||
@@ -119,23 +120,33 @@ public class Case {
|
||||
/**
|
||||
* Property name used for a property change event that indicates a new
|
||||
* data source (image, local/logical file or local disk) is being added
|
||||
* to the current case. The new value field of the property change event
|
||||
* is the path of the data source.
|
||||
* to the current case. The old and new values of the
|
||||
* PropertyChangeEvent are null - cast the PropertyChangeEvent to
|
||||
* org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent to
|
||||
* access event data.
|
||||
*/
|
||||
ADDING_DATA_SOURCE,
|
||||
/**
|
||||
* Property name used for a property change event that indicates a
|
||||
* failure adding a new data source (image, local/logical file or local
|
||||
* disk) to the current case. The old and new values of the
|
||||
* PropertyChangeEvent are null - cast the PropertyChangeEvent to
|
||||
* org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent
|
||||
* to access event data.
|
||||
*/
|
||||
ADDING_DATA_SOURCE_FAILED,
|
||||
/**
|
||||
* Property name that indicates a new data source (image, disk or local
|
||||
* file) has been added to the current case. The old and new values of
|
||||
* the PropertyChangeEvent are null - cast the PropertyChangeEvent to
|
||||
* org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent to
|
||||
* access event data.
|
||||
* file) has been added to the current case. The new value is the
|
||||
* newly-added instance of the new data source, and the old value is
|
||||
* always null.
|
||||
*/
|
||||
DATA_SOURCE_ADDED,
|
||||
/**
|
||||
* Property name that indicates a data source has been removed from the
|
||||
* current case. The "old value" is the (int) content ID of the data
|
||||
* source that was removed, the new value is the instance of the data
|
||||
* source. RJCTODO: Improve this doc
|
||||
* source.
|
||||
*/
|
||||
DATA_SOURCE_DELETED,
|
||||
/**
|
||||
@@ -215,7 +226,7 @@ public class Case {
|
||||
private boolean hasData = false;
|
||||
|
||||
private CollaborationMonitor collaborationMonitor;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for the Case class
|
||||
*/
|
||||
@@ -295,12 +306,13 @@ public class Case {
|
||||
eventPublisher.openRemoteEventChannel(String.format(EVENT_CHANNEL_NAME, newCase.getTextIndexName()));
|
||||
currentCase.collaborationMonitor = new CollaborationMonitor();
|
||||
} catch (AutopsyEventException | CollaborationMonitor.CollaborationMonitorException ex) {
|
||||
currentCase.collaborationMonitor.stop();
|
||||
logger.log(Level.SEVERE, "Failed to setup for collaboration", ex);
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(Case.class, "Case.CollaborationSetup.FailNotify.Title"), NbBundle.getMessage(Case.class, "Case.CollaborationSetup.FailNotify.ErrMsg"));
|
||||
}
|
||||
}
|
||||
eventPublisher.publishLocally(new AutopsyEvent(Events.CURRENT_CASE.toString(), null, currentCase));
|
||||
|
||||
|
||||
} else {
|
||||
Logger.setLogDirectory(PlatformUtil.getLogDirectory());
|
||||
}
|
||||
@@ -546,6 +558,16 @@ public class Case {
|
||||
eventPublisher.publish(new AddingDataSourceEvent(dataSourceId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies case event subscribers (property change listeners) that a data
|
||||
* source failed to be added to the case database.
|
||||
*
|
||||
* @param dataSourceId A unique identifier for the data source.
|
||||
*/
|
||||
public void notifyFailedAddingNewDataSource(UUID dataSourceId) {
|
||||
eventPublisher.publish(new AddingDataSourceFailedEvent(dataSourceId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies case event subscribers (property change listeners) that a data
|
||||
* source is being added to the case database.
|
||||
|
||||
@@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.casemodule;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -35,19 +34,18 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import javax.jms.Connection;
|
||||
import javax.jms.JMSException;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
import org.apache.solr.client.solrj.request.CoreAdminRequest;
|
||||
import org.netbeans.api.progress.ProgressHandle;
|
||||
import org.netbeans.api.progress.ProgressHandleFactory;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@@ -62,10 +60,10 @@ import org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisStartedEvent;
|
||||
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
||||
|
||||
/**
|
||||
* A collaboration monitor listens to local events and represents them as
|
||||
* collaboration tasks that are broadcast to collaborating nodes, informs the
|
||||
* user of collaboration tasks on other nodes using progress bars, and monitors
|
||||
* the health of the key collaboration services.
|
||||
* A collaboration monitor listens to local events and translates them into
|
||||
* collaboration tasksForHost that are broadcast to collaborating nodes, informs
|
||||
* the user of collaboration tasksForHost on other nodes using progress bars,
|
||||
* and monitors the health of key collaboration services.
|
||||
*/
|
||||
final class CollaborationMonitor {
|
||||
|
||||
@@ -88,9 +86,9 @@ final class CollaborationMonitor {
|
||||
|
||||
/**
|
||||
* Constructs a collaboration monitor that listens to local events and
|
||||
* represents them as collaboration tasks that are broadcast to
|
||||
* collaborating nodes, informs the user of collaboration tasks on other
|
||||
* nodes using progress bars, and monitors the health of the key
|
||||
* translates them into collaboration tasksForHost that are broadcast to
|
||||
* collaborating nodes, informs the user of collaboration tasksForHost on
|
||||
* other nodes using progress bars, and monitors the health of key
|
||||
* collaboration services.
|
||||
*/
|
||||
CollaborationMonitor() throws CollaborationMonitorException {
|
||||
@@ -141,7 +139,8 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the name of the local host for use in describing local tasks.
|
||||
* Determines the name of the local host for use in describing local
|
||||
* tasksForHost.
|
||||
*
|
||||
* @return The host name of this Autopsy node.
|
||||
*/
|
||||
@@ -183,11 +182,11 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* The local tasks manager listens to local events and translates them into
|
||||
* tasks it broadcasts to collaborating nodes. Note that all access to the
|
||||
* task collections is synchronized since they may be accessed by both the
|
||||
* threads publishing property change events and by the heartbeat task
|
||||
* thread.
|
||||
* The local tasksForHost manager listens to local events and translates
|
||||
* them into tasksForHost it broadcasts to collaborating nodes. Note that
|
||||
* all access to the task collections is synchronized since they may be
|
||||
* accessed by both the threads publishing property change events and by the
|
||||
* heartbeat task thread.
|
||||
*/
|
||||
private final class LocalTasksManager implements PropertyChangeListener {
|
||||
|
||||
@@ -196,9 +195,9 @@ final class CollaborationMonitor {
|
||||
private final Map<Long, Task> jobIdsTodataSourceAnalysisTasks;
|
||||
|
||||
/**
|
||||
* Constructs a local tasks manager that listens to local events and
|
||||
* translates them into tasks that can be broadcast to collaborating
|
||||
* nodes.
|
||||
* Constructs a local tasksForHost manager that listens to local events
|
||||
* and translates them into tasksForHost that can be broadcast to
|
||||
* collaborating nodes.
|
||||
*/
|
||||
LocalTasksManager() {
|
||||
nextTaskId = 0;
|
||||
@@ -207,8 +206,8 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates events into updates of the collection of local tasks this
|
||||
* node is broadcasting to other nodes.
|
||||
* Translates events into updates of the collection of local
|
||||
* tasksForHost this node is broadcasting to other nodes.
|
||||
*
|
||||
* @param event A PropertyChangeEvent.
|
||||
*/
|
||||
@@ -217,8 +216,10 @@ final class CollaborationMonitor {
|
||||
String eventName = event.getPropertyName();
|
||||
if (eventName.equals(Case.Events.ADDING_DATA_SOURCE.toString())) {
|
||||
addDataSourceAddTask((AddingDataSourceEvent) event);
|
||||
} else if (eventName.equals(Case.Events.ADDING_DATA_SOURCE_FAILED.toString())) {
|
||||
removeDataSourceAddTask(((AddingDataSourceFailedEvent) event).getDataSourceId());
|
||||
} else if (eventName.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
|
||||
removeDataSourceAddTask((DataSourceAddedEvent) event);
|
||||
removeDataSourceAddTask(((DataSourceAddedEvent) event).getDataSourceId());
|
||||
} else if (eventName.equals(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_STARTED.toString())) {
|
||||
addDataSourceAnalysisTask((DataSourceAnalysisStartedEvent) event);
|
||||
} else if (eventName.equals(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED.toString())) {
|
||||
@@ -227,8 +228,9 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an adding data source task to the collection of local tasks and
|
||||
* publishes the updated collection to any collaborating nodes.
|
||||
* Adds an adding data source task to the collection of local
|
||||
* tasksForHost and publishes the updated collection to any
|
||||
* collaborating nodes.
|
||||
*
|
||||
* @param event An adding data source event.
|
||||
*/
|
||||
@@ -239,19 +241,22 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an adding data source task from the collection of local tasks
|
||||
* and publishes the updated collection to any collaborating nodes.
|
||||
* Removes an adding data source task from the collection of local
|
||||
* tasksForHost and publishes the updated collection to any
|
||||
* collaborating nodes.
|
||||
*
|
||||
* @param event A data source added event
|
||||
* @param dataSourceId A data source id to pair a data source added or
|
||||
* adding data source failed event with an adding data source event.
|
||||
*/
|
||||
synchronized void removeDataSourceAddTask(DataSourceAddedEvent event) {
|
||||
uuidsToAddDataSourceTasks.remove(event.getDataSourceId().hashCode());
|
||||
synchronized void removeDataSourceAddTask(UUID dataSourceId) {
|
||||
uuidsToAddDataSourceTasks.remove(dataSourceId.hashCode());
|
||||
eventPublisher.publishRemotely(new CollaborationEvent(hostName, getCurrentTasks()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a data source analysis task to the collection of local tasks and
|
||||
* publishes the updated collection to any collaborating nodes.
|
||||
* Adds a data source analysis task to the collection of local
|
||||
* tasksForHost and publishes the updated collection to any
|
||||
* collaborating nodes.
|
||||
*
|
||||
* @param event A data source analysis started event.
|
||||
*/
|
||||
@@ -263,8 +268,8 @@ final class CollaborationMonitor {
|
||||
|
||||
/**
|
||||
* Removes a data source analysis task from the collection of local
|
||||
* tasks and publishes the updated collection to any collaborating
|
||||
* nodes.
|
||||
* tasksForHost and publishes the updated collection to any
|
||||
* collaborating nodes.
|
||||
*
|
||||
* @param event A data source analysis completed event.
|
||||
*/
|
||||
@@ -274,9 +279,9 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current local tasks.
|
||||
* Gets the current local tasksForHost.
|
||||
*
|
||||
* @return A mapping of task IDs to tasks, may be empty.
|
||||
* @return A mapping of task IDs to tasksForHost, may be empty.
|
||||
*/
|
||||
synchronized Map<Long, Task> getCurrentTasks() {
|
||||
Map<Long, Task> currentTasks = new HashMap<>();
|
||||
@@ -292,11 +297,11 @@ final class CollaborationMonitor {
|
||||
|
||||
/**
|
||||
* Listens for collaboration event messages broadcast by collaboration
|
||||
* monitors on other nodes and translates them into remote tasks represented
|
||||
* locally using progress bars. Note that all access to the remote tasks is
|
||||
* synchronized since it may be accessed by both the threads publishing
|
||||
* property change events and by the thread running periodic checks for
|
||||
* "stale" tasks.
|
||||
* monitors on other nodes and translates them into remote tasksForHost
|
||||
* represented locally using progress bars. Note that all access to the
|
||||
* remote tasksForHost is synchronized since it may be accessed by both the
|
||||
* threads publishing property change events and by the thread running
|
||||
* periodic checks for "stale" tasksForHost.
|
||||
*/
|
||||
private final class RemoteTasksManager implements PropertyChangeListener {
|
||||
|
||||
@@ -305,15 +310,16 @@ final class CollaborationMonitor {
|
||||
/**
|
||||
* Constructs an object that listens for collaboration event messages
|
||||
* broadcast by collaboration monitors on other nodes and translates
|
||||
* them into remote tasks represented locally using progress bars.
|
||||
* them into remote tasksForHost represented locally using progress
|
||||
* bars.
|
||||
*/
|
||||
RemoteTasksManager() {
|
||||
hostsToTasks = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the remote tasks based to reflect a collaboration event
|
||||
* received from another node.
|
||||
* Updates the remote tasksForHost based to reflect a collaboration
|
||||
* event received from another node.
|
||||
*
|
||||
* @param event A collaboration event.
|
||||
*/
|
||||
@@ -325,39 +331,39 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the remote tasks based to reflect a collaboration event
|
||||
* received from another node.
|
||||
* Updates the remote tasksForHost based to reflect a collaboration
|
||||
* event received from another node.
|
||||
*
|
||||
* @param event A collaboration event.
|
||||
*/
|
||||
synchronized void updateTasks(CollaborationEvent event) {
|
||||
// RJCTODO: This is a little hard to understand, consider some renaming
|
||||
RemoteTasks tasks = hostsToTasks.get(event.getHostName());
|
||||
if (null != tasks) {
|
||||
tasks.update(event);
|
||||
RemoteTasks tasksForHost = hostsToTasks.get(event.getHostName());
|
||||
if (null != tasksForHost) {
|
||||
tasksForHost.update(event);
|
||||
} else {
|
||||
hostsToTasks.put(event.getHostName(), new RemoteTasks(event));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes any remote tasks that have gone stale, i.e., tasks for which
|
||||
* updates have ceased, presumably because the collaborating node has
|
||||
* gone down or there is a network issue.
|
||||
* Finishes any remote tasksForHost that have gone stale, i.e.,
|
||||
* tasksForHost for which updates have ceased, presumably because the
|
||||
* collaborating node has gone down or there is a network issue.
|
||||
*/
|
||||
synchronized void finishStaleTasks() {
|
||||
for (Iterator<Map.Entry<String, RemoteTasks>> it = hostsToTasks.entrySet().iterator(); it.hasNext();) {
|
||||
Map.Entry<String, RemoteTasks> entry = it.next();
|
||||
RemoteTasks tasks = entry.getValue();
|
||||
if (tasks.isStale()) {
|
||||
tasks.finishAllTasks();
|
||||
RemoteTasks tasksForHost = entry.getValue();
|
||||
if (tasksForHost.isStale()) {
|
||||
tasksForHost.finishAllTasks();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of progress bars for tasks on a collaborating node.
|
||||
* A collection of progress bars for tasksForHost on a collaborating
|
||||
* node.
|
||||
*/
|
||||
class RemoteTasks {
|
||||
|
||||
@@ -366,8 +372,8 @@ final class CollaborationMonitor {
|
||||
private Map<Long, ProgressHandle> taskIdsToProgressBars;
|
||||
|
||||
/**
|
||||
* Construct a set of progress bars to represent remote tasks for a
|
||||
* particular host.
|
||||
* Construct a set of progress bars to represent remote tasksForHost
|
||||
* for a particular host.
|
||||
*
|
||||
* @param event A collaboration event.
|
||||
*/
|
||||
@@ -387,10 +393,10 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this remote tasks collection.
|
||||
* Updates this remote tasksForHost collection.
|
||||
*
|
||||
* @param event A collaboration event from the collaborating node
|
||||
* associated with these tasks.
|
||||
* associated with these tasksForHost.
|
||||
*/
|
||||
void update(CollaborationEvent event) {
|
||||
/**
|
||||
@@ -434,8 +440,8 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unconditionally finishes the entire set or remote tasks. To be
|
||||
* used when a host drops off unexpectedly.
|
||||
* Unconditionally finishes the entire set or remote tasksForHost.
|
||||
* To be used when a host drops off unexpectedly.
|
||||
*/
|
||||
void finishAllTasks() {
|
||||
taskIdsToProgressBars.values().stream().forEach((progress) -> {
|
||||
@@ -446,8 +452,8 @@ final class CollaborationMonitor {
|
||||
|
||||
/**
|
||||
* Determines whether or not the time since the last update of this
|
||||
* remote tasks collection is greater than the maximum acceptable
|
||||
* interval between updates.
|
||||
* remote tasksForHost collection is greater than the maximum
|
||||
* acceptable interval between updates.
|
||||
*
|
||||
* @return True or false.
|
||||
*/
|
||||
@@ -459,11 +465,12 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A Runnable task that periodically publishes the local tasks in progress
|
||||
* on this node, providing a heartbeat message for collaboration monitors on
|
||||
* other nodes. The current local tasks are included in the heartbeat
|
||||
* message so that nodes that have just joined the event channel know what
|
||||
* this node is doing, even if they join after the current tasks are begun.
|
||||
* A Runnable task that periodically publishes the local tasksForHost in
|
||||
* progress on this node, providing a heartbeat message for collaboration
|
||||
* monitors on other nodes. The current local tasksForHost are included in
|
||||
* the heartbeat message so that nodes that have just joined the event
|
||||
* channel know what this node is doing, even if they join after the current
|
||||
* tasksForHost are begun.
|
||||
*/
|
||||
private final class HeartbeatTask implements Runnable {
|
||||
|
||||
@@ -477,14 +484,15 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A Runnable task that periodically deals with any remote tasks that have
|
||||
* gone stale, i.e., tasks for which updates have ceased, presumably because
|
||||
* the collaborating node has gone down or there is a network issue.
|
||||
* A Runnable task that periodically deals with any remote tasksForHost that
|
||||
* have gone stale, i.e., tasksForHost for which updates have ceased,
|
||||
* presumably because the collaborating node has gone down or there is a
|
||||
* network issue.
|
||||
*/
|
||||
private final class StaleTaskDetectionTask implements Runnable {
|
||||
|
||||
/**
|
||||
* Check for stale remote tasks and clean them up, if found.
|
||||
* Check for stale remote tasksForHost and clean them up, if found.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -509,19 +517,26 @@ final class CollaborationMonitor {
|
||||
try {
|
||||
DriverManager.getConnection("jdbc:postgresql://" + dbInfo.getHost() + ":" + dbInfo.getPort() + "/" + "postgres", dbInfo.getUserName(), dbInfo.getUserName()); // NON-NLS
|
||||
} catch (SQLException ex) {
|
||||
MessageNotifyUtil.Notify.error("Collaboration Failure", "Lost connection to database server"); // RJCTODO: Bundle
|
||||
logger.log(Level.SEVERE, "Failed to connect to PostgreSQL", ex);
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedDbService.notify.msg"));
|
||||
}
|
||||
|
||||
// RJCTODO: Can this be made to work...seems to wander off on line 519 and never comes back...
|
||||
/**
|
||||
* TODO: Figure out what is wrong with this code. The call to
|
||||
* construct the HttpSolrServer object never returns. Perhaps this
|
||||
* is the result of a dependency of the solr-solrj-4.91.jar that is
|
||||
* not satisfied. Removing the jar from wrapped jars for now.
|
||||
*/
|
||||
// try {
|
||||
// String host = UserPreferences.getIndexingServerHost();
|
||||
// String port = UserPreferences.getIndexingServerPort();
|
||||
// HttpSolrServer solr = new HttpSolrServer("http://" + host + ":" + port + "/solr/" + Case.getCurrentCase().getTextIndexName());
|
||||
// HttpSolrServer solr = new HttpSolrServer("http://" + host + ":" + port + "/solr");
|
||||
// CoreAdminRequest.getStatus(Case.getCurrentCase().getTextIndexName(), solr);
|
||||
// } catch (SolrServerException | IOException ex) {
|
||||
// MessageNotifyUtil.Notify.error("Collaboration Failure", "Lost connection to keyword search server"); // RJCTODO: Bundle
|
||||
// logger.log(Level.SEVERE, "Failed to connect to Solr", ex);
|
||||
// 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());
|
||||
@@ -529,7 +544,8 @@ final class CollaborationMonitor {
|
||||
connection.start();
|
||||
connection.close();
|
||||
} catch (URISyntaxException | JMSException ex) {
|
||||
MessageNotifyUtil.Notify.error("Collaboration Failure", "Lost connection to messaging server"); // RJCTODO: Bundle
|
||||
logger.log(Level.SEVERE, "Failed to connect to ActiveMQ", ex);
|
||||
MessageNotifyUtil.Notify.error(NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedService.notify.title"), NbBundle.getMessage(CollaborationMonitor.class, "CollaborationMonitor.failedMessageService.notify.msg"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,7 +566,8 @@ final class CollaborationMonitor {
|
||||
* collaboration monitors on other Autopsy nodes.
|
||||
*
|
||||
* @param hostName The name of the host sending the event.
|
||||
* @param currentTasks The tasks in progress for this Autopsy node.
|
||||
* @param currentTasks The tasksForHost in progress for this Autopsy
|
||||
* node.
|
||||
*/
|
||||
CollaborationEvent(String hostName, Map<Long, Task> currentTasks) {
|
||||
super(COLLABORATION_MONITOR_EVENT, null, null);
|
||||
@@ -568,10 +585,10 @@ final class CollaborationMonitor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current tasks for the Autopsy node that published this
|
||||
* event.
|
||||
* Gets the current tasksForHost for the Autopsy node that published
|
||||
* this event.
|
||||
*
|
||||
* @return A mapping of task IDs to current tasks
|
||||
* @return A mapping of task IDs to current tasksForHost
|
||||
*/
|
||||
Map<Long, Task> getCurrentTasks() {
|
||||
return currentTasks;
|
||||
|
||||
@@ -38,7 +38,8 @@ public final class AddingDataSourceEvent extends AutopsyEvent implements Seriali
|
||||
* case.
|
||||
*
|
||||
* @param dataSourceId A unique identifier associated with the data source.
|
||||
* Used to pair this AddindDataSourceEvent with a DataSoruceAddedEvent.
|
||||
* Used to pair this AddingDataSourceEvent with a DataSourceAddedEvent or a
|
||||
* AddingDataSourceFailedEvent.
|
||||
*/
|
||||
public AddingDataSourceEvent(UUID dataSourceId) {
|
||||
super(Case.Events.ADDING_DATA_SOURCE.toString(), null, null);
|
||||
@@ -47,7 +48,8 @@ public final class AddingDataSourceEvent extends AutopsyEvent implements Seriali
|
||||
|
||||
/**
|
||||
* Gets the unique id for the data source used to pair this
|
||||
* AddindDataSourceEvent with a DataSoruceAddedEvent.
|
||||
* AddindDataSourceEvent with a a DataSourceAddedEvent or a
|
||||
* AddingDataSourceFailedEvent.
|
||||
*
|
||||
* @return The unique id.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 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.casemodule.events;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
|
||||
/**
|
||||
* Event published when an attempt to add a data source to a case fails.
|
||||
*/
|
||||
@Immutable
|
||||
public final class AddingDataSourceFailedEvent extends AutopsyEvent implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final UUID dataSourceId;
|
||||
|
||||
/**
|
||||
* Constructs an event published when an attempt to add a data source to a
|
||||
* case fails.
|
||||
*
|
||||
* @param dataSourceId A unique identifier associated with the data source.
|
||||
* Used to pair this AddingDataSourceFailedEvent with a AddingDataSourceEvent.
|
||||
*/
|
||||
public AddingDataSourceFailedEvent(UUID dataSourceId) {
|
||||
super(Case.Events.ADDING_DATA_SOURCE_FAILED.toString(), null, null);
|
||||
this.dataSourceId = dataSourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unique id for the data source used to pair this
|
||||
* AddingDataSourceFailedEvent with a AddingDataSourceEvent.
|
||||
*
|
||||
* @return The unique id.
|
||||
*/
|
||||
public UUID getDataSourceId() {
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public final class DataSourceAddedEvent extends AutopsyEvent implements Serializ
|
||||
*
|
||||
* @param dataSource The data source that was added.
|
||||
* @param dataSourceId A unique identifier associated with the data source.
|
||||
* Used to pair this DataSoruceAddedEvent with a AddindDataSourceEvent.
|
||||
* Used to pair this DataSourceAddedEvent with a AddindDataSourceEvent.
|
||||
*/
|
||||
public DataSourceAddedEvent(Content dataSource, UUID dataSourceId) {
|
||||
/**
|
||||
@@ -59,7 +59,8 @@ public final class DataSourceAddedEvent extends AutopsyEvent implements Serializ
|
||||
/**
|
||||
* Gets the data source that was added.
|
||||
*
|
||||
* @return The data source.
|
||||
* @return The data source or null if there is an error retrieving the data
|
||||
* source.
|
||||
*/
|
||||
@Override
|
||||
public Object getNewValue() {
|
||||
@@ -92,15 +93,15 @@ public final class DataSourceAddedEvent extends AutopsyEvent implements Serializ
|
||||
public Content getDataSource() {
|
||||
return (Content) getNewValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the unique id for the data source used to pair this
|
||||
* DataSoruceAddedEvent with a AddindDataSourceEvent.
|
||||
* DataSourceAddedEvent with a AddingDataSourceEvent.
|
||||
*
|
||||
* @return The unique id.
|
||||
*/
|
||||
public UUID getDataSourceId() {
|
||||
return dataSourceId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -174,11 +174,21 @@ public class IngestManager {
|
||||
*/
|
||||
CANCELLED,
|
||||
/**
|
||||
* RJCTODO
|
||||
* Property change event fired when analysis (ingest) of a data source
|
||||
* included in an ingest job is started. Both the old and new values of
|
||||
* the ProerptyChangeEvent are set to null - cast the
|
||||
* PropertyChangeEvent to
|
||||
* org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisStartedEvent to
|
||||
* access event data.
|
||||
*/
|
||||
DATA_SOURCE_ANALYSIS_STARTED,
|
||||
/**
|
||||
* RJCTODO
|
||||
* Property change event fired when analysis (ingest) of a data source
|
||||
* included in an ingest job is completed. Both the old and new values
|
||||
* of the ProerptyChangeEvent are set to null - cast the
|
||||
* PropertyChangeEvent to
|
||||
* org.sleuthkit.autopsy.ingest.events.DataSourceAnalysisCompletedEvent
|
||||
* to access event data.
|
||||
*/
|
||||
DATA_SOURCE_ANALYSIS_COMPLETED,
|
||||
};
|
||||
@@ -355,7 +365,7 @@ public class IngestManager {
|
||||
synchronized boolean isRunningInteractively() {
|
||||
return this.runInteractively;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the custom installer for this package once the window system is
|
||||
* initialized, allowing the ingest manager to get the top component used to
|
||||
@@ -664,7 +674,7 @@ public class IngestManager {
|
||||
* @param dataSource The data source.
|
||||
*/
|
||||
void fireDataSourceAnalysisCompleted(long ingestJobId, long dataSourceIngestJobId, Content dataSource) {
|
||||
AutopsyEvent event = new DataSourceAnalysisCompletedEvent(ingestJobId, dataSourceIngestJobId, dataSource, DataSourceAnalysisCompletedEvent.Reason.COMPLETED);
|
||||
AutopsyEvent event = new DataSourceAnalysisCompletedEvent(ingestJobId, dataSourceIngestJobId, dataSource, DataSourceAnalysisCompletedEvent.Reason.ANALYSIS_COMPLETED);
|
||||
eventPublishingExecutor.submit(new PublishEventTask(event, jobEventPublisher));
|
||||
}
|
||||
|
||||
@@ -676,7 +686,7 @@ public class IngestManager {
|
||||
* @param dataSource The data source.
|
||||
*/
|
||||
void fireDataSourceAnalysisCancelled(long ingestJobId, long dataSourceIngestJobId, Content dataSource) {
|
||||
AutopsyEvent event = new DataSourceAnalysisCompletedEvent(ingestJobId, dataSourceIngestJobId, dataSource, DataSourceAnalysisCompletedEvent.Reason.CANCELLED);
|
||||
AutopsyEvent event = new DataSourceAnalysisCompletedEvent(ingestJobId, dataSourceIngestJobId, dataSource, DataSourceAnalysisCompletedEvent.Reason.ANALYSIS_CANCELLED);
|
||||
eventPublishingExecutor.submit(new PublishEventTask(event, jobEventPublisher));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,25 +23,44 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
* RJCTODO
|
||||
* Event published when analysis (ingest) of a data source included in an ingest
|
||||
* job is completed.
|
||||
*/
|
||||
public class DataSourceAnalysisCompletedEvent extends DataSourceAnalysisEvent implements Serializable {
|
||||
|
||||
/**
|
||||
* The reason why the analysis of the data source completed.
|
||||
*/
|
||||
public enum Reason {
|
||||
COMPLETED,
|
||||
CANCELLED
|
||||
|
||||
ANALYSIS_COMPLETED,
|
||||
ANALYSIS_CANCELLED
|
||||
}
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Reason reason;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an event published when analysis (ingest) of a data source
|
||||
* included in an ingest job is completed.
|
||||
*
|
||||
* @param ingestJobId The identifier of the ingest job, specific to this
|
||||
* node.
|
||||
* @param dataSourceIngestJobId The identifier of the data source ingest
|
||||
* job,specific to this node.
|
||||
* @param dataSource The data source.
|
||||
* @param reason The reason analysis completed.
|
||||
*/
|
||||
public DataSourceAnalysisCompletedEvent(long ingestJobId, long dataSourceIngestJobId, Content dataSource, Reason reason) {
|
||||
super(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_COMPLETED, ingestJobId, dataSourceIngestJobId, dataSource);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the reason why the analysis of the data source completed.
|
||||
*/
|
||||
public Reason getResult() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,27 +19,36 @@
|
||||
package org.sleuthkit.autopsy.ingest.events;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* RJCTODO
|
||||
* A base class for events published in connection with the analysis (ingest) of
|
||||
* a data source.
|
||||
*/
|
||||
public abstract class DataSourceAnalysisEvent extends AutopsyEvent implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger logger = Logger.getLogger(DataSourceAnalysisEvent.class.getName());
|
||||
private final long ingestJobId;
|
||||
private final long dataSourceIngestJobId;
|
||||
private transient Content dataSource; // RJCTODO: Make able to be published remotely
|
||||
private transient Content dataSource;
|
||||
|
||||
/**
|
||||
* RJCTOD
|
||||
* Constructs an instance of the base class for events published in
|
||||
* connection with the analysis (ingest) of a data source.
|
||||
*
|
||||
* @param eventType
|
||||
* @param ingestJobId
|
||||
* @param dataSourceIngestJobId
|
||||
* @param dataSource
|
||||
* @param eventType The event string for the subtype.
|
||||
* @param ingestJobId The identifier of the ingest job, specific to this
|
||||
* node.
|
||||
* @param dataSourceIngestJobId The identifier of the data source ingest
|
||||
* job,specific to this node.
|
||||
* @param dataSource The data source.
|
||||
*/
|
||||
public DataSourceAnalysisEvent(IngestManager.IngestJobEvent eventType, long ingestJobId, long dataSourceIngestJobId, Content dataSource) {
|
||||
super(eventType.toString(), null, null);
|
||||
@@ -49,29 +58,50 @@ public abstract class DataSourceAnalysisEvent extends AutopsyEvent implements Se
|
||||
}
|
||||
|
||||
/**
|
||||
* RJCTODO
|
||||
* Gets the id of the ingest job of which the analysis of this data source
|
||||
* is a part.
|
||||
*
|
||||
* @return
|
||||
* @return The id.
|
||||
*/
|
||||
public long getIngestJobId() {
|
||||
return ingestJobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* RJCTODO
|
||||
* Gets the id of the data source ingest job of which the analysis of this
|
||||
* data source is a part.
|
||||
*
|
||||
* @return
|
||||
* @return The id.
|
||||
*/
|
||||
public long getDataSourceIngestJobId() {
|
||||
return dataSourceIngestJobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* RJCTODO
|
||||
* Gets the data source associated with this event.
|
||||
*
|
||||
* @return
|
||||
* @return The data source.
|
||||
*/
|
||||
public Content getDataSource() {
|
||||
return dataSource;
|
||||
/**
|
||||
* The dataSource field is set in the constructor, but it is transient
|
||||
* so it will become null when the event is serialized for publication
|
||||
* over a network. Doing a lazy load of the Content object bypasses the
|
||||
* issues related to the serialization and de-serialization of Content
|
||||
* objects and may also save database round trips from other nodes since
|
||||
* subscribers to this event are often not interested in the event data.
|
||||
*/
|
||||
if (null != dataSource) {
|
||||
return dataSource;
|
||||
}
|
||||
try {
|
||||
long id = (Long) super.getNewValue();
|
||||
dataSource = Case.getCurrentCase().getSleuthkitCase().getContentById(id);
|
||||
return dataSource;
|
||||
} catch (IllegalStateException | TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error doing lazy load for remote event", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,14 +23,25 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
|
||||
/**
|
||||
* RJCTODO
|
||||
* Event published when analysis (ingest) of a data source included in an ingest
|
||||
* job is started.
|
||||
*/
|
||||
public class DataSourceAnalysisStartedEvent extends DataSourceAnalysisEvent implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs an event published when analysis (ingest) of a data source
|
||||
* included in an ingest job is started.
|
||||
*
|
||||
* @param ingestJobId The identifier of the ingest job, specific to this
|
||||
* node.
|
||||
* @param dataSourceIngestJobId The identifier of the data source ingest
|
||||
* job,specific to this node.
|
||||
* @param dataSource The data source.
|
||||
*/
|
||||
public DataSourceAnalysisStartedEvent(long ingestJobId, long dataSourceIngestJobId, Content dataSource) {
|
||||
super(IngestManager.IngestJobEvent.DATA_SOURCE_ANALYSIS_STARTED, ingestJobId, dataSourceIngestJobId, dataSource);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user