Skip to content

Commit 40feec9

Browse files
committed
Compute Aggregation Id Field - #170
1 parent b31fa1e commit 40feec9

File tree

3 files changed

+254
-5
lines changed

3 files changed

+254
-5
lines changed

src/main/java/com/airbus_cyber_security/graylog/wizard/fields/AggregationFieldValueProvider.java

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,17 @@
2828
import org.graylog.events.fields.FieldValueType;
2929
import org.graylog.events.fields.providers.AbstractFieldValueProvider;
3030
import org.graylog.events.fields.providers.FieldValueProvider;
31+
import org.graylog.events.search.EventsSearchFilter;
32+
import org.graylog.events.search.EventsSearchParameters;
33+
import org.graylog.events.search.EventsSearchResult;
34+
import org.graylog.events.search.EventsSearchService;
35+
import org.graylog2.plugin.Message;
36+
import org.graylog2.plugin.indexer.searches.timeranges.RelativeRange;
3137
import org.slf4j.Logger;
3238
import org.slf4j.LoggerFactory;
3339

40+
import java.util.Collections;
41+
import java.util.Optional;
3442
import java.util.UUID;
3543

3644
public class AggregationFieldValueProvider extends AbstractFieldValueProvider {
@@ -42,18 +50,64 @@ public interface Factory extends AbstractFieldValueProvider.Factory<AggregationF
4250
private static final Logger LOG = LoggerFactory.getLogger(AggregationFieldValueProvider.class);
4351

4452
private final AggregationFieldValueProvider.Config config;
53+
private final EventsSearchService searchService;
4554

4655
@Inject
47-
public AggregationFieldValueProvider(@Assisted FieldValueProvider.Config config) {
56+
public AggregationFieldValueProvider(@Assisted FieldValueProvider.Config config, EventsSearchService searchService) {
4857
super(config);
4958
this.config = (AggregationFieldValueProvider.Config) config;
59+
this.searchService = searchService;
5060
}
5161

5262
@Override
5363
protected FieldValue doGet(String fieldName, EventWithContext eventWithContext) {
54-
return FieldValue.create(FieldValueType.STRING, UUID.randomUUID().toString());
64+
LOG.debug("Start Compute field {}", fieldName);
65+
66+
// Check if alert already exist in time range
67+
if (this.config.aggregationTimeRange() > 0) {
68+
LOG.debug("Aggregation Time Range is defined");
69+
70+
String eventDefinitionId = eventWithContext.event().getEventDefinitionId();
71+
int timeRange = this.config.aggregationTimeRange() * 60;
72+
73+
EventsSearchFilter searchFilter = EventsSearchFilter.builder()
74+
.alerts(EventsSearchFilter.Alerts.ONLY)
75+
.eventDefinitions(Collections.singleton(eventDefinitionId))
76+
.build();
77+
78+
EventsSearchParameters request = EventsSearchParameters.builder()
79+
.filter(searchFilter)
80+
.timerange(RelativeRange.create(timeRange))
81+
.page(1)
82+
// Do not use higher perPage value cause request failed
83+
.perPage(5000)
84+
.query("")
85+
.sortBy(Message.FIELD_TIMESTAMP)
86+
.sortDirection(EventsSearchParameters.SortDirection.DESC)
87+
.build();
88+
89+
EventsSearchResult result = this.searchService.search(request, new EmptySubject());
90+
91+
if (result.totalEvents() > 0) {
92+
LOG.debug("Found {} events for aggregation", result.totalEvents());
93+
94+
Optional<EventsSearchResult.Event> existingEvent = result.events().stream().filter(x -> x.event().groupByFields().equals(eventWithContext.event().getGroupByFields())).findFirst();
95+
96+
if (existingEvent.isPresent()) {
97+
String existingId = existingEvent.get().event().fields().getOrDefault(fieldName, UUID.randomUUID().toString());
98+
LOG.debug("Find existing Event with aggregation Id {}", existingId);
99+
100+
return FieldValue.create(FieldValueType.STRING, existingId);
101+
}
102+
}
103+
}
104+
105+
return getRandomFieldValue();
55106
}
56107

108+
public FieldValue getRandomFieldValue() {
109+
return FieldValue.create(FieldValueType.STRING, UUID.randomUUID().toString());
110+
}
57111

58112
@AutoValue
59113
@JsonTypeName(AggregationFieldValueProvider.Config.TYPE_NAME)
@@ -64,7 +118,7 @@ public static abstract class Config implements AbstractFieldValueProvider.Config
64118
private static final String FIELD_AGGREGATION_TIME_RANGE = "aggregation_time_range";
65119

66120
@JsonProperty(FIELD_AGGREGATION_TIME_RANGE)
67-
public abstract Long aggregationTimeRange();
121+
public abstract Integer aggregationTimeRange();
68122

69123
public static AggregationFieldValueProvider.Config.Builder builder() {
70124
return AggregationFieldValueProvider.Config.Builder.create();
@@ -80,7 +134,7 @@ public static AggregationFieldValueProvider.Config.Builder create() {
80134
}
81135

82136
@JsonProperty(FIELD_AGGREGATION_TIME_RANGE)
83-
public abstract AggregationFieldValueProvider.Config.Builder aggregationTimeRange(Long aggregationTimeRange);
137+
public abstract AggregationFieldValueProvider.Config.Builder aggregationTimeRange(Integer aggregationTimeRange);
84138

85139
public abstract AggregationFieldValueProvider.Config build();
86140
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/*
2+
* Copyright (C) 2018 Airbus CyberSecurity (SAS)
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the Server Side Public License, version 1,
6+
* as published by MongoDB, Inc.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* Server Side Public License for more details.
12+
*
13+
* You should have received a copy of the Server Side Public License
14+
* along with this program. If not, see
15+
* <http://www.mongodb.com/licensing/server-side-public-license>.
16+
*/
17+
package com.airbus_cyber_security.graylog.wizard.fields;
18+
19+
import org.apache.shiro.authc.AuthenticationException;
20+
import org.apache.shiro.authc.AuthenticationToken;
21+
import org.apache.shiro.authz.AuthorizationException;
22+
import org.apache.shiro.authz.Permission;
23+
import org.apache.shiro.session.Session;
24+
import org.apache.shiro.subject.ExecutionException;
25+
import org.apache.shiro.subject.PrincipalCollection;
26+
import org.apache.shiro.subject.Subject;
27+
28+
import java.util.Collection;
29+
import java.util.List;
30+
import java.util.concurrent.Callable;
31+
32+
/**
33+
* Empty implementation of Subject
34+
*/
35+
// TODO: Remove this when Graylog will allow search without Subject
36+
public class EmptySubject implements Subject {
37+
@Override
38+
public Object getPrincipal() {
39+
return null;
40+
}
41+
42+
@Override
43+
public PrincipalCollection getPrincipals() {
44+
return null;
45+
}
46+
47+
@Override
48+
public boolean isPermitted(String permission) {
49+
return true;
50+
}
51+
52+
@Override
53+
public boolean isPermitted(Permission permission) {
54+
return true;
55+
}
56+
57+
@Override
58+
public boolean[] isPermitted(String... permissions) {
59+
return new boolean[0];
60+
}
61+
62+
@Override
63+
public boolean[] isPermitted(List<Permission> permissions) {
64+
return new boolean[0];
65+
}
66+
67+
@Override
68+
public boolean isPermittedAll(String... permissions) {
69+
return false;
70+
}
71+
72+
@Override
73+
public boolean isPermittedAll(Collection<Permission> permissions) {
74+
return false;
75+
}
76+
77+
@Override
78+
public void checkPermission(String permission) throws AuthorizationException {
79+
80+
}
81+
82+
@Override
83+
public void checkPermission(Permission permission) throws AuthorizationException {
84+
85+
}
86+
87+
@Override
88+
public void checkPermissions(String... permissions) throws AuthorizationException {
89+
90+
}
91+
92+
@Override
93+
public void checkPermissions(Collection<Permission> permissions) throws AuthorizationException {
94+
95+
}
96+
97+
@Override
98+
public boolean hasRole(String roleIdentifier) {
99+
return false;
100+
}
101+
102+
@Override
103+
public boolean[] hasRoles(List<String> roleIdentifiers) {
104+
return new boolean[0];
105+
}
106+
107+
@Override
108+
public boolean hasAllRoles(Collection<String> roleIdentifiers) {
109+
return false;
110+
}
111+
112+
@Override
113+
public void checkRole(String roleIdentifier) throws AuthorizationException {
114+
115+
}
116+
117+
@Override
118+
public void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException {
119+
120+
}
121+
122+
@Override
123+
public void checkRoles(String... roleIdentifiers) throws AuthorizationException {
124+
125+
}
126+
127+
@Override
128+
public void login(AuthenticationToken token) throws AuthenticationException {
129+
130+
}
131+
132+
@Override
133+
public boolean isAuthenticated() {
134+
return false;
135+
}
136+
137+
@Override
138+
public boolean isRemembered() {
139+
return false;
140+
}
141+
142+
@Override
143+
public Session getSession() {
144+
return null;
145+
}
146+
147+
@Override
148+
public Session getSession(boolean create) {
149+
return null;
150+
}
151+
152+
@Override
153+
public void logout() {
154+
155+
}
156+
157+
@Override
158+
public <V> V execute(Callable<V> callable) throws ExecutionException {
159+
return null;
160+
}
161+
162+
@Override
163+
public void execute(Runnable runnable) {
164+
165+
}
166+
167+
@Override
168+
public <V> Callable<V> associateWith(Callable<V> callable) {
169+
return null;
170+
}
171+
172+
@Override
173+
public Runnable associateWith(Runnable runnable) {
174+
return null;
175+
}
176+
177+
@Override
178+
public void runAs(PrincipalCollection principals) throws NullPointerException, IllegalStateException {
179+
180+
}
181+
182+
@Override
183+
public boolean isRunAs() {
184+
return false;
185+
}
186+
187+
@Override
188+
public PrincipalCollection getPreviousPrincipals() {
189+
return null;
190+
}
191+
192+
@Override
193+
public PrincipalCollection releaseRunAs() {
194+
return null;
195+
}
196+
}

src/web/wizard/aggregationField/AggregationFieldValueProviderSummary.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const AggregationFieldValueProviderSummary = ({ fieldName, config, keys }: Props
3131

3232
const toggleDisplayDetails = () => {
3333
setDisplayDetails(!displayDetails);
34-
console.log(config);
3534
};
3635

3736
return (

0 commit comments

Comments
 (0)