diff --git a/plugin/src/main/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriter.java b/plugin/src/main/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriter.java index 5933783837f..c94e0d21da3 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriter.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriter.java @@ -21,6 +21,7 @@ import org.elasticsearch.xpack.ml.utils.MlStrings; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; @@ -36,6 +37,9 @@ public class FieldConfigWriter { private static final String CATEGORIZATION_FIELD_OPTION = " categorizationfield="; private static final String CATEGORIZATION_FILTER_PREFIX = "categorizationfilter."; private static final String FILTER_PREFIX = "filter."; + private static final String SCHEDULED_EVENT_PREFIX = "scheduledevent."; + private static final String SCHEDULED_EVENT_DESCRIPTION_SUFFIX = ".description"; + // Note: for the Engine API summarycountfield is currently passed as a // command line option to autodetect rather than in the field config file @@ -65,6 +69,7 @@ public class FieldConfigWriter { writeDetectors(contents); writeFilters(contents); + writeScheduledEvents(contents); writeAsEnumeratedSettings(CATEGORIZATION_FILTER_PREFIX, config.getCategorizationFilters(), contents, true); @@ -78,13 +83,10 @@ public class FieldConfigWriter { private void writeDetectors(StringBuilder contents) throws IOException { int counter = 0; - List events = scheduledEvents.stream().map(e -> e.toDetectionRule(config.getBucketSpan())) - .collect(Collectors.toList()); - for (Detector detector : config.getDetectors()) { int detectorId = counter++; writeDetectorClause(detectorId, detector, contents); - writeDetectorRules(detectorId, detector, events, contents); + writeDetectorRules(detectorId, detector, contents); } } @@ -102,21 +104,23 @@ public class FieldConfigWriter { contents.append(NEW_LINE); } - private void writeDetectorRules(int detectorId, Detector detector, List scheduledEvents, - StringBuilder contents) throws IOException { + private void writeDetectorRules(int detectorId, Detector detector, StringBuilder contents) throws IOException { List rules = new ArrayList<>(); if (detector.getRules() != null) { rules.addAll(detector.getRules()); } - rules.addAll(scheduledEvents); if (rules.isEmpty()) { return; } contents.append(DETECTOR_PREFIX).append(detectorId).append(DETECTOR_RULES_SUFFIX).append(EQUALS); + writeDetectionRulesJson(rules, contents); + contents.append(NEW_LINE); + } + private void writeDetectionRulesJson(List rules, StringBuilder contents) throws IOException { contents.append('['); boolean first = true; for (DetectionRule rule : rules) { @@ -130,7 +134,6 @@ public class FieldConfigWriter { } } contents.append(']'); - contents.append(NEW_LINE); } private void writeFilters(StringBuilder buffer) throws IOException { @@ -155,6 +158,28 @@ public class FieldConfigWriter { } } + private void writeScheduledEvents(StringBuilder contents) throws IOException { + if (scheduledEvents.isEmpty()) { + return; + } + + int eventIndex = 0; + for (ScheduledEvent event: scheduledEvents) { + + contents.append(SCHEDULED_EVENT_PREFIX).append(eventIndex) + .append(SCHEDULED_EVENT_DESCRIPTION_SUFFIX).append(EQUALS) + .append(quoteField(event.getDescription())) + .append(NEW_LINE); + + contents.append(SCHEDULED_EVENT_PREFIX).append(eventIndex) + .append(DETECTOR_RULES_SUFFIX).append(EQUALS); + writeDetectionRulesJson(Collections.singletonList(event.toDetectionRule(config.getBucketSpan())), contents); + contents.append(NEW_LINE); + + ++eventIndex; + } + } + private static void writeAsEnumeratedSettings(String settingName, List values, StringBuilder buffer, boolean quote) { if (values == null) { return; diff --git a/plugin/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriterTests.java b/plugin/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriterTests.java index 33b68193937..d6cb0bafa21 100644 --- a/plugin/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriterTests.java +++ b/plugin/src/test/java/org/elasticsearch/xpack/ml/job/process/autodetect/writer/FieldConfigWriterTests.java @@ -251,10 +251,12 @@ public class FieldConfigWriterTests extends ESTestCase { createFieldConfigWriter().write(); verify(writer).write("detector.0.clause = count\n" + - "detector.0.rules = [{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," + + "scheduledevent.0.description = \"The Ashes\"\n" + + "scheduledevent.0.rules = [{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," + "\"conditions\":[{\"type\":\"time\",\"condition\":{\"operator\":\"gte\",\"value\":\"1511395200\"}}," + - "{\"type\":\"time\",\"condition\":{\"operator\":\"lt\",\"value\":\"1515369600\"}}]}," + - "{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," + + "{\"type\":\"time\",\"condition\":{\"operator\":\"lt\",\"value\":\"1515369600\"}}]}]\n" + + "scheduledevent.1.description = elasticon\n" + + "scheduledevent.1.rules = [{\"actions\":[\"filter_results\",\"skip_sampling\"],\"conditions_connective\":\"and\"," + "\"conditions\":[{\"type\":\"time\",\"condition\":{\"operator\":\"gte\",\"value\":\"1519603200\"}}," + "{\"type\":\"time\",\"condition\":{\"operator\":\"lt\",\"value\":\"1519862400\"}}]}]" + "\n");