All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elasticsearch.cluster.metadata.IndexAbstraction Maven / Gradle / Ivy

/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */
package org.elasticsearch.cluster.metadata;

import org.elasticsearch.common.Strings;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.index.Index;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 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 IndexAbstraction {

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

    /**
     * @return the name of the index abstraction
     */
    String getName();

    /**
     * @return All {@link IndexMetadata} of all concrete indices this index abstraction is referring to.
     */
    List getIndices();

    /**
     * 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 * null if this index abstraction doesn't have a write index. */ @Nullable Index getWriteIndex(); /** * @return the data stream to which this index belongs or null if this is not a concrete index or * if it is a concrete index that does not belong to a data stream. */ @Nullable DataStream getParentDataStream(); /** * @return whether this index abstraction is hidden or not */ boolean isHidden(); /** * @return whether this index abstraction should be treated as a system index or not */ boolean isSystem(); /** * @return whether this index abstraction is related to data streams */ default boolean isDataStreamRelated() { return false; } /** * @return the names of aliases referring to this instance. * Returns null if aliases can't point to this instance. */ @Nullable List getAliases(); /** * 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"), /** * An index abstraction that refers to a data stream. * A data stream typically has multiple backing indices, the latest of which * is the target for index requests. */ DATA_STREAM("data_stream"); 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 ConcreteIndex implements IndexAbstraction { private final Index concreteIndexName; private final boolean isHidden; private final boolean isSystem; private final List aliases; private final DataStream dataStream; public ConcreteIndex(IndexMetadata indexMetadata, DataStream dataStream) { this.concreteIndexName = indexMetadata.getIndex(); this.isHidden = indexMetadata.isHidden(); this.isSystem = indexMetadata.isSystem(); this.aliases = indexMetadata.getAliases() != null ? Arrays.asList(indexMetadata.getAliases().keys().toArray(String.class)) : null; this.dataStream = dataStream; } public ConcreteIndex(IndexMetadata indexMetadata) { this(indexMetadata, null); } @Override public String getName() { return concreteIndexName.getName(); } @Override public Type getType() { return Type.CONCRETE_INDEX; } @Override public List getIndices() { return Collections.singletonList(concreteIndexName); } @Override public Index getWriteIndex() { return concreteIndexName; } @Override public DataStream getParentDataStream() { return dataStream; } @Override public boolean isHidden() { return isHidden; } @Override public boolean isSystem() { return isSystem; } @Override public List getAliases() { return aliases; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ConcreteIndex that = (ConcreteIndex) o; return isHidden == that.isHidden && isSystem == that.isSystem && concreteIndexName.equals(that.concreteIndexName) && Objects.equals(aliases, that.aliases) && Objects.equals(dataStream, that.dataStream); } @Override public int hashCode() { return Objects.hash(concreteIndexName, isHidden, isSystem, aliases, dataStream); } } /** * Represents an alias and groups all {@link IndexMetadata} instances sharing the same alias name together. */ class Alias implements IndexAbstraction { private final String aliasName; private final List referenceIndexMetadatas; private final Index writeIndex; private final boolean isHidden; private final boolean isSystem; private final boolean dataStreamAlias; public Alias(AliasMetadata aliasMetadata, List indices) { this.aliasName = aliasMetadata.getAlias(); this.referenceIndexMetadatas = new ArrayList<>(indices.size()); for (IndexMetadata imd : indices) { this.referenceIndexMetadatas.add(imd.getIndex()); } List writeIndices = indices.stream() .filter(idxMeta -> Boolean.TRUE.equals(idxMeta.getAliases().get(aliasName).writeIndex())) .collect(Collectors.toList()); if (writeIndices.isEmpty() && indices.size() == 1 && indices.get(0).getAliases().get(aliasName).writeIndex() == null) { writeIndices.add(indices.get(0)); } if (writeIndices.size() == 0) { this.writeIndex = null; } else if (writeIndices.size() == 1) { this.writeIndex = writeIndices.get(0).getIndex(); } else { List 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) + "]" ); } this.isHidden = aliasMetadata.isHidden() == null ? false : aliasMetadata.isHidden(); this.isSystem = indices.stream().allMatch(IndexMetadata::isSystem); dataStreamAlias = false; validateAliasProperties(indices); } public Alias(DataStreamAlias dataStreamAlias, List indicesOfAllDataStreams, Index writeIndexOfWriteDataStream) { this.aliasName = dataStreamAlias.getName(); this.referenceIndexMetadatas = indicesOfAllDataStreams; this.writeIndex = writeIndexOfWriteDataStream; this.isHidden = false; this.isSystem = false; this.dataStreamAlias = true; } @Override public Type getType() { return Type.ALIAS; } public String getName() { return aliasName; } @Override public List getIndices() { return referenceIndexMetadatas; } @Nullable public Index getWriteIndex() { return writeIndex; } @Override public DataStream getParentDataStream() { // aliases may not be part of a data stream return null; } @Override public boolean isHidden() { return isHidden; } @Override public boolean isSystem() { return isSystem; } @Override public boolean isDataStreamRelated() { return dataStreamAlias; } @Override public List getAliases() { return null; } private void validateAliasProperties(List referenceIndexMetadatas) { // Validate hidden status final Map> groupedByHiddenStatus = referenceIndexMetadatas.stream() .collect(Collectors.groupingBy(idxMeta -> Boolean.TRUE.equals(idxMeta.getAliases().get(aliasName).isHidden()))); if (isNonEmpty(groupedByHiddenStatus.get(true)) && isNonEmpty(groupedByHiddenStatus.get(false))) { List hiddenOn = groupedByHiddenStatus.get(true) .stream() .map(idx -> idx.getIndex().getName()) .collect(Collectors.toList()); List nonHiddenOn = groupedByHiddenStatus.get(false) .stream() .map(idx -> idx.getIndex().getName()) .collect(Collectors.toList()); throw new IllegalStateException( "alias [" + aliasName + "] has is_hidden set to true on indices [" + Strings.collectionToCommaDelimitedString(hiddenOn) + "] but does not have is_hidden set to true on indices [" + Strings.collectionToCommaDelimitedString(nonHiddenOn) + "]; alias must have the same is_hidden setting " + "on all indices" ); } } private boolean isNonEmpty(List idxMetas) { return (Objects.isNull(idxMetas) || idxMetas.isEmpty()) == false; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Alias alias = (Alias) o; return isHidden == alias.isHidden && isSystem == alias.isSystem && dataStreamAlias == alias.dataStreamAlias && aliasName.equals(alias.aliasName) && referenceIndexMetadatas.equals(alias.referenceIndexMetadatas) && Objects.equals(writeIndex, alias.writeIndex); } @Override public int hashCode() { return Objects.hash(aliasName, referenceIndexMetadatas, writeIndex, isHidden, isSystem, dataStreamAlias); } } class DataStream implements IndexAbstraction { private final org.elasticsearch.cluster.metadata.DataStream dataStream; private final List referencedByDataStreamAliases; public DataStream(org.elasticsearch.cluster.metadata.DataStream dataStream, List aliases) { this.dataStream = dataStream; this.referencedByDataStreamAliases = aliases; } @Override public String getName() { return dataStream.getName(); } @Override public Type getType() { return Type.DATA_STREAM; } @Override public List getIndices() { return dataStream.getIndices(); } public Index getWriteIndex() { return dataStream.getWriteIndex(); } @Override public DataStream getParentDataStream() { // a data stream cannot have a parent data stream return null; } @Override public boolean isHidden() { return dataStream.isHidden(); } @Override public boolean isSystem() { return dataStream.isSystem(); } @Override public boolean isDataStreamRelated() { return true; } @Override public List getAliases() { return referencedByDataStreamAliases; } public org.elasticsearch.cluster.metadata.DataStream getDataStream() { return dataStream; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DataStream that = (DataStream) o; return dataStream.equals(that.dataStream) && Objects.equals(referencedByDataStreamAliases, that.referencedByDataStreamAliases); } @Override public int hashCode() { return Objects.hash(dataStream, referencedByDataStreamAliases); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy