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

com.amazon.opendistroforelasticsearch.security.resolver.IndexResolverReplacer Maven / Gradle / Ivy

There is a newer version: 1.13.1.0
Show newest version
/*
 * Copyright 2015-2018 _floragunn_ GmbH
 * Licensed 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.
 */

/*
 * Portions Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * or in the "license" file accompanying this file. This file 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.
 */

package com.amazon.opendistroforelasticsearch.security.resolver;

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.IndicesRequest.Replaceable;
import org.elasticsearch.action.OriginalIndices;
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkShardRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.action.get.MultiGetRequest.Item;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.main.MainRequest;
import org.elasticsearch.action.search.ClearScrollRequest;
import org.elasticsearch.action.search.MultiSearchRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
import org.elasticsearch.action.support.replication.ReplicationRequest;
import org.elasticsearch.action.support.single.shard.SingleShardRequest;
import org.elasticsearch.action.termvectors.MultiTermVectorsRequest;
import org.elasticsearch.action.termvectors.TermVectorsRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.AliasOrIndex;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.reindex.ReindexRequest;
import org.elasticsearch.snapshots.SnapshotInfo;
import org.elasticsearch.snapshots.SnapshotUtils;
import org.elasticsearch.transport.RemoteClusterService;
import org.elasticsearch.transport.TransportRequest;

import com.amazon.opendistroforelasticsearch.security.OpenDistroSecurityPlugin;
import com.amazon.opendistroforelasticsearch.security.configuration.ClusterInfoHolder;
import com.amazon.opendistroforelasticsearch.security.securityconf.ConfigModel;
import com.amazon.opendistroforelasticsearch.security.securityconf.DynamicConfigFactory.DCFListener;
import com.amazon.opendistroforelasticsearch.security.securityconf.DynamicConfigModel;
import com.amazon.opendistroforelasticsearch.security.securityconf.InternalUsersModel;
import com.amazon.opendistroforelasticsearch.security.support.SnapshotRestoreHelper;
import com.amazon.opendistroforelasticsearch.security.support.WildcardMatcher;


import com.google.common.collect.Sets;

public final class IndexResolverReplacer implements DCFListener {

    private static final Set NULL_SET = Sets.newHashSet((String)null);
    private final Logger log = LogManager.getLogger(this.getClass());
    private final IndexNameExpressionResolver resolver;
    private final ClusterService clusterService;
    private final ClusterInfoHolder clusterInfoHolder;
    private volatile boolean respectRequestIndicesOptions = false;

    public IndexResolverReplacer(IndexNameExpressionResolver resolver, ClusterService clusterService, ClusterInfoHolder clusterInfoHolder) {
        super();
        this.resolver = resolver;
        this.clusterService = clusterService;
        this.clusterInfoHolder = clusterInfoHolder;
    }

    private static final boolean isAllWithNoRemote(final String... requestedPatterns) {

        final List patterns = requestedPatterns==null?null:Arrays.asList(requestedPatterns);

        if(IndexNameExpressionResolver.isAllIndices(patterns)) {
            return true;
        }

        if(patterns.size() == 1 && patterns.contains("*")) {
            return true;
        }

        if(new HashSet(patterns).equals(NULL_SET)) {
            return true;
        }

        return false;
    }

    private static final boolean isLocalAll(final String... requestedPatterns) {

        final List patterns = requestedPatterns==null?null:Arrays.asList(requestedPatterns);

        if(IndexNameExpressionResolver.isAllIndices(patterns)) {
            return true;
        }

        if(patterns.contains("*")) {
            return true;
        }

        if(patterns.contains("_all")) {
            return true;
        }

        if(new HashSet(patterns).equals(NULL_SET)) {
            return true;
        }

        return false;
    }

