Allows multiple patterns to be specified for index templates (#21009)
* Allows for an array of index template patterns to be provided to an index template, and rename the field from 'template' to 'index_pattern'. Closes #20690
This commit is contained in:
parent
5c4392e58a
commit
0219a211d3
|
@ -20,6 +20,7 @@ package org.elasticsearch.action.admin.indices.template.put;
|
|||
|
||||
import org.elasticsearch.ElasticsearchGenerationException;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.IndicesRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
|
@ -32,6 +33,8 @@ import org.elasticsearch.common.bytes.BytesReference;
|
|||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
|
@ -41,10 +44,13 @@ import org.elasticsearch.common.xcontent.XContentType;
|
|||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
import static org.elasticsearch.common.settings.Settings.readSettingsFromStream;
|
||||
|
@ -56,11 +62,15 @@ import static org.elasticsearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
|
|||
*/
|
||||
public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateRequest> implements IndicesRequest {
|
||||
|
||||
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(PutIndexTemplateRequest.class));
|
||||
|
||||
public static final Version V_5_1_0 = Version.fromId(5010099);
|
||||
|
||||
private String name;
|
||||
|
||||
private String cause = "";
|
||||
|
||||
private String template;
|
||||
private List<String> indexPatterns;
|
||||
|
||||
private int order;
|
||||
|
||||
|
@ -92,8 +102,8 @@ public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateR
|
|||
if (name == null) {
|
||||
validationException = addValidationError("name is missing", validationException);
|
||||
}
|
||||
if (template == null) {
|
||||
validationException = addValidationError("template is missing", validationException);
|
||||
if (indexPatterns == null || indexPatterns.size() == 0) {
|
||||
validationException = addValidationError("pattern is missing", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
@ -113,13 +123,13 @@ public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateR
|
|||
return this.name;
|
||||
}
|
||||
|
||||
public PutIndexTemplateRequest template(String template) {
|
||||
this.template = template;
|
||||
public PutIndexTemplateRequest patterns(List<String> indexPatterns) {
|
||||
this.indexPatterns = indexPatterns;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String template() {
|
||||
return this.template;
|
||||
public List<String> patterns() {
|
||||
return this.indexPatterns;
|
||||
}
|
||||
|
||||
public PutIndexTemplateRequest order(int order) {
|
||||
|
@ -286,7 +296,20 @@ public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateR
|
|||
for (Map.Entry<String, Object> entry : source.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
if (name.equals("template")) {
|
||||
template(entry.getValue().toString());
|
||||
// This is needed to allow for bwc (beats, logstash) with pre-5.0 templates (#21009)
|
||||
if(entry.getValue() instanceof String) {
|
||||
DEPRECATION_LOGGER.deprecated("Deprecated field [template] used, replaced by [index_patterns]");
|
||||
patterns(Collections.singletonList((String) entry.getValue()));
|
||||
}
|
||||
} else if (name.equals("index_patterns")) {
|
||||
if(entry.getValue() instanceof String) {
|
||||
patterns(Collections.singletonList((String) entry.getValue()));
|
||||
} else if (entry.getValue() instanceof List) {
|
||||
List<String> elements = ((List<?>) entry.getValue()).stream().map(Object::toString).collect(Collectors.toList());
|
||||
patterns(elements);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Malformed [template] value, should be a string or a list of strings");
|
||||
}
|
||||
} else if (name.equals("order")) {
|
||||
order(XContentMapValues.nodeIntegerValue(entry.getValue(), order()));
|
||||
} else if ("version".equals(name)) {
|
||||
|
@ -295,7 +318,7 @@ public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateR
|
|||
}
|
||||
version((Integer)entry.getValue());
|
||||
} else if (name.equals("settings")) {
|
||||
if (!(entry.getValue() instanceof Map)) {
|
||||
if ((entry.getValue() instanceof Map) == false) {
|
||||
throw new IllegalArgumentException("Malformed [settings] section, should include an inner object");
|
||||
}
|
||||
settings((Map<String, Object>) entry.getValue());
|
||||
|
@ -436,7 +459,7 @@ public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateR
|
|||
|
||||
@Override
|
||||
public String[] indices() {
|
||||
return new String[]{template};
|
||||
return indexPatterns.toArray(new String[indexPatterns.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -449,7 +472,12 @@ public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateR
|
|||
super.readFrom(in);
|
||||
cause = in.readString();
|
||||
name = in.readString();
|
||||
template = in.readString();
|
||||
|
||||
if (in.getVersion().onOrAfter(V_5_1_0)) {
|
||||
indexPatterns = in.readList(StreamInput::readString);
|
||||
} else {
|
||||
indexPatterns = Collections.singletonList(in.readString());
|
||||
}
|
||||
order = in.readInt();
|
||||
create = in.readBoolean();
|
||||
settings = readSettingsFromStream(in);
|
||||
|
@ -475,7 +503,11 @@ public class PutIndexTemplateRequest extends MasterNodeRequest<PutIndexTemplateR
|
|||
super.writeTo(out);
|
||||
out.writeString(cause);
|
||||
out.writeString(name);
|
||||
out.writeString(template);
|
||||
if (out.getVersion().onOrAfter(V_5_1_0)) {
|
||||
out.writeStringList(indexPatterns);
|
||||
} else {
|
||||
out.writeString(indexPatterns.size() > 0 ? indexPatterns.get(0) : "");
|
||||
}
|
||||
out.writeInt(order);
|
||||
out.writeBoolean(create);
|
||||
writeSettingsToStream(settings, out);
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.elasticsearch.common.bytes.BytesReference;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PutIndexTemplateRequestBuilder
|
||||
|
@ -39,10 +41,20 @@ public class PutIndexTemplateRequestBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the template match expression that will be used to match on indices created.
|
||||
* Sets the match expression that will be used to match on indices created.
|
||||
*
|
||||
* @deprecated Replaced by {@link #setPatterns(List)}
|
||||
*/
|
||||
public PutIndexTemplateRequestBuilder setTemplate(String template) {
|
||||
request.template(template);
|
||||
@Deprecated
|
||||
public PutIndexTemplateRequestBuilder setTemplate(String indexPattern) {
|
||||
return setPatterns(Collections.singletonList(indexPattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the match expression that will be used to match on indices created.
|
||||
*/
|
||||
public PutIndexTemplateRequestBuilder setPatterns(List<String> indexPatterns) {
|
||||
request.patterns(indexPatterns);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public class TransportPutIndexTemplateAction extends TransportMasterNodeAction<P
|
|||
templateSettingsBuilder.put(request.settings()).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX);
|
||||
indexScopedSettings.validate(templateSettingsBuilder);
|
||||
indexTemplateService.putTemplate(new MetaDataIndexTemplateService.PutRequest(cause, request.name())
|
||||
.template(request.template())
|
||||
.patterns(request.patterns())
|
||||
.order(request.order())
|
||||
.settings(templateSettingsBuilder.build())
|
||||
.mappings(request.mappings())
|
||||
|
|
|
@ -395,7 +395,7 @@ public class ClusterState implements ToXContent, Diffable<ClusterState> {
|
|||
IndexTemplateMetaData templateMetaData = cursor.value;
|
||||
builder.startObject(templateMetaData.name());
|
||||
|
||||
builder.field("template", templateMetaData.template());
|
||||
builder.field("index_patterns", templateMetaData.patterns());
|
||||
builder.field("order", templateMetaData.order());
|
||||
|
||||
builder.startObject("settings");
|
||||
|
|
|
@ -29,6 +29,8 @@ import org.elasticsearch.common.collect.MapBuilder;
|
|||
import org.elasticsearch.common.compress.CompressedXContent;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.loader.SettingsLoader;
|
||||
import org.elasticsearch.common.util.set.Sets;
|
||||
|
@ -38,13 +40,19 @@ import org.elasticsearch.common.xcontent.XContentFactory;
|
|||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaData> {
|
||||
|
||||
public static final Version V_5_1_0 = Version.fromId(5010099);
|
||||
|
||||
public static final IndexTemplateMetaData PROTO = IndexTemplateMetaData.builder("").build();
|
||||
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(IndexTemplateMetaData.class));
|
||||
|
||||
private final String name;
|
||||
|
||||
|
@ -56,7 +64,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
* <pre><code>
|
||||
* PUT /_template/my_template
|
||||
* {
|
||||
* "template": "my_index-*",
|
||||
* "index_patterns": ["my_index-*"],
|
||||
* "mappings": { ... },
|
||||
* "version": 1
|
||||
* }
|
||||
|
@ -70,7 +78,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
@Nullable
|
||||
private final Integer version;
|
||||
|
||||
private final String template;
|
||||
private final List<String> patterns;
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
|
@ -82,14 +90,14 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
private final ImmutableOpenMap<String, IndexMetaData.Custom> customs;
|
||||
|
||||
public IndexTemplateMetaData(String name, int order, Integer version,
|
||||
String template, Settings settings,
|
||||
List<String> patterns, Settings settings,
|
||||
ImmutableOpenMap<String, CompressedXContent> mappings,
|
||||
ImmutableOpenMap<String, AliasMetaData> aliases,
|
||||
ImmutableOpenMap<String, IndexMetaData.Custom> customs) {
|
||||
this.name = name;
|
||||
this.order = order;
|
||||
this.version = version;
|
||||
this.template = template;
|
||||
this.patterns= patterns;
|
||||
this.settings = settings;
|
||||
this.mappings = mappings;
|
||||
this.aliases = aliases;
|
||||
|
@ -122,12 +130,12 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
return this.name;
|
||||
}
|
||||
|
||||
public String template() {
|
||||
return this.template;
|
||||
public List<String> patterns() {
|
||||
return this.patterns;
|
||||
}
|
||||
|
||||
public String getTemplate() {
|
||||
return this.template;
|
||||
public List<String> getPatterns() {
|
||||
return this.patterns;
|
||||
}
|
||||
|
||||
public Settings settings() {
|
||||
|
@ -182,7 +190,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
if (!mappings.equals(that.mappings)) return false;
|
||||
if (!name.equals(that.name)) return false;
|
||||
if (!settings.equals(that.settings)) return false;
|
||||
if (!template.equals(that.template)) return false;
|
||||
if (!patterns.equals(that.patterns)) return false;
|
||||
|
||||
return Objects.equals(version, that.version);
|
||||
}
|
||||
|
@ -192,7 +200,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
int result = name.hashCode();
|
||||
result = 31 * result + order;
|
||||
result = 31 * result + Objects.hashCode(version);
|
||||
result = 31 * result + template.hashCode();
|
||||
result = 31 * result + patterns.hashCode();
|
||||
result = 31 * result + settings.hashCode();
|
||||
result = 31 * result + mappings.hashCode();
|
||||
return result;
|
||||
|
@ -202,7 +210,11 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
public IndexTemplateMetaData readFrom(StreamInput in) throws IOException {
|
||||
Builder builder = new Builder(in.readString());
|
||||
builder.order(in.readInt());
|
||||
builder.template(in.readString());
|
||||
if (in.getVersion().onOrAfter(V_5_1_0)) {
|
||||
builder.patterns(in.readList(StreamInput::readString));
|
||||
} else {
|
||||
builder.patterns(Collections.singletonList(in.readString()));
|
||||
}
|
||||
builder.settings(Settings.readSettingsFromStream(in));
|
||||
int mappingsSize = in.readVInt();
|
||||
for (int i = 0; i < mappingsSize; i++) {
|
||||
|
@ -229,7 +241,11 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeString(name);
|
||||
out.writeInt(order);
|
||||
out.writeString(template);
|
||||
if (out.getVersion().onOrAfter(V_5_1_0)) {
|
||||
out.writeStringList(patterns);
|
||||
} else {
|
||||
out.writeString(patterns.size() > 0 ? patterns.get(0) : "");
|
||||
}
|
||||
Settings.writeSettingsToStream(settings, out);
|
||||
out.writeVInt(mappings.size());
|
||||
for (ObjectObjectCursor<String, CompressedXContent> cursor : mappings) {
|
||||
|
@ -252,7 +268,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
|
||||
public static class Builder {
|
||||
|
||||
private static final Set<String> VALID_FIELDS = Sets.newHashSet("template", "order", "mappings", "settings");
|
||||
private static final Set<String> VALID_FIELDS = Sets.newHashSet("template", "order", "mappings", "settings", "index_patterns");
|
||||
static {
|
||||
VALID_FIELDS.addAll(IndexMetaData.customPrototypes.keySet());
|
||||
}
|
||||
|
@ -263,7 +279,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
|
||||
private Integer version;
|
||||
|
||||
private String template;
|
||||
private List<String> indexPatterns;
|
||||
|
||||
private Settings settings = Settings.Builder.EMPTY_SETTINGS;
|
||||
|
||||
|
@ -284,7 +300,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
this.name = indexTemplateMetaData.name();
|
||||
order(indexTemplateMetaData.order());
|
||||
version(indexTemplateMetaData.version());
|
||||
template(indexTemplateMetaData.template());
|
||||
patterns(indexTemplateMetaData.patterns());
|
||||
settings(indexTemplateMetaData.settings());
|
||||
|
||||
mappings = ImmutableOpenMap.builder(indexTemplateMetaData.mappings());
|
||||
|
@ -302,14 +318,11 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder template(String template) {
|
||||
this.template = template;
|
||||
public Builder patterns(List<String> indexPatterns) {
|
||||
this.indexPatterns = indexPatterns;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String template() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public Builder settings(Settings.Builder settings) {
|
||||
this.settings = settings.build();
|
||||
|
@ -361,7 +374,8 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
}
|
||||
|
||||
public IndexTemplateMetaData build() {
|
||||
return new IndexTemplateMetaData(name, order, version, template, settings, mappings.build(), aliases.build(), customs.build());
|
||||
return new IndexTemplateMetaData(name, order, version, indexPatterns, settings, mappings.build(),
|
||||
aliases.build(), customs.build());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -373,7 +387,7 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
if (indexTemplateMetaData.version() != null) {
|
||||
builder.field("version", indexTemplateMetaData.version());
|
||||
}
|
||||
builder.field("template", indexTemplateMetaData.template());
|
||||
builder.field("index_patterns", indexTemplateMetaData.patterns());
|
||||
|
||||
builder.startObject("settings");
|
||||
indexTemplateMetaData.settings().toXContent(builder, params);
|
||||
|
@ -478,10 +492,18 @@ public class IndexTemplateMetaData extends AbstractDiffable<IndexTemplateMetaDat
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if ("index_patterns".equals(currentFieldName)) {
|
||||
List<String> index_patterns = new ArrayList<>();
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
index_patterns.add(parser.text());
|
||||
}
|
||||
builder.patterns(index_patterns);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
if ("template".equals(currentFieldName)) {
|
||||
builder.template(parser.text());
|
||||
// Prior to 5.1.0, elasticsearch only supported a single index pattern called `template` (#21009)
|
||||
if("template".equals(currentFieldName)) {
|
||||
DEPRECATION_LOGGER.deprecated("Deprecated field [template] used, replaced by [index_patterns]");
|
||||
builder.patterns(Collections.singletonList(parser.text()));
|
||||
} else if ("order".equals(currentFieldName)) {
|
||||
builder.order(parser.intValue());
|
||||
} else if ("version".equals(currentFieldName)) {
|
||||
|
|
|
@ -464,21 +464,24 @@ public class MetaDataCreateIndexService extends AbstractComponent {
|
|||
}
|
||||
|
||||
private List<IndexTemplateMetaData> findTemplates(CreateIndexClusterStateUpdateRequest request, ClusterState state) throws IOException {
|
||||
List<IndexTemplateMetaData> templates = new ArrayList<>();
|
||||
List<IndexTemplateMetaData> templateMetadata = new ArrayList<>();
|
||||
for (ObjectCursor<IndexTemplateMetaData> cursor : state.metaData().templates().values()) {
|
||||
IndexTemplateMetaData template = cursor.value;
|
||||
if (Regex.simpleMatch(template.template(), request.index())) {
|
||||
templates.add(template);
|
||||
IndexTemplateMetaData metadata = cursor.value;
|
||||
for (String template: metadata.patterns()) {
|
||||
if (Regex.simpleMatch(template, request.index())) {
|
||||
templateMetadata.add(metadata);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CollectionUtil.timSort(templates, new Comparator<IndexTemplateMetaData>() {
|
||||
CollectionUtil.timSort(templateMetadata, new Comparator<IndexTemplateMetaData>() {
|
||||
@Override
|
||||
public int compare(IndexTemplateMetaData o1, IndexTemplateMetaData o2) {
|
||||
return o2.order() - o1.order();
|
||||
}
|
||||
});
|
||||
return templates;
|
||||
return templateMetadata;
|
||||
}
|
||||
|
||||
private void validate(CreateIndexClusterStateUpdateRequest request, ClusterState state) {
|
||||
|
|
|
@ -131,7 +131,7 @@ public class MetaDataIndexTemplateService extends AbstractComponent {
|
|||
listener.onFailure(new IllegalArgumentException("index_template must provide a name"));
|
||||
return;
|
||||
}
|
||||
if (request.template == null) {
|
||||
if (request.indexPatterns == null) {
|
||||
listener.onFailure(new IllegalArgumentException("index_template must provide a template"));
|
||||
return;
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ public class MetaDataIndexTemplateService extends AbstractComponent {
|
|||
|
||||
templateBuilder.order(request.order);
|
||||
templateBuilder.version(request.version);
|
||||
templateBuilder.template(request.template);
|
||||
templateBuilder.patterns(request.indexPatterns);
|
||||
templateBuilder.settings(request.settings);
|
||||
|
||||
Map<String, Map<String, Object>> mappingsForValidation = new HashMap<>();
|
||||
|
@ -248,20 +248,22 @@ public class MetaDataIndexTemplateService extends AbstractComponent {
|
|||
if (!request.name.toLowerCase(Locale.ROOT).equals(request.name)) {
|
||||
validationErrors.add("name must be lower cased");
|
||||
}
|
||||
if (request.template.contains(" ")) {
|
||||
validationErrors.add("template must not contain a space");
|
||||
}
|
||||
if (request.template.contains(",")) {
|
||||
validationErrors.add("template must not contain a ','");
|
||||
}
|
||||
if (request.template.contains("#")) {
|
||||
validationErrors.add("template must not contain a '#'");
|
||||
}
|
||||
if (request.template.startsWith("_")) {
|
||||
validationErrors.add("template must not start with '_'");
|
||||
}
|
||||
if (!Strings.validFileNameExcludingAstrix(request.template)) {
|
||||
validationErrors.add("template must not contain the following characters " + Strings.INVALID_FILENAME_CHARS);
|
||||
for(String indexPattern : request.indexPatterns) {
|
||||
if (indexPattern.contains(" ")) {
|
||||
validationErrors.add("template must not contain a space");
|
||||
}
|
||||
if (indexPattern.contains(",")) {
|
||||
validationErrors.add("template must not contain a ','");
|
||||
}
|
||||
if (indexPattern.contains("#")) {
|
||||
validationErrors.add("template must not contain a '#'");
|
||||
}
|
||||
if (indexPattern.startsWith("_")) {
|
||||
validationErrors.add("template must not start with '_'");
|
||||
}
|
||||
if (!Strings.validFileNameExcludingAstrix(indexPattern)) {
|
||||
validationErrors.add("template must not contain the following characters " + Strings.INVALID_FILENAME_CHARS);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -283,8 +285,9 @@ public class MetaDataIndexTemplateService extends AbstractComponent {
|
|||
for (Alias alias : request.aliases) {
|
||||
//we validate the alias only partially, as we don't know yet to which index it'll get applied to
|
||||
aliasValidator.validateAliasStandalone(alias);
|
||||
if (request.template.equals(alias.name())) {
|
||||
throw new IllegalArgumentException("Alias [" + alias.name() + "] cannot be the same as the template pattern [" + request.template + "]");
|
||||
if (request.indexPatterns.contains(alias.name())) {
|
||||
throw new IllegalArgumentException("Alias [" + alias.name() +
|
||||
"] cannot be the same as any pattern in [" + String.join(", ", request.indexPatterns) + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +305,7 @@ public class MetaDataIndexTemplateService extends AbstractComponent {
|
|||
boolean create;
|
||||
int order;
|
||||
Integer version;
|
||||
String template;
|
||||
List<String> indexPatterns;
|
||||
Settings settings = Settings.Builder.EMPTY_SETTINGS;
|
||||
Map<String, String> mappings = new HashMap<>();
|
||||
List<Alias> aliases = new ArrayList<>();
|
||||
|
@ -320,8 +323,8 @@ public class MetaDataIndexTemplateService extends AbstractComponent {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PutRequest template(String template) {
|
||||
this.template = template;
|
||||
public PutRequest patterns(List<String> indexPatterns) {
|
||||
this.indexPatterns = indexPatterns;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.rest.action.admin.indices;
|
|||
|
||||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
|
@ -29,9 +32,13 @@ import org.elasticsearch.rest.RestRequest;
|
|||
import org.elasticsearch.rest.action.AcknowledgedRestListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
public class RestPutIndexTemplateAction extends BaseRestHandler {
|
||||
|
||||
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(RestPutIndexTemplateAction.class));
|
||||
|
||||
@Inject
|
||||
public RestPutIndexTemplateAction(Settings settings, RestController controller) {
|
||||
super(settings);
|
||||
|
@ -42,7 +49,12 @@ public class RestPutIndexTemplateAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
PutIndexTemplateRequest putRequest = new PutIndexTemplateRequest(request.param("name"));
|
||||
putRequest.template(request.param("template", putRequest.template()));
|
||||
if (request.hasParam("template")) {
|
||||
DEPRECATION_LOGGER.deprecated("Deprecated parameter[template] used, replaced by [index_patterns]");
|
||||
putRequest.patterns(Collections.singletonList(request.param("template")));
|
||||
} else {
|
||||
putRequest.patterns(Arrays.asList(request.paramAsStringArray("index_patterns", Strings.EMPTY_ARRAY)));
|
||||
}
|
||||
putRequest.order(request.paramAsInt("order", putRequest.order()));
|
||||
putRequest.masterNodeTimeout(request.paramAsTime("master_timeout", putRequest.masterNodeTimeout()));
|
||||
putRequest.create(request.paramAsBoolean("create", false));
|
||||
|
|
|
@ -70,7 +70,7 @@ public class RestTemplatesAction extends AbstractCatAction {
|
|||
Table table = new Table();
|
||||
table.startHeaders();
|
||||
table.addCell("name", "alias:n;desc:template name");
|
||||
table.addCell("template", "alias:t;desc:template pattern string");
|
||||
table.addCell("index_patterns", "alias:t;desc:template index patterns");
|
||||
table.addCell("order", "alias:o;desc:template application order number");
|
||||
table.addCell("version", "alias:v;desc:version");
|
||||
table.endHeaders();
|
||||
|
@ -85,7 +85,7 @@ public class RestTemplatesAction extends AbstractCatAction {
|
|||
if (patternString == null || Regex.simpleMatch(patternString, indexData.name())) {
|
||||
table.startRow();
|
||||
table.addCell(indexData.name());
|
||||
table.addCell(indexData.getTemplate());
|
||||
table.addCell("[" + String.join(", ", indexData.patterns()) + "]");
|
||||
table.addCell(indexData.getOrder());
|
||||
table.addCell(indexData.getVersion());
|
||||
table.endRow();
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
package org.elasticsearch;
|
||||
|
||||
import org.elasticsearch.action.ShardValidateQueryRequestTests;
|
||||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.query.QueryStringQueryBuilder;
|
||||
|
@ -275,9 +277,11 @@ public class VersionTests extends ESTestCase {
|
|||
assertUnknownVersion(V_20_0_0_UNRELEASED);
|
||||
expectThrows(AssertionError.class, () -> assertUnknownVersion(Version.CURRENT));
|
||||
assertUnknownVersion(AliasFilter.V_5_1_0); // once we released 5.1.0 and it's added to Version.java we need to remove this constant
|
||||
assertUnknownVersion(IndexTemplateMetaData.V_5_1_0);
|
||||
assertUnknownVersion(OsStats.V_5_1_0); // once we released 5.1.0 and it's added to Version.java we need to remove this constant
|
||||
assertUnknownVersion(SimpleQueryStringBuilder.V_5_1_0_UNRELEASED);
|
||||
assertUnknownVersion(PutIndexTemplateRequest.V_5_1_0);
|
||||
assertUnknownVersion(QueryStringQueryBuilder.V_5_1_0_UNRELEASED);
|
||||
assertUnknownVersion(SimpleQueryStringBuilder.V_5_1_0_UNRELEASED);
|
||||
// once we released 5.0.0 and it's added to Version.java we need to remove this constant
|
||||
assertUnknownVersion(Script.V_5_1_0_UNRELEASED);
|
||||
// once we released 5.0.0 and it's added to Version.java we need to remove this constant
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.elasticsearch.indices.InvalidIndexTemplateException;
|
|||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -50,7 +51,7 @@ import static org.hamcrest.CoreMatchers.instanceOf;
|
|||
public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
||||
public void testIndexTemplateInvalidNumberOfShards() {
|
||||
PutRequest request = new PutRequest("test", "test_shards");
|
||||
request.template("test_shards*");
|
||||
request.patterns(Collections.singletonList("test_shards*"));
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, "0");
|
||||
|
@ -69,7 +70,7 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
|
||||
public void testIndexTemplateValidationAccumulatesValidationErrors() {
|
||||
PutRequest request = new PutRequest("test", "putTemplate shards");
|
||||
request.template("_test_shards*");
|
||||
request.patterns(Collections.singletonList("_test_shards*"));
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, "0");
|
||||
|
@ -86,18 +87,18 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
|
||||
public void testIndexTemplateWithAliasNameEqualToTemplatePattern() {
|
||||
PutRequest request = new PutRequest("api", "foobar_template");
|
||||
request.template("foobar");
|
||||
request.patterns(Arrays.asList("foo", "foobar"));
|
||||
request.aliases(Collections.singleton(new Alias("foobar")));
|
||||
|
||||
List<Throwable> errors = putTemplate(request);
|
||||
assertThat(errors.size(), equalTo(1));
|
||||
assertThat(errors.get(0), instanceOf(IllegalArgumentException.class));
|
||||
assertThat(errors.get(0).getMessage(), equalTo("Alias [foobar] cannot be the same as the template pattern [foobar]"));
|
||||
assertThat(errors.get(0).getMessage(), equalTo("Alias [foobar] cannot be the same as any pattern in [foo, foobar]"));
|
||||
}
|
||||
|
||||
public void testIndexTemplateWithValidateEmptyMapping() throws Exception {
|
||||
PutRequest request = new PutRequest("api", "validate_template");
|
||||
request.template("validate_template");
|
||||
request.patterns(Collections.singletonList("validate_template"));
|
||||
request.putMapping("type1", "{}");
|
||||
|
||||
List<Throwable> errors = putTemplateDetail(request);
|
||||
|
@ -108,7 +109,7 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
|
||||
public void testIndexTemplateWithValidateMapping() throws Exception {
|
||||
PutRequest request = new PutRequest("api", "validate_template");
|
||||
request.template("te*");
|
||||
request.patterns(Collections.singletonList("te*"));
|
||||
request.putMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field2").field("type", "string").field("analyzer", "custom_1").endObject()
|
||||
.endObject().endObject().endObject().string());
|
||||
|
@ -121,7 +122,7 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
|
||||
public void testBrokenMapping() throws Exception {
|
||||
PutRequest request = new PutRequest("api", "broken_mapping");
|
||||
request.template("te*");
|
||||
request.patterns(Collections.singletonList("te*"));
|
||||
request.putMapping("type1", "abcde");
|
||||
|
||||
List<Throwable> errors = putTemplateDetail(request);
|
||||
|
@ -132,7 +133,7 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
|
||||
public void testBlankMapping() throws Exception {
|
||||
PutRequest request = new PutRequest("api", "blank_mapping");
|
||||
request.template("te*");
|
||||
request.patterns(Collections.singletonList("te*"));
|
||||
request.putMapping("type1", "{}");
|
||||
|
||||
List<Throwable> errors = putTemplateDetail(request);
|
||||
|
@ -144,7 +145,7 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
public void testAliasInvalidFilterInvalidJson() throws Exception {
|
||||
//invalid json: put index template fails
|
||||
PutRequest request = new PutRequest("api", "blank_mapping");
|
||||
request.template("te*");
|
||||
request.patterns(Collections.singletonList("te*"));
|
||||
request.putMapping("type1", "{}");
|
||||
Set<Alias> aliases = new HashSet<>();
|
||||
aliases.add(new Alias("invalid_alias").filter("abcde"));
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.action.admin.indices.template.put;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
|
||||
public class PutIndexTemplateRequestTests extends ESTestCase {
|
||||
|
||||
// bwc for #21009
|
||||
public void testPutIndexTemplateRequest510() throws IOException {
|
||||
PutIndexTemplateRequest putRequest = new PutIndexTemplateRequest("test");
|
||||
putRequest.patterns(Collections.singletonList("test*"));
|
||||
putRequest.order(5);
|
||||
|
||||
PutIndexTemplateRequest multiPatternRequest = new PutIndexTemplateRequest("test");
|
||||
multiPatternRequest.patterns(Arrays.asList("test*", "*test2", "*test3*"));
|
||||
multiPatternRequest.order(5);
|
||||
|
||||
// These bytes were retrieved by Base64 encoding the result of the above with 5_0_0 code.
|
||||
// Note: Instead of a list for the template, in 5_0_0 the element was provided as a string.
|
||||
String putRequestBytes = "ADwDAAR0ZXN0BXRlc3QqAAAABQAAAAAAAA==";
|
||||
BytesArray bytes = new BytesArray(Base64.getDecoder().decode(putRequestBytes));
|
||||
|
||||
try (StreamInput in = bytes.streamInput()) {
|
||||
in.setVersion(Version.V_5_0_0);
|
||||
PutIndexTemplateRequest readRequest = new PutIndexTemplateRequest();
|
||||
readRequest.readFrom(in);
|
||||
assertEquals(putRequest.patterns(), readRequest.patterns());
|
||||
assertEquals(putRequest.order(), readRequest.order());
|
||||
|
||||
BytesStreamOutput output = new BytesStreamOutput();
|
||||
output.setVersion(Version.V_5_0_0);
|
||||
readRequest.writeTo(output);
|
||||
assertEquals(bytes.toBytesRef(), output.bytes().toBytesRef());
|
||||
|
||||
// test that multi templates are reverse-compatible.
|
||||
// for the bwc case, if multiple patterns, use only the first pattern seen.
|
||||
output.reset();
|
||||
multiPatternRequest.writeTo(output);
|
||||
assertEquals(bytes.toBytesRef(), output.bytes().toBytesRef());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -46,6 +46,7 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.SortedSet;
|
||||
|
@ -224,7 +225,7 @@ public class RestoreBackwardsCompatIT extends AbstractSnapshotIntegTestCase {
|
|||
logger.info("--> check templates");
|
||||
IndexTemplateMetaData template = clusterState.getMetaData().templates().get("template_" + version.toLowerCase(Locale.ROOT));
|
||||
assertThat(template, notNullValue());
|
||||
assertThat(template.template(), equalTo("te*"));
|
||||
assertThat(template.patterns(), equalTo(Collections.singletonList("te*")));
|
||||
assertThat(template.settings().getAsInt(IndexMetaData.SETTING_NUMBER_OF_SHARDS, -1), equalTo(1));
|
||||
assertThat(template.mappings().size(), equalTo(1));
|
||||
assertThat(template.mappings().get("type1").string(), equalTo("{\"type1\":{\"_source\":{\"enabled\":false}}}"));
|
||||
|
|
|
@ -553,7 +553,7 @@ public class ClusterStateDiffIT extends ESIntegTestCase {
|
|||
public IndexTemplateMetaData randomCreate(String name) {
|
||||
IndexTemplateMetaData.Builder builder = IndexTemplateMetaData.builder(name);
|
||||
builder.order(randomInt(1000))
|
||||
.template(randomName("temp"))
|
||||
.patterns(Collections.singletonList(randomName("temp")))
|
||||
.settings(randomSettings(Settings.EMPTY));
|
||||
int aliasCount = randomIntBetween(0, 10);
|
||||
for (int i = 0; i < aliasCount; i++) {
|
||||
|
|
|
@ -40,6 +40,8 @@ import org.elasticsearch.test.ESIntegTestCase;
|
|||
import org.elasticsearch.test.hamcrest.CollectionAssertions;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertIndexTemplateExists;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -92,7 +94,7 @@ public class SimpleClusterStateIT extends ESIntegTestCase {
|
|||
|
||||
public void testIndexTemplates() throws Exception {
|
||||
client().admin().indices().preparePutTemplate("foo_template")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -101,7 +103,7 @@ public class SimpleClusterStateIT extends ESIntegTestCase {
|
|||
.get();
|
||||
|
||||
client().admin().indices().preparePutTemplate("fuu_template")
|
||||
.setTemplate("test*")
|
||||
.setPatterns(Collections.singletonList("test*"))
|
||||
.setOrder(1)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field2").field("type", "text").field("store", "no").endObject()
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.cluster.metadata;
|
||||
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.set.Sets;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.elasticsearch.cluster.metadata;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.cluster.metadata.AliasMetaData.newAliasMetaDataBuilder;
|
||||
|
||||
public class IndexTemplateMetaDataTests extends ESTestCase {
|
||||
|
||||
// bwc for #21009
|
||||
public void testIndexTemplateMetaData510() throws IOException {
|
||||
IndexTemplateMetaData metaData = IndexTemplateMetaData.builder("foo")
|
||||
.patterns(Collections.singletonList("bar"))
|
||||
.order(1)
|
||||
.settings(Settings.builder()
|
||||
.put("setting1", "value1")
|
||||
.put("setting2", "value2"))
|
||||
.putAlias(newAliasMetaDataBuilder("alias-bar1")).build();
|
||||
|
||||
IndexTemplateMetaData multiMetaData = IndexTemplateMetaData.builder("foo")
|
||||
.patterns(Arrays.asList("bar", "foo"))
|
||||
.order(1)
|
||||
.settings(Settings.builder()
|
||||
.put("setting1", "value1")
|
||||
.put("setting2", "value2"))
|
||||
.putAlias(newAliasMetaDataBuilder("alias-bar1")).build();
|
||||
|
||||
// These bytes were retrieved by Base64 encoding the result of the above with 5_0_0 code
|
||||
String templateBytes = "A2ZvbwAAAAEDYmFyAghzZXR0aW5nMQEGdmFsdWUxCHNldHRpbmcyAQZ2YWx1ZTIAAQphbGlhcy1iYXIxAAAAAAA=";
|
||||
BytesArray bytes = new BytesArray(Base64.getDecoder().decode(templateBytes));
|
||||
|
||||
try (StreamInput in = bytes.streamInput()) {
|
||||
in.setVersion(Version.V_5_0_0);
|
||||
IndexTemplateMetaData readMetaData = IndexTemplateMetaData.Builder.readFrom(in);
|
||||
assertEquals(0, in.available());
|
||||
assertEquals(metaData.getName(), readMetaData.getName());
|
||||
assertEquals(metaData.getPatterns(), readMetaData.getPatterns());
|
||||
assertTrue(metaData.aliases().containsKey("alias-bar1"));
|
||||
assertEquals(1, metaData.aliases().size());
|
||||
|
||||
BytesStreamOutput output = new BytesStreamOutput();
|
||||
output.setVersion(Version.V_5_0_0);
|
||||
readMetaData.writeTo(output);
|
||||
assertEquals(bytes.toBytesRef(), output.bytes().toBytesRef());
|
||||
|
||||
// test that multi templates are reverse-compatible.
|
||||
// for the bwc case, if multiple patterns, use only the first pattern seen.
|
||||
output.reset();
|
||||
multiMetaData.writeTo(output);
|
||||
assertEquals(bytes.toBytesRef(), output.bytes().toBytesRef());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.xcontent.XContentType;
|
|||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.cluster.metadata.AliasMetaData.newAliasMetaDataBuilder;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -33,6 +34,7 @@ import static org.hamcrest.Matchers.is;
|
|||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
public class ToAndFromJsonMetaDataTests extends ESTestCase {
|
||||
|
||||
public void testSimpleJsonFromAndTo() throws IOException {
|
||||
MetaData metaData = MetaData.builder()
|
||||
.put(IndexMetaData.builder("test1")
|
||||
|
@ -113,7 +115,7 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
|
|||
.putAlias(newAliasMetaDataBuilder("alias2"))
|
||||
.putAlias(newAliasMetaDataBuilder("alias4").filter(ALIAS_FILTER2)))
|
||||
.put(IndexTemplateMetaData.builder("foo")
|
||||
.template("bar")
|
||||
.patterns(Collections.singletonList("bar"))
|
||||
.order(1)
|
||||
.settings(Settings.builder()
|
||||
.put("setting1", "value1")
|
||||
|
@ -134,7 +136,7 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
|
|||
.putAlias(newAliasMetaDataBuilder("alias2"))
|
||||
.putAlias(newAliasMetaDataBuilder("alias4").filter(ALIAS_FILTER2)))
|
||||
.put(IndexTemplateMetaData.builder("foo")
|
||||
.template("bar")
|
||||
.patterns(Collections.singletonList("bar"))
|
||||
.order(1)
|
||||
.settings(Settings.builder()
|
||||
.put("setting1", "value1")
|
||||
|
@ -292,7 +294,7 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
|
|||
|
||||
// templates
|
||||
assertThat(parsedMetaData.templates().get("foo").name(), is("foo"));
|
||||
assertThat(parsedMetaData.templates().get("foo").template(), is("bar"));
|
||||
assertThat(parsedMetaData.templates().get("foo").patterns(), is(Collections.singletonList("bar")));
|
||||
assertThat(parsedMetaData.templates().get("foo").settings().get("index.setting1"), is("value1"));
|
||||
assertThat(parsedMetaData.templates().get("foo").settings().getByPrefix("index.").get("setting2"), is("value2"));
|
||||
assertThat(parsedMetaData.templates().get("foo").aliases().size(), equalTo(3));
|
||||
|
|
|
@ -53,6 +53,7 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
@ -356,7 +357,7 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase {
|
|||
.setSource(jsonBuilder().startObject().startObject("type2").endObject().endObject())
|
||||
.execute().actionGet();
|
||||
client.admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -383,7 +384,7 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase {
|
|||
|
||||
ClusterState state = client().admin().cluster().prepareState().execute().actionGet().getState();
|
||||
assertThat(state.metaData().index("test").mapping("type2"), notNullValue());
|
||||
assertThat(state.metaData().templates().get("template_1").template(), equalTo("te*"));
|
||||
assertThat(state.metaData().templates().get("template_1").patterns(), equalTo(Collections.singletonList("te*")));
|
||||
assertThat(state.metaData().index("test").getAliases().get("test_alias"), notNullValue());
|
||||
assertThat(state.metaData().index("test").getAliases().get("test_alias").filter(), notNullValue());
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.elasticsearch.indices.TypeMissingException;
|
|||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -129,7 +130,7 @@ public class DynamicMappingIT extends ESIntegTestCase {
|
|||
public void testAutoCreateWithDisabledDynamicMappings() throws Exception {
|
||||
assertAcked(client().admin().indices().preparePutTemplate("my_template")
|
||||
.setCreate(true)
|
||||
.setTemplate("index_*")
|
||||
.setPatterns(Collections.singletonList("index_*"))
|
||||
.addMapping("foo", "field", "type=keyword")
|
||||
.setSettings(Settings.builder().put("index.mapper.dynamic", false).build())
|
||||
.get());
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.test.ESIntegTestCase;
|
|||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
|
@ -35,7 +36,7 @@ public class IndexTemplateBlocksIT extends ESIntegTestCase {
|
|||
public void testIndexTemplatesWithBlocks() throws IOException {
|
||||
// creates a simple index template
|
||||
client().admin().indices().preparePutTemplate("template_blocks")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -50,7 +51,7 @@ public class IndexTemplateBlocksIT extends ESIntegTestCase {
|
|||
assertThat(response.getIndexTemplates(), hasSize(1));
|
||||
|
||||
assertBlocked(client().admin().indices().preparePutTemplate("template_blocks_2")
|
||||
.setTemplate("block*")
|
||||
.setPatterns(Collections.singletonList("block*"))
|
||||
.setOrder(0)
|
||||
.addAlias(new Alias("alias_1")));
|
||||
|
||||
|
|
|
@ -41,8 +41,10 @@ import org.elasticsearch.test.ESIntegTestCase;
|
|||
|
||||
import org.junit.After;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -80,7 +82,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setSettings(indexSettings())
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
|
@ -90,7 +92,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
.get();
|
||||
|
||||
client().admin().indices().preparePutTemplate("template_2")
|
||||
.setTemplate("test*")
|
||||
.setPatterns(Collections.singletonList("test*"))
|
||||
.setSettings(indexSettings())
|
||||
.setOrder(1)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
|
@ -100,7 +102,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
// test create param
|
||||
assertThrows(client().admin().indices().preparePutTemplate("template_2")
|
||||
.setTemplate("test*")
|
||||
.setPatterns(Collections.singletonList("test*"))
|
||||
.setSettings(indexSettings())
|
||||
.setCreate(true)
|
||||
.setOrder(1)
|
||||
|
@ -152,7 +154,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
final int existingTemplates = admin().cluster().prepareState().execute().actionGet().getState().metaData().templates().size();
|
||||
logger.info("--> put template_1 and template_2");
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -161,7 +163,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
.execute().actionGet();
|
||||
|
||||
client().admin().indices().preparePutTemplate("template_2")
|
||||
.setTemplate("test*")
|
||||
.setPatterns(Collections.singletonList("test*"))
|
||||
.setOrder(1)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field2").field("type", "text").field("store", "no").endObject()
|
||||
|
@ -180,7 +182,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
logger.info("--> put template_1 back");
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -202,7 +204,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
public void testThatGetIndexTemplatesWorks() throws Exception {
|
||||
logger.info("--> put template_1");
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.setVersion(123)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
|
@ -215,7 +217,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
GetIndexTemplatesResponse getTemplate1Response = client().admin().indices().prepareGetTemplates("template_1").execute().actionGet();
|
||||
assertThat(getTemplate1Response.getIndexTemplates(), hasSize(1));
|
||||
assertThat(getTemplate1Response.getIndexTemplates().get(0), is(notNullValue()));
|
||||
assertThat(getTemplate1Response.getIndexTemplates().get(0).getTemplate(), is("te*"));
|
||||
assertThat(getTemplate1Response.getIndexTemplates().get(0).patterns(), is(Collections.singletonList("te*")));
|
||||
assertThat(getTemplate1Response.getIndexTemplates().get(0).getOrder(), is(0));
|
||||
assertThat(getTemplate1Response.getIndexTemplates().get(0).getVersion(), is(123));
|
||||
|
||||
|
@ -228,7 +230,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
public void testThatGetIndexTemplatesWithSimpleRegexWorks() throws Exception {
|
||||
logger.info("--> put template_1");
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -238,7 +240,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
logger.info("--> put template_2");
|
||||
client().admin().indices().preparePutTemplate("template_2")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -248,7 +250,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
logger.info("--> put template3");
|
||||
client().admin().indices().preparePutTemplate("template3")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(0)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
|
@ -316,7 +318,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
MapperParsingException e = expectThrows( MapperParsingException.class,
|
||||
() -> client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addMapping("type1", "abcde")
|
||||
.get());
|
||||
assertThat(e.getMessage(), containsString("Failed to parse mapping "));
|
||||
|
@ -335,7 +337,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||
() -> client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setSettings(Settings.builder().put("does_not_exist", "test"))
|
||||
.get());
|
||||
assertEquals("unknown setting [index.does_not_exist] please check that any required plugins are" +
|
||||
|
@ -353,7 +355,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
public void testIndexTemplateWithAliases() throws Exception {
|
||||
|
||||
client().admin().indices().preparePutTemplate("template_with_aliases")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addMapping("type1", "{\"type1\" : {\"properties\" : {\"value\" : {\"type\" : \"text\"}}}}")
|
||||
.addAlias(new Alias("simple_alias"))
|
||||
.addAlias(new Alias("templated_alias-{index}"))
|
||||
|
@ -440,7 +442,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
public void testIndexTemplateWithAliasesSource() {
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setAliases(
|
||||
" {\n" +
|
||||
" \"alias1\" : {},\n" +
|
||||
|
@ -478,7 +480,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
public void testDuplicateAlias() throws Exception {
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addAlias(new Alias("my_alias").filter(termQuery("field", "value1")))
|
||||
.addAlias(new Alias("my_alias").filter(termQuery("field", "value2")))
|
||||
.get();
|
||||
|
@ -492,7 +494,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
public void testAliasInvalidFilterValidJson() throws Exception {
|
||||
//invalid filter but valid json: put index template works fine, fails during index creation
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addAlias(new Alias("invalid_alias").filter("{ \"invalid\": {} }")).get();
|
||||
|
||||
GetIndexTemplatesResponse response = client().admin().indices().prepareGetTemplates("template_1").get();
|
||||
|
@ -510,7 +512,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
public void testAliasInvalidFilterInvalidJson() throws Exception {
|
||||
//invalid json: put index template fails
|
||||
PutIndexTemplateRequestBuilder putIndexTemplateRequestBuilder = client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addAlias(new Alias("invalid_alias").filter("abcde"));
|
||||
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||
|
@ -525,7 +527,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
createIndex("index");
|
||||
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addAlias(new Alias("index")).get();
|
||||
|
||||
InvalidAliasNameException e = expectThrows(InvalidAliasNameException.class,
|
||||
|
@ -535,7 +537,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
public void testAliasEmptyName() throws Exception {
|
||||
PutIndexTemplateRequestBuilder putIndexTemplateRequestBuilder = client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addAlias(new Alias(" ").indexRouting("1,2,3"));
|
||||
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||
|
@ -545,7 +547,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
public void testAliasWithMultipleIndexRoutings() throws Exception {
|
||||
PutIndexTemplateRequestBuilder putIndexTemplateRequestBuilder = client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.addAlias(new Alias("alias").indexRouting("1,2,3"));
|
||||
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||
|
@ -555,7 +557,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
|
||||
public void testMultipleAliasesPrecedence() throws Exception {
|
||||
client().admin().indices().preparePutTemplate("template1")
|
||||
.setTemplate("*")
|
||||
.setPatterns(Collections.singletonList("*"))
|
||||
.setOrder(0)
|
||||
.addAlias(new Alias("alias1"))
|
||||
.addAlias(new Alias("{index}-alias"))
|
||||
|
@ -563,7 +565,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
.addAlias(new Alias("alias4")).get();
|
||||
|
||||
client().admin().indices().preparePutTemplate("template2")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setOrder(1)
|
||||
.addAlias(new Alias("alias1").routing("test"))
|
||||
.addAlias(new Alias("alias3")).get();
|
||||
|
@ -593,27 +595,27 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
public void testStrictAliasParsingInIndicesCreatedViaTemplates() throws Exception {
|
||||
// Indexing into a should succeed, because the field mapping for field 'field' is defined in the test mapping.
|
||||
client().admin().indices().preparePutTemplate("template1")
|
||||
.setTemplate("a*")
|
||||
.setPatterns(Collections.singletonList("a*"))
|
||||
.setOrder(0)
|
||||
.addMapping("test", "field", "type=text")
|
||||
.addAlias(new Alias("alias1").filter(termQuery("field", "value"))).get();
|
||||
// Indexing into b should succeed, because the field mapping for field 'field' is defined in the _default_ mapping and
|
||||
// the test type exists.
|
||||
client().admin().indices().preparePutTemplate("template2")
|
||||
.setTemplate("b*")
|
||||
.setPatterns(Collections.singletonList("b*"))
|
||||
.setOrder(0)
|
||||
.addMapping("_default_", "field", "type=text")
|
||||
.addMapping("test")
|
||||
.addAlias(new Alias("alias2").filter(termQuery("field", "value"))).get();
|
||||
// Indexing into c should succeed, because the field mapping for field 'field' is defined in the _default_ mapping.
|
||||
client().admin().indices().preparePutTemplate("template3")
|
||||
.setTemplate("c*")
|
||||
.setPatterns(Collections.singletonList("c*"))
|
||||
.setOrder(0)
|
||||
.addMapping("_default_", "field", "type=text")
|
||||
.addAlias(new Alias("alias3").filter(termQuery("field", "value"))).get();
|
||||
// Indexing into d index should fail, since there is field with name 'field' in the mapping
|
||||
client().admin().indices().preparePutTemplate("template4")
|
||||
.setTemplate("d*")
|
||||
.setPatterns(Collections.singletonList("d*"))
|
||||
.setOrder(0)
|
||||
.addAlias(new Alias("alias4").filter(termQuery("field", "value"))).get();
|
||||
|
||||
|
@ -672,7 +674,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
//Now, a complete mapping with two separated templates is error
|
||||
// base template
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setTemplate("*")
|
||||
.setPatterns(Collections.singletonList("*"))
|
||||
.setSettings(
|
||||
" {\n" +
|
||||
" \"index\" : {\n" +
|
||||
|
@ -690,7 +692,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
// put template using custom_1 analyzer
|
||||
MapperParsingException e = expectThrows(MapperParsingException.class,
|
||||
() -> client().admin().indices().preparePutTemplate("template_2")
|
||||
.setTemplate("test*")
|
||||
.setPatterns(Collections.singletonList("test*"))
|
||||
.setCreate(true)
|
||||
.setOrder(1)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
|
@ -709,7 +711,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
Integer version = randomBoolean() ? randomInt() : null;
|
||||
|
||||
assertAcked(client().admin().indices().preparePutTemplate("versioned_template")
|
||||
.setTemplate("te*")
|
||||
.setPatterns(Collections.singletonList("te*"))
|
||||
.setVersion(version)
|
||||
.setOrder(order)
|
||||
.addMapping("test", "field", "type=text")
|
||||
|
@ -721,4 +723,46 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
|||
assertThat(response.getIndexTemplates().get(0).getOrder(), equalTo(order));
|
||||
}
|
||||
|
||||
public void testMultipleTemplate() throws IOException {
|
||||
client().admin().indices().preparePutTemplate("template_1")
|
||||
.setPatterns(Arrays.asList("a*", "b*"))
|
||||
.setSettings(indexSettings())
|
||||
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
.startObject("field2").field("type", "keyword").field("store", false).endObject()
|
||||
.endObject().endObject().endObject())
|
||||
.get();
|
||||
|
||||
client().prepareIndex("ax", "type1", "1")
|
||||
.setSource("field1", "value1", "field2", "value2")
|
||||
.setRefreshPolicy(IMMEDIATE).get();
|
||||
|
||||
client().prepareIndex("bx", "type1", "1")
|
||||
.setSource("field1", "value1", "field2", "value2")
|
||||
.setRefreshPolicy(IMMEDIATE).get();
|
||||
|
||||
ensureGreen();
|
||||
|
||||
// ax -> matches template
|
||||
SearchResponse searchResponse = client().prepareSearch("ax")
|
||||
.setQuery(termQuery("field1", "value1"))
|
||||
.addStoredField("field1")
|
||||
.addStoredField("field2")
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 1);
|
||||
assertEquals("value1", searchResponse.getHits().getAt(0).field("field1").value().toString());
|
||||
assertNull(searchResponse.getHits().getAt(0).field("field2"));
|
||||
|
||||
// bx -> matches template
|
||||
searchResponse = client().prepareSearch("bx")
|
||||
.setQuery(termQuery("field1", "value1"))
|
||||
.addStoredField("field1")
|
||||
.addStoredField("field2")
|
||||
.execute().actionGet();
|
||||
|
||||
assertHitCount(searchResponse, 1);
|
||||
assertEquals("value1", searchResponse.getHits().getAt(0).field("field1").value().toString());
|
||||
assertNull(searchResponse.getHits().getAt(0).field("field2"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -445,7 +445,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
|
|||
.setType("fs").setSettings(Settings.builder().put("location", randomRepoPath())));
|
||||
|
||||
logger.info("--> creating test template");
|
||||
assertThat(client.admin().indices().preparePutTemplate("test-template").setTemplate("te*").addMapping("test-mapping", XContentFactory.jsonBuilder().startObject().startObject("test-mapping").startObject("properties")
|
||||
assertThat(client.admin().indices().preparePutTemplate("test-template").setPatterns(Collections.singletonList("te*")).addMapping("test-mapping", XContentFactory.jsonBuilder().startObject().startObject("test-mapping").startObject("properties")
|
||||
.startObject("field1").field("type", "string").field("store", "yes").endObject()
|
||||
.startObject("field2").field("type", "string").field("store", "yes").field("index", "not_analyzed").endObject()
|
||||
.endObject().endObject().endObject()).get().isAcknowledged(), equalTo(true));
|
||||
|
@ -486,7 +486,7 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
|
|||
|
||||
if(testTemplate) {
|
||||
logger.info("--> creating test template");
|
||||
assertThat(client.admin().indices().preparePutTemplate("test-template").setTemplate("te*").addMapping("test-mapping", XContentFactory.jsonBuilder().startObject().startObject("test-mapping").startObject("properties")
|
||||
assertThat(client.admin().indices().preparePutTemplate("test-template").setPatterns(Collections.singletonList("te*")).addMapping("test-mapping", XContentFactory.jsonBuilder().startObject().startObject("test-mapping").startObject("properties")
|
||||
.startObject("field1").field("type", "string").field("store", "yes").endObject()
|
||||
.startObject("field2").field("type", "string").field("store", "yes").field("index", "not_analyzed").endObject()
|
||||
.endObject().endObject().endObject()).get().isAcknowledged(), equalTo(true));
|
||||
|
|
|
@ -191,7 +191,7 @@ order by column3.
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
GET _cat/templates?v&s=order:desc,template
|
||||
GET _cat/templates?v&s=order:desc,index_patterns
|
||||
--------------------------------------------------
|
||||
//CONSOLE
|
||||
|
||||
|
@ -199,10 +199,10 @@ returns:
|
|||
|
||||
[source,sh]
|
||||
--------------------------------------------------
|
||||
name template order version
|
||||
pizza_pepperoni *pepperoni* 2
|
||||
sushi_california_roll *avocado* 1 1
|
||||
pizza_hawaiian *pineapples* 1
|
||||
name index_patterns order version
|
||||
pizza_pepperoni [*pepperoni*] 2
|
||||
sushi_california_roll [*avocado*] 1 1
|
||||
pizza_hawaiian [*pineapples*] 1
|
||||
--------------------------------------------------
|
||||
|
||||
--
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
Index templates allow you to define templates that will automatically be
|
||||
applied when new indices are created. The templates include both settings and
|
||||
mappings, and a simple pattern template that controls whether the template
|
||||
should be applied to the new index.
|
||||
mappings, and a list of patterns that control whether the template should be
|
||||
applied to the new index.
|
||||
|
||||
NOTE: Templates are only applied at index creation time. Changing a template
|
||||
will have no impact on existing indices.
|
||||
|
@ -15,7 +15,7 @@ For example:
|
|||
--------------------------------------------------
|
||||
PUT _template/template_1
|
||||
{
|
||||
"template": "te*",
|
||||
"index_patterns": ["te*", "bar*"],
|
||||
"settings": {
|
||||
"number_of_shards": 1
|
||||
},
|
||||
|
@ -53,7 +53,7 @@ It is also possible to include aliases in an index template as follows:
|
|||
--------------------------------------------------
|
||||
PUT _template/template_1
|
||||
{
|
||||
"template" : "te*",
|
||||
"index_patterns" : ["te*"],
|
||||
"settings" : {
|
||||
"number_of_shards" : 1
|
||||
},
|
||||
|
@ -147,7 +147,7 @@ orders overriding them. For example:
|
|||
--------------------------------------------------
|
||||
PUT /_template/template_1
|
||||
{
|
||||
"template" : "*",
|
||||
"index_patterns" : ["*"],
|
||||
"order" : 0,
|
||||
"settings" : {
|
||||
"number_of_shards" : 1
|
||||
|
@ -161,7 +161,7 @@ PUT /_template/template_1
|
|||
|
||||
PUT /_template/template_2
|
||||
{
|
||||
"template" : "te*",
|
||||
"index_patterns" : ["te*"],
|
||||
"order" : 1,
|
||||
"settings" : {
|
||||
"number_of_shards" : 1
|
||||
|
@ -196,7 +196,7 @@ one.
|
|||
--------------------------------------------------
|
||||
PUT /_template/template_1
|
||||
{
|
||||
"template" : "*",
|
||||
"index_patterns" : ["*"],
|
||||
"order" : 0,
|
||||
"settings" : {
|
||||
"number_of_shards" : 1
|
||||
|
|
|
@ -61,7 +61,7 @@ Automatic type creation can also be disabled for all indices by setting an index
|
|||
--------------------------------------------------
|
||||
PUT _template/template_all
|
||||
{
|
||||
"template": "*",
|
||||
"index_patterns": ["*"],
|
||||
"order":0,
|
||||
"settings": {
|
||||
"index.mapper.dynamic": false <1>
|
||||
|
|
|
@ -44,7 +44,7 @@ within automatically created indices:
|
|||
--------------------------------------------------
|
||||
PUT _template/logging
|
||||
{
|
||||
"template": "logs-*", <1>
|
||||
"index_patterns": ["logs-*"], <1>
|
||||
"settings": { "number_of_shards": 1 }, <2>
|
||||
"mappings": {
|
||||
"_default_": {
|
||||
|
|
|
@ -407,7 +407,7 @@ new indices, you could create the following index template:
|
|||
PUT _template/disable_all_field
|
||||
{
|
||||
"order": 0,
|
||||
"template": "*", <1>
|
||||
"index_patterns": ["*"], <1>
|
||||
"mappings": {
|
||||
"_default_": { <2>
|
||||
"_all": { <3>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
- match:
|
||||
$body: |
|
||||
/^ name .+ \n
|
||||
template .+ \n
|
||||
index_patterns .+ \n
|
||||
order .+ \n
|
||||
version .+ \n
|
||||
$/
|
||||
|
@ -39,7 +39,7 @@
|
|||
body:
|
||||
order: 0
|
||||
version: 1
|
||||
template: test-*
|
||||
index_patterns: test-*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -50,7 +50,7 @@
|
|||
body:
|
||||
order: 1
|
||||
version: 2
|
||||
template: test-2*
|
||||
index_patterns: test-2*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -61,7 +61,7 @@
|
|||
- match:
|
||||
$body: /
|
||||
(^|\n)test \s+
|
||||
test-\* \s+
|
||||
\[test-\*\] \s+
|
||||
0 \s+
|
||||
1
|
||||
(\n|$)
|
||||
|
@ -70,7 +70,7 @@
|
|||
- match:
|
||||
$body: /
|
||||
(^|\n)test_2 \s+
|
||||
test-2\* \s+
|
||||
\[test-2\*\] \s+
|
||||
1 \s+
|
||||
2
|
||||
(\n|$)
|
||||
|
@ -87,7 +87,7 @@
|
|||
body:
|
||||
order: 0
|
||||
version: 1
|
||||
template: t*
|
||||
index_patterns: t*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -98,7 +98,7 @@
|
|||
body:
|
||||
order: 2
|
||||
version: 1
|
||||
template: tea*
|
||||
index_patterns: tea*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -111,7 +111,7 @@
|
|||
$body: |
|
||||
/^
|
||||
test \s+
|
||||
t\* \s+
|
||||
\[t\*\] \s+
|
||||
0 \s+
|
||||
1
|
||||
\n
|
||||
|
@ -128,7 +128,7 @@
|
|||
body:
|
||||
order: 0
|
||||
version: 1
|
||||
template: t*
|
||||
index_patterns: t*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -141,14 +141,14 @@
|
|||
- match:
|
||||
$body: |
|
||||
/^
|
||||
name \s+
|
||||
template \s+
|
||||
order \s+
|
||||
name \s+
|
||||
index_patterns \s+
|
||||
order \s+
|
||||
version
|
||||
\n
|
||||
test \s+
|
||||
t\* \s+
|
||||
0 \s+
|
||||
test \s+
|
||||
\[t\*\] \s+
|
||||
0 \s+
|
||||
1
|
||||
\n
|
||||
$/
|
||||
|
@ -164,14 +164,14 @@
|
|||
body:
|
||||
order: 0
|
||||
version: 1
|
||||
template: t*
|
||||
index_patterns: t*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
||||
- do:
|
||||
cat.templates:
|
||||
h: [name, template]
|
||||
h: [name, index_patterns]
|
||||
v: true
|
||||
name: test*
|
||||
|
||||
|
@ -179,10 +179,10 @@
|
|||
$body: |
|
||||
/^
|
||||
name \s+
|
||||
template
|
||||
index_patterns
|
||||
\n
|
||||
test \s+
|
||||
t\*
|
||||
\[t\*\]
|
||||
\n
|
||||
$/
|
||||
|
||||
|
@ -196,7 +196,7 @@
|
|||
name: test
|
||||
body:
|
||||
order: 0
|
||||
template: t*
|
||||
index_patterns: t*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -207,31 +207,62 @@
|
|||
body:
|
||||
order: 0
|
||||
version: 1
|
||||
template: te*
|
||||
index_patterns: te*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
||||
- do:
|
||||
cat.templates:
|
||||
h: [name, template, version]
|
||||
h: [name, index_patterns, version]
|
||||
s: [version]
|
||||
|
||||
- match:
|
||||
$body: |
|
||||
/^
|
||||
test \s+ t\* \s+\n
|
||||
test_1 \s+ te\* \s+ 1\n
|
||||
test \s+ \[t\*\] \s+ \n
|
||||
test_1 \s+ \[te\*\] \s+ 1 \n
|
||||
$/
|
||||
|
||||
- do:
|
||||
cat.templates:
|
||||
h: [name, template, version]
|
||||
h: [name, index_patterns, version]
|
||||
s: ["version:desc"]
|
||||
|
||||
- match:
|
||||
$body: |
|
||||
/^
|
||||
test_1 \s+ te\* \s+ 1\n
|
||||
test \s+ t\* \s+\n
|
||||
test_1 \s+ \[te\*\] \s+ 1\n
|
||||
test \s+ \[t\*\] \s+ \n
|
||||
|
||||
$/
|
||||
|
||||
---
|
||||
"Multiple template":
|
||||
- do:
|
||||
indices.put_template:
|
||||
name: test_1
|
||||
body:
|
||||
order: 0
|
||||
version: 1
|
||||
index_patterns: [t*, te*]
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
||||
- do:
|
||||
cat.templates:
|
||||
h: [name, index_patterns]
|
||||
v: true
|
||||
|
||||
|
||||
- match:
|
||||
$body: |
|
||||
/^
|
||||
name \s+
|
||||
index_patterns
|
||||
\n
|
||||
test_1 \s+
|
||||
\[t\*,\ te\*\]
|
||||
\n
|
||||
$/
|
||||
|
|
|
@ -16,7 +16,7 @@ setup:
|
|||
indices.put_template:
|
||||
name: test
|
||||
body:
|
||||
template: 'test-*'
|
||||
index_patterns: ['test-*']
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
|
|
@ -3,7 +3,7 @@ setup:
|
|||
indices.put_template:
|
||||
name: test
|
||||
body:
|
||||
template: test-*
|
||||
index_patterns: test-*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -15,7 +15,7 @@ setup:
|
|||
indices.get_template:
|
||||
name: test
|
||||
|
||||
- match: {test.template: "test-*"}
|
||||
- match: {test.index_patterns: ["test-*"]}
|
||||
- match: {test.settings: {index: {number_of_shards: '1', number_of_replicas: '0'}}}
|
||||
|
||||
---
|
||||
|
@ -25,15 +25,15 @@ setup:
|
|||
indices.put_template:
|
||||
name: test2
|
||||
body:
|
||||
template: test2-*
|
||||
index_patterns: test2-*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
|
||||
- do:
|
||||
indices.get_template: {}
|
||||
|
||||
- match: {test.template: "test-*"}
|
||||
- match: {test2.template: "test2-*"}
|
||||
- match: {test.index_patterns: ["test-*"]}
|
||||
- match: {test2.index_patterns: ["test2-*"]}
|
||||
|
||||
---
|
||||
"Get template with local flag":
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
indices.put_template:
|
||||
name: test
|
||||
body:
|
||||
template: test-*
|
||||
index_patterns: test-*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -14,7 +14,26 @@
|
|||
name: test
|
||||
flat_settings: true
|
||||
|
||||
- match: {test.template: "test-*"}
|
||||
- match: {test.index_patterns: ["test-*"]}
|
||||
- match: {test.settings: {index.number_of_shards: '1', index.number_of_replicas: '0'}}
|
||||
|
||||
---
|
||||
"Put multiple template":
|
||||
- do:
|
||||
indices.put_template:
|
||||
name: test
|
||||
body:
|
||||
index_patterns: [test-*, test2-*]
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
||||
- do:
|
||||
indices.get_template:
|
||||
name: test
|
||||
flat_settings: true
|
||||
|
||||
- match: {test.index_patterns: ["test-*", "test2-*"]}
|
||||
- match: {test.settings: {index.number_of_shards: '1', index.number_of_replicas: '0'}}
|
||||
|
||||
---
|
||||
|
@ -23,7 +42,7 @@
|
|||
indices.put_template:
|
||||
name: test
|
||||
body:
|
||||
template: test-*
|
||||
index_patterns: test-*
|
||||
aliases:
|
||||
test_alias: {}
|
||||
test_blias: { routing: b }
|
||||
|
@ -33,7 +52,7 @@
|
|||
indices.get_template:
|
||||
name: test
|
||||
|
||||
- match: { test.template: "test-*" }
|
||||
- match: { test.index_patterns: ["test-*"] }
|
||||
- length: { test.aliases: 3 }
|
||||
- is_true: test.aliases.test_alias
|
||||
- match: { test.aliases.test_blias.index_routing: "b" }
|
||||
|
@ -47,7 +66,7 @@
|
|||
name: test
|
||||
create: true
|
||||
body:
|
||||
template: test-*
|
||||
index_patterns: test-*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -57,7 +76,7 @@
|
|||
name: test
|
||||
flat_settings: true
|
||||
|
||||
- match: {test.template: "test-*"}
|
||||
- match: {test.index_patterns: ["test-*"]}
|
||||
- match: {test.settings: {index.number_of_shards: '1', index.number_of_replicas: '0'}}
|
||||
|
||||
- do:
|
||||
|
@ -66,7 +85,7 @@
|
|||
name: test
|
||||
create: true
|
||||
body:
|
||||
template: test-*
|
||||
index_patterns: test-*
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
@ -79,7 +98,7 @@
|
|||
body: >
|
||||
{
|
||||
"version": 10,
|
||||
"template": "*",
|
||||
"index_patterns": "*",
|
||||
"settings": { "number_of_shards": 1 }
|
||||
}
|
||||
- match: { acknowledged: true }
|
||||
|
@ -96,7 +115,7 @@
|
|||
body: >
|
||||
{
|
||||
"version": 9,
|
||||
"template": "*",
|
||||
"index_patterns": "*",
|
||||
"settings": { "number_of_shards": 1 }
|
||||
}
|
||||
- match: { acknowledged: true }
|
||||
|
@ -113,7 +132,7 @@
|
|||
body: >
|
||||
{
|
||||
"version": 6789,
|
||||
"template": "*",
|
||||
"index_patterns": "*",
|
||||
"settings": { "number_of_shards": 1 }
|
||||
}
|
||||
- match: { acknowledged: true }
|
||||
|
@ -129,7 +148,7 @@
|
|||
name: "my_template"
|
||||
body: >
|
||||
{
|
||||
"template": "*",
|
||||
"index_patterns": "*",
|
||||
"settings": { "number_of_shards": 1 }
|
||||
}
|
||||
- match: { acknowledged: true }
|
||||
|
@ -146,7 +165,7 @@
|
|||
body: >
|
||||
{
|
||||
"version": 5385,
|
||||
"template": "*",
|
||||
"index_patterns": "*",
|
||||
"settings": { "number_of_shards": 1 }
|
||||
}
|
||||
- match: { acknowledged: true }
|
||||
|
|
|
@ -408,7 +408,7 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||
}
|
||||
PutIndexTemplateRequestBuilder putTemplate = client().admin().indices()
|
||||
.preparePutTemplate("random_index_template")
|
||||
.setTemplate("*")
|
||||
.setPatterns(Collections.singletonList("*"))
|
||||
.setOrder(0)
|
||||
.setSettings(randomSettingsBuilder);
|
||||
if (mappings != null) {
|
||||
|
|
|
@ -87,7 +87,7 @@ public abstract class ESSingleNodeTestCase extends ESTestCase {
|
|||
assertFalse(clusterHealthResponse.isTimedOut());
|
||||
client().admin().indices()
|
||||
.preparePutTemplate("random_index_template")
|
||||
.setTemplate("*")
|
||||
.setPatterns(Collections.singletonList("*"))
|
||||
.setOrder(0)
|
||||
.setSettings(Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)).get();
|
||||
|
|
Loading…
Reference in New Issue