
org.elasticsearch.cluster.metadata.ComposableIndexTemplate Maven / Gradle / Ivy
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.cluster.metadata;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.AbstractDiffable;
import org.elasticsearch.cluster.Diff;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.index.mapper.DataStreamTimestampFieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.xcontent.ConstructingObjectParser;
import org.elasticsearch.xcontent.ParseField;
import org.elasticsearch.xcontent.ToXContentObject;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static java.util.Collections.singletonMap;
import static org.elasticsearch.cluster.metadata.DataStream.TimestampField.FIXED_TIMESTAMP_FIELD;
/**
* An index template is comprised of a set of index patterns, an optional template, and a list of
* ids corresponding to component templates that should be composed in order when creating a new
* index.
*/
public class ComposableIndexTemplate extends AbstractDiffable implements ToXContentObject {
private static final ParseField INDEX_PATTERNS = new ParseField("index_patterns");
private static final ParseField TEMPLATE = new ParseField("template");
private static final ParseField PRIORITY = new ParseField("priority");
private static final ParseField COMPOSED_OF = new ParseField("composed_of");
private static final ParseField VERSION = new ParseField("version");
private static final ParseField METADATA = new ParseField("_meta");
private static final ParseField DATA_STREAM = new ParseField("data_stream");
private static final ParseField ALLOW_AUTO_CREATE = new ParseField("allow_auto_create");
private static final Version ALLOW_AUTO_CREATE_VERSION = Version.V_7_11_0;
@SuppressWarnings("unchecked")
public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
"index_template",
false,
a -> new ComposableIndexTemplate(
(List) a[0],
(Template) a[1],
(List) a[2],
(Long) a[3],
(Long) a[4],
(Map) a[5],
(DataStreamTemplate) a[6],
(Boolean) a[7]
)
);
static {
PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), INDEX_PATTERNS);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), Template.PARSER, TEMPLATE);
PARSER.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), COMPOSED_OF);
PARSER.declareLong(ConstructingObjectParser.optionalConstructorArg(), PRIORITY);
PARSER.declareLong(ConstructingObjectParser.optionalConstructorArg(), VERSION);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> p.map(), METADATA);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), DataStreamTemplate.PARSER, DATA_STREAM);
PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), ALLOW_AUTO_CREATE);
}
private final List indexPatterns;
@Nullable
private final Template template;
@Nullable
private final List componentTemplates;
@Nullable
private final Long priority;
@Nullable
private final Long version;
@Nullable
private final Map metadata;
@Nullable
private final DataStreamTemplate dataStreamTemplate;
@Nullable
private final Boolean allowAutoCreate;
static Diff readITV2DiffFrom(StreamInput in) throws IOException {
return AbstractDiffable.readDiffFrom(ComposableIndexTemplate::new, in);
}
public static ComposableIndexTemplate parse(XContentParser parser) throws IOException {
return PARSER.parse(parser, null);
}
public ComposableIndexTemplate(
List indexPatterns,
@Nullable Template template,
@Nullable List componentTemplates,
@Nullable Long priority,
@Nullable Long version,
@Nullable Map metadata
) {
this(indexPatterns, template, componentTemplates, priority, version, metadata, null, null);
}
public ComposableIndexTemplate(
List indexPatterns,
@Nullable Template template,
@Nullable List componentTemplates,
@Nullable Long priority,
@Nullable Long version,
@Nullable Map metadata,
@Nullable DataStreamTemplate dataStreamTemplate
) {
this(indexPatterns, template, componentTemplates, priority, version, metadata, dataStreamTemplate, null);
}
public ComposableIndexTemplate(
List indexPatterns,
@Nullable Template template,
@Nullable List componentTemplates,
@Nullable Long priority,
@Nullable Long version,
@Nullable Map metadata,
@Nullable DataStreamTemplate dataStreamTemplate,
@Nullable Boolean allowAutoCreate
) {
this.indexPatterns = indexPatterns;
this.template = template;
this.componentTemplates = componentTemplates;
this.priority = priority;
this.version = version;
this.metadata = metadata;
this.dataStreamTemplate = dataStreamTemplate;
this.allowAutoCreate = allowAutoCreate;
}
public ComposableIndexTemplate(StreamInput in) throws IOException {
this.indexPatterns = in.readStringList();
if (in.readBoolean()) {
this.template = new Template(in);
} else {
this.template = null;
}
this.componentTemplates = in.readOptionalStringList();
this.priority = in.readOptionalVLong();
this.version = in.readOptionalVLong();
this.metadata = in.readMap();
if (in.getVersion().onOrAfter(Version.V_7_9_0)) {
this.dataStreamTemplate = in.readOptionalWriteable(DataStreamTemplate::new);
} else {
this.dataStreamTemplate = null;
}
if (in.getVersion().onOrAfter(ALLOW_AUTO_CREATE_VERSION)) {
this.allowAutoCreate = in.readOptionalBoolean();
} else {
this.allowAutoCreate = null;
}
}
public List indexPatterns() {
return indexPatterns;
}
@Nullable
public Template template() {
return template;
}
public List composedOf() {
if (componentTemplates == null) {
return Collections.emptyList();
}
return componentTemplates;
}
@Nullable
public Long priority() {
return priority;
}
public long priorityOrZero() {
if (priority == null) {
return 0L;
}
return priority;
}
@Nullable
public Long version() {
return version;
}
@Nullable
public Map metadata() {
return metadata;
}
@Nullable
public DataStreamTemplate getDataStreamTemplate() {
return dataStreamTemplate;
}
@Nullable
public Boolean getAllowAutoCreate() {
return this.allowAutoCreate;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeStringCollection(this.indexPatterns);
if (this.template == null) {
out.writeBoolean(false);
} else {
out.writeBoolean(true);
this.template.writeTo(out);
}
out.writeOptionalStringCollection(this.componentTemplates);
out.writeOptionalVLong(this.priority);
out.writeOptionalVLong(this.version);
out.writeMap(this.metadata);
if (out.getVersion().onOrAfter(Version.V_7_9_0)) {
out.writeOptionalWriteable(dataStreamTemplate);
}
if (out.getVersion().onOrAfter(ALLOW_AUTO_CREATE_VERSION)) {
out.writeOptionalBoolean(allowAutoCreate);
}
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.stringListField(INDEX_PATTERNS.getPreferredName(), this.indexPatterns);
if (this.template != null) {
builder.field(TEMPLATE.getPreferredName(), this.template, params);
}
if (this.componentTemplates != null) {
builder.stringListField(COMPOSED_OF.getPreferredName(), this.componentTemplates);
}
if (this.priority != null) {
builder.field(PRIORITY.getPreferredName(), priority);
}
if (this.version != null) {
builder.field(VERSION.getPreferredName(), version);
}
if (this.metadata != null) {
builder.field(METADATA.getPreferredName(), metadata);
}
if (this.dataStreamTemplate != null) {
builder.field(DATA_STREAM.getPreferredName(), dataStreamTemplate, params);
}
if (this.allowAutoCreate != null) {
builder.field(ALLOW_AUTO_CREATE.getPreferredName(), allowAutoCreate);
}
builder.endObject();
return builder;
}
@Override
public int hashCode() {
return Objects.hash(
this.indexPatterns,
this.template,
this.componentTemplates,
this.priority,
this.version,
this.metadata,
this.dataStreamTemplate,
this.allowAutoCreate
);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ComposableIndexTemplate other = (ComposableIndexTemplate) obj;
return Objects.equals(this.indexPatterns, other.indexPatterns)
&& Objects.equals(this.template, other.template)
&& Objects.equals(this.componentTemplates, other.componentTemplates)
&& Objects.equals(this.priority, other.priority)
&& Objects.equals(this.version, other.version)
&& Objects.equals(this.metadata, other.metadata)
&& Objects.equals(this.dataStreamTemplate, other.dataStreamTemplate)
&& Objects.equals(this.allowAutoCreate, other.allowAutoCreate);
}
@Override
public String toString() {
return Strings.toString(this);
}
public static class DataStreamTemplate implements Writeable, ToXContentObject {
private static final ParseField HIDDEN = new ParseField("hidden");
public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
"data_stream_template",
false,
a -> new DataStreamTemplate(a[0] != null && (boolean) a[0])
);
static {
PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), HIDDEN);
}
private final boolean hidden;
public DataStreamTemplate() {
this(false);
}
public DataStreamTemplate(boolean hidden) {
this.hidden = hidden;
}
DataStreamTemplate(StreamInput in) throws IOException {
hidden = in.getVersion().onOrAfter(DataStream.NEW_FEATURES_VERSION) && in.readBoolean();
}
public String getTimestampField() {
return FIXED_TIMESTAMP_FIELD;
}
/**
* @return a mapping snippet for a backing index with `_data_stream_timestamp` meta field mapper properly configured.
*/
public Map getDataStreamMappingSnippet() {
// _data_stream_timestamp meta fields default to @timestamp:
return singletonMap(
MapperService.SINGLE_MAPPING_NAME,
singletonMap(DataStreamTimestampFieldMapper.NAME, singletonMap("enabled", true))
);
}
public boolean isHidden() {
return hidden;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
if (out.getVersion().onOrAfter(DataStream.NEW_FEATURES_VERSION)) {
out.writeBoolean(hidden);
}
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field("hidden", hidden);
builder.endObject();
return builder;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DataStreamTemplate that = (DataStreamTemplate) o;
return hidden == that.hidden;
}
@Override
public int hashCode() {
return Objects.hash(hidden);
}
}
public static class Builder {
private List indexPatterns;
private Template template;
private List componentTemplates;
private Long priority;
private Long version;
private Map metadata;
private DataStreamTemplate dataStreamTemplate;
private Boolean allowAutoCreate;
public Builder() {}
public Builder indexPatterns(List indexPatterns) {
this.indexPatterns = indexPatterns;
return this;
}
public Builder template(Template template) {
this.template = template;
return this;
}
public Builder componentTemplates(List componentTemplates) {
this.componentTemplates = componentTemplates;
return this;
}
public Builder priority(Long priority) {
this.priority = priority;
return this;
}
public Builder version(Long version) {
this.version = version;
return this;
}
public Builder metadata(Map metadata) {
this.metadata = metadata;
return this;
}
public Builder dataStreamTemplate(DataStreamTemplate dataStreamTemplate) {
this.dataStreamTemplate = dataStreamTemplate;
return this;
}
public Builder allowAutoCreate(Boolean allowAutoCreate) {
this.allowAutoCreate = allowAutoCreate;
return this;
}
public ComposableIndexTemplate build() {
return new ComposableIndexTemplate(
this.indexPatterns,
this.template,
this.componentTemplates,
this.priority,
this.version,
this.metadata,
this.dataStreamTemplate,
this.allowAutoCreate
);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy