introduce TimelineCacheException and throw it instead of ExecutionException

This commit is contained in:
millmanorama
2018-05-10 13:35:53 +02:00
parent ae55e5b5f6
commit b9872c8f61
3 changed files with 98 additions and 52 deletions
@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import static java.util.Objects.isNull;
@@ -37,7 +38,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
@@ -194,41 +194,55 @@ public class EventsRepository {
/**
* @return min time (in seconds from unix epoch)
*/
public Long getMaxTime() {
return maxCache.getUnchecked("max"); // NON-NLS
public Long getMaxTime() throws TimelineCacheException {
try {
return maxCache.get("max"); // NON-NLS
} catch (ExecutionException ex) {
throw new TimelineCacheException("Error getting cached max time", ex); // NON-NLS
}
}
/**
* @return max tie (in seconds from unix epoch)
*/
public Long getMinTime() {
return minCache.getUnchecked("min"); // NON-NLS
}
public SingleEvent getEventById(Long eventID) {
return idToEventCache.getUnchecked(eventID);
}
synchronized public Set<SingleEvent> getEventsById(Collection<Long> eventIDs) {
return eventIDs.stream()
.map(idToEventCache::getUnchecked)
.collect(Collectors.toSet());
}
synchronized public List<EventStripe> getEventStripes(ZoomParams params) {
public Long getMinTime() throws TimelineCacheException {
try {
return eventStripeCache.get(params);
return minCache.get("min"); // NON-NLS
} catch (ExecutionException ex) {
logger.log(Level.SEVERE, "Failed to load Event Stripes from cache for " + params.toString(), ex); //NON-NLS
return Collections.emptyList();
throw new TimelineCacheException("Error getting cached min time", ex); // NON-NLS
}
}
synchronized public Map<EventType, Long> countEvents(ZoomParams params) throws ExecutionException {
return eventCountsCache.get(params);
public SingleEvent getEventById(Long eventID) throws TimelineCacheException {
try {
return idToEventCache.get(eventID);
} catch (ExecutionException ex) {
throw new TimelineCacheException("Error getting cached event from id " + eventID, ex); // NON-NLS
}
}
synchronized public Set<SingleEvent> getEventsById(Collection<Long> eventIDs) throws TimelineCacheException {
HashSet<SingleEvent> events = new HashSet<>();
for (Long eventID : eventIDs) {
events.add(getEventById(eventID));
}
return events;
}
synchronized public List<EventStripe> getEventStripes(ZoomParams params) throws TimelineCacheException {
try {
return eventStripeCache.get(params);
} catch (ExecutionException ex) {
throw new TimelineCacheException("Failed to load Event Stripes from cache for " + params.toString(), ex); //NON-NLS
}
}
synchronized public Map<EventType, Long> countEvents(ZoomParams params) throws TimelineCacheException {
try {
return eventCountsCache.get(params);
} catch (ExecutionException ex) {
throw new TimelineCacheException("Failed to load event counts from cache for " + params.toString(), ex); //NON-NLS
}
}
synchronized public int countAllEvents() throws TskCoreException {
@@ -678,9 +692,9 @@ public class EventsRepository {
for (Map.Entry<FileSystemTypes, Long> timeEntry : timeMap.entrySet()) {
if (timeEntry.getValue() > 0) {
// if the time is legitimate ( greater than zero ) insert it
eventManager.insertEvent(timeEntry.getValue(), timeEntry.getKey(),
eventManager.addEvent(timeEntry.getValue(), timeEntry.getKey(),
datasourceID, f.getId(), null, uniquePath, medDesc,
shortDesc, known, hashSets, tags);
shortDesc, known, hashSets.isEmpty() == false, tags.isEmpty() == false);
}
}
}
@@ -743,7 +757,7 @@ public class EventsRepository {
String fullDescription = eventDescription.getFullDescription();
String medDescription = eventDescription.getMedDescription();
String shortDescription = eventDescription.getShortDescription();
eventManager.insertEvent(eventDescription.getTime(), type, datasourceID, objectID, artifactID, fullDescription, medDescription, shortDescription, null, hashSets, tags);
eventManager.addEvent(eventDescription.getTime(), type, datasourceID, objectID, artifactID, fullDescription, medDescription, shortDescription, null, hashSets.isEmpty() == false, tags.isEmpty() == false);
}
}
}
@@ -24,7 +24,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javafx.beans.Observable;
import javafx.beans.property.ReadOnlyObjectProperty;
@@ -48,6 +47,21 @@ import org.sleuthkit.autopsy.timeline.events.DBUpdatedEvent;
import org.sleuthkit.autopsy.timeline.events.RefreshRequestedEvent;
import org.sleuthkit.autopsy.timeline.events.TagsAddedEvent;
import org.sleuthkit.autopsy.timeline.events.TagsDeletedEvent;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.timeline.CombinedEvent;
import org.sleuthkit.datamodel.timeline.DescriptionLoD;
import org.sleuthkit.datamodel.timeline.EventStripe;
import org.sleuthkit.datamodel.timeline.EventType;
import org.sleuthkit.datamodel.timeline.EventTypeZoomLevel;
import org.sleuthkit.datamodel.timeline.RootEventType;
import org.sleuthkit.datamodel.timeline.SingleEvent;
import org.sleuthkit.datamodel.timeline.ZoomParams;
import org.sleuthkit.datamodel.timeline.filters.DataSourceFilter;
import org.sleuthkit.datamodel.timeline.filters.DataSourcesFilter;
import org.sleuthkit.datamodel.timeline.filters.Filter;
@@ -59,21 +73,6 @@ import org.sleuthkit.datamodel.timeline.filters.TagNameFilter;
import org.sleuthkit.datamodel.timeline.filters.TagsFilter;
import org.sleuthkit.datamodel.timeline.filters.TextFilter;
import org.sleuthkit.datamodel.timeline.filters.TypeFilter;
import org.sleuthkit.datamodel.timeline.DescriptionLoD;
import org.sleuthkit.datamodel.timeline.ZoomParams;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.timeline.CombinedEvent;
import org.sleuthkit.datamodel.timeline.EventStripe;
import org.sleuthkit.datamodel.timeline.EventType;
import org.sleuthkit.datamodel.timeline.EventTypeZoomLevel;
import org.sleuthkit.datamodel.timeline.RootEventType;
import org.sleuthkit.datamodel.timeline.SingleEvent;
/**
* This class acts as the model for a TimelineView
@@ -83,8 +82,8 @@ import org.sleuthkit.datamodel.timeline.SingleEvent;
* This class is implemented as a filtered view into an underlying
* EventsRepository.
*
* Maintainers, NOTE: as many methods as possible should cache their results
* so as to avoid unnecessary db calls through the EventsRepository -jm
* Maintainers, NOTE: as many methods as possible should cache their results so
* as to avoid unnecessary db calls through the EventsRepository -jm
*
* Concurrency Policy: repo is internally synchronized, so methods that only
* access the repo atomically do not need further synchronization
@@ -318,7 +317,7 @@ public final class FilteredEventsModel {
*
* @return
*/
public Map<EventType, Long> getEventCounts(Interval timeRange) throws ExecutionException {
public Map<EventType, Long> getEventCounts(Interval timeRange) throws TimelineCacheException {
final RootFilter filter;
final EventTypeZoomLevel typeZoom;
@@ -349,7 +348,7 @@ public final class FilteredEventsModel {
* event available from the repository, ignoring any filters or
* requested ranges
*/
public Long getMinTime() {
public Long getMinTime() throws TimelineCacheException {
return repo.getMinTime();
}
@@ -358,7 +357,7 @@ public final class FilteredEventsModel {
* event available from the repository, ignoring any filters or
* requested ranges
*/
public Long getMaxTime() {
public Long getMaxTime() throws TimelineCacheException {
return repo.getMaxTime();
}
@@ -367,7 +366,7 @@ public final class FilteredEventsModel {
* @return a list of event clusters at the requested zoom levels that are
* within the requested time range and pass the requested filter
*/
public List<EventStripe> getEventStripes() {
public List<EventStripe> getEventStripes() throws TimelineCacheException {
final Interval range;
final RootFilter filter;
final EventTypeZoomLevel zoom;
@@ -388,7 +387,7 @@ public final class FilteredEventsModel {
* range and pass the requested filter, using the given aggregation
* to control the grouping of events
*/
public List<EventStripe> getEventStripes(ZoomParams params) {
public List<EventStripe> getEventStripes(ZoomParams params) throws TimelineCacheException {
return repo.getEventStripes(params);
}
@@ -0,0 +1,33 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2018 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.timeline.datamodel;
/**
* Exception thown when there is an error loading a cached value.
*
* NOTE: This should probably not be a RuntimeException. But the ripple effect
* of introducing this as a checked exception was spreading extremely far.
*
*/
public class TimelineCacheException extends RuntimeException {
public TimelineCacheException(String message, Throwable cause) {
super(message, cause);
}
}