Skip to content

Commit ff9b8bd

Browse files
authored
Implement hidden aliases (#52547)
This commit introduces hidden aliases. These are similar to hidden indices, in that they are not visible by default, unless explicitly specified by name or by indicating that hidden indices/aliases are desired. The new alias property, `is_hidden` is implemented similarly to `is_write_index`, except that it must be consistent across all indices with a given alias - that is, all indices with a given alias must specify the alias as either hidden, or all specify it as non-hidden, either explicitly or by omitting the `is_hidden` property.
1 parent 7c9641e commit ff9b8bd

File tree

21 files changed

+839
-58
lines changed

21 files changed

+839
-58
lines changed

docs/reference/indices/aliases.asciidoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ include::{docdir}/rest-api/common-parms.asciidoc[tag=index-alias-filter]
106106
+
107107
See <<filtered>> for an example.
108108

109+
`is_hidden`::
110+
(Optional, boolean)
111+
If `true`, the alias will be excluded from wildcard expressions by default,
112+
unless overriden in the request using the `expand_wildcards` parameter,
113+
similar to <<index-hidden,hidden indices>>. This property must be set to the
114+
same value on all indices that share an alias. Defaults to `false`.
115+
109116
`is_write_index`::
110117
(Optional, boolean)
111118
If `true`, assigns the index as an alias's write index.

server/src/main/java/org/elasticsearch/action/admin/indices/alias/Alias.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class Alias implements Writeable, ToXContentFragment {
5050
private static final ParseField INDEX_ROUTING = new ParseField("index_routing", "indexRouting", "index-routing");
5151
private static final ParseField SEARCH_ROUTING = new ParseField("search_routing", "searchRouting", "search-routing");
5252
private static final ParseField IS_WRITE_INDEX = new ParseField("is_write_index");
53+
private static final ParseField IS_HIDDEN = new ParseField("is_hidden");
5354

5455
private String name;
5556

@@ -65,6 +66,9 @@ public class Alias implements Writeable, ToXContentFragment {
6566
@Nullable
6667
private Boolean writeIndex;
6768

69+
@Nullable
70+
private Boolean isHidden;
71+
6872
public Alias(StreamInput in) throws IOException {
6973
name = in.readString();
7074
filter = in.readOptionalString();
@@ -75,6 +79,11 @@ public Alias(StreamInput in) throws IOException {
7579
} else {
7680
writeIndex = null;
7781
}
82+
if (in.getVersion().onOrAfter(Version.V_7_7_0)) {
83+
isHidden = in.readOptionalBoolean();
84+
} else {
85+
isHidden = null;
86+
}
7887
}
7988

8089
public Alias(String name) {
@@ -194,6 +203,21 @@ public Alias writeIndex(@Nullable Boolean writeIndex) {
194203
return this;
195204
}
196205

206+
/**
207+
* @return whether this alias is hidden or not
208+
*/
209+
public Boolean isHidden() {
210+
return isHidden;
211+
}
212+
213+
/**
214+
* Sets whether this alias is hidden
215+
*/
216+
public Alias isHidden(@Nullable Boolean isHidden) {
217+
this.isHidden = isHidden;
218+
return this;
219+
}
220+
197221
@Override
198222
public void writeTo(StreamOutput out) throws IOException {
199223
out.writeString(name);
@@ -203,6 +227,9 @@ public void writeTo(StreamOutput out) throws IOException {
203227
if (out.getVersion().onOrAfter(Version.V_6_4_0)) {
204228
out.writeOptionalBoolean(writeIndex);
205229
}
230+
if (out.getVersion().onOrAfter(Version.V_7_7_0)) {
231+
out.writeOptionalBoolean(isHidden);
232+
}
206233
}
207234

208235
/**
@@ -235,6 +262,8 @@ public static Alias fromXContent(XContentParser parser) throws IOException {
235262
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
236263
if (IS_WRITE_INDEX.match(currentFieldName, parser.getDeprecationHandler())) {
237264
alias.writeIndex(parser.booleanValue());
265+
} else if (IS_HIDDEN.match(currentFieldName, parser.getDeprecationHandler())) {
266+
alias.isHidden(parser.booleanValue());
238267
}
239268
}
240269
}
@@ -264,6 +293,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
264293

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

296+
if (isHidden != null) {
297+
builder.field(IS_HIDDEN.getPreferredName(), isHidden);
298+
}
299+
267300
builder.endObject();
268301
return builder;
269302
}

server/src/main/java/org/elasticsearch/action/admin/indices/alias/IndicesAliasesRequest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public static class AliasActions implements AliasesRequest, Writeable, ToXConten
9797
private static final ParseField INDEX_ROUTING = new ParseField("index_routing", "indexRouting", "index-routing");
9898
private static final ParseField SEARCH_ROUTING = new ParseField("search_routing", "searchRouting", "search-routing");
9999
private static final ParseField IS_WRITE_INDEX = new ParseField("is_write_index");
100+
private static final ParseField IS_HIDDEN = new ParseField("is_hidden");
100101

101102
private static final ParseField ADD = new ParseField("add");
102103
private static final ParseField REMOVE = new ParseField("remove");
@@ -193,6 +194,7 @@ private static ObjectParser<AliasActions, Void> parser(String name, Supplier<Ali
193194
ADD_PARSER.declareField(AliasActions::indexRouting, XContentParser::text, INDEX_ROUTING, ValueType.INT);
194195
ADD_PARSER.declareField(AliasActions::searchRouting, XContentParser::text, SEARCH_ROUTING, ValueType.INT);
195196
ADD_PARSER.declareField(AliasActions::writeIndex, XContentParser::booleanValue, IS_WRITE_INDEX, ValueType.BOOLEAN);
197+
ADD_PARSER.declareField(AliasActions::isHidden, XContentParser::booleanValue, IS_HIDDEN, ValueType.BOOLEAN);
196198
}
197199
private static final ObjectParser<AliasActions, Void> REMOVE_PARSER = parser(REMOVE.getPreferredName(), AliasActions::remove);
198200
private static final ObjectParser<AliasActions, Void> REMOVE_INDEX_PARSER = parser(REMOVE_INDEX.getPreferredName(),
@@ -231,6 +233,7 @@ private static ObjectParser<AliasActions, Void> parser(String name, Supplier<Ali
231233
private String indexRouting;
232234
private String searchRouting;
233235
private Boolean writeIndex;
236+
private Boolean isHidden;
234237

235238
public AliasActions(AliasActions.Type type) {
236239
this.type = type;
@@ -250,9 +253,13 @@ public AliasActions(StreamInput in) throws IOException {
250253
if (in.getVersion().onOrAfter(Version.V_6_4_0)) {
251254
writeIndex = in.readOptionalBoolean();
252255
}
256+
if (in.getVersion().onOrAfter(Version.V_7_7_0)) { //TODO fix for backport of https://github.com/elastic/elasticsearch/pull/52547
257+
isHidden = in.readOptionalBoolean();
258+
}
253259
if (in.getVersion().onOrAfter(Version.V_7_0_0)) {
254260
originalAliases = in.readStringArray();
255261
}
262+
256263
}
257264

258265
@Override
@@ -267,6 +274,9 @@ public void writeTo(StreamOutput out) throws IOException {
267274
if (out.getVersion().onOrAfter(Version.V_6_4_0)) {
268275
out.writeOptionalBoolean(writeIndex);
269276
}
277+
if (out.getVersion().onOrAfter(Version.V_7_7_0)) { //TODO fix for backport https://github.com/elastic/elasticsearch/pull/52547
278+
out.writeOptionalBoolean(isHidden);
279+
}
270280
if (out.getVersion().onOrAfter(Version.V_7_0_0)) {
271281
out.writeStringArray(originalAliases);
272282
}
@@ -442,6 +452,18 @@ public Boolean writeIndex() {
442452
return writeIndex;
443453
}
444454

455+
public AliasActions isHidden(Boolean isHidden) {
456+
if (type != AliasActions.Type.ADD) {
457+
throw new IllegalArgumentException("[" + IS_HIDDEN.getPreferredName() + "] is unsupported for [" + type + "]");
458+
}
459+
this.isHidden = isHidden;
460+
return this;
461+
}
462+
463+
public Boolean isHidden() {
464+
return isHidden;
465+
}
466+
445467
@Override
446468
public String[] aliases() {
447469
return aliases;
@@ -500,6 +522,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
500522
if (null != writeIndex) {
501523
builder.field(IS_WRITE_INDEX.getPreferredName(), writeIndex);
502524
}
525+
if (null != isHidden) {
526+
builder.field(IS_HIDDEN.getPreferredName(), isHidden);
527+
}
503528
builder.endObject();
504529
builder.endObject();
505530
return builder;

server/src/main/java/org/elasticsearch/action/admin/indices/alias/TransportIndicesAliasesAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ protected void masterOperation(final IndicesAliasesRequest request, final Cluste
125125
case ADD:
126126
for (String alias : concreteAliases(action, state.metaData(), index.getName())) {
127127
finalActions.add(new AliasAction.Add(index.getName(), alias, action.filter(), action.indexRouting(),
128-
action.searchRouting(), action.writeIndex()));
128+
action.searchRouting(), action.writeIndex(), action.isHidden()));
129129
}
130130
break;
131131
case REMOVE:

server/src/main/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverAction.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,11 @@ static List<AliasAction> rolloverAliasToNewIndex(String oldIndex, String newInde
214214
boolean explicitWriteIndex) {
215215
if (explicitWriteIndex) {
216216
return unmodifiableList(Arrays.asList(
217-
new AliasAction.Add(newIndex, request.getAlias(), null, null, null, true),
218-
new AliasAction.Add(oldIndex, request.getAlias(), null, null, null, false)));
217+
new AliasAction.Add(newIndex, request.getAlias(), null, null, null, true, null),
218+
new AliasAction.Add(oldIndex, request.getAlias(), null, null, null, false, null)));
219219
} else {
220220
return unmodifiableList(Arrays.asList(
221-
new AliasAction.Add(newIndex, request.getAlias(), null, null, null, null),
221+
new AliasAction.Add(newIndex, request.getAlias(), null, null, null, null, null),
222222
new AliasAction.Remove(oldIndex, request.getAlias())));
223223
}
224224
}

server/src/main/java/org/elasticsearch/cluster/metadata/AliasAction.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ public static class Add extends AliasAction {
8585
@Nullable
8686
private final Boolean writeIndex;
8787

88+
@Nullable final Boolean isHidden;
89+
8890
/**
8991
* Build the operation.
9092
*/
91-
public Add(String index, String alias, @Nullable String filter, @Nullable String indexRouting,
92-
@Nullable String searchRouting, @Nullable Boolean writeIndex) {
93+
public Add(String index, String alias, @Nullable String filter, @Nullable String indexRouting, @Nullable String searchRouting,
94+
@Nullable Boolean writeIndex, @Nullable Boolean isHidden) {
9395
super(index);
9496
if (false == Strings.hasText(alias)) {
9597
throw new IllegalArgumentException("[alias] is required");
@@ -99,6 +101,7 @@ public Add(String index, String alias, @Nullable String filter, @Nullable String
99101
this.indexRouting = indexRouting;
100102
this.searchRouting = searchRouting;
101103
this.writeIndex = writeIndex;
104+
this.isHidden = isHidden;
102105
}
103106

104107
/**
@@ -112,6 +115,11 @@ public Boolean writeIndex() {
112115
return writeIndex;
113116
}
114117

118+
@Nullable
119+
public Boolean isHidden() {
120+
return isHidden;
121+
}
122+
115123
@Override
116124
boolean removeIndex() {
117125
return false;
@@ -122,7 +130,7 @@ boolean apply(NewAliasValidator aliasValidator, MetaData.Builder metadata, Index
122130
aliasValidator.validate(alias, indexRouting, filter, writeIndex);
123131

124132
AliasMetaData newAliasMd = AliasMetaData.newAliasMetaDataBuilder(alias).filter(filter).indexRouting(indexRouting)
125-
.searchRouting(searchRouting).writeIndex(writeIndex).build();
133+
.searchRouting(searchRouting).writeIndex(writeIndex).isHidden(isHidden).build();
126134

127135
// Check if this alias already exists
128136
AliasMetaData currentAliasMd = index.getAliases().get(alias);

server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.io.IOException;
4242
import java.util.Collections;
4343
import java.util.Map;
44+
import java.util.Objects;
4445
import java.util.Set;
4546

4647
import static java.util.Collections.emptySet;
@@ -60,7 +61,11 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
6061
@Nullable
6162
private final Boolean writeIndex;
6263

63-
private AliasMetaData(String alias, CompressedXContent filter, String indexRouting, String searchRouting, Boolean writeIndex) {
64+
@Nullable
65+
private final Boolean isHidden;
66+
67+
private AliasMetaData(String alias, CompressedXContent filter, String indexRouting, String searchRouting, Boolean writeIndex,
68+
@Nullable Boolean isHidden) {
6469
this.alias = alias;
6570
this.filter = filter;
6671
this.indexRouting = indexRouting;
@@ -71,10 +76,12 @@ private AliasMetaData(String alias, CompressedXContent filter, String indexRouti
7176
searchRoutingValues = emptySet();
7277
}
7378
this.writeIndex = writeIndex;
79+
this.isHidden = isHidden;
7480
}
7581

7682
private AliasMetaData(AliasMetaData aliasMetaData, String alias) {
77-
this(alias, aliasMetaData.filter(), aliasMetaData.indexRouting(), aliasMetaData.searchRouting(), aliasMetaData.writeIndex());
83+
this(alias, aliasMetaData.filter(), aliasMetaData.indexRouting(), aliasMetaData.searchRouting(), aliasMetaData.writeIndex(),
84+
aliasMetaData.isHidden);
7885
}
7986

8087
public String alias() {
@@ -121,6 +128,11 @@ public Boolean writeIndex() {
121128
return writeIndex;
122129
}
123130

131+
@Nullable
132+
public Boolean isHidden() {
133+
return isHidden;
134+
}
135+
124136
public static Builder builder(String alias) {
125137
return new Builder(alias);
126138
}
@@ -143,11 +155,12 @@ public boolean equals(Object o) {
143155

144156
final AliasMetaData that = (AliasMetaData) o;
145157

146-
if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false;
147-
if (filter != null ? !filter.equals(that.filter) : that.filter != null) return false;
148-
if (indexRouting != null ? !indexRouting.equals(that.indexRouting) : that.indexRouting != null) return false;
149-
if (searchRouting != null ? !searchRouting.equals(that.searchRouting) : that.searchRouting != null) return false;
150-
if (writeIndex != null ? writeIndex != that.writeIndex : that.writeIndex != null) return false;
158+
if (Objects.equals(alias, that.alias) == false) return false;
159+
if (Objects.equals(filter, that.filter) == false) return false;
160+
if (Objects.equals(indexRouting, that.indexRouting) == false) return false;
161+
if (Objects.equals(searchRouting, that.searchRouting) == false) return false;
162+
if (Objects.equals(writeIndex, that.writeIndex) == false) return false;
163+
if (Objects.equals(isHidden, that.isHidden) == false) return false;
151164

152165
return true;
153166
}
@@ -187,6 +200,10 @@ public void writeTo(StreamOutput out) throws IOException {
187200
if (out.getVersion().onOrAfter(Version.V_6_4_0)) {
188201
out.writeOptionalBoolean(writeIndex());
189202
}
203+
204+
if (out.getVersion().onOrAfter(Version.V_7_7_0)) {
205+
out.writeOptionalBoolean(isHidden());
206+
}
190207
}
191208

192209
public AliasMetaData(StreamInput in) throws IOException {
@@ -213,6 +230,12 @@ public AliasMetaData(StreamInput in) throws IOException {
213230
} else {
214231
writeIndex = null;
215232
}
233+
234+
if (in.getVersion().onOrAfter(Version.V_7_7_0)) {
235+
isHidden = in.readOptionalBoolean();
236+
} else {
237+
isHidden = null;
238+
}
216239
}
217240

218241
public static Diff<AliasMetaData> readDiffFrom(StreamInput in) throws IOException {
@@ -243,6 +266,8 @@ public static class Builder {
243266
@Nullable
244267
private Boolean writeIndex;
245268

269+
@Nullable
270+
private Boolean isHidden;
246271

247272
public Builder(String alias) {
248273
this.alias = alias;
@@ -300,8 +325,13 @@ public Builder writeIndex(@Nullable Boolean writeIndex) {
300325
return this;
301326
}
302327

328+
public Builder isHidden(@Nullable Boolean isHidden) {
329+
this.isHidden = isHidden;
330+
return this;
331+
}
332+
303333
public AliasMetaData build() {
304-
return new AliasMetaData(alias, filter, indexRouting, searchRouting, writeIndex);
334+
return new AliasMetaData(alias, filter, indexRouting, searchRouting, writeIndex, isHidden);
305335
}
306336

307337
public static void toXContent(AliasMetaData aliasMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException {
@@ -327,6 +357,10 @@ public static void toXContent(AliasMetaData aliasMetaData, XContentBuilder build
327357
builder.field("is_write_index", aliasMetaData.writeIndex());
328358
}
329359

360+
if (aliasMetaData.isHidden != null) {
361+
builder.field("is_hidden", aliasMetaData.isHidden());
362+
}
363+
330364
builder.endObject();
331365
}
332366

@@ -366,6 +400,8 @@ public static AliasMetaData fromXContent(XContentParser parser) throws IOExcepti
366400
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
367401
if ("is_write_index".equals(currentFieldName)) {
368402
builder.writeIndex(parser.booleanValue());
403+
} else if ("is_hidden".equals(currentFieldName)) {
404+
builder.isHidden(parser.booleanValue());
369405
}
370406
}
371407
}

0 commit comments

Comments
 (0)