Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds stream categories to dashboard widgets #20199

Merged
merged 41 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0ec884c
Add StreamCategoryFilter and stream_category to StreamDTO
kingzacko1 Aug 7, 2024
c272dea
Fix introduced test failures
kingzacko1 Aug 7, 2024
2ac60fa
Remove streamService from eventlists and messagelists
kingzacko1 Aug 8, 2024
874e188
Merge branch 'master' into add-stream-category-filter
kingzacko1 Aug 8, 2024
b5784cb
Merge remote-tracking branch 'origin/master' into add-stream-category…
kingzacko1 Aug 12, 2024
3c0d90d
Move StreamCategory resolution to SearchExecutor from SearchBackend
kingzacko1 Aug 13, 2024
ddec6c0
revert unnecessary changes
kingzacko1 Aug 13, 2024
5f19b85
Add logic to populate queries with streamcategories with streamIds
kingzacko1 Aug 13, 2024
38390da
Move streamcategory mapping from CommandFactory to MessagesResource
kingzacko1 Aug 13, 2024
2175a6f
Fix MessagesResourceTest
kingzacko1 Aug 13, 2024
a7d1e54
Revert unused changes
kingzacko1 Aug 13, 2024
a762413
Merge remote-tracking branch 'origin/master' into add-stream-category…
kingzacko1 Aug 14, 2024
cb42003
Merge branch 'master' into add-stream-category-filter
kingzacko1 Aug 15, 2024
55efe86
cl
kingzacko1 Aug 15, 2024
1f84f6e
Adds stream categories to dashboard widgets
kingzacko1 Aug 16, 2024
e9c32af
Merge remote-tracking branch 'origin/master' into add-stream-category…
kingzacko1 Aug 19, 2024
865a36d
Add enterprise issue to changelog
kingzacko1 Aug 19, 2024
10f384a
Merge branch 'add-stream-category-filter' into add-stream-categories-…
kingzacko1 Aug 19, 2024
cf62e8e
Merge remote-tracking branch 'origin/master' into add-stream-category…
kingzacko1 Aug 22, 2024
0578852
Replace StreamCategoryFilters with StreamFilters in place instead of …
kingzacko1 Aug 22, 2024
ead7631
Merge branch 'add-stream-category-filter' into add-stream-categories-…
kingzacko1 Aug 22, 2024
e066ada
Merge remote-tracking branch 'origin/master' into add-stream-category…
kingzacko1 Aug 23, 2024
43a84e0
Move StreamCategory to StreamFilter logic and address other feedback
kingzacko1 Aug 23, 2024
26446ca
Merge branch 'add-stream-category-filter' into add-stream-categories-…
kingzacko1 Aug 23, 2024
d21c787
Merge remote-tracking branch 'origin/master' into add-stream-categori…
kingzacko1 Aug 26, 2024
b1f8209
Fix migration test errors missing new field
kingzacko1 Aug 26, 2024
86b5ed1
Fix test AggregationWidget
kingzacko1 Aug 26, 2024
b98cef4
Merge branch 'master' into add-stream-categories-to-dashboard-widgets
kingzacko1 Aug 29, 2024
d3f2f96
Merge remote-tracking branch 'origin/master' into add-stream-categori…
kingzacko1 Aug 30, 2024
f62c3bd
Add stream categories to SearchBar and WidgetQueryControls (#20226)
kingzacko1 Sep 3, 2024
b5c1805
Merge branch 'master' into add-stream-categories-to-dashboard-widgets
kingzacko1 Sep 3, 2024
695ea28
Merge remote-tracking branch 'origin/master' into add-stream-categori…
kingzacko1 Sep 3, 2024
22b348a
feat: Hide stream categories dropdown if no categories
zeeklop Sep 3, 2024
ae361df
Merge branch 'add-stream-categories-to-dashboard-widgets' of github.c…
zeeklop Sep 3, 2024
6986a67
Merge branch 'master' into add-stream-categories-to-dashboard-widgets
kingzacko1 Sep 4, 2024
277a6d5
Merge branch 'master' of github.com:Graylog2/graylog2-server into add…
zeeklop Sep 4, 2024
275055f
account for categories for search types
ryan-carroll-graylog Sep 4, 2024
e9947af
Merge branch 'add-stream-categories-to-dashboard-widgets' of github.c…
zeeklop Sep 4, 2024
8f9c033
Map stream categories before adding all streams to queries without st…
kingzacko1 Sep 4, 2024
214d17d
feat: Better check for duplicate categories
zeeklop Sep 4, 2024
bdde0e7
Merge branch 'add-stream-categories-to-dashboard-widgets' of github.c…
zeeklop Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public abstract class AggregationWidget implements ViewWidget {
private static final String FIELD_TIMERANGE = "timerange";
private static final String FIELD_QUERY = "query";
private static final String FIELD_STREAMS = "streams";
private static final String FIELD_STREAM_CATEGORIES = "stream_categories";

@JsonProperty(FIELD_ID)
public abstract String id();
Expand All @@ -60,13 +61,17 @@ public abstract class AggregationWidget implements ViewWidget {
@JsonProperty(FIELD_STREAMS)
abstract Set<String> streams();

@JsonProperty(FIELD_STREAM_CATEGORIES)
abstract Set<String> streamCategories();

@JsonProperty(FIELD_CONFIG)
public abstract AggregationConfig config();

public static Builder builder() {
return new AutoValue_AggregationWidget.Builder()
.type(TYPE_AGGREGATION)
.streams(Collections.emptySet());
.streams(Collections.emptySet())
.streamCategories(Collections.emptySet());
}

public Set<SearchType> toSearchTypes(RandomUUIDProvider randomUUIDProvider) {
Expand All @@ -75,6 +80,7 @@ public Set<SearchType> toSearchTypes(RandomUUIDProvider randomUUIDProvider) {
.name("chart")
.query(query())
.streams(streams())
.streamCategories(streamCategories())
.timerange(timerange())
.rollup(config().rollup())
.rowGroups(config().rowPivots().stream().map(pivot -> pivot.toBucketSpec()).collect(Collectors.toList()))
Expand Down Expand Up @@ -122,6 +128,9 @@ public Builder query(String query) {
@JsonProperty(FIELD_STREAMS)
public abstract Builder streams(Set<String> streams);

@JsonProperty(FIELD_STREAM_CATEGORIES)
public abstract Builder streamCategories(Set<String> streamCategories);

@JsonProperty(FIELD_CONFIG)
public abstract Builder config(AggregationConfig config);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ Builder query(String query) {

abstract Builder streams(Set<String> streams);

abstract Builder streamCategories(Set<String> streamCategories);

abstract Builder limit(int limit);

abstract Builder offset(int offset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ Builder query(String query) {

abstract Builder streams(Set<String> streams);

abstract Builder streamCategories(Set<String> streamCategories);

abstract Pivot build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public interface SearchType {
@JsonProperty
Set<String> streams();

@JsonProperty
Set<String> streamCategories();

@JsonProperty
Optional<String> name();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.graylog.plugins.views.migrations.V20191203120602_MigrateSavedSearchesToViewsSupport.view.ElasticsearchQueryString;
import org.graylog.plugins.views.migrations.V20191203120602_MigrateSavedSearchesToViewsSupport.view.TimeRange;

import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
Expand All @@ -35,6 +36,7 @@ public abstract class MessagesSearchType implements SearchType {
private static final String FIELD_TIMERANGE = "timerange";
private static final String FIELD_QUERY = "query";
private static final String FIELD_STREAMS = "streams";
private static final String FIELD_STREAM_CATEGORIES = "stream_categories";
private static final String FIELD_NAME = "name";
private static final String FIELD_LIMIT = "limit";
private static final String FIELD_OFFSET = "offset";
Expand Down Expand Up @@ -62,6 +64,12 @@ public Set<String> streams() {
return Collections.emptySet();
}

@Nullable
@JsonProperty(FIELD_STREAM_CATEGORIES)
public Set<String> streamCategories() {
return Collections.emptySet();
}

@JsonProperty(FIELD_NAME)
public Optional<String> name() {
return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public Set<String> streams() {
return Collections.emptySet();
}

@Override
public Set<String> streamCategories() {
return Collections.emptySet();
}

@JsonProperty("row_groups")
abstract List<Time> rowGroups();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ public interface SearchType {

@JsonProperty
Set<String> streams();

@JsonProperty
Set<String> streamCategories();
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public abstract class AggregationWidget implements ViewWidget {
private static final String FIELD_TIMERANGE = "timerange";
private static final String FIELD_QUERY = "query";
private static final String FIELD_STREAMS = "streams";
private static final String FIELD_STREAM_CATEGORIES = "stream_categories";

@JsonProperty(FIELD_ID)
public abstract String id();
Expand Down Expand Up @@ -74,6 +75,11 @@ Set<String> streams() {
return Collections.emptySet();
}

@JsonProperty(FIELD_STREAM_CATEGORIES)
Set<String> streamCategories() {
return Collections.emptySet();
}

@JsonProperty(FIELD_CONFIG)
public abstract AggregationConfig config();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public abstract class MessagesWidget implements ViewWidget {
private static final String FIELD_TIMERANGE = "timerange";
private static final String FIELD_QUERY = "query";
private static final String FIELD_STREAMS = "streams";
private static final String FIELD_STREAM_CATEGORIES = "stream_categories";
private static final String FIELD_CONFIG = "config";

@JsonProperty(FIELD_ID)
Expand Down Expand Up @@ -63,6 +64,11 @@ Set<String> streams() {
return Collections.emptySet();
}

@JsonProperty(FIELD_STREAM_CATEGORIES)
Set<String> streamCategories() {
return Collections.emptySet();
}

@JsonProperty(FIELD_CONFIG)
abstract MessagesWidgetConfig config();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,39 @@ public Search addStreamsToQueriesWithCategories(Function<Collection<String>, Str
return toBuilder().queries(newQueries).build();
}

public Search addStreamsToSearchTypesWithCategories(Function<Collection<String>, Stream<String>> categoryMappingFunction,
StreamPermissions streamPermissions) {
if (!hasQuerySearchTypesWithStreamCategories()) {
return this;
}
final Set<Query> withStreamCategories = queries().stream()
.filter(q -> q.searchTypes().stream()
.anyMatch(SearchType::hasStreamCategories))
.collect(toSet());
final Set<Query> withoutStreamCategories = Sets.difference(queries(), withStreamCategories);
final Set<Query> withMappedStreamCategories = new HashSet<>();

for (Query query : withStreamCategories) {
final Set<SearchType> mappedSearchTypes = new HashSet<>();
for (SearchType st : query.searchTypes()) {
if (!st.hasStreamCategories()) {
mappedSearchTypes.add(st);
} else {
final Set<String> mappedStreamIds = categoryMappingFunction.apply(st.streamCategories())
.filter(streamPermissions::canReadStream)
.collect(toSet());
mappedStreamIds.addAll(st.streams());
mappedSearchTypes.add(st.toBuilder().streams(mappedStreamIds).build());
}
}
withMappedStreamCategories.add(query.toBuilder().searchTypes(mappedSearchTypes).build());
}

final ImmutableSet<Query> newQueries = Sets.union(withMappedStreamCategories, withoutStreamCategories).immutableCopy();

return toBuilder().queries(newQueries).build();
}

private boolean hasQueriesWithoutStreams() {
return !queries().stream().allMatch(Query::hasStreams);
}
Expand All @@ -180,6 +213,12 @@ private boolean hasQueriesWithStreamCategories() {
return queries().stream().anyMatch(q -> !q.usedStreamCategories().isEmpty());
}

private boolean hasQuerySearchTypesWithStreamCategories() {
return queries().stream()
.flatMap(q -> q.searchTypes().stream())
.anyMatch(SearchType::hasStreamCategories);
}

public abstract Builder toBuilder();

public static Builder builder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ public interface SearchType extends ContentPackable<SearchTypeEntity>, Exportabl
@JsonProperty
Set<String> streams();

@Nullable
@JsonProperty
Set<String> streamCategories();

SearchType applyExecutionContext(SearchTypeExecutionState executionState);

default SearchType withQuery(BackendQuery query) {
Expand All @@ -110,6 +114,10 @@ default SearchType withReferenceDate(DateTime now) {
.orElse(this);
}

default boolean hasStreamCategories() {
return streamCategories() != null && !streamCategories().isEmpty();
}

SearchTypeBuilder toBuilder();

/**
Expand Down Expand Up @@ -164,6 +172,10 @@ class Fallback implements SearchType {
@JsonProperty
private Set<String> streams;

@Nullable
@JsonProperty
private Set<String> streamCategories;

@Override
public String type() {
return type;
Expand Down Expand Up @@ -204,6 +216,11 @@ public Set<String> streams() {
return this.streams == null ? Collections.emptySet() : this.streams;
}

@Override
public Set<String> streamCategories() {
return this.streamCategories == null ? Collections.emptySet() : this.streamCategories;
}

@Override
public SearchType applyExecutionContext(SearchTypeExecutionState state) {
return this;
Expand Down Expand Up @@ -284,6 +301,11 @@ public SearchTypeBuilder query(@Nullable BackendQuery query) {
public SearchTypeBuilder filter(@Nullable Filter filter) {
return this;
}

@Override
public SearchTypeBuilder streams(Set<String> streams) {
return this;
}
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;

public interface SearchTypeBuilder {
SearchType build();
Expand All @@ -33,4 +34,6 @@ public interface SearchTypeBuilder {
SearchTypeBuilder query(@Nullable BackendQuery query);

SearchTypeBuilder filter(@Nullable Filter filter);

SearchTypeBuilder streams(Set<String> streams);
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ private Query normalize(final Query query,
@Override
public Search preValidation(Search search, SearchUser searchUser, ExecutionState executionState) {
final Search searchWithStreams = search
.addStreamsToQueriesWithoutStreams(() -> searchUser.streams().loadMessageStreamsWithFallback())
.addStreamsToQueriesWithCategories(streamCategoryMapper, searchUser);
.addStreamsToQueriesWithCategories(streamCategoryMapper, searchUser)
.addStreamsToSearchTypesWithCategories(streamCategoryMapper, searchUser)
.addStreamsToQueriesWithoutStreams(() -> searchUser.streams().loadMessageStreamsWithFallback());
final var now = referenceDateFromOverrideOrNow(executionState);
final var normalizedSearch = searchWithStreams.applyExecutionState(firstNonNull(executionState, ExecutionState.empty()))
.withReferenceDate(now);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public ImmutableSet<String> loadMessageStreamsWithFallback() {
}
}

public ImmutableSet<String> loadStreamsWithCategories(Set<String> categories) {
return permittedStreams.loadWithCategories(categories, streamPermissions);
}

/**
* If any stream IDs are provided, they will be filtered out by read permission. If none are given, we'll load
* all available streams for the current SearchUser
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.graylog2.shared.rest.resources.RestResource;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -90,10 +91,19 @@ private boolean containsWarmIndices(Set<ExplainResults.IndexRangeResult> searche
}

private ValidationRequest prepareRequest(ValidationRequestDTO validationRequest, SearchUser searchUser) {
// Combine stream IDs mapped from streamCategories and stream IDs from the validationRequest before calling
// readableOrAllIfEmpty to ensure all possible requested streams are added first.
final Set<String> streamsAndMappedCategories = validationRequest.streams().orElse(new HashSet<>());
if (validationRequest.streamCategories().isPresent()) {
streamsAndMappedCategories.addAll(searchUser.streams().loadStreamsWithCategories(validationRequest.streamCategories().get()));
}
ImmutableSet.Builder<String> allRequestedStreams = ImmutableSet.<String>builder()
.addAll(searchUser.streams().readableOrAllIfEmpty(streamsAndMappedCategories));

final ValidationRequest.Builder q = ValidationRequest.Builder.builder()
.query(validationRequest.query())
.timerange(validationRequest.timerange().orElse(defaultTimeRange()))
.streams(searchUser.streams().readableOrAllIfEmpty(validationRequest.streams()))
.streams(allRequestedStreams.build())
.parameters(resolveParameters(validationRequest))
.validationMode(validationRequest.validationMode().toInternalRepresentation());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
public abstract class ValidationRequestDTO {

private static final String FIELD_STREAMS = "streams";
private static final String FIELD_STREAM_CATEGORIES = "stream_categories";
private static final String FIELD_TIMERANGE = "timerange";

@JsonProperty
Expand All @@ -58,6 +59,9 @@ public abstract class ValidationRequestDTO {
@JsonProperty(FIELD_STREAMS)
public abstract Optional<Set<String>> streams();

@JsonProperty(FIELD_STREAM_CATEGORIES)
public abstract Optional<Set<String>> streamCategories();

@JsonProperty
public abstract ImmutableSet<Parameter> parameters();

Expand All @@ -79,6 +83,9 @@ public abstract static class Builder {
@JsonProperty(FIELD_STREAMS)
public abstract Builder streams(@Nullable Set<String> streams);

@JsonProperty(FIELD_STREAM_CATEGORIES)
public abstract Builder streamCategories(@Nullable Set<String> streamCategories);

@JsonProperty(FIELD_TIMERANGE)
public abstract Builder timerange(@Nullable TimeRange timerange);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public static Builder builder() {
.offset(0)
.filters(Collections.emptyList())
.streams(Collections.emptySet())
.streamCategories(Collections.emptySet())
.decorators(Collections.emptyList())
.fields(Collections.emptyList());
}
Expand All @@ -129,6 +130,7 @@ public abstract static class Builder implements SearchTypeBuilder {
public static Builder createDefault() {
return builder()
.filters(Collections.emptyList())
.streamCategories(Collections.emptySet())
.streams(Collections.emptySet());
}

Expand Down Expand Up @@ -164,6 +166,9 @@ public Builder timerange(@Nullable TimeRange timerange) {
@JsonProperty
public abstract Builder streams(Set<String> streams);

@JsonProperty
public abstract Builder streamCategories(Set<String> streamCategories);

@JsonProperty
public abstract Builder limit(int limit);

Expand Down
Loading
Loading