From fe3c9e71d12e9f7c79856438f897280ee65e853f Mon Sep 17 00:00:00 2001 From: Dimitris Athanasiou Date: Fri, 13 Dec 2019 17:00:55 +0200 Subject: [PATCH] [7.x][ML] Fix DFA explain API timeout when source index is missing (#50176) (#50180) This commit fixes a bug that caused the data frame analytics _explain API to time out in a multi-node setup when the source index was missing. When we try to create the extracted fields detector, we check the index settings. If the index is missing that responds with a failure that could be wrapped as a remote exception. While we unwrapped correctly to check if the cause was an `IndexNotFoundException`, we then proceeded to cast the original exception instead of the cause. Backport of #50176 --- .../ml/integration/ExplainDataFrameAnalyticsIT.java | 13 +++++++++++++ .../extractor/ExtractedFieldsDetectorFactory.java | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/test/java/org/elasticsearch/xpack/ml/integration/ExplainDataFrameAnalyticsIT.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/test/java/org/elasticsearch/xpack/ml/integration/ExplainDataFrameAnalyticsIT.java index ba00e49456f..32ee2d28c86 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/test/java/org/elasticsearch/xpack/ml/integration/ExplainDataFrameAnalyticsIT.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/test/java/org/elasticsearch/xpack/ml/integration/ExplainDataFrameAnalyticsIT.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.ml.integration; +import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.index.IndexRequest; @@ -14,14 +15,26 @@ import org.elasticsearch.xpack.core.ml.action.ExplainDataFrameAnalyticsAction; import org.elasticsearch.xpack.core.ml.dataframe.DataFrameAnalyticsConfig; import org.elasticsearch.xpack.core.ml.dataframe.DataFrameAnalyticsSource; import org.elasticsearch.xpack.core.ml.dataframe.analyses.Classification; +import org.elasticsearch.xpack.core.ml.dataframe.analyses.OutlierDetection; import org.elasticsearch.xpack.core.ml.utils.QueryProvider; import java.io.IOException; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.lessThanOrEqualTo; public class ExplainDataFrameAnalyticsIT extends MlNativeDataFrameAnalyticsIntegTestCase { + public void testExplain_GivenMissingSourceIndex() { + DataFrameAnalyticsConfig config = new DataFrameAnalyticsConfig.Builder() + .setSource(new DataFrameAnalyticsSource(new String[] {"missing_index"}, null, null)) + .setAnalysis(new OutlierDetection.Builder().build()) + .buildForExplain(); + + ResourceNotFoundException e = expectThrows(ResourceNotFoundException.class, () -> explainDataFrame(config)); + assertThat(e.getMessage(), equalTo("cannot retrieve data because index [missing_index] does not exist")); + } + public void testSourceQueryIsApplied() throws IOException { // To test the source query is applied when we extract data, // we set up a job where we have a query which excludes all but one document. diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java index 8e6ad7a614b..c44555921cf 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/dataframe/extractor/ExtractedFieldsDetectorFactory.java @@ -171,9 +171,10 @@ public class ExtractedFieldsDetectorFactory { docValueFieldsLimitListener.onResponse(minDocValueFieldsLimit); }, e -> { - if (ExceptionsHelper.unwrapCause(e) instanceof IndexNotFoundException) { + Throwable cause = ExceptionsHelper.unwrapCause(e); + if (cause instanceof IndexNotFoundException) { docValueFieldsLimitListener.onFailure(new ResourceNotFoundException("cannot retrieve data because index " - + ((IndexNotFoundException) e).getIndex() + " does not exist")); + + ((IndexNotFoundException) cause).getIndex() + " does not exist")); } else { docValueFieldsLimitListener.onFailure(e); }