    private Resolved resolveIndexPatterns(final IndicesOptions indicesOptions, final Object request, final String... requestedPatterns0) {

        if(log.isTraceEnabled()) {
            log.trace("resolve requestedPatterns: "+ Arrays.toString(requestedPatterns0));
        }

        if (isAllWithNoRemote(requestedPatterns0)) {
            if (log.isTraceEnabled()) {
                log.trace(Arrays.toString(requestedPatterns0) + " is an ALL pattern without any remote indices");
            }
            return Resolved._LOCAL_ALL;
        }

        Set remoteIndices;
        final List localRequestedPatterns = new ArrayList<>(Arrays.asList(requestedPatterns0));

        final RemoteClusterService remoteClusterService = OpenDistroSecurityPlugin.GuiceHolder.getRemoteClusterService();

        if(remoteClusterService.isCrossClusterSearchEnabled() && request != null
                && (request instanceof FieldCapabilitiesRequest || request instanceof SearchRequest)) {
            remoteIndices = new HashSet<>();
            final Map remoteClusterIndices = OpenDistroSecurityPlugin.GuiceHolder.getRemoteClusterService()
                    .groupIndices(indicesOptions, requestedPatterns0, idx -> resolver.hasIndexOrAlias(idx, clusterService.state()));
            final Set remoteClusters = remoteClusterIndices.keySet().stream()
                    .filter(k->!RemoteClusterService.LOCAL_CLUSTER_GROUP_KEY.equals(k)).collect(Collectors.toSet());
            for(String remoteCluster : remoteClusters) {
                for(String remoteIndex : remoteClusterIndices.get(remoteCluster).indices()) {
                    remoteIndices.add(RemoteClusterService.buildRemoteIndexName(remoteCluster, remoteIndex));
                }
            }

            final Iterator iterator = localRequestedPatterns.iterator();
            while (iterator.hasNext()) {
                final String[] split = iterator.next().split(String.valueOf(RemoteClusterService.REMOTE_CLUSTER_INDEX_SEPARATOR), 2);
                if (split.length > 1 && WildcardMatcher.matchAny(split[0], remoteClusters)) {
                    iterator.remove();
                }
            }

            if (log.isTraceEnabled()) {
                log.trace("CCS is enabled, we found this local patterns " + localRequestedPatterns + " and this remote patterns: " + remoteIndices);
            }

        } else {
            remoteIndices = Collections.emptySet();
        }

        final Set matchingAliases;
        final Set matchingIndices;
        final Set matchingAllIndices;

        if (isLocalAll(requestedPatterns0)) {
            if (log.isTraceEnabled()) {
                log.trace(Arrays.toString(requestedPatterns0) + " is an LOCAL ALL pattern");
            }
            matchingAliases = Resolved.All_SET;
            matchingIndices = Resolved.All_SET;
            matchingAllIndices = Resolved.All_SET;

        } else if (!remoteIndices.isEmpty() && localRequestedPatterns.isEmpty()) {
            if (log.isTraceEnabled()) {
                log.trace(Arrays.toString(requestedPatterns0) + " is an LOCAL EMPTY request");
            }
            return new Resolved.Builder().addOriginalRequested(Arrays.asList(requestedPatterns0)).addRemoteIndices(remoteIndices).build();
        }

        else {

            ClusterState state = clusterService.state();

            final SortedMap lookup = state.metaData().getAliasAndIndexLookup();
            final Set aliases = lookup.entrySet().stream().filter(e -> e.getValue().isAlias()).map(e -> e.getKey())
                    .collect(Collectors.toSet());

            matchingAliases = new HashSet<>(localRequestedPatterns.size() * 10);
            matchingIndices = new HashSet<>(localRequestedPatterns.size() * 10);
            matchingAllIndices = new HashSet<>(localRequestedPatterns.size() * 10);

            //fill matchingAliases
            for (String localRequestedPattern : localRequestedPatterns) {
                final String requestedPattern = resolver.resolveDateMathExpression(localRequestedPattern);
                final List _aliases = WildcardMatcher.getMatchAny(requestedPattern, aliases);
                matchingAliases.addAll(_aliases);
            }


            List _indices;
            try {
                _indices = new ArrayList<>(
                        Arrays.asList(resolver.concreteIndexNames(state, indicesOptions, localRequestedPatterns.toArray(new String[0]))));
                if (log.isDebugEnabled()) {
                    log.debug("Resolved pattern {} to {}", localRequestedPatterns, _indices);
                }
            } catch (IndexNotFoundException e1) {
                if (log.isDebugEnabled()) {
                    log.debug("No such indices for pattern {}, use raw value", localRequestedPatterns);
                }

                _indices = new ArrayList<>(localRequestedPatterns.size());

                for (String requestedPattern : localRequestedPatterns) {
                    _indices.add(resolver.resolveDateMathExpression(requestedPattern));
                }

            }

            final List _aliases = WildcardMatcher.getMatchAny(localRequestedPatterns.toArray(new String[0]), aliases);

            matchingAllIndices.addAll(_indices);

            if (_aliases.isEmpty()) {
                matchingIndices.addAll(_indices); //date math resolved?
            } else {

                if (!_indices.isEmpty()) {

                    for (String al : _aliases) {
                        Set doubleIndices = lookup.get(al).getIndices().stream().map(a -> a.getIndex().getName()).collect(Collectors.toSet());
                        _indices.removeAll(doubleIndices);
                    }

                    matchingIndices.addAll(_indices);
                }
            }
        }

        return new Resolved.Builder(matchingAliases, matchingIndices, matchingAllIndices, null, requestedPatterns0, remoteIndices)
                /*.addTypes(resolveTypes(request))*/.build();

    }



    //dnfof
    public boolean replace(final TransportRequest request, boolean retainMode, String... replacements) {
        return getOrReplaceAllIndices(request, new IndicesProvider() {

            @Override
            public String[] provide(String[] original, Object request, boolean supportsReplace) {
                if(supportsReplace) {

                    if(retainMode && !isAllWithNoRemote(original)) {
                        final Resolved resolved = resolveRequest(request);
                        final List retained = WildcardMatcher.getMatchAny(resolved.getAllIndices(), replacements);
                        retained.addAll(resolved.getRemoteIndices());
                        return retained.toArray(new String[0]);
                    }
                    return replacements;
                } else {
                    return NOOP;
                }
            }
        }, false);
    }

    public Resolved resolveRequest(final Object request) {
        if(log.isDebugEnabled()) {
            log.debug("Resolve aliases, indices and types from {}", request.getClass().getSimpleName());
        }

        final Resolved.Builder resolvedBuilder = new Resolved.Builder();
        final AtomicBoolean isIndicesRequest = new AtomicBoolean();
        getOrReplaceAllIndices(request, new IndicesProvider() {

            @Override
            public String[] provide(String[] original, Object localRequest, boolean supportsReplace) {
                final IndicesOptions indicesOptions = indicesOptionsFrom(localRequest);
                final Resolved iResolved = resolveIndexPatterns(indicesOptions, localRequest, original);
                resolvedBuilder.add(iResolved);
                isIndicesRequest.set(true);

                if(log.isTraceEnabled()) {
                    log.trace("Resolved patterns {} for {} ({}) to {}", original, localRequest.getClass().getSimpleName(), request.getClass().getSimpleName(), iResolved);
                }

                return IndicesProvider.NOOP;
            }
        }, false);

        if(!isIndicesRequest.get()) {
            //not an indices request
            return Resolved._LOCAL_ALL;
        }

        if(log.isTraceEnabled()) {
            log.trace("Finally resolved for {}: {}", request.getClass().getSimpleName(), resolvedBuilder.build());
        }

        return resolvedBuilder.build();
    }

    public final static class Resolved implements Serializable, Writeable {

        /**
         *
         */
        private static final Set All_SET = Collections.singleton("*");
        private static final long serialVersionUID = 1L;
        public final static Resolved _LOCAL_ALL = new Resolved(All_SET, All_SET, All_SET, All_SET, Collections.emptySet(), Collections.emptySet());
        private final Set aliases;
        private final Set indices;
        private final Set allIndices;
        private final Set types;

        private final Set originalRequested;
        private final Set remoteIndices;

