Remove shard level injector usage

This commit catches up with master which removed the shard level injector
and changed the logic how the SearcherWrapper works and is installed.
The way we now install it is via a package private onModule(IndexModule) call.
There is no public API for this anymore.
The wrapper also doesn't need to watch the IndexShards state since now it will only
be used when the shard is STARTED or RECOVERED.

Original commit: elastic/x-pack-elasticsearch@42b9eeef3d
This commit is contained in:
Simon Willnauer 2015-10-05 14:43:45 +02:00
parent 01db047053
commit b7ca362df5
7 changed files with 38 additions and 83 deletions

View File

@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.index;
import org.elasticsearch.shield.authz.accesscontrol.ShieldIndexSearcherWrapper;
public class SearcherWrapperInstaller {
public static void install(IndexModule module) {
module.indexSearcherWrapper = ShieldIndexSearcherWrapper.class;
}
}

View File

@ -15,6 +15,7 @@ import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.http.HttpServerModule;
import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.cache.IndexCacheModule;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestModule;
@ -29,8 +30,9 @@ import org.elasticsearch.shield.authc.Realms;
import org.elasticsearch.shield.authc.support.SecuredString;
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
import org.elasticsearch.shield.authz.AuthorizationModule;
import org.elasticsearch.shield.authz.accesscontrol.AccessControlShardModule;
import org.elasticsearch.index.SearcherWrapperInstaller;
import org.elasticsearch.shield.authz.accesscontrol.OptOutQueryCache;
import org.elasticsearch.shield.authz.accesscontrol.ShieldIndexSearcherWrapper;
import org.elasticsearch.shield.authz.store.FileRolesStore;
import org.elasticsearch.shield.crypto.CryptoModule;
import org.elasticsearch.shield.crypto.InternalCryptoService;
@ -115,20 +117,11 @@ public class ShieldPlugin extends Plugin {
public Collection<Module> indexModules(Settings settings) {
if (enabled && clientMode == false) {
failIfShieldQueryCacheIsNotActive(settings, false);
return Collections.emptyList();
}
return Collections.emptyList();
}
@Override
public Collection<Module> shardModules(Settings settings) {
if (enabled && clientMode == false) {
failIfShieldQueryCacheIsNotActive(settings, false);
return Collections.<Module>singletonList(new AccessControlShardModule(settings));
} else {
return Collections.emptyList();
}
}
@Override
public Collection<Class<? extends LifecycleComponent>> nodeServices() {
if (enabled && clientMode == false) {
@ -158,6 +151,13 @@ public class ShieldPlugin extends Plugin {
clusterDynamicSettingsModule.registerClusterDynamicSetting(IPFilter.IP_FILTER_ENABLED_HTTP_SETTING, Validator.EMPTY);
}
public void onModule(IndexModule module) {
if (enabled == false) {
return;
}
SearcherWrapperInstaller.install(module);
}
public void onModule(ActionModule module) {
if (enabled == false) {
return;

View File

@ -1,25 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.authz.accesscontrol;
import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.engine.IndexSearcherWrapper;
import org.elasticsearch.shield.support.AbstractShieldModule;
public class AccessControlShardModule extends AbstractShieldModule.Node {
public AccessControlShardModule(Settings settings) {
super(settings);
}
@Override
protected void configureNode() {
Multibinder<IndexSearcherWrapper> multibinder
= Multibinder.newSetBinder(binder(), IndexSearcherWrapper.class);
multibinder.addBinding().to(ShieldIndexSearcherWrapper.class);
}
}

View File

@ -12,24 +12,22 @@ import org.apache.lucene.util.*;
import org.apache.lucene.util.BitSet;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.support.LoggerMessageFormat;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.engine.EngineConfig;
import org.elasticsearch.index.engine.EngineException;
import org.elasticsearch.index.engine.IndexSearcherWrapper;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.query.IndexQueryParserService;
import org.elasticsearch.index.query.ParsedQuery;
import org.elasticsearch.index.settings.IndexSettings;
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.shard.IndexSearcherWrapper;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.shard.ShardUtils;
import org.elasticsearch.indices.IndicesLifecycle;
import org.elasticsearch.shield.authz.InternalAuthorizationService;
import org.elasticsearch.shield.authz.accesscontrol.DocumentSubsetReader.DocumentSubsetDirectoryReader;
import org.elasticsearch.shield.support.Exceptions;
@ -50,22 +48,19 @@ import static org.apache.lucene.search.BooleanClause.Occur.FILTER;
* Document level security is enabled by wrapping the original {@link DirectoryReader} in a {@link DocumentSubsetReader}
* instance.
*/
public final class ShieldIndexSearcherWrapper extends AbstractIndexShardComponent implements IndexSearcherWrapper {
public final class ShieldIndexSearcherWrapper extends AbstractComponent implements IndexSearcherWrapper {
private final MapperService mapperService;
private final Set<String> allowedMetaFields;
private final IndexQueryParserService parserService;
private final BitsetFilterCache bitsetFilterCache;
private volatile boolean shardStarted = false;
@Inject
public ShieldIndexSearcherWrapper(ShardId shardId, @IndexSettings Settings indexSettings, IndexQueryParserService parserService, IndicesLifecycle indicesLifecycle, MapperService mapperService, BitsetFilterCache bitsetFilterCache) {
super(shardId, indexSettings);
public ShieldIndexSearcherWrapper(@IndexSettings Settings indexSettings, IndexQueryParserService parserService, MapperService mapperService, BitsetFilterCache bitsetFilterCache) {
super(indexSettings);
this.mapperService = mapperService;
this.parserService = parserService;
this.bitsetFilterCache = bitsetFilterCache;
indicesLifecycle.addListener(new ShardLifecycleListener());
Set<String> allowedMetaFields = new HashSet<>();
allowedMetaFields.addAll(Arrays.asList(MapperService.getAllMetaFields()));
@ -82,15 +77,8 @@ public final class ShieldIndexSearcherWrapper extends AbstractIndexShardComponen
try {
RequestContext context = RequestContext.current();
if (context == null) {
if (shardStarted == false) {
// The shard this index searcher wrapper has been created for hasn't started yet,
// We may load some initial stuff like for example previous stored percolator queries and recovery,
// so for this reason we should provide access to all fields:
return reader;
} else {
logger.debug("couldn't locate the current request, field level security will only allow meta fields");
return FieldSubsetReader.wrap(reader, allowedMetaFields);
}
logger.debug("couldn't locate the current request, field level security will only allow meta fields");
return FieldSubsetReader.wrap(reader, allowedMetaFields);
}
IndicesAccessControl indicesAccessControl = context.getRequest().getFromContext(InternalAuthorizationService.INDICES_PERMISSIONS_KEY);
@ -207,16 +195,6 @@ public final class ShieldIndexSearcherWrapper extends AbstractIndexShardComponen
}
}
private class ShardLifecycleListener extends IndicesLifecycle.Listener {
@Override
public void afterIndexShardPostRecovery(IndexShard indexShard) {
if (shardId.equals(indexShard.shardId())) {
shardStarted = true;
}
}
}
static void intersectScorerAndRoleBits(Scorer scorer, SparseFixedBitSet roleBits, LeafCollector collector, Bits acceptDocs) throws IOException {
// ConjunctionDISI uses the DocIdSetIterator#cost() to order the iterators, so if roleBits has the lowest cardinality it should be used first:
DocIdSetIterator iterator = ConjunctionDISI.intersect(Arrays.asList(new BitSetIterator(roleBits, roleBits.approximateCardinality()), scorer));

View File

@ -11,27 +11,15 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.*;
import org.apache.lucene.search.*;
import org.apache.lucene.search.join.BitDocIdSetFilter;
import org.apache.lucene.search.join.BitSetProducer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BitDocIdSet;
import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.SparseFixedBitSet;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.test.ESTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.IOException;
import java.util.concurrent.Callable;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

View File

@ -62,7 +62,7 @@ public class ShieldIndexSearcherWrapperIntegrationTests extends ESTestCase {
public void testDLS() throws Exception {
ShardId shardId = new ShardId("_index", 0);
EngineConfig engineConfig = new EngineConfig(shardId, null, null, Settings.EMPTY, null, null, null, null, null, null, null, null, null, null, null, QueryCachingPolicy.ALWAYS_CACHE, null, null); // can't mock...
EngineConfig engineConfig = new EngineConfig(shardId, null, null, Settings.EMPTY, null, null, null, null, null, null, null, null, null, null, null, QueryCachingPolicy.ALWAYS_CACHE, null); // can't mock...
MapperService mapperService = mock(MapperService.class);
when(mapperService.docMappers(anyBoolean())).thenReturn(Collections.emptyList());
@ -102,7 +102,7 @@ public class ShieldIndexSearcherWrapperIntegrationTests extends ESTestCase {
}
});
ShieldIndexSearcherWrapper wrapper = new ShieldIndexSearcherWrapper(
shardId, Settings.EMPTY, parserService, indicesLifecycle, mapperService, bitsetFilterCache
Settings.EMPTY, parserService, mapperService, bitsetFilterCache
);
Directory directory = newDirectory();

View File

@ -86,11 +86,9 @@ public class ShieldIndexSearcherWrapperUnitTests extends ESTestCase {
mapperService = new MapperService(index, settings, analysisService, similarityLookupService, scriptService);
shardId = new ShardId(index, 0);
InternalIndicesLifecycle indicesLifecycle = new InternalIndicesLifecycle(settings);
shieldIndexSearcherWrapper = new ShieldIndexSearcherWrapper(shardId, settings, null, indicesLifecycle, mapperService, null);
shieldIndexSearcherWrapper = new ShieldIndexSearcherWrapper(settings, null, mapperService, null);
IndexShard indexShard = mock(IndexShard.class);
when(indexShard.shardId()).thenReturn(shardId);
indicesLifecycle.afterIndexShardPostRecovery(indexShard);
request = new TransportRequest.Empty();
RequestContext.setCurrent(new RequestContext(request));
@ -227,7 +225,7 @@ public class ShieldIndexSearcherWrapperUnitTests extends ESTestCase {
public void testDelegateSimilarity() throws Exception {
ShardId shardId = new ShardId("_index", 0);
EngineConfig engineConfig = new EngineConfig(shardId, null, null, Settings.EMPTY, null, null, null, null, null, null, new BM25Similarity(), null, null, null, new NoneQueryCache(shardId.index(), Settings.EMPTY), QueryCachingPolicy.ALWAYS_CACHE, null, null); // can't mock...
EngineConfig engineConfig = new EngineConfig(shardId, null, null, Settings.EMPTY, null, null, null, null, null, null, new BM25Similarity(), null, null, null, new NoneQueryCache(shardId.index(), Settings.EMPTY), QueryCachingPolicy.ALWAYS_CACHE, null); // can't mock...
BitsetFilterCache bitsetFilterCache = mock(BitsetFilterCache.class);
DirectoryReader directoryReader = DocumentSubsetReader.wrap(esIn, bitsetFilterCache, new MatchAllDocsQuery());