Skip to content

Commit baad6f6

Browse files
authored
[7.17][ML] defend against negative datafeed start times (#100332)
* [ML] Defend against negative datafeed start times (#100284) A negative start time in the datafeed can cause significant disruption to an entire cluster. This PR checks that the start time is greater than or equal to 0 and throws an exception otherwise. * Adjust backported test for 7.17
1 parent 1e8696f commit baad6f6

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

docs/changelog/100284.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 100284
2+
summary: Defend against negative datafeed start times
3+
area: Machine Learning
4+
type: bug
5+
issues: []

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ public static DatafeedParams parseRequest(String datafeedId, XContentParser pars
193193

194194
public DatafeedParams(String datafeedId, long startTime) {
195195
this.datafeedId = ExceptionsHelper.requireNonNull(datafeedId, DatafeedConfig.ID.getPreferredName());
196+
if (startTime < 0) {
197+
throw new IllegalArgumentException("[" + START_TIME.getPreferredName() + "] must not be negative [" + startTime + "].");
198+
}
196199
this.startTime = startTime;
197200
}
198201

x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/DatafeedJobsIT.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.elasticsearch.xpack.core.ml.action.GetJobsStatsAction;
3333
import org.elasticsearch.xpack.core.ml.action.KillProcessAction;
3434
import org.elasticsearch.xpack.core.ml.action.PutJobAction;
35+
import org.elasticsearch.xpack.core.ml.action.StartDatafeedAction;
3536
import org.elasticsearch.xpack.core.ml.action.StopDatafeedAction;
3637
import org.elasticsearch.xpack.core.ml.datafeed.ChunkingConfig;
3738
import org.elasticsearch.xpack.core.ml.datafeed.DatafeedConfig;
@@ -832,4 +833,36 @@ private void startRealtime(String jobId, Integer maxEmptySearches) throws Except
832833
assertThat(dataCounts.getOutOfOrderTimeStampCount(), equalTo(0L));
833834
}, 30, TimeUnit.SECONDS);
834835
}
836+
837+
public void testStartDatafeed_GivenNegativeStartTime_Returns408() throws Exception {
838+
client().admin().indices().prepareCreate("data-1").addMapping("type", "time", "type=date").get();
839+
long numDocs = 100;
840+
long now = System.currentTimeMillis();
841+
long oneWeekAgo = now - 604800000;
842+
long negativeStartTime = -1000;
843+
indexDocs(logger, "data-1", numDocs, oneWeekAgo, now);
844+
845+
String jobId = "job-for-start-datafeed-timeout";
846+
String datafeedId = jobId + "-datafeed";
847+
848+
Job.Builder job = createScheduledJob(jobId);
849+
putJob(job);
850+
openJob(job.getId());
851+
assertBusy(() -> assertEquals(getJobStats(job.getId()).get(0).getState(), JobState.OPENED));
852+
853+
DatafeedConfig.Builder datafeedConfigBuilder = createDatafeedBuilder(
854+
job.getId() + "-datafeed",
855+
job.getId(),
856+
Collections.singletonList("data-1")
857+
);
858+
DatafeedConfig datafeedConfig = datafeedConfigBuilder.build();
859+
putDatafeed(datafeedConfig);
860+
861+
IllegalArgumentException e = expectThrows(
862+
IllegalArgumentException.class,
863+
() -> new StartDatafeedAction.Request(datafeedId, negativeStartTime)
864+
);
865+
866+
assertThat(e.getMessage(), equalTo("[start] must not be negative [-1000]."));
867+
}
835868
}

0 commit comments

Comments
 (0)