Search in sources :

Example 1 with NewAliasValidator

use of org.elasticsearch.cluster.metadata.AliasAction.NewAliasValidator in project elasticsearch by elastic.

the class MetaDataIndexAliasesService method innerExecute.

ClusterState innerExecute(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());
                }
                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
        for (AliasAction action : actions) {
            if (action.removeIndex()) {
                // Handled above
                continue;
            }
            IndexMetaData index = metadata.get(action.getIndex());
            if (index == null) {
                throw new IndexNotFoundException(action.getIndex());
            }
            NewAliasValidator newAliasValidator = (alias, indexRouting, filter) -> {
                /* 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());
                    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(), shardId -> {
                                });
                                indicesToClose.add(index.getIndex());
                            } catch (IOException e) {
                                throw new ElasticsearchException("Failed to create temporary index for parsing the alias", e);
                            }
                            indexService.mapperService().merge(index, MapperService.MergeReason.MAPPING_RECOVERY, false);
                        }
                        indices.put(action.getIndex(), indexService);
                    }
                    // the context is only used for validation so it's fine to pass fake values for the shard id and the current
                    // timestamp
                    aliasValidator.validateAliasFilter(alias, filter, indexService.newQueryShardContext(0, null, () -> 0L), xContentRegistry);
                }
            };
            changed |= action.apply(newAliasValidator, metadata, index);
        }
        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 : ElasticsearchException(org.elasticsearch.ElasticsearchException) AckedClusterStateUpdateTask(org.elasticsearch.cluster.AckedClusterStateUpdateTask) ClusterService(org.elasticsearch.cluster.service.ClusterService) HashMap(java.util.HashMap) Index(org.elasticsearch.index.Index) Function(java.util.function.Function) Strings(org.elasticsearch.common.Strings) Inject(org.elasticsearch.common.inject.Inject) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ClusterState(org.elasticsearch.cluster.ClusterState) Settings(org.elasticsearch.common.settings.Settings) IndexNotFoundException(org.elasticsearch.index.IndexNotFoundException) Map(java.util.Map) IndicesService(org.elasticsearch.indices.IndicesService) NamedXContentRegistry(org.elasticsearch.common.xcontent.NamedXContentRegistry) Priority(org.elasticsearch.common.Priority) AbstractComponent(org.elasticsearch.common.component.AbstractComponent) Collections.emptyList(java.util.Collections.emptyList) IndexService(org.elasticsearch.index.IndexService) Set(java.util.Set) IOException(java.io.IOException) ObjectCursor(com.carrotsearch.hppc.cursors.ObjectCursor) MapperService(org.elasticsearch.index.mapper.MapperService) List(java.util.List) IndicesAliasesClusterStateUpdateRequest(org.elasticsearch.action.admin.indices.alias.IndicesAliasesClusterStateUpdateRequest) ClusterStateUpdateResponse(org.elasticsearch.cluster.ack.ClusterStateUpdateResponse) NO_LONGER_ASSIGNED(org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED) ActionListener(org.elasticsearch.action.ActionListener) NewAliasValidator(org.elasticsearch.cluster.metadata.AliasAction.NewAliasValidator) ClusterState(org.elasticsearch.cluster.ClusterState) HashMap(java.util.HashMap) IndexService(org.elasticsearch.index.IndexService) ArrayList(java.util.ArrayList) Index(org.elasticsearch.index.Index) IOException(java.io.IOException) ElasticsearchException(org.elasticsearch.ElasticsearchException) NewAliasValidator(org.elasticsearch.cluster.metadata.AliasAction.NewAliasValidator) Function(java.util.function.Function) IndexNotFoundException(org.elasticsearch.index.IndexNotFoundException) HashSet(java.util.HashSet)

Aggregations

ObjectCursor (com.carrotsearch.hppc.cursors.ObjectCursor)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Collections.emptyList (java.util.Collections.emptyList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 Function (java.util.function.Function)1 ElasticsearchException (org.elasticsearch.ElasticsearchException)1 ActionListener (org.elasticsearch.action.ActionListener)1 IndicesAliasesClusterStateUpdateRequest (org.elasticsearch.action.admin.indices.alias.IndicesAliasesClusterStateUpdateRequest)1 AckedClusterStateUpdateTask (org.elasticsearch.cluster.AckedClusterStateUpdateTask)1 ClusterState (org.elasticsearch.cluster.ClusterState)1 ClusterStateUpdateResponse (org.elasticsearch.cluster.ack.ClusterStateUpdateResponse)1 NewAliasValidator (org.elasticsearch.cluster.metadata.AliasAction.NewAliasValidator)1 ClusterService (org.elasticsearch.cluster.service.ClusterService)1 Priority (org.elasticsearch.common.Priority)1 Strings (org.elasticsearch.common.Strings)1