Backports the following commits to 7.x: - Validate non-negative priorities for V2 index templates (#56139)
This commit is contained in:
parent
922a80c3f4
commit
8fa14b333d
|
@ -212,7 +212,8 @@ specified, meaning that the last component template specified has the highest pr
|
||||||
`priority`::
|
`priority`::
|
||||||
(Optional, integer)
|
(Optional, integer)
|
||||||
Priority to determine index template precedence when a new index is created. The index template with
|
Priority to determine index template precedence when a new index is created. The index template with
|
||||||
the highest priority is chosen.
|
the highest priority is chosen. If no priority is specified the template is treated as though it is
|
||||||
|
of priority 0 (lowest priority).
|
||||||
This number is not automatically generated by {es}.
|
This number is not automatically generated by {es}.
|
||||||
|
|
||||||
`version`::
|
`version`::
|
||||||
|
|
|
@ -103,6 +103,9 @@ public class PutIndexTemplateV2Action extends ActionType<AcknowledgedResponse> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (indexTemplate.priority() != null && indexTemplate.priority() < 0) {
|
||||||
|
validationException = addValidationError("index template priority must be >= 0", validationException);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return validationException;
|
return validationException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,13 @@ public class IndexTemplateV2 extends AbstractDiffable<IndexTemplateV2> implement
|
||||||
return priority;
|
return priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long priorityOrZero() {
|
||||||
|
if (priority == null) {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
public Long version() {
|
public Long version() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,7 @@ public class MetadataIndexTemplateService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, List<String>> overlaps = findConflictingV2Templates(currentState, name, template.indexPatterns(), true,
|
Map<String, List<String>> overlaps = findConflictingV2Templates(currentState, name, template.indexPatterns(), true,
|
||||||
template.priority());
|
template.priorityOrZero());
|
||||||
overlaps.remove(name);
|
overlaps.remove(name);
|
||||||
if (overlaps.size() > 0) {
|
if (overlaps.size() > 0) {
|
||||||
String error = String.format(Locale.ROOT, "index template [%s] has index patterns %s matching patterns from " +
|
String error = String.format(Locale.ROOT, "index template [%s] has index patterns %s matching patterns from " +
|
||||||
|
@ -351,7 +351,7 @@ public class MetadataIndexTemplateService {
|
||||||
overlaps.entrySet().stream()
|
overlaps.entrySet().stream()
|
||||||
.map(e -> e.getKey() + " => " + e.getValue())
|
.map(e -> e.getKey() + " => " + e.getValue())
|
||||||
.collect(Collectors.joining(",")),
|
.collect(Collectors.joining(",")),
|
||||||
template.priority());
|
template.priorityOrZero());
|
||||||
throw new IllegalArgumentException(error);
|
throw new IllegalArgumentException(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ public class MetadataIndexTemplateService {
|
||||||
*/
|
*/
|
||||||
public static Map<String, List<String>> findConflictingV2Templates(final ClusterState state, final String candidateName,
|
public static Map<String, List<String>> findConflictingV2Templates(final ClusterState state, final String candidateName,
|
||||||
final List<String> indexPatterns) {
|
final List<String> indexPatterns) {
|
||||||
return findConflictingV2Templates(state, candidateName, indexPatterns, false, null);
|
return findConflictingV2Templates(state, candidateName, indexPatterns, false, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -449,7 +449,7 @@ public class MetadataIndexTemplateService {
|
||||||
* index templates with the same priority).
|
* index templates with the same priority).
|
||||||
*/
|
*/
|
||||||
static Map<String, List<String>> findConflictingV2Templates(final ClusterState state, final String candidateName,
|
static Map<String, List<String>> findConflictingV2Templates(final ClusterState state, final String candidateName,
|
||||||
final List<String> indexPatterns, boolean checkPriority, Long priority) {
|
final List<String> indexPatterns, boolean checkPriority, long priority) {
|
||||||
Automaton v1automaton = Regex.simpleMatchToAutomaton(indexPatterns.toArray(Strings.EMPTY_ARRAY));
|
Automaton v1automaton = Regex.simpleMatchToAutomaton(indexPatterns.toArray(Strings.EMPTY_ARRAY));
|
||||||
Map<String, List<String>> overlappingTemplates = new HashMap<>();
|
Map<String, List<String>> overlappingTemplates = new HashMap<>();
|
||||||
for (Map.Entry<String, IndexTemplateV2> entry : state.metadata().templatesV2().entrySet()) {
|
for (Map.Entry<String, IndexTemplateV2> entry : state.metadata().templatesV2().entrySet()) {
|
||||||
|
@ -457,7 +457,7 @@ public class MetadataIndexTemplateService {
|
||||||
IndexTemplateV2 template = entry.getValue();
|
IndexTemplateV2 template = entry.getValue();
|
||||||
Automaton v2automaton = Regex.simpleMatchToAutomaton(template.indexPatterns().toArray(Strings.EMPTY_ARRAY));
|
Automaton v2automaton = Regex.simpleMatchToAutomaton(template.indexPatterns().toArray(Strings.EMPTY_ARRAY));
|
||||||
if (Operations.isEmpty(Operations.intersection(v1automaton, v2automaton)) == false) {
|
if (Operations.isEmpty(Operations.intersection(v1automaton, v2automaton)) == false) {
|
||||||
if (checkPriority == false || Objects.equals(priority, template.priority())) {
|
if (checkPriority == false || priority == template.priorityOrZero()) {
|
||||||
logger.debug("old template {} and index template {} would overlap: {} <=> {}",
|
logger.debug("old template {} and index template {} would overlap: {} <=> {}",
|
||||||
candidateName, name, indexPatterns, template.indexPatterns());
|
candidateName, name, indexPatterns, template.indexPatterns());
|
||||||
overlappingTemplates.put(name, template.indexPatterns());
|
overlappingTemplates.put(name, template.indexPatterns());
|
||||||
|
@ -716,8 +716,7 @@ public class MetadataIndexTemplateService {
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<IndexTemplateV2> candidates = new ArrayList<>(matchedTemplates.keySet());
|
final List<IndexTemplateV2> candidates = new ArrayList<>(matchedTemplates.keySet());
|
||||||
CollectionUtil.timSort(candidates, Comparator.comparing(IndexTemplateV2::priority,
|
CollectionUtil.timSort(candidates, Comparator.comparing(IndexTemplateV2::priorityOrZero, Comparator.reverseOrder()));
|
||||||
Comparator.nullsLast(Comparator.reverseOrder())));
|
|
||||||
|
|
||||||
assert candidates.size() > 0 : "we should have returned early with no candidates";
|
assert candidates.size() > 0 : "we should have returned early with no candidates";
|
||||||
IndexTemplateV2 winner = candidates.get(0);
|
IndexTemplateV2 winner = candidates.get(0);
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class RestTemplatesAction extends AbstractCatAction {
|
||||||
table.startRow();
|
table.startRow();
|
||||||
table.addCell(name);
|
table.addCell(name);
|
||||||
table.addCell("[" + String.join(", ", template.indexPatterns()) + "]");
|
table.addCell("[" + String.join(", ", template.indexPatterns()) + "]");
|
||||||
table.addCell(template.priority());
|
table.addCell(template.priorityOrZero());
|
||||||
table.addCell(template.version());
|
table.addCell(template.version());
|
||||||
table.addCell("[" + String.join(", ", template.composedOf()) + "]");
|
table.addCell("[" + String.join(", ", template.composedOf()) + "]");
|
||||||
table.endRow();
|
table.endRow();
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
@ -80,4 +81,15 @@ public class PutIndexTemplateV2RequestTests extends AbstractWireSerializingTestC
|
||||||
String error = validationErrors.get(0);
|
String error = validationErrors.get(0);
|
||||||
assertThat(error, is("an index template is required"));
|
assertThat(error, is("an index template is required"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testValidationOfPriority() {
|
||||||
|
PutIndexTemplateV2Action.Request req = new PutIndexTemplateV2Action.Request("test");
|
||||||
|
req.indexTemplate(new IndexTemplateV2(Arrays.asList("foo", "bar"), null, null, -5L, null, null));
|
||||||
|
ActionRequestValidationException validationException = req.validate();
|
||||||
|
assertThat(validationException, is(notNullValue()));
|
||||||
|
List<String> validationErrors = validationException.validationErrors();
|
||||||
|
assertThat(validationErrors.size(), is(1));
|
||||||
|
String error = validationErrors.get(0);
|
||||||
|
assertThat(error, is("index template priority must be >= 0"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,7 +415,7 @@ public class MetadataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||||
"take precedence during new index creation");
|
"take precedence during new index creation");
|
||||||
|
|
||||||
assertNotNull(state.metadata().templatesV2().get("v2-template"));
|
assertNotNull(state.metadata().templatesV2().get("v2-template"));
|
||||||
assertThat(state.metadata().templatesV2().get("v2-template"), equalTo(v2Template));
|
assertTemplatesEqual(state.metadata().templatesV2().get("v2-template"), v2Template);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPutGlobalV2TemplateWhichResolvesIndexHiddenSetting() throws Exception {
|
public void testPutGlobalV2TemplateWhichResolvesIndexHiddenSetting() throws Exception {
|
||||||
|
@ -525,7 +525,7 @@ public class MetadataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||||
"take precedence during new index creation");
|
"take precedence during new index creation");
|
||||||
|
|
||||||
assertNotNull(state.metadata().templatesV2().get("v2-template"));
|
assertNotNull(state.metadata().templatesV2().get("v2-template"));
|
||||||
assertThat(state.metadata().templatesV2().get("v2-template"), equalTo(v2Template));
|
assertTemplatesEqual(state.metadata().templatesV2().get("v2-template"), v2Template);
|
||||||
|
|
||||||
// Now try to update the existing v1-template
|
// Now try to update the existing v1-template
|
||||||
|
|
||||||
|
@ -565,7 +565,7 @@ public class MetadataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||||
"take precedence during new index creation");
|
"take precedence during new index creation");
|
||||||
|
|
||||||
assertNotNull(state.metadata().templatesV2().get("v2-template"));
|
assertNotNull(state.metadata().templatesV2().get("v2-template"));
|
||||||
assertThat(state.metadata().templatesV2().get("v2-template"), equalTo(v2Template));
|
assertTemplatesEqual(state.metadata().templatesV2().get("v2-template"), v2Template);
|
||||||
|
|
||||||
// Now try to update the existing v1-template
|
// Now try to update the existing v1-template
|
||||||
|
|
||||||
|
@ -580,15 +580,29 @@ public class MetadataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPuttingOverlappingV2Template() throws Exception {
|
public void testPuttingOverlappingV2Template() throws Exception {
|
||||||
IndexTemplateV2 template = new IndexTemplateV2(Arrays.asList("egg*", "baz"), null, null, 1L, null, null);
|
{
|
||||||
MetadataIndexTemplateService metadataIndexTemplateService = getMetadataIndexTemplateService();
|
IndexTemplateV2 template = new IndexTemplateV2(Arrays.asList("egg*", "baz"), null, null, 1L, null, null);
|
||||||
ClusterState state = metadataIndexTemplateService.addIndexTemplateV2(ClusterState.EMPTY_STATE, false, "foo", template);
|
MetadataIndexTemplateService metadataIndexTemplateService = getMetadataIndexTemplateService();
|
||||||
IndexTemplateV2 newTemplate = new IndexTemplateV2(Arrays.asList("abc", "baz*"), null, null, 1L, null, null);
|
ClusterState state = metadataIndexTemplateService.addIndexTemplateV2(ClusterState.EMPTY_STATE, false, "foo", template);
|
||||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
IndexTemplateV2 newTemplate = new IndexTemplateV2(Arrays.asList("abc", "baz*"), null, null, 1L, null, null);
|
||||||
() -> metadataIndexTemplateService.addIndexTemplateV2(state, false, "foo2", newTemplate));
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||||
assertThat(e.getMessage(), equalTo("index template [foo2] has index patterns [abc, baz*] matching patterns from existing " +
|
() -> metadataIndexTemplateService.addIndexTemplateV2(state, false, "foo2", newTemplate));
|
||||||
"templates [foo] with patterns (foo => [egg*, baz]) that have the same priority [1], multiple index templates may not " +
|
assertThat(e.getMessage(), equalTo("index template [foo2] has index patterns [abc, baz*] matching patterns from existing " +
|
||||||
"match during index creation, please use a different priority"));
|
"templates [foo] with patterns (foo => [egg*, baz]) that have the same priority [1], multiple index templates may not " +
|
||||||
|
"match during index creation, please use a different priority"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
IndexTemplateV2 template = new IndexTemplateV2(Arrays.asList("egg*", "baz"), null, null, null, null, null);
|
||||||
|
MetadataIndexTemplateService metadataIndexTemplateService = getMetadataIndexTemplateService();
|
||||||
|
ClusterState state = metadataIndexTemplateService.addIndexTemplateV2(ClusterState.EMPTY_STATE, false, "foo", template);
|
||||||
|
IndexTemplateV2 newTemplate = new IndexTemplateV2(Arrays.asList("abc", "baz*"), null, null, 0L, null, null);
|
||||||
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||||
|
() -> metadataIndexTemplateService.addIndexTemplateV2(state, false, "foo2", newTemplate));
|
||||||
|
assertThat(e.getMessage(), equalTo("index template [foo2] has index patterns [abc, baz*] matching patterns from existing " +
|
||||||
|
"templates [foo] with patterns (foo => [egg*, baz]) that have the same priority [0], multiple index templates may not " +
|
||||||
|
"match during index creation, please use a different priority"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFindV2Templates() throws Exception {
|
public void testFindV2Templates() throws Exception {
|
||||||
|
|
Loading…
Reference in New Issue