updates to handle ingest events

This commit is contained in:
Greg DiCristofaro 2020-09-16 12:04:31 -04:00
parent 840569f2c0
commit ada91b260e
8 changed files with 141 additions and 12 deletions

View File

@ -20,10 +20,13 @@ package org.sleuthkit.autopsy.datasourcesummary.datamodel;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -35,6 +38,9 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
private final SleuthkitCaseProvider provider; private final SleuthkitCaseProvider provider;
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
Arrays.asList(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED));
/** /**
* Main constructor. * Main constructor.
*/ */
@ -56,6 +62,16 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
return true; return true;
} }
@Override
public boolean isRefreshRequired(IngestManager.IngestJobEvent evt) {
return (evt != null && INGEST_JOB_EVENTS.contains(evt));
}
@Override
public Set<IngestManager.IngestJobEvent> getIngestJobEventUpdates() {
return INGEST_JOB_EVENTS;
}
/** /**
* Get the number of files in the case database for the current data source * Get the number of files in the case database for the current data source
* which have the specified mimetypes. * which have the specified mimetypes.

View File

@ -20,7 +20,11 @@ package org.sleuthkit.autopsy.datasourcesummary.datamodel;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultUpdateGovernor;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -31,6 +35,9 @@ import org.sleuthkit.datamodel.TskData;
*/ */
public class TypesSummary implements DefaultUpdateGovernor { public class TypesSummary implements DefaultUpdateGovernor {
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
Arrays.asList(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED));
private final SleuthkitCaseProvider provider; private final SleuthkitCaseProvider provider;
/** /**
@ -54,6 +61,16 @@ public class TypesSummary implements DefaultUpdateGovernor {
return true; return true;
} }
@Override
public boolean isRefreshRequired(IngestManager.IngestJobEvent evt) {
return (evt != null && INGEST_JOB_EVENTS.contains(evt));
}
@Override
public Set<IngestManager.IngestJobEvent> getIngestJobEventUpdates() {
return INGEST_JOB_EVENTS;
}
/** /**
* Get count of regular files (not directories) in a data source. * Get count of regular files (not directories) in a data source.
* *

View File

@ -36,6 +36,7 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.EventUpdateHandler;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent; import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.SwingWorkerSequentialExecutor; import org.sleuthkit.autopsy.datasourcesummary.uiutils.SwingWorkerSequentialExecutor;
import org.sleuthkit.autopsy.datasourcesummary.uiutils.UpdateGovernor; import org.sleuthkit.autopsy.datasourcesummary.uiutils.UpdateGovernor;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
@ -139,6 +140,17 @@ abstract class BaseDataSourceSummaryPanel extends JPanel {
return false; return false;
} }
@Override
public boolean isRefreshRequired(IngestJobEvent evt) {
for (UpdateGovernor governor : governors) {
if (governor.isRefreshRequired(evt)) {
return true;
}
}
return false;
}
@Override @Override
public boolean isRefreshRequiredForCaseEvent(PropertyChangeEvent evt) { public boolean isRefreshRequiredForCaseEvent(PropertyChangeEvent evt) {
for (UpdateGovernor governor : governors) { for (UpdateGovernor governor : governors) {
@ -158,6 +170,15 @@ abstract class BaseDataSourceSummaryPanel extends JPanel {
.flatMap(governor -> governor.getCaseEventUpdates().stream()) .flatMap(governor -> governor.getCaseEventUpdates().stream())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@Override
public Set<IngestJobEvent> getIngestJobEventUpdates() {
// return the union of all case events sets from delegates.
return governors.stream()
.filter(governor -> governor.getIngestJobEventUpdates() != null)
.flatMap(governor -> governor.getIngestJobEventUpdates().stream())
.collect(Collectors.toSet());
}
}; };
/** /**

View File

@ -71,6 +71,7 @@ public class DataFetchWorker<A, R> extends SwingWorker<R, Void> {
} }
private static final Logger logger = Logger.getLogger(DataFetchWorker.class.getName()); private static final Logger logger = Logger.getLogger(DataFetchWorker.class.getName());
private static final int MAX_INNER_EXCEPTION_DEPTH = 100;
private final A args; private final A args;
private final DataFetcher<A, R> processor; private final DataFetcher<A, R> processor;
@ -128,9 +129,15 @@ public class DataFetchWorker<A, R> extends SwingWorker<R, Void> {
return; return;
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
Throwable inner = ex.getCause(); Throwable inner = ex.getCause();
// if cancelled during operation, simply return for (int i = 0; i < MAX_INNER_EXCEPTION_DEPTH; i++) {
if (inner instanceof InterruptedException) { if (inner == null) {
return; break;
} else if (inner instanceof InterruptedException) {
// if cancelled during operation, simply return
return;
} else {
inner = inner.getCause();
}
} }
// otherwise, there is an error to log // otherwise, there is an error to log

View File

@ -18,7 +18,11 @@
*/ */
package org.sleuthkit.autopsy.datasourcesummary.uiutils; package org.sleuthkit.autopsy.datasourcesummary.uiutils;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
/** /**
@ -27,11 +31,24 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
*/ */
public interface DefaultArtifactUpdateGovernor extends DefaultUpdateGovernor { public interface DefaultArtifactUpdateGovernor extends DefaultUpdateGovernor {
static final Set<IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
Arrays.asList(IngestJobEvent.COMPLETED, IngestJobEvent.CANCELLED));
@Override @Override
default boolean isRefreshRequired(ModuleDataEvent evt) { default boolean isRefreshRequired(ModuleDataEvent evt) {
return getArtifactTypeIdsForRefresh().contains(evt.getBlackboardArtifactType().getTypeID()); return getArtifactTypeIdsForRefresh().contains(evt.getBlackboardArtifactType().getTypeID());
} }
@Override
default boolean isRefreshRequired(IngestManager.IngestJobEvent evt) {
return (evt != null && INGEST_JOB_EVENTS.contains(evt));
}
@Override
default Set<IngestJobEvent> getIngestJobEventUpdates() {
return INGEST_JOB_EVENTS;
}
/** /**
* @return The set of artifact type id's that should trigger an update. * @return The set of artifact type id's that should trigger an update.
*/ */

View File

@ -22,6 +22,7 @@ import java.beans.PropertyChangeEvent;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@ -46,9 +47,18 @@ public interface DefaultUpdateGovernor extends UpdateGovernor {
return false; return false;
} }
@Override
default boolean isRefreshRequired(IngestManager.IngestJobEvent evt) {
return false;
}
@Override @Override
default Set<Case.Events> getCaseEventUpdates() { default Set<Case.Events> getCaseEventUpdates() {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override
default Set<IngestManager.IngestJobEvent> getIngestJobEventUpdates() {
return Collections.emptySet();
}
} }

View File

@ -24,6 +24,7 @@ import java.util.Set;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.guiutils.RefreshThrottler; import org.sleuthkit.autopsy.guiutils.RefreshThrottler;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@ -68,17 +69,31 @@ public class EventUpdateHandler {
} }
}; };
private final PropertyChangeListener ingestJobEventsListener = (evt) -> {
if (evt == null) {
return;
}
String eventName = evt.getPropertyName();
for (IngestJobEvent ingestEvt : IngestJobEvent.values()) {
if (ingestEvt.name().equals(eventName) && isRefreshRequired(ingestEvt)) {
onRefresh();
}
}
};
private final UpdateGovernor governor; private final UpdateGovernor governor;
private final Set<Case.Events> caseEvents; private final Set<Case.Events> caseEvents;
private final Set<IngestJobEvent> ingestEvents;
private final Runnable onUpdate; private final Runnable onUpdate;
/** /**
* Constructor. * Constructor.
* *
* @param onUpdate The function to call if an update should be required. * @param onUpdate The function to call if an update should be required.
* @param governor The item used to determine if an update is required. If * @param governor The item used to determine if an update is required. If
* the governor requires an update, then onUpdate is * the governor requires an update, then onUpdate is
* triggered. * triggered.
*/ */
public EventUpdateHandler(Runnable onUpdate, UpdateGovernor governor) { public EventUpdateHandler(Runnable onUpdate, UpdateGovernor governor) {
if (onUpdate == null) { if (onUpdate == null) {
@ -88,7 +103,7 @@ public class EventUpdateHandler {
this.onUpdate = onUpdate; this.onUpdate = onUpdate;
this.governor = governor; this.governor = governor;
this.caseEvents = governor.getCaseEventUpdates(); this.caseEvents = governor.getCaseEventUpdates();
this.ingestEvents = governor.getIngestJobEventUpdates();
} }
/** /**
@ -113,6 +128,17 @@ public class EventUpdateHandler {
return governor.isRefreshRequired(evt); return governor.isRefreshRequired(evt);
} }
/**
* Handles whether or not a IngestJobEvent should trigger an update.
*
* @param evt The IngestJobEvent.
*
* @return True if an update should occur.
*/
protected boolean isRefreshRequired(IngestJobEvent evt) {
return governor.isRefreshRequired(evt);
}
/** /**
* Handles whether or not a case event should trigger an update. * Handles whether or not a case event should trigger an update.
* *
@ -139,6 +165,7 @@ public class EventUpdateHandler {
Case.addEventTypeSubscriber(caseEvents, caseEventsListener); Case.addEventTypeSubscriber(caseEvents, caseEventsListener);
} }
IngestManager.getInstance().addIngestJobEventListener(ingestEvents, ingestJobEventsListener);
refreshThrottler.registerForIngestModuleEvents(); refreshThrottler.registerForIngestModuleEvents();
} }
@ -150,6 +177,7 @@ public class EventUpdateHandler {
Case.removeEventTypeSubscriber(caseEvents, caseEventsListener); Case.removeEventTypeSubscriber(caseEvents, caseEventsListener);
} }
IngestManager.getInstance().removeIngestJobEventListener(ingestEvents, ingestJobEventsListener);
refreshThrottler.unregisterEventListener(); refreshThrottler.unregisterEventListener();
} }
} }

View File

@ -19,9 +19,9 @@
package org.sleuthkit.autopsy.datasourcesummary.uiutils; package org.sleuthkit.autopsy.datasourcesummary.uiutils;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.Collections;
import java.util.Set; import java.util.Set;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent; import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@ -34,9 +34,12 @@ public interface UpdateGovernor {
/** /**
* @return The set of Case Events for which data should be updated. * @return The set of Case Events for which data should be updated.
*/ */
default Set<Case.Events> getCaseEventUpdates() { Set<Case.Events> getCaseEventUpdates();
return Collections.emptySet();
} /**
* @return The set of Ingest Job Events for which data should be updated.
*/
Set<IngestJobEvent> getIngestJobEventUpdates();
/** /**
* Given a module data event, whether or not an update should occur. * Given a module data event, whether or not an update should occur.
@ -56,6 +59,16 @@ public interface UpdateGovernor {
*/ */
boolean isRefreshRequired(ModuleContentEvent evt); boolean isRefreshRequired(ModuleContentEvent evt);
/**
* Given an ingest job event, determines whether or not an update should
* occur.
*
* @param evt The event.
*
* @return Whether or not this event should trigger an update.
*/
boolean isRefreshRequired(IngestJobEvent evt);
/** /**
* Given a case event, whether or not an update should occur. * Given a case event, whether or not an update should occur.
* *