        private Resolved(final Set aliases, final Set indices, final Set allIndices,
                         final Set types, final Set originalRequested, final Set remoteIndices) {
            super();
            this.aliases = aliases;
            this.indices = indices;
            this.allIndices = allIndices;
            this.types = types;
            this.originalRequested = originalRequested;
            this.remoteIndices = remoteIndices;

            if(!aliases.isEmpty() || !indices.isEmpty() || !allIndices.isEmpty()) {
                if(types.isEmpty()) {
                    //throw new ElasticsearchException("Empty types for nonempty indices or aliases");
                }
            }
        }

        public boolean isLocalAll() {
            if(IndexResolverReplacer.isLocalAll(originalRequested==null?null:originalRequested.toArray(new String[0]))) {
                return true;
            }

            return aliases.contains("*") && indices.contains("*") && allIndices.contains("*") && types.contains("*");
        }

        public Set getAliases() {
            return Collections.unmodifiableSet(aliases);
        }

        public Set getIndices() {
            return Collections.unmodifiableSet(indices);
        }

        public Set getAllIndices() {
            return Collections.unmodifiableSet(allIndices);
        }

        public Set getTypes() {
            return Collections.unmodifiableSet(types);
        }

        public Set getOriginalRequested() {
            return Collections.unmodifiableSet(originalRequested);
        }

        public Set getRemoteIndices() {
            return Collections.unmodifiableSet(remoteIndices);
        }

        @Override
        public String toString() {
            return "Resolved [aliases=" + aliases + ", indices=" + indices + ", allIndices=" + allIndices + ", types=" + types
                    + ", originalRequested=" + originalRequested + ", remoteIndices=" + remoteIndices + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((aliases == null) ? 0 : aliases.hashCode());
            result = prime * result + ((allIndices == null) ? 0 : allIndices.hashCode());
            result = prime * result + ((indices == null) ? 0 : indices.hashCode());
            result = prime * result + ((originalRequested == null) ? 0 : originalRequested.hashCode());
            result = prime * result + ((remoteIndices == null) ? 0 : remoteIndices.hashCode());
            result = prime * result + ((types == null) ? 0 : types.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Resolved other = (Resolved) obj;
            if (aliases == null) {
                if (other.aliases != null)
                    return false;
            } else if (!aliases.equals(other.aliases))
                return false;
            if (allIndices == null) {
                if (other.allIndices != null)
                    return false;
            } else if (!allIndices.equals(other.allIndices))
                return false;
            if (indices == null) {
                if (other.indices != null)
                    return false;
            } else if (!indices.equals(other.indices))
                return false;
            if (originalRequested == null) {
                if (other.originalRequested != null)
                    return false;
            } else if (!originalRequested.equals(other.originalRequested))
                return false;
            if (remoteIndices == null) {
                if (other.remoteIndices != null)
                    return false;
            } else if (!remoteIndices.equals(other.remoteIndices))
                return false;
            if (types == null) {
                if (other.types != null)
                    return false;
            } else if (!types.equals(other.types))
                return false;
            return true;
        }



        private static class Builder {

            private final Set aliases = new HashSet();
            private final Set indices = new HashSet();
            private final Set allIndices = new HashSet();
            //private final Set types = new HashSet();
            private final Set originalRequested = new HashSet();
            private final Set remoteIndices = new HashSet();

            public Builder() {
                this(null, null, null, null, null, null);
            }

            public Builder(Collection aliases, Collection indices, Collection allIndices,
                           Collection types, String[] originalRequested, Collection remoteIndices) {

                if(aliases != null) {
                    this.aliases.addAll(aliases);
                }

                if(indices != null) {
                    this.indices.addAll(indices);
                }

                if(allIndices != null) {
                    this.allIndices.addAll(allIndices);
                }

                if(types != null) {
                    //this.types.addAll(types);
                }

                if(originalRequested != null) {
                    this.originalRequested.addAll(Arrays.asList(originalRequested));
                }

                if(remoteIndices != null) {
                    this.remoteIndices.addAll(remoteIndices);
                }
            }

            /*public Builder addTypes(Collection types) {
                if(types != null && types.size() > 0) {
                    if(this.types.contains("*")) {
                        this.types.remove("*");
                    }
                    this.types.addAll(types);
                }
                return this;
            }*/

            public Builder add(Resolved r) {

                this.aliases.addAll(r.aliases);
                this.indices.addAll(r.indices);
                this.allIndices.addAll(r.allIndices);
                this.originalRequested.addAll(r.originalRequested);
                this.remoteIndices.addAll(r.remoteIndices);
                //addTypes(r.types);
                return this;
            }
            
            public Builder addOriginalRequested(List originalRequested) {
                if(originalRequested != null) {
                    this.originalRequested.addAll(originalRequested);
                }
                return this;
            }
            
            public Builder addRemoteIndices(Set remoteIndices) {
                if(remoteIndices != null) {
                    this.remoteIndices.addAll(remoteIndices);
                }
                return this;
            }

            public Resolved build() {
//                if(types.isEmpty()) {
//                    types.add("*");
//                }

                return new Resolved(new HashSet(aliases), new HashSet(indices), new HashSet(allIndices),
                        Collections.singleton("*"), new HashSet(originalRequested), new HashSet(remoteIndices));
            }
        }

        public Resolved(final StreamInput in) throws IOException {
            aliases = new HashSet(in.readList(StreamInput::readString));
            indices = new HashSet(in.readList(StreamInput::readString));
            allIndices = new HashSet(in.readList(StreamInput::readString));
            types = new HashSet(in.readList(StreamInput::readString));
            originalRequested = new HashSet(in.readList(StreamInput::readString));
            remoteIndices = new HashSet(in.readList(StreamInput::readString));
        }


        @Override
        public void writeTo(StreamOutput out) throws IOException {
            out.writeStringCollection(new ArrayList<>(aliases));
            out.writeStringCollection(new ArrayList<>(indices));
            out.writeStringCollection(new ArrayList<>(allIndices));
            out.writeStringCollection(new ArrayList<>(types));
            out.writeStringCollection(new ArrayList<>(originalRequested));
            out.writeStringCollection(new ArrayList<>(remoteIndices));
        }
    }

