Skip to content

Commit e49df55

Browse files
authored
Index name expression resolver bwc layer for date parsing (#58503)
backports #34507 closes #58481 also closes general parsing issue (no date processors) #58602
1 parent fd5a708 commit e49df55

File tree

4 files changed

+141
-48
lines changed

4 files changed

+141
-48
lines changed

modules/ingest-common/src/test/resources/rest-api-spec/test/ingest/100_date_index_name_processor.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,66 @@ teardown:
3434
date: "2016-04-22T16:32:14.968Z"
3535
}
3636
- match: { _index: "events-2016-04-22"}
37+
38+
---
39+
"Test date index name processor with joda pattern":
40+
- do:
41+
ingest.put_pipeline:
42+
id: "1"
43+
body: >
44+
{
45+
"processors": [
46+
{
47+
"date_index_name" : {
48+
"field": "date",
49+
"date_rounding": "d",
50+
"index_name_prefix": "prefix-",
51+
"index_name_format": "xxxx-w"
52+
}
53+
}
54+
]
55+
}
56+
- match: { acknowledged: true }
57+
58+
- do:
59+
index:
60+
index: test
61+
type: _doc
62+
id: 1
63+
pipeline: "1"
64+
body: {
65+
date: "2020-08-10T01:01:01.000Z"
66+
}
67+
- match: { _index: "prefix-2020-33"}
68+
69+
70+
---
71+
"Test date index name processor with java pattern":
72+
- do:
73+
ingest.put_pipeline:
74+
id: "1"
75+
body: >
76+
{
77+
"processors": [
78+
{
79+
"date_index_name" : {
80+
"field": "date",
81+
"date_rounding": "d",
82+
"index_name_prefix": "prefix-",
83+
"index_name_format": "8YYYY-w"
84+
}
85+
}
86+
]
87+
}
88+
- match: { acknowledged: true }
89+
90+
- do:
91+
index:
92+
index: test
93+
type: _doc
94+
id: 1
95+
pipeline: "1"
96+
body: {
97+
date: "2020-08-10T01:01:01.000Z"
98+
}
99+
- match: { _index: "prefix-2020-33"}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
"Index java 8 date without timezone":
3+
4+
- skip:
5+
version: " - 6.7.99"
6+
reason: fixed in 6.8.11
7+
8+
- do:
9+
indices.create:
10+
index: test_index
11+
body:
12+
settings:
13+
number_of_shards: 1
14+
mappings:
15+
doc:
16+
properties:
17+
date_field:
18+
type: date
19+
format: "8YYYY-ww"
20+
- do:
21+
bulk:
22+
refresh: true
23+
body:
24+
- '{"index": {"_index": "test_index", "_type": "doc", "_id": "1"}}'
25+
- '{"date_field": "2020-32"}'
26+
- '{"index": {"_index": "test_index", "_type": "doc", "_id": "2"}}'
27+
- '{"date_field": "2020-33"}'
28+
29+
- match: { errors: false }
30+
31+
- do:
32+
get:
33+
index: test_index
34+
type: doc
35+
id: 2
36+
37+
- match: { _index: test_index }
38+
- match: { _type: doc }
39+
- match: { _id: "2"}
40+
- match: { _version: 1}
41+
- match: { _source: { "date_field": "2020-33" }}
42+
43+
- do:
44+
search:
45+
index: test_index
46+
body: { "query": { "range": { "date_field": { "gte": "2020-33" } } } }
47+
48+
- match: {hits.total: 1 }
49+
- match: {hits.hits.0._index: test_index }
50+
- match: {hits.hits.0._type: doc }
51+
- match: {hits.hits.0._source.date_field: "2020-33" }
52+

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

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,29 +27,26 @@
2727
import org.elasticsearch.common.Strings;
2828
import org.elasticsearch.common.collect.ImmutableOpenMap;
2929
import org.elasticsearch.common.collect.Tuple;
30-
import org.elasticsearch.common.joda.JodaDateFormatter;
3130
import org.elasticsearch.common.regex.Regex;
3231
import org.elasticsearch.common.settings.Settings;
32+
import org.elasticsearch.common.time.DateFormatter;
33+
import org.elasticsearch.common.time.DateFormatters;
3334
import org.elasticsearch.common.time.DateMathParser;
34-
import org.elasticsearch.common.time.DateUtils;
3535
import org.elasticsearch.common.util.set.Sets;
3636
import org.elasticsearch.index.Index;
3737
import org.elasticsearch.index.IndexNotFoundException;
3838
import org.elasticsearch.index.IndexSettings;
3939
import org.elasticsearch.indices.IndexClosedException;
4040
import org.elasticsearch.indices.InvalidIndexNameException;
41-
import org.joda.time.DateTimeZone;
42-
import org.joda.time.format.DateTimeFormat;
43-
import org.joda.time.format.DateTimeFormatter;
4441

