Skip to content

Commit

Permalink
[DRAFT] Introduce PluginMetadataClient
Browse files Browse the repository at this point in the history
  • Loading branch information
fddattal committed May 16, 2024
1 parent f217270 commit 9d9e2dd
Show file tree
Hide file tree
Showing 16 changed files with 1,017 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,21 @@ public <T> T get(Setting<T> setting) {
return setting.get(this.lastSettingsApplied, settings);
}

/**
* Creates a snapshot of the scoped settings as a Settings instance.
* <p>
* Note: Updates to scoped settings are not reflected in the result Settings instance. This API is meant to
* represent a point in time.
* </p>
* @return The current settings
*/
public Settings toSettings() {
return Settings.builder()
.put(settings)
.put(lastSettingsApplied)
.build();
}

/**
* Updates a target settings builder with new, updated or deleted settings from a given settings builder.
* <p>
Expand Down
20 changes: 20 additions & 0 deletions server/src/main/java/org/opensearch/node/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,14 @@
import org.opensearch.plugins.PluginsService;
import org.opensearch.plugins.RepositoryPlugin;
import org.opensearch.plugins.ScriptPlugin;
import org.opensearch.plugins.SdkAwarePlugin;
import org.opensearch.plugins.SearchPipelinePlugin;
import org.opensearch.plugins.SearchPlugin;
import org.opensearch.plugins.SecureSettingsFactory;
import org.opensearch.plugins.SystemIndexPlugin;
import org.opensearch.plugins.TelemetryPlugin;
import org.opensearch.plugins.sdk.DefaultPluginMetadataClient;
import org.opensearch.plugins.sdk.PluginMetadataClient;
import org.opensearch.ratelimitting.admissioncontrol.AdmissionControlService;
import org.opensearch.ratelimitting.admissioncontrol.transport.AdmissionControlTransportInterceptor;
import org.opensearch.repositories.RepositoriesModule;
Expand Down Expand Up @@ -890,6 +893,22 @@ protected Node(

final ViewService viewService = new ViewService(clusterService, client, null);

DefaultPluginMetadataClient defaultPluginMetadataClient = new DefaultPluginMetadataClient(
clusterService,
clusterModule.getIndexNameExpressionResolver(),
settingsModule.getIndexScopedSettings()
);

SdkAwarePlugin.Dependencies sdkDependencies = new SdkAwarePlugin.Dependencies() {
@Override
public PluginMetadataClient getPluginMetadataClient() {
return defaultPluginMetadataClient;
}
};

pluginsService.filterPlugins(SdkAwarePlugin.class)
.forEach(plugin -> plugin.setupSdkPlugin(sdkDependencies));

Collection<Object> pluginComponents = pluginsService.filterPlugins(Plugin.class)
.stream()
.flatMap(
Expand Down Expand Up @@ -1329,6 +1348,7 @@ protected Node(
b.bind(PersistedStateRegistry.class).toInstance(persistedStateRegistry);
b.bind(SegmentReplicationStatsTracker.class).toInstance(segmentReplicationStatsTracker);
b.bind(SearchRequestOperationsCompositeListenerFactory.class).toInstance(searchRequestOperationsCompositeListenerFactory);
b.bind(PluginMetadataClient.class).toInstance(defaultPluginMetadataClient);
});
injector = modules.createInjector();

Expand Down
27 changes: 27 additions & 0 deletions server/src/main/java/org/opensearch/plugins/SdkAwarePlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.plugins;

import org.opensearch.plugins.sdk.PluginMetadataClient;

/**
* SdkAwarePlugin is an additional extension point for {@link Plugin}'s for receiving
* OpenSearch abstractions.
*/
public interface SdkAwarePlugin {

void setupSdkPlugin(Dependencies dependencies);

/**
* Dependencies is a simple container class holding plugin sdk dependencies.
*/
public static interface Dependencies {
PluginMetadataClient getPluginMetadataClient();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.plugins.sdk;

import org.opensearch.cluster.ClusterState;
import org.opensearch.cluster.metadata.IndexMetadata;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.metadata.MappingMetadata;
import org.opensearch.cluster.metadata.Metadata;
import org.opensearch.cluster.service.ClusterService;
import org.opensearch.common.CheckedSupplier;
import org.opensearch.common.annotation.ExperimentalApi;
import org.opensearch.common.settings.ClusterSettings;
import org.opensearch.common.settings.IndexScopedSettings;
import org.opensearch.common.settings.Settings;
import org.opensearch.core.index.Index;
import org.opensearch.plugins.sdk.actions.ConcreteIndicesRequest;
import org.opensearch.plugins.sdk.actions.ConcreteIndicesResponse;
import org.opensearch.plugins.sdk.actions.GetIndexMappingMetadataRequest;
import org.opensearch.plugins.sdk.actions.GetIndexMappingMetadataResponse;
import org.opensearch.plugins.sdk.actions.GetIndexSettingsRequest;
import org.opensearch.plugins.sdk.actions.GetIndexSettingsResponse;
import org.opensearch.plugins.sdk.actions.GetSystemSettingsRequest;
import org.opensearch.plugins.sdk.actions.GetSystemSettingsResponse;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

/**
* DefaultPluginMetadataClient is the de-facto implementation of the
* PluginMetadataClient.
*
* @see PluginMetadataClient
*/
@ExperimentalApi
public class DefaultPluginMetadataClient implements PluginMetadataClient {

private final ClusterService clusterService;
private final IndexNameExpressionResolver indexNameExpressionResolver;
private final IndexScopedSettings indexScopedSettings;

public DefaultPluginMetadataClient(ClusterService clusterService,
IndexNameExpressionResolver indexNameExpressionResolver,
IndexScopedSettings indexScopedSettings) {

this.clusterService = clusterService;
this.indexNameExpressionResolver = indexNameExpressionResolver;
this.indexScopedSettings = indexScopedSettings;
}

@Override
public CompletionStage<ConcreteIndicesResponse> concreteIndices(
ConcreteIndicesRequest request
) {
return synchronously(() -> {
ClusterState state = clusterService.state();

Index[] result = indexNameExpressionResolver.concreteIndices(
state,
request.indicesOptions(),
request.indexExpressions());

return ConcreteIndicesResponse.builder()
.indices(result)
.build();
});
}

@Override
public CompletionStage<GetSystemSettingsResponse> getSystemSettings(
GetSystemSettingsRequest request
) {
return synchronously(() -> {
ClusterSettings clusterSettings = clusterService.getClusterSettings();
Settings settings = clusterSettings.toSettings();
Set<String> settingKeys = Set.of(request.settings());
settings = settings.filter(settingKeys::contains);
return GetSystemSettingsResponse.builder()
.settings(settings)
.build();
});
}

@Override
public CompletionStage<GetIndexMappingMetadataResponse> getIndexMappingMetadata(
GetIndexMappingMetadataRequest request
) {
return synchronously(() -> {
ClusterState state = clusterService.state();
Metadata metadata = state.metadata();
Map<Index, MappingMetadata> result = new HashMap<>();
for (Index index : request.indices()) {
MappingMetadata mappingMetadata = metadata.getIndexSafe(index).mapping();
result.put(index, mappingMetadata);
}
return GetIndexMappingMetadataResponse.builder()
.mappingMetadata(result)
.build();
});
}

@Override
public CompletionStage<GetIndexSettingsResponse> getIndexSettings(
GetIndexSettingsRequest request
) {
return synchronously(() -> {
ClusterState state = clusterService.state();
Settings currentDefaultIndexScopedSettings = indexScopedSettings.toSettings();
Set<String> settingsKeys = Set.of(request.settings());
Map<Index, Settings> result = new HashMap<>();

for (Index index : request.indices()) {
IndexMetadata indexMetadata = state.metadata().getIndexSafe(index);

Settings indexSettings = indexMetadata.getSettings();

Settings resultSettings = Settings.builder()
.put(currentDefaultIndexScopedSettings)
.put(indexSettings)
.build()
.filter(settingsKeys::contains);

result.put(index, resultSettings);
}

return GetIndexSettingsResponse.builder()
.settings(result)
.build();
});
}

private static <T> CompletionStage<T> synchronously(CheckedSupplier<T, Exception> supplier) {
try {
T result = supplier.get();
return CompletableFuture.completedStage(result);
} catch (Exception e) {
return CompletableFuture.failedStage(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.plugins.sdk;

import org.opensearch.action.support.IndicesOptions;
import org.opensearch.cluster.ClusterState;
import org.opensearch.common.annotation.ExperimentalApi;
import org.opensearch.common.settings.Setting;
import org.opensearch.plugins.sdk.actions.ConcreteIndicesRequest;
import org.opensearch.plugins.sdk.actions.ConcreteIndicesResponse;
import org.opensearch.plugins.sdk.actions.GetIndexMappingMetadataRequest;
import org.opensearch.plugins.sdk.actions.GetIndexMappingMetadataResponse;
import org.opensearch.plugins.sdk.actions.GetIndexSettingsRequest;
import org.opensearch.plugins.sdk.actions.GetIndexSettingsResponse;
import org.opensearch.plugins.sdk.actions.GetSystemSettingsRequest;
import org.opensearch.plugins.sdk.actions.GetSystemSettingsResponse;

import java.util.concurrent.CompletionStage;

/**
* PluginMetadataClient provides an abstract interface for plugins to access OpenSearch core cluster metadata.
*/
@ExperimentalApi
public interface PluginMetadataClient {

/**
* Resolves the concrete indices for a given set of index name expressions.
*
* This is an abstraction over IndexNameExpressionResolver.
*
* @see org.opensearch.cluster.metadata.IndexNameExpressionResolver#concreteIndexNames(ClusterState, IndicesOptions, String...)
*
* @param request The index names to resolve and associated resolution options
* @return The resolved concrete index names
*/
CompletionStage<ConcreteIndicesResponse> concreteIndices(ConcreteIndicesRequest request);

/**
* Gets the system settings for a particular set of setting.
*
* This is an abstraction over ClusterSetting access.
*
* @see org.opensearch.common.settings.ClusterSettings#get(Setting)
*
* @param request The settings to retrieve.
* @return The system settings.
*/
CompletionStage<GetSystemSettingsResponse> getSystemSettings(GetSystemSettingsRequest request);

/**
* Gets the mapping metadata of the provided indices.
*
* This is an abstraction over ClusterState Metadata access.
*
* @see org.opensearch.cluster.metadata.Metadata#indices()
*
* @param request The indices to retrieve mapping metadata for.
* @return The mapping metadata for the requested indices.
*/
CompletionStage<GetIndexMappingMetadataResponse> getIndexMappingMetadata(GetIndexMappingMetadataRequest request);

/**
* Gets the index settings for a particular set of indices.
*
* This is an abstraction over ClusterState Metadata access.
*
* @see org.opensearch.cluster.metadata.IndexMetadata#getSettings()
*
* @param request The indices to retrieve mapping metadata for.
* @return The mapping metadata for the requested indices.
*/
CompletionStage<GetIndexSettingsResponse> getIndexSettings(GetIndexSettingsRequest request);
}
Loading

0 comments on commit 9d9e2dd

Please sign in to comment.