Skip to content

Commit 9a72766

Browse files
author
Hendrik Muhs
authored
date_histogram interval got deprecated in #33727 (#42542)
data frames should use the new syntax. There is no need to support the old syntax as this feature will be released with 7.2. fixes #42297
1 parent 9da0250 commit 9a72766

File tree

9 files changed

+476
-163
lines changed

9 files changed

+476
-163
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/transforms/pivot/DateHistogramGroupSource.java

+164-67
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
package org.elasticsearch.client.dataframe.transforms.pivot;
2121

2222
import org.elasticsearch.common.ParseField;
23-
import org.elasticsearch.common.unit.TimeValue;
2423
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
2524
import org.elasticsearch.common.xcontent.ObjectParser;
25+
import org.elasticsearch.common.xcontent.ToXContentFragment;
2626
import org.elasticsearch.common.xcontent.ToXContentObject;
2727
import org.elasticsearch.common.xcontent.XContentBuilder;
2828
import org.elasticsearch.common.xcontent.XContentParser;
@@ -31,7 +31,11 @@
3131
import java.io.IOException;
3232
import java.time.ZoneId;
3333
import java.time.ZoneOffset;
34+
import java.util.Arrays;
35+
import java.util.Collections;
36+
import java.util.HashSet;
3437
import java.util.Objects;
38+
import java.util.Set;
3539

3640
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
3741

@@ -43,32 +47,164 @@ public class DateHistogramGroupSource extends SingleGroupSource implements ToXCo
4347
private static final ParseField TIME_ZONE = new ParseField("time_zone");
4448
private static final ParseField FORMAT = new ParseField("format");
4549

