Skip to content

Commit 067f5d3

Browse files
author
David Roberts
authored
[ML] Fix ML usage action when ML sub-features are disabled (elastic#97820)
To support differentiation of serverless product types it's now possible to disable subsets of ML functionality. The ML usage action was not updated to reflect this, so still attempted to call actions to find out about usage of disabled sub-features. Because that action is designed to never fail, it actually returned reasonable output in these cases. However, it generated a lot of log spam with warnings about calling non-existent actions. This PR adjusts the logic of the ML usage action to take into account which sub-features might be disabled, and avoid calling actions which won't exist in this case.
1 parent 3f9279d commit 067f5d3

File tree

5 files changed

+556
-300
lines changed

5 files changed

+556
-300
lines changed

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -885,8 +885,9 @@ public Collection<Object> createComponents(
885885
IndicesService indicesService
886886
) {
887887
if (enabled == false) {
888-
// special holder for @link(MachineLearningFeatureSetUsage) which needs access to job manager, empty if ML is disabled
889-
return List.of(new JobManagerHolder());
888+
// Holders for @link(MachineLearningFeatureSetUsage) which needs access to job manager and ML extension,
889+
// both empty if ML is disabled
890+
return List.of(new JobManagerHolder(), new MachineLearningExtensionHolder());
890891
}
891892

892893
machineLearningExtension.get().configure(environment.settings());
@@ -1247,7 +1248,8 @@ public Collection<Object> createComponents(
12471248
trainedModelAssignmentService,
12481249
trainedModelAllocationClusterServiceSetOnce.get(),
12491250
deploymentManager.get(),
1250-
nodeAvailabilityZoneMapper
1251+
nodeAvailabilityZoneMapper,
1252+
new MachineLearningExtensionHolder(machineLearningExtension.get())
12511253
);
12521254
}
12531255

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.ml;
9+
10+
import org.elasticsearch.node.Node;
11+
12+
import java.util.Objects;
13+
14+
/**
15+
* Wrapper for the {@link MachineLearningExtension} interface that allows it to be used
16+
* given the way {@link Node} does Guice bindings for plugin components.
17+
* TODO: remove this class entirely once Guice is removed entirely.
18+
*/
19+
public class MachineLearningExtensionHolder {
20+
21+
private final MachineLearningExtension machineLearningExtension;
22+
23+
/**
24+
* Used by Guice, and in cases where ML is disabled.
25+
*/
26+
public MachineLearningExtensionHolder() {
27+
this.machineLearningExtension = null;
28+
}
29+
30+
public MachineLearningExtensionHolder(MachineLearningExtension machineLearningExtension) {
31+
this.machineLearningExtension = Objects.requireNonNull(machineLearningExtension);
32+
}
33+
34+
public boolean isEmpty() {
35+
return machineLearningExtension == null;
36+
}
37+
38+
public MachineLearningExtension getMachineLearningExtension() {
39+
return machineLearningExtension;
40+
}
41+
}

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearningUsageTransportAction.java

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public class MachineLearningUsageTransportAction extends XPackUsageFeatureTransp
7373
private final Client client;
7474
private final XPackLicenseState licenseState;
7575
private final JobManagerHolder jobManagerHolder;
76+
private final MachineLearningExtension machineLearningExtension;
7677
private final boolean enabled;
7778

7879
@Inject
@@ -85,7 +86,8 @@ public MachineLearningUsageTransportAction(
8586
Environment environment,
8687
Client client,
8788
XPackLicenseState licenseState,
88-
JobManagerHolder jobManagerHolder
89+
JobManagerHolder jobManagerHolder,
90+
MachineLearningExtensionHolder machineLearningExtensionHolder
8991
) {
9092
super(
9193
XPackUsageFeatureAction.MACHINE_LEARNING.name(),
@@ -98,6 +100,11 @@ public MachineLearningUsageTransportAction(
98100
this.client = new OriginSettingClient(client, ML_ORIGIN);
99101
this.licenseState = licenseState;
100102
this.jobManagerHolder = jobManagerHolder;
103+
if (machineLearningExtensionHolder.isEmpty()) {
104+
this.machineLearningExtension = new DefaultMachineLearningExtension();
105+
} else {
106+
this.machineLearningExtension = machineLearningExtensionHolder.getMachineLearningExtension();
107+
}
101108
this.enabled = XPackSettings.MACHINE_LEARNING_ENABLED.get(environment.settings());
102109
}
103110

@@ -187,10 +194,18 @@ protected void masterOperation(
187194
dataframeAnalyticsStatsRequest.setPageParams(new PageParams(0, 10_000));
188195
ActionListener<GetDatafeedsStatsAction.Response> datafeedStatsListener = ActionListener.wrap(response -> {
189196
addDatafeedsUsage(response, datafeedsUsage);
190-
client.execute(GetDataFrameAnalyticsStatsAction.INSTANCE, dataframeAnalyticsStatsRequest, dataframeAnalyticsStatsListener);
197+
if (machineLearningExtension.isDataFrameAnalyticsEnabled()) {
198+
client.execute(GetDataFrameAnalyticsStatsAction.INSTANCE, dataframeAnalyticsStatsRequest, dataframeAnalyticsStatsListener);
199+
} else {
200+
addInferenceUsage(inferenceUsageListener);
201+
}
191202
}, e -> {
192203
logger.warn("Failed to get datafeed stats to include in ML usage", e);
193-
client.execute(GetDataFrameAnalyticsStatsAction.INSTANCE, dataframeAnalyticsStatsRequest, dataframeAnalyticsStatsListener);
204+
if (machineLearningExtension.isDataFrameAnalyticsEnabled()) {
205+
client.execute(GetDataFrameAnalyticsStatsAction.INSTANCE, dataframeAnalyticsStatsRequest, dataframeAnalyticsStatsListener);
206+
} else {
207+
addInferenceUsage(inferenceUsageListener);
208+
}
194209
});
195210

196211
// Step 1. Extract usage from jobs stats and then request stats for all datafeeds
@@ -210,8 +225,14 @@ protected void masterOperation(
210225
);
211226

212227
// Step 0. Kick off the chain of callbacks by requesting jobs stats
213-
GetJobsStatsAction.Request jobStatsRequest = new GetJobsStatsAction.Request(Metadata.ALL);
214-
client.execute(GetJobsStatsAction.INSTANCE, jobStatsRequest, jobStatsListener);
228+
if (machineLearningExtension.isAnomalyDetectionEnabled()) {
229+
GetJobsStatsAction.Request jobStatsRequest = new GetJobsStatsAction.Request(Metadata.ALL);
230+
client.execute(GetJobsStatsAction.INSTANCE, jobStatsRequest, jobStatsListener);
231+
} else if (machineLearningExtension.isDataFrameAnalyticsEnabled()) {
232+
client.execute(GetDataFrameAnalyticsStatsAction.INSTANCE, dataframeAnalyticsStatsRequest, dataframeAnalyticsStatsListener);
233+
} else {
234+
addInferenceUsage(inferenceUsageListener);
235+
}
215236
}
216237

217238
private void addJobsUsage(GetJobsStatsAction.Response response, List<Job> jobs, Map<String, Object> jobsUsage) {
@@ -361,23 +382,27 @@ private void addDataFrameAnalyticsUsage(GetDataFrameAnalyticsAction.Response res
361382
}
362383

363384
private void addInferenceUsage(ActionListener<Map<String, Object>> listener) {
364-
GetTrainedModelsAction.Request getModelsRequest = new GetTrainedModelsAction.Request(
365-
"*",
366-
Collections.emptyList(),
367-
Collections.emptySet()
368-
);
369-
getModelsRequest.setPageParams(new PageParams(0, 10_000));
370-
client.execute(GetTrainedModelsAction.INSTANCE, getModelsRequest, ActionListener.wrap(getModelsResponse -> {
371-
GetTrainedModelsStatsAction.Request getStatsRequest = new GetTrainedModelsStatsAction.Request("*");
372-
getStatsRequest.setPageParams(new PageParams(0, 10_000));
373-
client.execute(GetTrainedModelsStatsAction.INSTANCE, getStatsRequest, ActionListener.wrap(getStatsResponse -> {
374-
Map<String, Object> inferenceUsage = new LinkedHashMap<>();
375-
addInferenceIngestUsage(getStatsResponse, inferenceUsage);
376-
addTrainedModelStats(getModelsResponse, getStatsResponse, inferenceUsage);
377-
addDeploymentStats(getStatsResponse, inferenceUsage);
378-
listener.onResponse(inferenceUsage);
385+
if (machineLearningExtension.isDataFrameAnalyticsEnabled() || machineLearningExtension.isNlpEnabled()) {
386+
GetTrainedModelsAction.Request getModelsRequest = new GetTrainedModelsAction.Request(
387+
"*",
388+
Collections.emptyList(),
389+
Collections.emptySet()
390+
);
391+
getModelsRequest.setPageParams(new PageParams(0, 10_000));
392+
client.execute(GetTrainedModelsAction.INSTANCE, getModelsRequest, ActionListener.wrap(getModelsResponse -> {
393+
GetTrainedModelsStatsAction.Request getStatsRequest = new GetTrainedModelsStatsAction.Request("*");
394+
getStatsRequest.setPageParams(new PageParams(0, 10_000));
395+
client.execute(GetTrainedModelsStatsAction.INSTANCE, getStatsRequest, ActionListener.wrap(getStatsResponse -> {
396+
Map<String, Object> inferenceUsage = new LinkedHashMap<>();
397+
addInferenceIngestUsage(getStatsResponse, inferenceUsage);
398+
addTrainedModelStats(getModelsResponse, getStatsResponse, inferenceUsage);
399+
addDeploymentStats(getStatsResponse, inferenceUsage);
400+
listener.onResponse(inferenceUsage);
401+
}, listener::onFailure));
379402
}, listener::onFailure));
380-
}, listener::onFailure));
403+
} else {
404+
listener.onResponse(Map.of());
405+
}
381406
}
382407

383408
private void addDeploymentStats(GetTrainedModelsStatsAction.Response statsResponse, Map<String, Object> inferenceUsage) {

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/process/MlControllerHolder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*/
1818
public class MlControllerHolder {
1919

20-
private MlController mlController;
20+
private final MlController mlController;
2121

2222
public MlControllerHolder(MlController mlController) {
2323
this.mlController = Objects.requireNonNull(mlController);

0 commit comments

Comments
 (0)