Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding deprecation info API message for sparse_vector #77381

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ private static String getDetailsMessageForIndexTemplates(ImmutableOpenMap<String

@SuppressWarnings("unchecked")
static DeprecationIssue checkGeoShapeTemplates(final ClusterState clusterState) {
String detailsForComponentTemplates = getDetailsMessageForComponentTemplates(clusterState.getMetadata().componentTemplates());
String detailsForComponentTemplates =
getDetailsMessageForComponentTemplates(clusterState.getMetadata().componentTemplates());
String detailsForIndexTemplates = getDetailsMessageForIndexTemplates(clusterState.getMetadata().getTemplates());
boolean deprecationInComponentTemplates = Strings.isEmpty(detailsForComponentTemplates) == false;
boolean deprecationInIndexTemplates = Strings.isEmpty(detailsForIndexTemplates) == false;
Expand All @@ -290,4 +291,95 @@ static DeprecationIssue checkGeoShapeTemplates(final ClusterState clusterState)
return null;
}
}

protected static boolean isSparseVector(Map<?, ?> property) {
return "sparse_vector".equals(property.get("type"));
}

protected static String formatDeprecatedSparseVectorMessage(String type, Map.Entry<?, ?> entry) {
return entry.getKey().toString();
}

@SuppressWarnings("unchecked")
private static String getDetailsMessageForSparseVectorComponentTemplates(Map<String, ComponentTemplate> componentTemplates) {
String detailsForComponentTemplates =
componentTemplates.entrySet().stream().map((templateCursor) -> {
String templateName = templateCursor.getKey();
ComponentTemplate componentTemplate = templateCursor.getValue();
CompressedXContent mappings = componentTemplate.template().mappings();
if (mappings != null) {
Tuple<XContentType, Map<String, Object>> tuple = XContentHelper.convertToMap(mappings.uncompressed(), true,
XContentType.JSON);
Map<String, Object> mappingAsMap = tuple.v2();
List<String> messages = mappingAsMap == null ? Collections.emptyList() :
IndexDeprecationChecks.findInPropertiesRecursively(LegacyGeoShapeFieldMapper.CONTENT_TYPE,
mappingAsMap,
ClusterDeprecationChecks::isSparseVector,
ClusterDeprecationChecks::formatDeprecatedSparseVectorMessage);
if (messages.isEmpty() == false) {
String messageForMapping =
"mappings in component template " + templateName + " contains deprecated sparse_vector fields: " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets surround the template name in some kind of quotations or punctuation so that it's easier to see as a resource name instead of just text

messages.stream().collect(Collectors.joining(", "));
return messageForMapping;
}
}
return null;
}).filter(messageForTemplate -> Strings.isEmpty(messageForTemplate) == false).collect(Collectors.joining("; "));
return detailsForComponentTemplates;
}

@SuppressWarnings("unchecked")
private static String getDetailsMessageForSparseVectorIndexTemplates(ImmutableOpenMap<String, IndexTemplateMetadata> indexTemplates) {
String detailsForIndexTemplates =
StreamSupport.stream(indexTemplates.spliterator(), false).map((templateCursor) -> {
String templateName = templateCursor.key;
IndexTemplateMetadata indexTemplateMetadata = templateCursor.value;
String messageForTemplate =
StreamSupport.stream(indexTemplateMetadata.getMappings().spliterator(), false).map((mappingCursor) -> {
CompressedXContent mapping = mappingCursor.value;
Tuple<XContentType, Map<String, Object>> tuple = XContentHelper.convertToMap(mapping.uncompressed(), true,
XContentType.JSON);
Map<String, Object> mappingAsMap = (Map<String, Object>) tuple.v2().get("_doc");
List<String> messages = mappingAsMap == null ? Collections.emptyList() :
IndexDeprecationChecks.findInPropertiesRecursively(LegacyGeoShapeFieldMapper.CONTENT_TYPE,
mappingAsMap,
ClusterDeprecationChecks::isSparseVector,
ClusterDeprecationChecks::formatDeprecatedSparseVectorMessage);
return messages;
}).filter(messages -> messages.isEmpty() == false).map(messages -> {
String messageForMapping =
"mappings in index template " + templateName + " contains deprecated sparse_vector fields: " +
messages.stream().collect(Collectors.joining(", "));
return messageForMapping;
}).collect(Collectors.joining("; "));
return messageForTemplate;
}).filter(messageForTemplate -> Strings.isEmpty(messageForTemplate) == false).collect(Collectors.joining("; "));
return detailsForIndexTemplates;
}

