add is-write-index flag to aliases (#30942)

This commit adds the is-write-index flag for aliases.
It allows requests to set the flag, and responses to display the flag.
It does not validate and/or affect any indexing/getting/updating behavior
of Elasticsearch -- this will be done in a follow-up PR.
This commit is contained in:
Tal Levy 2018-06-15 08:45:29 -07:00 committed by GitHub
parent eda4964f64
commit 3b70e943eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 524 additions and 40 deletions

View File

@ -244,6 +244,94 @@ GET /alias2/_search?q=user:kimchy&routing=2,3
// CONSOLE
// TEST[continued]
[float]
[[aliases-write-index]]
==== Write Index
It is possible to associate the index pointed to by an alias as the write index.
When specified, all index and update requests against an alias that point to multiple
indices will attempt to resolve to the one index that is the write index.
Only one index per alias can be assigned to be the write index at a time. If no write index is specified
and there are multiple indices referenced by an alias, then writes will not be allowed.
It is possible to specify an index associated with an alias as a write index using both the aliases API
and index creation API.
[source,js]
--------------------------------------------------
POST /_aliases
{
"actions" : [
{
"add" : {
"index" : "test",
"alias" : "alias1",
"is_write_index" : true
}
}
]
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT test\n/]
In this example, we associate the alias `alias1` to both `test` and `test2`, where
`test` will be the index chosen for writing to.
[source,js]
--------------------------------------------------
PUT /alias1/_doc/1
{
"foo": "bar"
}
--------------------------------------------------
// CONSOLE
// TEST[continued]
The new document that was indexed to `/alias1/_doc/1` will be indexed as if it were
`/test/_doc/1`.
[source,js]
--------------------------------------------------
GET /test/_doc/1
--------------------------------------------------
// CONSOLE
// TEST[continued]
To swap which index is the write index for an alias, the Aliases API can be leveraged to
do an atomic swap. The swap is not dependent on the ordering of the actions.
[source,js]
--------------------------------------------------
POST /_aliases
{
"actions" : [
{
"add" : {
"index" : "test",
"alias" : "alias1",
"is_write_index" : true
}
}, {
"add" : {
"index" : "test2",
"alias" : "alias1",
"is_write_index" : false
}
}
]
}
--------------------------------------------------
// CONSOLE
// TEST[s/^/PUT test\nPUT test2\n/]
[IMPORTANT]
=====================================
Aliases that do not explicitly set `is_write_index: true` for an index, and
only reference one index, will have that referenced index behave as if it is the write index
until an additional index is referenced. At that point, there will be no write index and
writes will be rejected.
=====================================
[float]
[[alias-adding]]

View File

@ -79,7 +79,6 @@
indices.get_alias:
index: test_index
- match: {test_index.aliases.test_alias: {}}
- match: {test_index.aliases.test_blias.search_routing: b}
- match: {test_index.aliases.test_blias.index_routing: b}
- is_false: test_index.aliases.test_blias.filter
@ -87,6 +86,30 @@
- is_false: test_index.aliases.test_clias.index_routing
- is_false: test_index.aliases.test_clias.search_routing
---
"Create index with write aliases":
- skip:
version: " - 6.99.99"
reason: is_write_index is not implemented in ES <= 6.x
- do:
indices.create:
index: test_index
body:
aliases:
test_alias: {}
test_blias:
is_write_index: false
test_clias:
is_write_index: true
- do:
indices.get_alias:
index: test_index
- is_false: test_index.aliases.test_alias.is_write_index
- is_false: test_index.aliases.test_blias.is_write_index
- is_true: test_index.aliases.test_clias.is_write_index
---
"Create index with no type mappings":
- do:

View File

@ -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;
@ -49,6 +50,7 @@ public class Alias implements Streamable, ToXContentFragment {
private static final ParseField ROUTING = new ParseField("routing");
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 String name;
@ -61,6 +63,9 @@ public class Alias implements Streamable, ToXContentFragment {
@Nullable
private String searchRouting;
@Nullable
private Boolean writeIndex;
private Alias() {
}
@ -167,6 +172,21 @@ public class Alias implements Streamable, ToXContentFragment {
return this;
}
/**
* @return the write index flag for the alias
*/
public Boolean writeIndex() {
return writeIndex;
}
/**
* Sets whether an alias is pointing to a write-index
*/
public Alias writeIndex(@Nullable Boolean writeIndex) {
this.writeIndex = writeIndex;
return this;
}
/**
* Allows to read an alias from the provided input stream
*/
@ -182,6 +202,11 @@ public class Alias implements Streamable, ToXContentFragment {
filter = in.readOptionalString();
indexRouting = in.readOptionalString();
searchRouting = in.readOptionalString();
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
writeIndex = in.readOptionalBoolean();
} else {
writeIndex = null;
}
}
@Override
@ -190,6 +215,9 @@ public class Alias implements Streamable, ToXContentFragment {
out.writeOptionalString(filter);
out.writeOptionalString(indexRouting);
out.writeOptionalString(searchRouting);
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
out.writeOptionalBoolean(writeIndex);
}
}
/**
@ -219,6 +247,10 @@ public class Alias implements Streamable, ToXContentFragment {
} else if (SEARCH_ROUTING.match(currentFieldName, parser.getDeprecationHandler())) {
alias.searchRouting(parser.text());
}
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
if (IS_WRITE_INDEX.match(currentFieldName, parser.getDeprecationHandler())) {
alias.writeIndex(parser.booleanValue());
}
}
}
return alias;
@ -245,6 +277,8 @@ public class Alias implements Streamable, ToXContentFragment {
}
}
builder.field(IS_WRITE_INDEX.getPreferredName(), writeIndex);
builder.endObject();
return builder;
}

View File

@ -20,6 +20,7 @@
package org.elasticsearch.action.admin.indices.alias;
import org.elasticsearch.ElasticsearchGenerationException;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.AliasesRequest;
import org.elasticsearch.action.support.IndicesOptions;
@ -84,6 +85,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
private static final ParseField ROUTING = new ParseField("routing");
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 ADD = new ParseField("add");
private static final ParseField REMOVE = new ParseField("remove");
@ -179,6 +181,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
ADD_PARSER.declareField(AliasActions::routing, XContentParser::text, ROUTING, ValueType.INT);
ADD_PARSER.declareField(AliasActions::indexRouting, XContentParser::text, INDEX_ROUTING, ValueType.INT);
ADD_PARSER.declareField(AliasActions::searchRouting, XContentParser::text, SEARCH_ROUTING, ValueType.INT);
ADD_PARSER.declareField(AliasActions::writeIndex, XContentParser::booleanValue, IS_WRITE_INDEX, ValueType.BOOLEAN);
}
private static final ObjectParser<AliasActions, Void> REMOVE_PARSER = parser(REMOVE.getPreferredName(), AliasActions::remove);
private static final ObjectParser<AliasActions, Void> REMOVE_INDEX_PARSER = parser(REMOVE_INDEX.getPreferredName(),
@ -215,6 +218,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
private String routing;
private String indexRouting;
private String searchRouting;
private Boolean writeIndex;
public AliasActions(AliasActions.Type type) {
this.type = type;
@ -231,6 +235,9 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
routing = in.readOptionalString();
searchRouting = in.readOptionalString();
indexRouting = in.readOptionalString();
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
writeIndex = in.readOptionalBoolean();
}
}
@Override
@ -242,6 +249,9 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
out.writeOptionalString(routing);
out.writeOptionalString(searchRouting);
out.writeOptionalString(indexRouting);
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
out.writeOptionalBoolean(writeIndex);
}
}
/**
@ -401,6 +411,18 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
}
}
public AliasActions writeIndex(Boolean writeIndex) {
if (type != AliasActions.Type.ADD) {
throw new IllegalArgumentException("[is_write_index] is unsupported for [" + type + "]");
}
this.writeIndex = writeIndex;
return this;
}
public Boolean writeIndex() {
return writeIndex;
}
@Override
public String[] aliases() {
return aliases;

View File

@ -130,6 +130,18 @@ public class IndicesAliasesRequestBuilder
return this;
}
/**
* Adds an alias to the index.
*
* @param index The index
* @param alias The alias
* @param writeIndex write index flag
*/
public IndicesAliasesRequestBuilder addAlias(String index, String alias, boolean writeIndex) {
request.addAliasAction(AliasActions.add().index(index).alias(alias).writeIndex(writeIndex));
return this;
}
/**
* Removes an alias from the index.
*

View File

@ -100,7 +100,8 @@ public class TransportIndicesAliasesAction extends TransportMasterNodeAction<Ind
switch (action.actionType()) {
case ADD:
for (String alias : concreteAliases(action, state.metaData(), index)) {
finalActions.add(new AliasAction.Add(index, alias, action.filter(), action.indexRouting(), action.searchRouting()));
finalActions.add(new AliasAction.Add(index, alias, action.filter(), action.indexRouting(),
action.searchRouting(), action.writeIndex()));
}
break;
case REMOVE:

View File

@ -196,7 +196,7 @@ public class TransportRolloverAction extends TransportMasterNodeAction<RolloverR
static IndicesAliasesClusterStateUpdateRequest prepareRolloverAliasesUpdateRequest(String oldIndex, String newIndex,
RolloverRequest request) {
List<AliasAction> actions = unmodifiableList(Arrays.asList(
new AliasAction.Add(newIndex, request.getAlias(), null, null, null),
new AliasAction.Add(newIndex, request.getAlias(), null, null, null, null),
new AliasAction.Remove(oldIndex, request.getAlias())));
final IndicesAliasesClusterStateUpdateRequest updateRequest = new IndicesAliasesClusterStateUpdateRequest(actions)
.ackTimeout(request.ackTimeout())

View File

@ -51,7 +51,7 @@ public abstract class AliasAction {
/**
* Apply the action.
*
*
* @param aliasValidator call to validate a new alias before adding it to the builder
* @param metadata metadata builder for the changes made by all actions as part of this request
* @param index metadata for the index being changed
@ -64,7 +64,7 @@ public abstract class AliasAction {
*/
@FunctionalInterface
public interface NewAliasValidator {
void validate(String alias, @Nullable String indexRouting, @Nullable String filter);
void validate(String alias, @Nullable String indexRouting, @Nullable String filter, @Nullable Boolean writeIndex);
}
/**
@ -82,10 +82,14 @@ public abstract class AliasAction {
@Nullable
private final String searchRouting;
@Nullable
private final Boolean writeIndex;
/**
* Build the operation.
*/
public Add(String index, String alias, @Nullable String filter, @Nullable String indexRouting, @Nullable String searchRouting) {
public Add(String index, String alias, @Nullable String filter, @Nullable String indexRouting,
@Nullable String searchRouting, @Nullable Boolean writeIndex) {
super(index);
if (false == Strings.hasText(alias)) {
throw new IllegalArgumentException("[alias] is required");
@ -94,6 +98,7 @@ public abstract class AliasAction {
this.filter = filter;
this.indexRouting = indexRouting;
this.searchRouting = searchRouting;
this.writeIndex = writeIndex;
}
/**
@ -103,6 +108,10 @@ public abstract class AliasAction {
return alias;
}
public Boolean writeIndex() {
return writeIndex;
}
@Override
boolean removeIndex() {
return false;
@ -110,15 +119,18 @@ public abstract class AliasAction {
@Override
boolean apply(NewAliasValidator aliasValidator, MetaData.Builder metadata, IndexMetaData index) {
aliasValidator.validate(alias, indexRouting, filter);
aliasValidator.validate(alias, indexRouting, filter, writeIndex);
AliasMetaData newAliasMd = AliasMetaData.newAliasMetaDataBuilder(alias).filter(filter).indexRouting(indexRouting)
.searchRouting(searchRouting).build();
.searchRouting(searchRouting).writeIndex(writeIndex).build();
// Check if this alias already exists
AliasMetaData currentAliasMd = index.getAliases().get(alias);
if (currentAliasMd != null && currentAliasMd.equals(newAliasMd)) {
// It already exists, ignore it
return false;
}
metadata.put(IndexMetaData.builder(index).putAlias(newAliasMd));
return true;
}
@ -182,4 +194,4 @@ public abstract class AliasAction {
throw new UnsupportedOperationException();
}
}
}
}

View File

@ -20,8 +20,10 @@
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;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
@ -55,7 +57,10 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
private final Set<String> searchRoutingValues;
private AliasMetaData(String alias, CompressedXContent filter, String indexRouting, String searchRouting) {
@Nullable
private final Boolean writeIndex;
private AliasMetaData(String alias, CompressedXContent filter, String indexRouting, String searchRouting, Boolean writeIndex) {
this.alias = alias;
this.filter = filter;
this.indexRouting = indexRouting;
@ -65,10 +70,11 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
} else {
searchRoutingValues = emptySet();
}
this.writeIndex = writeIndex;
}
private AliasMetaData(AliasMetaData aliasMetaData, String alias) {
this(alias, aliasMetaData.filter(), aliasMetaData.indexRouting(), aliasMetaData.searchRouting());
this(alias, aliasMetaData.filter(), aliasMetaData.indexRouting(), aliasMetaData.searchRouting(), aliasMetaData.writeIndex());
}
public String alias() {
@ -111,6 +117,10 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
return searchRoutingValues;
}
public Boolean writeIndex() {
return writeIndex;
}
public static Builder builder(String alias) {
return new Builder(alias);
}
@ -138,6 +148,8 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
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;
return true;
}
@ -148,6 +160,7 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
result = 31 * result + (filter != null ? filter.hashCode() : 0);
result = 31 * result + (indexRouting != null ? indexRouting.hashCode() : 0);
result = 31 * result + (searchRouting != null ? searchRouting.hashCode() : 0);
result = 31 * result + (writeIndex != null ? writeIndex.hashCode() : 0);
return result;
}
@ -173,6 +186,9 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
out.writeBoolean(false);
}
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
out.writeOptionalBoolean(writeIndex());
}
}
public AliasMetaData(StreamInput in) throws IOException {
@ -194,6 +210,11 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
searchRouting = null;
searchRoutingValues = emptySet();
}
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
writeIndex = in.readOptionalBoolean();
} else {
writeIndex = null;
}
}
public static Diff<AliasMetaData> readDiffFrom(StreamInput in) throws IOException {
@ -221,6 +242,9 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
private String searchRouting;
@Nullable
private Boolean writeIndex;
public Builder(String alias) {
this.alias = alias;
@ -231,6 +255,7 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
filter = aliasMetaData.filter();
indexRouting = aliasMetaData.indexRouting();
searchRouting = aliasMetaData.searchRouting();
writeIndex = aliasMetaData.writeIndex();
}
public String alias() {
@ -284,8 +309,13 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
return this;
}
public Builder writeIndex(@Nullable Boolean writeIndex) {
this.writeIndex = writeIndex;
return this;
}
public AliasMetaData build() {
return new AliasMetaData(alias, filter, indexRouting, searchRouting);
return new AliasMetaData(alias, filter, indexRouting, searchRouting, writeIndex);
}
public static void toXContent(AliasMetaData aliasMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException {
@ -307,6 +337,10 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
builder.field("search_routing", aliasMetaData.searchRouting());
}
if (aliasMetaData.writeIndex() != null) {
builder.field("is_write_index", aliasMetaData.writeIndex());
}
builder.endObject();
}
@ -343,6 +377,10 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements To
}
} else if (token == XContentParser.Token.START_ARRAY) {
parser.skipChildren();
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
if ("is_write_index".equals(currentFieldName)) {
builder.writeIndex(parser.booleanValue());
}
}
}
return builder.build();

View File

@ -19,12 +19,16 @@
package org.elasticsearch.cluster.metadata;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
* Encapsulates the {@link IndexMetaData} instances of a concrete index or indices an alias is pointing to.
@ -78,6 +82,7 @@ public interface AliasOrIndex {
private final String aliasName;
private final List<IndexMetaData> referenceIndexMetaDatas;
private SetOnce<IndexMetaData> writeIndex = new SetOnce<>();
public Alias(AliasMetaData aliasMetaData, IndexMetaData indexMetaData) {
this.aliasName = aliasMetaData.getAlias();
@ -90,11 +95,21 @@ public interface AliasOrIndex {
return true;
}
public String getAliasName() {
return aliasName;
}
@Override
public List<IndexMetaData> getIndices() {
return referenceIndexMetaDatas;
}
@Nullable
public IndexMetaData getWriteIndex() {
return writeIndex.get();
}
/**
* Returns the unique alias metadata per concrete index.
*
@ -138,5 +153,20 @@ public interface AliasOrIndex {
this.referenceIndexMetaDatas.add(indexMetaData);
}
public void computeAndValidateWriteIndex() {
List<IndexMetaData> writeIndices = referenceIndexMetaDatas.stream()
.filter(idxMeta -> Boolean.TRUE.equals(idxMeta.getAliases().get(aliasName).writeIndex()))
.collect(Collectors.toList());
if (referenceIndexMetaDatas.size() == 1) {
writeIndex.set(referenceIndexMetaDatas.get(0));
} else if (writeIndices.size() == 1) {
writeIndex.set(writeIndices.get(0));
} else if (writeIndices.size() > 1) {
List<String> writeIndicesStrings = writeIndices.stream()
.map(i -> i.getIndex().getName()).collect(Collectors.toList());
throw new IllegalStateException("alias [" + aliasName + "] has more than one write index [" +
Strings.collectionToCommaDelimitedString(writeIndicesStrings) + "]");
}
}
}
}

View File

@ -57,7 +57,7 @@ public class AliasValidator extends AbstractComponent {
* @throws IllegalArgumentException if the alias is not valid
*/
public void validateAlias(Alias alias, String index, MetaData metaData) {
validateAlias(alias.name(), index, alias.indexRouting(), name -> metaData.index(name));
validateAlias(alias.name(), index, alias.indexRouting(), metaData::index);
}
/**
@ -66,7 +66,7 @@ public class AliasValidator extends AbstractComponent {
* @throws IllegalArgumentException if the alias is not valid
*/
public void validateAliasMetaData(AliasMetaData aliasMetaData, String index, MetaData metaData) {
validateAlias(aliasMetaData.alias(), index, aliasMetaData.indexRouting(), name -> metaData.index(name));
validateAlias(aliasMetaData.alias(), index, aliasMetaData.indexRouting(), metaData::index);
}
/**

View File

@ -1039,7 +1039,22 @@ public class MetaData implements Iterable<IndexMetaData>, Diffable<MetaData>, To
}
// build all indices map
SortedMap<String, AliasOrIndex> aliasAndIndexLookup = Collections.unmodifiableSortedMap(buildAliasAndIndexLookup());
// build all concrete indices arrays:
// TODO: I think we can remove these arrays. it isn't worth the effort, for operations on all indices.
// When doing an operation across all indices, most of the time is spent on actually going to all shards and
// do the required operations, the bottleneck isn't resolving expressions into concrete indices.
String[] allIndicesArray = allIndices.toArray(new String[allIndices.size()]);
String[] allOpenIndicesArray = allOpenIndices.toArray(new String[allOpenIndices.size()]);
String[] allClosedIndicesArray = allClosedIndices.toArray(new String[allClosedIndices.size()]);
return new MetaData(clusterUUID, version, transientSettings, persistentSettings, indices.build(), templates.build(),
customs.build(), allIndicesArray, allOpenIndicesArray, allClosedIndicesArray, aliasAndIndexLookup);
}
private SortedMap<String, AliasOrIndex> buildAliasAndIndexLookup() {
SortedMap<String, AliasOrIndex> aliasAndIndexLookup = new TreeMap<>();
for (ObjectCursor<IndexMetaData> cursor : indices.values()) {
IndexMetaData indexMetaData = cursor.value;
@ -1059,17 +1074,9 @@ public class MetaData implements Iterable<IndexMetaData>, Diffable<MetaData>, To
});
}
}
aliasAndIndexLookup = Collections.unmodifiableSortedMap(aliasAndIndexLookup);
// build all concrete indices arrays:
// TODO: I think we can remove these arrays. it isn't worth the effort, for operations on all indices.
// When doing an operation across all indices, most of the time is spent on actually going to all shards and
// do the required operations, the bottleneck isn't resolving expressions into concrete indices.
String[] allIndicesArray = allIndices.toArray(new String[allIndices.size()]);
String[] allOpenIndicesArray = allOpenIndices.toArray(new String[allOpenIndices.size()]);
String[] allClosedIndicesArray = allClosedIndices.toArray(new String[allClosedIndices.size()]);
return new MetaData(clusterUUID, version, transientSettings, persistentSettings, indices.build(), templates.build(),
customs.build(), allIndicesArray, allOpenIndicesArray, allClosedIndicesArray, aliasAndIndexLookup);
aliasAndIndexLookup.values().stream().filter(AliasOrIndex::isAlias)
.forEach(alias -> ((AliasOrIndex.Alias) alias).computeAndValidateWriteIndex());
return aliasAndIndexLookup;
}
public static String toXContent(MetaData metaData) throws IOException {

View File

@ -516,7 +516,7 @@ public class MetaDataCreateIndexService extends AbstractComponent {
}
for (Alias alias : request.aliases()) {
AliasMetaData aliasMetaData = AliasMetaData.builder(alias.name()).filter(alias.filter())
.indexRouting(alias.indexRouting()).searchRouting(alias.searchRouting()).build();
.indexRouting(alias.indexRouting()).searchRouting(alias.searchRouting()).writeIndex(alias.writeIndex()).build();
indexMetaDataBuilder.putAlias(aliasMetaData);
}

View File

@ -127,7 +127,7 @@ public class MetaDataIndexAliasesService extends AbstractComponent {
if (index == null) {
throw new IndexNotFoundException(action.getIndex());
}
NewAliasValidator newAliasValidator = (alias, indexRouting, filter) -> {
NewAliasValidator newAliasValidator = (alias, indexRouting, filter, writeIndex) -> {
/* It is important that we look up the index using the metadata builder we are modifying so we can remove an
* index and replace it with an alias. */
Function<String, IndexMetaData> indexLookup = name -> metadata.get(name);

View File

@ -114,6 +114,7 @@ public class AliasActionsTests extends ESTestCase {
Map<String, Object> filter = randomBoolean() ? randomMap(5) : null;
Object searchRouting = randomBoolean() ? randomRouting() : null;
Object indexRouting = randomBoolean() ? randomBoolean() ? searchRouting : randomRouting() : null;
boolean writeIndex = randomBoolean();
XContentBuilder b = XContentBuilder.builder(randomFrom(XContentType.values()).xContent());
b.startObject();
{
@ -142,6 +143,7 @@ public class AliasActionsTests extends ESTestCase {
if (indexRouting != null && false == indexRouting.equals(searchRouting)) {
b.field("index_routing", indexRouting);
}
b.field("is_write_index", writeIndex);
}
b.endObject();
}
@ -159,6 +161,7 @@ public class AliasActionsTests extends ESTestCase {
}
assertEquals(Objects.toString(searchRouting, null), action.searchRouting());
assertEquals(Objects.toString(indexRouting, null), action.indexRouting());
assertEquals(writeIndex, action.writeIndex());
}
}

View File

@ -93,6 +93,7 @@ public class CreateIndexRequestTests extends ESTestCase {
Alias alias = new Alias("test_alias");
alias.routing("1");
alias.filter("{\"term\":{\"year\":2016}}");
alias.writeIndex(true);
request.alias(alias);
Settings.Builder settings = Settings.builder();
@ -103,7 +104,7 @@ public class CreateIndexRequestTests extends ESTestCase {
String expectedRequestBody = "{\"settings\":{\"index\":{\"number_of_shards\":\"10\"}}," +
"\"mappings\":{\"my_type\":{\"type\":{}}}," +
"\"aliases\":{\"test_alias\":{\"filter\":{\"term\":{\"year\":2016}},\"routing\":\"1\"}}}";
"\"aliases\":{\"test_alias\":{\"filter\":{\"term\":{\"year\":2016}},\"routing\":\"1\",\"is_write_index\":true}}}";
assertEquals(expectedRequestBody, actualRequestBody);
}

View File

@ -71,6 +71,7 @@ public class ResizeRequestTests extends ESTestCase {
Alias alias = new Alias("test_alias");
alias.routing("1");
alias.filter("{\"term\":{\"year\":2016}}");
alias.writeIndex(true);
target.alias(alias);
Settings.Builder settings = Settings.builder();
settings.put(SETTING_NUMBER_OF_SHARDS, 10);
@ -78,7 +79,7 @@ public class ResizeRequestTests extends ESTestCase {
request.setTargetIndex(target);
String actualRequestBody = Strings.toString(request);
String expectedRequestBody = "{\"settings\":{\"index\":{\"number_of_shards\":\"10\"}}," +
"\"aliases\":{\"test_alias\":{\"filter\":{\"term\":{\"year\":2016}},\"routing\":\"1\"}}}";
"\"aliases\":{\"test_alias\":{\"filter\":{\"term\":{\"year\":2016}},\"routing\":\"1\",\"is_write_index\":true}}}";
assertEquals(expectedRequestBody, actualRequestBody);
}
}

View File

@ -41,6 +41,7 @@ public class AliasMetaDataTests extends AbstractXContentTestCase<AliasMetaData>
.indexRouting("indexRouting")
.routing("routing")
.searchRouting("trim,tw , ltw , lw")
.writeIndex(randomBoolean() ? null : randomBoolean())
.build();
assertThat(before.searchRoutingValues(), equalTo(Sets.newHashSet("trim", "tw ", " ltw ", " lw")));
@ -54,6 +55,21 @@ public class AliasMetaDataTests extends AbstractXContentTestCase<AliasMetaData>
assertThat(after, equalTo(before));
}
@Override
protected void assertEqualInstances(AliasMetaData expectedInstance, AliasMetaData newInstance) {
assertNotSame(newInstance, expectedInstance);
if (expectedInstance.writeIndex() == null) {
expectedInstance = AliasMetaData.builder(expectedInstance.alias())
.filter(expectedInstance.filter())
.indexRouting(expectedInstance.indexRouting())
.searchRouting(expectedInstance.searchRouting())
.writeIndex(randomBoolean() ? null : randomBoolean())
.build();
}
assertEquals(expectedInstance, newInstance);
assertEquals(expectedInstance.hashCode(), newInstance.hashCode());
}
@Override
protected AliasMetaData createTestInstance() {
return createTestItem();
@ -95,6 +111,7 @@ public class AliasMetaDataTests extends AbstractXContentTestCase<AliasMetaData>
if (randomBoolean()) {
builder.filter("{\"term\":{\"year\":2016}}");
}
builder.writeIndex(randomBoolean());
return builder.build();
}

View File

@ -69,6 +69,7 @@ import static org.elasticsearch.test.hamcrest.CollectionAssertions.hasKey;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -291,6 +292,32 @@ public class IndexCreationTaskTests extends ESTestCase {
assertThat(e.getMessage(), containsString("invalid wait_for_active_shards"));
}
public void testWriteIndex() throws Exception {
Boolean writeIndex = randomBoolean() ? null : randomBoolean();
setupRequestAlias(new Alias("alias1").writeIndex(writeIndex));
setupRequestMapping("mapping1", createMapping());
setupRequestCustom("custom1", createCustom());
reqSettings.put("key1", "value1");
final ClusterState result = executeTask();
assertThat(result.metaData().index("test").getAliases(), hasKey("alias1"));
assertThat(result.metaData().index("test").getAliases().get("alias1").writeIndex(), equalTo(writeIndex));
}
public void testWriteIndexValidationException() throws Exception {
IndexMetaData existingWriteIndex = IndexMetaData.builder("test2")
.settings(settings(Version.CURRENT)).putAlias(AliasMetaData.builder("alias1").writeIndex(true).build())
.numberOfShards(1).numberOfReplicas(0).build();
idxBuilder.put("test2", existingWriteIndex);
setupRequestMapping("mapping1", createMapping());
setupRequestCustom("custom1", createCustom());
reqSettings.put("key1", "value1");
setupRequestAlias(new Alias("alias1").writeIndex(true));
Exception exception = expectThrows(IllegalStateException.class, () -> executeTask());
assertThat(exception.getMessage(), startsWith("alias [alias1] has more than one write index ["));
}
private IndexRoutingTable createIndexRoutingTableWithStartedShards(Index index) {
final IndexRoutingTable idxRoutingTable = mock(IndexRoutingTable.class);

View File

@ -19,6 +19,7 @@
package org.elasticsearch.cluster.metadata;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.common.settings.Settings;
@ -29,9 +30,13 @@ import org.elasticsearch.test.VersionUtils;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.startsWith;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anySetOf;
import static org.mockito.Mockito.mock;
@ -64,7 +69,7 @@ public class MetaDataIndexAliasesServiceTests extends ESTestCase {
ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), index);
// Add an alias to it
ClusterState after = service.innerExecute(before, singletonList(new AliasAction.Add(index, "test", null, null, null)));
ClusterState after = service.innerExecute(before, singletonList(new AliasAction.Add(index, "test", null, null, null, null)));
AliasOrIndex alias = after.metaData().getAliasAndIndexLookup().get("test");
assertNotNull(alias);
assertTrue(alias.isAlias());
@ -74,7 +79,7 @@ public class MetaDataIndexAliasesServiceTests extends ESTestCase {
before = after;
after = service.innerExecute(before, Arrays.asList(
new AliasAction.Remove(index, "test"),
new AliasAction.Add(index, "test_2", null, null, null)));
new AliasAction.Add(index, "test_2", null, null, null, null)));
assertNull(after.metaData().getAliasAndIndexLookup().get("test"));
alias = after.metaData().getAliasAndIndexLookup().get("test_2");
assertNotNull(alias);
@ -95,7 +100,7 @@ public class MetaDataIndexAliasesServiceTests extends ESTestCase {
// Now remove "test" and add an alias to "test" to "test_2" in one go
ClusterState after = service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test_2", "test", null, null, null),
new AliasAction.Add("test_2", "test", null, null, null, null),
new AliasAction.RemoveIndex("test")));
AliasOrIndex alias = after.metaData().getAliasAndIndexLookup().get("test");
assertNotNull(alias);
@ -109,7 +114,7 @@ public class MetaDataIndexAliasesServiceTests extends ESTestCase {
// Attempt to add an alias to "test" at the same time as we remove it
IndexNotFoundException e = expectThrows(IndexNotFoundException.class, () -> service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null),
new AliasAction.Add("test", "alias", null, null, null, null),
new AliasAction.RemoveIndex("test"))));
assertEquals("test", e.getIndex().getName());
}
@ -125,6 +130,127 @@ public class MetaDataIndexAliasesServiceTests extends ESTestCase {
assertNull(after.metaData().getAliasAndIndexLookup().get("test"));
}
public void testAddWriteOnlyWithNoExistingAliases() {
ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), "test");
ClusterState after = service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null, false)));
assertFalse(after.metaData().index("test").getAliases().get("alias").writeIndex());
assertThat(((AliasOrIndex.Alias) after.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex(),
equalTo(after.metaData().index("test")));
after = service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null, null)));
assertNull(after.metaData().index("test").getAliases().get("alias").writeIndex());
assertThat(((AliasOrIndex.Alias) after.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex(),
equalTo(after.metaData().index("test")));
after = service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null, true)));
assertTrue(after.metaData().index("test").getAliases().get("alias").writeIndex());
assertThat(((AliasOrIndex.Alias) after.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex(),
equalTo(after.metaData().index("test")));
}
public void testAddWriteOnlyWithExistingWriteIndex() {
IndexMetaData.Builder indexMetaData = IndexMetaData.builder("test")
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
IndexMetaData.Builder indexMetaData2 = IndexMetaData.builder("test2")
.putAlias(AliasMetaData.builder("alias").writeIndex(true).build())
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
ClusterState before = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder().put(indexMetaData).put(indexMetaData2)).build();
ClusterState after = service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null, null)));
assertNull(after.metaData().index("test").getAliases().get("alias").writeIndex());
assertThat(((AliasOrIndex.Alias) after.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex(),
equalTo(after.metaData().index("test2")));
Exception exception = expectThrows(IllegalStateException.class, () -> service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null, true))));
assertThat(exception.getMessage(), startsWith("alias [alias] has more than one write index ["));
}
public void testSwapWriteOnlyIndex() {
IndexMetaData.Builder indexMetaData = IndexMetaData.builder("test")
.putAlias(AliasMetaData.builder("alias").writeIndex(true).build())
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
IndexMetaData.Builder indexMetaData2 = IndexMetaData.builder("test2")
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
ClusterState before = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder().put(indexMetaData).put(indexMetaData2)).build();
Boolean unsetValue = randomBoolean() ? null : false;
List<AliasAction> swapActions = Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null, unsetValue),
new AliasAction.Add("test2", "alias", null, null, null, true)
);
Collections.shuffle(swapActions, random());
ClusterState after = service.innerExecute(before, swapActions);
assertThat(after.metaData().index("test").getAliases().get("alias").writeIndex(), equalTo(unsetValue));
assertTrue(after.metaData().index("test2").getAliases().get("alias").writeIndex());
assertThat(((AliasOrIndex.Alias) after.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex(),
equalTo(after.metaData().index("test2")));
}
public void testAddWriteOnlyWithExistingNonWriteIndices() {
IndexMetaData.Builder indexMetaData = IndexMetaData.builder("test")
.putAlias(AliasMetaData.builder("alias").writeIndex(randomBoolean() ? null : false).build())
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
IndexMetaData.Builder indexMetaData2 = IndexMetaData.builder("test2")
.putAlias(AliasMetaData.builder("alias").writeIndex(randomBoolean() ? null : false).build())
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
IndexMetaData.Builder indexMetaData3 = IndexMetaData.builder("test3")
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
ClusterState before = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder().put(indexMetaData).put(indexMetaData2).put(indexMetaData3)).build();
assertNull(((AliasOrIndex.Alias) before.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex());
ClusterState after = service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test3", "alias", null, null, null, true)));
assertTrue(after.metaData().index("test3").getAliases().get("alias").writeIndex());
assertThat(((AliasOrIndex.Alias) after.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex(),
equalTo(after.metaData().index("test3")));
}
public void testAddWriteOnlyWithIndexRemoved() {
IndexMetaData.Builder indexMetaData = IndexMetaData.builder("test")
.putAlias(AliasMetaData.builder("alias").build())
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
IndexMetaData.Builder indexMetaData2 = IndexMetaData.builder("test2")
.putAlias(AliasMetaData.builder("alias").build())
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
ClusterState before = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder().put(indexMetaData).put(indexMetaData2)).build();
assertNull(before.metaData().index("test").getAliases().get("alias").writeIndex());
assertNull(before.metaData().index("test2").getAliases().get("alias").writeIndex());
assertNull(((AliasOrIndex.Alias) before.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex());
ClusterState after = service.innerExecute(before, Collections.singletonList(new AliasAction.RemoveIndex("test")));
assertNull(after.metaData().index("test2").getAliases().get("alias").writeIndex());
assertThat(((AliasOrIndex.Alias) after.metaData().getAliasAndIndexLookup().get("alias")).getWriteIndex(),
equalTo(after.metaData().index("test2")));
}
public void testAddWriteOnlyValidatesAgainstMetaDataBuilder() {
IndexMetaData.Builder indexMetaData = IndexMetaData.builder("test")
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
IndexMetaData.Builder indexMetaData2 = IndexMetaData.builder("test2")
.settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1);
ClusterState before = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder().put(indexMetaData).put(indexMetaData2)).build();
Exception exception = expectThrows(IllegalStateException.class, () -> service.innerExecute(before, Arrays.asList(
new AliasAction.Add("test", "alias", null, null, null, true),
new AliasAction.Add("test2", "alias", null, null, null, true)
)));
assertThat(exception.getMessage(), startsWith("alias [alias] has more than one write index ["));
}
private ClusterState createIndex(ClusterState state, String index) {
IndexMetaData indexMetaData = IndexMetaData.builder(index)
.settings(Settings.builder().put("index.version.created", VersionUtils.randomVersion(random())))

View File

@ -99,6 +99,34 @@ public class MetaDataTests extends ESTestCase {
}
}
public void testValidateAliasWriteOnly() {
String alias = randomAlphaOfLength(5);
String indexA = randomAlphaOfLength(6);
String indexB = randomAlphaOfLength(7);
Boolean aWriteIndex = randomBoolean() ? null : randomBoolean();
Boolean bWriteIndex;
if (Boolean.TRUE.equals(aWriteIndex)) {
bWriteIndex = randomFrom(Boolean.FALSE, null);
} else {
bWriteIndex = randomFrom(Boolean.TRUE, Boolean.FALSE, null);
}
// when only one index/alias pair exist
MetaData metaData = MetaData.builder().put(buildIndexMetaData(indexA, alias, aWriteIndex)).build();
// when alias points to two indices, but valid
// one of the following combinations: [(null, null), (null, true), (null, false), (false, false)]
MetaData.builder(metaData).put(buildIndexMetaData(indexB, alias, bWriteIndex)).build();
// when too many write indices
Exception exception = expectThrows(IllegalStateException.class,
() -> {
IndexMetaData.Builder metaA = buildIndexMetaData(indexA, alias, true);
IndexMetaData.Builder metaB = buildIndexMetaData(indexB, alias, true);
MetaData.builder().put(metaA).put(metaB).build();
});
assertThat(exception.getMessage(), startsWith("alias [" + alias + "] has more than one write index ["));
}
public void testResolveIndexRouting() {
IndexMetaData.Builder builder = IndexMetaData.builder("index")
.settings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT))
@ -428,6 +456,13 @@ public class MetaDataTests extends ESTestCase {
}
}
private IndexMetaData.Builder buildIndexMetaData(String name, String alias, Boolean writeIndex) {
return IndexMetaData.builder(name)
.settings(settings(Version.CURRENT)).creationDate(randomNonNegativeLong())
.putAlias(AliasMetaData.builder(alias).writeIndex(writeIndex))
.numberOfShards(1).numberOfReplicas(0);
}
@SuppressWarnings("unchecked")
private static void assertIndexMappingsNoFields(ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> mappings,
String index) {

View File

@ -111,7 +111,7 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
.putMapping("mapping1", MAPPING_SOURCE1)
.putMapping("mapping2", MAPPING_SOURCE2)
.putAlias(newAliasMetaDataBuilder("alias1").filter(ALIAS_FILTER1))
.putAlias(newAliasMetaDataBuilder("alias2"))
.putAlias(newAliasMetaDataBuilder("alias2").writeIndex(randomBoolean() ? null : randomBoolean()))
.putAlias(newAliasMetaDataBuilder("alias4").filter(ALIAS_FILTER2)))
.put(IndexTemplateMetaData.builder("foo")
.patterns(Collections.singletonList("bar"))
@ -132,7 +132,7 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
.putMapping("mapping1", MAPPING_SOURCE1)
.putMapping("mapping2", MAPPING_SOURCE2)
.putAlias(newAliasMetaDataBuilder("alias1").filter(ALIAS_FILTER1))
.putAlias(newAliasMetaDataBuilder("alias2"))
.putAlias(newAliasMetaDataBuilder("alias2").writeIndex(randomBoolean() ? null : randomBoolean()))
.putAlias(newAliasMetaDataBuilder("alias4").filter(ALIAS_FILTER2)))
.put(IndexTemplateMetaData.builder("foo")
.patterns(Collections.singletonList("bar"))
@ -146,7 +146,6 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
.build();
String metaDataSource = MetaData.Builder.toXContent(metaData);
// System.out.println("ToJson: " + metaDataSource);
MetaData parsedMetaData = MetaData.Builder.fromXContent(createParser(JsonXContent.jsonXContent, metaDataSource));
@ -270,6 +269,8 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
assertThat(indexMetaData.getAliases().get("alias1").filter().string(), equalTo(ALIAS_FILTER1));
assertThat(indexMetaData.getAliases().get("alias2").alias(), equalTo("alias2"));
assertThat(indexMetaData.getAliases().get("alias2").filter(), nullValue());
assertThat(indexMetaData.getAliases().get("alias2").writeIndex(),
equalTo(metaData.index("test11").getAliases().get("alias2").writeIndex()));
assertThat(indexMetaData.getAliases().get("alias4").alias(), equalTo("alias4"));
assertThat(indexMetaData.getAliases().get("alias4").filter().string(), equalTo(ALIAS_FILTER2));
@ -288,6 +289,8 @@ public class ToAndFromJsonMetaDataTests extends ESTestCase {
assertThat(indexMetaData.getAliases().get("alias1").filter().string(), equalTo(ALIAS_FILTER1));
assertThat(indexMetaData.getAliases().get("alias2").alias(), equalTo("alias2"));
assertThat(indexMetaData.getAliases().get("alias2").filter(), nullValue());
assertThat(indexMetaData.getAliases().get("alias2").writeIndex(),
equalTo(metaData.index("test12").getAliases().get("alias2").writeIndex()));
assertThat(indexMetaData.getAliases().get("alias4").alias(), equalTo("alias4"));
assertThat(indexMetaData.getAliases().get("alias4").filter().string(), equalTo(ALIAS_FILTER2));

View File

@ -1518,9 +1518,9 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
ensureGreen();
assertAcked(client.admin().indices().prepareAliases()
.addAlias("test-idx-1", "alias-1")
.addAlias("test-idx-2", "alias-2")
.addAlias("test-idx-3", "alias-3")
.addAlias("test-idx-1", "alias-1", false)
.addAlias("test-idx-2", "alias-2", false)
.addAlias("test-idx-3", "alias-3", false)
);
logger.info("--> indexing some data");

View File

@ -138,6 +138,10 @@ public final class RandomCreateIndexGenerator {
alias.filter("{\"term\":{\"year\":2016}}");
}
if (randomBoolean()) {
alias.writeIndex(randomBoolean());
}
return alias;
}
}