    private List renamedIndices(final RestoreSnapshotRequest request, final List filteredIndices) {
        try {
            final List renamedIndices = new ArrayList<>();
            for (final String index : filteredIndices) {
                String renamedIndex = index;
                if (request.renameReplacement() != null && request.renamePattern() != null) {
                    renamedIndex = index.replaceAll(request.renamePattern(), request.renameReplacement());
                }
                renamedIndices.add(renamedIndex);
            }
            return renamedIndices;
        } catch (PatternSyntaxException e) {
            log.error("Unable to parse the regular expression denoted in 'rename_pattern'. Please correct the pattern an try again.");
            throw e;
        }
    }


    //--

    @FunctionalInterface
    public interface IndicesProvider {
        public static final String[] NOOP = new String[0];
        String[] provide(String[] original, Object request, boolean supportsReplace);
    }

    private boolean checkIndices(Object request, String[] indices, boolean needsToBeSizeOne, boolean allowEmpty) {

        if(indices == IndicesProvider.NOOP) {
            return false;
        }

        if(!allowEmpty && (indices == null || indices.length == 0)) {
            if(log.isTraceEnabled() && request != null) {
                log.trace("Null or empty indices for "+request.getClass().getName());
            }
            return false;
        }

        if(!allowEmpty && needsToBeSizeOne && indices.length != 1) {
            if(log.isTraceEnabled() && request != null) {
                log.trace("To much indices for "+request.getClass().getName());
            }
            return false;
        }

        for (int i = 0; i < indices.length; i++) {
            final String index = indices[i];
            if(index == null || index.isEmpty()) {
                //not allowed
                if(log.isTraceEnabled() && request != null) {
                    log.trace("At least one null or empty index for "+request.getClass().getName());
                }
                return false;
            }
        }

        return true;
    }

