|
10 | 10 | import org.apache.logging.log4j.LogManager;
|
11 | 11 | import org.apache.logging.log4j.Logger;
|
12 | 12 | import org.elasticsearch.cluster.ClusterState;
|
| 13 | +import org.elasticsearch.cluster.metadata.ComponentTemplate; |
| 14 | +import org.elasticsearch.cluster.metadata.IndexTemplateMetadata; |
13 | 15 | import org.elasticsearch.cluster.metadata.MappingMetadata;
|
14 | 16 | import org.elasticsearch.common.Strings;
|
15 | 17 | import org.elasticsearch.common.collect.ImmutableOpenMap;
|
16 | 18 | import org.elasticsearch.common.compress.CompressedXContent;
|
17 | 19 | import org.elasticsearch.common.xcontent.XContentHelper;
|
| 20 | +import org.elasticsearch.common.xcontent.XContentType; |
18 | 21 | import org.elasticsearch.core.TimeValue;
|
| 22 | +import org.elasticsearch.core.Tuple; |
19 | 23 | import org.elasticsearch.index.IndexSettings;
|
20 | 24 | import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
|
| 25 | +import org.elasticsearch.index.mapper.LegacyGeoShapeFieldMapper; |
21 | 26 | import org.elasticsearch.ingest.IngestService;
|
22 | 27 | import org.elasticsearch.ingest.PipelineConfiguration;
|
23 | 28 |
|
24 | 29 | import java.util.ArrayList;
|
| 30 | +import java.util.Collections; |
25 | 31 | import java.util.HashSet;
|
26 | 32 | import java.util.List;
|
27 | 33 | import java.util.Map;
|
28 | 34 | import java.util.Objects;
|
29 | 35 | import java.util.Set;
|
30 | 36 | import java.util.concurrent.atomic.AtomicInteger;
|
31 | 37 | import java.util.stream.Collectors;
|
| 38 | +import java.util.stream.StreamSupport; |
32 | 39 |
|
33 | 40 | import static org.elasticsearch.cluster.routing.allocation.DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING;
|
34 | 41 | import static org.elasticsearch.search.SearchModule.INDICES_MAX_CLAUSE_COUNT_SETTING;
|
@@ -201,4 +208,86 @@ static DeprecationIssue checkClusterRoutingAllocationIncludeRelocationsSetting(f
|
201 | 208 | DeprecationIssue.Level.WARNING
|
202 | 209 | );
|
203 | 210 | }
|
| 211 | + |
| 212 | + @SuppressWarnings("unchecked") |
| 213 | + private static String getDetailsMessageForComponentTemplates(Map<String, ComponentTemplate> componentTemplates) { |
| 214 | + String detailsForComponentTemplates = |
| 215 | + componentTemplates.entrySet().stream().map((templateCursor) -> { |
| 216 | + String templateName = templateCursor.getKey(); |
| 217 | + ComponentTemplate componentTemplate = templateCursor.getValue(); |
| 218 | + CompressedXContent mappings = componentTemplate.template().mappings(); |
| 219 | + if (mappings != null) { |
| 220 | + Tuple<XContentType, Map<String, Object>> tuple = XContentHelper.convertToMap(mappings.uncompressed(), true, |
| 221 | + XContentType.JSON); |
| 222 | + Map<String, Object> mappingAsMap = tuple.v2(); |
| 223 | + List<String> messages = mappingAsMap == null ? Collections.emptyList() : |
| 224 | + IndexDeprecationChecks.findInPropertiesRecursively(LegacyGeoShapeFieldMapper.CONTENT_TYPE, |
| 225 | + mappingAsMap, |
| 226 | + IndexDeprecationChecks::isGeoShapeFieldWithDeprecatedParam, |
| 227 | + IndexDeprecationChecks::formatDeprecatedGeoShapeParamMessage); |
| 228 | + if (messages.isEmpty() == false) { |
| 229 | + String messageForMapping = |
| 230 | + "mappings in component template " + templateName + " contains deprecated geo_shape properties. " + |
| 231 | + messages.stream().collect(Collectors.joining("; ")); |
| 232 | + return messageForMapping; |
| 233 | + } |
| 234 | + } |
| 235 | + return null; |
| 236 | + }).filter(messageForTemplate -> Strings.isEmpty(messageForTemplate) == false).collect(Collectors.joining("; ")); |
| 237 | + return detailsForComponentTemplates; |
| 238 | + } |
| 239 | + |
| 240 | + @SuppressWarnings("unchecked") |
| 241 | + private static String getDetailsMessageForIndexTemplates(ImmutableOpenMap<String, IndexTemplateMetadata> indexTemplates) { |
| 242 | + String detailsForIndexTemplates = |
| 243 | + StreamSupport.stream(indexTemplates.spliterator(), false).map((templateCursor) -> { |
| 244 | + String templateName = templateCursor.key; |
| 245 | + IndexTemplateMetadata indexTemplateMetadata = templateCursor.value; |
| 246 | + String messageForTemplate = |
| 247 | + StreamSupport.stream(indexTemplateMetadata.getMappings().spliterator(), false).map((mappingCursor) -> { |
| 248 | + CompressedXContent mapping = mappingCursor.value; |
| 249 | + Tuple<XContentType, Map<String, Object>> tuple = XContentHelper.convertToMap(mapping.uncompressed(), true, |
| 250 | + XContentType.JSON); |
| 251 | + Map<String, Object> mappingAsMap = (Map<String, Object>) tuple.v2().get("_doc"); |
| 252 | + List<String> messages = mappingAsMap == null ? Collections.emptyList() : |
| 253 | + IndexDeprecationChecks.findInPropertiesRecursively(LegacyGeoShapeFieldMapper.CONTENT_TYPE, |
| 254 | + mappingAsMap, |
| 255 | + IndexDeprecationChecks::isGeoShapeFieldWithDeprecatedParam, |
| 256 | + IndexDeprecationChecks::formatDeprecatedGeoShapeParamMessage); |
| 257 | + return messages; |
| 258 | + }).filter(messages -> messages.isEmpty() == false).map(messages -> { |
| 259 | + String messageForMapping = |
| 260 | + "mappings in index template " + templateName + " contains deprecated geo_shape properties. " + |
| 261 | + messages.stream().collect(Collectors.joining("; ")); |
| 262 | + return messageForMapping; |
| 263 | + }).collect(Collectors.joining("; ")); |
| 264 | + return messageForTemplate; |
| 265 | + }).filter(messageForTemplate -> Strings.isEmpty(messageForTemplate) == false).collect(Collectors.joining("; ")); |
| 266 | + return detailsForIndexTemplates; |
| 267 | + } |
| 268 | + |
| 269 | + @SuppressWarnings("unchecked") |
| 270 | + static DeprecationIssue checkGeoShapeTemplates(final ClusterState clusterState) { |
| 271 | + String detailsForComponentTemplates = getDetailsMessageForComponentTemplates(clusterState.getMetadata().componentTemplates()); |
| 272 | + String detailsForIndexTemplates = getDetailsMessageForIndexTemplates(clusterState.getMetadata().getTemplates()); |
| 273 | + boolean deprecationInComponentTemplates = Strings.isEmpty(detailsForComponentTemplates) == false; |
| 274 | + boolean deprecationInIndexTemplates = Strings.isEmpty(detailsForIndexTemplates) == false; |
| 275 | + String url = "https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html#breaking_80_mappings_changes"; |
| 276 | + if (deprecationInComponentTemplates && deprecationInIndexTemplates) { |
| 277 | + String message = "component templates and index templates contain deprecated geo_shape properties that must be removed"; |
| 278 | + String details = detailsForComponentTemplates + "; " + detailsForIndexTemplates; |
| 279 | + return new DeprecationIssue(DeprecationIssue.Level.CRITICAL, message, url, details, false, |
| 280 | + null); |
| 281 | + } if (deprecationInComponentTemplates == false && deprecationInIndexTemplates) { |
| 282 | + String message = "index templates contain deprecated geo_shape properties that must be removed"; |
| 283 | + return new DeprecationIssue(DeprecationIssue.Level.CRITICAL, message, url, detailsForIndexTemplates, false, |
| 284 | + null); |
| 285 | + } else if (deprecationInIndexTemplates == false && deprecationInComponentTemplates) { |
| 286 | + String message = "component templates contain deprecated geo_shape properties that must be removed"; |
| 287 | + return new DeprecationIssue(DeprecationIssue.Level.CRITICAL, message, url, detailsForComponentTemplates, false, |
| 288 | + null); |
| 289 | + } else { |
| 290 | + return null; |
| 291 | + } |
| 292 | + } |
204 | 293 | }
|
0 commit comments