Search in sources :

Example 1 with NO_LONGER_ASSIGNED

use of org.opensearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED in project OpenSearch by opensearch-project.

the class MetadataMappingService method executeRefresh.

/**
 * Batch method to apply all the queued refresh operations. The idea is to try and batch as much
 * as possible so we won't create the same index all the time for example for the updates on the same mapping
 * and generate a single cluster change event out of all of those.
 */
ClusterState executeRefresh(final ClusterState currentState, final List<RefreshTask> allTasks) throws Exception {
    // break down to tasks per index, so we can optimize the on demand index service creation
    // to only happen for the duration of a single index processing of its respective events
    Map<String, List<RefreshTask>> tasksPerIndex = new HashMap<>();
    for (RefreshTask task : allTasks) {
        if (task.index == null) {
            logger.debug("ignoring a mapping task of type [{}] with a null index.", task);
        }
        tasksPerIndex.computeIfAbsent(task.index, k -> new ArrayList<>()).add(task);
    }
    boolean dirty = false;
    Metadata.Builder mdBuilder = Metadata.builder(currentState.metadata());
    for (Map.Entry<String, List<RefreshTask>> entry : tasksPerIndex.entrySet()) {
        IndexMetadata indexMetadata = mdBuilder.get(entry.getKey());
        if (indexMetadata == null) {
            // index got deleted on us, ignore...
            logger.debug("[{}] ignoring tasks - index meta data doesn't exist", entry.getKey());
            continue;
        }
        final Index index = indexMetadata.getIndex();
        // the tasks lists to iterate over, filled with the list of mapping tasks, trying to keep
        // the latest (based on order) update mapping one per node
        List<RefreshTask> allIndexTasks = entry.getValue();
        boolean hasTaskWithRightUUID = false;
        for (RefreshTask task : allIndexTasks) {
            if (indexMetadata.isSameUUID(task.indexUUID)) {
                hasTaskWithRightUUID = true;
            } else {
                logger.debug("{} ignoring task [{}] - index meta data doesn't match task uuid", index, task);
            }
        }
        if (hasTaskWithRightUUID == false) {
            continue;
        }
        // construct the actual index if needed, and make sure the relevant mappings are there
        boolean removeIndex = false;
        IndexService indexService = indicesService.indexService(indexMetadata.getIndex());
        if (indexService == null) {
            // we need to create the index here, and add the current mapping to it, so we can merge
            indexService = indicesService.createIndex(indexMetadata, Collections.emptyList(), false);
            removeIndex = true;
            indexService.mapperService().merge(indexMetadata, MergeReason.MAPPING_RECOVERY);
        }
        IndexMetadata.Builder builder = IndexMetadata.builder(indexMetadata);
        try {
            boolean indexDirty = refreshIndexMapping(indexService, builder);
            if (indexDirty) {
                mdBuilder.put(builder);
                dirty = true;
            }
        } finally {
            if (removeIndex) {
                indicesService.removeIndex(index, NO_LONGER_ASSIGNED, "created for mapping processing");
            }
        }
    }
    if (!dirty) {
        return currentState;
    }
    return ClusterState.builder(currentState).metadata(mdBuilder).build();
}
Also used : AckedClusterStateTaskListener(org.opensearch.cluster.AckedClusterStateTaskListener) NO_LONGER_ASSIGNED(org.opensearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED) CompressedXContent(org.opensearch.common.compress.CompressedXContent) Priority(org.opensearch.common.Priority) HashMap(java.util.HashMap) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) Strings(org.opensearch.common.Strings) ArrayList(java.util.ArrayList) ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) PutMappingClusterStateUpdateRequest(org.opensearch.action.admin.indices.mapping.put.PutMappingClusterStateUpdateRequest) MapperService(org.opensearch.index.mapper.MapperService) Map(java.util.Map) Inject(org.opensearch.common.inject.Inject) ClusterStateTaskConfig(org.opensearch.cluster.ClusterStateTaskConfig) ActionListener(org.opensearch.action.ActionListener) TimeValue(org.opensearch.common.unit.TimeValue) Index(org.opensearch.index.Index) IndicesService(org.opensearch.indices.IndicesService) ClusterStateTaskExecutor(org.opensearch.cluster.ClusterStateTaskExecutor) IOException(java.io.IOException) IndexService(org.opensearch.index.IndexService) Nullable(org.opensearch.common.Nullable) DocumentMapper(org.opensearch.index.mapper.DocumentMapper) IOUtils(org.opensearch.core.internal.io.IOUtils) List(java.util.List) Logger(org.apache.logging.log4j.Logger) MergeReason(org.opensearch.index.mapper.MapperService.MergeReason) ClusterService(org.opensearch.cluster.service.ClusterService) ClusterStateUpdateResponse(org.opensearch.cluster.ack.ClusterStateUpdateResponse) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) HashMap(java.util.HashMap) IndexService(org.opensearch.index.IndexService) ArrayList(java.util.ArrayList) Index(org.opensearch.index.Index) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with NO_LONGER_ASSIGNED

use of org.opensearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED in project OpenSearch by opensearch-project.

the class MetadataIndexAliasesService method applyAliasActions.

/**
 * Handles the cluster state transition to a version that reflects the provided {@link AliasAction}s.
 */
public ClusterState applyAliasActions(ClusterState currentState, Iterable<AliasAction> actions) {
    List<Index> indicesToClose = new ArrayList<>();
    Map<String, IndexService> indices = new HashMap<>();
    try {
        boolean changed = false;
        // Gather all the indexes that must be removed first so:
        // 1. We don't cause error when attempting to replace an index with a alias of the same name.
        // 2. We don't allow removal of aliases from indexes that we're just going to delete anyway. That'd be silly.
        Set<Index> indicesToDelete = new HashSet<>();
        for (AliasAction action : actions) {
            if (action.removeIndex()) {
                IndexMetadata index = currentState.metadata().getIndices().get(action.getIndex());
                if (index == null) {
                    throw new IndexNotFoundException(action.getIndex());
                }
                validateAliasTargetIsNotDSBackingIndex(currentState, action);
                indicesToDelete.add(index.getIndex());
                changed = true;
            }
        }
        // Remove the indexes if there are any to remove
        if (changed) {
            currentState = deleteIndexService.deleteIndices(currentState, indicesToDelete);
        }
        Metadata.Builder metadata = Metadata.builder(currentState.metadata());
        // Run the remaining alias actions
        final Set<String> maybeModifiedIndices = new HashSet<>();
        for (AliasAction action : actions) {
            if (action.removeIndex()) {
                // Handled above
                continue;
            }
            IndexMetadata index = metadata.get(action.getIndex());
            if (index == null) {
                throw new IndexNotFoundException(action.getIndex());
            }
            validateAliasTargetIsNotDSBackingIndex(currentState, action);
            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);
                aliasValidator.validateAlias(alias, action.getIndex(), indexRouting, indexLookup);
                if (Strings.hasLength(filter)) {
                    IndexService indexService = indices.get(index.getIndex().getName());
                    if (indexService == null) {
                        indexService = indicesService.indexService(index.getIndex());
                        if (indexService == null) {
                            // temporarily create the index and add mappings so we can parse the filter
                            try {
                                indexService = indicesService.createIndex(index, emptyList(), false);
                                indicesToClose.add(index.getIndex());
                            } catch (IOException e) {
                                throw new OpenSearchException("Failed to create temporary index for parsing the alias", e);
                            }
                            indexService.mapperService().merge(index, MapperService.MergeReason.MAPPING_RECOVERY);
                        }
                        indices.put(action.getIndex(), indexService);
                    }
                    // the context is only used for validation so it's fine to pass fake values for the shard id,
                    // but the current timestamp should be set to real value as we may use `now` in a filtered alias
                    aliasValidator.validateAliasFilter(alias, filter, indexService.newQueryShardContext(0, null, () -> System.currentTimeMillis(), null), xContentRegistry);
                }
            };
            if (action.apply(newAliasValidator, metadata, index)) {
                changed = true;
                maybeModifiedIndices.add(index.getIndex().getName());
            }
        }
        for (final String maybeModifiedIndex : maybeModifiedIndices) {
            final IndexMetadata currentIndexMetadata = currentState.metadata().index(maybeModifiedIndex);
            final IndexMetadata newIndexMetadata = metadata.get(maybeModifiedIndex);
            // only increment the aliases version if the aliases actually changed for this index
            if (currentIndexMetadata.getAliases().equals(newIndexMetadata.getAliases()) == false) {
                assert currentIndexMetadata.getAliasesVersion() == newIndexMetadata.getAliasesVersion();
                metadata.put(new IndexMetadata.Builder(newIndexMetadata).aliasesVersion(1 + currentIndexMetadata.getAliasesVersion()));
            }
        }
        if (changed) {
            ClusterState updatedState = ClusterState.builder(currentState).metadata(metadata).build();
            // i.e. remove and add the same alias to the same index
            if (!updatedState.metadata().equalsAliases(currentState.metadata())) {
                return updatedState;
            }
        }
        return currentState;
    } finally {
        for (Index index : indicesToClose) {
            indicesService.removeIndex(index, NO_LONGER_ASSIGNED, "created for alias processing");
        }
    }
}
Also used : NO_LONGER_ASSIGNED(org.opensearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED) Priority(org.opensearch.common.Priority) HashMap(java.util.HashMap) OpenSearchException(org.opensearch.OpenSearchException) Function(java.util.function.Function) Strings(org.opensearch.common.Strings) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ClusterState(org.opensearch.cluster.ClusterState) MapperService(org.opensearch.index.mapper.MapperService) Map(java.util.Map) AckedClusterStateUpdateTask(org.opensearch.cluster.AckedClusterStateUpdateTask) Inject(org.opensearch.common.inject.Inject) ActionListener(org.opensearch.action.ActionListener) Index(org.opensearch.index.Index) Collections.emptyList(java.util.Collections.emptyList) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) IndicesService(org.opensearch.indices.IndicesService) Set(java.util.Set) IOException(java.io.IOException) IndexService(org.opensearch.index.IndexService) List(java.util.List) NewAliasValidator(org.opensearch.cluster.metadata.AliasAction.NewAliasValidator) NamedXContentRegistry(org.opensearch.common.xcontent.NamedXContentRegistry) ClusterService(org.opensearch.cluster.service.ClusterService) IndicesAliasesClusterStateUpdateRequest(org.opensearch.action.admin.indices.alias.IndicesAliasesClusterStateUpdateRequest) ClusterStateUpdateResponse(org.opensearch.cluster.ack.ClusterStateUpdateResponse) ClusterState(org.opensearch.cluster.ClusterState) IndexService(org.opensearch.index.IndexService) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Index(org.opensearch.index.Index) IOException(java.io.IOException) NewAliasValidator(org.opensearch.cluster.metadata.AliasAction.NewAliasValidator) Function(java.util.function.Function) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) OpenSearchException(org.opensearch.OpenSearchException) HashSet(java.util.HashSet)

Aggregations

IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 ActionListener (org.opensearch.action.ActionListener)2 ClusterState (org.opensearch.cluster.ClusterState)2 ClusterStateUpdateResponse (org.opensearch.cluster.ack.ClusterStateUpdateResponse)2 ClusterService (org.opensearch.cluster.service.ClusterService)2 Priority (org.opensearch.common.Priority)2 Strings (org.opensearch.common.Strings)2 Inject (org.opensearch.common.inject.Inject)2 Index (org.opensearch.index.Index)2 IndexService (org.opensearch.index.IndexService)2 MapperService (org.opensearch.index.mapper.MapperService)2 IndicesService (org.opensearch.indices.IndicesService)2 NO_LONGER_ASSIGNED (org.opensearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED)2 Collections (java.util.Collections)1 Collections.emptyList (java.util.Collections.emptyList)1 HashSet (java.util.HashSet)1