Skip to content

Commit eba60ee

Browse files
authored
Removes the now callable in the date math parser in favour of a LongSupplier (#20796)
Previous to this change the DateMathParser accepted a Callable<Long> to use for accessing the now value. The implementations of this callable would fall back on System.currentTimeMillis() if there was no context object provided. This is no longer necessary for two reasons: We should not fall back to System.currentTimeMillis() as a context should always be provided. This ensures consistency between shards for the now value in all cases We should use a LongSupplier rather than requiring an implementation of Callable. This means that we can just pass in context::noInMillis for this parameter and not have not implement anything.
1 parent 0a1b8a3 commit eba60ee

File tree

11 files changed

+112
-120
lines changed

11 files changed

+112
-120
lines changed

core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import java.util.Locale;
4949
import java.util.Map;
5050
import java.util.Set;
51-
import java.util.concurrent.Callable;
5251
import java.util.stream.Collectors;
5352

5453
public class IndexNameExpressionResolver extends AbstractComponent {
@@ -848,12 +847,7 @@ String resolveExpression(String expression, final Context context) {
848847
DateTimeFormatter parser = dateFormatter.withZone(timeZone);
849848
FormatDateTimeFormatter formatter = new FormatDateTimeFormatter(dateFormatterPattern, parser, Locale.ROOT);
850849
DateMathParser dateMathParser = new DateMathParser(formatter);
851-
long millis = dateMathParser.parse(mathExpression, new Callable<Long>() {
852-
@Override
853-
public Long call() throws Exception {
854-
return context.getStartTime();
855-
}
856-
}, false, timeZone);
850+
long millis = dateMathParser.parse(mathExpression, context::getStartTime, false, timeZone);
857851

858852
String time = formatter.printer().print(millis);
859853
beforePlaceHolderSb.append(time);

core/src/main/java/org/elasticsearch/common/joda/DateMathParser.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
import org.joda.time.format.DateTimeFormatter;
2626

2727
import java.util.Objects;
28-
import java.util.concurrent.Callable;
28+
import java.util.function.LongSupplier;
2929

3030
/**
3131
* A parser for date/time formatted text with optional date math.
32-
*
32+
*
3333
* The format of the datetime is configurable, and unix timestamps can also be used. Datemath
3434
* is appended to a datetime with the following syntax:
3535
* <code>||[+-/](\d+)?[yMwdhHms]</code>.
@@ -43,19 +43,19 @@ public DateMathParser(FormatDateTimeFormatter dateTimeFormatter) {
4343
this.dateTimeFormatter = dateTimeFormatter;
4444
}
4545

46-
public long parse(String text, Callable<Long> now) {
46+
public long parse(String text, LongSupplier now) {
4747
return parse(text, now, false, null);
4848
}
4949

5050
// Note: we take a callable here for the timestamp in order to be able to figure out
5151
// if it has been used. For instance, the request cache does not cache requests that make
5252
// use of `now`.
53-
public long parse(String text, Callable<Long> now, boolean roundUp, DateTimeZone timeZone) {
53+
public long parse(String text, LongSupplier now, boolean roundUp, DateTimeZone timeZone) {
5454
long time;
5555
String mathString;
5656
if (text.startsWith("now")) {
5757
try {
58-
time = now.call();
58+
time = now.getAsLong();
5959
} catch (Exception e) {
6060
throw new ElasticsearchParseException("could not read the current timestamp", e);
6161
}
@@ -97,7 +97,7 @@ private long parseMath(String mathString, long time, boolean roundUp, DateTimeZo
9797
throw new ElasticsearchParseException("operator not supported for date math [{}]", mathString);
9898
}
9999
}
100-
100+
101101
if (i >= mathString.length()) {
102102
throw new ElasticsearchParseException("truncated date math [{}]", mathString);
103103
}
@@ -198,7 +198,7 @@ private long parseDateTime(String value, DateTimeZone timeZone) {
198198
try {
199199
return parser.parseMillis(value);
200200
} catch (IllegalArgumentException e) {
201-
201+
202202
throw new ElasticsearchParseException("failed to parse date field [{}] with format [{}]", e, value, dateTimeFormatter.format());
203203
}
204204
}

core/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@
5454
import java.util.Locale;
5555
import java.util.Map;
5656
import java.util.Objects;
57-
import java.util.concurrent.Callable;
58-
5957
import static org.elasticsearch.index.mapper.TypeParsers.parseDateTimeFormatter;
6058

6159
/** A {@link FieldMapper} for ip addresses. */
@@ -361,15 +359,7 @@ public long parseToMilliseconds(Object value, boolean roundUp,
361359
} else {
362360
strValue = value.toString();
363361
}
364-
return dateParser.parse(strValue, now(context), roundUp, zone);
365-
}
366-
367-
private static Callable<Long> now(QueryRewriteContext context) {
368-
return () -> {
369-
return context != null
370-
? context.nowInMillis()
371-
: System.currentTimeMillis();
372-
};
362+
return dateParser.parse(strValue, context::nowInMillis, roundUp, zone);
373363
}
374364

375365
@Override

core/src/main/java/org/elasticsearch/index/mapper/LegacyDateFieldMapper.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import java.util.Locale;
5555
import java.util.Map;
5656
import java.util.Objects;
57-
import java.util.concurrent.Callable;
5857
import java.util.concurrent.TimeUnit;
5958

6059
import static org.elasticsearch.index.mapper.TypeParsers.parseDateTimeFormatter;
@@ -453,7 +452,7 @@ public long parseToMilliseconds(Object value, boolean inclusive, @Nullable DateT
453452
} else {
454453
strValue = value.toString();
455454
}
456-
return dateParser.parse(strValue, now(context), inclusive, zone);
455+
return dateParser.parse(strValue, context::nowInMillis, inclusive, zone);
457456
}
458457

459458
@Override
@@ -485,17 +484,6 @@ public DateFieldType fieldType() {
485484
return (DateFieldType) super.fieldType();
486485
}
487486

488-
private static Callable<Long> now(QueryRewriteContext context) {
489-
return new Callable<Long>() {
490-
@Override
491-
public Long call() {
492-
return context != null
493-
? context.nowInMillis()
494-
: System.currentTimeMillis();
495-
}
496-
};
497-
}
498-
499487
@Override
500488
protected boolean customBoost() {
501489
return true;

core/src/main/java/org/elasticsearch/search/DocValueFormat.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import java.util.Arrays;
4242
import java.util.Locale;
4343
import java.util.Objects;
44-
import java.util.concurrent.Callable;
44+
import java.util.function.LongSupplier;
4545

4646
/** A formatter for values as returned by the fielddata/doc-values APIs. */
4747
public interface DocValueFormat extends NamedWriteable {
@@ -63,11 +63,11 @@ public interface DocValueFormat extends NamedWriteable {
6363

6464
/** Parse a value that was formatted with {@link #format(long)} back to the
6565
* original long value. */
66-
long parseLong(String value, boolean roundUp, Callable<Long> now);
66+
long parseLong(String value, boolean roundUp, LongSupplier now);
6767

6868
/** Parse a value that was formatted with {@link #format(double)} back to
6969
* the original double value. */
70-
double parseDouble(String value, boolean roundUp, Callable<Long> now);
70+
double parseDouble(String value, boolean roundUp, LongSupplier now);
7171

7272
/** Parse a value that was formatted with {@link #format(BytesRef)} back
7373
* to the original BytesRef. */
@@ -100,7 +100,7 @@ public String format(BytesRef value) {
100100
}
101101

102102
@Override
103-
public long parseLong(String value, boolean roundUp, Callable<Long> now) {
103+
public long parseLong(String value, boolean roundUp, LongSupplier now) {
104104
double d = Double.parseDouble(value);
105105
if (roundUp) {
106106
d = Math.ceil(d);
@@ -111,7 +111,7 @@ public long parseLong(String value, boolean roundUp, Callable<Long> now) {
111111
}
112112

113113
@Override
114-
public double parseDouble(String value, boolean roundUp, Callable<Long> now) {
114+
public double parseDouble(String value, boolean roundUp, LongSupplier now) {
115115
return Double.parseDouble(value);
116116
}
117117

@@ -166,12 +166,12 @@ public String format(BytesRef value) {
166166
}
167167

168168
@Override
169-
public long parseLong(String value, boolean roundUp, Callable<Long> now) {
169+
public long parseLong(String value, boolean roundUp, LongSupplier now) {
170170
return parser.parse(value, now, roundUp, timeZone);
171171
}
172172

173173
@Override
174-
public double parseDouble(String value, boolean roundUp, Callable<Long> now) {
174+
public double parseDouble(String value, boolean roundUp, LongSupplier now) {
175175
return parseLong(value, roundUp, now);
176176
}
177177

@@ -208,12 +208,12 @@ public String format(BytesRef value) {
208208
}
209209

210210
@Override
211-
public long parseLong(String value, boolean roundUp, Callable<Long> now) {
211+
public long parseLong(String value, boolean roundUp, LongSupplier now) {
212212
throw new UnsupportedOperationException();
213213
}
214214

215215
@Override
216-
public double parseDouble(String value, boolean roundUp, Callable<Long> now) {
216+
public double parseDouble(String value, boolean roundUp, LongSupplier now) {
217217
throw new UnsupportedOperationException();
218218
}
219219

@@ -250,7 +250,7 @@ public String format(BytesRef value) {
250250
}
251251

252252
@Override
253-
public long parseLong(String value, boolean roundUp, Callable<Long> now) {
253+
public long parseLong(String value, boolean roundUp, LongSupplier now) {
254254
switch (value) {
255255
case "false":
256256
return 0;
@@ -261,7 +261,7 @@ public long parseLong(String value, boolean roundUp, Callable<Long> now) {
261261
}
262262

263263
@Override
264-
public double parseDouble(String value, boolean roundUp, Callable<Long> now) {
264+
public double parseDouble(String value, boolean roundUp, LongSupplier now) {
265265
throw new UnsupportedOperationException();
266266
}
267267

@@ -300,12 +300,12 @@ public String format(BytesRef value) {
300300
}
301301

302302
@Override
303-
public long parseLong(String value, boolean roundUp, Callable<Long> now) {
303+
public long parseLong(String value, boolean roundUp, LongSupplier now) {
304304
throw new UnsupportedOperationException();
305305
}
306306

307307
@Override
308-
public double parseDouble(String value, boolean roundUp, Callable<Long> now) {
308+
public double parseDouble(String value, boolean roundUp, LongSupplier now) {
309309
throw new UnsupportedOperationException();
310310
}
311311

@@ -358,7 +358,7 @@ public String format(BytesRef value) {
358358
}
359359

360360
@Override
361-
public long parseLong(String value, boolean roundUp, Callable<Long> now) {
361+
public long parseLong(String value, boolean roundUp, LongSupplier now) {
362362
Number n;
363363
try {
364364
n = format.parse(value);
@@ -379,7 +379,7 @@ public long parseLong(String value, boolean roundUp, Callable<Long> now) {
379379
}
380380

381381
@Override
382-
public double parseDouble(String value, boolean roundUp, Callable<Long> now) {
382+
public double parseDouble(String value, boolean roundUp, LongSupplier now) {
383383
Number n;
384384
try {
385385
n = format.parse(value);

core/src/test/java/org/elasticsearch/common/joda/DateMathParserTests.java

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import org.joda.time.DateTimeZone;
2626

2727
import java.util.TimeZone;
28-
import java.util.concurrent.Callable;
2928
import java.util.concurrent.atomic.AtomicBoolean;
29+
import java.util.function.LongSupplier;
3030

3131
import static org.hamcrest.Matchers.containsString;
3232
import static org.hamcrest.Matchers.equalTo;
@@ -36,26 +36,17 @@ public class DateMathParserTests extends ESTestCase {
3636
FormatDateTimeFormatter formatter = Joda.forPattern("dateOptionalTime||epoch_millis");
3737
DateMathParser parser = new DateMathParser(formatter);
3838

39-
private static Callable<Long> callable(final long value) {
40-
return new Callable<Long>() {
41-
@Override
42-
public Long call() throws Exception {
43-
return value;
44-
}
45-
};
46-
}
47-
4839
void assertDateMathEquals(String toTest, String expected) {
4940
assertDateMathEquals(toTest, expected, 0, false, null);
5041
}
5142

5243
void assertDateMathEquals(String toTest, String expected, final long now, boolean roundUp, DateTimeZone timeZone) {
53-
long gotMillis = parser.parse(toTest, callable(now), roundUp, timeZone);
44+
long gotMillis = parser.parse(toTest, () -> now, roundUp, timeZone);
5445
assertDateEquals(gotMillis, toTest, expected);
5546
}
5647

5748
void assertDateEquals(long gotMillis, String original, String expected) {
58-
long expectedMillis = parser.parse(expected, callable(0));
49+
long expectedMillis = parser.parse(expected, () -> 0);
5950
if (gotMillis != expectedMillis) {
6051
fail("Date math not equal\n" +
6152
"Original : " + original + "\n" +
@@ -132,7 +123,7 @@ public void testMultipleAdjustments() {
132123

133124

134125
public void testNow() {
135-
final long now = parser.parse("2014-11-18T14:27:32", callable(0), false, null);
126+
final long now = parser.parse("2014-11-18T14:27:32", () -> 0, false, null);
136127

137128
assertDateMathEquals("now", "2014-11-18T14:27:32", now, false, null);
138129
assertDateMathEquals("now+M", "2014-12-18T14:27:32", now, false, null);
@@ -204,7 +195,7 @@ public void testTimestamps() {
204195

205196
// also check other time units
206197
DateMathParser parser = new DateMathParser(Joda.forPattern("epoch_second||dateOptionalTime"));
207-
long datetime = parser.parse("1418248078", callable(0));
198+
long datetime = parser.parse("1418248078", () -> 0);
208199
assertDateEquals(datetime, "1418248078", "2014-12-10T21:47:58.000");
209200

210201
// a timestamp before 10000 is a year
@@ -217,7 +208,7 @@ public void testTimestamps() {
217208

218209
void assertParseException(String msg, String date, String exc) {
219210
try {
220-
parser.parse(date, callable(0));
211+
parser.parse(date, () -> 0);
221212
fail("Date: " + date + "\n" + msg);
222213
} catch (ElasticsearchParseException e) {
223214
assertThat(ExceptionsHelper.detailedMessage(e).contains(exc), equalTo(true));
@@ -239,12 +230,9 @@ public void testIllegalDateFormat() {
239230

240231
public void testOnlyCallsNowIfNecessary() {
241232
final AtomicBoolean called = new AtomicBoolean();
242-
final Callable<Long> now = new Callable<Long>() {
243-
@Override
244-
public Long call() throws Exception {
245-
called.set(true);
246-
return 42L;
247-
}
233+
final LongSupplier now = () -> {
234+
called.set(true);
235+
return 42L;
248236
};
249237
parser.parse("2014-11-18T14:27:32", now, false, null);
250238
assertFalse(called.get());
@@ -255,7 +243,7 @@ public Long call() throws Exception {
255243
public void testThatUnixTimestampMayNotHaveTimeZone() {
256244
DateMathParser parser = new DateMathParser(Joda.forPattern("epoch_millis"));
257245
try {
258-
parser.parse("1234567890123", callable(42), false, DateTimeZone.forTimeZone(TimeZone.getTimeZone("CET")));
246+
parser.parse("1234567890123", () -> 42, false, DateTimeZone.forTimeZone(TimeZone.getTimeZone("CET")));
259247
fail("Expected ElasticsearchParseException");
260248
} catch(ElasticsearchParseException e) {
261249
assertThat(e.getMessage(), containsString("failed to parse date field"));

0 commit comments

Comments
 (0)