Skip to content

Commit

Permalink
Add dependent plugins check during plugin load
Browse files Browse the repository at this point in the history
Signed-off-by: Junqiu Lei <junqiu@amazon.com>
  • Loading branch information
junqiu-lei committed Jan 17, 2025
1 parent 660f577 commit e3c084f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 4 deletions.
22 changes: 22 additions & 0 deletions src/main/java/org/opensearch/neuralsearch/plugin/NeuralSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.Optional;
import java.util.function.Supplier;

import com.google.common.annotations.VisibleForTesting;
import org.opensearch.client.Client;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.service.ClusterService;
Expand Down Expand Up @@ -86,6 +87,14 @@ public class NeuralSearch extends Plugin implements ActionPlugin, SearchPlugin,
private final ScoreCombinationFactory scoreCombinationFactory = new ScoreCombinationFactory();
public static final String EXPLANATION_RESPONSE_KEY = "explanation_response";

@VisibleForTesting
public static final Map<String, String> DEPENDENT_PLUGINS = Map.of(
"opensearch-knn",
"org.opensearch.knn.plugin.KNNPlugin",
"opensearch-ml-commons",
"org.opensearch.ml.client.MachineLearningClient"
);

@Override
public Collection<Object> createComponents(
final Client client,
Expand All @@ -100,6 +109,7 @@ public Collection<Object> createComponents(
final IndexNameExpressionResolver indexNameExpressionResolver,
final Supplier<RepositoriesService> repositoriesServiceSupplier
) {
validateDependentPlugins();
NeuralSearchClusterUtil.instance().initialize(clusterService);
NeuralQueryBuilder.initialize(clientAccessor);
NeuralSparseQueryBuilder.initialize(clientAccessor);
Expand Down Expand Up @@ -204,4 +214,16 @@ public List<SearchPlugin.SearchExtSpec<?>> getSearchExts() {
)
);
}

private void validateDependentPlugins() {
DEPENDENT_PLUGINS.forEach((pluginName, className) -> {
try {
Class.forName(className);
log.info("Plugin [{}] is installed", pluginName);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Neural Search plugin requires the " + pluginName + " plugin to be installed", e);
}
});
log.info("All required plugins {} are installed", DEPENDENT_PLUGINS.keySet());
}
}
39 changes: 35 additions & 4 deletions src/test/java/org/opensearch/neuralsearch/NeuralSearchTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,44 @@
*/
package org.opensearch.neuralsearch;

import org.opensearch.knn.common.KNNConstants;
import org.opensearch.knn.index.engine.KNNEngine;
import org.opensearch.test.OpenSearchTestCase;
import static org.opensearch.neuralsearch.plugin.NeuralSearch.DEPENDENT_PLUGINS;

public class NeuralSearchTests extends OpenSearchTestCase {

public void testValidateKNNDependency() {
assertEquals(KNNConstants.LUCENE_NAME, KNNEngine.LUCENE.getName());
public void testDependentPluginsMapContainsRequiredPlugins() {
// Verify the map contains both required plugins
assertTrue("Map should contain k-NN plugin", DEPENDENT_PLUGINS.containsKey("opensearch-knn"));
assertTrue("Map should contain ML Commons plugin", DEPENDENT_PLUGINS.containsKey("opensearch-ml-commons"));

// Verify the class names are correct
assertEquals(
"k-NN plugin should map to KNNPlugin class",
"org.opensearch.knn.plugin.KNNPlugin",
DEPENDENT_PLUGINS.get("opensearch-knn")
);
assertEquals(
"ML Commons plugin should map to MachineLearningClient class",
"org.opensearch.ml.client.MachineLearningClient",
DEPENDENT_PLUGINS.get("opensearch-ml-commons")
);
}

public void testDependentPluginsMapIsImmutable() {
// Verify the map cannot be modified
expectThrows(UnsupportedOperationException.class, () -> { DEPENDENT_PLUGINS.put("test-plugin", "test.class.Name"); });
}

public void testValidatePluginsWithMissingDependencies() {
// Test with non-existent class
IllegalStateException exception = expectThrows(IllegalStateException.class, () -> {
try {
Class.forName("non.existent.Class");
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Neural Search plugin requires the test plugin to be installed", e);
}
});
assertTrue(exception.getMessage().contains("Neural Search plugin requires"));
assertTrue(exception.getCause() instanceof ClassNotFoundException);
}
}

0 comments on commit e3c084f

Please sign in to comment.