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 java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
@ -35,6 +38,9 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
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.
*/
@ -56,6 +62,16 @@ public class MimeTypeSummary implements DefaultUpdateGovernor {
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
* 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 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.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
@ -31,6 +35,9 @@ import org.sleuthkit.datamodel.TskData;
*/
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;
/**
@ -54,6 +61,16 @@ public class TypesSummary implements DefaultUpdateGovernor {
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.
*

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.SwingWorkerSequentialExecutor;
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.ModuleDataEvent;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ -139,6 +140,17 @@ abstract class BaseDataSourceSummaryPanel extends JPanel {
return false;
}
@Override
public boolean isRefreshRequired(IngestJobEvent evt) {
for (UpdateGovernor governor : governors) {
if (governor.isRefreshRequired(evt)) {
return true;
}
}
return false;
}
@Override
public boolean isRefreshRequiredForCaseEvent(PropertyChangeEvent evt) {
for (UpdateGovernor governor : governors) {
@ -158,6 +170,15 @@ abstract class BaseDataSourceSummaryPanel extends JPanel {
.flatMap(governor -> governor.getCaseEventUpdates().stream())
.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 int MAX_INNER_EXCEPTION_DEPTH = 100;
private final A args;
private final DataFetcher<A, R> processor;
@ -128,9 +129,15 @@ public class DataFetchWorker<A, R> extends SwingWorker<R, Void> {
return;
} catch (ExecutionException ex) {
Throwable inner = ex.getCause();
// if cancelled during operation, simply return
if (inner instanceof InterruptedException) {
return;
for (int i = 0; i < MAX_INNER_EXCEPTION_DEPTH; i++) {
if (inner == null) {
break;
} else if (inner instanceof InterruptedException) {
// if cancelled during operation, simply return
return;
} else {
inner = inner.getCause();
}
}
// otherwise, there is an error to log

View File

@ -18,7 +18,11 @@
*/
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
/**
@ -27,11 +31,24 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
*/
public interface DefaultArtifactUpdateGovernor extends DefaultUpdateGovernor {
static final Set<IngestJobEvent> INGEST_JOB_EVENTS = new HashSet<>(
Arrays.asList(IngestJobEvent.COMPLETED, IngestJobEvent.CANCELLED));
@Override
default boolean isRefreshRequired(ModuleDataEvent evt) {
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.
*/

View File

@ -22,6 +22,7 @@ import java.beans.PropertyChangeEvent;
import java.util.Collections;
import java.util.Set;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
@ -46,9 +47,18 @@ public interface DefaultUpdateGovernor extends UpdateGovernor {
return false;
}
@Override
default boolean isRefreshRequired(IngestManager.IngestJobEvent evt) {
return false;
}
@Override
default Set<Case.Events> getCaseEventUpdates() {
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.guiutils.RefreshThrottler;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
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 Set<Case.Events> caseEvents;
private final Set<IngestJobEvent> ingestEvents;
private final Runnable onUpdate;
/**
* 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
* the governor requires an update, then onUpdate is
* triggered.
* the governor requires an update, then onUpdate is
* triggered.
*/
public EventUpdateHandler(Runnable onUpdate, UpdateGovernor governor) {
if (onUpdate == null) {
@ -88,7 +103,7 @@ public class EventUpdateHandler {
this.onUpdate = onUpdate;
this.governor = governor;
this.caseEvents = governor.getCaseEventUpdates();
this.ingestEvents = governor.getIngestJobEventUpdates();
}
/**
@ -113,6 +128,17 @@ public class EventUpdateHandler {
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.
*
@ -139,6 +165,7 @@ public class EventUpdateHandler {
Case.addEventTypeSubscriber(caseEvents, caseEventsListener);
}
IngestManager.getInstance().addIngestJobEventListener(ingestEvents, ingestJobEventsListener);
refreshThrottler.registerForIngestModuleEvents();
}
@ -149,7 +176,8 @@ public class EventUpdateHandler {
if (!caseEvents.isEmpty()) {
Case.removeEventTypeSubscriber(caseEvents, caseEventsListener);
}
IngestManager.getInstance().removeIngestJobEventListener(ingestEvents, ingestJobEventsListener);
refreshThrottler.unregisterEventListener();
}
}

View File

@ -19,9 +19,9 @@
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
import java.beans.PropertyChangeEvent;
import java.util.Collections;
import java.util.Set;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.ingest.IngestManager.IngestJobEvent;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
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.
*/
default Set<Case.Events> getCaseEventUpdates() {
return Collections.emptySet();
}
Set<Case.Events> getCaseEventUpdates();
/**
* @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.
@ -56,6 +59,16 @@ public interface UpdateGovernor {
*/
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.
*