2626import org .elasticsearch .xpack .core .XPackSettings ;
2727import org .elasticsearch .xpack .core .XPackField ;
2828import org .elasticsearch .xpack .core .ml .MachineLearningFeatureSetUsage ;
29- import org .elasticsearch .xpack .core .ml .MlMetadata ;
3029import org .elasticsearch .xpack .core .ml .action .GetDatafeedsStatsAction ;
3130import org .elasticsearch .xpack .core .ml .action .GetJobsStatsAction ;
3231import org .elasticsearch .xpack .core .ml .datafeed .DatafeedState ;
3332import org .elasticsearch .xpack .core .ml .job .config .Job ;
3433import org .elasticsearch .xpack .core .ml .job .config .JobState ;
34+ import org .elasticsearch .xpack .ml .job .JobManagerHolder ;
3535import org .elasticsearch .xpack .ml .process .NativeController ;
3636import org .elasticsearch .xpack .ml .process .NativeControllerHolder ;
3737import org .elasticsearch .xpack .core .ml .job .process .autodetect .state .ModelSizeStats ;
4848import java .util .Map ;
4949import java .util .Objects ;
5050import java .util .concurrent .TimeoutException ;
51+ import java .util .stream .Collectors ;
5152
5253public class MachineLearningFeatureSet implements XPackFeatureSet {
5354
@@ -61,15 +62,17 @@ public class MachineLearningFeatureSet implements XPackFeatureSet {
6162 private final XPackLicenseState licenseState ;
6263 private final ClusterService clusterService ;
6364 private final Client client ;
65+ private final JobManagerHolder jobManagerHolder ;
6466 private final Map <String , Object > nativeCodeInfo ;
6567
6668 @ Inject
6769 public MachineLearningFeatureSet (Environment environment , ClusterService clusterService , Client client ,
68- @ Nullable XPackLicenseState licenseState ) {
70+ @ Nullable XPackLicenseState licenseState , JobManagerHolder jobManagerHolder ) {
6971 this .enabled = XPackSettings .MACHINE_LEARNING_ENABLED .get (environment .settings ());
7072 this .clusterService = Objects .requireNonNull (clusterService );
7173 this .client = Objects .requireNonNull (client );
7274 this .licenseState = licenseState ;
75+ this .jobManagerHolder = jobManagerHolder ;
7376 Map <String , Object > nativeCodeInfo = NativeController .UNKNOWN_NATIVE_CODE_INFO ;
7477 // Don't try to get the native code version if ML is disabled - it causes too much controversy
7578 // if ML has been disabled because of some OS incompatibility. Also don't try to get the native
@@ -135,7 +138,7 @@ public Map<String, Object> nativeCodeInfo() {
135138 @ Override
136139 public void usage (ActionListener <XPackFeatureSet .Usage > listener ) {
137140 ClusterState state = clusterService .state ();
138- new Retriever (client , MlMetadata . getMlMetadata ( state ) , available (), enabled (), mlNodeCount (state )).execute (listener );
141+ new Retriever (client , jobManagerHolder , available (), enabled (), mlNodeCount (state )).execute (listener );
139142 }
140143
141144 private int mlNodeCount (final ClusterState clusterState ) {
@@ -156,16 +159,16 @@ private int mlNodeCount(final ClusterState clusterState) {
156159 public static class Retriever {
157160
158161 private final Client client ;
159- private final MlMetadata mlMetadata ;
162+ private final JobManagerHolder jobManagerHolder ;
160163 private final boolean available ;
161164 private final boolean enabled ;
162165 private Map <String , Object > jobsUsage ;
163166 private Map <String , Object > datafeedsUsage ;
164167 private int nodeCount ;
165168
166- public Retriever (Client client , MlMetadata mlMetadata , boolean available , boolean enabled , int nodeCount ) {
169+ public Retriever (Client client , JobManagerHolder jobManagerHolder , boolean available , boolean enabled , int nodeCount ) {
167170 this .client = Objects .requireNonNull (client );
168- this .mlMetadata = mlMetadata ;
171+ this .jobManagerHolder = jobManagerHolder ;
169172 this .available = available ;
170173 this .enabled = enabled ;
171174 this .jobsUsage = new LinkedHashMap <>();
@@ -174,7 +177,8 @@ public Retriever(Client client, MlMetadata mlMetadata, boolean available, boolea
174177 }
175178
176179 public void execute (ActionListener <Usage > listener ) {
177- if (enabled == false ) {
180+ // empty holder means either ML disabled or transport client mode
181+ if (jobManagerHolder .isEmpty ()) {
178182 listener .onResponse (
179183 new MachineLearningFeatureSetUsage (available , enabled , Collections .emptyMap (), Collections .emptyMap (), 0 ));
180184 return ;
@@ -194,20 +198,19 @@ public void execute(ActionListener<Usage> listener) {
194198 GetJobsStatsAction .Request jobStatsRequest = new GetJobsStatsAction .Request (MetaData .ALL );
195199 ActionListener <GetJobsStatsAction .Response > jobStatsListener = ActionListener .wrap (
196200 response -> {
197- addJobsUsage (response );
198- GetDatafeedsStatsAction .Request datafeedStatsRequest =
199- new GetDatafeedsStatsAction .Request (GetDatafeedsStatsAction .ALL );
200- client .execute (GetDatafeedsStatsAction .INSTANCE , datafeedStatsRequest ,
201- datafeedStatsListener );
202- },
203- listener ::onFailure
204- );
201+ jobManagerHolder .getJobManager ().expandJobs (MetaData .ALL , true , ActionListener .wrap (jobs -> {
202+ addJobsUsage (response , jobs .results ());
203+ GetDatafeedsStatsAction .Request datafeedStatsRequest = new GetDatafeedsStatsAction .Request (
204+ GetDatafeedsStatsAction .ALL );
205+ client .execute (GetDatafeedsStatsAction .INSTANCE , datafeedStatsRequest , datafeedStatsListener );
206+ }, listener ::onFailure ));
207+ }, listener ::onFailure );
205208
206209 // Step 0. Kick off the chain of callbacks by requesting jobs stats
207210 client .execute (GetJobsStatsAction .INSTANCE , jobStatsRequest , jobStatsListener );
208211 }
209212
210- private void addJobsUsage (GetJobsStatsAction .Response response ) {
213+ private void addJobsUsage (GetJobsStatsAction .Response response , List < Job > jobs ) {
211214 StatsAccumulator allJobsDetectorsStats = new StatsAccumulator ();
212215 StatsAccumulator allJobsModelSizeStats = new StatsAccumulator ();
213216 ForecastStats allJobsForecastStats = new ForecastStats ();
@@ -217,11 +220,11 @@ private void addJobsUsage(GetJobsStatsAction.Response response) {
217220 Map <JobState , StatsAccumulator > modelSizeStatsByState = new HashMap <>();
218221 Map <JobState , ForecastStats > forecastStatsByState = new HashMap <>();
219222
220- Map <String , Job > jobs = mlMetadata .getJobs ();
221223 List <GetJobsStatsAction .Response .JobStats > jobsStats = response .getResponse ().results ();
224+ Map <String , Job > jobMap = jobs .stream ().collect (Collectors .toMap (Job ::getId , item -> item ));
222225 for (GetJobsStatsAction .Response .JobStats jobStats : jobsStats ) {
223226 ModelSizeStats modelSizeStats = jobStats .getModelSizeStats ();
224- int detectorsCount = jobs .get (jobStats .getJobId ()).getAnalysisConfig ()
227+ int detectorsCount = jobMap .get (jobStats .getJobId ()).getAnalysisConfig ()
225228 .getDetectors ().size ();
226229 double modelSize = modelSizeStats == null ? 0.0
227230 : jobStats .getModelSizeStats ().getModelBytes ();
0 commit comments