OpenSearch SDK for Java

Extension Documentation

OpenSearch Logo

opensearch-sdk-java repository

OpenSearch user documentation

Plugin Migration

Note: This document is evolving and is in draft state.

The goal of the Extensions SDK is to ease developer migration of plugins to extensions. We’ll be supporting this goal by doing the following:

Migration of the Anomaly Detection plugin to an extension is in progress. We’ll use it to identify and refine migration challenges and provide examples to other plugin developers.

Use the notes in the following sections to help migrate a plugin to an extension.

Implement extension interfaces and extension points

Use wrapper classes

Refer to the following notes for using wrapper classes.

Replace ClusterService with SDKClusterService

Replace Client with SDKClient: either OpenSearchClient (JavaClient) or SDKRestClient

The SDKClient provides two (eventually three) client options.

The Java client for OpenSearch (OpenSearchClient) will be supported with both synchronous and asynchronous clients, is actively developed along with other language clients, and should be used whenever possible. These clients do have significant implementation differences compared to the existing Client interface implemented by plugins.

Change plugin and OpenSearch TransportAction implementations

The SDKRestClient provides wrapper methods matching the Client API (but not implementing it), implemented internally with the (soon to be deprecated) RestHighLevelClient. While this expedites migration efforts, it should be considered a temporary “bridge,” with follow-up migration efforts to the OpenSearchClient planned.

The client.execute(action, request, responseListener) method is implemented in the SDKClient.

For TransportActions internal to the plugin (registered with getActions()), change the transport action inheritance from HandledTransportAction to directly inherit from TransportAction.

OpenSearch TransportActions are not accessible to extensions and will need to be replaced with functionality from either a client (OpenSearch client for Java or the SDKRestClient) or some other functionality directly provided by the Extensions SDK. The following are a few examples of the types of changes needed:

Replace RestHandler with ExtensionRestHandler

Pass the ExtensionsRunner and Extension objects to the handler and access createComponent equivalents, such as:

this.sdkNamedXContentRegistry = extensionsRunner.getNamedXContentRegistry();

When a NamedXContentRegistry object is required, get the current one from this.sdkNamedXContentRegistry.getRegistry().

When initializing objects for createComponents, the SDKNamedXContentRegistry should be passed to the component constructors. In the objects that are instantiated for createComponents, whenever there is a NamedXContentRegistry object required, call getRegistry() from the SDKNamedXContentRegistry object passed from the constructor, for example:

XContentParser parser = XContentType.JSON
                    .xContent()
                    .createParser(sdkNamedXContentRegistry.getRegistry(), LoggingDeprecationHandler.INSTANCE, value);

Other potential initialization values are:

this.environmentSettings = extensionsRunner.getEnvironmentSettings();
this.transportService = extensionsRunner.getSdkTransportService().getTransportService();
this.restClient = anomalyDetectorExtension.getRestClient();
this.sdkClusterService = new SDKClusterService(extensionsRunner);

Many of these components are also available via Guice injection.

Replace Route with NamedRoute

Change routes() to be NamedRoutes. Here is a sample of an existing route converted to a named route: Before:

public List<Route> routes() {
    return ImmutableList.of(
            new Route(GET, "/uri")
        );
}

With new scheme:

private Function<RestRequest, RestResponse> uriHandler = () -> {};
public List<NamedRoute> routes() {
    return ImmutableList.of(
            new NamedRoute.Builder().method(GET).path("/uri").uniqueName("extension:uri").handler(uriHandler).build()
        );
}

You can optionally also add actionNames() to this route. These should correspond to any current actions defined as permissions in roles. actionNames() serve as a valuable tool for converting plugins into extensions while maintaining compatibility with pre-defined reserved roles. Ensure that these name-to-route mappings are easily accessible to the cluster admins to allow granting access to these APIs.

Change prepareRequest() to handleRequest().

Replace BytesRestResponse with ExtensionRestResponse

Replace Return Type for SDKRestClient

While most SDKRestClient client return types match existing classes, some changes may be necessary to conform to the new method signatures. Examples include: