Skip to content

Commit 1bc6739

Browse files
[ML] Fix datafeed preview with remote indices (#81099) (#81103)
In #77109 a bug was fixed with regard to `date_nanos` time fields and the preview datafeed API. However, that fix introduces a new bug. As we are calling the field caps API to find out whether the time field is `date_nanos`, we are setting the datafeed indices on the request. This may result to erroneous behaviour on local indices and it certainly will result to an error if the datafeed's indices are remote. This commit fixes that problem by setting the datafeed's indices on the field caps request.
1 parent b6cf74c commit 1bc6739

File tree

2 files changed

+17
-21
lines changed

2 files changed

+17
-21
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private void previewDatafeed(DatafeedConfig datafeedConfig, Job job, ActionListe
119119
new DatafeedTimingStatsReporter(new DatafeedTimingStats(datafeedConfig.getJobId()), (ts, refreshPolicy) -> {}),
120120
listener.delegateFailure((l, dataExtractorFactory) -> {
121121
isDateNanos(
122-
previewDatafeedConfig.getHeaders(),
122+
previewDatafeedConfig,
123123
job.getDataDescription().getTimeField(),
124124
listener.delegateFailure((l2, isDateNanos) -> {
125125
DataExtractor dataExtractor = dataExtractorFactory.newExtractor(
@@ -151,13 +151,16 @@ static DatafeedConfig.Builder buildPreviewDatafeed(DatafeedConfig datafeed) {
151151
return previewDatafeed;
152152
}
153153

154-
private void isDateNanos(Map<String, String> headers, String timeField, ActionListener<Boolean> listener) {
154+
private void isDateNanos(DatafeedConfig datafeed, String timeField, ActionListener<Boolean> listener) {
155+
FieldCapabilitiesRequest fieldCapabilitiesRequest = new FieldCapabilitiesRequest();
156+
fieldCapabilitiesRequest.indices(datafeed.getIndices().toArray(new String[0])).indicesOptions(datafeed.getIndicesOptions());
157+
fieldCapabilitiesRequest.fields(timeField);
155158
executeWithHeadersAsync(
156-
headers,
159+
datafeed.getHeaders(),
157160
ML_ORIGIN,
158161
client,
159162
FieldCapabilitiesAction.INSTANCE,
160-
new FieldCapabilitiesRequest().fields(timeField),
163+
fieldCapabilitiesRequest,
161164
ActionListener.wrap(fieldCapsResponse -> {
162165
Map<String, FieldCapabilities> timeFieldCaps = fieldCapsResponse.getField(timeField);
163166
listener.onResponse(timeFieldCaps.keySet().contains(DateFieldMapper.DATE_NANOS_CONTENT_TYPE));

x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/action/TransportPreviewDatafeedActionTests.java

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.elasticsearch.xpack.core.ml.datafeed.DatafeedConfig;
1818
import org.elasticsearch.xpack.core.ml.datafeed.extractor.DataExtractor;
1919
import org.junit.Before;
20-
import org.mockito.invocation.InvocationOnMock;
2120
import org.mockito.stubbing.Answer;
2221

2322
import java.io.ByteArrayInputStream;
@@ -51,21 +50,15 @@ public void setUpTests() {
5150
dataExtractor = mock(DataExtractor.class);
5251
actionListener = mock(ActionListener.class);
5352

54-
doAnswer(new Answer<Void>() {
55-
@Override
56-
public Void answer(InvocationOnMock invocationOnMock) {
57-
PreviewDatafeedAction.Response response = (PreviewDatafeedAction.Response) invocationOnMock.getArguments()[0];
58-
capturedResponse = response.toString();
59-
return null;
60-
}
53+
doAnswer((Answer<Void>) invocationOnMock -> {
54+
PreviewDatafeedAction.Response response = (PreviewDatafeedAction.Response) invocationOnMock.getArguments()[0];
55+
capturedResponse = response.toString();
56+
return null;
6157
}).when(actionListener).onResponse(any());
6258

63-
doAnswer(new Answer<Void>() {
64-
@Override
65-
public Void answer(InvocationOnMock invocationOnMock) {
66-
capturedFailure = (Exception) invocationOnMock.getArguments()[0];
67-
return null;
68-
}
59+
doAnswer((Answer<Void>) invocationOnMock -> {
60+
capturedFailure = (Exception) invocationOnMock.getArguments()[0];
61+
return null;
6962
}).when(actionListener).onFailure(any());
7063
}
7164

@@ -95,7 +88,7 @@ public void testBuildPreviewDatafeed_GivenAggregations() {
9588
assertThat(previewDatafeed.getChunkingConfig(), equalTo(datafeed.build().getChunkingConfig()));
9689
}
9790

98-
public void testPreviewDatafed_GivenEmptyStream() throws IOException {
91+
public void testPreviewDatafeed_GivenEmptyStream() throws IOException {
9992
when(dataExtractor.next()).thenReturn(Optional.empty());
10093

10194
TransportPreviewDatafeedAction.previewDatafeed(dataExtractor, actionListener);
@@ -105,7 +98,7 @@ public void testPreviewDatafed_GivenEmptyStream() throws IOException {
10598
verify(dataExtractor).cancel();
10699
}
107100

108-
public void testPreviewDatafed_GivenNonEmptyStream() throws IOException {
101+
public void testPreviewDatafeed_GivenNonEmptyStream() throws IOException {
109102
String streamAsString = "{\"a\":1, \"b\":2} {\"c\":3, \"d\":4}\n{\"e\":5, \"f\":6}";
110103
InputStream stream = new ByteArrayInputStream(streamAsString.getBytes(StandardCharsets.UTF_8));
111104
when(dataExtractor.next()).thenReturn(Optional.of(stream));
@@ -117,7 +110,7 @@ public void testPreviewDatafed_GivenNonEmptyStream() throws IOException {
117110
verify(dataExtractor).cancel();
118111
}
119112

120-
public void testPreviewDatafed_GivenFailure() throws IOException {
113+
public void testPreviewDatafeed_GivenFailure() throws IOException {
121114
doThrow(new RuntimeException("failed")).when(dataExtractor).next();
122115

123116
TransportPreviewDatafeedAction.previewDatafeed(dataExtractor, actionListener);

0 commit comments

Comments
 (0)