Skip to content

Commit 97362dd

Browse files
committed
XContent change to support parsing and display of TimeZone fields on schedules
1 parent fbe973b commit 97362dd

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/trigger/schedule/ScheduleRegistry.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
import org.elasticsearch.xcontent.XContentParser;
1111

1212
import java.io.IOException;
13+
import java.time.DateTimeException;
14+
import java.time.ZoneId;
1315
import java.util.HashMap;
1416
import java.util.Map;
1517
import java.util.Set;
18+
import java.util.TimeZone;
1619

1720
public class ScheduleRegistry {
1821
private final Map<String, Schedule.Parser<? extends Schedule>> parsers = new HashMap<>();
@@ -29,9 +32,15 @@ public Schedule parse(String context, XContentParser parser) throws IOException
2932
String type = null;
3033
XContentParser.Token token;
3134
Schedule schedule = null;
35+
TimeZone timeZone = null; // Default to UTC
3236
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
3337
if (token == XContentParser.Token.FIELD_NAME) {
34-
type = parser.currentName();
38+
var fieldName = parser.currentName();
39+
if (fieldName.equals(ScheduleTrigger.TIMEZONE_FIELD)) {
40+
timeZone = parseTimezone(parser);
41+
} else {
42+
type = parser.currentName();
43+
}
3544
} else if (type != null) {
3645
schedule = parse(context, type, parser);
3746
} else {
@@ -44,9 +53,38 @@ public Schedule parse(String context, XContentParser parser) throws IOException
4453
if (schedule == null) {
4554
throw new ElasticsearchParseException("could not parse schedule. expected a schedule type field, but no fields were found");
4655
}
56+
57+
if (timeZone != null && schedule instanceof CronnableSchedule cronnableSchedule) {
58+
cronnableSchedule.setTimeZone(timeZone);
59+
} else if (timeZone != null) {
60+
throw new ElasticsearchParseException(
61+
"could not parse schedule. Timezone is not supported for schedule type [{}]",
62+
schedule.type()
63+
);
64+
}
65+
4766
return schedule;
4867
}
4968

69+
private static TimeZone parseTimezone(XContentParser parser) throws IOException {
70+
TimeZone timeZone;
71+
XContentParser.Token token = parser.nextToken();
72+
if (token == XContentParser.Token.VALUE_STRING) {
73+
String text = parser.text();
74+
try {
75+
timeZone = TimeZone.getTimeZone(ZoneId.of(text));
76+
} catch (DateTimeException e) {
77+
throw new ElasticsearchParseException("could not parse schedule. invalid timezone [{}]", e, text);
78+
}
79+
} else {
80+
throw new ElasticsearchParseException(
81+
"could not parse schedule. expected a string value for timezone, but found [{}] instead",
82+
token
83+
);
84+
}
85+
return timeZone;
86+
}
87+
5088
public Schedule parse(String context, String type, XContentParser parser) throws IOException {
5189
Schedule.Parser<?> scheduleParser = parsers.get(type);
5290
if (scheduleParser == null) {

x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/trigger/schedule/ScheduleTrigger.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
public class ScheduleTrigger implements Trigger {
1515

1616
public static final String TYPE = "schedule";
17+
public static final String TIMEZONE_FIELD = "timezone";
1718

1819
private final Schedule schedule;
1920

@@ -49,7 +50,13 @@ public int hashCode() {
4950

5051
@Override
5152
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
52-
return builder.startObject().field(schedule.type(), schedule, params).endObject();
53+
builder.startObject();
54+
if (schedule instanceof CronnableSchedule cronnableSchedule && cronnableSchedule.getTimeZone() != null) {
55+
builder.field(TIMEZONE_FIELD, cronnableSchedule.getTimeZone().getID());
56+
}
57+
58+
builder.field(schedule.type(), schedule, params);
59+
return builder.endObject();
5360
}
5461

5562
public static Builder builder(Schedule schedule) {

x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/trigger/schedule/ScheduleRegistryTests.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import java.util.HashSet;
1616
import java.util.Set;
17+
import java.util.TimeZone;
1718

1819
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
1920
import static org.hamcrest.Matchers.equalTo;
@@ -50,14 +51,21 @@ public void testParserInterval() throws Exception {
5051

5152
public void testParseCron() throws Exception {
5253
Object cron = randomBoolean() ? Schedules.cron("* 0/5 * * * ?") : Schedules.cron("* 0/2 * * * ?", "* 0/3 * * * ?", "* 0/5 * * * ?");
53-
XContentBuilder builder = jsonBuilder().startObject().field(CronSchedule.TYPE, cron).endObject();
54+
TimeZone timeZone = null;
55+
XContentBuilder builder = jsonBuilder().startObject().field(CronSchedule.TYPE, cron);
56+
if (randomBoolean()) {
57+
timeZone = randomTimeZone();
58+
builder.field(ScheduleTrigger.TIMEZONE_FIELD, timeZone.getID());
59+
}
60+
builder.endObject();
5461
BytesReference bytes = BytesReference.bytes(builder);
5562
XContentParser parser = createParser(JsonXContent.jsonXContent, bytes);
5663
parser.nextToken();
57-
Schedule schedule = registry.parse("ctx", parser);
64+
CronnableSchedule schedule = (CronnableSchedule) registry.parse("ctx", parser);
5865
assertThat(schedule, notNullValue());
5966
assertThat(schedule, instanceOf(CronSchedule.class));
6067
assertThat(schedule, is(cron));
68+
assertThat(schedule.getTimeZone(), equalTo(timeZone));
6169
}
6270

6371
public void testParseHourly() throws Exception {

0 commit comments

Comments
 (0)