50+
// From DateHistogramAggregationBuilder in core, transplanted and modified to a set
51+
// so we don't need to import a dependency on the class
52+
private static final Set<String> DATE_FIELD_UNITS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
53+
"year",
54+
"1y",
55+
"quarter",
56+
"1q",
57+
"month",
58+
"1M",
59+
"week",
60+
"1w",
61+
"day",
62+
"1d",
63+
"hour",
64+
"1h",
65+
"minute",
66+
"1m",
67+
"second",
68+
"1s")));
69+
70+
/**
71+
* Interval can be specified in 2 ways:
72+
*
73+
* fixed_interval fixed intervals like 1h, 1m, 1d
74+
* calendar_interval calendar aware intervals like 1M, 1Y, ...
75+
*
76+
* Note: data frames do not support the deprecated interval option
77+
*/
78+
public interface Interval extends ToXContentFragment {
79+
String getName();
80+
DateHistogramInterval getInterval();
81+
}
82+
83+
public static class FixedInterval implements Interval {
84+
private static final String NAME = "fixed_interval";
85+
private final DateHistogramInterval interval;
86+
87+
public FixedInterval(DateHistogramInterval interval) {
88+
this.interval = interval;
89+
}
90+
91+
@Override
92+
public String getName() {
93+
return NAME;
94+
}
95+
96+
@Override
97+
public DateHistogramInterval getInterval() {
98+
return interval;
99+
}
100+
101+
@Override
102+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
103+
builder.field(NAME);
104+
interval.toXContent(builder, params);
105+
return builder;
106+
}
107+
108+
@Override
109+
public boolean equals(Object other) {
110+
if (this == other) {
111+
return true;
112+
}
113+
114+
if (other == null || getClass() != other.getClass()) {
115+
return false;
116+
}
117+
118+
final FixedInterval that = (FixedInterval) other;
119+
return Objects.equals(this.interval, that.interval);
120+
}
121+
122+
@Override
123+
public int hashCode() {
124+
return Objects.hash(interval);
125+
}
126+
}
127+
128+
public static class CalendarInterval implements Interval {
129+
private static final String NAME = "calendar_interval";
130+
private final DateHistogramInterval interval;
131+
132+
public CalendarInterval(DateHistogramInterval interval) {
133+
this.interval = interval;
134+
if (DATE_FIELD_UNITS.contains(interval.toString()) == false) {
135+
throw new IllegalArgumentException("The supplied interval [" + interval + "] could not be parsed " +
136+
"as a calendar interval.");
137+
}
138+
}
139+
140+
@Override
141+
public String getName() {
142+
return NAME;
143+
}
144+
145+
@Override
146+
public DateHistogramInterval getInterval() {
147+
return interval;
148+
}
149+
150+
@Override
151+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
152+
builder.field(NAME);
153+
interval.toXContent(builder, params);
154+
return builder;
155+
}
156+
157+
@Override
158+
public boolean equals(Object other) {
159+
if (this == other) {
160+
return true;
161+
}
162+
163+
if (other == null || getClass() != other.getClass()) {
164+
return false;
165+
}
166+
167+
final CalendarInterval that = (CalendarInterval) other;
168+
return Objects.equals(this.interval, that.interval);
169+
}
170+
171+
@Override
172+
public int hashCode() {
173+
return Objects.hash(interval);
174+
}
175+
}
176+
46177
private static final ConstructingObjectParser<DateHistogramGroupSource, Void> PARSER =
47178
new ConstructingObjectParser<>("date_histogram_group_source",
48179
true,
49180
(args) -> {
50181
String field = (String)args[0];
51-
long interval = 0;
52-
DateHistogramInterval dateHistogramInterval = null;
53-
if (args[1] instanceof Long) {
54-
interval = (Long)args[1];
182+
String fixedInterval = (String) args[1];
183+
String calendarInterval = (String) args[2];
184+
185+
Interval interval = null;
186+
187+
if (fixedInterval != null && calendarInterval != null) {
188+
throw new IllegalArgumentException("You must specify either fixed_interval or calendar_interval, found both");
189+
} else if (fixedInterval != null) {
190+
interval = new FixedInterval(new DateHistogramInterval(fixedInterval));
191+
} else if (calendarInterval != null) {
192+
interval = new CalendarInterval(new DateHistogramInterval(calendarInterval));
55193
} else {
56-
dateHistogramInterval = (DateHistogramInterval) args[1];
194+
throw new IllegalArgumentException("You must specify either fixed_interval or calendar_interval, found none");
57195
}
58-
ZoneId zoneId = (ZoneId) args[2];
59-
String format = (String) args[3];
60-
return new DateHistogramGroupSource(field, interval, dateHistogramInterval, format, zoneId);
196+
197+
ZoneId zoneId = (ZoneId) args[3];
198+
String format = (String) args[4];
199+
return new DateHistogramGroupSource(field, interval, format, zoneId);
61200
});
62201

63202
static {
64203
PARSER.declareString(optionalConstructorArg(), FIELD);
65-
PARSER.declareField(optionalConstructorArg(), p -> {
66-
if (p.currentToken() == XContentParser.Token.VALUE_NUMBER) {
67-
return p.longValue();
68-
} else {
69-
return new DateHistogramInterval(p.text());
70-
}
71-
}, HistogramGroupSource.INTERVAL, ObjectParser.ValueType.LONG);
204+
205+
PARSER.declareString(optionalConstructorArg(), new ParseField(FixedInterval.NAME));
206+
PARSER.declareString(optionalConstructorArg(), new ParseField(CalendarInterval.NAME));
207+
72208
PARSER.declareField(optionalConstructorArg(), p -> {
73209
if (p.currentToken() == XContentParser.Token.VALUE_STRING) {
74210
return ZoneId.of(p.text());
@@ -84,15 +220,13 @@ public static DateHistogramGroupSource fromXContent(final XContentParser parser)
84220
return PARSER.apply(parser, null);
85221
}
86222

87-
private final long interval;
88-
private final DateHistogramInterval dateHistogramInterval;
223+
private final Interval interval;
89224
private final String format;
90225
private final ZoneId timeZone;
91226

92-
DateHistogramGroupSource(String field, long interval, DateHistogramInterval dateHistogramInterval, String format, ZoneId timeZone) {
227+
DateHistogramGroupSource(String field, Interval interval, String format, ZoneId timeZone) {
93228
super(field);
94229
this.interval = interval;
95-
this.dateHistogramInterval = dateHistogramInterval;
96230
this.format = format;
97231
this.timeZone = timeZone;
98232
}
@@ -102,14 +236,10 @@ public Type getType() {
102236
return Type.DATE_HISTOGRAM;
103237
}
104238

105-
public long getInterval() {
239+
public Interval getInterval() {
106240
return interval;
107241
}
108242

109-
public DateHistogramInterval getDateHistogramInterval() {
110-
return dateHistogramInterval;
111-
}
112-
113243
public String getFormat() {
114244
return format;
115245
}
@@ -124,11 +254,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
124254
if (field != null) {
125255
builder.field(FIELD.getPreferredName(), field);
126256
}
127-
if (dateHistogramInterval == null) {
128-
builder.field(HistogramGroupSource.INTERVAL.getPreferredName(), interval);
129-
} else {
130-
builder.field(HistogramGroupSource.INTERVAL.getPreferredName(), dateHistogramInterval.toString());
131-
}
257+
interval.toXContent(builder, params);
132258
if (timeZone != null) {
133259
builder.field(TIME_ZONE.getPreferredName(), timeZone.toString());
134260
}
@@ -152,15 +278,14 @@ public boolean equals(Object other) {
152278
final DateHistogramGroupSource that = (DateHistogramGroupSource) other;
153279

154280
return Objects.equals(this.field, that.field) &&
155-
Objects.equals(interval, that.interval) &&
156-
Objects.equals(dateHistogramInterval, that.dateHistogramInterval) &&
157-
Objects.equals(timeZone, that.timeZone) &&
158-
Objects.equals(format, that.format);
281+
Objects.equals(this.interval, that.interval) &&
282+
Objects.equals(this.timeZone, that.timeZone) &&
283+
Objects.equals(this.format, that.format);
159284
}
160285

161286
@Override
162287
public int hashCode() {
163-
return Objects.hash(field, interval, dateHistogramInterval, timeZone, format);
288+
return Objects.hash(field, interval, timeZone, format);
164289
}
165290

166291
public static Builder builder() {
@@ -170,8 +295,7 @@ public static Builder builder() {
170295
public static class Builder {
171296

172297
private String field;
173-
private long interval = 0;
174-
private DateHistogramInterval dateHistogramInterval;
298+
private Interval interval;
175299
private String format;
176300
private ZoneId timeZone;
177301

@@ -187,41 +311,14 @@ public Builder setField(String field) {
187311

188312
/**
189313
* Set the interval for the DateHistogram grouping
190-
* @param interval the time interval in milliseconds
314+
* @param interval a fixed or calendar interval
191315
* @return the {@link Builder} with the interval set.
192316
*/
193-
public Builder setInterval(long interval) {
194-
if (interval < 1) {
195-
throw new IllegalArgumentException("[interval] must be greater than or equal to 1.");
196-
}
317+
public Builder setInterval(Interval interval) {
197318
this.interval = interval;
198319
return this;
199320
}
200321

201-
/**
202-
* Set the interval for the DateHistogram grouping
203-
* @param timeValue The time value to use as the interval
204-
* @return the {@link Builder} with the interval set.
205-
*/
206-
public Builder setInterval(TimeValue timeValue) {
207-
return setInterval(timeValue.getMillis());
208-
}
209-
210-
/**
211-
* Sets the interval of the DateHistogram grouping
212-
*
213-
* If this DateHistogramInterval is set, it supersedes the #{@link DateHistogramGroupSource#getInterval()}
214-
* @param dateHistogramInterval the DateHistogramInterval to set
215-
* @return The {@link Builder} with the dateHistogramInterval set.
216-
*/
217-
public Builder setDateHistgramInterval(DateHistogramInterval dateHistogramInterval) {
218-
if (dateHistogramInterval == null) {
219-
throw new IllegalArgumentException("[dateHistogramInterval] must not be null");
220-
}
221-
this.dateHistogramInterval = dateHistogramInterval;
222-
return this;
223-
}
224-
225322
/**
226323
* Set the optional String formatting for the time interval.
227324
* @param format The format of the output for the time interval key
@@ -243,7 +340,7 @@ public Builder setTimeZone(ZoneId timeZone) {
243340
}
244341

245342
public DateHistogramGroupSource build() {
246-
return new DateHistogramGroupSource(field, interval, dateHistogramInterval, format, timeZone);
343+
return new DateHistogramGroupSource(field, interval, format, timeZone);
247344
}
248345
}
249346
}

client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/transforms/pivot/DateHistogramGroupSourceTests.java

+11-6
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,20 @@
2727

2828
public class DateHistogramGroupSourceTests extends AbstractXContentTestCase<DateHistogramGroupSource> {
2929

30+
public static DateHistogramGroupSource.Interval randomDateHistogramInterval() {
31+
if (randomBoolean()) {
32+
return new DateHistogramGroupSource.FixedInterval(new DateHistogramInterval(randomPositiveTimeValue()));
33+
} else {
34+
return new DateHistogramGroupSource.CalendarInterval(new DateHistogramInterval(randomTimeValue(1, 1, "m", "h", "d", "w")));
35+
}
36+
}
37+
3038
public static DateHistogramGroupSource randomDateHistogramGroupSource() {
3139
String field = randomAlphaOfLengthBetween(1, 20);
32-
boolean setInterval = randomBoolean();
3340
return new DateHistogramGroupSource(field,
34-
setInterval ? randomLongBetween(1, 10_000) : 0,
35-
setInterval ? null : randomFrom(DateHistogramInterval.days(10),
36-
DateHistogramInterval.minutes(1), DateHistogramInterval.weeks(1)),
37-
randomBoolean() ? randomAlphaOfLength(10) : null,
38-
randomBoolean() ? randomZone() : null);
41+
randomDateHistogramInterval(),
42+
randomBoolean() ? randomAlphaOfLength(10) : null,
43+
randomBoolean() ? randomZone() : null);
3944
}
4045

4146
@Override

0 commit comments

Comments
 (0)