Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Implement hidden aliases #52547

Merged
merged 21 commits into from
Mar 3, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/reference/indices/aliases.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ include::{docdir}/rest-api/common-parms.asciidoc[tag=index-alias-filter]
+
See <<filtered>> for an example.

`is_hidden`::
(Optional, boolean)
If `true`, the alias will be excluded from wildcard expressions by default,
unless overriden in the request using the `expand_wildcards` parameter,
similar to <<index-hidden,hidden indices>>. This property must be set to the
same value on all indices that share an alias. Defaults to `false`.

`is_write_index`::
(Optional, boolean)
If `true`, assigns the index as an alias's write index.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.elasticsearch.action.admin.indices.alias;

import org.elasticsearch.ElasticsearchGenerationException;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
Expand Down Expand Up @@ -49,6 +50,7 @@ public class Alias implements Writeable, ToXContentFragment {
private static final ParseField INDEX_ROUTING = new ParseField("index_routing", "indexRouting", "index-routing");
private static final ParseField SEARCH_ROUTING = new ParseField("search_routing", "searchRouting", "search-routing");
private static final ParseField IS_WRITE_INDEX = new ParseField("is_write_index");
private static final ParseField IS_HIDDEN = new ParseField("is_hidden");

private String name;

Expand All @@ -64,12 +66,18 @@ public class Alias implements Writeable, ToXContentFragment {
@Nullable
private Boolean writeIndex;

@Nullable
private Boolean isHidden;

public Alias(StreamInput in) throws IOException {
name = in.readString();
filter = in.readOptionalString();
indexRouting = in.readOptionalString();
searchRouting = in.readOptionalString();
writeIndex = in.readOptionalBoolean();
if (in.getVersion().onOrAfter(Version.V_8_0_0)) {
isHidden = in.readOptionalBoolean();
}
}

public Alias(String name) {
Expand Down Expand Up @@ -189,13 +197,31 @@ public Alias writeIndex(@Nullable Boolean writeIndex) {
return this;
}

/**
* @return whether this alias is hidden or not
*/
public Boolean isHidden() {
return isHidden;
}

/**
* Sets whether this alias is hidden
*/
public Alias isHidden(@Nullable Boolean isHidden) {
this.isHidden = isHidden;
return this;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(name);
out.writeOptionalString(filter);
out.writeOptionalString(indexRouting);
out.writeOptionalString(searchRouting);
out.writeOptionalBoolean(writeIndex);
if (out.getVersion().onOrAfter(Version.V_8_0_0)) {
out.writeOptionalBoolean(isHidden);
}
}

/**
Expand Down Expand Up @@ -228,6 +254,8 @@ public static Alias fromXContent(XContentParser parser) throws IOException {
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
if (IS_WRITE_INDEX.match(currentFieldName, parser.getDeprecationHandler())) {
alias.writeIndex(parser.booleanValue());
} else if (IS_HIDDEN.match(currentFieldName, parser.getDeprecationHandler())) {
alias.isHidden(parser.booleanValue());
}
}
}
Expand Down Expand Up @@ -257,6 +285,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws

builder.field(IS_WRITE_INDEX.getPreferredName(), writeIndex);

if (isHidden != null) {
builder.field(IS_HIDDEN.getPreferredName(), isHidden);
}

builder.endObject();
return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.elasticsearch.cluster.metadata;

import org.elasticsearch.ElasticsearchGenerationException;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.AbstractDiffable;
import org.elasticsearch.cluster.Diff;
import org.elasticsearch.common.Nullable;
Expand All @@ -40,6 +41,7 @@
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static java.util.Collections.emptySet;
Expand All @@ -59,7 +61,11 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
@Nullable
private final Boolean writeIndex;

private AliasMetaData(String alias, CompressedXContent filter, String indexRouting, String searchRouting, Boolean writeIndex) {
@Nullable
private final Boolean isHidden;

private AliasMetaData(String alias, CompressedXContent filter, String indexRouting, String searchRouting, Boolean writeIndex,
Boolean isHidden) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Boolean isHidden) {
@Nullable Boolean isHidden) {

this.alias = alias;
this.filter = filter;
this.indexRouting = indexRouting;
Expand All @@ -70,10 +76,12 @@ private AliasMetaData(String alias, CompressedXContent filter, String indexRouti
searchRoutingValues = emptySet();
}
this.writeIndex = writeIndex;
this.isHidden = isHidden;
}

private AliasMetaData(AliasMetaData aliasMetaData, String alias) {
this(alias, aliasMetaData.filter(), aliasMetaData.indexRouting(), aliasMetaData.searchRouting(), aliasMetaData.writeIndex());
this(alias, aliasMetaData.filter(), aliasMetaData.indexRouting(), aliasMetaData.searchRouting(), aliasMetaData.writeIndex(),
aliasMetaData.isHidden);
}

public String alias() {
Expand Down Expand Up @@ -120,6 +128,10 @@ public Boolean writeIndex() {
return writeIndex;
}

public Boolean isHidden() {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public Boolean isHidden() {
@Nullable
public Boolean isHidden() {

return isHidden;
}

public static Builder builder(String alias) {
return new Builder(alias);
}
Expand All @@ -142,11 +154,12 @@ public boolean equals(Object o) {

final AliasMetaData that = (AliasMetaData) o;

if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false;
if (filter != null ? !filter.equals(that.filter) : that.filter != null) return false;
if (indexRouting != null ? !indexRouting.equals(that.indexRouting) : that.indexRouting != null) return false;
if (searchRouting != null ? !searchRouting.equals(that.searchRouting) : that.searchRouting != null) return false;
if (writeIndex != null ? writeIndex != that.writeIndex : that.writeIndex != null) return false;
if (Objects.equals(alias, that.alias) == false) return false;
if (Objects.equals(filter, that.filter) == false) return false;
if (Objects.equals(indexRouting, that.indexRouting) == false) return false;
if (Objects.equals(searchRouting, that.searchRouting) == false) return false;
if (Objects.equals(writeIndex, that.writeIndex) == false) return false;
if (Objects.equals(isHidden, that.isHidden) == false) return false;

return true;
}
Expand Down Expand Up @@ -183,6 +196,10 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeBoolean(false);
}
out.writeOptionalBoolean(writeIndex());

if (out.getVersion().onOrAfter(Version.V_8_0_0)) {
out.writeOptionalBoolean(isHidden);
}
}

public AliasMetaData(StreamInput in) throws IOException {
Expand All @@ -205,6 +222,12 @@ public AliasMetaData(StreamInput in) throws IOException {
searchRoutingValues = emptySet();
}
writeIndex = in.readOptionalBoolean();

if (in.getVersion().onOrAfter(Version.V_8_0_0)) {
isHidden = in.readOptionalBoolean();
} else {
isHidden = null;
}
}

public static Diff<AliasMetaData> readDiffFrom(StreamInput in) throws IOException {
Expand Down Expand Up @@ -235,6 +258,8 @@ public static class Builder {
@Nullable
private Boolean writeIndex;

@Nullable
private Boolean isHidden;

public Builder(String alias) {
this.alias = alias;
Expand Down Expand Up @@ -292,8 +317,13 @@ public Builder writeIndex(@Nullable Boolean writeIndex) {
return this;
}

public Builder isHidden(@Nullable Boolean isHidden) {
this.isHidden = isHidden;
return this;
}

public AliasMetaData build() {
return new AliasMetaData(alias, filter, indexRouting, searchRouting, writeIndex);
return new AliasMetaData(alias, filter, indexRouting, searchRouting, writeIndex, isHidden);
}

public static void toXContent(AliasMetaData aliasMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException {
Expand All @@ -319,6 +349,10 @@ public static void toXContent(AliasMetaData aliasMetaData, XContentBuilder build
builder.field("is_write_index", aliasMetaData.writeIndex());
}

if (aliasMetaData.isHidden != null) {
builder.field("is_hidden", aliasMetaData.isHidden());
}

builder.endObject();
}

Expand Down Expand Up @@ -358,6 +392,8 @@ public static AliasMetaData fromXContent(XContentParser parser) throws IOExcepti
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
if ("is_write_index".equals(currentFieldName)) {
builder.writeIndex(parser.booleanValue());
} else if ("is_hidden".equals(currentFieldName)) {
builder.isHidden(parser.booleanValue());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_HIDDEN_SETTING;

/**
* Encapsulates the {@link IndexMetaData} instances of a concrete index or indices an alias is pointing to.
*/
Expand All @@ -46,6 +50,11 @@ public interface AliasOrIndex {
*/
List<IndexMetaData> getIndices();

/**
* @return whether this alias/index is hidden or not
*/
boolean isHidden();

/**
* Represents an concrete index and encapsulates its {@link IndexMetaData}
*/
Expand All @@ -66,6 +75,11 @@ public boolean isAlias() {
public List<IndexMetaData> getIndices() {
return Collections.singletonList(concreteIndex);
}

@Override
public boolean isHidden() {
return INDEX_HIDDEN_SETTING.get(concreteIndex.getSettings());
}
}

/**
Expand All @@ -76,11 +90,13 @@ class Alias implements AliasOrIndex {
private final String aliasName;
private final List<IndexMetaData> referenceIndexMetaDatas;
private final SetOnce<IndexMetaData> writeIndex = new SetOnce<>();
private final boolean isHidden;

public Alias(AliasMetaData aliasMetaData, IndexMetaData indexMetaData) {
this.aliasName = aliasMetaData.getAlias();
this.referenceIndexMetaDatas = new ArrayList<>();
this.referenceIndexMetaDatas.add(indexMetaData);
this.isHidden = aliasMetaData.isHidden() == null ? false : aliasMetaData.isHidden();
}

@Override
Expand All @@ -103,6 +119,11 @@ public IndexMetaData getWriteIndex() {
return writeIndex.get();
}

@Override
public boolean isHidden() {
return isHidden;
}

/**
* Returns the unique alias metadata per concrete index.
*
Expand Down Expand Up @@ -135,7 +156,8 @@ void addIndex(IndexMetaData indexMetaData) {
this.referenceIndexMetaDatas.add(indexMetaData);
}

public void computeAndValidateWriteIndex() {
public void computeAndValidateAliasProperties() {
// Validate write indices
List<IndexMetaData> writeIndices = referenceIndexMetaDatas.stream()
.filter(idxMeta -> Boolean.TRUE.equals(idxMeta.getAliases().get(aliasName).writeIndex()))
.collect(Collectors.toList());
Expand All @@ -153,6 +175,24 @@ public void computeAndValidateWriteIndex() {
throw new IllegalStateException("alias [" + aliasName + "] has more than one write index [" +
Strings.collectionToCommaDelimitedString(writeIndicesStrings) + "]");
}

// Validate hidden status
final Map<Boolean, List<IndexMetaData>> groupedByHiddenStatus = referenceIndexMetaDatas.stream()
gwbrown marked this conversation as resolved.
Show resolved Hide resolved
.collect(Collectors.groupingBy(idxMeta -> Boolean.TRUE.equals(idxMeta.getAliases().get(aliasName).isHidden())));
if (isNonEmpty(groupedByHiddenStatus.get(true)) && isNonEmpty(groupedByHiddenStatus.get(false))) {
List<String> hiddenOn = groupedByHiddenStatus.get(true).stream()
.map(idx -> idx.getIndex().getName()).collect(Collectors.toList());
List<String> nonHiddenOn = groupedByHiddenStatus.get(false).stream()
.map(idx -> idx.getIndex().getName()).collect(Collectors.toList());
throw new IllegalStateException("alias [" + aliasName + "] has is_hidden set to true on indices [" +
Strings.collectionToCommaDelimitedString(hiddenOn) + "] but does not have is_hidden set to true on indices [" +
Strings.collectionToCommaDelimitedString(nonHiddenOn) + "]; alias must have the same is_hidden setting " +
"on all indices");
}
}

private boolean isNonEmpty(List<IndexMetaData> idxMetas) {
return (Objects.isNull(idxMetas) || idxMetas.isEmpty()) == false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ private Set<String> innerResolve(Context context, List<String> expressions, Indi
// add all the previous ones...
result = new HashSet<>(expressions.subList(0, i));
}
if (!Regex.isSimpleMatchPattern(expression)) {
if (Regex.isSimpleMatchPattern(expression) == false) {
//TODO why does wildcard resolver throw exceptions regarding non wildcarded expressions? This should not be done here.
if (options.ignoreUnavailable() == false) {
AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(expression);
Expand Down Expand Up @@ -840,27 +840,29 @@ private static Set<String> expand(Context context, IndexMetaData.State excludeSt
String expression, boolean includeHidden) {
Set<String> expand = new HashSet<>();
for (Map.Entry<String, AliasOrIndex> entry : matches.entrySet()) {
String aliasOrIndexName = entry.getKey();
AliasOrIndex aliasOrIndex = entry.getValue();
if (context.isPreserveAliases() && aliasOrIndex.isAlias()) {
expand.add(entry.getKey());
} else {
for (IndexMetaData meta : aliasOrIndex.getIndices()) {
if (excludeState == null || meta.getState() != excludeState) {
if (includeHidden) {
expand.add(meta.getIndex().getName());
} else if (IndexMetaData.INDEX_HIDDEN_SETTING.get(meta.getSettings()) == false) {
expand.add(meta.getIndex().getName());
} else if (meta.getIndex().getName().startsWith(".") &&
expression.startsWith(".") && Regex.isSimpleMatchPattern(expression)) {

if (aliasOrIndex.isHidden() == false || includeHidden || implicitHiddenMatch(aliasOrIndexName, expression)) {
if (context.isPreserveAliases() && aliasOrIndex.isAlias()) {
expand.add(aliasOrIndexName);
} else {
for (IndexMetaData meta : aliasOrIndex.getIndices()) {
if (excludeState == null || meta.getState() != excludeState) {
expand.add(meta.getIndex().getName());
}
}

}
}
}
return expand;
}

private static boolean implicitHiddenMatch(String itemName, String expression) {
return itemName.startsWith(".") && expression.startsWith(".") && Regex.isSimpleMatchPattern(expression);
}

private boolean isEmptyOrTrivialWildcard(List<String> expressions) {
return expressions.isEmpty() || (expressions.size() == 1 && (MetaData.ALL.equals(expressions.get(0)) ||
Regex.isMatchAllPattern(expressions.get(0))));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ private SortedMap<String, AliasOrIndex> buildAliasAndIndexLookup() {
}
}
aliasAndIndexLookup.values().stream().filter(AliasOrIndex::isAlias)
.forEach(alias -> ((AliasOrIndex.Alias) alias).computeAndValidateWriteIndex());
.forEach(alias -> ((AliasOrIndex.Alias) alias).computeAndValidateAliasProperties());
return aliasAndIndexLookup;
}

Expand Down
Loading