Skip to content

Commit

Permalink
Deprecation info api for camel case date formats (#83839)
Browse files Browse the repository at this point in the history
using camel case date formats was deprecated in
#59949
but only using deprecation logger.
This commit adds deprecation info checks
  • Loading branch information
pgomulka authored Feb 14, 2022
1 parent 4482fb8 commit 49d8c20
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 8 deletions.
13 changes: 13 additions & 0 deletions docs/changelog/83839.yaml
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ private static Set<Setting<Boolean>> 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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -165,7 +167,7 @@ static List<String> 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"));
}
Expand All @@ -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<String> fields = new ArrayList<>();
Expand All @@ -203,8 +205,8 @@ static DeprecationIssue deprecatedDateTimeFormat(IndexMetadata indexMetadata) {
findInPropertiesRecursively(
mappingMetadata.type(),
sourceAsMap,
IndexDeprecationChecks::isDateFieldWithDeprecatedPattern,
IndexDeprecationChecks::formatDateField,
IndexDeprecationChecks::isDateFieldWithJodaPattern,
IndexDeprecationChecks::changeFormatToJavaTime,
"",
""
)
Expand All @@ -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<String> 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<String> 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<String> 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<String> issues = new ArrayList<>();
fieldLevelMappingIssue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand Down Expand Up @@ -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<DeprecationIssue> 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<DeprecationIssue> 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(
Expand Down

0 comments on commit 49d8c20

Please sign in to comment.