Merge branch 'develop' of https://github.com/sleuthkit/autopsy into develop
@ -47,7 +47,7 @@ public interface EventBundle<ParentType extends EventBundle<?>> {
|
|||||||
|
|
||||||
Optional<ParentType> getParentBundle();
|
Optional<ParentType> getParentBundle();
|
||||||
|
|
||||||
default long getCount() {
|
default int getCount() {
|
||||||
return getEventIDs().size();
|
return getEventIDs().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.datamodel;
|
package org.sleuthkit.autopsy.timeline.datamodel;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -89,28 +89,28 @@ public class EventCluster implements EventBundle<EventStripe> {
|
|||||||
/**
|
/**
|
||||||
* the set of ids of the clustered events
|
* the set of ids of the clustered events
|
||||||
*/
|
*/
|
||||||
final private Set<Long> eventIDs;
|
final private ImmutableSet<Long> eventIDs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the ids of the subset of clustered events that have at least one tag
|
* the ids of the subset of clustered events that have at least one tag
|
||||||
* applied to them
|
* applied to them
|
||||||
*/
|
*/
|
||||||
private final Set<Long> tagged;
|
private final ImmutableSet<Long> tagged;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the ids of the subset of clustered events that have at least one hash set
|
* the ids of the subset of clustered events that have at least one hash set
|
||||||
* hit
|
* hit
|
||||||
*/
|
*/
|
||||||
private final Set<Long> hashHits;
|
private final ImmutableSet<Long> hashHits;
|
||||||
|
|
||||||
private EventCluster(Interval spanningInterval, EventType type, Set<Long> eventIDs, Set<Long> hashHits, Set<Long> tagged, String description, DescriptionLoD lod, EventStripe parent) {
|
private EventCluster(Interval spanningInterval, EventType type, Set<Long> eventIDs, Set<Long> hashHits, Set<Long> tagged, String description, DescriptionLoD lod, EventStripe parent) {
|
||||||
|
|
||||||
this.span = spanningInterval;
|
this.span = spanningInterval;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.hashHits = hashHits;
|
this.hashHits = ImmutableSet.copyOf(hashHits);
|
||||||
this.tagged = tagged;
|
this.tagged = ImmutableSet.copyOf(tagged);
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.eventIDs = eventIDs;
|
this.eventIDs = ImmutableSet.copyOf(eventIDs);
|
||||||
this.lod = lod;
|
this.lod = lod;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
@ -139,18 +139,21 @@ public class EventCluster implements EventBundle<EventStripe> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getEventIDs() {
|
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||||
return Collections.unmodifiableSet(eventIDs);
|
public ImmutableSet<Long> getEventIDs() {
|
||||||
|
return eventIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getEventIDsWithHashHits() {
|
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||||
return Collections.unmodifiableSet(hashHits);
|
public ImmutableSet<Long> getEventIDsWithHashHits() {
|
||||||
|
return hashHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getEventIDsWithTags() {
|
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||||
return Collections.unmodifiableSet(tagged);
|
public ImmutableSet<Long> getEventIDsWithTags() {
|
||||||
|
return tagged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,13 +19,11 @@
|
|||||||
package org.sleuthkit.autopsy.timeline.datamodel;
|
package org.sleuthkit.autopsy.timeline.datamodel;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import java.util.Collections;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import org.python.google.common.base.Objects;
|
import org.python.google.common.base.Objects;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
import org.sleuthkit.autopsy.timeline.datamodel.eventtype.EventType;
|
||||||
@ -50,7 +48,7 @@ public final class EventStripe implements EventBundle<EventCluster> {
|
|||||||
|
|
||||||
private final EventCluster parent;
|
private final EventCluster parent;
|
||||||
|
|
||||||
private final SortedSet<EventCluster> clusters = new TreeSet<>(Comparator.comparing(EventCluster::getStartMillis));
|
private final ImmutableSortedSet<EventCluster> clusters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the type of all the events
|
* the type of all the events
|
||||||
@ -70,59 +68,70 @@ public final class EventStripe implements EventBundle<EventCluster> {
|
|||||||
/**
|
/**
|
||||||
* the set of ids of the events
|
* the set of ids of the events
|
||||||
*/
|
*/
|
||||||
private final Set<Long> eventIDs = new HashSet<>();
|
private final ImmutableSet<Long> eventIDs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the ids of the subset of events that have at least one tag applied to
|
* the ids of the subset of events that have at least one tag applied to
|
||||||
* them
|
* them
|
||||||
*/
|
*/
|
||||||
private final Set<Long> tagged = new HashSet<>();
|
private final ImmutableSet<Long> tagged;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the ids of the subset of events that have at least one hash set hit
|
* the ids of the subset of events that have at least one hash set hit
|
||||||
*/
|
*/
|
||||||
private final Set<Long> hashHits = new HashSet<>();
|
private final ImmutableSet<Long> hashHits;
|
||||||
|
|
||||||
public EventStripe withParent(EventCluster parent) {
|
public EventStripe withParent(EventCluster parent) {
|
||||||
EventStripe eventStripe = new EventStripe(parent, this.type, this.description, this.lod);
|
EventStripe eventStripe = new EventStripe(parent, this.type, this.description, this.lod, clusters, eventIDs, tagged, hashHits);
|
||||||
eventStripe.clusters.addAll(clusters);
|
|
||||||
eventStripe.eventIDs.addAll(eventIDs);
|
|
||||||
eventStripe.tagged.addAll(tagged);
|
|
||||||
eventStripe.hashHits.addAll(hashHits);
|
|
||||||
return eventStripe;
|
return eventStripe;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventStripe(EventCluster parent, EventType type, String description, DescriptionLoD lod) {
|
private EventStripe(EventCluster parent, EventType type, String description, DescriptionLoD lod, SortedSet<EventCluster> clusters, ImmutableSet<Long> eventIDs, ImmutableSet<Long> tagged, ImmutableSet<Long> hashHits) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.lod = lod;
|
this.lod = lod;
|
||||||
|
this.clusters = ImmutableSortedSet.copyOf(Comparator.comparing(EventCluster::getStartMillis), clusters);
|
||||||
|
|
||||||
|
this.eventIDs = eventIDs;
|
||||||
|
this.tagged = tagged;
|
||||||
|
this.hashHits = hashHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventStripe(EventCluster cluster, EventCluster parent) {
|
public EventStripe(EventCluster cluster, EventCluster parent) {
|
||||||
clusters.add(cluster);
|
this.clusters = ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis))
|
||||||
|
.add(cluster).build();
|
||||||
|
|
||||||
type = cluster.getEventType();
|
type = cluster.getEventType();
|
||||||
description = cluster.getDescription();
|
description = cluster.getDescription();
|
||||||
lod = cluster.getDescriptionLoD();
|
lod = cluster.getDescriptionLoD();
|
||||||
eventIDs.addAll(cluster.getEventIDs());
|
eventIDs = cluster.getEventIDs();
|
||||||
tagged.addAll(cluster.getEventIDsWithTags());
|
tagged = cluster.getEventIDsWithTags();
|
||||||
hashHits.addAll(cluster.getEventIDsWithHashHits());
|
hashHits = cluster.getEventIDsWithHashHits();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventStripe(EventStripe u, EventStripe v) {
|
private EventStripe(EventStripe u, EventStripe v) {
|
||||||
clusters.addAll(u.clusters);
|
clusters = ImmutableSortedSet.orderedBy(Comparator.comparing(EventCluster::getStartMillis))
|
||||||
clusters.addAll(v.clusters);
|
.addAll(u.getClusters())
|
||||||
|
.addAll(v.getClusters())
|
||||||
|
.build();
|
||||||
|
|
||||||
type = u.getEventType();
|
type = u.getEventType();
|
||||||
description = u.getDescription();
|
description = u.getDescription();
|
||||||
lod = u.getDescriptionLoD();
|
lod = u.getDescriptionLoD();
|
||||||
eventIDs.addAll(u.getEventIDs());
|
eventIDs = ImmutableSet.<Long>builder()
|
||||||
eventIDs.addAll(v.getEventIDs());
|
.addAll(u.getEventIDs())
|
||||||
tagged.addAll(u.getEventIDsWithTags());
|
.addAll(v.getEventIDs())
|
||||||
tagged.addAll(v.getEventIDsWithTags());
|
.build();
|
||||||
hashHits.addAll(u.getEventIDsWithHashHits());
|
tagged = ImmutableSet.<Long>builder()
|
||||||
hashHits.addAll(v.getEventIDsWithHashHits());
|
.addAll(u.getEventIDsWithTags())
|
||||||
|
.addAll(v.getEventIDsWithTags())
|
||||||
|
.build();
|
||||||
|
hashHits = ImmutableSet.<Long>builder()
|
||||||
|
.addAll(u.getEventIDsWithHashHits())
|
||||||
|
.addAll(v.getEventIDsWithHashHits())
|
||||||
|
.build();
|
||||||
parent = u.getParentBundle().orElse(v.getParentBundle().orElse(null));
|
parent = u.getParentBundle().orElse(v.getParentBundle().orElse(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,18 +156,21 @@ public final class EventStripe implements EventBundle<EventCluster> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getEventIDs() {
|
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||||
return Collections.unmodifiableSet(eventIDs);
|
public ImmutableSet<Long> getEventIDs() {
|
||||||
|
return eventIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getEventIDsWithHashHits() {
|
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||||
return Collections.unmodifiableSet(hashHits);
|
public ImmutableSet<Long> getEventIDsWithHashHits() {
|
||||||
|
return hashHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getEventIDsWithTags() {
|
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||||
return Collections.unmodifiableSet(tagged);
|
public ImmutableSet<Long> getEventIDsWithTags() {
|
||||||
|
return tagged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -172,14 +184,13 @@ public final class EventStripe implements EventBundle<EventCluster> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SortedSet< EventCluster> getClusters() {
|
@SuppressWarnings("ReturnOfCollectionOrArrayField")
|
||||||
return Collections.unmodifiableSortedSet(clusters);
|
public ImmutableSortedSet< EventCluster> getClusters() {
|
||||||
|
return clusters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "EventStripe{" + "description=" + description + ", eventIDs=" + eventIDs.size() + '}';
|
return "EventStripe{" + "description=" + description + ", eventIDs=" + eventIDs.size() + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.timeline.ui.detailview;
|
package org.sleuthkit.autopsy.timeline.ui.detailview;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -32,7 +31,10 @@ import javafx.animation.KeyFrame;
|
|||||||
import javafx.animation.KeyValue;
|
import javafx.animation.KeyValue;
|
||||||
import javafx.animation.Timeline;
|
import javafx.animation.Timeline;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
@ -120,7 +122,7 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
final Background defaultBackground;
|
final Background defaultBackground;
|
||||||
final Color evtColor;
|
final Color evtColor;
|
||||||
|
|
||||||
final List<ParentNodeType> subNodes = new ArrayList<>();
|
final ObservableList<ParentNodeType> subNodes = FXCollections.observableArrayList();
|
||||||
final Pane subNodePane = new Pane();
|
final Pane subNodePane = new Pane();
|
||||||
final Label descrLabel = new Label();
|
final Label descrLabel = new Label();
|
||||||
final Label countLabel = new Label();
|
final Label countLabel = new Label();
|
||||||
@ -152,7 +154,11 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
|
|
||||||
setBackground(defaultBackground);
|
setBackground(defaultBackground);
|
||||||
setAlignment(Pos.TOP_LEFT);
|
setAlignment(Pos.TOP_LEFT);
|
||||||
|
setMaxWidth(USE_PREF_SIZE);
|
||||||
|
infoHBox.setMaxWidth(USE_PREF_SIZE);
|
||||||
|
subNodePane.setPrefWidth(USE_COMPUTED_SIZE);
|
||||||
|
subNodePane.setMinWidth(USE_PREF_SIZE);
|
||||||
|
subNodePane.setMaxWidth(USE_PREF_SIZE);
|
||||||
/*
|
/*
|
||||||
* This triggers the layout when a mousover causes the action buttons to
|
* This triggers the layout when a mousover causes the action buttons to
|
||||||
* interesect with another node, forcing it down.
|
* interesect with another node, forcing it down.
|
||||||
@ -185,6 +191,8 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
setOnMouseClicked(new ClickHandler());
|
setOnMouseClicked(new ClickHandler());
|
||||||
descVisibility.addListener(observable -> setDescriptionVisibiltiyImpl(descVisibility.get()));
|
descVisibility.addListener(observable -> setDescriptionVisibiltiyImpl(descVisibility.get()));
|
||||||
descVisibility.set(DescriptionVisibility.SHOWN); //trigger listener for initial value
|
descVisibility.set(DescriptionVisibility.SHOWN); //trigger listener for initial value
|
||||||
|
|
||||||
|
Bindings.bindContent(subNodePane.getChildren(), subNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
final DescriptionLoD getDescriptionLoD() {
|
final DescriptionLoD getDescriptionLoD() {
|
||||||
@ -342,6 +350,8 @@ public abstract class EventBundleNodeBase<BundleType extends EventBundle<ParentT
|
|||||||
super.layoutChildren();
|
super.layoutChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract ParentNodeType createChildNode(ParentType rawChild);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param w the maximum width the description label should have
|
* @param w the maximum width the description label should have
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +25,10 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import static java.util.Objects.nonNull;
|
import static java.util.Objects.nonNull;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
@ -45,7 +48,9 @@ import org.controlsfx.control.action.ActionUtils;
|
|||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.Interval;
|
import org.joda.time.Interval;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.LoggedTask;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
|
import org.sleuthkit.autopsy.timeline.datamodel.EventCluster;
|
||||||
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
import org.sleuthkit.autopsy.timeline.datamodel.EventStripe;
|
||||||
import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
import org.sleuthkit.autopsy.timeline.filters.DescriptionFilter;
|
||||||
@ -63,6 +68,25 @@ import org.sleuthkit.autopsy.timeline.zooming.ZoomParams;
|
|||||||
final public class EventClusterNode extends EventBundleNodeBase<EventCluster, EventStripe, EventStripeNode> {
|
final public class EventClusterNode extends EventBundleNodeBase<EventCluster, EventStripe, EventStripeNode> {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(EventClusterNode.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(EventClusterNode.class.getName());
|
||||||
|
/**
|
||||||
|
* Use this recursive function to flatten a tree of nodes into an single
|
||||||
|
* stream. More specifically it takes an EventStripeNode and produces a
|
||||||
|
* stream of EventStripes conaiting the stripes for the given node and all
|
||||||
|
* child eventStripes, ignoring intervening EventCluster nodes.
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* #loadSubBundles(org.sleuthkit.autopsy.timeline.zooming.DescriptionLoD.RelativeDetail)
|
||||||
|
* for usage
|
||||||
|
*/
|
||||||
|
private final static Function<EventStripeNode, Stream<EventStripe>> stripeFlattener = new Function<EventStripeNode, Stream<EventStripe>>() {
|
||||||
|
@Override
|
||||||
|
public Stream<EventStripe> apply(EventStripeNode node) {
|
||||||
|
return Stream.concat(
|
||||||
|
Stream.of(node.getEventStripe()),
|
||||||
|
node.getSubNodes().stream().flatMap(clusterNode -> clusterNode.getSubNodes().stream().flatMap(this)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static final BorderWidths CLUSTER_BORDER_WIDTHS = new BorderWidths(2, 1, 2, 1);
|
private static final BorderWidths CLUSTER_BORDER_WIDTHS = new BorderWidths(2, 1, 2, 1);
|
||||||
private static final Image PLUS = new Image("/org/sleuthkit/autopsy/timeline/images/plus-button.png"); // NON-NLS //NOI18N
|
private static final Image PLUS = new Image("/org/sleuthkit/autopsy/timeline/images/plus-button.png"); // NON-NLS //NOI18N
|
||||||
private static final Image MINUS = new Image("/org/sleuthkit/autopsy/timeline/images/minus-button.png"); // NON-NLS //NOI18N
|
private static final Image MINUS = new Image("/org/sleuthkit/autopsy/timeline/images/minus-button.png"); // NON-NLS //NOI18N
|
||||||
@ -89,6 +113,7 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
subNodePane.setBorder(clusterBorder);
|
subNodePane.setBorder(clusterBorder);
|
||||||
subNodePane.setBackground(defaultBackground);
|
subNodePane.setBackground(defaultBackground);
|
||||||
subNodePane.setMinWidth(1);
|
subNodePane.setMinWidth(1);
|
||||||
|
subNodePane.setMaxWidth(USE_PREF_SIZE);
|
||||||
setMinHeight(24);
|
setMinHeight(24);
|
||||||
setAlignment(Pos.CENTER_LEFT);
|
setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
@ -118,7 +143,7 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
||||||
final int size = getEventBundle().getEventIDs().size();
|
final int size = getEventCluster().getCount();
|
||||||
switch (descrVis) {
|
switch (descrVis) {
|
||||||
case HIDDEN:
|
case HIDDEN:
|
||||||
countLabel.setText("");
|
countLabel.setText("");
|
||||||
@ -142,10 +167,10 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
* @param expand
|
* @param expand
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages(value = "EventStripeNode.loggedTask.name=Load sub clusters")
|
@NbBundle.Messages(value = "EventStripeNode.loggedTask.name=Load sub clusters")
|
||||||
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private synchronized void loadSubBundles(DescriptionLoD.RelativeDetail relativeDetail) {
|
private synchronized void loadSubBundles(DescriptionLoD.RelativeDetail relativeDetail) {
|
||||||
chart.setCursor(Cursor.WAIT);
|
chart.setCursor(Cursor.WAIT);
|
||||||
chart.getEventStripes().removeAll(Lists.transform(subNodes, EventStripeNode::getEventStripe));
|
|
||||||
subNodes.clear();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make new ZoomParams to query with
|
* make new ZoomParams to query with
|
||||||
@ -159,14 +184,10 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
final EventTypeZoomLevel eventTypeZoomLevel = eventsModel.eventTypeZoomProperty().get();
|
final EventTypeZoomLevel eventTypeZoomLevel = eventsModel.eventTypeZoomProperty().get();
|
||||||
final ZoomParams zoomParams = new ZoomParams(subClusterSpan, eventTypeZoomLevel, subClusterFilter, getDescriptionLoD());
|
final ZoomParams zoomParams = new ZoomParams(subClusterSpan, eventTypeZoomLevel, subClusterFilter, getDescriptionLoD());
|
||||||
|
|
||||||
Task<List<EventStripe>> loggedTask = new Task<List<EventStripe>>() {
|
Task<List<EventStripe>> loggedTask = new LoggedTask<List<EventStripe>>(Bundle.EventStripeNode_loggedTask_name(), false) {
|
||||||
|
|
||||||
private volatile DescriptionLoD loadedDescriptionLoD = getDescriptionLoD().withRelativeDetail(relativeDetail);
|
private volatile DescriptionLoD loadedDescriptionLoD = getDescriptionLoD().withRelativeDetail(relativeDetail);
|
||||||
|
|
||||||
{
|
|
||||||
updateTitle(Bundle.EventStripeNode_loggedTask_name());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<EventStripe> call() throws Exception {
|
protected List<EventStripe> call() throws Exception {
|
||||||
List<EventStripe> bundles;
|
List<EventStripe> bundles;
|
||||||
@ -182,7 +203,9 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
} while (bundles.size() == 1 && nonNull(next));
|
} while (bundles.size() == 1 && nonNull(next));
|
||||||
|
|
||||||
// return list of EventStripes representing sub-bundles
|
// return list of EventStripes representing sub-bundles
|
||||||
return Lists.transform(bundles, eventStripe -> eventStripe.withParent(getEventCluster()));
|
return bundles.stream()
|
||||||
|
.map(eventStripe -> eventStripe.withParent(getEventCluster()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -190,14 +213,16 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
try {
|
try {
|
||||||
List<EventStripe> bundles = get();
|
List<EventStripe> bundles = get();
|
||||||
|
|
||||||
|
//clear the existing subnodes
|
||||||
|
List<EventStripe> transform = subNodes.stream().flatMap(stripeFlattener).collect(Collectors.toList());
|
||||||
|
chart.getEventStripes().removeAll(transform);
|
||||||
|
subNodes.clear();
|
||||||
if (bundles.isEmpty()) {
|
if (bundles.isEmpty()) {
|
||||||
subNodePane.getChildren().clear();
|
|
||||||
getChildren().setAll(subNodePane, infoHBox);
|
getChildren().setAll(subNodePane, infoHBox);
|
||||||
descLOD.set(getEventBundle().getDescriptionLoD());
|
descLOD.set(getEventBundle().getDescriptionLoD());
|
||||||
} else {
|
} else {
|
||||||
chart.getEventStripes().addAll(bundles);
|
chart.getEventStripes().addAll(bundles);
|
||||||
subNodes.addAll(Lists.transform(bundles, EventClusterNode.this::createStripeNode));
|
subNodes.addAll(Lists.transform(bundles, EventClusterNode.this::createChildNode));
|
||||||
subNodePane.getChildren().setAll(subNodes);
|
|
||||||
getChildren().setAll(new VBox(infoHBox, subNodePane));
|
getChildren().setAll(new VBox(infoHBox, subNodePane));
|
||||||
descLOD.set(loadedDescriptionLoD);
|
descLOD.set(loadedDescriptionLoD);
|
||||||
}
|
}
|
||||||
@ -214,7 +239,8 @@ final public class EventClusterNode extends EventBundleNodeBase<EventCluster, Ev
|
|||||||
chart.getController().monitorTask(loggedTask);
|
chart.getController().monitorTask(loggedTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventStripeNode createStripeNode(EventStripe stripe) {
|
@Override
|
||||||
|
EventStripeNode createChildNode(EventStripe stripe) {
|
||||||
return new EventStripeNode(chart, stripe, this);
|
return new EventStripeNode(chart, stripe, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ public final class EventDetailsChart extends XYChart<DateTime, EventStripe> impl
|
|||||||
* @return all the nodes that pass the given predicate
|
* @return all the nodes that pass the given predicate
|
||||||
*/
|
*/
|
||||||
synchronized Iterable<EventBundleNodeBase<?, ?, ?>> getNodes(Predicate<EventBundleNodeBase<?, ?, ?>> p) {
|
synchronized Iterable<EventBundleNodeBase<?, ?, ?>> getNodes(Predicate<EventBundleNodeBase<?, ?, ?>> p) {
|
||||||
//use this recursive function to flatten the tree of nodes into an iterable.
|
//use this recursive function to flatten the tree of nodes into an single stream.
|
||||||
Function<EventBundleNodeBase<?, ?, ?>, Stream<EventBundleNodeBase<?, ?, ?>>> stripeFlattener =
|
Function<EventBundleNodeBase<?, ?, ?>, Stream<EventBundleNodeBase<?, ?, ?>>> stripeFlattener =
|
||||||
new Function<EventBundleNodeBase<?, ?, ?>, Stream<EventBundleNodeBase<?, ?, ?>>>() {
|
new Function<EventBundleNodeBase<?, ?, ?>, Stream<EventBundleNodeBase<?, ?, ?>>>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,22 +68,25 @@ final public class EventStripeNode extends EventBundleNodeBase<EventStripe, Even
|
|||||||
super(chart, eventStripe, parentNode);
|
super(chart, eventStripe, parentNode);
|
||||||
|
|
||||||
setMinHeight(48);
|
setMinHeight(48);
|
||||||
|
|
||||||
//setup description label
|
//setup description label
|
||||||
eventTypeImageView.setImage(getEventType().getFXImage());
|
eventTypeImageView.setImage(getEventType().getFXImage());
|
||||||
descrLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
|
descrLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
|
||||||
descrLabel.setGraphic(eventTypeImageView);
|
descrLabel.setGraphic(eventTypeImageView);
|
||||||
|
descrLabel.setPrefWidth(USE_COMPUTED_SIZE);
|
||||||
setAlignment(subNodePane, Pos.BOTTOM_LEFT);
|
setAlignment(subNodePane, Pos.BOTTOM_LEFT);
|
||||||
|
|
||||||
for (EventCluster cluster : eventStripe.getClusters()) {
|
for (EventCluster cluster : eventStripe.getClusters()) {
|
||||||
EventClusterNode clusterNode = new EventClusterNode(chart, cluster, this);
|
subNodes.add(createChildNode(cluster));
|
||||||
subNodes.add(clusterNode);
|
|
||||||
subNodePane.getChildren().addAll(clusterNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildren().addAll(new VBox(infoHBox, subNodePane));
|
getChildren().addAll(new VBox(infoHBox, subNodePane));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
EventClusterNode createChildNode(EventCluster cluster) {
|
||||||
|
return new EventClusterNode(chart, cluster, this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void showHoverControls(final boolean showControls) {
|
void showHoverControls(final boolean showControls) {
|
||||||
super.showHoverControls(showControls);
|
super.showHoverControls(showControls);
|
||||||
@ -121,7 +124,7 @@ final public class EventStripeNode extends EventBundleNodeBase<EventStripe, Even
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
void setDescriptionVisibiltiyImpl(DescriptionVisibility descrVis) {
|
||||||
final int size = getEventStripe().getEventIDs().size();
|
final int size = getEventStripe().getCount();
|
||||||
|
|
||||||
switch (descrVis) {
|
switch (descrVis) {
|
||||||
case HIDDEN:
|
case HIDDEN:
|
||||||
|
@ -37,13 +37,15 @@ class EventDescriptionTreeItem extends NavTreeItem {
|
|||||||
*/
|
*/
|
||||||
private final Map<String, EventDescriptionTreeItem> childMap = new HashMap<>();
|
private final Map<String, EventDescriptionTreeItem> childMap = new HashMap<>();
|
||||||
private final EventBundle<?> bundle;
|
private final EventBundle<?> bundle;
|
||||||
|
private Comparator<TreeItem<EventBundle<?>>> comparator = TreeComparator.Description;
|
||||||
|
|
||||||
public EventBundle<?> getEventBundle() {
|
public EventBundle<?> getEventBundle() {
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventDescriptionTreeItem(EventBundle<?> g) {
|
EventDescriptionTreeItem(EventBundle<?> g, Comparator<TreeItem<EventBundle<?>>> comp) {
|
||||||
bundle = g;
|
bundle = g;
|
||||||
|
comparator = comp;
|
||||||
setValue(g);
|
setValue(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +58,11 @@ class EventDescriptionTreeItem extends NavTreeItem {
|
|||||||
public void insert(Deque<EventBundle<?>> path) {
|
public void insert(Deque<EventBundle<?>> path) {
|
||||||
EventBundle<?> head = path.removeFirst();
|
EventBundle<?> head = path.removeFirst();
|
||||||
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(head.getDescription(), description -> {
|
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(head.getDescription(), description -> {
|
||||||
EventDescriptionTreeItem newTreeItem = new EventDescriptionTreeItem(head);
|
EventDescriptionTreeItem newTreeItem = new EventDescriptionTreeItem(head, comparator);
|
||||||
newTreeItem.setExpanded(true);
|
newTreeItem.setExpanded(true);
|
||||||
childMap.put(description, newTreeItem);
|
childMap.put(description, newTreeItem);
|
||||||
getChildren().add(newTreeItem);
|
getChildren().add(newTreeItem);
|
||||||
|
resort(comparator, false);
|
||||||
return newTreeItem;
|
return newTreeItem;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -81,8 +84,12 @@ class EventDescriptionTreeItem extends NavTreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resort(Comparator<TreeItem<EventBundle<?>>> comp) {
|
void resort(Comparator<TreeItem<EventBundle<?>>> comp, Boolean recursive) {
|
||||||
|
this.comparator = comp;
|
||||||
FXCollections.sort(getChildren(), comp);
|
FXCollections.sort(getChildren(), comp);
|
||||||
|
if (recursive) {
|
||||||
|
childMap.values().forEach(ti -> ti.resort(comp, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,10 +34,11 @@ class EventTypeTreeItem extends NavTreeItem {
|
|||||||
*/
|
*/
|
||||||
private final Map<String, EventDescriptionTreeItem> childMap = new HashMap<>();
|
private final Map<String, EventDescriptionTreeItem> childMap = new HashMap<>();
|
||||||
|
|
||||||
private final Comparator<TreeItem<EventBundle<?>>> comparator = TreeComparator.Description;
|
private Comparator<TreeItem<EventBundle<?>>> comparator = TreeComparator.Description;
|
||||||
|
|
||||||
EventTypeTreeItem(EventBundle<?> g) {
|
EventTypeTreeItem(EventBundle<?> g, Comparator<TreeItem<EventBundle<?>>> comp) {
|
||||||
setValue(g);
|
setValue(g);
|
||||||
|
comparator = comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,11 +50,11 @@ class EventTypeTreeItem extends NavTreeItem {
|
|||||||
public void insert(Deque<EventBundle<?>> path) {
|
public void insert(Deque<EventBundle<?>> path) {
|
||||||
EventBundle<?> head = path.removeFirst();
|
EventBundle<?> head = path.removeFirst();
|
||||||
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(head.getDescription(), description -> {
|
EventDescriptionTreeItem treeItem = childMap.computeIfAbsent(head.getDescription(), description -> {
|
||||||
EventDescriptionTreeItem newTreeItem = new EventDescriptionTreeItem(head);
|
EventDescriptionTreeItem newTreeItem = new EventDescriptionTreeItem(head, comparator);
|
||||||
newTreeItem.setExpanded(true);
|
newTreeItem.setExpanded(true);
|
||||||
childMap.put(head.getDescription(), newTreeItem);
|
childMap.put(head.getDescription(), newTreeItem);
|
||||||
getChildren().add(newTreeItem);
|
getChildren().add(newTreeItem);
|
||||||
|
resort(comparator, false);
|
||||||
return newTreeItem;
|
return newTreeItem;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -63,16 +64,15 @@ class EventTypeTreeItem extends NavTreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void remove(Deque<EventBundle<?>> path) {
|
void remove(Deque<EventBundle<?>> path) {
|
||||||
|
|
||||||
EventBundle<?> head = path.removeFirst();
|
EventBundle<?> head = path.removeFirst();
|
||||||
EventDescriptionTreeItem descTreeItem = childMap.get(head.getDescription());
|
EventDescriptionTreeItem descTreeItem = childMap.get(head.getDescription());
|
||||||
if (descTreeItem != null) {
|
if (descTreeItem != null) {
|
||||||
if (path.isEmpty() == false) {
|
if (path.isEmpty() == false) {
|
||||||
descTreeItem.remove(path);
|
descTreeItem.remove(path);
|
||||||
} else if (descTreeItem.getChildren().isEmpty()) {
|
}
|
||||||
|
if (descTreeItem.getChildren().isEmpty()) {
|
||||||
childMap.remove(head.getDescription());
|
childMap.remove(head.getDescription());
|
||||||
getChildren().remove(descTreeItem);
|
getChildren().remove(descTreeItem);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,8 +92,11 @@ class EventTypeTreeItem extends NavTreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resort(Comparator<TreeItem<EventBundle<?>>> comp
|
void resort(Comparator<TreeItem<EventBundle<?>>> comp, Boolean recursive) {
|
||||||
) {
|
this.comparator = comp;
|
||||||
FXCollections.sort(getChildren(), comp);
|
FXCollections.sort(getChildren(), comp);
|
||||||
|
if (recursive) {
|
||||||
|
childMap.values().forEach(ti -> ti.resort(comp, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,6 @@ final public class EventsTree extends BorderPane {
|
|||||||
getRoot().remove(bundle);
|
getRoot().remove(bundle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getRoot().resort(sortByBox.getSelectionModel().getSelectedItem());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setRoot();
|
setRoot();
|
||||||
@ -114,11 +113,10 @@ final public class EventsTree extends BorderPane {
|
|||||||
|
|
||||||
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
@ThreadConfined(type = ThreadConfined.ThreadType.JFX)
|
||||||
private void setRoot() {
|
private void setRoot() {
|
||||||
RootItem root = new RootItem();
|
RootItem root = new RootItem(TreeComparator.Type.reversed().thenComparing(sortByBox.getSelectionModel().getSelectedItem()));
|
||||||
for (EventBundle<?> bundle : detailViewPane.getEventStripes()) {
|
for (EventBundle<?> bundle : detailViewPane.getEventStripes()) {
|
||||||
root.insert(bundle);
|
root.insert(bundle);
|
||||||
}
|
}
|
||||||
root.resort(TreeComparator.Type.reversed().thenComparing(sortByBox.getSelectionModel().getSelectedItem()));
|
|
||||||
eventsTree.setRoot(root);
|
eventsTree.setRoot(root);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -131,7 +129,7 @@ final public class EventsTree extends BorderPane {
|
|||||||
sortByBox.getItems().setAll(Arrays.asList(TreeComparator.Description, TreeComparator.Count));
|
sortByBox.getItems().setAll(Arrays.asList(TreeComparator.Description, TreeComparator.Count));
|
||||||
sortByBox.getSelectionModel().select(TreeComparator.Description);
|
sortByBox.getSelectionModel().select(TreeComparator.Description);
|
||||||
sortByBox.getSelectionModel().selectedItemProperty().addListener((Observable o) -> {
|
sortByBox.getSelectionModel().selectedItemProperty().addListener((Observable o) -> {
|
||||||
getRoot().resort(TreeComparator.Type.reversed().thenComparing(sortByBox.getSelectionModel().getSelectedItem()));
|
getRoot().resort(TreeComparator.Type.reversed().thenComparing(sortByBox.getSelectionModel().getSelectedItem()), true);
|
||||||
});
|
});
|
||||||
eventsTree.setShowRoot(false);
|
eventsTree.setShowRoot(false);
|
||||||
|
|
||||||
|
@ -32,9 +32,8 @@ abstract class NavTreeItem extends TreeItem<EventBundle<?>> {
|
|||||||
|
|
||||||
abstract long getCount();
|
abstract long getCount();
|
||||||
|
|
||||||
abstract void resort(Comparator<TreeItem<EventBundle<?>>> comp);
|
abstract void resort(Comparator<TreeItem<EventBundle<?>>> comp, Boolean recursive);
|
||||||
|
|
||||||
abstract NavTreeItem findTreeItemForEvent(EventBundle<?> t);
|
abstract NavTreeItem findTreeItemForEvent(EventBundle<?> t);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,10 @@ class RootItem extends NavTreeItem {
|
|||||||
/**
|
/**
|
||||||
* the comparator if any used to sort the children of this item
|
* the comparator if any used to sort the children of this item
|
||||||
*/
|
*/
|
||||||
// private TreeNodeComparators comp;
|
private Comparator<TreeItem<EventBundle<?>>> comparator = TreeComparator.Type.reversed();
|
||||||
RootItem() {
|
|
||||||
|
|
||||||
|
RootItem(Comparator<TreeItem<EventBundle<?>>> comp) {
|
||||||
|
comp = comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -62,12 +63,13 @@ class RootItem extends NavTreeItem {
|
|||||||
|
|
||||||
EventTypeTreeItem treeItem = childMap.computeIfAbsent(bundle.getEventType().getBaseType(),
|
EventTypeTreeItem treeItem = childMap.computeIfAbsent(bundle.getEventType().getBaseType(),
|
||||||
baseType -> {
|
baseType -> {
|
||||||
EventTypeTreeItem newTreeItem = new EventTypeTreeItem(bundle);
|
EventTypeTreeItem newTreeItem = new EventTypeTreeItem(bundle, comparator);
|
||||||
newTreeItem.setExpanded(true);
|
newTreeItem.setExpanded(true);
|
||||||
getChildren().add(newTreeItem);
|
getChildren().add(newTreeItem);
|
||||||
return newTreeItem;
|
return newTreeItem;
|
||||||
});
|
});
|
||||||
treeItem.insert(getTreePath(bundle));
|
treeItem.insert(getTreePath(bundle));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(EventBundle<?> bundle) {
|
void remove(EventBundle<?> bundle) {
|
||||||
@ -96,8 +98,9 @@ class RootItem extends NavTreeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resort(Comparator<TreeItem<EventBundle<?>>> comp) {
|
void resort(Comparator<TreeItem<EventBundle<?>>> comp, Boolean recursive) {
|
||||||
childMap.values().forEach(ti -> ti.resort(comp));
|
comparator = comp;
|
||||||
|
childMap.values().forEach(ti -> ti.resort(comp, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
BIN
docs/doxygen-user/images/autoPurge.PNG
Executable file
After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
@ -55,7 +55,7 @@ The following steps will configure Solr to run using an account that will have a
|
|||||||
<br><br>
|
<br><br>
|
||||||
\image html javaproperties.PNG
|
\image html javaproperties.PNG
|
||||||
<br><br>
|
<br><br>
|
||||||
A fully updated _serviceinstall.bat_ is shown below, with the changes marked in yellow.
|
A portion of an updated _serviceinstall.bat_ is shown below, with the changes marked in yellow.
|
||||||
<br><br>
|
<br><br>
|
||||||
\image html updatedServiceInstall.PNG
|
\image html updatedServiceInstall.PNG
|
||||||
<br><br>
|
<br><br>
|
||||||
@ -75,7 +75,11 @@ The added part is highlighted in yellow below. Ensure that it is inside the <i>\
|
|||||||
<br><br>
|
<br><br>
|
||||||
\image html dataDir.PNG
|
\image html dataDir.PNG
|
||||||
<br><br>
|
<br><br>
|
||||||
7. Edit <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\resources/log4j.properties"</i> to configure Solr log settings:
|
7. Edit the file <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr\zoo.cfg"</i> to add the lines <i>autopurge.snapRetainCount=3</i> and <i>autopurge.purgeInterval=1</i> as shown in the screenshot below.
|
||||||
|
<br><br>
|
||||||
|
\image html autoPurge.PNG
|
||||||
|
<br><br>
|
||||||
|
8. Edit <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\resources/log4j.properties"</i> to configure Solr log settings:
|
||||||
- Increase the log rotation size threshold (_log4j\.appender\.file\.MaxFileSize_) from 4MB to 100MB.
|
- Increase the log rotation size threshold (_log4j\.appender\.file\.MaxFileSize_) from 4MB to 100MB.
|
||||||
- Remove the _CONSOLE_ appender from the _log4j\.rootLogger_ line.
|
- Remove the _CONSOLE_ appender from the _log4j\.rootLogger_ line.
|
||||||
<br><br>
|
<br><br>
|
||||||
@ -85,9 +89,9 @@ The log file should end up looking like this (modified lines are highlighted in
|
|||||||
<br><br>
|
<br><br>
|
||||||
\image html log4j.PNG
|
\image html log4j.PNG
|
||||||
<br><br>
|
<br><br>
|
||||||
8. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
9. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\configsets"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||||
9. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
10. From an Autopsy installation, copy the folder <i>"C:\Program Files\Autopsy-4.0\autopsy\solr\solr\lib"</i> to <i>"C:\Bitnami\solr-4.10.3-0\apache-solr\solr"</i>.
|
||||||
10. Start a Windows command prompt as administrator by pressing _Start_, typing _command_, right clicking on _Command Prompt_, and clicking on _Run as administrator_. Then run the following command to install the _solrJetty_ service:
|
11. Start a Windows command prompt as administrator by pressing _Start_, typing _command_, right clicking on _Command Prompt_, and clicking on _Run as administrator_. Then run the following command to install the _solrJetty_ service:
|
||||||
<br><br>
|
<br><br>
|
||||||
<i>cmd /c C:\\Bitnami\\solr-4.10.3-0\\apache-solr\\scripts\\serviceinstall.bat INSTALL</i>
|
<i>cmd /c C:\\Bitnami\\solr-4.10.3-0\\apache-solr\\scripts\\serviceinstall.bat INSTALL</i>
|
||||||
<br><br>
|
<br><br>
|
||||||
@ -95,13 +99,13 @@ The log file should end up looking like this (modified lines are highlighted in
|
|||||||
<br><br>
|
<br><br>
|
||||||
\image html solrinstall1.PNG
|
\image html solrinstall1.PNG
|
||||||
<br><br>
|
<br><br>
|
||||||
11. Press _Start_, type _services.msc_, and press _Enter_. Find _solrJetty_. If the service is running, press _Stop the service_, then double click it, and switch to the _Log On_ tab to change the logon credentials to a user who will have access to read and write the primary shared drive. If the machine is on a domain, the Account Name will be in the form of _DOMAINNAME\\username_ as shown in the example below. Note that in the screenshot below, the domain name is _DOMAIN_ and the user name is _username_. These are just examples, not real values.
|
12. Press _Start_, type _services.msc_, and press _Enter_. Find _solrJetty_. If the service is running, press _Stop the service_, then double click it, and switch to the _Log On_ tab to change the logon credentials to a user who will have access to read and write the primary shared drive. If the machine is on a domain, the Account Name will be in the form of _DOMAINNAME\\username_ as shown in the example below. Note that in the screenshot below, the domain name is _DOMAIN_ and the user name is _username_. These are just examples, not real values.
|
||||||
<br><br>
|
<br><br>
|
||||||
\image html solrinstall2.PNG
|
\image html solrinstall2.PNG
|
||||||
<br>
|
<br>
|
||||||
If the machine is on a domain, **make sure** to select the domain with the mouse by going to the _Log On_ tab, clicking _Browse_, then clicking _Locations_ and selecting the domain of interest. Then enter the user name desired and press _Check Names_. When that completes, press _OK_, type in the password once for each box and press _OK_. You may see "The user has been granted the log on as a service right."
|
If the machine is on a domain, **make sure** to select the domain with the mouse by going to the _Log On_ tab, clicking _Browse_, then clicking _Locations_ and selecting the domain of interest. Then enter the user name desired and press _Check Names_. When that completes, press _OK_, type in the password once for each box and press _OK_. You may see "The user has been granted the log on as a service right."
|
||||||
|
|
||||||
12. You should be able to see the Solr service in a web browser via the URL <i>http://localhost:8983/solr/#/</i> as shown in the screenshot below.
|
13. You should be able to see the Solr service in a web browser via the URL <i>http://localhost:8983/solr/#/</i> as shown in the screenshot below.
|
||||||
<br><br>
|
<br><br>
|
||||||
\image html solrinstall3.PNG
|
\image html solrinstall3.PNG
|
||||||
<br><br>
|
<br><br>
|
||||||
|