diff --git a/muted-tests.yml b/muted-tests.yml index a803a7ec315ca..cb749e3c1e3e6 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -456,27 +456,12 @@ tests: - class: org.elasticsearch.xpack.ml.integration.BasicDistributedJobsIT method: testFailOverBasics issue: https://github.com/elastic/elasticsearch/issues/136778 -- class: org.elasticsearch.xpack.inference.qa.mixed.CohereServiceMixedIT - method: testRerank - issue: https://github.com/elastic/elasticsearch/issues/136872 -- class: org.elasticsearch.xpack.inference.qa.mixed.CohereServiceMixedIT - method: testCohereEmbeddings - issue: https://github.com/elastic/elasticsearch/issues/136779 - class: org.elasticsearch.xpack.search.CrossClusterAsyncSearchIT method: testRemoteClusterOnlyCCSWithFailuresOnAllShards issue: https://github.com/elastic/elasticsearch/issues/136894 -- class: org.elasticsearch.xpack.esql.qa.mixed.FieldExtractorIT - method: testTextFieldWithIpSubfieldMalformed {STORED} - issue: https://github.com/elastic/elasticsearch/issues/136917 -- class: org.elasticsearch.xpack.esql.qa.mixed.FieldExtractorIT - method: testTextFieldWithKeywordSubfield {STORED} - issue: https://github.com/elastic/elasticsearch/issues/136918 - class: org.elasticsearch.xpack.esql.optimizer.rules.logical.HoistRemoteEnrichTopNTests method: testTopNSortExpressionWithinRemoteEnrichAliasing issue: https://github.com/elastic/elasticsearch/issues/136957 -- class: org.elasticsearch.xpack.esql.qa.mixed.FieldExtractorIT - method: testByteFieldWithIntSubfieldTooBig {NONE} - issue: https://github.com/elastic/elasticsearch/issues/137034 - class: org.elasticsearch.xpack.esql.qa.single_node.GenerativeMetricsIT method: test issue: https://github.com/elastic/elasticsearch/issues/137071 diff --git a/x-pack/plugin/ml/src/main/java/module-info.java b/x-pack/plugin/ml/src/main/java/module-info.java index 1013b8e052e4c..a7c498b0a4e61 100644 --- a/x-pack/plugin/ml/src/main/java/module-info.java +++ b/x-pack/plugin/ml/src/main/java/module-info.java @@ -32,6 +32,7 @@ opens org.elasticsearch.xpack.ml to org.elasticsearch.painless.spi; // whitelist resource access opens org.elasticsearch.xpack.ml.utils; // for exact.properties access + provides org.elasticsearch.features.FeatureSpecification with org.elasticsearch.xpack.ml.MachineLearningFeatures; provides org.elasticsearch.painless.spi.PainlessExtension with org.elasticsearch.xpack.ml.MachineLearningPainlessExtension; provides org.elasticsearch.xpack.autoscaling.AutoscalingExtension with org.elasticsearch.xpack.ml.autoscaling.MlAutoscalingExtension; diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearningFeatures.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearningFeatures.java new file mode 100644 index 0000000000000..166ed59cdbeb5 --- /dev/null +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearningFeatures.java @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.ml; + +import org.elasticsearch.features.FeatureSpecification; +import org.elasticsearch.features.NodeFeature; + +import java.util.Set; + +public class MachineLearningFeatures implements FeatureSpecification { + + public static final NodeFeature COMPONENTS_RESET_ACTION = new NodeFeature("ml.components.reset"); + + public Set getFeatures() { + return Set.of(COMPONENTS_RESET_ACTION); + } +} diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportResetMlComponentsAction.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportResetMlComponentsAction.java index 748de68b8c46c..af6998baf4425 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportResetMlComponentsAction.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportResetMlComponentsAction.java @@ -7,17 +7,20 @@ package org.elasticsearch.xpack.ml.action; +import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.nodes.TransportNodesAction; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.features.FeatureService; import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.core.ml.action.ResetMlComponentsAction; +import org.elasticsearch.xpack.ml.MachineLearningFeatures; import org.elasticsearch.xpack.ml.inference.TrainedModelStatsService; import org.elasticsearch.xpack.ml.notifications.AnomalyDetectionAuditor; import org.elasticsearch.xpack.ml.notifications.DataFrameAnalyticsAuditor; @@ -37,6 +40,7 @@ public class TransportResetMlComponentsAction extends TransportNodesAction< private final DataFrameAnalyticsAuditor dfaAuditor; private final InferenceAuditor inferenceAuditor; private final TrainedModelStatsService trainedModelStatsService; + private final FeatureService featureService; @Inject public TransportResetMlComponentsAction( @@ -47,7 +51,8 @@ public TransportResetMlComponentsAction( AnomalyDetectionAuditor anomalyDetectionAuditor, DataFrameAnalyticsAuditor dfaAuditor, InferenceAuditor inferenceAuditor, - TrainedModelStatsService trainedModelStatsService + TrainedModelStatsService trainedModelStatsService, + FeatureService featureService ) { super( ResetMlComponentsAction.NAME, @@ -61,6 +66,20 @@ public TransportResetMlComponentsAction( this.dfaAuditor = dfaAuditor; this.inferenceAuditor = inferenceAuditor; this.trainedModelStatsService = trainedModelStatsService; + this.featureService = featureService; + } + + @Override + protected void doExecute( + Task task, + ResetMlComponentsAction.Request request, + ActionListener listener + ) { + if (featureService.clusterHasFeature(clusterService.state(), MachineLearningFeatures.COMPONENTS_RESET_ACTION) == false) { + listener.onResponse(new ResetMlComponentsAction.Response(clusterService.getClusterName(), List.of(), List.of())); + } else { + super.doExecute(task, request, listener); + } } @Override