Note: This document is evolving and is in draft state.
A goal of the Extensions SDK is to ease developer migration of plugins to extensions. Supporting this goal:
- Plugin interfaces and their extension points are being migrated to equivalent Extension interfaces
- Same-named methods and arguments are used whenever possible, with differences highlighted in this migration guide
- Wrapper classes are provided when possible to retain existing code logic
Migration of the Anomaly Detection Plugin to an Extension is in progress to both identify and refine migration challenges and provide examples to other plugin developers.
- Change the implementing class
FooPlugin
toFooExtension
and either implement theExtension
interface or extendBaseExtension
.- Implement other corresponding Extension interfaces, for example
ActionPlugin
interface would beActionExtension
. - Change extension point implementation, if necessary, to conform to new types. For example,
RestHandler
classes becomeExtensionRestHandler
classes. Consider extending base implementations such asBaseExtensionRestHandler
to provide additional convenience methods. - The
createComponents()
method no longer takes parameters. The parameters formerly sent in a constructor may be accessed using Guice@Inject
annotation. - Extension developers who need to use a Rest Client should initialize it using
SDKClient
and return the appropriate client as an object increateComponents()
to make it available for extension actions. - Annotations of
@Inject
in actions bound usinggetActions()
should change the import from the OpenSearch internal package tocom.google.inject.Inject
- Implement other corresponding Extension interfaces, for example
- Calls to
clusterService.getClusterSettings().addSettingsUpdateConsumer()
with a single consumer do not require changes. However, this method has an overload which takes a map parameter, and can do multiple consumer updates more efficiently. - Calls to
clusterService.state()
do not require changes.
The SDKClient
provides two (eventually three) client options.
The Java Client for OpenSearch (OpenSearchClient
) will be supported with both synchronous and asynchronous clients, and 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.
The SDKRestClient
provides wrapper methods matching the Client
API (but not implementing it), implemented internally with the (soon to be deprecated) RestHighLevelClient
. While this speeds migration efforts, it should be considered a temporary "bridge" with follow up migration efforts to the OpenSearchClient
planned.
- While the class names and method parameters are the same, the
Request
andResponse
classes are often in different packages. In most cases, other than changingimport
statements, no additional code changes are required. In a few cases, there are minor changes required to interface with the new response class API.
The client.execute(action, request, responseListener)
method is implemented on the SDKClient.
For TransportActions internal to the plugin (registered with getActions()
), change the transport action inheritance from HandledTransportAction to directly inherit from TransportAction
.
TransportActions on OpenSearch 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. A few examples of the types of changes needed include:
- Some transport actions on OpenSearch, such as the
GetFieldMappingsAction
, are exposed via the REST API and should be called using those clients. - Some information available from services on OpenSearch, such as the state on ClusterService, stats on IndexingPressure object, and others, are designed for local access and would transfer far more data than needed if implemented directly. Calls to these services should be replaced by REST API calls to endpoints which filter to just the information required. For example, cluster state associated with inidices should use one of the Index API endpoints. Indexing Pressure can be retrieved by Node API endpoints.
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 an 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:
this.environmentSettings = extensionsRunner.getEnvironmentSettings();
this.transportService = extensionsRunner.getExtensionTransportService();
this.restClient = anomalyDetectorExtension.getRestClient();
this.sdkClusterService = new SDKClusterService(extensionsRunner);
Many of these components are also available via Guice injection.
Optionally change the routes()
to routeHandlers()
. Change prepareRequest()
to handleRequest()
.
- Add the
request
as the first parameter, the remainder of the parameters should be the same.
While most SDKRestClient client return types match existing classes, some changes may be necessary to conform to the new method signatures. Examples include:
- InternalAggregation/Min/Max should be replaced with the corresponding Parsed class. For example:
ParsedStringTerms
fromStringTerms
to fetch the aggregation for a specific index.ParsedMax
fromInternalMax
to fetch max agg result parsed between nodes.
- Replace
ObjectObjectCursor<String, List<AliasMetadata>> entry
withEntry<String, Set<AliasMetadata>> entry