    /**
     * new
     * @param request
     * @param newIndices
     * @return
     */
    @SuppressWarnings("rawtypes")
    private boolean getOrReplaceAllIndices(final Object request, final IndicesProvider provider, boolean allowEmptyIndices) {

        if(log.isTraceEnabled()) {
            log.trace("getOrReplaceAllIndices() for "+request.getClass());
        }

        boolean result = true;

        if (request instanceof BulkRequest) {

            for (DocWriteRequest ar : ((BulkRequest) request).requests()) {
                result = getOrReplaceAllIndices(ar, provider, false) && result;
            }

        } else if (request instanceof MultiGetRequest) {

            for (ListIterator it = ((MultiGetRequest) request).getItems().listIterator(); it.hasNext();){
                Item item = it.next();
                result = getOrReplaceAllIndices(item, provider, false) && result;
                /*if(item.index() == null || item.indices() == null || item.indices().length == 0) {
                    it.remove();
                }*/
            }

        } else if (request instanceof MultiSearchRequest) {

            for (ListIterator it = ((MultiSearchRequest) request).requests().listIterator(); it.hasNext();) {
                SearchRequest ar = it.next();
                result = getOrReplaceAllIndices(ar, provider, false) && result;
                /*if(ar.indices() == null || ar.indices().length == 0) {
                    it.remove();
                }*/
            }

        } else if (request instanceof MultiTermVectorsRequest) {

            for (ActionRequest ar : (Iterable) () -> ((MultiTermVectorsRequest) request).iterator()) {
                result = getOrReplaceAllIndices(ar, provider, false) && result;
            }

        } else if(request instanceof PutMappingRequest) {
            PutMappingRequest pmr = (PutMappingRequest) request;
            Index concreteIndex = pmr.getConcreteIndex();
            if(concreteIndex != null && (pmr.indices() == null || pmr.indices().length == 0)) {
                String[] newIndices = provider.provide(new String[]{concreteIndex.getName()}, request, true);
                if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                    return false;
                }

                ((PutMappingRequest) request).indices(newIndices);
                ((PutMappingRequest) request).setConcreteIndex(null);
            } else {
                String[] newIndices = provider.provide(((PutMappingRequest) request).indices(), request, true);
                if(checkIndices(request, newIndices, false, allowEmptyIndices) == false) {
                    return false;
                }
                ((PutMappingRequest) request).indices(newIndices);
            }
        } else if(request instanceof RestoreSnapshotRequest) {

                if(clusterInfoHolder.isLocalNodeElectedMaster() == Boolean.FALSE) {
                    return true;
                }

                final RestoreSnapshotRequest restoreRequest = (RestoreSnapshotRequest) request;
                final SnapshotInfo snapshotInfo = SnapshotRestoreHelper.getSnapshotInfo(restoreRequest);

                if (snapshotInfo == null) {
                    log.warn("snapshot repository '" + restoreRequest.repository() + "', snapshot '" + restoreRequest.snapshot() + "' not found");
                    provider.provide(new String[]{"*"}, request, false);
                } else {
                    final List requestedResolvedIndices = SnapshotUtils.filterIndices(snapshotInfo.indices(), restoreRequest.indices(), restoreRequest.indicesOptions());
                    final List renamedTargetIndices = renamedIndices(restoreRequest, requestedResolvedIndices);
                    //final Set indices = new HashSet<>(requestedResolvedIndices);
                    //indices.addAll(renamedTargetIndices);
                    if(log.isDebugEnabled()) {
                        log.debug("snapshot: {} contains this indices: {}", snapshotInfo.snapshotId().getName(), renamedTargetIndices);
                    }
                    provider.provide(renamedTargetIndices.toArray(new String[0]), request, false);
            }

        } else if (request instanceof IndicesAliasesRequest) {
            for(AliasActions ar: ((IndicesAliasesRequest) request).getAliasActions()) {
                result = getOrReplaceAllIndices(ar, provider, false) && result;
            }
        } else if (request instanceof DeleteRequest) {
            String[] newIndices = provider.provide(((DeleteRequest) request).indices(), request, true);
            if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                return false;
            }
            ((DeleteRequest) request).index(newIndices.length!=1?null:newIndices[0]);
        } else if (request instanceof UpdateRequest) {
            String[] newIndices = provider.provide(((UpdateRequest) request).indices(), request, true);
            if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                return false;
            }
            ((UpdateRequest) request).index(newIndices.length!=1?null:newIndices[0]);
        } else if (request instanceof SingleShardRequest) {
            final SingleShardRequest gr = (SingleShardRequest) request;
            final String[] indices = gr.indices();
            final String index = gr.index();

            final List indicesL = new ArrayList();

            if (index != null) {
                indicesL.add(index);
            }

            if (indices != null && indices.length > 0) {
                indicesL.addAll(Arrays.asList(indices));
            }

            String[] newIndices = provider.provide(indicesL.toArray(new String[0]), request, true);
            if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                return false;
            }
            ((SingleShardRequest) request).index(newIndices.length!=1?null:newIndices[0]);
        } else if (request instanceof IndexRequest) {
            String[] newIndices = provider.provide(((IndexRequest) request).indices(), request, true);
            if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                return false;
            }
            ((IndexRequest) request).index(newIndices.length!=1?null:newIndices[0]);
        } else if (request instanceof Replaceable) {
            String[] newIndices = provider.provide(((Replaceable) request).indices(), request, true);
            if(checkIndices(request, newIndices, false, allowEmptyIndices) == false) {
                return false;
            }
            ((Replaceable) request).indices(newIndices);
        } else if (request instanceof BulkShardRequest) {
            provider.provide(((ReplicationRequest) request).indices(), request, false);
            //replace not supported?
        } else if (request instanceof ReplicationRequest) {
            String[] newIndices = provider.provide(((ReplicationRequest) request).indices(), request, true);
            if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                return false;
            }
            ((ReplicationRequest) request).index(newIndices.length!=1?null:newIndices[0]);
        } else if (request instanceof MultiGetRequest.Item) {
            String[] newIndices = provider.provide(((MultiGetRequest.Item) request).indices(), request, true);
            if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                return false;
            }
            ((MultiGetRequest.Item) request).index(newIndices.length!=1?null:newIndices[0]);
        } else if (request instanceof CreateIndexRequest) {
            String[] newIndices = provider.provide(((CreateIndexRequest) request).indices(), request, true);
            if(checkIndices(request, newIndices, true, allowEmptyIndices) == false) {
                return false;
            }
            ((CreateIndexRequest) request).index(newIndices.length!=1?null:newIndices[0]);
        } else if (request instanceof ReindexRequest) {
            result = getOrReplaceAllIndices(((ReindexRequest) request).getDestination(), provider, false) && result;
            result = getOrReplaceAllIndices(((ReindexRequest) request).getSearchRequest(), provider, false) && result;
        } else if (request instanceof BaseNodesRequest) {
            //do nothing
        } else if (request instanceof MainRequest) {
            //do nothing
        } else if (request instanceof ClearScrollRequest) {
            //do nothing
        } else if (request instanceof SearchScrollRequest) {
            //do nothing
        } else {
            if(log.isDebugEnabled()) {
                log.debug(request.getClass() + " not supported (It is likely not a indices related request)");
            }
            result = false;
        }

        return result;
    }

    private IndicesOptions indicesOptionsFrom(Object localRequest) {
        
        if(!respectRequestIndicesOptions) {
            return IndicesOptions.fromOptions(false, true, true, false);
        }

        if (IndicesRequest.class.isInstance(localRequest)) {
            return ((IndicesRequest) localRequest).indicesOptions();
        }
        else if (RestoreSnapshotRequest.class.isInstance(localRequest)) {
            return ((RestoreSnapshotRequest) localRequest).indicesOptions();
        }
        else {
            return IndicesOptions.fromOptions(false, true, true, false);
        }
    }

    @Override
    public void onChanged(ConfigModel cm, DynamicConfigModel dcm, InternalUsersModel ium) {
        respectRequestIndicesOptions = dcm.isRespectRequestIndicesEnabled();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy