@@ -166,8 +166,8 @@ public interface DirectoryWrapper {
166166 private final AnalysisRegistry analysisRegistry ;
167167 private final EngineFactory engineFactory ;
168168 private final SetOnce <DirectoryWrapper > indexDirectoryWrapper = new SetOnce <>();
169- private final SetOnce <Function <IndexService , CheckedFunction <DirectoryReader , DirectoryReader , IOException >>> indexReaderWrapper =
170- new SetOnce <>();
169+ private final List <Function <IndexService , CheckedFunction <DirectoryReader , DirectoryReader , IOException >>> indexReaderWrappers =
170+ new ArrayList <>();
171171 private final Set <IndexEventListener > indexEventListeners = new HashSet <>();
172172 private final Map <String , TriFunction <Settings , IndexVersion , ScriptService , Similarity >> similarities = new HashMap <>();
173173 private final Map <String , IndexStorePlugin .DirectoryFactory > directoryFactories ;
@@ -368,9 +368,9 @@ public void addSimilarity(String name, TriFunction<Settings, IndexVersion, Scrip
368368 }
369369
370370 /**
371- * Sets the factory for creating new {@link DirectoryReader} wrapper instances.
371+ * Adds a new instance of factory creating new {@link DirectoryReader} wrapper instances.
372372 * The factory ({@link Function}) is called once the IndexService is fully constructed.
373- * NOTE: this method can only be called once per index. Multiple wrappers are not supported .
373+ * All added wrappers are applied in the order they have been added .
374374 * <p>
375375 * The {@link CheckedFunction} is invoked each time a {@link Engine.Searcher} is requested to do an operation,
376376 * for example search, and must return a new directory reader wrapping the provided directory reader or if no
@@ -384,11 +384,11 @@ public void addSimilarity(String name, TriFunction<Settings, IndexVersion, Scrip
384384 * The returned reader is closed once it goes out of scope.
385385 * </p>
386386 */
387- public void setReaderWrapper (
387+ public void addReaderWrapper (
388388 Function <IndexService , CheckedFunction <DirectoryReader , DirectoryReader , IOException >> indexReaderWrapperFactory
389389 ) {
390390 ensureNotFrozen ();
391- this .indexReaderWrapper . set (indexReaderWrapperFactory );
391+ this .indexReaderWrappers . add (indexReaderWrapperFactory );
392392 }
393393
394394 /**
@@ -499,8 +499,14 @@ public IndexService newIndexService(
499499 QueryRewriteInterceptor queryRewriteInterceptor
500500 ) throws IOException {
501501 final IndexEventListener eventListener = freeze ();
502- Function <IndexService , CheckedFunction <DirectoryReader , DirectoryReader , IOException >> readerWrapperFactory = indexReaderWrapper
503- .get () == null ? (shard ) -> null : indexReaderWrapper .get ();
502+ Function <IndexService , CheckedFunction <DirectoryReader , DirectoryReader , IOException >> readerWrapperFactory = indexReaderWrappers
503+ .isEmpty () ? indexService -> null : indexService -> (directoryReader ) -> {
504+ var wrapped = indexReaderWrappers .get (0 ).apply (indexService ).apply (directoryReader );
505+ for (int i = 1 ; i < indexReaderWrappers .size (); i ++) {
506+ wrapped = indexReaderWrappers .get (i ).apply (indexService ).apply (wrapped );
507+ }
508+ return wrapped ;
509+ };
504510 eventListener .beforeIndexCreated (indexSettings .getIndex (), indexSettings .getSettings ());
505511 final IndexStorePlugin .DirectoryFactory directoryFactory = getDirectoryFactory (indexSettings , directoryFactories );
506512 final IndexStorePlugin .RecoveryStateFactory recoveryStateFactory = getRecoveryStateFactory (indexSettings , recoveryStateFactories );
0 commit comments