/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ package org.opensearch.cluster.metadata; import org.opensearch.Version; import org.opensearch.cluster.ClusterName; import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.service.ClusterService; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.set.Sets; import org.opensearch.core.index.Index; import org.opensearch.index.IndexNotFoundException; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.test.VersionUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import static java.util.Collections.singletonList; import static org.opensearch.cluster.DataStreamTestHelper.createTimestampField; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anySet; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class MetadataIndexAliasesServiceTests extends OpenSearchTestCase { private final AliasValidator aliasValidator = new AliasValidator(); private final MetadataDeleteIndexService deleteIndexService = mock(MetadataDeleteIndexService.class); private final MetadataIndexAliasesService service = new MetadataIndexAliasesService( mock(ClusterService.class), null, aliasValidator, deleteIndexService, xContentRegistry() ); public MetadataIndexAliasesServiceTests() { // Mock any deletes so we don't need to worry about how MetadataDeleteIndexService does its job when(deleteIndexService.deleteIndices(any(ClusterState.class), anySet())).then(i -> { ClusterState state = (ClusterState) i.getArguments()[0]; @SuppressWarnings("unchecked") Collection indices = (Collection) i.getArguments()[1]; Metadata.Builder meta = Metadata.builder(state.metadata()); for (Index index : indices) { assertTrue("index now found", state.metadata().hasConcreteIndex(index.getName())); meta.remove(index.getName()); // We only think about metadata for this test. Not routing or any other fun stuff. } return ClusterState.builder(state).metadata(meta).build(); }); } public void testAddAndRemove() { // Create a state with a single index String index = randomAlphaOfLength(5); ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), index); // Add an alias to it ClusterState after = service.applyAliasActions( before, singletonList(new AliasAction.Add(index, "test", null, null, null, null, null)) ); IndexAbstraction alias = after.metadata().getIndicesLookup().get("test"); assertNotNull(alias); assertThat(alias.getType(), equalTo(IndexAbstraction.Type.ALIAS)); assertThat(alias.getIndices(), contains(after.metadata().index(index))); assertAliasesVersionIncreased(index, before, after); // Remove the alias from it while adding another one before = after; after = service.applyAliasActions( before, Arrays.asList(new AliasAction.Remove(index, "test", null), new AliasAction.Add(index, "test_2", null, null, null, null, null)) ); assertNull(after.metadata().getIndicesLookup().get("test")); alias = after.metadata().getIndicesLookup().get("test_2"); assertNotNull(alias); assertThat(alias.getType(), equalTo(IndexAbstraction.Type.ALIAS)); assertThat(alias.getIndices(), contains(after.metadata().index(index))); assertAliasesVersionIncreased(index, before, after); // Now just remove on its own before = after; after = service.applyAliasActions(before, singletonList(new AliasAction.Remove(index, "test_2", randomBoolean()))); assertNull(after.metadata().getIndicesLookup().get("test")); assertNull(after.metadata().getIndicesLookup().get("test_2")); assertAliasesVersionIncreased(index, before, after); } public void testMustExist() { // Create a state with a single index String index = randomAlphaOfLength(5); ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), index); // Add an alias to it ClusterState after = service.applyAliasActions( before, singletonList(new AliasAction.Add(index, "test", null, null, null, null, null)) ); IndexAbstraction alias = after.metadata().getIndicesLookup().get("test"); assertNotNull(alias); assertThat(alias.getType(), equalTo(IndexAbstraction.Type.ALIAS)); assertThat(alias.getIndices(), contains(after.metadata().index(index))); assertAliasesVersionIncreased(index, before, after); // Remove the alias from it with mustExist == true while adding another one before = after; after = service.applyAliasActions( before, Arrays.asList(new AliasAction.Remove(index, "test", true), new AliasAction.Add(index, "test_2", null, null, null, null, null)) ); assertNull(after.metadata().getIndicesLookup().get("test")); alias = after.metadata().getIndicesLookup().get("test_2"); assertNotNull(alias); assertThat(alias.getType(), equalTo(IndexAbstraction.Type.ALIAS)); assertThat(alias.getIndices(), contains(after.metadata().index(index))); assertAliasesVersionIncreased(index, before, after); // Now just remove on its own before = after; after = service.applyAliasActions(before, singletonList(new AliasAction.Remove(index, "test_2", randomBoolean()))); assertNull(after.metadata().getIndicesLookup().get("test")); assertNull(after.metadata().getIndicesLookup().get("test_2")); assertAliasesVersionIncreased(index, before, after); // Show that removing non-existing alias with mustExist == true fails final ClusterState finalCS = after; final IllegalArgumentException iae = expectThrows( IllegalArgumentException.class, () -> service.applyAliasActions(finalCS, singletonList(new AliasAction.Remove(index, "test_2", true))) ); assertThat(iae.getMessage(), containsString("required alias [test_2] does not exist")); } public void testMultipleIndices() { final int length = randomIntBetween(2, 8); final Set indices = new HashSet<>(length); ClusterState before = ClusterState.builder(ClusterName.DEFAULT).build(); final List addActions = new ArrayList<>(length); for (int i = 0; i < length; i++) { final String index = randomValueOtherThanMany(v -> indices.add(v) == false, () -> randomAlphaOfLength(8)); before = createIndex(before, index); addActions.add(new AliasAction.Add(index, "alias-" + index, null, null, null, null, null)); } final ClusterState afterAddingAliasesToAll = service.applyAliasActions(before, addActions); assertAliasesVersionIncreased(indices.toArray(new String[0]), before, afterAddingAliasesToAll); // now add some aliases randomly final Set randomIndices = new HashSet<>(length); final List randomAddActions = new ArrayList<>(length); for (String index : indices) { if (randomBoolean()) { randomAddActions.add(new AliasAction.Add(index, "random-alias-" + index, null, null, null, null, null)); randomIndices.add(index); } } final ClusterState afterAddingRandomAliases = service.applyAliasActions(afterAddingAliasesToAll, randomAddActions); assertAliasesVersionIncreased(randomIndices.toArray(new String[0]), afterAddingAliasesToAll, afterAddingRandomAliases); assertAliasesVersionUnchanged( Sets.difference(indices, randomIndices).toArray(new String[0]), afterAddingAliasesToAll, afterAddingRandomAliases ); } public void testChangingWriteAliasStateIncreasesAliasesVersion() { final String index = randomAlphaOfLength(8); final ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), index); final ClusterState afterAddWriteAlias = service.applyAliasActions( before, singletonList(new AliasAction.Add(index, "test", null, null, null, true, null)) ); assertAliasesVersionIncreased(index, before, afterAddWriteAlias); final ClusterState afterChangeWriteAliasToNonWriteAlias = service.applyAliasActions( afterAddWriteAlias, singletonList(new AliasAction.Add(index, "test", null, null, null, false, null)) ); assertAliasesVersionIncreased(index, afterAddWriteAlias, afterChangeWriteAliasToNonWriteAlias); final ClusterState afterChangeNonWriteAliasToWriteAlias = service.applyAliasActions( afterChangeWriteAliasToNonWriteAlias, singletonList(new AliasAction.Add(index, "test", null, null, null, true, null)) ); assertAliasesVersionIncreased(index, afterChangeWriteAliasToNonWriteAlias, afterChangeNonWriteAliasToWriteAlias); } public void testAddingAliasMoreThanOnceShouldOnlyIncreaseAliasesVersionByOne() { final String index = randomAlphaOfLength(8); final ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), index); // add an alias to the index multiple times final int length = randomIntBetween(2, 8); final List addActions = new ArrayList<>(length); for (int i = 0; i < length; i++) { addActions.add(new AliasAction.Add(index, "test", null, null, null, null, null)); } final ClusterState afterAddingAliases = service.applyAliasActions(before, addActions); assertAliasesVersionIncreased(index, before, afterAddingAliases); } public void testAliasesVersionUnchangedWhenActionsAreIdempotent() { final String index = randomAlphaOfLength(8); final ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), index); // add some aliases to the index final int length = randomIntBetween(1, 8); final Set aliasNames = new HashSet<>(); final List addActions = new ArrayList<>(length); for (int i = 0; i < length; i++) { final String aliasName = randomValueOtherThanMany(v -> aliasNames.add(v) == false, () -> randomAlphaOfLength(8)); addActions.add(new AliasAction.Add(index, aliasName, null, null, null, null, null)); } final ClusterState afterAddingAlias = service.applyAliasActions(before, addActions); // now perform a remove and add for each alias which is idempotent, the resulting aliases are unchanged final List removeAndAddActions = new ArrayList<>(2 * length); for (final String aliasName : aliasNames) { removeAndAddActions.add(new AliasAction.Remove(index, aliasName, null)); removeAndAddActions.add(new AliasAction.Add(index, aliasName, null, null, null, null, null)); } final ClusterState afterRemoveAndAddAlias = service.applyAliasActions(afterAddingAlias, removeAndAddActions); assertAliasesVersionUnchanged(index, afterAddingAlias, afterRemoveAndAddAlias); } public void testSwapIndexWithAlias() { // Create "test" and "test_2" ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), "test"); before = createIndex(before, "test_2"); // Now remove "test" and add an alias to "test" to "test_2" in one go ClusterState after = service.applyAliasActions( before, Arrays.asList(new AliasAction.Add("test_2", "test", null, null, null, null, null), new AliasAction.RemoveIndex("test")) ); IndexAbstraction alias = after.metadata().getIndicesLookup().get("test"); assertNotNull(alias); assertThat(alias.getType(), equalTo(IndexAbstraction.Type.ALIAS)); assertThat(alias.getIndices(), contains(after.metadata().index("test_2"))); assertAliasesVersionIncreased("test_2", before, after); } public void testAddAliasToRemovedIndex() { // Create "test" ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), "test"); // Attempt to add an alias to "test" at the same time as we remove it IndexNotFoundException e = expectThrows( IndexNotFoundException.class, () -> service.applyAliasActions( before, Arrays.asList(new AliasAction.Add("test", "alias", null, null, null, null, null), new AliasAction.RemoveIndex("test")) ) ); assertEquals("test", e.getIndex().getName()); } public void testRemoveIndexTwice() { // Create "test" ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), "test"); // Try to remove an index twice. This should just remove the index once.... ClusterState after = service.applyAliasActions( before, Arrays.asList(new AliasAction.RemoveIndex("test"), new AliasAction.RemoveIndex("test")) ); assertNull(after.metadata().getIndicesLookup().get("test")); } public void testAddWriteOnlyWithNoExistingAliases() { ClusterState before = createIndex(ClusterState.builder(ClusterName.DEFAULT).build(), "test"); ClusterState after = service.applyAliasActions( before, Arrays.asList(new AliasAction.Add("test", "alias", null, null, null, false, null)) ); assertFalse(after.metadata().index("test").getAliases().get("alias").writeIndex()); assertNull(after.metadata().getIndicesLookup().get("alias").getWriteIndex()); assertAliasesVersionIncreased("test", before, after); after = service.applyAliasActions(before, Arrays.asList(new AliasAction.Add("test", "alias", null, null, null, null, null))); assertNull(after.metadata().index("test").getAliases().get("alias").writeIndex()); assertThat(after.metadata().getIndicesLookup().get("alias").getWriteIndex(), equalTo(after.metadata().index("test"))); assertAliasesVersionIncreased("test", before, after); after = service.applyAliasActions(before, Arrays.asList(new AliasAction.Add("test", "alias", null, null, null, true, null))); assertTrue(after.metadata().index("test").getAliases().get("alias").writeIndex()); assertThat(after.metadata().getIndicesLookup().get("alias").getWriteIndex(), equalTo(after.metadata().index("test"))); assertAliasesVersionIncreased("test", before, after); } 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.applyAliasActions( before, Arrays.asList(new AliasAction.Add("test", "alias", null, null, null, null, null)) ); assertNull(after.metadata().index("test").getAliases().get("alias").writeIndex()); assertThat(after.metadata().getIndicesLookup().get("alias").getWriteIndex(), equalTo(after.metadata().index("test2"))); assertAliasesVersionIncreased("test", before, after); assertAliasesVersionUnchanged("test2", before, after); Exception exception = expectThrows( IllegalStateException.class, () -> service.applyAliasActions(before, Arrays.asList(new AliasAction.Add("test", "alias", null, null, null, true, null))) ); 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 swapActions = Arrays.asList( new AliasAction.Add("test", "alias", null, null, null, unsetValue, null), new AliasAction.Add("test2", "alias", null, null, null, true, null) ); Collections.shuffle(swapActions, random()); ClusterState after = service.applyAliasActions(before, swapActions); assertThat(after.metadata().index("test").getAliases().get("alias").writeIndex(), equalTo(unsetValue)); assertTrue(after.metadata().index("test2").getAliases().get("alias").writeIndex()); assertThat(after.metadata().getIndicesLookup().get("alias").getWriteIndex(), equalTo(after.metadata().index("test2"))); assertAliasesVersionIncreased("test", before, after); assertAliasesVersionIncreased("test2", before, after); } 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(before.metadata().getIndicesLookup().get("alias").getWriteIndex()); ClusterState after = service.applyAliasActions( before, Arrays.asList(new AliasAction.Add("test3", "alias", null, null, null, true, null)) ); assertTrue(after.metadata().index("test3").getAliases().get("alias").writeIndex()); assertThat(after.metadata().getIndicesLookup().get("alias").getWriteIndex(), equalTo(after.metadata().index("test3"))); assertAliasesVersionUnchanged("test", before, after); assertAliasesVersionUnchanged("test2", before, after); assertAliasesVersionIncreased("test3", before, after); } 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(before.metadata().getIndicesLookup().get("alias").getWriteIndex()); ClusterState after = service.applyAliasActions(before, Collections.singletonList(new AliasAction.RemoveIndex("test"))); assertNull(after.metadata().index("test2").getAliases().get("alias").writeIndex()); assertThat(after.metadata().getIndicesLookup().get("alias").getWriteIndex(), equalTo(after.metadata().index("test2"))); assertAliasesVersionUnchanged("test2", before, after); } 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.applyAliasActions( before, Arrays.asList( new AliasAction.Add("test", "alias", null, null, null, true, null), new AliasAction.Add("test2", "alias", null, null, null, true, null) ) ) ); assertThat(exception.getMessage(), startsWith("alias [alias] has more than one write index [")); } public void testHiddenPropertyValidation() { ClusterState originalState = ClusterState.EMPTY_STATE; originalState = createIndex(originalState, "test1"); originalState = createIndex(originalState, "test2"); { // Add a non-hidden alias to one index ClusterState testState = service.applyAliasActions( originalState, Collections.singletonList(new AliasAction.Add("test1", "alias", null, null, null, null, randomFrom(false, null))) ); // Adding the same alias as hidden to another index should throw Exception ex = expectThrows(IllegalStateException.class, () -> // Add a non-hidden alias to one index service.applyAliasActions( testState, Collections.singletonList(new AliasAction.Add("test2", "alias", null, null, null, null, true)) )); assertThat(ex.getMessage(), containsString("alias [alias] has is_hidden set to true on indices")); } { // Add a hidden alias to one index ClusterState testState = service.applyAliasActions( originalState, Collections.singletonList(new AliasAction.Add("test1", "alias", null, null, null, null, true)) ); // Adding the same alias as non-hidden to another index should throw Exception ex = expectThrows(IllegalStateException.class, () -> // Add a non-hidden alias to one index service.applyAliasActions( testState, Collections.singletonList(new AliasAction.Add("test2", "alias", null, null, null, null, randomFrom(false, null))) )); assertThat(ex.getMessage(), containsString("alias [alias] has is_hidden set to true on indices")); } { // Add a non-hidden alias to one index ClusterState testState = service.applyAliasActions( originalState, Collections.singletonList(new AliasAction.Add("test1", "alias", null, null, null, null, randomFrom(false, null))) ); // Adding the same alias as non-hidden should be OK service.applyAliasActions( testState, Collections.singletonList(new AliasAction.Add("test2", "alias", null, null, null, null, randomFrom(false, null))) ); } { // Add a hidden alias to one index ClusterState testState = service.applyAliasActions( originalState, Collections.singletonList(new AliasAction.Add("test1", "alias", null, null, null, null, true)) ); // Adding the same alias as hidden should be OK service.applyAliasActions( testState, Collections.singletonList(new AliasAction.Add("test2", "alias", null, null, null, null, true)) ); } } public void testSimultaneousHiddenPropertyValidation() { 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(); { // These should all be fine applyHiddenAliasMix(before, null, null); applyHiddenAliasMix(before, false, false); applyHiddenAliasMix(before, false, null); applyHiddenAliasMix(before, null, false); applyHiddenAliasMix(before, true, true); } { Exception exception = expectThrows( IllegalStateException.class, () -> applyHiddenAliasMix(before, true, randomFrom(false, null)) ); assertThat(exception.getMessage(), startsWith("alias [alias] has is_hidden set to true on indices [")); } { Exception exception = expectThrows( IllegalStateException.class, () -> applyHiddenAliasMix(before, randomFrom(false, null), true) ); assertThat(exception.getMessage(), startsWith("alias [alias] has is_hidden set to true on indices [")); } } public void testAliasesForDataStreamBackingIndicesNotSupported() { String dataStreamName = "foo-stream"; String backingIndexName = DataStream.getDefaultBackingIndexName(dataStreamName, 1); IndexMetadata indexMetadata = IndexMetadata.builder(backingIndexName) .settings(settings(Version.CURRENT)) .numberOfShards(1) .numberOfReplicas(1) .build(); ClusterState state = ClusterState.builder(ClusterName.DEFAULT) .metadata( Metadata.builder() .put(indexMetadata, true) .put(new DataStream(dataStreamName, createTimestampField("@timestamp"), singletonList(indexMetadata.getIndex()))) ) .build(); IllegalArgumentException exception = expectThrows( IllegalArgumentException.class, () -> service.applyAliasActions( state, singletonList(new AliasAction.Add(backingIndexName, "test", null, null, null, null, null)) ) ); assertThat( exception.getMessage(), is( "The provided index [ .ds-foo-stream-000001] is a backing index belonging to data stream " + "[foo-stream]. Data streams and their backing indices don't support alias operations." ) ); } private ClusterState applyHiddenAliasMix(ClusterState before, Boolean isHidden1, Boolean isHidden2) { return service.applyAliasActions( before, Arrays.asList( new AliasAction.Add("test", "alias", null, null, null, null, isHidden1), new AliasAction.Add("test2", "alias", null, null, null, null, isHidden2) ) ); } private ClusterState createIndex(ClusterState state, String index) { IndexMetadata indexMetadata = IndexMetadata.builder(index) .settings(Settings.builder().put("index.version.created", VersionUtils.randomVersion(random()))) .numberOfShards(1) .numberOfReplicas(1) .build(); return ClusterState.builder(state).metadata(Metadata.builder(state.metadata()).put(indexMetadata, false)).build(); } private void assertAliasesVersionUnchanged(final String index, final ClusterState before, final ClusterState after) { assertAliasesVersionUnchanged(new String[] { index }, before, after); } private void assertAliasesVersionUnchanged(final String[] indices, final ClusterState before, final ClusterState after) { for (final String index : indices) { final long expected = before.metadata().index(index).getAliasesVersion(); final long actual = after.metadata().index(index).getAliasesVersion(); assertThat("index metadata aliases version mismatch", actual, equalTo(expected)); } } private void assertAliasesVersionIncreased(final String index, final ClusterState before, final ClusterState after) { assertAliasesVersionIncreased(new String[] { index }, before, after); } private void assertAliasesVersionIncreased(final String[] indices, final ClusterState before, final ClusterState after) { for (final String index : indices) { final long expected = 1 + before.metadata().index(index).getAliasesVersion(); final long actual = after.metadata().index(index).getAliasesVersion(); assertThat("index metadata aliases version mismatch", actual, equalTo(expected)); } } }