12
12
import org .elasticsearch .search .sort .SortOrder ;
13
13
import org .elasticsearch .xpack .core .ml .action .GetBucketsAction ;
14
14
import org .elasticsearch .xpack .core .ml .action .GetRecordsAction ;
15
+ import org .elasticsearch .xpack .core .ml .action .UpdateJobAction ;
15
16
import org .elasticsearch .xpack .core .ml .calendars .ScheduledEvent ;
16
17
import org .elasticsearch .xpack .core .ml .job .config .AnalysisConfig ;
17
18
import org .elasticsearch .xpack .core .ml .job .config .DataDescription ;
18
19
import org .elasticsearch .xpack .core .ml .job .config .Detector ;
19
20
import org .elasticsearch .xpack .core .ml .job .config .Job ;
21
+ import org .elasticsearch .xpack .core .ml .job .config .JobUpdate ;
20
22
import org .elasticsearch .xpack .core .ml .job .results .AnomalyRecord ;
21
23
import org .elasticsearch .xpack .core .ml .job .results .Bucket ;
22
24
import org .junit .After ;
@@ -193,9 +195,9 @@ public void testScheduledEventWithInterimResults() throws IOException {
193
195
/**
194
196
* Test an open job picks up changes to scheduled events/calendars
195
197
*/
196
- public void testOnlineUpdate () throws Exception {
198
+ public void testAddEventsToOpenJob () throws Exception {
197
199
TimeValue bucketSpan = TimeValue .timeValueMinutes (30 );
198
- Job .Builder job = createJob ("scheduled-events-online-update " , bucketSpan );
200
+ Job .Builder job = createJob ("scheduled-events-add-events-to-open-job " , bucketSpan );
199
201
200
202
long startTime = 1514764800000L ;
201
203
final int bucketCount = 5 ;
@@ -209,7 +211,7 @@ public void testOnlineUpdate() throws Exception {
209
211
210
212
// Now create a calendar and events for the job while it is open
211
213
String calendarId = "test-calendar-online-update" ;
212
- putCalendar (calendarId , Collections .singletonList (job .getId ()), "testOnlineUpdate calendar" );
214
+ putCalendar (calendarId , Collections .singletonList (job .getId ()), "testAddEventsToOpenJob calendar" );
213
215
214
216
List <ScheduledEvent > events = new ArrayList <>();
215
217
long eventStartTime = startTime + (bucketCount + 1 ) * bucketSpan .millis ();
@@ -257,6 +259,81 @@ public void testOnlineUpdate() throws Exception {
257
259
assertEquals (0 , buckets .get (8 ).getScheduledEvents ().size ());
258
260
}
259
261
262
+ /**
263
+ * An open job that later gets added to a calendar, should take the scheduled events into account
264
+ */
265
+ public void testAddOpenedJobToGroupWithCalendar () throws Exception {
266
+ TimeValue bucketSpan = TimeValue .timeValueMinutes (30 );
267
+ String groupName = "opened-calendar-job-group" ;
268
+ Job .Builder job = createJob ("scheduled-events-add-opened-job-to-group-with-calendar" , bucketSpan );
269
+
270
+ long startTime = 1514764800000L ;
271
+ final int bucketCount = 5 ;
272
+
273
+ // Open the job
274
+ openJob (job .getId ());
275
+
276
+ // write some buckets of data
277
+ postData (job .getId (), generateData (startTime , bucketSpan , bucketCount , bucketIndex -> randomIntBetween (100 , 200 ))
278
+ .stream ().collect (Collectors .joining ()));
279
+
280
+ String calendarId = "test-calendar-open-job-update" ;
281
+
282
+ // Create a new calendar referencing groupName
283
+ putCalendar (calendarId , Collections .singletonList (groupName ), "testAddOpenedJobToGroupWithCalendar calendar" );
284
+
285
+ // Put events in the calendar
286
+ List <ScheduledEvent > events = new ArrayList <>();
287
+ long eventStartTime = startTime + (bucketCount + 1 ) * bucketSpan .millis ();
288
+ long eventEndTime = eventStartTime + (long )(1.5 * bucketSpan .millis ());
289
+ events .add (new ScheduledEvent .Builder ().description ("Some Event" )
290
+ .startTime (ZonedDateTime .ofInstant (Instant .ofEpochMilli (eventStartTime ), ZoneOffset .UTC ))
291
+ .endTime (ZonedDateTime .ofInstant (Instant .ofEpochMilli (eventEndTime ), ZoneOffset .UTC ))
292
+ .calendarId (calendarId ).build ());
293
+
294
+ postScheduledEvents (calendarId , events );
295
+
296
+ // Update the job to be a member of the group
297
+ UpdateJobAction .Request jobUpdateRequest = new UpdateJobAction .Request (job .getId (),
298
+ new JobUpdate .Builder (job .getId ()).setGroups (Collections .singletonList (groupName )).build ());
299
+ client ().execute (UpdateJobAction .INSTANCE , jobUpdateRequest ).actionGet ();
300
+
301
+ // Wait until the notification that the job was updated is indexed
302
+ assertBusy (() -> {
303
+ SearchResponse searchResponse = client ().prepareSearch (".ml-notifications" )
304
+ .setSize (1 )
305
+ .addSort ("timestamp" , SortOrder .DESC )
306
+ .setQuery (QueryBuilders .boolQuery ()
307
+ .filter (QueryBuilders .termQuery ("job_id" , job .getId ()))
308
+ .filter (QueryBuilders .termQuery ("level" , "info" ))
309
+ ).get ();
310
+ SearchHit [] hits = searchResponse .getHits ().getHits ();
311
+ assertThat (hits .length , equalTo (1 ));
312
+ assertThat (hits [0 ].getSourceAsMap ().get ("message" ), equalTo ("Job updated: [groups]" ));
313
+ });
314
+
315
+ // write some more buckets of data that cover the scheduled event period
316
+ postData (job .getId (), generateData (startTime + bucketCount * bucketSpan .millis (), bucketSpan , 5 ,
317
+ bucketIndex -> randomIntBetween (100 , 200 ))
318
+ .stream ().collect (Collectors .joining ()));
319
+ // and close
320
+ closeJob (job .getId ());
321
+
322
+ GetBucketsAction .Request getBucketsRequest = new GetBucketsAction .Request (job .getId ());
323
+ List <Bucket > buckets = getBuckets (getBucketsRequest );
324
+
325
+ // the first 6 buckets have no events
326
+ for (int i =0 ; i <=bucketCount ; i ++) {
327
+ assertEquals (0 , buckets .get (i ).getScheduledEvents ().size ());
328
+ }
329
+ // 7th and 8th buckets have the event but the last one does not
330
+ assertEquals (1 , buckets .get (6 ).getScheduledEvents ().size ());
331
+ assertEquals ("Some Event" , buckets .get (6 ).getScheduledEvents ().get (0 ));
332
+ assertEquals (1 , buckets .get (7 ).getScheduledEvents ().size ());
333
+ assertEquals ("Some Event" , buckets .get (7 ).getScheduledEvents ().get (0 ));
334
+ assertEquals (0 , buckets .get (8 ).getScheduledEvents ().size ());
335
+ }
336
+
260
337
private Job .Builder createJob (String jobId , TimeValue bucketSpan ) {
261
338
Detector .Builder detector = new Detector .Builder ("count" , null );
262
339
AnalysisConfig .Builder analysisConfig = new AnalysisConfig .Builder (Collections .singletonList (detector .build ()));
0 commit comments