2525import org .elasticsearch .xpack .core .XPackSettings ;
2626import org .elasticsearch .xpack .core .XPackField ;
2727import org .elasticsearch .xpack .core .ml .MachineLearningFeatureSetUsage ;
28- import org .elasticsearch .xpack .core .ml .MlMetadata ;
2928import org .elasticsearch .xpack .core .ml .action .GetDatafeedsStatsAction ;
3029import org .elasticsearch .xpack .core .ml .action .GetJobsStatsAction ;
3130import org .elasticsearch .xpack .core .ml .datafeed .DatafeedState ;
3231import org .elasticsearch .xpack .core .ml .job .config .Job ;
3332import org .elasticsearch .xpack .core .ml .job .config .JobState ;
33+ import org .elasticsearch .xpack .ml .job .JobManagerHolder ;
3434import org .elasticsearch .xpack .ml .process .NativeController ;
3535import org .elasticsearch .xpack .ml .process .NativeControllerHolder ;
3636import org .elasticsearch .xpack .core .ml .job .process .autodetect .state .ModelSizeStats ;
4747import java .util .Map ;
4848import java .util .Objects ;
4949import java .util .concurrent .TimeoutException ;
50+ import java .util .stream .Collectors ;
5051
5152public class MachineLearningFeatureSet implements XPackFeatureSet {
5253
@@ -60,15 +61,17 @@ public class MachineLearningFeatureSet implements XPackFeatureSet {
6061 private final XPackLicenseState licenseState ;
6162 private final ClusterService clusterService ;
6263 private final Client client ;
64+ private final JobManagerHolder jobManagerHolder ;
6365 private final Map <String , Object > nativeCodeInfo ;
6466
6567 @ Inject
6668 public MachineLearningFeatureSet (Environment environment , ClusterService clusterService , Client client ,
67- @ Nullable XPackLicenseState licenseState ) {
69+ @ Nullable XPackLicenseState licenseState , JobManagerHolder jobManagerHolder ) {
6870 this .enabled = XPackSettings .MACHINE_LEARNING_ENABLED .get (environment .settings ());
6971 this .clusterService = Objects .requireNonNull (clusterService );
7072 this .client = Objects .requireNonNull (client );
7173 this .licenseState = licenseState ;
74+ this .jobManagerHolder = jobManagerHolder ;
7275 Map <String , Object > nativeCodeInfo = NativeController .UNKNOWN_NATIVE_CODE_INFO ;
7376 // Don't try to get the native code version if ML is disabled - it causes too much controversy
7477 // if ML has been disabled because of some OS incompatibility. Also don't try to get the native
@@ -133,7 +136,7 @@ public Map<String, Object> nativeCodeInfo() {
133136 @ Override
134137 public void usage (ActionListener <XPackFeatureSet .Usage > listener ) {
135138 ClusterState state = clusterService .state ();
136- new Retriever (client , MlMetadata . getMlMetadata ( state ) , available (), enabled (), mlNodeCount (state )).execute (listener );
139+ new Retriever (client , jobManagerHolder , available (), enabled (), mlNodeCount (state )).execute (listener );
137140 }
138141
139142 private int mlNodeCount (final ClusterState clusterState ) {
@@ -153,16 +156,16 @@ private int mlNodeCount(final ClusterState clusterState) {
153156 public static class Retriever {
154157
155158 private final Client client ;
156- private final MlMetadata mlMetadata ;
159+ private final JobManagerHolder jobManagerHolder ;
157160 private final boolean available ;
158161 private final boolean enabled ;
159162 private Map <String , Object > jobsUsage ;
160163 private Map <String , Object > datafeedsUsage ;
161164 private int nodeCount ;
162165
163- public Retriever (Client client , MlMetadata mlMetadata , boolean available , boolean enabled , int nodeCount ) {
166+ public Retriever (Client client , JobManagerHolder jobManagerHolder , boolean available , boolean enabled , int nodeCount ) {
164167 this .client = Objects .requireNonNull (client );
165- this .mlMetadata = mlMetadata ;
168+ this .jobManagerHolder = jobManagerHolder ;
166169 this .available = available ;
167170 this .enabled = enabled ;
168171 this .jobsUsage = new LinkedHashMap <>();
@@ -171,7 +174,8 @@ public Retriever(Client client, MlMetadata mlMetadata, boolean available, boolea
171174 }
172175
173176 public void execute (ActionListener <Usage > listener ) {
174- if (enabled == false ) {
177+ // empty holder means either ML disabled or transport client mode
178+ if (jobManagerHolder .isEmpty ()) {
175179 listener .onResponse (
176180 new MachineLearningFeatureSetUsage (available , enabled , Collections .emptyMap (), Collections .emptyMap (), 0 ));
177181 return ;
@@ -191,20 +195,19 @@ public void execute(ActionListener<Usage> listener) {
191195 GetJobsStatsAction .Request jobStatsRequest = new GetJobsStatsAction .Request (MetaData .ALL );
192196 ActionListener <GetJobsStatsAction .Response > jobStatsListener = ActionListener .wrap (
193197 response -> {
194- addJobsUsage (response );
195- GetDatafeedsStatsAction .Request datafeedStatsRequest =
196- new GetDatafeedsStatsAction .Request (GetDatafeedsStatsAction .ALL );
197- client .execute (GetDatafeedsStatsAction .INSTANCE , datafeedStatsRequest ,
198- datafeedStatsListener );
199- },
200- listener ::onFailure
201- );
198+ jobManagerHolder .getJobManager ().expandJobs (MetaData .ALL , true , ActionListener .wrap (jobs -> {
199+ addJobsUsage (response , jobs .results ());
200+ GetDatafeedsStatsAction .Request datafeedStatsRequest = new GetDatafeedsStatsAction .Request (
201+ GetDatafeedsStatsAction .ALL );
202+ client .execute (GetDatafeedsStatsAction .INSTANCE , datafeedStatsRequest , datafeedStatsListener );
203+ }, listener ::onFailure ));
204+ }, listener ::onFailure );
202205
203206 // Step 0. Kick off the chain of callbacks by requesting jobs stats
204207 client .execute (GetJobsStatsAction .INSTANCE , jobStatsRequest , jobStatsListener );
205208 }
206209
207- private void addJobsUsage (GetJobsStatsAction .Response response ) {
210+ private void addJobsUsage (GetJobsStatsAction .Response response , List < Job > jobs ) {
208211 StatsAccumulator allJobsDetectorsStats = new StatsAccumulator ();
209212 StatsAccumulator allJobsModelSizeStats = new StatsAccumulator ();
210213 ForecastStats allJobsForecastStats = new ForecastStats ();
@@ -214,11 +217,11 @@ private void addJobsUsage(GetJobsStatsAction.Response response) {
214217 Map <JobState , StatsAccumulator > modelSizeStatsByState = new HashMap <>();
215218 Map <JobState , ForecastStats > forecastStatsByState = new HashMap <>();
216219
217- Map <String , Job > jobs = mlMetadata .getJobs ();
218220 List <GetJobsStatsAction .Response .JobStats > jobsStats = response .getResponse ().results ();
221+ Map <String , Job > jobMap = jobs .stream ().collect (Collectors .toMap (Job ::getId , item -> item ));
219222 for (GetJobsStatsAction .Response .JobStats jobStats : jobsStats ) {
220223 ModelSizeStats modelSizeStats = jobStats .getModelSizeStats ();
221- int detectorsCount = jobs .get (jobStats .getJobId ()).getAnalysisConfig ()
224+ int detectorsCount = jobMap .get (jobStats .getJobId ()).getAnalysisConfig ()
222225 .getDetectors ().size ();
223226 double modelSize = modelSizeStats == null ? 0.0
224227 : jobStats .getModelSizeStats ().getModelBytes ();
0 commit comments