42+
import java.time.ZoneId;
4543
import java.util.ArrayList;
4644
import java.util.Arrays;
4745
import java.util.Collection;
4846
import java.util.Collections;
4947
import java.util.HashMap;
5048
import java.util.HashSet;
5149
import java.util.List;
52-
import java.util.Locale;
5350
import java.util.Map;
5451
import java.util.Objects;
5552
import java.util.Set;
@@ -66,10 +63,10 @@ public class IndexNameExpressionResolver {
6663
public IndexNameExpressionResolver(Settings settings) {
6764
dateMathExpressionResolver = new DateMathExpressionResolver(settings);
6865
expressionResolvers = Arrays.asList(
69-
dateMathExpressionResolver,
70-
new WildcardExpressionResolver());
66+
dateMathExpressionResolver,
67+
new WildcardExpressionResolver()
68+
);
7169
}
72-
7370

7471
/**
7572
* Same as {@link #concreteIndexNames(ClusterState, IndicesOptions, String...)}, but the index expressions and options
@@ -848,22 +845,23 @@ private static List<String> resolveEmptyOrTrivialWildcard(IndicesOptions options
848845

849846
static final class DateMathExpressionResolver implements ExpressionResolver {
850847

848+
private static final DateFormatter DEFAULT_DATE_FORMATTER = DateFormatters.forPattern("uuuu.MM.dd");
851849
private static final String EXPRESSION_LEFT_BOUND = "<";
852850
private static final String EXPRESSION_RIGHT_BOUND = ">";
853851
private static final char LEFT_BOUND = '{';
854852
private static final char RIGHT_BOUND = '}';
855853
private static final char ESCAPE_CHAR = '\\';
856854
private static final char TIME_ZONE_BOUND = '|';
857855

858-
private final DateTimeZone defaultTimeZone;
856+
private final ZoneId defaultTimeZone;
859857
private final String defaultDateFormatterPattern;
860-
private final DateTimeFormatter defaultDateFormatter;
858+
private final DateFormatter defaultDateFormatter;
861859

862860
DateMathExpressionResolver(Settings settings) {
863861
String defaultTimeZoneId = settings.get("date_math_expression_resolver.default_time_zone", "UTC");
864-
this.defaultTimeZone = DateTimeZone.forID(defaultTimeZoneId);
865-
defaultDateFormatterPattern = settings.get("date_math_expression_resolver.default_date_format", "YYYY.MM.dd");
866-
this.defaultDateFormatter = DateTimeFormat.forPattern(defaultDateFormatterPattern);
862+
this.defaultTimeZone = ZoneId.of(defaultTimeZoneId);
863+
defaultDateFormatterPattern = settings.get("date_math_expression_resolver.default_date_format", "8uuuu.MM.dd");
864+
this.defaultDateFormatter = DateFormatter.forPattern(defaultDateFormatterPattern);
867865
}
868866

869867
@Override
@@ -930,11 +928,10 @@ String resolveExpression(String expression, final Context context) {
930928
int dateTimeFormatLeftBoundIndex = inPlaceHolderString.indexOf(LEFT_BOUND);
931929
String mathExpression;
932930
String dateFormatterPattern;
933-
DateTimeFormatter dateFormatter;
934-
final DateTimeZone timeZone;
931+
DateFormatter dateFormatter;
932+
final ZoneId timeZone;
935933
if (dateTimeFormatLeftBoundIndex < 0) {
936934
mathExpression = inPlaceHolderString;
937-
dateFormatterPattern = defaultDateFormatterPattern;
938935
dateFormatter = defaultDateFormatter;
939936
timeZone = defaultTimeZone;
940937
} else {
@@ -947,23 +944,25 @@ String resolveExpression(String expression, final Context context) {
947944
inPlaceHolderString);
948945
}
949946
mathExpression = inPlaceHolderString.substring(0, dateTimeFormatLeftBoundIndex);
950-
String patternAndTZid =
947+
String dateFormatterPatternAndTimeZoneId =
951948
inPlaceHolderString.substring(dateTimeFormatLeftBoundIndex + 1, inPlaceHolderString.length() - 1);
952-
int formatPatternTimeZoneSeparatorIndex = patternAndTZid.indexOf(TIME_ZONE_BOUND);
949+
int formatPatternTimeZoneSeparatorIndex = dateFormatterPatternAndTimeZoneId.indexOf(TIME_ZONE_BOUND);
953950
if (formatPatternTimeZoneSeparatorIndex != -1) {
954-
dateFormatterPattern = patternAndTZid.substring(0, formatPatternTimeZoneSeparatorIndex);
955-
timeZone = DateTimeZone.forID(patternAndTZid.substring(formatPatternTimeZoneSeparatorIndex + 1));
951+
dateFormatterPattern
952+
= dateFormatterPatternAndTimeZoneId.substring(0, formatPatternTimeZoneSeparatorIndex);
953+
timeZone = ZoneId.of(
954+
dateFormatterPatternAndTimeZoneId.substring(formatPatternTimeZoneSeparatorIndex + 1));
956955
} else {
957-
dateFormatterPattern = patternAndTZid;
956+
dateFormatterPattern = dateFormatterPatternAndTimeZoneId;
958957
timeZone = defaultTimeZone;
959958
}
960-
dateFormatter = DateTimeFormat.forPattern(dateFormatterPattern);
959+
dateFormatter = DateFormatter.forPattern(dateFormatterPattern);
961960
}
962-
DateTimeFormatter parser = dateFormatter.withLocale(Locale.ROOT).withZone(timeZone);
963-
JodaDateFormatter formatter = new JodaDateFormatter(dateFormatterPattern, parser, parser);
961+
DateFormatter formatter = dateFormatter.withZone(timeZone);
964962
DateMathParser dateMathParser = formatter.toDateMathParser();
965-
long millis = dateMathParser.parse(mathExpression, context::getStartTime, false,
966-
DateUtils.dateTimeZoneToZoneId(timeZone));
963+
long millis = dateMathParser.parse(mathExpression, context::getStartTime, false, timeZone);
964+
965+
967966
String time = formatter.formatMillis(millis);
968967
beforePlaceHolderSb.append(time);
969968
inPlaceHolderSb = new StringBuilder();
@@ -1007,18 +1006,4 @@ String resolveExpression(String expression, final Context context) {
10071006
return beforePlaceHolderSb.toString();
10081007
}
10091008
}
1010-
1011-
/**
1012-
* Returns <code>true</code> iff the given expression resolves to the given index name otherwise <code>false</code>
1013-
*/
1014-
public final boolean matchesIndex(String indexName, String expression, ClusterState state) {
1015-
final String[] concreteIndices = concreteIndexNames(state, IndicesOptions.lenientExpandOpen(), expression);
1016-
for (String index : concreteIndices) {
1017-
if (Regex.simpleMatch(index, indexName)) {
1018-
return true;
1019-
}
1020-
}
1021-
return indexName.equals(expression);
1022-
}
1023-
10241009
}

