Skip to content

Commit

Permalink
Refactor AliasOrIndex abstraction. (elastic#53982)
Browse files Browse the repository at this point in the history
In order to prepare the `AliasOrIndex` abstraction for the introduction of data streams,
the abstraction needs to be made more flexible, because currently it really can be only
an alias or an index.

* Renamed `AliasOrIndex` to `IndexAbstraction`.
* Introduced a `IndexAbstraction.Type` enum to indicate what a `IndexAbstraction` instance is.
* Replaced the `isAlias()` method that returns a boolean with the `getType()` method that returns the new Type enum.
* Moved `getWriteIndex()` up from the `IndexAbstraction.Alias` to the `IndexAbstraction` interface.
* Moved `getAliasName()` up from the `IndexAbstraction.Alias` to the `IndexAbstraction` interface and renamed it to `getName()`.
* Removed unnecessary casting to `IndexAbstraction.Alias` by just checking the `getType()` method.

Relates to elastic#53100
  • Loading branch information
martijnvg committed Mar 30, 2020
1 parent 6e025c1 commit 627fcaf
Show file tree
Hide file tree
Showing 41 changed files with 346 additions and 292 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
package org.elasticsearch.example;

import org.elasticsearch.action.ActionListener;
import org.elasticsearch.cluster.metadata.AliasOrIndex;
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesRequest;
import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse;
import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse.Indices;
Expand Down Expand Up @@ -90,7 +90,7 @@ public void authorizeClusterAction(RequestInfo requestInfo, AuthorizationInfo au
@Override
public void authorizeIndexAction(RequestInfo requestInfo, AuthorizationInfo authorizationInfo,
AsyncSupplier<ResolvedIndices> indicesAsyncSupplier,
Map<String, AliasOrIndex> aliasOrIndexLookup,
Map<String, IndexAbstraction> aliasOrIndexLookup,
ActionListener<IndexAuthorizationResult> listener) {
if (isSuperuser(requestInfo.getAuthentication().getUser())) {
indicesAsyncSupplier.getAsync(ActionListener.wrap(resolvedIndices -> {
Expand All @@ -109,9 +109,9 @@ public void authorizeIndexAction(RequestInfo requestInfo, AuthorizationInfo auth

@Override
public void loadAuthorizedIndices(RequestInfo requestInfo, AuthorizationInfo authorizationInfo,
Map<String, AliasOrIndex> aliasOrIndexLookup, ActionListener<List<String>> listener) {
Map<String, IndexAbstraction> indicesLookup, ActionListener<List<String>> listener) {
if (isSuperuser(requestInfo.getAuthentication().getUser())) {
listener.onResponse(new ArrayList<>(aliasOrIndexLookup.keySet()));
listener.onResponse(new ArrayList<>(indicesLookup.keySet()));
} else {
listener.onResponse(Collections.emptyList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import org.elasticsearch.Version;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.cluster.metadata.AliasOrIndex;
import org.elasticsearch.cluster.metadata.AliasOrIndex.Index;
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.cluster.metadata.IndexAbstraction.Index;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.ESTestCase;
Expand Down Expand Up @@ -130,8 +130,8 @@ public void testAuthorizeClusterAction() {

public void testAuthorizeIndexAction() {
CustomAuthorizationEngine engine = new CustomAuthorizationEngine();
Map<String, AliasOrIndex> aliasOrIndexMap = new HashMap<>();
aliasOrIndexMap.put("index", new Index(IndexMetaData.builder("index")
Map<String, IndexAbstraction> indicesMap = new HashMap<>();
indicesMap.put("index", new Index(IndexMetaData.builder("index")
.settings(Settings.builder().put("index.version.created", Version.CURRENT))
.numberOfShards(1)
.numberOfReplicas(0)
Expand All @@ -148,7 +148,7 @@ public void testAuthorizeIndexAction() {
PlainActionFuture<IndexAuthorizationResult> resultFuture = new PlainActionFuture<>();
engine.authorizeIndexAction(requestInfo, authzInfo,
listener -> listener.onResponse(new ResolvedIndices(Collections.singletonList("index"), Collections.emptyList())),
aliasOrIndexMap, resultFuture);
indicesMap, resultFuture);
IndexAuthorizationResult result = resultFuture.actionGet();
assertThat(result.isGranted(), is(true));
assertThat(result.isAuditable(), is(true));
Expand All @@ -169,7 +169,7 @@ public void testAuthorizeIndexAction() {
PlainActionFuture<IndexAuthorizationResult> resultFuture = new PlainActionFuture<>();
engine.authorizeIndexAction(requestInfo, authzInfo,
listener -> listener.onResponse(new ResolvedIndices(Collections.singletonList("index"), Collections.emptyList())),
aliasOrIndexMap, resultFuture);
indicesMap, resultFuture);
IndexAuthorizationResult result = resultFuture.actionGet();
assertThat(result.isGranted(), is(false));
assertThat(result.isAuditable(), is(true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.AliasAction;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.cluster.metadata.AliasOrIndex;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.metadata.MetaDataCreateIndexService;
Expand Down Expand Up @@ -79,9 +79,9 @@ public RolloverResult rolloverClusterState(ClusterState currentState, String ali
boolean silent) throws Exception {
final MetaData metaData = currentState.metaData();
validate(metaData, aliasName);
final AliasOrIndex.Alias alias = (AliasOrIndex.Alias) metaData.getAliasAndIndexLookup().get(aliasName);
final IndexAbstraction alias = metaData.getIndicesLookup().get(aliasName);
final IndexMetaData indexMetaData = alias.getWriteIndex();
final AliasMetaData aliasMetaData = indexMetaData.getAliases().get(alias.getAliasName());
final AliasMetaData aliasMetaData = indexMetaData.getAliases().get(alias.getName());
final String sourceProvidedName = indexMetaData.getSettings().get(IndexMetaData.SETTING_INDEX_PROVIDED_NAME,
indexMetaData.getIndex().getName());
final String sourceIndexName = indexMetaData.getIndex().getName();
Expand Down Expand Up @@ -176,16 +176,16 @@ static void checkNoDuplicatedAliasInIndexTemplate(MetaData metaData, String roll
}

static void validate(MetaData metaData, String aliasName) {
final AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(aliasName);
if (aliasOrIndex == null) {
final IndexAbstraction indexAbstraction = metaData.getIndicesLookup().get(aliasName);
if (indexAbstraction == null) {
throw new IllegalArgumentException("source alias does not exist");
}
if (aliasOrIndex.isAlias() == false) {
throw new IllegalArgumentException("source alias is a concrete index");
if (indexAbstraction.getType() != IndexAbstraction.Type.ALIAS) {
throw new IllegalArgumentException("source alias is a [" + indexAbstraction.getType().getDisplayName() +
"], but an [" + IndexAbstraction.Type.ALIAS.getDisplayName() + "] was expected");
}
final AliasOrIndex.Alias alias = (AliasOrIndex.Alias) aliasOrIndex;
if (alias.getWriteIndex() == null) {
throw new IllegalArgumentException("source alias [" + alias.getAliasName() + "] does not point to a write index");
if (indexAbstraction.getWriteIndex() == null) {
throw new IllegalArgumentException("source alias [" + indexAbstraction.getName() + "] does not point to a write index");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
import org.elasticsearch.cluster.ClusterStateObserver;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.AliasOrIndex;
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
Expand Down Expand Up @@ -285,18 +285,16 @@ static boolean resolvePipelines(final DocWriteRequest<?> originalRequest, final
IndexMetaData indexMetaData = metaData.indices().get(originalRequest.index());
// check the alias for the index request (this is how normal index requests are modeled)
if (indexMetaData == null && indexRequest.index() != null) {
AliasOrIndex indexOrAlias = metaData.getAliasAndIndexLookup().get(indexRequest.index());
if (indexOrAlias != null && indexOrAlias.isAlias()) {
AliasOrIndex.Alias alias = (AliasOrIndex.Alias) indexOrAlias;
indexMetaData = alias.getWriteIndex();
IndexAbstraction indexAbstraction = metaData.getIndicesLookup().get(indexRequest.index());
if (indexAbstraction != null) {
indexMetaData = indexAbstraction.getWriteIndex();
}
}
// check the alias for the action request (this is how upserts are modeled)
if (indexMetaData == null && originalRequest.index() != null) {
AliasOrIndex indexOrAlias = metaData.getAliasAndIndexLookup().get(originalRequest.index());
if (indexOrAlias != null && indexOrAlias.isAlias()) {
AliasOrIndex.Alias alias = (AliasOrIndex.Alias) indexOrAlias;
indexMetaData = alias.getWriteIndex();
IndexAbstraction indexAbstraction = metaData.getIndicesLookup().get(originalRequest.index());
if (indexAbstraction != null) {
indexMetaData = indexAbstraction.getWriteIndex();
}
}
if (indexMetaData != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.cluster.metadata;

import org.apache.lucene.util.SetOnce;
Expand All @@ -25,7 +24,6 @@
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.Map;
Expand All @@ -35,30 +33,77 @@
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.
* An index abstraction is a reference to one or more concrete indices.
* An index abstraction has a unique name and encapsulates all the {@link IndexMetaData} instances it is pointing to.
* Also depending on type it may refer to a single or many concrete indices and may or may not have a write index.
*/
public interface AliasOrIndex {
public interface IndexAbstraction {

/**
* @return the type of the index abstraction
*/
Type getType();

/**
* @return whether this an alias or concrete index
* @return the name of the index abstraction
*/
boolean isAlias();
String getName();

/**
* @return All {@link IndexMetaData} of all concrete indices this alias is referring to
* or if this is a concrete index its {@link IndexMetaData}
* @return All {@link IndexMetaData} of all concrete indices this index abstraction is referring to.
*/
List<IndexMetaData> getIndices();

/**
* @return whether this alias/index is hidden or not
* A write index is a dedicated concrete index, that accepts all the new documents that belong to an index abstraction.
*
* A write index may also be a regular concrete index of a index abstraction and may therefore also be returned
* by {@link #getIndices()}. An index abstraction may also not have a dedicated write index.
*
* @return the write index of this index abstraction or
* <code>null</code> if this index abstraction doesn't have a write index.
*/
@Nullable
IndexMetaData getWriteIndex();

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

/**
* An index abstraction type.
*/
enum Type {

/**
* An index abstraction that refers to a single concrete index.
* This concrete index is also the write index.
*/
CONCRETE_INDEX("concrete index"),

/**
* An index abstraction that refers to an alias.
* An alias typically refers to many concrete indices and
* may have a write index.
*/
ALIAS("alias");

private final String displayName;

Type(String displayName) {
this.displayName = displayName;
}

public String getDisplayName() {
return displayName;
}
}

/**
* Represents an concrete index and encapsulates its {@link IndexMetaData}
*/
class Index implements AliasOrIndex {
class Index implements IndexAbstraction {

private final IndexMetaData concreteIndex;

Expand All @@ -67,13 +112,23 @@ public Index(IndexMetaData indexMetaData) {
}

@Override
public boolean isAlias() {
return false;
public String getName() {
return concreteIndex.getIndex().getName();
}

@Override
public Type getType() {
return Type.CONCRETE_INDEX;
}

@Override
public List<IndexMetaData> getIndices() {
return Collections.singletonList(concreteIndex);
return List.of(concreteIndex);
}

@Override
public IndexMetaData getWriteIndex() {
return concreteIndex;
}

@Override
Expand All @@ -85,7 +140,7 @@ public boolean isHidden() {
/**
* Represents an alias and groups all {@link IndexMetaData} instances sharing the same alias name together.
*/
class Alias implements AliasOrIndex {
class Alias implements IndexAbstraction {

private final String aliasName;
private final List<IndexMetaData> referenceIndexMetaDatas;
Expand All @@ -100,11 +155,11 @@ public Alias(AliasMetaData aliasMetaData, IndexMetaData indexMetaData) {
}

@Override
public boolean isAlias() {
return true;
public Type getType() {
return Type.ALIAS;
}

public String getAliasName() {
public String getName() {
return aliasName;
}

Expand All @@ -131,7 +186,7 @@ public boolean isHidden() {
* and filters)
*/
public Iterable<Tuple<String, AliasMetaData>> getConcreteIndexAndAliasMetaDatas() {
return () -> new Iterator<Tuple<String,AliasMetaData>>() {
return () -> new Iterator<>() {

int index = 0;

Expand Down
Loading

0 comments on commit 627fcaf

Please sign in to comment.