@SuppressWarnings("unchecked")
static DeprecationIssue checkSparseVectorTemplates(final ClusterState clusterState) {
String detailsForComponentTemplates =
getDetailsMessageForSparseVectorComponentTemplates(clusterState.getMetadata().componentTemplates());
String detailsForIndexTemplates = getDetailsMessageForSparseVectorIndexTemplates(clusterState.getMetadata().getTemplates());
boolean deprecationInComponentTemplates = Strings.isEmpty(detailsForComponentTemplates) == false;
boolean deprecationInIndexTemplates = Strings.isEmpty(detailsForIndexTemplates) == false;
String url = "https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html#breaking_80_search_changes";
if (deprecationInComponentTemplates && deprecationInIndexTemplates) {
String message = "component templates and index templates contain deprecated sparse_vector fields that must be removed";
String details = detailsForComponentTemplates + "; " + detailsForIndexTemplates;
return new DeprecationIssue(DeprecationIssue.Level.CRITICAL, message, url, details, false,
null);
} if (deprecationInComponentTemplates == false && deprecationInIndexTemplates) {
String message = "index templates contain deprecated sparse_vector fields that must be removed";
return new DeprecationIssue(DeprecationIssue.Level.CRITICAL, message, url, detailsForIndexTemplates, false,
null);
} else if (deprecationInIndexTemplates == false && deprecationInComponentTemplates) {
String message = "component templates contain deprecated sparse_vector fields that must be removed";
return new DeprecationIssue(DeprecationIssue.Level.CRITICAL, message, url, detailsForComponentTemplates, false,
null);
} else {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ private DeprecationChecks() {
ClusterDeprecationChecks::checkTemplatesWithFieldNamesDisabled,
ClusterDeprecationChecks::checkTemplatesWithMultipleTypes,
ClusterDeprecationChecks::checkClusterRoutingAllocationIncludeRelocationsSetting,
ClusterDeprecationChecks::checkGeoShapeTemplates
ClusterDeprecationChecks::checkGeoShapeTemplates,
ClusterDeprecationChecks::checkSparseVectorTemplates
));

static final List<NodeDeprecationCheck<Settings, PluginsAndModules, ClusterState, XPackLicenseState, DeprecationIssue>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,4 +439,81 @@ public void testCheckGeoShapeMappings() throws Exception {
"[strategy]]", false, null)
));
}

public void testSparseVectorMappings() throws Exception {
// First, testing only an index template:
IndexTemplateMetadata indexTemplateMetadata = IndexTemplateMetadata.builder("single-type")
.patterns(Collections.singletonList("foo"))
.putMapping("_doc", "{\n" +
" \"_doc\":{\n" +
" \"properties\":{\n" +
" \"my_sparse_vector\":{\n" +
" \"type\":\"sparse_vector\"\n" +
" },\n" +
" \"nested_field\":{\n" +
" \"type\":\"nested\",\n" +
" \"properties\":{\n" +
" \"my_nested_sparse_vector\":{\n" +
" \"type\":\"sparse_vector\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}")
.build();
ImmutableOpenMap<String, IndexTemplateMetadata> templates = ImmutableOpenMap.<String, IndexTemplateMetadata>builder()
.fPut("single-type", indexTemplateMetadata)
.build();
Metadata badMetadata = Metadata.builder()
.templates(templates)
.build();
ClusterState badState = ClusterState.builder(new ClusterName("test")).metadata(badMetadata).build();
DeprecationIssue issue = ClusterDeprecationChecks.checkSparseVectorTemplates(badState);

assertThat(issue, equalTo(
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
"index templates contain deprecated sparse_vector fields that must be removed",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html#breaking_80_search_changes",
"mappings in index template single-type contains deprecated sparse_vector fields: [my_sparse_vector], " +
"[my_nested_sparse_vector]", false, null)
));

// Second, testing only a component template:
String templateName = "my-template";
Settings settings = Settings.builder().put("index.number_of_shards", 1).build();
CompressedXContent mappings = new CompressedXContent("{\"properties\":{\"my_sparse_vector\":{\"type\":\"sparse_vector\"}}}");
AliasMetadata alias = AliasMetadata.builder("alias").writeIndex(true).build();
Template template = new Template(settings, mappings, Collections.singletonMap("alias", alias));
ComponentTemplate componentTemplate = new ComponentTemplate(template, 1L, new HashMap<>());
badMetadata = Metadata.builder()
.componentTemplates(Collections.singletonMap(templateName, componentTemplate))
.build();
badState = ClusterState.builder(new ClusterName("test")).metadata(badMetadata).build();
issue = ClusterDeprecationChecks.checkSparseVectorTemplates(badState);

assertThat(issue, equalTo(
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
"component templates contain deprecated sparse_vector fields that must be removed",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html#breaking_80_search_changes",
"mappings in component template my-template contains deprecated sparse_vector fields: [my_sparse_vector]", false, null)
));

// Third, trying a component template and an index template:
badMetadata = Metadata.builder()
.componentTemplates(Collections.singletonMap(templateName, componentTemplate))
.templates(templates)
.build();
badState = ClusterState.builder(new ClusterName("test")).metadata(badMetadata).build();
issue = ClusterDeprecationChecks.checkSparseVectorTemplates(badState);

assertThat(issue, equalTo(
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
"component templates and index templates contain deprecated sparse_vector fields that must be removed",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-8.0.html#breaking_80_search_changes",
"mappings in component template my-template contains deprecated sparse_vector fields: [my_sparse_vector]; " +
"mappings in index template single-type contains deprecated sparse_vector fields: " +
"[my_sparse_vector], [my_nested_sparse_vector]", false, null)
));
}
}