Deprecation info for joda-java migration on 7.x (#42659)

Some clusters might have been already migrated to version 7 without being warned about the joda-java migration changes.
Deprecation api on that version will give them guidance on what patterns need to be changed.
relates. This change is using the same logic like in 6.8 that is: verifying the pattern is from the incompatible set ('y'-Y', 'C', 'Z' etc), not from predifined set, not prefixed with 8. AND was also created in 6.x. Mappings created in 7.x are considered migrated and should not generate warnings

There is no pipeline check (present on 6.8) as it is impossible to verify when the pipeline was created, and therefore to make sure the format is depracated or not
#42010
This commit is contained in:
Przemyslaw Gomulka 2019-06-05 19:50:04 +02:00 committed by GitHub
parent 790d2124f6
commit ab5bc83597
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 725 additions and 196 deletions

View File

@ -23,6 +23,7 @@ import org.apache.logging.log4j.LogManager;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.FormatNames;
import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.DateTimeField;
@ -65,173 +66,173 @@ public class Joda {
}
DateTimeFormatter formatter;
if ("basicDate".equals(input) || "basic_date".equals(input)) {
if (FormatNames.BASIC_DATE.matches(input)) {
formatter = ISODateTimeFormat.basicDate();
} else if ("basicDateTime".equals(input) || "basic_date_time".equals(input)) {
} else if (FormatNames.BASIC_DATE_TIME.matches(input) ) {
formatter = ISODateTimeFormat.basicDateTime();
} else if ("basicDateTimeNoMillis".equals(input) || "basic_date_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_DATE_TIME_NO_MILLIS.matches(input) ) {
formatter = ISODateTimeFormat.basicDateTimeNoMillis();
} else if ("basicOrdinalDate".equals(input) || "basic_ordinal_date".equals(input)) {
} else if (FormatNames.BASIC_ORDINAL_DATE.matches(input) ) {
formatter = ISODateTimeFormat.basicOrdinalDate();
} else if ("basicOrdinalDateTime".equals(input) || "basic_ordinal_date_time".equals(input)) {
} else if (FormatNames.BASIC_ORDINAL_DATE_TIME.matches(input) ) {
formatter = ISODateTimeFormat.basicOrdinalDateTime();
} else if ("basicOrdinalDateTimeNoMillis".equals(input) || "basic_ordinal_date_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_ORDINAL_DATE_TIME_NO_MILLIS.matches(input) ) {
formatter = ISODateTimeFormat.basicOrdinalDateTimeNoMillis();
} else if ("basicTime".equals(input) || "basic_time".equals(input)) {
} else if (FormatNames.BASIC_TIME.matches(input) ) {
formatter = ISODateTimeFormat.basicTime();
} else if ("basicTimeNoMillis".equals(input) || "basic_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_TIME_NO_MILLIS.matches(input) ) {
formatter = ISODateTimeFormat.basicTimeNoMillis();
} else if ("basicTTime".equals(input) || "basic_t_time".equals(input)) {
} else if (FormatNames.BASIC_T_TIME.matches(input) ) {
formatter = ISODateTimeFormat.basicTTime();
} else if ("basicTTimeNoMillis".equals(input) || "basic_t_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_T_TIME_NO_MILLIS.matches(input) ) {
formatter = ISODateTimeFormat.basicTTimeNoMillis();
} else if ("basicWeekDate".equals(input) || "basic_week_date".equals(input)) {
} else if (FormatNames.BASIC_WEEK_DATE.matches(input)) {
formatter = ISODateTimeFormat.basicWeekDate();
} else if ("basicWeekDateTime".equals(input) || "basic_week_date_time".equals(input)) {
} else if (FormatNames.BASIC_WEEK_DATE_TIME.matches(input) ) {
formatter = ISODateTimeFormat.basicWeekDateTime();
} else if ("basicWeekDateTimeNoMillis".equals(input) || "basic_week_date_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
formatter = ISODateTimeFormat.basicWeekDateTimeNoMillis();
} else if ("date".equals(input)) {
} else if (FormatNames.DATE.matches(input)) {
formatter = ISODateTimeFormat.date();
} else if ("dateHour".equals(input) || "date_hour".equals(input)) {
} else if (FormatNames.DATE_HOUR.matches(input)) {
formatter = ISODateTimeFormat.dateHour();
} else if ("dateHourMinute".equals(input) || "date_hour_minute".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE.matches(input)) {
formatter = ISODateTimeFormat.dateHourMinute();
} else if ("dateHourMinuteSecond".equals(input) || "date_hour_minute_second".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE_SECOND.matches(input)) {
formatter = ISODateTimeFormat.dateHourMinuteSecond();
} else if ("dateHourMinuteSecondFraction".equals(input) || "date_hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
formatter = ISODateTimeFormat.dateHourMinuteSecondFraction();
} else if ("dateHourMinuteSecondMillis".equals(input) || "date_hour_minute_second_millis".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE_SECOND_MILLIS.matches(input) ) {
formatter = ISODateTimeFormat.dateHourMinuteSecondMillis();
} else if ("dateOptionalTime".equals(input) || "date_optional_time".equals(input)) {
} else if (FormatNames.DATE_OPTIONAL_TIME.matches(input)) {
// in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
// this sucks we should use the root local by default and not be dependent on the node
return new JodaDateFormatter(input,
ISODateTimeFormat.dateOptionalTimeParser().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970),
ISODateTimeFormat.dateTime().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970));
} else if ("dateTime".equals(input) || "date_time".equals(input)) {
} else if (FormatNames.DATE_TIME.matches(input)) {
formatter = ISODateTimeFormat.dateTime();
} else if ("dateTimeNoMillis".equals(input) || "date_time_no_millis".equals(input)) {
} else if (FormatNames.DATE_TIME_NO_MILLIS.matches(input) ) {
formatter = ISODateTimeFormat.dateTimeNoMillis();
} else if ("hour".equals(input)) {
} else if (FormatNames.HOUR.matches(input)) {
formatter = ISODateTimeFormat.hour();
} else if ("hourMinute".equals(input) || "hour_minute".equals(input)) {
} else if (FormatNames.HOUR_MINUTE.matches(input)) {
formatter = ISODateTimeFormat.hourMinute();
} else if ("hourMinuteSecond".equals(input) || "hour_minute_second".equals(input)) {
} else if (FormatNames.HOUR_MINUTE_SECOND.matches(input) ) {
formatter = ISODateTimeFormat.hourMinuteSecond();
} else if ("hourMinuteSecondFraction".equals(input) || "hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
formatter = ISODateTimeFormat.hourMinuteSecondFraction();
} else if ("hourMinuteSecondMillis".equals(input) || "hour_minute_second_millis".equals(input)) {
} else if (FormatNames.HOUR_MINUTE_SECOND_MILLIS.matches(input)) {
formatter = ISODateTimeFormat.hourMinuteSecondMillis();
} else if ("ordinalDate".equals(input) || "ordinal_date".equals(input)) {
} else if (FormatNames.ORDINAL_DATE.matches(input)) {
formatter = ISODateTimeFormat.ordinalDate();
} else if ("ordinalDateTime".equals(input) || "ordinal_date_time".equals(input)) {
} else if (FormatNames.ORDINAL_DATE_TIME.matches(input)) {
formatter = ISODateTimeFormat.ordinalDateTime();
} else if ("ordinalDateTimeNoMillis".equals(input) || "ordinal_date_time_no_millis".equals(input)) {
} else if (FormatNames.ORDINAL_DATE_TIME_NO_MILLIS.matches(input) ) {
formatter = ISODateTimeFormat.ordinalDateTimeNoMillis();
} else if ("time".equals(input)) {
} else if (FormatNames.TIME.matches(input)) {
formatter = ISODateTimeFormat.time();
} else if ("timeNoMillis".equals(input) || "time_no_millis".equals(input)) {
} else if (FormatNames.TIME_NO_MILLIS.matches(input)) {
formatter = ISODateTimeFormat.timeNoMillis();
} else if ("tTime".equals(input) || "t_time".equals(input)) {
} else if (FormatNames.T_TIME.matches(input)) {
formatter = ISODateTimeFormat.tTime();
} else if ("tTimeNoMillis".equals(input) || "t_time_no_millis".equals(input)) {
} else if (FormatNames.T_TIME_NO_MILLIS.matches(input)) {
formatter = ISODateTimeFormat.tTimeNoMillis();
} else if ("weekDate".equals(input) || "week_date".equals(input)) {
} else if (FormatNames.WEEK_DATE.matches(input)) {
formatter = ISODateTimeFormat.weekDate();
} else if ("weekDateTime".equals(input) || "week_date_time".equals(input)) {
} else if (FormatNames.WEEK_DATE_TIME.matches(input)) {
formatter = ISODateTimeFormat.weekDateTime();
} else if ("weekDateTimeNoMillis".equals(input) || "week_date_time_no_millis".equals(input)) {
} else if (FormatNames.WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
formatter = ISODateTimeFormat.weekDateTimeNoMillis();
} else if ("weekyear".equals(input) || "week_year".equals(input)) {
} else if (FormatNames.WEEK_YEAR.matches(input)) {
formatter = ISODateTimeFormat.weekyear();
} else if ("weekyearWeek".equals(input) || "weekyear_week".equals(input)) {
} else if (FormatNames.WEEK_YEAR_WEEK.matches(input)) {
formatter = ISODateTimeFormat.weekyearWeek();
} else if ("weekyearWeekDay".equals(input) || "weekyear_week_day".equals(input)) {
} else if (FormatNames.WEEKYEAR_WEEK_DAY.matches(input)) {
formatter = ISODateTimeFormat.weekyearWeekDay();
} else if ("year".equals(input)) {
} else if (FormatNames.YEAR.matches(input)) {
formatter = ISODateTimeFormat.year();
} else if ("yearMonth".equals(input) || "year_month".equals(input)) {
} else if (FormatNames.YEAR_MONTH.matches(input) ) {
formatter = ISODateTimeFormat.yearMonth();
} else if ("yearMonthDay".equals(input) || "year_month_day".equals(input)) {
} else if (FormatNames.YEAR_MONTH_DAY.matches(input)) {
formatter = ISODateTimeFormat.yearMonthDay();
} else if ("epoch_second".equals(input)) {
} else if (FormatNames.EPOCH_SECOND.matches(input)) {
formatter = new DateTimeFormatterBuilder().append(new EpochTimePrinter(false),
new EpochTimeParser(false)).toFormatter();
} else if ("epoch_millis".equals(input)) {
} else if (FormatNames.EPOCH_MILLIS.matches(input)) {
formatter = new DateTimeFormatterBuilder().append(new EpochTimePrinter(true),
new EpochTimeParser(true)).toFormatter();
// strict date formats here, must be at least 4 digits for year and two for months and two for day
} else if ("strictBasicWeekDate".equals(input) || "strict_basic_week_date".equals(input)) {
} else if (FormatNames.STRICT_BASIC_WEEK_DATE.matches(input) ) {
formatter = StrictISODateTimeFormat.basicWeekDate();
} else if ("strictBasicWeekDateTime".equals(input) || "strict_basic_week_date_time".equals(input)) {
} else if (FormatNames.STRICT_BASIC_WEEK_DATE_TIME.matches(input)) {
formatter = StrictISODateTimeFormat.basicWeekDateTime();
} else if ("strictBasicWeekDateTimeNoMillis".equals(input) || "strict_basic_week_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_BASIC_WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.basicWeekDateTimeNoMillis();
} else if ("strictDate".equals(input) || "strict_date".equals(input)) {
} else if (FormatNames.STRICT_DATE.matches(input)) {
formatter = StrictISODateTimeFormat.date();
} else if ("strictDateHour".equals(input) || "strict_date_hour".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR.matches(input)) {
formatter = StrictISODateTimeFormat.dateHour();
} else if ("strictDateHourMinute".equals(input) || "strict_date_hour_minute".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE.matches(input)) {
formatter = StrictISODateTimeFormat.dateHourMinute();
} else if ("strictDateHourMinuteSecond".equals(input) || "strict_date_hour_minute_second".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND.matches(input)) {
formatter = StrictISODateTimeFormat.dateHourMinuteSecond();
} else if ("strictDateHourMinuteSecondFraction".equals(input) || "strict_date_hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
formatter = StrictISODateTimeFormat.dateHourMinuteSecondFraction();
} else if ("strictDateHourMinuteSecondMillis".equals(input) || "strict_date_hour_minute_second_millis".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.dateHourMinuteSecondMillis();
} else if ("strictDateOptionalTime".equals(input) || "strict_date_optional_time".equals(input)) {
} else if (FormatNames.STRICT_DATE_OPTIONAL_TIME.matches(input)) {
// in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
// this sucks we should use the root local by default and not be dependent on the node
return new JodaDateFormatter(input,
StrictISODateTimeFormat.dateOptionalTimeParser().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC)
.withDefaultYear(1970),
StrictISODateTimeFormat.dateTime().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970));
} else if ("strictDateTime".equals(input) || "strict_date_time".equals(input)) {
} else if (FormatNames.STRICT_DATE_TIME.matches(input)) {
formatter = StrictISODateTimeFormat.dateTime();
} else if ("strictDateTimeNoMillis".equals(input) || "strict_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_DATE_TIME_NO_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.dateTimeNoMillis();
} else if ("strictHour".equals(input) || "strict_hour".equals(input)) {
} else if (FormatNames.STRICT_HOUR.matches(input)) {
formatter = StrictISODateTimeFormat.hour();
} else if ("strictHourMinute".equals(input) || "strict_hour_minute".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE.matches(input)) {
formatter = StrictISODateTimeFormat.hourMinute();
} else if ("strictHourMinuteSecond".equals(input) || "strict_hour_minute_second".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE_SECOND.matches(input)) {
formatter = StrictISODateTimeFormat.hourMinuteSecond();
} else if ("strictHourMinuteSecondFraction".equals(input) || "strict_hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
formatter = StrictISODateTimeFormat.hourMinuteSecondFraction();
} else if ("strictHourMinuteSecondMillis".equals(input) || "strict_hour_minute_second_millis".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE_SECOND_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.hourMinuteSecondMillis();
} else if ("strictOrdinalDate".equals(input) || "strict_ordinal_date".equals(input)) {
} else if (FormatNames.STRICT_ORDINAL_DATE.matches(input)) {
formatter = StrictISODateTimeFormat.ordinalDate();
} else if ("strictOrdinalDateTime".equals(input) || "strict_ordinal_date_time".equals(input)) {
} else if (FormatNames.STRICT_ORDINAL_DATE_TIME.matches(input)) {
formatter = StrictISODateTimeFormat.ordinalDateTime();
} else if ("strictOrdinalDateTimeNoMillis".equals(input) || "strict_ordinal_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_ORDINAL_DATE_TIME_NO_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.ordinalDateTimeNoMillis();
} else if ("strictTime".equals(input) || "strict_time".equals(input)) {
} else if (FormatNames.STRICT_TIME.matches(input)) {
formatter = StrictISODateTimeFormat.time();
} else if ("strictTimeNoMillis".equals(input) || "strict_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_TIME_NO_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.timeNoMillis();
} else if ("strictTTime".equals(input) || "strict_t_time".equals(input)) {
} else if (FormatNames.STRICT_T_TIME.matches(input) ) {
formatter = StrictISODateTimeFormat.tTime();
} else if ("strictTTimeNoMillis".equals(input) || "strict_t_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_T_TIME_NO_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.tTimeNoMillis();
} else if ("strictWeekDate".equals(input) || "strict_week_date".equals(input)) {
} else if (FormatNames.STRICT_WEEK_DATE.matches(input)) {
formatter = StrictISODateTimeFormat.weekDate();
} else if ("strictWeekDateTime".equals(input) || "strict_week_date_time".equals(input)) {
} else if (FormatNames.STRICT_WEEK_DATE_TIME.matches(input)) {
formatter = StrictISODateTimeFormat.weekDateTime();
} else if ("strictWeekDateTimeNoMillis".equals(input) || "strict_week_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
formatter = StrictISODateTimeFormat.weekDateTimeNoMillis();
} else if ("strictWeekyear".equals(input) || "strict_weekyear".equals(input)) {
} else if (FormatNames.STRICT_WEEKYEAR.matches(input) ) {
formatter = StrictISODateTimeFormat.weekyear();
} else if ("strictWeekyearWeek".equals(input) || "strict_weekyear_week".equals(input)) {
} else if (FormatNames.STRICT_WEEKYEAR_WEEK.matches(input)) {
formatter = StrictISODateTimeFormat.weekyearWeek();
} else if ("strictWeekyearWeekDay".equals(input) || "strict_weekyear_week_day".equals(input)) {
} else if (FormatNames.STRICT_WEEKYEAR_WEEK_DAY.matches(input)) {
formatter = StrictISODateTimeFormat.weekyearWeekDay();
} else if ("strictYear".equals(input) || "strict_year".equals(input)) {
} else if (FormatNames.STRICT_YEAR.matches(input)) {
formatter = StrictISODateTimeFormat.year();
} else if ("strictYearMonth".equals(input) || "strict_year_month".equals(input)) {
} else if (FormatNames.STRICT_YEAR_MONTH.matches(input)) {
formatter = StrictISODateTimeFormat.yearMonth();
} else if ("strictYearMonthDay".equals(input) || "strict_year_month_day".equals(input)) {
} else if (FormatNames.STRICT_YEAR_MONTH_DAY.matches(input)) {
formatter = StrictISODateTimeFormat.yearMonthDay();
} else if (Strings.hasLength(input) && input.contains("||")) {
String[] formats = Strings.delimitedListToStringArray(input, "||");
@ -267,18 +268,11 @@ public class Joda {
return new JodaDateFormatter(input, formatter, formatter);
}
private static void maybeLogJodaDeprecation(String input) {
if (input.contains("CC")) {
deprecationLogger.deprecatedAndMaybeLog("joda-century-of-era-format",
"Use of 'C' (century-of-era) is deprecated and will not be supported in the next major version of Elasticsearch.");
}
if (input.contains("YY")) {
deprecationLogger.deprecatedAndMaybeLog("joda-year-of-era-format", "Use of 'Y' (year-of-era) will change to 'y' in the" +
" next major version of Elasticsearch. Prefix your date format with '8' to use the new specifier.");
}
if (input.contains("xx")) {
deprecationLogger.deprecatedAndMaybeLog("joda-week-based-year-format","Use of 'x' (week-based-year) will change" +
" to 'Y' in the next major version of Elasticsearch. Prefix your date format with '8' to use the new specifier.");
private static void maybeLogJodaDeprecation(String format) {
if (JodaDeprecationPatterns.isDeprecatedPattern(format)) {
String suggestion = JodaDeprecationPatterns.formatSuggestion(format);
deprecationLogger.deprecatedAndMaybeLog("joda-pattern-deprecation",
suggestion + " " + JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
}
}

View File

@ -0,0 +1,94 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.joda;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.FormatNames;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class JodaDeprecationPatterns {
public static final String USE_NEW_FORMAT_SPECIFIERS = "Use new java.time date format specifiiers.";
private static Map<String, String> JODA_PATTERNS_DEPRECATIONS = new LinkedHashMap<>();
static {
JODA_PATTERNS_DEPRECATIONS.put("Y", "'Y' year-of-era should be replaced with 'y'. Use 'Y' for week-based-year.");
JODA_PATTERNS_DEPRECATIONS.put("y", "'y' year should be replaced with 'u'. Use 'y' for year-of-era.");
JODA_PATTERNS_DEPRECATIONS.put("C", "'C' century of era is no longer supported.");
JODA_PATTERNS_DEPRECATIONS.put("x", "'x' weak-year should be replaced with 'Y'. Use 'x' for zone-offset.");
JODA_PATTERNS_DEPRECATIONS.put("Z",
"'Z' time zone offset/id fails when parsing 'Z' for Zulu timezone. Consider using 'X'.");
JODA_PATTERNS_DEPRECATIONS.put("z",
"'z' time zone text. Will print 'Z' for Zulu given UTC timezone.");
}
/**
* Checks if date parsing pattern is deprecated.
* Deprecated here means: when it was not already prefixed with 8 (meaning already upgraded)
* and it is not a predefined pattern from <code>FormatNames</code> like basic_date_time_no_millis
* and it uses pattern characters which changed meaning from joda to java like Y becomes y.
* @param pattern - a format to be checked
* @return true if format is deprecated, otherwise false
*/
public static boolean isDeprecatedPattern(String pattern) {
List<String> patterns = DateFormatter.splitCombinedPatterns(pattern);
for (String subPattern : patterns) {
boolean isDeprecated = subPattern.startsWith("8") == false && FormatNames.exist(subPattern) == false &&
JODA_PATTERNS_DEPRECATIONS.keySet().stream()
.filter(s -> subPattern.contains(s))
.findAny()
.isPresent();
if (isDeprecated) {
return true;
}
}
return false;
}
/**
* Formats deprecation message for suggestion field in a warning header.
* Joins all warnings in a one message.
* @param pattern - a pattern to be formatted
* @return a formatted deprecation message
*/
public static String formatSuggestion(String pattern) {
List<String> patterns = DateFormatter.splitCombinedPatterns(pattern);
Set<String> warnings = new LinkedHashSet<>();
for (String subPattern : patterns) {
if (isDeprecatedPattern(subPattern)) {
String suggestion = JODA_PATTERNS_DEPRECATIONS.entrySet().stream()
.filter(s -> subPattern.contains(s.getKey()))
.map(s -> s.getValue())
.collect(Collectors.joining("; "));
warnings.add(suggestion);
}
}
String combinedWarning = warnings.stream()
.collect(Collectors.joining("; "));
return combinedWarning;
}
}

View File

@ -31,6 +31,7 @@ import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public interface DateFormatter {
@ -137,13 +138,10 @@ public interface DateFormatter {
input = input.substring(1);
}
List<DateFormatter> formatters = new ArrayList<>();
for (String pattern : Strings.delimitedListToStringArray(input, "||")) {
if (Strings.hasLength(pattern) == false) {
throw new IllegalArgumentException("Cannot have empty element in multi date format pattern: " + input);
}
formatters.add(DateFormatters.forPattern(pattern));
}
List<String> patterns = splitCombinedPatterns(input);
List<DateFormatter> formatters = patterns.stream()
.map(DateFormatters::forPattern)
.collect(Collectors.toList());
if (formatters.size() == 1) {
return formatters.get(0);
@ -151,4 +149,15 @@ public interface DateFormatter {
return DateFormatters.merge(input, formatters);
}
static List<String> splitCombinedPatterns(String input) {
List<String> patterns = new ArrayList<>();
for (String pattern : Strings.delimitedListToStringArray(input, "||")) {
if (Strings.hasLength(pattern) == false) {
throw new IllegalArgumentException("Cannot have empty element in multi date format pattern: " + input);
}
patterns.add(pattern);
}
return patterns;
}
}

View File

@ -1423,166 +1423,166 @@ public class DateFormatters {
throw new IllegalArgumentException("No date pattern provided");
}
if ("iso8601".equals(input)) {
if (FormatNames.ISO8601.matches(input)) {
return ISO_8601;
} else if ("basicDate".equals(input) || "basic_date".equals(input)) {
} else if (FormatNames.BASIC_DATE.matches(input) ) {
return BASIC_DATE;
} else if ("basicDateTime".equals(input) || "basic_date_time".equals(input)) {
} else if (FormatNames.BASIC_DATE_TIME.matches(input) ) {
return BASIC_DATE_TIME;
} else if ("basicDateTimeNoMillis".equals(input) || "basic_date_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_DATE_TIME_NO_MILLIS.matches(input) ) {
return BASIC_DATE_TIME_NO_MILLIS;
} else if ("basicOrdinalDate".equals(input) || "basic_ordinal_date".equals(input)) {
} else if (FormatNames.BASIC_ORDINAL_DATE.matches(input) ) {
return BASIC_ORDINAL_DATE;
} else if ("basicOrdinalDateTime".equals(input) || "basic_ordinal_date_time".equals(input)) {
} else if (FormatNames.BASIC_ORDINAL_DATE_TIME.matches(input) ) {
return BASIC_ORDINAL_DATE_TIME;
} else if ("basicOrdinalDateTimeNoMillis".equals(input) || "basic_ordinal_date_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_ORDINAL_DATE_TIME_NO_MILLIS.matches(input) ) {
return BASIC_ORDINAL_DATE_TIME_NO_MILLIS;
} else if ("basicTime".equals(input) || "basic_time".equals(input)) {
} else if (FormatNames.BASIC_TIME.matches(input) ) {
return BASIC_TIME;
} else if ("basicTimeNoMillis".equals(input) || "basic_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_TIME_NO_MILLIS.matches(input) ) {
return BASIC_TIME_NO_MILLIS;
} else if ("basicTTime".equals(input) || "basic_t_time".equals(input)) {
} else if (FormatNames.BASIC_T_TIME.matches(input) ) {
return BASIC_T_TIME;
} else if ("basicTTimeNoMillis".equals(input) || "basic_t_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_T_TIME_NO_MILLIS.matches(input) ) {
return BASIC_T_TIME_NO_MILLIS;
} else if ("basicWeekDate".equals(input) || "basic_week_date".equals(input)) {
} else if (FormatNames.BASIC_WEEK_DATE.matches(input) ) {
return BASIC_WEEK_DATE;
} else if ("basicWeekDateTime".equals(input) || "basic_week_date_time".equals(input)) {
} else if (FormatNames.BASIC_WEEK_DATE_TIME.matches(input) ) {
return BASIC_WEEK_DATE_TIME;
} else if ("basicWeekDateTimeNoMillis".equals(input) || "basic_week_date_time_no_millis".equals(input)) {
} else if (FormatNames.BASIC_WEEK_DATE_TIME_NO_MILLIS.matches(input) ) {
return BASIC_WEEK_DATE_TIME_NO_MILLIS;
} else if ("date".equals(input)) {
} else if (FormatNames.DATE.matches(input)) {
return DATE;
} else if ("dateHour".equals(input) || "date_hour".equals(input)) {
} else if (FormatNames.DATE_HOUR.matches(input) ) {
return DATE_HOUR;
} else if ("dateHourMinute".equals(input) || "date_hour_minute".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE.matches(input) ) {
return DATE_HOUR_MINUTE;
} else if ("dateHourMinuteSecond".equals(input) || "date_hour_minute_second".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE_SECOND.matches(input) ) {
return DATE_HOUR_MINUTE_SECOND;
} else if ("dateHourMinuteSecondFraction".equals(input) || "date_hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE_SECOND_FRACTION.matches(input) ) {
return DATE_HOUR_MINUTE_SECOND_FRACTION;
} else if ("dateHourMinuteSecondMillis".equals(input) || "date_hour_minute_second_millis".equals(input)) {
} else if (FormatNames.DATE_HOUR_MINUTE_SECOND_MILLIS.matches(input) ) {
return DATE_HOUR_MINUTE_SECOND_MILLIS;
} else if ("dateOptionalTime".equals(input) || "date_optional_time".equals(input)) {
} else if (FormatNames.DATE_OPTIONAL_TIME.matches(input) ) {
return DATE_OPTIONAL_TIME;
} else if ("dateTime".equals(input) || "date_time".equals(input)) {
} else if (FormatNames.DATE_TIME.matches(input) ) {
return DATE_TIME;
} else if ("dateTimeNoMillis".equals(input) || "date_time_no_millis".equals(input)) {
} else if (FormatNames.DATE_TIME_NO_MILLIS.matches(input) ) {
return DATE_TIME_NO_MILLIS;
} else if ("hour".equals(input)) {
} else if (FormatNames.HOUR.matches(input)) {
return HOUR;
} else if ("hourMinute".equals(input) || "hour_minute".equals(input)) {
} else if (FormatNames.HOUR_MINUTE.matches(input) ) {
return HOUR_MINUTE;
} else if ("hourMinuteSecond".equals(input) || "hour_minute_second".equals(input)) {
} else if (FormatNames.HOUR_MINUTE_SECOND.matches(input) ) {
return HOUR_MINUTE_SECOND;
} else if ("hourMinuteSecondFraction".equals(input) || "hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.HOUR_MINUTE_SECOND_FRACTION.matches(input) ) {
return HOUR_MINUTE_SECOND_FRACTION;
} else if ("hourMinuteSecondMillis".equals(input) || "hour_minute_second_millis".equals(input)) {
} else if (FormatNames.HOUR_MINUTE_SECOND_MILLIS.matches(input) ) {
return HOUR_MINUTE_SECOND_MILLIS;
} else if ("ordinalDate".equals(input) || "ordinal_date".equals(input)) {
} else if (FormatNames.ORDINAL_DATE.matches(input) ) {
return ORDINAL_DATE;
} else if ("ordinalDateTime".equals(input) || "ordinal_date_time".equals(input)) {
} else if (FormatNames.ORDINAL_DATE_TIME.matches(input) ) {
return ORDINAL_DATE_TIME;
} else if ("ordinalDateTimeNoMillis".equals(input) || "ordinal_date_time_no_millis".equals(input)) {
} else if (FormatNames.ORDINAL_DATE_TIME_NO_MILLIS.matches(input) ) {
return ORDINAL_DATE_TIME_NO_MILLIS;
} else if ("time".equals(input)) {
} else if (FormatNames.TIME.matches(input)) {
return TIME;
} else if ("timeNoMillis".equals(input) || "time_no_millis".equals(input)) {
} else if (FormatNames.TIME_NO_MILLIS.matches(input) ) {
return TIME_NO_MILLIS;
} else if ("tTime".equals(input) || "t_time".equals(input)) {
} else if (FormatNames.T_TIME.matches(input) ) {
return T_TIME;
} else if ("tTimeNoMillis".equals(input) || "t_time_no_millis".equals(input)) {
} else if (FormatNames.T_TIME_NO_MILLIS.matches(input) ) {
return T_TIME_NO_MILLIS;
} else if ("weekDate".equals(input) || "week_date".equals(input)) {
} else if (FormatNames.WEEK_DATE.matches(input) ) {
return WEEK_DATE;
} else if ("weekDateTime".equals(input) || "week_date_time".equals(input)) {
} else if (FormatNames.WEEK_DATE_TIME.matches(input) ) {
return WEEK_DATE_TIME;
} else if ("weekDateTimeNoMillis".equals(input) || "week_date_time_no_millis".equals(input)) {
} else if (FormatNames.WEEK_DATE_TIME_NO_MILLIS.matches(input) ) {
return WEEK_DATE_TIME_NO_MILLIS;
} else if ("weekyear".equals(input) || "week_year".equals(input)) {
} else if (FormatNames.WEEK_YEAR.matches(input) ) {
return WEEK_YEAR;
} else if ("weekyearWeek".equals(input) || "weekyear_week".equals(input)) {
} else if (FormatNames.WEEK_YEAR_WEEK.matches(input) ) {
return WEEKYEAR_WEEK;
} else if ("weekyearWeekDay".equals(input) || "weekyear_week_day".equals(input)) {
} else if (FormatNames.WEEKYEAR_WEEK_DAY.matches(input) ) {
return WEEKYEAR_WEEK_DAY;
} else if ("year".equals(input)) {
} else if (FormatNames.YEAR.matches(input)) {
return YEAR;
} else if ("yearMonth".equals(input) || "year_month".equals(input)) {
} else if (FormatNames.YEAR_MONTH.matches(input) ) {
return YEAR_MONTH;
} else if ("yearMonthDay".equals(input) || "year_month_day".equals(input)) {
} else if (FormatNames.YEAR_MONTH_DAY.matches(input) ) {
return YEAR_MONTH_DAY;
} else if ("epoch_second".equals(input)) {
} else if (FormatNames.EPOCH_SECOND.matches(input)) {
return EpochTime.SECONDS_FORMATTER;
} else if ("epoch_millis".equals(input)) {
} else if (FormatNames.EPOCH_MILLIS.matches(input)) {
return EpochTime.MILLIS_FORMATTER;
// strict date formats here, must be at least 4 digits for year and two for months and two for day
} else if ("strictBasicWeekDate".equals(input) || "strict_basic_week_date".equals(input)) {
// strict date formats here, must be at least 4 digits for year and two for months and two for day
} else if (FormatNames.STRICT_BASIC_WEEK_DATE.matches(input) ) {
return STRICT_BASIC_WEEK_DATE;
} else if ("strictBasicWeekDateTime".equals(input) || "strict_basic_week_date_time".equals(input)) {
} else if (FormatNames.STRICT_BASIC_WEEK_DATE_TIME.matches(input) ) {
return STRICT_BASIC_WEEK_DATE_TIME;
} else if ("strictBasicWeekDateTimeNoMillis".equals(input) || "strict_basic_week_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_BASIC_WEEK_DATE_TIME_NO_MILLIS.matches(input) ) {
return STRICT_BASIC_WEEK_DATE_TIME_NO_MILLIS;
} else if ("strictDate".equals(input) || "strict_date".equals(input)) {
} else if (FormatNames.STRICT_DATE.matches(input) ) {
return STRICT_DATE;
} else if ("strictDateHour".equals(input) || "strict_date_hour".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR.matches(input) ) {
return STRICT_DATE_HOUR;
} else if ("strictDateHourMinute".equals(input) || "strict_date_hour_minute".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE.matches(input) ) {
return STRICT_DATE_HOUR_MINUTE;
} else if ("strictDateHourMinuteSecond".equals(input) || "strict_date_hour_minute_second".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND.matches(input) ) {
return STRICT_DATE_HOUR_MINUTE_SECOND;
} else if ("strictDateHourMinuteSecondFraction".equals(input) || "strict_date_hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND_FRACTION.matches(input) ) {
return STRICT_DATE_HOUR_MINUTE_SECOND_FRACTION;
} else if ("strictDateHourMinuteSecondMillis".equals(input) || "strict_date_hour_minute_second_millis".equals(input)) {
} else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND_MILLIS.matches(input) ) {
return STRICT_DATE_HOUR_MINUTE_SECOND_MILLIS;
} else if ("strictDateOptionalTime".equals(input) || "strict_date_optional_time".equals(input)) {
} else if (FormatNames.STRICT_DATE_OPTIONAL_TIME.matches(input) ) {
return STRICT_DATE_OPTIONAL_TIME;
} else if ("strictDateOptionalTimeNanos".equals(input) || "strict_date_optional_time_nanos".equals(input)) {
} else if (FormatNames.STRICT_DATE_OPTIONAL_TIME_NANOS.matches(input) ) {
return STRICT_DATE_OPTIONAL_TIME_NANOS;
} else if ("strictDateTime".equals(input) || "strict_date_time".equals(input)) {
} else if (FormatNames.STRICT_DATE_TIME.matches(input) ) {
return STRICT_DATE_TIME;
} else if ("strictDateTimeNoMillis".equals(input) || "strict_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_DATE_TIME_NO_MILLIS.matches(input) ) {
return STRICT_DATE_TIME_NO_MILLIS;
} else if ("strictHour".equals(input) || "strict_hour".equals(input)) {
} else if (FormatNames.STRICT_HOUR.matches(input) ) {
return STRICT_HOUR;
} else if ("strictHourMinute".equals(input) || "strict_hour_minute".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE.matches(input) ) {
return STRICT_HOUR_MINUTE;
} else if ("strictHourMinuteSecond".equals(input) || "strict_hour_minute_second".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE_SECOND.matches(input) ) {
return STRICT_HOUR_MINUTE_SECOND;
} else if ("strictHourMinuteSecondFraction".equals(input) || "strict_hour_minute_second_fraction".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE_SECOND_FRACTION.matches(input) ) {
return STRICT_HOUR_MINUTE_SECOND_FRACTION;
} else if ("strictHourMinuteSecondMillis".equals(input) || "strict_hour_minute_second_millis".equals(input)) {
} else if (FormatNames.STRICT_HOUR_MINUTE_SECOND_MILLIS.matches(input) ) {
return STRICT_HOUR_MINUTE_SECOND_MILLIS;
} else if ("strictOrdinalDate".equals(input) || "strict_ordinal_date".equals(input)) {
} else if (FormatNames.STRICT_ORDINAL_DATE.matches(input) ) {
return STRICT_ORDINAL_DATE;
} else if ("strictOrdinalDateTime".equals(input) || "strict_ordinal_date_time".equals(input)) {
} else if (FormatNames.STRICT_ORDINAL_DATE_TIME.matches(input) ) {
return STRICT_ORDINAL_DATE_TIME;
} else if ("strictOrdinalDateTimeNoMillis".equals(input) || "strict_ordinal_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_ORDINAL_DATE_TIME_NO_MILLIS.matches(input) ) {
return STRICT_ORDINAL_DATE_TIME_NO_MILLIS;
} else if ("strictTime".equals(input) || "strict_time".equals(input)) {
} else if (FormatNames.STRICT_TIME.matches(input) ) {
return STRICT_TIME;
} else if ("strictTimeNoMillis".equals(input) || "strict_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_TIME_NO_MILLIS.matches(input) ) {
return STRICT_TIME_NO_MILLIS;
} else if ("strictTTime".equals(input) || "strict_t_time".equals(input)) {
} else if (FormatNames.STRICT_T_TIME.matches(input) ) {
return STRICT_T_TIME;
} else if ("strictTTimeNoMillis".equals(input) || "strict_t_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_T_TIME_NO_MILLIS.matches(input) ) {
return STRICT_T_TIME_NO_MILLIS;
} else if ("strictWeekDate".equals(input) || "strict_week_date".equals(input)) {
} else if (FormatNames.STRICT_WEEK_DATE.matches(input) ) {
return STRICT_WEEK_DATE;
} else if ("strictWeekDateTime".equals(input) || "strict_week_date_time".equals(input)) {
} else if (FormatNames.STRICT_WEEK_DATE_TIME.matches(input) ) {
return STRICT_WEEK_DATE_TIME;
} else if ("strictWeekDateTimeNoMillis".equals(input) || "strict_week_date_time_no_millis".equals(input)) {
} else if (FormatNames.STRICT_WEEK_DATE_TIME_NO_MILLIS.matches(input) ) {
return STRICT_WEEK_DATE_TIME_NO_MILLIS;
} else if ("strictWeekyear".equals(input) || "strict_weekyear".equals(input)) {
} else if (FormatNames.STRICT_WEEKYEAR.matches(input) ) {
return STRICT_WEEKYEAR;
} else if ("strictWeekyearWeek".equals(input) || "strict_weekyear_week".equals(input)) {
} else if (FormatNames.STRICT_WEEKYEAR_WEEK.matches(input) ) {
return STRICT_WEEKYEAR_WEEK;
} else if ("strictWeekyearWeekDay".equals(input) || "strict_weekyear_week_day".equals(input)) {
} else if (FormatNames.STRICT_WEEKYEAR_WEEK_DAY.matches(input) ) {
return STRICT_WEEKYEAR_WEEK_DAY;
} else if ("strictYear".equals(input) || "strict_year".equals(input)) {
} else if (FormatNames.STRICT_YEAR.matches(input) ) {
return STRICT_YEAR;
} else if ("strictYearMonth".equals(input) || "strict_year_month".equals(input)) {
} else if (FormatNames.STRICT_YEAR_MONTH.matches(input) ) {
return STRICT_YEAR_MONTH;
} else if ("strictYearMonthDay".equals(input) || "strict_year_month_day".equals(input)) {
} else if (FormatNames.STRICT_YEAR_MONTH_DAY.matches(input) ) {
return STRICT_YEAR_MONTH_DAY;
} else {
try {

View File

@ -0,0 +1,128 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.time;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public enum FormatNames {
ISO8601("iso8601", "iso8601"),
BASIC_DATE("basicDate", "basic_date"),
BASIC_DATE_TIME("basicDateTime", "basic_date_time"),
BASIC_DATE_TIME_NO_MILLIS("basicDateTimeNoMillis", "basic_date_time_no_millis"),
BASIC_ORDINAL_DATE("basicOrdinalDate", "basic_ordinal_date"),
BASIC_ORDINAL_DATE_TIME("basicOrdinalDateTime", "basic_ordinal_date_time"),
BASIC_ORDINAL_DATE_TIME_NO_MILLIS("basicOrdinalDateTimeNoMillis", "basic_ordinal_date_time_no_millis"),
BASIC_TIME("basicTime", "basic_time"),
BASIC_TIME_NO_MILLIS("basicTimeNoMillis", "basic_time_no_millis"),
BASIC_T_TIME("basicTTime", "basic_t_time"),
BASIC_T_TIME_NO_MILLIS("basicTTimeNoMillis", "basic_t_time_no_millis"),
BASIC_WEEK_DATE("basicWeekDate", "basic_week_date"),
BASIC_WEEK_DATE_TIME("basicWeekDateTime", "basic_week_date_time"),
BASIC_WEEK_DATE_TIME_NO_MILLIS("basicWeekDateTimeNoMillis", "basic_week_date_time_no_millis"),
DATE("date", "date"),
DATE_HOUR("dateHour", "date_hour"),
DATE_HOUR_MINUTE("dateHourMinute", "date_hour_minute"),
DATE_HOUR_MINUTE_SECOND("dateHourMinuteSecond", "date_hour_minute_second"),
DATE_HOUR_MINUTE_SECOND_FRACTION("dateHourMinuteSecondFraction", "date_hour_minute_second_fraction"),
DATE_HOUR_MINUTE_SECOND_MILLIS("dateHourMinuteSecondMillis", "date_hour_minute_second_millis"),
DATE_OPTIONAL_TIME("dateOptionalTime", "date_optional_time"),
DATE_TIME("dateTime", "date_time"),
DATE_TIME_NO_MILLIS("dateTimeNoMillis", "date_time_no_millis"),
HOUR("hour", "hour"),
HOUR_MINUTE("hourMinute", "hour_minute"),
HOUR_MINUTE_SECOND("hourMinuteSecond", "hour_minute_second"),
HOUR_MINUTE_SECOND_FRACTION("hourMinuteSecondFraction", "hour_minute_second_fraction"),
HOUR_MINUTE_SECOND_MILLIS("hourMinuteSecondMillis", "hour_minute_second_millis"),
ORDINAL_DATE("ordinalDate", "ordinal_date"),
ORDINAL_DATE_TIME("ordinalDateTime", "ordinal_date_time"),
ORDINAL_DATE_TIME_NO_MILLIS("ordinalDateTimeNoMillis", "ordinal_date_time_no_millis"),
TIME("time", "time"),
TIME_NO_MILLIS("timeNoMillis", "time_no_millis"),
T_TIME("tTime", "t_time"),
T_TIME_NO_MILLIS("tTimeNoMillis", "t_time_no_millis"),
WEEK_DATE("weekDate", "week_date"),
WEEK_DATE_TIME("weekDateTime", "week_date_time"),
WEEK_DATE_TIME_NO_MILLIS("weekDateTimeNoMillis", "week_date_time_no_millis"),
WEEK_YEAR("weekyear", "week_year"),
WEEK_YEAR_WEEK("weekyearWeek", "weekyear_week"),
WEEKYEAR_WEEK_DAY("weekyearWeekDay", "weekyear_week_day"),
YEAR("year", "year"),
YEAR_MONTH("yearMonth", "year_month"),
YEAR_MONTH_DAY("yearMonthDay", "year_month_day"),
EPOCH_SECOND("epoch_second", "epoch_second"),
EPOCH_MILLIS("epoch_millis", "epoch_millis"),
// strict date formats here, must be at least 4 digits for year and two for months and two for day"
STRICT_BASIC_WEEK_DATE("strictBasicWeekDate", "strict_basic_week_date"),
STRICT_BASIC_WEEK_DATE_TIME("strictBasicWeekDateTime", "strict_basic_week_date_time"),
STRICT_BASIC_WEEK_DATE_TIME_NO_MILLIS("strictBasicWeekDateTimeNoMillis", "strict_basic_week_date_time_no_millis"),
STRICT_DATE("strictDate", "strict_date"),
STRICT_DATE_HOUR("strictDateHour", "strict_date_hour"),
STRICT_DATE_HOUR_MINUTE("strictDateHourMinute", "strict_date_hour_minute"),
STRICT_DATE_HOUR_MINUTE_SECOND("strictDateHourMinuteSecond", "strict_date_hour_minute_second"),
STRICT_DATE_HOUR_MINUTE_SECOND_FRACTION("strictDateHourMinuteSecondFraction", "strict_date_hour_minute_second_fraction"),
STRICT_DATE_HOUR_MINUTE_SECOND_MILLIS("strictDateHourMinuteSecondMillis", "strict_date_hour_minute_second_millis"),
STRICT_DATE_OPTIONAL_TIME("strictDateOptionalTime", "strict_date_optional_time"),
STRICT_DATE_OPTIONAL_TIME_NANOS("strictDateOptionalTimeNanos", "strict_date_optional_time_nanos"),
STRICT_DATE_TIME("strictDateTime", "strict_date_time"),
STRICT_DATE_TIME_NO_MILLIS("strictDateTimeNoMillis", "strict_date_time_no_millis"),
STRICT_HOUR("strictHour", "strict_hour"),
STRICT_HOUR_MINUTE("strictHourMinute", "strict_hour_minute"),
STRICT_HOUR_MINUTE_SECOND("strictHourMinuteSecond", "strict_hour_minute_second"),
STRICT_HOUR_MINUTE_SECOND_FRACTION("strictHourMinuteSecondFraction", "strict_hour_minute_second_fraction"),
STRICT_HOUR_MINUTE_SECOND_MILLIS("strictHourMinuteSecondMillis", "strict_hour_minute_second_millis"),
STRICT_ORDINAL_DATE("strictOrdinalDate", "strict_ordinal_date"),
STRICT_ORDINAL_DATE_TIME("strictOrdinalDateTime", "strict_ordinal_date_time"),
STRICT_ORDINAL_DATE_TIME_NO_MILLIS("strictOrdinalDateTimeNoMillis", "strict_ordinal_date_time_no_millis"),
STRICT_TIME("strictTime", "strict_time"),
STRICT_TIME_NO_MILLIS("strictTimeNoMillis", "strict_time_no_millis"),
STRICT_T_TIME("strictTTime", "strict_t_time"),
STRICT_T_TIME_NO_MILLIS("strictTTimeNoMillis", "strict_t_time_no_millis"),
STRICT_WEEK_DATE("strictWeekDate", "strict_week_date"),
STRICT_WEEK_DATE_TIME("strictWeekDateTime", "strict_week_date_time"),
STRICT_WEEK_DATE_TIME_NO_MILLIS("strictWeekDateTimeNoMillis", "strict_week_date_time_no_millis"),
STRICT_WEEKYEAR("strictWeekyear", "strict_weekyear"),
STRICT_WEEKYEAR_WEEK("strictWeekyearWeek", "strict_weekyear_week"),
STRICT_WEEKYEAR_WEEK_DAY("strictWeekyearWeekDay", "strict_weekyear_week_day"),
STRICT_YEAR("strictYear", "strict_year"),
STRICT_YEAR_MONTH("strictYearMonth", "strict_year_month"),
STRICT_YEAR_MONTH_DAY("strictYearMonthDay", "strict_year_month_day");
private static final Set<String> ALL_NAMES = Arrays.stream(values())
.flatMap(n -> Stream.of(n.snakeCaseName, n.camelCaseName))
.collect(Collectors.toSet());
private final String camelCaseName;
private final String snakeCaseName;
FormatNames(String camelCaseName, String snakeCaseName) {
this.camelCaseName = camelCaseName;
this.snakeCaseName = snakeCaseName;
}
public static boolean exist(String format) {
return ALL_NAMES.contains(format);
}
public boolean matches(String format) {
return format.equals(camelCaseName) || format.equals(snakeCaseName);
}
}

View File

@ -26,6 +26,7 @@ import org.elasticsearch.test.ESTestCase;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat;
import org.joda.time.format.DateTimeFormat;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
@ -34,10 +35,53 @@ import java.time.temporal.TemporalAccessor;
import java.util.Locale;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
public class JavaJodaTimeDuellingTests extends ESTestCase {
public void testIncompatiblePatterns() {
// in joda 'y' means year, this is changed to 'u' in java.time. difference is in before era yeaers
assertSameMillis("-0001-01-01", "yyyy-MM-dd", "8uuuu-MM-dd");
assertSameMillis("-1", "y", "8u");
// year-of-era in joda becomes 'y' in java.time
assertSameMillis("2019-01-01", "YYYY-MM-dd", "8yyyy-MM-dd");
//in joda 'Z' was able to parse 'Z' zulu but in java it fails. You have to use 'X' to do that.
assertSameMillis("2019-01-01T01:01:01.001Z", "YYYY-MM-dd'T'HH:mm:ss.SSSZ", "8yyyy-MM-dd'T'HH:mm:ss.SSSX");
assertSameMillis("2019-01-01T01:01:01.001+0000", "YYYY-MM-dd'T'HH:mm:ss.SSSZ", "8yyyy-MM-dd'T'HH:mm:ss.SSSZ");
// 'z' zoneId in joda prints UTC whereas joda prints 'Z' for zulu
TemporalAccessor parse = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz",Locale.getDefault())
.parse("2019-01-01T01:01:01.001+00:00");
String javaZoneId = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz",Locale.getDefault())
.format(parse);
DateTime dateTime = DateTimeFormat.forPattern("YYYY-MM-dd'T'HH:mm:ss.SSSZ").withOffsetParsed()
.parseDateTime("2019-01-01T01:01:01.001+0000");
String jodaZoneId = DateTimeFormat.forPattern("YYYY-MM-dd'T'HH:mm:ss.SSSz").print(dateTime);
assertThat(javaZoneId, equalTo("2019-01-01T01:01:01.001Z"));
assertThat(jodaZoneId, equalTo("2019-01-01T01:01:01.001UTC"));
}
private void assertSameMillis(String input, String jodaFormat, String javaFormat) {
DateFormatter jodaFormatter = Joda.forPattern(jodaFormat);
DateFormatter javaFormatter = DateFormatter.forPattern(javaFormat);
DateTime jodaDateTime = jodaFormatter.parseJoda(input);
TemporalAccessor javaTimeAccessor = javaFormatter.parse(input);
ZonedDateTime zonedDateTime = DateFormatters.from(javaTimeAccessor);
String msg = String.format(Locale.ROOT, "Input [%s] JodaFormat [%s] JavaFormat [%s] Joda [%s], Java [%s]",
input, jodaFormat, javaFormat, jodaDateTime, DateTimeFormatter.ISO_INSTANT.format(zonedDateTime.toInstant()));
assertThat(msg, jodaDateTime.getMillis(), is(zonedDateTime.toInstant().toEpochMilli()));
}
public void testTimeZoneFormatting() {
assertSameDate("2001-01-01T00:00:00Z", "date_time_no_millis");
// the following fail under java 8 but work under java 10, needs investigation

View File

@ -65,6 +65,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.joda.JodaDeprecationPatterns;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.LogConfigurator;
import org.elasticsearch.common.logging.Loggers;
@ -355,6 +356,10 @@ public abstract class ESTestCase extends LuceneTestCase {
return true;
}
protected boolean enableJodaDeprecationWarningsCheck() {
return false;
}
@After
public final void after() throws Exception {
checkStaticState(false);
@ -385,7 +390,13 @@ public abstract class ESTestCase extends LuceneTestCase {
//appropriate test
try {
final List<String> warnings = threadContext.getResponseHeaders().get("Warning");
assertNull("unexpected warning headers", warnings);
if (warnings != null && enableJodaDeprecationWarningsCheck() == false) {
List<String> filteredWarnings = filterJodaDeprecationWarnings(warnings);
assertThat( filteredWarnings, empty());
} else {
assertNull("unexpected warning headers", warnings);
}
} finally {
resetDeprecationLogger(false);
}
@ -418,20 +429,35 @@ public abstract class ESTestCase extends LuceneTestCase {
}
try {
final List<String> actualWarnings = threadContext.getResponseHeaders().get("Warning");
assertNotNull("no warnings, expected: " + Arrays.asList(expectedWarnings), actualWarnings);
final Set<String> actualWarningValues =
actualWarnings.stream().map(DeprecationLogger::extractWarningValueFromWarningHeader).collect(Collectors.toSet());
for (String msg : expectedWarnings) {
assertThat(actualWarningValues, hasItem(DeprecationLogger.escapeAndEncode(msg)));
if (actualWarnings != null && enableJodaDeprecationWarningsCheck() == false) {
List<String> filteredWarnings = filterJodaDeprecationWarnings(actualWarnings);
assertWarnings(filteredWarnings, expectedWarnings);
} else {
assertWarnings(actualWarnings, expectedWarnings);
}
assertEquals("Expected " + expectedWarnings.length + " warnings but found " + actualWarnings.size() + "\nExpected: "
+ Arrays.asList(expectedWarnings) + "\nActual: " + actualWarnings,
expectedWarnings.length, actualWarnings.size());
} finally {
resetDeprecationLogger(true);
}
}
private List<String> filterJodaDeprecationWarnings(List<String> actualWarnings) {
return actualWarnings.stream()
.filter(m -> m.contains(JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS) == false)
.collect(Collectors.toList());
}
private void assertWarnings(List<String> actualWarnings, String[] expectedWarnings) {
assertNotNull("no warnings, expected: " + Arrays.asList(expectedWarnings), actualWarnings);
final Set<String> actualWarningValues =
actualWarnings.stream().map(DeprecationLogger::extractWarningValueFromWarningHeader).collect(Collectors.toSet());
for (String msg : expectedWarnings) {
assertThat(actualWarningValues, hasItem(DeprecationLogger.escapeAndEncode(msg)));
}
assertEquals("Expected " + expectedWarnings.length + " warnings but found " + actualWarnings.size() + "\nExpected: "
+ Arrays.asList(expectedWarnings) + "\nActual: " + actualWarnings,
expectedWarnings.length, actualWarnings.size());
}
/**
* Reset the deprecation logger by removing the current thread context, and setting a new thread context if {@code setNewThreadContext}
* is set to {@code true} and otherwise clearing the current thread context.

View File

@ -58,7 +58,6 @@ public class ClusterDeprecationChecks {
"Ingest pipelines " + pipelinesWithDeprecatedEcsConfig + " uses the [ecs] option which needs to be removed to work in 8.0");
}
return null;
}
static DeprecationIssue checkTemplatesWithTooManyFields(ClusterState state) {

View File

@ -48,7 +48,8 @@ public class DeprecationChecks {
Collections.unmodifiableList(Arrays.asList(
IndexDeprecationChecks::oldIndicesCheck,
IndexDeprecationChecks::tooManyFieldsCheck,
IndexDeprecationChecks::chainedMultiFieldsCheck
IndexDeprecationChecks::chainedMultiFieldsCheck,
IndexDeprecationChecks::deprecatedDateTimeFormat
));
static List<BiFunction<DatafeedConfig, NamedXContentRegistry, DeprecationIssue>> ML_SETTINGS_CHECKS =

View File

@ -10,6 +10,7 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.joda.JodaDeprecationPatterns;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
@ -21,8 +22,10 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* Index-specific deprecation checks
*/
@ -42,11 +45,13 @@ public class IndexDeprecationChecks {
* @param type the document type
* @param parentMap the mapping to read properties from
* @param predicate the predicate to check against for issues, issue is returned if predicate evaluates to true
* @param fieldFormatter a function that takes a type and mapping field entry and returns a formatted field representation
* @return a list of issues found in fields
*/
@SuppressWarnings("unchecked")
static List<String> findInPropertiesRecursively(String type, Map<String, Object> parentMap,
Function<Map<?,?>, Boolean> predicate) {
Function<Map<?,?>, Boolean> predicate,
BiFunction<String, Map.Entry<?, ?>, String> fieldFormatter) {
List<String> issues = new ArrayList<>();
Map<?, ?> properties = (Map<?, ?>) parentMap.get("properties");
if (properties == null) {
@ -55,7 +60,7 @@ public class IndexDeprecationChecks {
for (Map.Entry<?, ?> entry : properties.entrySet()) {
Map<String, Object> valueMap = (Map<String, Object>) entry.getValue();
if (predicate.apply(valueMap)) {
issues.add("[type: " + type + ", field: " + entry.getKey() + "]");
issues.add("[" + fieldFormatter.apply(type, entry) + "]");
}
Map<?, ?> values = (Map<?, ?>) valueMap.get("fields");
@ -63,21 +68,31 @@ public class IndexDeprecationChecks {
for (Map.Entry<?, ?> multifieldEntry : values.entrySet()) {
Map<String, Object> multifieldValueMap = (Map<String, Object>) multifieldEntry.getValue();
if (predicate.apply(multifieldValueMap)) {
issues.add("[type: " + type + ", field: " + entry.getKey() + ", multifield: " + multifieldEntry.getKey() + "]");
issues.add("[" + fieldFormatter.apply(type, entry) + ", multifield: " + multifieldEntry.getKey() + "]");
}
if (multifieldValueMap.containsKey("properties")) {
issues.addAll(findInPropertiesRecursively(type, multifieldValueMap, predicate));
issues.addAll(findInPropertiesRecursively(type, multifieldValueMap, predicate, fieldFormatter));
}
}
}
if (valueMap.containsKey("properties")) {
issues.addAll(findInPropertiesRecursively(type, valueMap, predicate));
issues.addAll(findInPropertiesRecursively(type, valueMap, predicate, fieldFormatter));
}
}
return issues;
}
private static String formatDateField(String type, Map.Entry<?, ?> entry) {
Map<?,?> value = (Map<?, ?>) entry.getValue();
return "type: " + type + ", field: " + entry.getKey() +", format: "+ value.get("format") +", suggestion: "
+ JodaDeprecationPatterns.formatSuggestion((String)value.get("format"));
}
private static String formatField(String type, Map.Entry<?, ?> entry) {
return "type: " + type + ", field: " + entry.getKey();
}
static DeprecationIssue oldIndicesCheck(IndexMetaData indexMetaData) {
Version createdWith = indexMetaData.getCreationVersion();
if (createdWith.before(Version.V_7_0_0)) {
@ -86,7 +101,7 @@ public class IndexDeprecationChecks {
"https://www.elastic.co/guide/en/elasticsearch/reference/master/" +
"breaking-changes-8.0.html",
"This index was created using version: " + createdWith);
}
}
return null;
}
@ -115,10 +130,38 @@ public class IndexDeprecationChecks {
return null;
}
static DeprecationIssue deprecatedDateTimeFormat(IndexMetaData indexMetaData) {
Version createdWith = indexMetaData.getCreationVersion();
if (createdWith.before(Version.V_7_0_0)) {
List<String> fields = new ArrayList<>();
fieldLevelMappingIssue(indexMetaData, ((mappingMetaData, sourceAsMap) -> fields.addAll(
findInPropertiesRecursively(mappingMetaData.type(), sourceAsMap,
IndexDeprecationChecks::isDateFieldWithDeprecatedPattern,
IndexDeprecationChecks::formatDateField))));
if (fields.size() > 0) {
return new DeprecationIssue(DeprecationIssue.Level.WARNING,
"Date field format uses patterns which has changed meaning in 7.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html#breaking_70_java_time_changes",
"This index has date fields with deprecated formats: " + fields + ". "
+ JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
}
}
return null;
}
private static boolean isDateFieldWithDeprecatedPattern(Map<?, ?> property) {
return "date".equals(property.get("type")) &&
property.containsKey("format") &&
JodaDeprecationPatterns.isDeprecatedPattern((String) property.get("format"));
}
static DeprecationIssue chainedMultiFieldsCheck(IndexMetaData indexMetaData) {
List<String> issues = new ArrayList<>();
fieldLevelMappingIssue(indexMetaData, ((mappingMetaData, sourceAsMap) -> issues.addAll(
findInPropertiesRecursively(mappingMetaData.type(), sourceAsMap, IndexDeprecationChecks::containsChainedMultiFields))));
findInPropertiesRecursively(mappingMetaData.type(), sourceAsMap,
IndexDeprecationChecks::containsChainedMultiFields, IndexDeprecationChecks::formatField))));
if (issues.size() > 0) {
return new DeprecationIssue(DeprecationIssue.Level.WARNING,
"Multi-fields within multi-fields",

View File

@ -10,6 +10,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.joda.JodaDeprecationPatterns;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexSettings;
@ -25,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Collections.singletonList;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.deprecation.DeprecationChecks.INDEX_SETTINGS_CHECKS;
import static org.hamcrest.Matchers.hasItem;
public class IndexDeprecationChecksTests extends ESTestCase {
public void testOldIndicesCheck() {
@ -156,6 +158,195 @@ public class IndexDeprecationChecksTests extends ESTestCase {
"The names of fields that contain chained multi-fields: [[type: _doc, field: invalid-field]]");
assertEquals(singletonList(expected), issues);
}
public void testDefinedPatternsDoNotWarn() throws IOException {
String simpleMapping = "{\n" +
"\"properties\" : {\n" +
" \"date_time_field_Y\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"strictWeekyearWeek\"\n" +
" }\n" +
" }" +
"}";
IndexMetaData simpleIndex = createV6Index(simpleMapping);
DeprecationIssue issue = IndexDeprecationChecks.deprecatedDateTimeFormat(simpleIndex);
assertNull(issue);
}
public void testMigratedPatterns() throws IOException {
String simpleMapping = "{\n" +
"\"properties\" : {\n" +
" \"date_time_field_Y\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"8MM-YYYY\"\n" +
" }\n" +
" }" +
"}";
IndexMetaData simpleIndex = createV6Index(simpleMapping);
DeprecationIssue issue = IndexDeprecationChecks.deprecatedDateTimeFormat(simpleIndex);
assertNull(issue);
}
public void testMultipleWarningsOnCombinedPattern() throws IOException {
String simpleMapping = "{\n" +
"\"properties\" : {\n" +
" \"date_time_field_Y\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"dd-CC||MM-YYYY\"\n" +
" }\n" +
" }" +
"}";
IndexMetaData simpleIndex = createV6Index(simpleMapping);
DeprecationIssue expected = new DeprecationIssue(DeprecationIssue.Level.WARNING,
"Date field format uses patterns which has changed meaning in 7.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html#breaking_70_java_time_changes",
"This index has date fields with deprecated formats: ["+
"[type: _doc, field: date_time_field_Y, format: dd-CC||MM-YYYY, " +
"suggestion: 'C' century of era is no longer supported." +
"; "+
"'Y' year-of-era should be replaced with 'y'. Use 'Y' for week-based-year.]"+
"]. "+ JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
List<DeprecationIssue> issues = DeprecationChecks.filterChecks(INDEX_SETTINGS_CHECKS, c -> c.apply(simpleIndex));
assertThat(issues, hasItem(expected));
}
public void testDuplicateWarningsOnCombinedPattern() throws IOException {
String simpleMapping = "{\n" +
"\"properties\" : {\n" +
" \"date_time_field_Y\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"dd-YYYY||MM-YYYY\"\n" +
" }\n" +
" }" +
"}";
IndexMetaData simpleIndex = createV6Index(simpleMapping);
DeprecationIssue expected = new DeprecationIssue(DeprecationIssue.Level.WARNING,
"Date field format uses patterns which has changed meaning in 7.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html#breaking_70_java_time_changes",
"This index has date fields with deprecated formats: ["+
"[type: _doc, field: date_time_field_Y, format: dd-YYYY||MM-YYYY, " +
"suggestion: 'Y' year-of-era should be replaced with 'y'. Use 'Y' for week-based-year.]"+
"]. "+ JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
List<DeprecationIssue> issues = DeprecationChecks.filterChecks(INDEX_SETTINGS_CHECKS, c -> c.apply(simpleIndex));
assertThat(issues, hasItem(expected));
}
public void testWarningsOnMixCustomAndDefinedPattern() throws IOException {
String simpleMapping = "{\n" +
"\"properties\" : {\n" +
" \"date_time_field_Y\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"strictWeekyearWeek||MM-YYYY\"\n" +
" }\n" +
" }" +
"}";
IndexMetaData simpleIndex = createV6Index(simpleMapping);
DeprecationIssue expected = new DeprecationIssue(DeprecationIssue.Level.WARNING,
"Date field format uses patterns which has changed meaning in 7.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html#breaking_70_java_time_changes",
"This index has date fields with deprecated formats: ["+
"[type: _doc, field: date_time_field_Y, format: strictWeekyearWeek||MM-YYYY, " +
"suggestion: 'Y' year-of-era should be replaced with 'y'. Use 'Y' for week-based-year.]"+
"]. "+ JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
List<DeprecationIssue> issues = DeprecationChecks.filterChecks(INDEX_SETTINGS_CHECKS, c -> c.apply(simpleIndex));
assertThat(issues, hasItem(expected));
}
public void testJodaPatternDeprecations() throws IOException {
String simpleMapping = "{\n" +
"\"properties\" : {\n" +
" \"date_time_field_Y\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"MM-YYYY\"\n" +
" },\n" +
" \"date_time_field_C\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"CC\"\n" +
" },\n" +
" \"date_time_field_x\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"xx-MM\"\n" +
" },\n" +
" \"date_time_field_y\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"yy-MM\"\n" +
" },\n" +
" \"date_time_field_Z\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"HH:mmZ\"\n" +
" },\n" +
" \"date_time_field_z\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"HH:mmz\"\n" +
" }\n" +
" }" +
"}";
IndexMetaData simpleIndex = createV6Index(simpleMapping);
DeprecationIssue expected = new DeprecationIssue(DeprecationIssue.Level.WARNING,
"Date field format uses patterns which has changed meaning in 7.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html#breaking_70_java_time_changes",
"This index has date fields with deprecated formats: ["+
"[type: _doc, field: date_time_field_Y, format: MM-YYYY, " +
"suggestion: 'Y' year-of-era should be replaced with 'y'. Use 'Y' for week-based-year.], "+
"[type: _doc, field: date_time_field_C, format: CC, " +
"suggestion: 'C' century of era is no longer supported.], "+
"[type: _doc, field: date_time_field_x, format: xx-MM, " +
"suggestion: 'x' weak-year should be replaced with 'Y'. Use 'x' for zone-offset.], "+
"[type: _doc, field: date_time_field_y, format: yy-MM, " +
"suggestion: 'y' year should be replaced with 'u'. Use 'y' for year-of-era.], "+
"[type: _doc, field: date_time_field_Z, format: HH:mmZ, " +
"suggestion: 'Z' time zone offset/id fails when parsing 'Z' for Zulu timezone. Consider using 'X'.], "+
"[type: _doc, field: date_time_field_z, format: HH:mmz, " +
"suggestion: 'z' time zone text. Will print 'Z' for Zulu given UTC timezone." +
"]"+
"]. "+ JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
List<DeprecationIssue> issues = DeprecationChecks.filterChecks(INDEX_SETTINGS_CHECKS, c -> c.apply(simpleIndex));
assertThat(issues, hasItem(expected));
}
public void testMultipleJodaPatternDeprecationInOneField() throws IOException {
String simpleMapping = "{\n" +
"\"properties\" : {\n" +
" \"date_time_field\" : {\n" +
" \"type\" : \"date\",\n" +
" \"format\" : \"Y-C-x-y\"\n" +
" }\n" +
" }" +
"}";
IndexMetaData simpleIndex = createV6Index(simpleMapping);
DeprecationIssue expected = new DeprecationIssue(DeprecationIssue.Level.WARNING,
"Date field format uses patterns which has changed meaning in 7.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html#breaking_70_java_time_changes",
"This index has date fields with deprecated formats: ["+
"[type: _doc, field: date_time_field, format: Y-C-x-y, " +
"suggestion: 'Y' year-of-era should be replaced with 'y'. Use 'Y' for week-based-year.; " +
"'y' year should be replaced with 'u'. Use 'y' for year-of-era.; " +
"'C' century of era is no longer supported.; " +
"'x' weak-year should be replaced with 'Y'. Use 'x' for zone-offset." +
"]"+
"]. "+ JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
List<DeprecationIssue> issues = DeprecationChecks.filterChecks(INDEX_SETTINGS_CHECKS, c -> c.apply(simpleIndex));
assertThat(issues, hasItem(expected));
}
public IndexMetaData createV6Index(String simpleMapping) throws IOException {
return IndexMetaData.builder(randomAlphaOfLengthBetween(5, 10))
.settings(settings(
VersionUtils.randomVersionBetween(random(), Version.V_6_0_0,
VersionUtils.getPreviousVersion(Version.V_7_0_0))))
.numberOfShards(randomIntBetween(1, 100))
.numberOfReplicas(randomIntBetween(1, 100))
.putMapping("_doc", simpleMapping)
.build();
}
static void addRandomFields(final int fieldLimit,
XContentBuilder mappingBuilder) throws IOException {