diff --git a/src/main/java/org/opensearch/knn/plugin/KNNPlugin.java b/src/main/java/org/opensearch/knn/plugin/KNNPlugin.java index de4932c47..ed5948901 100644 --- a/src/main/java/org/opensearch/knn/plugin/KNNPlugin.java +++ b/src/main/java/org/opensearch/knn/plugin/KNNPlugin.java @@ -10,6 +10,7 @@ import org.opensearch.common.ParseField; import org.opensearch.index.codec.CodecServiceFactory; import org.opensearch.index.engine.EngineFactory; +import org.opensearch.index.shard.IndexSettingProvider; import org.opensearch.indices.SystemIndexDescriptor; import org.opensearch.knn.index.KNNCircuitBreaker; import org.opensearch.knn.index.KNNClusterUtil; @@ -342,12 +343,26 @@ public Collection getSystemIndexDescriptors(Settings sett } /** - * Plugin can provide additional node settings, that includes new settings or overrides for existing one from core. + * Plugin can provide additional index settings, that includes new settings or overrides for existing one from core. * * @return settings that are set by plugin */ @Override - public Settings additionalSettings() { + public Collection getAdditionalIndexSettingProviders() { + final IndexSettingProvider settingProvider = new IndexSettingProvider() { + @Override + public Settings getAdditionalIndexSettings( + final String indexName, + boolean isDataStreamIndex, + final Settings templateAndRequestSettings + ) { + return pluginAdditionalSettings(templateAndRequestSettings); + } + }; + return List.of(settingProvider); + } + + private void additionalMMapFileExtensionsForHybridFs(final Settings.Builder settingsBuilder) { // We add engine specific extensions to the core list for HybridFS store type. We read existing values // and append ours because in core setting will be replaced by override. // Values are set as cluster defaults and are used at index creation time. Index specific overrides will take priority over values @@ -359,6 +374,16 @@ public Settings additionalSettings() { IndexModule.INDEX_STORE_HYBRID_MMAP_EXTENSIONS.getDefault(Settings.EMPTY).stream(), engineSettings.stream() ).collect(Collectors.toList()); - return Settings.builder().putList(IndexModule.INDEX_STORE_HYBRID_MMAP_EXTENSIONS.getKey(), combinedSettings).build(); + + settingsBuilder.putList(IndexModule.INDEX_STORE_HYBRID_MMAP_EXTENSIONS.getKey(), combinedSettings); + } + + private Settings pluginAdditionalSettings(final Settings templateAndRequestSettings) { + final var settingsBuilder = Settings.builder(); + boolean isKnnIndex = Boolean.parseBoolean(templateAndRequestSettings.get(KNNSettings.KNN_INDEX, Boolean.FALSE.toString())); + if (isKnnIndex) { + additionalMMapFileExtensionsForHybridFs(settingsBuilder); + } + return settingsBuilder.build(); } } diff --git a/src/test/java/org/opensearch/knn/plugin/KNNPluginTests.java b/src/test/java/org/opensearch/knn/plugin/KNNPluginTests.java new file mode 100644 index 000000000..93c507edf --- /dev/null +++ b/src/test/java/org/opensearch/knn/plugin/KNNPluginTests.java @@ -0,0 +1,59 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.knn.plugin; + +import org.opensearch.common.settings.Settings; +import org.opensearch.index.IndexModule; +import org.opensearch.index.shard.IndexSettingProvider; +import org.opensearch.knn.KNNTestCase; +import org.opensearch.knn.index.util.KNNEngine; + +import java.util.Collection; +import java.util.List; + +public class KNNPluginTests extends KNNTestCase { + + private static final String INDEX_NAME = "test_index"; + + public void testMMapFileExtensionsForHybridFs() { + final KNNPlugin knnPlugin = new KNNPlugin(); + + final Collection additionalIndexSettingProviders = knnPlugin.getAdditionalIndexSettingProviders(); + + assertEquals(1, additionalIndexSettingProviders.size()); + + final IndexSettingProvider indexSettingProvider = additionalIndexSettingProviders.iterator().next(); + // settings for knn enabled index + final Settings knnIndexSettings = indexSettingProvider.getAdditionalIndexSettings(INDEX_NAME, false, getKnnDefaultIndexSettings()); + final List mmapFileExtensionsForHybridFsKnnIndex = knnIndexSettings.getAsList( + IndexModule.INDEX_STORE_HYBRID_MMAP_EXTENSIONS.getKey() + ); + + assertNotNull(mmapFileExtensionsForHybridFsKnnIndex); + assertFalse(mmapFileExtensionsForHybridFsKnnIndex.isEmpty()); + + for (KNNEngine engine : KNNEngine.values()) { + assertTrue(mmapFileExtensionsForHybridFsKnnIndex.containsAll(engine.mmapFileExtensions())); + } + + // settings for index without knn + final Settings nonKnnIndexSettings = indexSettingProvider.getAdditionalIndexSettings(INDEX_NAME, false, getNonKnnIndexSettings()); + final List mmapFileExtensionsForHybridFsNonKnnIndex = nonKnnIndexSettings.getAsList( + IndexModule.INDEX_STORE_HYBRID_MMAP_EXTENSIONS.getKey() + ); + + assertNotNull(mmapFileExtensionsForHybridFsNonKnnIndex); + assertTrue(mmapFileExtensionsForHybridFsNonKnnIndex.isEmpty()); + } + + private Settings getKnnDefaultIndexSettings() { + return Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0).put("index.knn", true).build(); + } + + private Settings getNonKnnIndexSettings() { + return Settings.builder().put("number_of_shards", 1).put("number_of_replicas", 0).build(); + } +}