From 49d8c203f5e25c959747260a720e89de75ed52c5 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gomulka Date: Mon, 14 Feb 2022 15:47:33 +0100 Subject: [PATCH] Deprecation info api for camel case date formats (#83839) using camel case date formats was deprecated in #59949 but only using deprecation logger. This commit adds deprecation info checks --- docs/changelog/83839.yaml | 13 ++++ .../xpack/deprecation/DeprecationChecks.java | 3 +- .../deprecation/IndexDeprecationChecks.java | 70 ++++++++++++++++-- .../IndexDeprecationChecksTests.java | 71 ++++++++++++++++++- 4 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 docs/changelog/83839.yaml diff --git a/docs/changelog/83839.yaml b/docs/changelog/83839.yaml new file mode 100644 index 0000000000000..95bbc2441bcc5 --- /dev/null +++ b/docs/changelog/83839.yaml @@ -0,0 +1,13 @@ +pr: 83839 +summary: Deprecation info api for camel case date formats +area: Infra/Core +type: deprecation +issues: [] +deprecation: + title: Deprecation info api for camel case date formats + area: Mappings + body: |- + The use of camel case patterns on date formats is deprecated + and will be removed in {es} 8.0.0. + The corresponding snake case pattern should be used instead. + diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java index 7ea5fe8dfcde9..a83a7b6b48bd2 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java @@ -253,7 +253,8 @@ private static Set> getAllDeprecatedNodeRolesSettings() { (clusterState, indexMetadata) -> IndexDeprecationChecks.chainedMultiFieldsDynamicTemplateCheck(indexMetadata), (clusterState, indexMetadata) -> IndexDeprecationChecks.boostMappingCheck(indexMetadata), (clusterState, indexMetadata) -> IndexDeprecationChecks.boostDynamicTemplateCheck(indexMetadata), - (clusterState, indexMetadata) -> IndexDeprecationChecks.deprecatedDateTimeFormat(indexMetadata), + (clusterState, indexMetadata) -> IndexDeprecationChecks.deprecatedJodaDateTimeFormat(indexMetadata), + (clusterState, indexMetadata) -> IndexDeprecationChecks.deprecatedCamelCasePattern(indexMetadata), (clusterState, indexMetadata) -> IndexDeprecationChecks.translogRetentionSettingCheck(indexMetadata), (clusterState, indexMetadata) -> IndexDeprecationChecks.fieldNamesDisabledCheck(indexMetadata), (clusterState, indexMetadata) -> IndexDeprecationChecks.checkIndexDataPath(indexMetadata), diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecks.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecks.java index 91d601939d078..7a7ef65ec7d50 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecks.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecks.java @@ -14,6 +14,8 @@ import org.elasticsearch.common.joda.JodaDeprecationPatterns; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.time.DateFormatter; +import org.elasticsearch.common.time.FormatNames; import org.elasticsearch.index.IndexModule; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.IndexingSlowLog; @@ -165,7 +167,7 @@ static List findInDynamicTemplates( return issues; } - private static String formatDateField(String type, Map.Entry entry) { + private static String changeFormatToJavaTime(String type, Map.Entry entry) { Map value = (Map) entry.getValue(); return String.format(Locale.ROOT, "Convert [%s] format %s to java.time.", entry.getKey(), value.get("format")); } @@ -192,7 +194,7 @@ static DeprecationIssue oldIndicesCheck(IndexMetadata indexMetadata) { return null; } - static DeprecationIssue deprecatedDateTimeFormat(IndexMetadata indexMetadata) { + static DeprecationIssue deprecatedJodaDateTimeFormat(IndexMetadata indexMetadata) { Version createdWith = indexMetadata.getCreationVersion(); if (createdWith.before(Version.V_7_0_0)) { List fields = new ArrayList<>(); @@ -203,8 +205,8 @@ static DeprecationIssue deprecatedDateTimeFormat(IndexMetadata indexMetadata) { findInPropertiesRecursively( mappingMetadata.type(), sourceAsMap, - IndexDeprecationChecks::isDateFieldWithDeprecatedPattern, - IndexDeprecationChecks::formatDateField, + IndexDeprecationChecks::isDateFieldWithJodaPattern, + IndexDeprecationChecks::changeFormatToJavaTime, "", "" ) @@ -226,12 +228,70 @@ static DeprecationIssue deprecatedDateTimeFormat(IndexMetadata indexMetadata) { return null; } - private static boolean isDateFieldWithDeprecatedPattern(Map property) { + private static boolean isDateFieldWithJodaPattern(Map property) { return "date".equals(property.get("type")) && property.containsKey("format") && JodaDeprecationPatterns.isDeprecatedPattern((String) property.get("format")); } + static DeprecationIssue deprecatedCamelCasePattern(IndexMetadata indexMetadata) { + List fields = new ArrayList<>(); + fieldLevelMappingIssue( + indexMetadata, + ((mappingMetadata, sourceAsMap) -> fields.addAll( + findInPropertiesRecursively( + mappingMetadata.type(), + sourceAsMap, + IndexDeprecationChecks::isDateFieldWithCamelCasePattern, + IndexDeprecationChecks::changeFormatToSnakeCase, + "", + "" + ) + )) + ); + + if (fields.size() > 0) { + String detailsMessageBeginning = fields.stream().collect(Collectors.joining(" ")); + return new DeprecationIssue( + DeprecationIssue.Level.CRITICAL, + "Date fields use deprecated camel case formats", + "https://ela.st/es-deprecation-7-camel-case-format", + detailsMessageBeginning, + false, + null + ); + } + return null; + } + + private static boolean isDateFieldWithCamelCasePattern(Map property) { + if ("date".equals(property.get("type")) && property.containsKey("format")) { + List patterns = DateFormatter.splitCombinedPatterns((String) property.get("format")); + for (String pattern : patterns) { + FormatNames format = FormatNames.forName(pattern); + return format != null && format.isCamelCase(pattern); + } + } + return false; + } + + private static String changeFormatToSnakeCase(String type, Map.Entry entry) { + Map value = (Map) entry.getValue(); + final String formatFieldValue = (String) value.get("format"); + List patterns = DateFormatter.splitCombinedPatterns(formatFieldValue); + StringBuilder sb = new StringBuilder( + "Convert [" + entry.getKey() + "] format [" + formatFieldValue + "] " + "which contains deprecated camel case to snake case. " + ); + for (String pattern : patterns) { + FormatNames format = FormatNames.forName(pattern); + if (format != null && format.isCamelCase(pattern)) { + sb.append("[" + pattern + "] to [" + format.getSnakeCaseName() + "]. "); + } + } + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); + } + static DeprecationIssue boostMappingCheck(IndexMetadata indexMetadata) { List issues = new ArrayList<>(); fieldLevelMappingIssue( diff --git a/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecksTests.java b/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecksTests.java index 7e5adf491605d..5b8d90c6fe11b 100644 --- a/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecksTests.java +++ b/x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/IndexDeprecationChecksTests.java @@ -347,7 +347,7 @@ public void testDefinedPatternsDoNotWarn() throws IOException { + "}"; IndexMetadata simpleIndex = createV6Index(simpleMapping); - DeprecationIssue issue = IndexDeprecationChecks.deprecatedDateTimeFormat(simpleIndex); + DeprecationIssue issue = IndexDeprecationChecks.deprecatedJodaDateTimeFormat(simpleIndex); assertNull(issue); } @@ -362,7 +362,7 @@ public void testMigratedPatterns() throws IOException { + "}"; IndexMetadata simpleIndex = createV6Index(simpleMapping); - DeprecationIssue issue = IndexDeprecationChecks.deprecatedDateTimeFormat(simpleIndex); + DeprecationIssue issue = IndexDeprecationChecks.deprecatedJodaDateTimeFormat(simpleIndex); assertNull(issue); } @@ -521,6 +521,73 @@ public void testMultipleJodaPatternDeprecationInOneField() throws IOException { assertThat(issues, hasItem(expected)); } + public void testCamelCaseDeprecation() throws IOException { + String simpleMapping = "{\n" + + "\"properties\" : {\n" + + " \"date_time_field\" : {\n" + + " \"type\" : \"date\",\n" + + " \"format\" : \"strictDateOptionalTime\"\n" + + " }\n" + + " }" + + "}"; + + IndexMetadata simpleIndex = IndexMetadata.builder(randomAlphaOfLengthBetween(5, 10)) + .settings(settings(Version.V_7_0_0)) + .numberOfShards(1) + .numberOfReplicas(1) + .putMapping("_doc", simpleMapping) + .build(); + + DeprecationIssue expected = new DeprecationIssue( + DeprecationIssue.Level.CRITICAL, + "Date fields use deprecated camel case formats", + "https://ela.st/es-deprecation-7-camel-case-format", + "Convert [date_time_field] format [strictDateOptionalTime] " + + "which contains deprecated camel case to snake case. [strictDateOptionalTime] to [strict_date_optional_time].", + false, + null + ); + List issues = DeprecationChecks.filterChecks( + INDEX_SETTINGS_CHECKS, + c -> c.apply(ClusterState.EMPTY_STATE, simpleIndex) + ); + assertThat(issues, hasItem(expected)); + } + + public void testCamelCaseDeprecationOnCombined() throws IOException { + String simpleMapping = "{\n" + + "\"properties\" : {\n" + + " \"date_time_field\" : {\n" + + " \"type\" : \"date\",\n" + + " \"format\" : \"strictDateOptionalTime||strictWeekDateTime||epoch_seconds\"\n" + + " }\n" + + " }" + + "}"; + + IndexMetadata simpleIndex = IndexMetadata.builder(randomAlphaOfLengthBetween(5, 10)) + .settings(settings(Version.V_7_0_0)) + .numberOfShards(1) + .numberOfReplicas(1) + .putMapping("_doc", simpleMapping) + .build(); + + DeprecationIssue expected = new DeprecationIssue( + DeprecationIssue.Level.CRITICAL, + "Date fields use deprecated camel case formats", + "https://ela.st/es-deprecation-7-camel-case-format", + "Convert [date_time_field] format [strictDateOptionalTime||strictWeekDateTime||epoch_seconds] " + + "which contains deprecated camel case to snake case. [strictDateOptionalTime] to [strict_date_optional_time]. " + + "[strictWeekDateTime] to [strict_week_date_time].", + false, + null + ); + List issues = DeprecationChecks.filterChecks( + INDEX_SETTINGS_CHECKS, + c -> c.apply(ClusterState.EMPTY_STATE, simpleIndex) + ); + assertThat(issues, hasItem(expected)); + } + public IndexMetadata createV6Index(String simpleMapping) throws IOException { return IndexMetadata.builder(randomAlphaOfLengthBetween(5, 10)) .settings(