29
29
import org .elasticsearch .cluster .service .ClusterApplierService ;
30
30
import org .elasticsearch .cluster .service .ClusterService ;
31
31
import org .elasticsearch .cluster .service .MasterService ;
32
+ import org .elasticsearch .common .CheckedSupplier ;
32
33
import org .elasticsearch .common .Strings ;
33
34
import org .elasticsearch .common .collect .ImmutableOpenMap ;
34
35
import org .elasticsearch .common .settings .ClusterSettings ;
62
63
import org .elasticsearch .xpack .core .ml .job .process .autodetect .state .ModelSizeStats ;
63
64
import org .elasticsearch .xpack .core .ml .job .process .autodetect .state .ModelSnapshot ;
64
65
import org .elasticsearch .xpack .core .ml .job .process .autodetect .state .Quantiles ;
66
+ import org .elasticsearch .xpack .core .ml .job .process .autodetect .state .TimingStats ;
65
67
import org .elasticsearch .xpack .core .ml .utils .ToXContentParams ;
66
68
import org .elasticsearch .xpack .ml .MlSingleNodeTestCase ;
67
69
import org .elasticsearch .xpack .ml .inference .ingest .InferenceProcessor ;
88
90
import java .util .Set ;
89
91
import java .util .concurrent .CountDownLatch ;
90
92
import java .util .concurrent .atomic .AtomicReference ;
93
+ import java .util .function .Consumer ;
91
94
import java .util .stream .Collectors ;
92
95
93
96
import static org .elasticsearch .xpack .core .ml .job .persistence .AnomalyDetectorsIndex .createStateIndexAndAliasIfNecessary ;
@@ -106,6 +109,7 @@ public class JobResultsProviderIT extends MlSingleNodeTestCase {
106
109
107
110
private JobResultsProvider jobProvider ;
108
111
private ResultsPersisterService resultsPersisterService ;
112
+ private JobResultsPersister jobResultsPersister ;
109
113
private AnomalyDetectionAuditor auditor ;
110
114
111
115
@ Before
@@ -131,6 +135,7 @@ public void createComponents() throws Exception {
131
135
132
136
OriginSettingClient originSettingClient = new OriginSettingClient (client (), ClientHelper .ML_ORIGIN );
133
137
resultsPersisterService = new ResultsPersisterService (tp , originSettingClient , clusterService , builder .build ());
138
+ jobResultsPersister = new JobResultsPersister (originSettingClient , resultsPersisterService );
134
139
auditor = new AnomalyDetectionAuditor (client (), clusterService );
135
140
waitForMlTemplates ();
136
141
}
@@ -406,6 +411,96 @@ public void testRemoveJobFromCalendar() throws Exception {
406
411
}
407
412
}
408
413
414
+ public void testGetDataCountsModelSizeAndTimingStatsWithNoDocs () throws Exception {
415
+ Job .Builder job = new Job .Builder ("first_job" );
416
+ job .setAnalysisConfig (createAnalysisConfig ("by_field_1" , Collections .emptyList ()));
417
+ job .setDataDescription (new DataDescription .Builder ());
418
+
419
+ // Put first job. This should create the results index as it's the first job.
420
+ client ().execute (PutJobAction .INSTANCE , new PutJobAction .Request (job )).actionGet ();
421
+ AtomicReference <DataCounts > dataCountsAtomicReference = new AtomicReference <>();
422
+ AtomicReference <ModelSizeStats > modelSizeStatsAtomicReference = new AtomicReference <>();
423
+ AtomicReference <TimingStats > timingStatsAtomicReference = new AtomicReference <>();
424
+ AtomicReference <Exception > exceptionAtomicReference = new AtomicReference <>();
425
+
426
+ getDataCountsModelSizeAndTimingStats (
427
+ job .getId (),
428
+ dataCountsAtomicReference ::set ,
429
+ modelSizeStatsAtomicReference ::set ,
430
+ timingStatsAtomicReference ::set ,
431
+ exceptionAtomicReference ::set
432
+ );
433
+
434
+ if (exceptionAtomicReference .get () != null ) {
435
+ throw exceptionAtomicReference .get ();
436
+ }
437
+
438
+ assertThat (dataCountsAtomicReference .get ().getJobId (), equalTo (job .getId ()));
439
+ assertThat (modelSizeStatsAtomicReference .get ().getJobId (), equalTo (job .getId ()));
440
+ assertThat (timingStatsAtomicReference .get ().getJobId (), equalTo (job .getId ()));
441
+ }
442
+
443
+ public void testGetDataCountsModelSizeAndTimingStatsWithSomeDocs () throws Exception {
444
+ Job .Builder job = new Job .Builder ("first_job" );
445
+ job .setAnalysisConfig (createAnalysisConfig ("by_field_1" , Collections .emptyList ()));
446
+ job .setDataDescription (new DataDescription .Builder ());
447
+
448
+ // Put first job. This should create the results index as it's the first job.
449
+ client ().execute (PutJobAction .INSTANCE , new PutJobAction .Request (job )).actionGet ();
450
+ AtomicReference <DataCounts > dataCountsAtomicReference = new AtomicReference <>();
451
+ AtomicReference <ModelSizeStats > modelSizeStatsAtomicReference = new AtomicReference <>();
452
+ AtomicReference <TimingStats > timingStatsAtomicReference = new AtomicReference <>();
453
+ AtomicReference <Exception > exceptionAtomicReference = new AtomicReference <>();
454
+
455
+ CheckedSupplier <Void , Exception > setOrThrow = () -> {
456
+ getDataCountsModelSizeAndTimingStats (
457
+ job .getId (),
458
+ dataCountsAtomicReference ::set ,
459
+ modelSizeStatsAtomicReference ::set ,
460
+ timingStatsAtomicReference ::set ,
461
+ exceptionAtomicReference ::set
462
+ );
463
+
464
+ if (exceptionAtomicReference .get () != null ) {
465
+ throw exceptionAtomicReference .get ();
466
+ }
467
+ return null ;
468
+ };
469
+
470
+ ModelSizeStats storedModelSizeStats = new ModelSizeStats .Builder (job .getId ()).setModelBytes (10L ).build ();
471
+ jobResultsPersister .persistModelSizeStats (storedModelSizeStats , () -> false );
472
+ jobResultsPersister .commitResultWrites (job .getId ());
473
+
474
+ setOrThrow .get ();
475
+ assertThat (dataCountsAtomicReference .get ().getJobId (), equalTo (job .getId ()));
476
+ assertThat (modelSizeStatsAtomicReference .get (), equalTo (storedModelSizeStats ));
477
+ assertThat (timingStatsAtomicReference .get ().getJobId (), equalTo (job .getId ()));
478
+
479
+ TimingStats storedTimingStats = new TimingStats (job .getId ());
480
+ storedTimingStats .updateStats (10 );
481
+
482
+ jobResultsPersister .bulkPersisterBuilder (job .getId ()).persistTimingStats (storedTimingStats ).executeRequest ();
483
+ jobResultsPersister .commitResultWrites (job .getId ());
484
+
485
+ setOrThrow .get ();
486
+
487
+ assertThat (dataCountsAtomicReference .get ().getJobId (), equalTo (job .getId ()));
488
+ assertThat (modelSizeStatsAtomicReference .get (), equalTo (storedModelSizeStats ));
489
+ assertThat (timingStatsAtomicReference .get (), equalTo (storedTimingStats ));
490
+
491
+ DataCounts storedDataCounts = new DataCounts (job .getId ());
492
+ storedDataCounts .incrementInputBytes (1L );
493
+ storedDataCounts .incrementMissingFieldCount (1L );
494
+ JobDataCountsPersister jobDataCountsPersister = new JobDataCountsPersister (client (), resultsPersisterService , auditor );
495
+ jobDataCountsPersister .persistDataCounts (job .getId (), storedDataCounts );
496
+ jobResultsPersister .commitResultWrites (job .getId ());
497
+
498
+ setOrThrow .get ();
499
+ assertThat (dataCountsAtomicReference .get (), equalTo (storedDataCounts ));
500
+ assertThat (modelSizeStatsAtomicReference .get (), equalTo (storedModelSizeStats ));
501
+ assertThat (timingStatsAtomicReference .get (), equalTo (storedTimingStats ));
502
+ }
503
+
409
504
private Map <String , Object > getIndexMappingProperties (String index ) {
410
505
GetMappingsRequest request = new GetMappingsRequest ().indices (index );
411
506
GetMappingsResponse response = client ().execute (GetMappingsAction .INSTANCE , request ).actionGet ();
@@ -498,6 +593,26 @@ private Calendar getCalendar(String calendarId) throws Exception {
498
593
return calendarHolder .get ();
499
594
}
500
595
596
+ private void getDataCountsModelSizeAndTimingStats (
597
+ String jobId ,
598
+ Consumer <DataCounts > dataCountsConsumer ,
599
+ Consumer <ModelSizeStats > modelSizeStatsConsumer ,
600
+ Consumer <TimingStats > timingStatsConsumer ,
601
+ Consumer <Exception > exceptionConsumer
602
+ ) throws Exception {
603
+ CountDownLatch latch = new CountDownLatch (1 );
604
+ jobProvider .getDataCountsModelSizeAndTimingStats (jobId , (dataCounts , modelSizeStats , timingStats ) -> {
605
+ dataCountsConsumer .accept (dataCounts );
606
+ modelSizeStatsConsumer .accept (modelSizeStats );
607
+ timingStatsConsumer .accept (timingStats );
608
+ latch .countDown ();
609
+ }, e -> {
610
+ exceptionConsumer .accept (e );
611
+ latch .countDown ();
612
+ });
613
+ latch .await ();
614
+ }
615
+
501
616
public void testScheduledEventsForJobs () throws Exception {
502
617
Job .Builder jobA = createJob ("job_a" );
503
618
Job .Builder jobB = createJob ("job_b" );
0 commit comments