12
12
import org .elasticsearch .cluster .metadata .MappingMetadata ;
13
13
import org .elasticsearch .common .TriFunction ;
14
14
import org .elasticsearch .common .time .DateFormatter ;
15
+ import org .elasticsearch .common .time .DateUtils ;
15
16
import org .elasticsearch .common .time .LegacyFormatNames ;
16
17
import org .elasticsearch .core .Strings ;
17
18
import org .elasticsearch .index .IndexModule ;
@@ -98,6 +99,21 @@ private DeprecationIssue oldIndicesCheck(
98
99
IndexVersion currentCompatibilityVersion = indexMetadata .getCompatibilityVersion ();
99
100
// We intentionally exclude indices that are in data streams because they will be picked up by DataStreamDeprecationChecks
100
101
if (DeprecatedIndexPredicate .reindexRequired (indexMetadata , false , false ) && isNotDataStreamIndex (indexMetadata , clusterState )) {
102
+ List <String > cldrIncompatibleFieldMappings = new ArrayList <>();
103
+ fieldLevelMappingIssue (
104
+ indexMetadata ,
105
+ (mappingMetadata , sourceAsMap ) -> cldrIncompatibleFieldMappings .addAll (
106
+ findInPropertiesRecursively (
107
+ mappingMetadata .type (),
108
+ sourceAsMap ,
109
+ this ::isDateFieldWithCompatFormatPattern ,
110
+ this ::cldrIncompatibleFormatPattern ,
111
+ "" ,
112
+ ""
113
+ )
114
+ )
115
+ );
116
+
101
117
var transforms = transformIdsForIndex (indexMetadata , indexToTransformIds );
102
118
if (transforms .isEmpty () == false ) {
103
119
return new DeprecationIssue (
@@ -115,6 +131,17 @@ private DeprecationIssue oldIndicesCheck(
115
131
false ,
116
132
Map .of ("reindex_required" , true , "transform_ids" , transforms )
117
133
);
134
+ } else if (cldrIncompatibleFieldMappings .isEmpty () == false ) {
135
+ return new DeprecationIssue (
136
+ DeprecationIssue .Level .CRITICAL ,
137
+ "Field mappings with incompatible date format patterns in old index" ,
138
+ "https://www.elastic.co/blog/locale-changes-elasticsearch-8-16-jdk-23" ,
139
+ "The index was created before 8.0 and contains mappings that must be reindexed due to locale changes in 8.16+. "
140
+ + "Manual reindexing is required. "
141
+ + String .join (", " , cldrIncompatibleFieldMappings ),
142
+ false ,
143
+ null
144
+ );
118
145
} else {
119
146
return new DeprecationIssue (
120
147
DeprecationIssue .Level .CRITICAL ,
@@ -393,6 +420,24 @@ private DeprecationIssue deprecatedCamelCasePattern(
393
420
return null ;
394
421
}
395
422
423
+ private boolean isDateFieldWithCompatFormatPattern (Map <?, ?> property ) {
424
+ if ("date" .equals (property .get ("type" )) && property .containsKey ("format" )) {
425
+ String [] patterns = DateFormatter .splitCombinedPatterns ((String ) property .get ("format" ));
426
+ for (String pattern : patterns ) {
427
+ if (DateUtils .containsCompatOnlyDateFormat (pattern )) {
428
+ return true ;
429
+ }
430
+ }
431
+ }
432
+ return false ;
433
+ }
434
+
435
+ private String cldrIncompatibleFormatPattern (String type , Map .Entry <?, ?> entry ) {
436
+ Map <?, ?> value = (Map <?, ?>) entry .getValue ();
437
+ final String formatFieldValue = (String ) value .get ("format" );
438
+ return "Field [" + entry .getKey () + "] with format pattern [" + formatFieldValue + "]." ;
439
+ }
440
+
396
441
private boolean isDateFieldWithCamelCasePattern (Map <?, ?> property ) {
397
442
if ("date" .equals (property .get ("type" )) && property .containsKey ("format" )) {
398
443
String [] patterns = DateFormatter .splitCombinedPatterns ((String ) property .get ("format" ));
0 commit comments