4040import com .airbus_cyber_security .graylog .wizard .config .rest .ImportPolicyType ;
4141import com .airbus_cyber_security .graylog .wizard .permissions .AlertRuleRestPermissions ;
4242import com .codahale .metrics .annotation .Timed ;
43+ import com .google .common .collect .ImmutableMap ;
4344import com .mongodb .MongoException ;
4445import io .swagger .annotations .Api ;
4546import io .swagger .annotations .ApiOperation ;
4950import jakarta .ws .rs .BadRequestException ;
5051import jakarta .ws .rs .Consumes ;
5152import jakarta .ws .rs .DELETE ;
53+ import jakarta .ws .rs .DefaultValue ;
5254import jakarta .ws .rs .GET ;
5355import jakarta .ws .rs .POST ;
5456import jakarta .ws .rs .PUT ;
5557import jakarta .ws .rs .Path ;
5658import jakarta .ws .rs .PathParam ;
5759import jakarta .ws .rs .Produces ;
60+ import jakarta .ws .rs .QueryParam ;
5861import org .apache .shiro .authz .annotation .RequiresAuthentication ;
5962import org .apache .shiro .authz .annotation .RequiresPermissions ;
6063import org .graylog .events .notifications .NotificationDto ;
6164import org .graylog .events .processor .EventDefinition ;
6265import org .graylog .events .processor .EventDefinitionDto ;
6366import org .graylog .events .processor .EventProcessorConfig ;
64- import org .graylog .events .processor .aggregation .AggregationEventProcessorConfig ;
6567import org .graylog .events .rest .EventNotificationsResource ;
6668import org .graylog .security .UserContext ;
6769import org .graylog2 .audit .jersey .AuditEvent ;
6870import org .graylog2 .database .NotFoundException ;
71+ import org .graylog2 .database .PaginatedList ;
6972import org .graylog2 .plugin .database .ValidationException ;
7073import org .graylog2 .plugin .rest .PluginRestResource ;
74+ import org .graylog2 .rest .models .SortOrder ;
75+ import org .graylog2 .rest .models .tools .responses .PageListResponse ;
76+ import org .graylog2 .rest .resources .entities .EntityAttribute ;
77+ import org .graylog2 .rest .resources .entities .EntityDefaults ;
78+ import org .graylog2 .rest .resources .entities .Sorting ;
79+ import org .graylog2 .search .SearchQuery ;
80+ import org .graylog2 .search .SearchQueryField ;
81+ import org .graylog2 .search .SearchQueryParser ;
7182import org .graylog2 .shared .rest .resources .RestResource ;
7283import org .joda .time .DateTime ;
7384import org .joda .time .DateTimeZone ;
8394import java .io .UnsupportedEncodingException ;
8495import java .util .ArrayList ;
8596import java .util .List ;
97+ import java .util .Locale ;
8698import java .util .Map ;
8799import java .util .Optional ;
88100
@@ -96,6 +108,22 @@ public class AlertRuleResource extends RestResource implements PluginRestResourc
96108 private static final String ENCODING = "UTF-8" ;
97109 private static final String TITLE = "title" ;
98110
111+ private static final String DEFAULT_SORT_FIELD = "title" ;
112+ private static final String DEFAULT_SORT_DIRECTION = "asc" ;
113+ private static final ImmutableMap <String , SearchQueryField > SEARCH_FIELD_MAPPING = ImmutableMap .<String , SearchQueryField >builder ()
114+ .put ("id" , SearchQueryField .create ("_id" , SearchQueryField .Type .OBJECT_ID ))
115+ .put ("title" , SearchQueryField .create (GetDataAlertRule .FIELD_TITLE ))
116+ .put ("description" , SearchQueryField .create (GetDataAlertRule .FIELD_DESCRIPTION ))
117+ .build ();
118+ private static final List <EntityAttribute > attributes = List .of (
119+ EntityAttribute .builder ().id ("title" ).title ("Title" ).build (),
120+ EntityAttribute .builder ().id ("description" ).title ("Description" ).build (),
121+ EntityAttribute .builder ().id ("priority" ).title ("Priority" ).type (SearchQueryField .Type .INT ).build ()
122+ );
123+ private static final EntityDefaults settings = EntityDefaults .builder ()
124+ .sort (Sorting .create (DEFAULT_SORT_FIELD , Sorting .Direction .valueOf (DEFAULT_SORT_DIRECTION .toUpperCase (Locale .ROOT ))))
125+ .build ();
126+
99127 // TODO try to remove this field => move it down in business
100128 private final AlertWizardConfigurationService configurationService ;
101129
@@ -108,6 +136,8 @@ public class AlertRuleResource extends RestResource implements PluginRestResourc
108136 private final TriggeringConditionsService triggeringConditionsService ;
109137 private final NotificationService notificationService ;
110138
139+ private final SearchQueryParser searchQueryParser ;
140+
111141 @ Inject
112142 public AlertRuleResource (AlertRuleService alertRuleService ,
113143 TriggeringConditionsService triggeringConditionsService ,
@@ -125,6 +155,7 @@ public AlertRuleResource(AlertRuleService alertRuleService,
125155
126156 this .conversions = conversions ;
127157 this .notificationService = notificationService ;
158+ this .searchQueryParser = new SearchQueryParser (GetDataAlertRule .FIELD_TITLE , SEARCH_FIELD_MAPPING );
128159 }
129160
130161 private AlertRuleStream constructAlertRuleStream (TriggeringConditions conditions ) {
@@ -574,4 +605,44 @@ private String createNotificationFromCloneRequest(String alertTitle, UserContext
574605 return this .notificationService .createNotification (alertTitle , userContext );
575606 }
576607 }
608+
609+ // This method is based on method getPage in class org.graylog.events.rest.EventDefinitionsResource
610+ @ GET
611+ @ Timed
612+ @ Path ("/paginated" )
613+ @ ApiOperation (value = "Get a paginated list of alerts" )
614+ @ Produces (MediaType .APPLICATION_JSON )
615+ public PageListResponse <GetDataAlertRule > getPage (@ ApiParam (name = "page" ) @ QueryParam ("page" ) @ DefaultValue ("1" ) int page ,
616+ @ ApiParam (name = "per_page" ) @ QueryParam ("per_page" ) @ DefaultValue ("50" ) int perPage ,
617+ @ ApiParam (name = "query" ) @ QueryParam ("query" ) @ DefaultValue ("" ) String query ,
618+ @ ApiParam (name = "sort" ,
619+ value = "The field to sort the result on" ,
620+ required = true ,
621+ allowableValues = "title,description,priority" )
622+ @ DefaultValue (DEFAULT_SORT_FIELD ) @ QueryParam ("sort" ) String sort ,
623+ @ ApiParam (name = "order" , value = "The sort direction" , allowableValues = "asc, desc" )
624+ @ DefaultValue (DEFAULT_SORT_DIRECTION ) @ QueryParam ("order" ) SortOrder order ) {
625+
626+ SearchQuery searchQuery ;
627+ try {
628+ searchQuery = searchQueryParser .parse (query );
629+ } catch (IllegalArgumentException e ) {
630+ throw new BadRequestException ("Invalid argument in search query: " + e .getMessage ());
631+ }
632+ final PaginatedList <AlertRule > result = this .alertRuleService .searchPaginated (
633+ searchQuery ,
634+ alertRule -> true ,
635+ order .toBsonSort (sort ),
636+ page ,
637+ perPage );
638+
639+ PaginatedList <AlertRule > alertRules = new PaginatedList <>(
640+ result .delegate (), result .pagination ().total (), result .pagination ().page (), result .pagination ().perPage ()
641+ );
642+
643+ List <GetDataAlertRule > elements = result .delegate ().stream ().map (this ::constructDataAlertRule ).toList ();
644+
645+ return PageListResponse .create (query , alertRules .pagination (),
646+ result .grandTotal ().orElse (0L ), sort , order , elements , attributes , settings );
647+ }
577648}
0 commit comments