Skip to content

Commit eae6fed

Browse files
[ML] Updating detectors should not affect existing job (#32040)
This is a light backport of #31957 for 6.3.
1 parent bda7033 commit eae6fed

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/config/AnalysisConfig.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ public Builder(List<Detector> detectors) {
487487
}
488488

489489
public Builder(AnalysisConfig analysisConfig) {
490-
this.detectors = analysisConfig.detectors;
490+
this.detectors = new ArrayList<>(analysisConfig.detectors);
491491
this.bucketSpan = analysisConfig.bucketSpan;
492492
this.latency = analysisConfig.latency;
493493
this.categorizationFieldName = analysisConfig.categorizationFieldName;
@@ -518,6 +518,10 @@ public void setDetectors(List<Detector> detectors) {
518518
this.detectors = sequentialIndexDetectors;
519519
}
520520

521+
public void setDetector(int detectorIndex, Detector detector) {
522+
detectors.set(detectorIndex, detector);
523+
}
524+
521525
public void setBucketSpan(TimeValue bucketSpan) {
522526
this.bucketSpan = bucketSpan;
523527
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/job/config/JobUpdate.java

+7-10
Original file line numberDiff line numberDiff line change
@@ -346,33 +346,31 @@ public Set<String> getUpdateFields() {
346346
*/
347347
public Job mergeWithJob(Job source, ByteSizeValue maxModelMemoryLimit) {
348348
Job.Builder builder = new Job.Builder(source);
349+
AnalysisConfig currentAnalysisConfig = source.getAnalysisConfig();
350+
AnalysisConfig.Builder newAnalysisConfig = new AnalysisConfig.Builder(currentAnalysisConfig);
349351
if (groups != null) {
350352
builder.setGroups(groups);
351353
}
352354
if (description != null) {
353355
builder.setDescription(description);
354356
}
355357
if (detectorUpdates != null && detectorUpdates.isEmpty() == false) {
356-
AnalysisConfig ac = source.getAnalysisConfig();
357-
int numDetectors = ac.getDetectors().size();
358+
int numDetectors = currentAnalysisConfig.getDetectors().size();
358359
for (DetectorUpdate dd : detectorUpdates) {
359360
if (dd.getDetectorIndex() >= numDetectors) {
360361
throw ExceptionsHelper.badRequestException("Supplied detector_index [{}] is >= the number of detectors [{}]",
361362
dd.getDetectorIndex(), numDetectors);
362363
}
363364

364-
Detector.Builder detectorbuilder = new Detector.Builder(ac.getDetectors().get(dd.getDetectorIndex()));
365+
Detector.Builder detectorbuilder = new Detector.Builder(currentAnalysisConfig.getDetectors().get(dd.getDetectorIndex()));
365366
if (dd.getDescription() != null) {
366367
detectorbuilder.setDetectorDescription(dd.getDescription());
367368
}
368369
if (dd.getRules() != null) {
369370
detectorbuilder.setRules(dd.getRules());
370371
}
371-
ac.getDetectors().set(dd.getDetectorIndex(), detectorbuilder.build());
372+
newAnalysisConfig.setDetector(dd.getDetectorIndex(), detectorbuilder.build());
372373
}
373-
374-
AnalysisConfig.Builder acBuilder = new AnalysisConfig.Builder(ac);
375-
builder.setAnalysisConfig(acBuilder);
376374
}
377375
if (modelPlotConfig != null) {
378376
builder.setModelPlotConfig(modelPlotConfig);
@@ -395,9 +393,7 @@ public Job mergeWithJob(Job source, ByteSizeValue maxModelMemoryLimit) {
395393
builder.setResultsRetentionDays(resultsRetentionDays);
396394
}
397395
if (categorizationFilters != null) {
398-
AnalysisConfig.Builder analysisConfigBuilder = new AnalysisConfig.Builder(source.getAnalysisConfig());
399-
analysisConfigBuilder.setCategorizationFilters(categorizationFilters);
400-
builder.setAnalysisConfig(analysisConfigBuilder);
396+
newAnalysisConfig.setCategorizationFilters(categorizationFilters);
401397
}
402398
if (customSettings != null) {
403399
builder.setCustomSettings(customSettings);
@@ -416,6 +412,7 @@ public Job mergeWithJob(Job source, ByteSizeValue maxModelMemoryLimit) {
416412
if (jobVersion != null) {
417413
builder.setJobVersion(jobVersion);
418414
}
415+
builder.setAnalysisConfig(newAnalysisConfig);
419416
return builder.build();
420417
}
421418

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/job/config/JobUpdateTests.java

+23
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323

2424
import static org.hamcrest.Matchers.equalTo;
25+
import static org.hamcrest.Matchers.is;
2526
import static org.mockito.Mockito.mock;
2627

2728
public class JobUpdateTests extends AbstractSerializingTestCase<JobUpdate> {
@@ -182,6 +183,28 @@ public void testMergeWithJob() {
182183
}
183184
}
184185

186+
public void testDetectorUpdate_DoesNotAffectOriginalJob() {
187+
Job.Builder jobBuilder = new Job.Builder("foo");
188+
Detector.Builder detector = new Detector.Builder("count", null);
189+
AnalysisConfig.Builder ac = new AnalysisConfig.Builder(Collections.singletonList(detector.build()));
190+
jobBuilder.setAnalysisConfig(ac);
191+
jobBuilder.setDataDescription(new DataDescription.Builder());
192+
jobBuilder.setCreateTime(new Date());
193+
Job job = jobBuilder.build();
194+
195+
List<DetectionRule> rules = Collections.singletonList(new DetectionRule.Builder(Collections.singletonList(
196+
new RuleCondition(RuleConditionType.NUMERICAL_ACTUAL, null, null, new Condition(Operator.GT, "5"), null))).build());
197+
JobUpdate.DetectorUpdate detectorUpdate = new JobUpdate.DetectorUpdate(0, null, rules);
198+
JobUpdate.Builder updateBuilder = new JobUpdate.Builder("foo");
199+
updateBuilder.setDetectorUpdates(Collections.singletonList(detectorUpdate));
200+
JobUpdate update = updateBuilder.build();
201+
202+
Job updatedJob = update.mergeWithJob(job, new ByteSizeValue(0L));
203+
204+
assertThat(updatedJob.getAnalysisConfig().getDetectors().get(0).getRules(), equalTo(rules));
205+
assertThat(job.getAnalysisConfig().getDetectors().get(0).getRules().isEmpty(), is(true));
206+
}
207+
185208
public void testIsAutodetectProcessUpdate() {
186209
JobUpdate update = new JobUpdate.Builder("foo").build();
187210
assertFalse(update.isAutodetectProcessUpdate());

0 commit comments

Comments
 (0)