server/src/main/java/org/elasticsearch/common/time/DateFormatters.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,12 +1680,6 @@ public static ZonedDateTime from(TemporalAccessor accessor, Locale locale, ZoneI
16801680
} else {
16811681
return Year.of(accessor.get(ChronoField.YEAR)).atDay(1).atStartOfDay(zoneId);
16821682
}
1683-
} else if (accessor.isSupported(ChronoField.YEAR)) {
1684-
if (accessor.isSupported(MONTH_OF_YEAR)) {
1685-
return getFirstOfMonth(accessor).atStartOfDay(zoneId);
1686-
} else {
1687-
return Year.of(accessor.get(ChronoField.YEAR)).atDay(1).atStartOfDay(zoneId);
1688-
}
16891683
} else if (accessor.isSupported(MONTH_OF_YEAR)) {
16901684
// missing year, falling back to the epoch and then filling
16911685
return getLocaldate(accessor, locale).atStartOfDay(zoneId);
@@ -1713,7 +1707,6 @@ private static LocalDate localDateFromWeekBasedDate(TemporalAccessor accessor, L
17131707
}
17141708
}
17151709

1716-
17171710
private static LocalDate getLocaldate(TemporalAccessor accessor, Locale locale) {
17181711
if (accessor.isSupported(WeekFields.of(locale).weekBasedYear())) {
17191712
return localDateFromWeekBasedDate(accessor, locale);

0 commit comments

Comments
 (0)