Move RestHandler registration to ActionModule and ActionPlugin

`RestHandler`s are highly tied to actions so registering them in the
same place makes sense.

Removes the need to for plugins to check if they are in transport client
mode before registering a RestHandler - `getRestHandlers` isn't called
at all in transport client mode.

This caused guice to throw a massive fit about the circular dependency
between NodeClient and the allocation deciders. I broke the circular
dependency by registering the actions map with the node client after
instantiation.
This commit is contained in:
Nik Everett 2016-06-29 14:55:31 -04:00
parent 00356edd33
commit 8db43c0107
16 changed files with 488 additions and 340 deletions

View File

@ -194,14 +194,120 @@ import org.elasticsearch.common.NamedRegistry;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.multibindings.MapBinder;
import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.ActionPlugin.ActionHandler;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.action.admin.cluster.allocation.RestClusterAllocationExplainAction;
import org.elasticsearch.rest.action.admin.cluster.health.RestClusterHealthAction;
import org.elasticsearch.rest.action.admin.cluster.node.hotthreads.RestNodesHotThreadsAction;
import org.elasticsearch.rest.action.admin.cluster.node.info.RestNodesInfoAction;
import org.elasticsearch.rest.action.admin.cluster.node.stats.RestNodesStatsAction;
import org.elasticsearch.rest.action.admin.cluster.node.tasks.RestCancelTasksAction;
import org.elasticsearch.rest.action.admin.cluster.node.tasks.RestGetTaskAction;
import org.elasticsearch.rest.action.admin.cluster.node.tasks.RestListTasksAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.delete.RestDeleteRepositoryAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.get.RestGetRepositoriesAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.put.RestPutRepositoryAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.verify.RestVerifyRepositoryAction;
import org.elasticsearch.rest.action.admin.cluster.reroute.RestClusterRerouteAction;
import org.elasticsearch.rest.action.admin.cluster.settings.RestClusterGetSettingsAction;
import org.elasticsearch.rest.action.admin.cluster.settings.RestClusterUpdateSettingsAction;
import org.elasticsearch.rest.action.admin.cluster.shards.RestClusterSearchShardsAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.create.RestCreateSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.delete.RestDeleteSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.get.RestGetSnapshotsAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.restore.RestRestoreSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.status.RestSnapshotsStatusAction;
import org.elasticsearch.rest.action.admin.cluster.state.RestClusterStateAction;
import org.elasticsearch.rest.action.admin.cluster.stats.RestClusterStatsAction;
import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestDeleteStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestGetStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestPutStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.tasks.RestPendingClusterTasksAction;
import org.elasticsearch.rest.action.admin.indices.RestRolloverIndexAction;
import org.elasticsearch.rest.action.admin.indices.RestShrinkIndexAction;
import org.elasticsearch.rest.action.admin.indices.alias.RestIndicesAliasesAction;
import org.elasticsearch.rest.action.admin.indices.alias.delete.RestIndexDeleteAliasesAction;
import org.elasticsearch.rest.action.admin.indices.alias.get.RestGetAliasesAction;
import org.elasticsearch.rest.action.admin.indices.alias.head.RestAliasesExistAction;
import org.elasticsearch.rest.action.admin.indices.alias.put.RestIndexPutAliasAction;
import org.elasticsearch.rest.action.admin.indices.analyze.RestAnalyzeAction;
import org.elasticsearch.rest.action.admin.indices.cache.clear.RestClearIndicesCacheAction;
import org.elasticsearch.rest.action.admin.indices.close.RestCloseIndexAction;
import org.elasticsearch.rest.action.admin.indices.create.RestCreateIndexAction;
import org.elasticsearch.rest.action.admin.indices.delete.RestDeleteIndexAction;
import org.elasticsearch.rest.action.admin.indices.exists.indices.RestIndicesExistsAction;
import org.elasticsearch.rest.action.admin.indices.exists.types.RestTypesExistsAction;
import org.elasticsearch.rest.action.admin.indices.flush.RestFlushAction;
import org.elasticsearch.rest.action.admin.indices.flush.RestSyncedFlushAction;
import org.elasticsearch.rest.action.admin.indices.forcemerge.RestForceMergeAction;
import org.elasticsearch.rest.action.admin.indices.get.RestGetIndicesAction;
import org.elasticsearch.rest.action.admin.indices.mapping.get.RestGetFieldMappingAction;
import org.elasticsearch.rest.action.admin.indices.mapping.get.RestGetMappingAction;
import org.elasticsearch.rest.action.admin.indices.mapping.put.RestPutMappingAction;
import org.elasticsearch.rest.action.admin.indices.open.RestOpenIndexAction;
import org.elasticsearch.rest.action.admin.indices.recovery.RestRecoveryAction;
import org.elasticsearch.rest.action.admin.indices.refresh.RestRefreshAction;
import org.elasticsearch.rest.action.admin.indices.segments.RestIndicesSegmentsAction;
import org.elasticsearch.rest.action.admin.indices.settings.RestGetSettingsAction;
import org.elasticsearch.rest.action.admin.indices.settings.RestUpdateSettingsAction;
import org.elasticsearch.rest.action.admin.indices.shards.RestIndicesShardStoresAction;
import org.elasticsearch.rest.action.admin.indices.stats.RestIndicesStatsAction;
import org.elasticsearch.rest.action.admin.indices.template.delete.RestDeleteIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.template.get.RestGetIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.template.head.RestHeadIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.template.put.RestPutIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.upgrade.RestUpgradeAction;
import org.elasticsearch.rest.action.admin.indices.validate.query.RestValidateQueryAction;
import org.elasticsearch.rest.action.bulk.RestBulkAction;
import org.elasticsearch.rest.action.cat.AbstractCatAction;
import org.elasticsearch.rest.action.cat.RestAliasAction;
import org.elasticsearch.rest.action.cat.RestAllocationAction;
import org.elasticsearch.rest.action.cat.RestCatAction;
import org.elasticsearch.rest.action.cat.RestFielddataAction;
import org.elasticsearch.rest.action.cat.RestHealthAction;
import org.elasticsearch.rest.action.cat.RestIndicesAction;
import org.elasticsearch.rest.action.cat.RestMasterAction;
import org.elasticsearch.rest.action.cat.RestNodeAttrsAction;
import org.elasticsearch.rest.action.cat.RestNodesAction;
import org.elasticsearch.rest.action.cat.RestPluginsAction;
import org.elasticsearch.rest.action.cat.RestRepositoriesAction;
import org.elasticsearch.rest.action.cat.RestSegmentsAction;
import org.elasticsearch.rest.action.cat.RestShardsAction;
import org.elasticsearch.rest.action.cat.RestSnapshotAction;
import org.elasticsearch.rest.action.cat.RestTasksAction;
import org.elasticsearch.rest.action.cat.RestThreadPoolAction;
import org.elasticsearch.rest.action.delete.RestDeleteAction;
import org.elasticsearch.rest.action.explain.RestExplainAction;
import org.elasticsearch.rest.action.fieldstats.RestFieldStatsAction;
import org.elasticsearch.rest.action.get.RestGetAction;
import org.elasticsearch.rest.action.get.RestGetSourceAction;
import org.elasticsearch.rest.action.get.RestHeadAction;
import org.elasticsearch.rest.action.get.RestMultiGetAction;
import org.elasticsearch.rest.action.index.RestIndexAction;
import org.elasticsearch.rest.action.ingest.RestDeletePipelineAction;
import org.elasticsearch.rest.action.ingest.RestGetPipelineAction;
import org.elasticsearch.rest.action.ingest.RestPutPipelineAction;
import org.elasticsearch.rest.action.ingest.RestSimulatePipelineAction;
import org.elasticsearch.rest.action.main.RestMainAction;
import org.elasticsearch.rest.action.search.RestClearScrollAction;
import org.elasticsearch.rest.action.search.RestMultiSearchAction;
import org.elasticsearch.rest.action.search.RestSearchAction;
import org.elasticsearch.rest.action.search.RestSearchScrollAction;
import org.elasticsearch.rest.action.suggest.RestSuggestAction;
import org.elasticsearch.rest.action.termvectors.RestMultiTermVectorsAction;
import org.elasticsearch.rest.action.termvectors.RestTermVectorsAction;
import org.elasticsearch.rest.action.update.RestUpdateAction;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
@ -212,21 +318,27 @@ import static java.util.Collections.unmodifiableMap;
public class ActionModule extends AbstractModule {
private final boolean transportClient;
private final Settings settings;
private final List<ActionPlugin> actionPlugins;
private final Map<String, ActionHandler<?, ?>> actions;
private final List<Class<? extends ActionFilter>> actionFilters;
private final AutoCreateIndex autoCreateIndex;
private final DestructiveOperations destructiveOperations;
private final RestController restController;
public ActionModule(boolean ingestEnabled, boolean transportClient, Settings settings, IndexNameExpressionResolver resolver,
ClusterSettings clusterSettings, List<ActionPlugin> actionPlugins) {
this.transportClient = transportClient;
this.settings = settings;
this.actionPlugins = actionPlugins;
actions = setupActions(actionPlugins);
actionFilters = setupActionFilters(actionPlugins, ingestEnabled);
autoCreateIndex = transportClient ? null : new AutoCreateIndex(settings, resolver);
destructiveOperations = new DestructiveOperations(settings, clusterSettings);
restController = new RestController(settings);
}
private Map<String, ActionHandler<?, ?>> setupActions(List<ActionPlugin> actionPlugins) {
static Map<String, ActionHandler<?, ?>> setupActions(List<ActionPlugin> actionPlugins) {
// Subclass NamedRegistry for easy registration
class ActionRegistry extends NamedRegistry<ActionHandler<?, ?>> {
public ActionRegistry() {
@ -357,6 +469,149 @@ public class ActionModule extends AbstractModule {
return unmodifiableList(filters);
}
static Set<Class<? extends RestHandler>> setupRestHandlers(List<ActionPlugin> actionPlugins) {
Set<Class<? extends RestHandler>> handlers = new HashSet<>();
registerRestHandler(handlers, RestMainAction.class);
registerRestHandler(handlers, RestNodesInfoAction.class);
registerRestHandler(handlers, RestNodesStatsAction.class);
registerRestHandler(handlers, RestNodesHotThreadsAction.class);
registerRestHandler(handlers, RestClusterAllocationExplainAction.class);
registerRestHandler(handlers, RestClusterStatsAction.class);
registerRestHandler(handlers, RestClusterStateAction.class);
registerRestHandler(handlers, RestClusterHealthAction.class);
registerRestHandler(handlers, RestClusterUpdateSettingsAction.class);
registerRestHandler(handlers, RestClusterGetSettingsAction.class);
registerRestHandler(handlers, RestClusterRerouteAction.class);
registerRestHandler(handlers, RestClusterSearchShardsAction.class);
registerRestHandler(handlers, RestPendingClusterTasksAction.class);
registerRestHandler(handlers, RestPutRepositoryAction.class);
registerRestHandler(handlers, RestGetRepositoriesAction.class);
registerRestHandler(handlers, RestDeleteRepositoryAction.class);
registerRestHandler(handlers, RestVerifyRepositoryAction.class);
registerRestHandler(handlers, RestGetSnapshotsAction.class);
registerRestHandler(handlers, RestCreateSnapshotAction.class);
registerRestHandler(handlers, RestRestoreSnapshotAction.class);
registerRestHandler(handlers, RestDeleteSnapshotAction.class);
registerRestHandler(handlers, RestSnapshotsStatusAction.class);
registerRestHandler(handlers, RestIndicesExistsAction.class);
registerRestHandler(handlers, RestTypesExistsAction.class);
registerRestHandler(handlers, RestGetIndicesAction.class);
registerRestHandler(handlers, RestIndicesStatsAction.class);
registerRestHandler(handlers, RestIndicesSegmentsAction.class);
registerRestHandler(handlers, RestIndicesShardStoresAction.class);
registerRestHandler(handlers, RestGetAliasesAction.class);
registerRestHandler(handlers, RestAliasesExistAction.class);
registerRestHandler(handlers, RestIndexDeleteAliasesAction.class);
registerRestHandler(handlers, RestIndexPutAliasAction.class);
registerRestHandler(handlers, RestIndicesAliasesAction.class);
registerRestHandler(handlers, RestCreateIndexAction.class);
registerRestHandler(handlers, RestShrinkIndexAction.class);
registerRestHandler(handlers, RestRolloverIndexAction.class);
registerRestHandler(handlers, RestDeleteIndexAction.class);
registerRestHandler(handlers, RestCloseIndexAction.class);
registerRestHandler(handlers, RestOpenIndexAction.class);
registerRestHandler(handlers, RestUpdateSettingsAction.class);
registerRestHandler(handlers, RestGetSettingsAction.class);
registerRestHandler(handlers, RestAnalyzeAction.class);
registerRestHandler(handlers, RestGetIndexTemplateAction.class);
registerRestHandler(handlers, RestPutIndexTemplateAction.class);
registerRestHandler(handlers, RestDeleteIndexTemplateAction.class);
registerRestHandler(handlers, RestHeadIndexTemplateAction.class);
registerRestHandler(handlers, RestPutMappingAction.class);
registerRestHandler(handlers, RestGetMappingAction.class);
registerRestHandler(handlers, RestGetFieldMappingAction.class);
registerRestHandler(handlers, RestRefreshAction.class);
registerRestHandler(handlers, RestFlushAction.class);
registerRestHandler(handlers, RestSyncedFlushAction.class);
registerRestHandler(handlers, RestForceMergeAction.class);
registerRestHandler(handlers, RestUpgradeAction.class);
registerRestHandler(handlers, RestClearIndicesCacheAction.class);
registerRestHandler(handlers, RestIndexAction.class);
registerRestHandler(handlers, RestGetAction.class);
registerRestHandler(handlers, RestGetSourceAction.class);
registerRestHandler(handlers, RestHeadAction.Document.class);
registerRestHandler(handlers, RestHeadAction.Source.class);
registerRestHandler(handlers, RestMultiGetAction.class);
registerRestHandler(handlers, RestDeleteAction.class);
registerRestHandler(handlers, org.elasticsearch.rest.action.count.RestCountAction.class);
registerRestHandler(handlers, RestSuggestAction.class);
registerRestHandler(handlers, RestTermVectorsAction.class);
registerRestHandler(handlers, RestMultiTermVectorsAction.class);
registerRestHandler(handlers, RestBulkAction.class);
registerRestHandler(handlers, RestUpdateAction.class);
registerRestHandler(handlers, RestSearchAction.class);
registerRestHandler(handlers, RestSearchScrollAction.class);
registerRestHandler(handlers, RestClearScrollAction.class);
registerRestHandler(handlers, RestMultiSearchAction.class);
registerRestHandler(handlers, RestValidateQueryAction.class);
registerRestHandler(handlers, RestExplainAction.class);
registerRestHandler(handlers, RestRecoveryAction.class);
// Scripts API
registerRestHandler(handlers, RestGetStoredScriptAction.class);
registerRestHandler(handlers, RestPutStoredScriptAction.class);
registerRestHandler(handlers, RestDeleteStoredScriptAction.class);
registerRestHandler(handlers, RestFieldStatsAction.class);
// Tasks API
registerRestHandler(handlers, RestListTasksAction.class);
registerRestHandler(handlers, RestGetTaskAction.class);
registerRestHandler(handlers, RestCancelTasksAction.class);
// Ingest API
registerRestHandler(handlers, RestPutPipelineAction.class);
registerRestHandler(handlers, RestGetPipelineAction.class);
registerRestHandler(handlers, RestDeletePipelineAction.class);
registerRestHandler(handlers, RestSimulatePipelineAction.class);
// CAT API
registerRestHandler(handlers, RestCatAction.class);
registerRestHandler(handlers, RestAllocationAction.class);
registerRestHandler(handlers, RestShardsAction.class);
registerRestHandler(handlers, RestMasterAction.class);
registerRestHandler(handlers, RestNodesAction.class);
registerRestHandler(handlers, RestTasksAction.class);
registerRestHandler(handlers, RestIndicesAction.class);
registerRestHandler(handlers, RestSegmentsAction.class);
// Fully qualified to prevent interference with rest.action.count.RestCountAction
registerRestHandler(handlers, org.elasticsearch.rest.action.cat.RestCountAction.class);
// Fully qualified to prevent interference with rest.action.indices.RestRecoveryAction
registerRestHandler(handlers, org.elasticsearch.rest.action.cat.RestRecoveryAction.class);
registerRestHandler(handlers, RestHealthAction.class);
registerRestHandler(handlers, org.elasticsearch.rest.action.cat.RestPendingClusterTasksAction.class);
registerRestHandler(handlers, RestAliasAction.class);
registerRestHandler(handlers, RestThreadPoolAction.class);
registerRestHandler(handlers, RestPluginsAction.class);
registerRestHandler(handlers, RestFielddataAction.class);
registerRestHandler(handlers, RestNodeAttrsAction.class);
registerRestHandler(handlers, RestRepositoriesAction.class);
registerRestHandler(handlers, RestSnapshotAction.class);
for (ActionPlugin plugin : actionPlugins) {
for (Class<? extends RestHandler> handler : plugin.getRestHandlers()) {
registerRestHandler(handlers, handler);
}
}
return handlers;
}
private static void registerRestHandler(Set<Class<? extends RestHandler>> handlers, Class<? extends RestHandler> handler) {
if (handlers.contains(handler)) {
throw new IllegalArgumentException("can't register the same [rest_handler] more than once for [" + handler.getName() + "]");
}
handlers.add(handler);
}
@Override
protected void configure() {
Multibinder<ActionFilter> actionFilterMultibinder = Multibinder.newSetBinder(binder(), ActionFilter.class);
@ -374,11 +629,12 @@ public class ActionModule extends AbstractModule {
for (Map.Entry<String, ActionHandler<?, ?>> entry : actions.entrySet()) {
actionsBinder.addBinding(entry.getKey()).toInstance(entry.getValue().getAction());
}
// register GenericAction -> transportAction Map that can be injected to instances.
// also register any supporting classes
if (false == transportClient) {
// Supporting classes only used when not a transport client
bind(AutoCreateIndex.class).toInstance(autoCreateIndex);
bind(TransportLivenessAction.class).asEagerSingleton();
// register GenericAction -> transportAction Map used by NodeClient
@SuppressWarnings("rawtypes")
MapBinder<GenericAction, TransportAction> transportActionsBinder
= MapBinder.newMapBinder(binder(), GenericAction.class, TransportAction.class);
@ -390,6 +646,23 @@ public class ActionModule extends AbstractModule {
bind(supportAction).asEagerSingleton();
}
}
// Bind the RestController which is required (by Node) even if rest isn't enabled.
bind(RestController.class).toInstance(restController);
// Setup the RestHandlers
if (NetworkModule.HTTP_ENABLED.get(settings)) {
Multibinder<RestHandler> restHandlers = Multibinder.newSetBinder(binder(), RestHandler.class);
Multibinder<AbstractCatAction> catHandlers = Multibinder.newSetBinder(binder(), AbstractCatAction.class);
for (Class<? extends RestHandler> handler : setupRestHandlers(actionPlugins)) {
bind(handler).asEagerSingleton();
if (AbstractCatAction.class.isAssignableFrom(handler)) {
catHandlers.addBinding().to(handler.asSubclass(AbstractCatAction.class));
} else {
restHandlers.addBinding().to(handler);
}
}
}
}
}
}

View File

@ -27,25 +27,24 @@ import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.GenericAction;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.client.support.AbstractClient;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import java.util.Map;
import static java.util.Collections.unmodifiableMap;
/**
*
*/
public class NodeClient extends AbstractClient {
private final Map<GenericAction, TransportAction> actions;
private Map<GenericAction, TransportAction> actions;
@Inject
public NodeClient(Settings settings, ThreadPool threadPool, Map<GenericAction, TransportAction> actions) {
public NodeClient(Settings settings, ThreadPool threadPool) {
super(settings, threadPool);
this.actions = unmodifiableMap(actions);
}
public void intialize(Map<GenericAction, TransportAction> actions) {
this.actions = actions;
}
@Override
@ -57,6 +56,9 @@ public class NodeClient extends AbstractClient {
@Override
public <Request extends ActionRequest<Request>, Response extends ActionResponse, RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder>> void doExecute(
Action<Request, Response, RequestBuilder> action, Request request, ActionListener<Response> listener) {
if (actions == null) {
throw new IllegalStateException("NodeClient has not been initialized");
}
TransportAction<Request, Response> transportAction = actions.get(action);
if (transportAction == null) {
throw new IllegalStateException("failed to find action [" + action + "] to execute");

View File

@ -27,7 +27,6 @@ import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.regex.Regex;
@ -57,7 +56,6 @@ public class IndexNameExpressionResolver extends AbstractComponent {
private final List<ExpressionResolver> expressionResolvers;
private final DateMathExpressionResolver dateMathExpressionResolver;
@Inject
public IndexNameExpressionResolver(Settings settings) {
super(settings);
expressionResolvers = Arrays.asList(

View File

@ -45,7 +45,7 @@ public class NamedRegistry<T> {
requireNonNull(name, "name is required");
requireNonNull(t, targetName + " is required");
if (registry.putIfAbsent(name, t) != null) {
throw new IllegalArgumentException(targetName + " for name " + name + " already registered");
throw new IllegalArgumentException(targetName + " for name [" + name + "] already registered");
}
}

View File

@ -41,109 +41,6 @@ import org.elasticsearch.common.util.ExtensionPoint;
import org.elasticsearch.http.HttpServer;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.http.netty.NettyHttpServerTransport;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.action.admin.cluster.allocation.RestClusterAllocationExplainAction;
import org.elasticsearch.rest.action.admin.cluster.health.RestClusterHealthAction;
import org.elasticsearch.rest.action.admin.cluster.node.hotthreads.RestNodesHotThreadsAction;
import org.elasticsearch.rest.action.admin.cluster.node.info.RestNodesInfoAction;
import org.elasticsearch.rest.action.admin.cluster.node.stats.RestNodesStatsAction;
import org.elasticsearch.rest.action.admin.cluster.node.tasks.RestCancelTasksAction;
import org.elasticsearch.rest.action.admin.cluster.node.tasks.RestGetTaskAction;
import org.elasticsearch.rest.action.admin.cluster.node.tasks.RestListTasksAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.delete.RestDeleteRepositoryAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.get.RestGetRepositoriesAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.put.RestPutRepositoryAction;
import org.elasticsearch.rest.action.admin.cluster.repositories.verify.RestVerifyRepositoryAction;
import org.elasticsearch.rest.action.admin.cluster.reroute.RestClusterRerouteAction;
import org.elasticsearch.rest.action.admin.cluster.settings.RestClusterGetSettingsAction;
import org.elasticsearch.rest.action.admin.cluster.settings.RestClusterUpdateSettingsAction;
import org.elasticsearch.rest.action.admin.cluster.shards.RestClusterSearchShardsAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.create.RestCreateSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.delete.RestDeleteSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.get.RestGetSnapshotsAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.restore.RestRestoreSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.snapshots.status.RestSnapshotsStatusAction;
import org.elasticsearch.rest.action.admin.cluster.state.RestClusterStateAction;
import org.elasticsearch.rest.action.admin.cluster.stats.RestClusterStatsAction;
import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestDeleteStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestGetStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.storedscripts.RestPutStoredScriptAction;
import org.elasticsearch.rest.action.admin.cluster.tasks.RestPendingClusterTasksAction;
import org.elasticsearch.rest.action.admin.indices.RestRolloverIndexAction;
import org.elasticsearch.rest.action.admin.indices.RestShrinkIndexAction;
import org.elasticsearch.rest.action.admin.indices.alias.RestIndicesAliasesAction;
import org.elasticsearch.rest.action.admin.indices.alias.delete.RestIndexDeleteAliasesAction;
import org.elasticsearch.rest.action.admin.indices.alias.get.RestGetAliasesAction;
import org.elasticsearch.rest.action.admin.indices.alias.head.RestAliasesExistAction;
import org.elasticsearch.rest.action.admin.indices.alias.put.RestIndexPutAliasAction;
import org.elasticsearch.rest.action.admin.indices.analyze.RestAnalyzeAction;
import org.elasticsearch.rest.action.admin.indices.cache.clear.RestClearIndicesCacheAction;
import org.elasticsearch.rest.action.admin.indices.close.RestCloseIndexAction;
import org.elasticsearch.rest.action.admin.indices.create.RestCreateIndexAction;
import org.elasticsearch.rest.action.admin.indices.delete.RestDeleteIndexAction;
import org.elasticsearch.rest.action.admin.indices.exists.indices.RestIndicesExistsAction;
import org.elasticsearch.rest.action.admin.indices.exists.types.RestTypesExistsAction;
import org.elasticsearch.rest.action.admin.indices.flush.RestFlushAction;
import org.elasticsearch.rest.action.admin.indices.flush.RestSyncedFlushAction;
import org.elasticsearch.rest.action.admin.indices.forcemerge.RestForceMergeAction;
import org.elasticsearch.rest.action.admin.indices.get.RestGetIndicesAction;
import org.elasticsearch.rest.action.admin.indices.mapping.get.RestGetFieldMappingAction;
import org.elasticsearch.rest.action.admin.indices.mapping.get.RestGetMappingAction;
import org.elasticsearch.rest.action.admin.indices.mapping.put.RestPutMappingAction;
import org.elasticsearch.rest.action.admin.indices.open.RestOpenIndexAction;
import org.elasticsearch.rest.action.admin.indices.recovery.RestRecoveryAction;
import org.elasticsearch.rest.action.admin.indices.refresh.RestRefreshAction;
import org.elasticsearch.rest.action.admin.indices.segments.RestIndicesSegmentsAction;
import org.elasticsearch.rest.action.admin.indices.settings.RestGetSettingsAction;
import org.elasticsearch.rest.action.admin.indices.settings.RestUpdateSettingsAction;
import org.elasticsearch.rest.action.admin.indices.shards.RestIndicesShardStoresAction;
import org.elasticsearch.rest.action.admin.indices.stats.RestIndicesStatsAction;
import org.elasticsearch.rest.action.admin.indices.template.delete.RestDeleteIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.template.get.RestGetIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.template.head.RestHeadIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.template.put.RestPutIndexTemplateAction;
import org.elasticsearch.rest.action.admin.indices.upgrade.RestUpgradeAction;
import org.elasticsearch.rest.action.admin.indices.validate.query.RestValidateQueryAction;
import org.elasticsearch.rest.action.bulk.RestBulkAction;
import org.elasticsearch.rest.action.cat.AbstractCatAction;
import org.elasticsearch.rest.action.cat.RestAliasAction;
import org.elasticsearch.rest.action.cat.RestAllocationAction;
import org.elasticsearch.rest.action.cat.RestCatAction;
import org.elasticsearch.rest.action.cat.RestFielddataAction;
import org.elasticsearch.rest.action.cat.RestHealthAction;
import org.elasticsearch.rest.action.cat.RestIndicesAction;
import org.elasticsearch.rest.action.cat.RestMasterAction;
import org.elasticsearch.rest.action.cat.RestNodeAttrsAction;
import org.elasticsearch.rest.action.cat.RestNodesAction;
import org.elasticsearch.rest.action.cat.RestPluginsAction;
import org.elasticsearch.rest.action.cat.RestRepositoriesAction;
import org.elasticsearch.rest.action.cat.RestSegmentsAction;
import org.elasticsearch.rest.action.cat.RestShardsAction;
import org.elasticsearch.rest.action.cat.RestSnapshotAction;
import org.elasticsearch.rest.action.cat.RestTasksAction;
import org.elasticsearch.rest.action.cat.RestThreadPoolAction;
import org.elasticsearch.rest.action.delete.RestDeleteAction;
import org.elasticsearch.rest.action.explain.RestExplainAction;
import org.elasticsearch.rest.action.fieldstats.RestFieldStatsAction;
import org.elasticsearch.rest.action.get.RestGetAction;
import org.elasticsearch.rest.action.get.RestGetSourceAction;
import org.elasticsearch.rest.action.get.RestHeadAction;
import org.elasticsearch.rest.action.get.RestMultiGetAction;
import org.elasticsearch.rest.action.index.RestIndexAction;
import org.elasticsearch.rest.action.ingest.RestDeletePipelineAction;
import org.elasticsearch.rest.action.ingest.RestGetPipelineAction;
import org.elasticsearch.rest.action.ingest.RestPutPipelineAction;
import org.elasticsearch.rest.action.ingest.RestSimulatePipelineAction;
import org.elasticsearch.rest.action.main.RestMainAction;
import org.elasticsearch.rest.action.search.RestClearScrollAction;
import org.elasticsearch.rest.action.search.RestMultiSearchAction;
import org.elasticsearch.rest.action.search.RestSearchAction;
import org.elasticsearch.rest.action.search.RestSearchScrollAction;
import org.elasticsearch.rest.action.suggest.RestSuggestAction;
import org.elasticsearch.rest.action.termvectors.RestMultiTermVectorsAction;
import org.elasticsearch.rest.action.termvectors.RestTermVectorsAction;
import org.elasticsearch.rest.action.update.RestUpdateAction;
import org.elasticsearch.tasks.RawTaskStatus;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.transport.Transport;
@ -151,9 +48,6 @@ import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.local.LocalTransport;
import org.elasticsearch.transport.netty.NettyTransport;
import java.util.Arrays;
import java.util.List;
/**
* A module to handle registering and binding all network related classes.
*/
@ -171,140 +65,6 @@ public class NetworkModule extends AbstractModule {
Setting.simpleString(TRANSPORT_SERVICE_TYPE_KEY, Property.NodeScope);
public static final Setting<String> TRANSPORT_TYPE_SETTING = Setting.simpleString(TRANSPORT_TYPE_KEY, Property.NodeScope);
private static final List<Class<? extends RestHandler>> builtinRestHandlers = Arrays.asList(
RestMainAction.class,
RestNodesInfoAction.class,
RestNodesStatsAction.class,
RestNodesHotThreadsAction.class,
RestClusterAllocationExplainAction.class,
RestClusterStatsAction.class,
RestClusterStateAction.class,
RestClusterHealthAction.class,
RestClusterUpdateSettingsAction.class,
RestClusterGetSettingsAction.class,
RestClusterRerouteAction.class,
RestClusterSearchShardsAction.class,
RestPendingClusterTasksAction.class,
RestPutRepositoryAction.class,
RestGetRepositoriesAction.class,
RestDeleteRepositoryAction.class,
RestVerifyRepositoryAction.class,
RestGetSnapshotsAction.class,
RestCreateSnapshotAction.class,
RestRestoreSnapshotAction.class,
RestDeleteSnapshotAction.class,
RestSnapshotsStatusAction.class,
RestIndicesExistsAction.class,
RestTypesExistsAction.class,
RestGetIndicesAction.class,
RestIndicesStatsAction.class,
RestIndicesSegmentsAction.class,
RestIndicesShardStoresAction.class,
RestGetAliasesAction.class,
RestAliasesExistAction.class,
RestIndexDeleteAliasesAction.class,
RestIndexPutAliasAction.class,
RestIndicesAliasesAction.class,
RestCreateIndexAction.class,
RestShrinkIndexAction.class,
RestRolloverIndexAction.class,
RestDeleteIndexAction.class,
RestCloseIndexAction.class,
RestOpenIndexAction.class,
RestUpdateSettingsAction.class,
RestGetSettingsAction.class,
RestAnalyzeAction.class,
RestGetIndexTemplateAction.class,
RestPutIndexTemplateAction.class,
RestDeleteIndexTemplateAction.class,
RestHeadIndexTemplateAction.class,
RestPutMappingAction.class,
RestGetMappingAction.class,
RestGetFieldMappingAction.class,
RestRefreshAction.class,
RestFlushAction.class,
RestSyncedFlushAction.class,
RestForceMergeAction.class,
RestUpgradeAction.class,
RestClearIndicesCacheAction.class,
RestIndexAction.class,
RestGetAction.class,
RestGetSourceAction.class,
RestHeadAction.Document.class,
RestHeadAction.Source.class,
RestMultiGetAction.class,
RestDeleteAction.class,
org.elasticsearch.rest.action.count.RestCountAction.class,
RestSuggestAction.class,
RestTermVectorsAction.class,
RestMultiTermVectorsAction.class,
RestBulkAction.class,
RestUpdateAction.class,
RestSearchAction.class,
RestSearchScrollAction.class,
RestClearScrollAction.class,
RestMultiSearchAction.class,
RestValidateQueryAction.class,
RestExplainAction.class,
RestRecoveryAction.class,
// Scripts API
RestGetStoredScriptAction.class,
RestPutStoredScriptAction.class,
RestDeleteStoredScriptAction.class,
RestFieldStatsAction.class,
// no abstract cat action
RestCatAction.class,
// Tasks API
RestListTasksAction.class,
RestGetTaskAction.class,
RestCancelTasksAction.class,
// Ingest API
RestPutPipelineAction.class,
RestGetPipelineAction.class,
RestDeletePipelineAction.class,
RestSimulatePipelineAction.class
);
private static final List<Class<? extends AbstractCatAction>> builtinCatHandlers = Arrays.asList(
RestAllocationAction.class,
RestShardsAction.class,
RestMasterAction.class,
RestNodesAction.class,
RestTasksAction.class,
RestIndicesAction.class,
RestSegmentsAction.class,
// Fully qualified to prevent interference with rest.action.count.RestCountAction
org.elasticsearch.rest.action.cat.RestCountAction.class,
// Fully qualified to prevent interference with rest.action.indices.RestRecoveryAction
org.elasticsearch.rest.action.cat.RestRecoveryAction.class,
RestHealthAction.class,
org.elasticsearch.rest.action.cat.RestPendingClusterTasksAction.class,
RestAliasAction.class,
RestThreadPoolAction.class,
RestPluginsAction.class,
RestFielddataAction.class,
RestNodeAttrsAction.class,
RestRepositoriesAction.class,
RestSnapshotAction.class
);
private final NetworkService networkService;
private final Settings settings;
private final boolean transportClient;
@ -313,9 +73,6 @@ public class NetworkModule extends AbstractModule {
private final ExtensionPoint.SelectedType<TransportService> transportServiceTypes = new ExtensionPoint.SelectedType<>("transport_service", TransportService.class);
private final ExtensionPoint.SelectedType<Transport> transportTypes = new ExtensionPoint.SelectedType<>("transport", Transport.class);
private final ExtensionPoint.SelectedType<HttpServerTransport> httpTransportTypes = new ExtensionPoint.SelectedType<>("http_transport", HttpServerTransport.class);
private final ExtensionPoint.ClassSet<RestHandler> restHandlers = new ExtensionPoint.ClassSet<>("rest_handler", RestHandler.class);
// we must separate the cat rest handlers so RestCatAction can collect them...
private final ExtensionPoint.ClassSet<AbstractCatAction> catHandlers = new ExtensionPoint.ClassSet<>("cat_handler", AbstractCatAction.class);
private final NamedWriteableRegistry namedWriteableRegistry;
/**
@ -340,13 +97,6 @@ public class NetworkModule extends AbstractModule {
if (transportClient == false) {
registerHttpTransport(NETTY_TRANSPORT, NettyHttpServerTransport.class);
for (Class<? extends AbstractCatAction> catAction : builtinCatHandlers) {
catHandlers.registerExtension(catAction);
}
for (Class<? extends RestHandler> restAction : builtinRestHandlers) {
restHandlers.registerExtension(restAction);
}
}
}
@ -373,19 +123,6 @@ public class NetworkModule extends AbstractModule {
httpTransportTypes.registerExtension(name, clazz);
}
/** Adds an additional rest action. */
// TODO: change this further to eliminate the middle man, ie RestController, and just register method and path here
public void registerRestHandler(Class<? extends RestHandler> clazz) {
if (transportClient) {
throw new IllegalArgumentException("Cannot register rest handler " + clazz.getName() + " for transport client");
}
if (AbstractCatAction.class.isAssignableFrom(clazz)) {
catHandlers.registerExtension(clazz.asSubclass(AbstractCatAction.class));
} else {
restHandlers.registerExtension(clazz);
}
}
public void registerTaskStatus(String name, Writeable.Reader<? extends Task.Status> reader) {
namedWriteableRegistry.register(Task.Status.class, name, reader);
}
@ -430,9 +167,6 @@ public class NetworkModule extends AbstractModule {
bind(HttpServer.class).asEagerSingleton();
httpTransportTypes.bindType(binder(), settings, HTTP_TYPE_SETTING.getKey(), NETTY_TRANSPORT);
}
bind(RestController.class).asEagerSingleton();
catHandlers.bind(binder());
restHandlers.bind(binder());
// Bind the AllocationCommandRegistry so RestClusterRerouteAction can get it.
bind(AllocationCommandRegistry.class).toInstance(allocationCommandRegistry);
}

View File

@ -26,6 +26,8 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchTimeoutException;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionModule;
import org.elasticsearch.action.GenericAction;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.cluster.ClusterModule;
@ -42,6 +44,7 @@ import org.elasticsearch.common.StopWatch;
import org.elasticsearch.common.component.Lifecycle;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Injector;
import org.elasticsearch.common.inject.Key;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.inject.ModulesBuilder;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@ -122,6 +125,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ -165,7 +169,7 @@ public class Node implements Closeable {
private final Environment environment;
private final NodeEnvironment nodeEnvironment;
private final PluginsService pluginsService;
private final Client client;
private final NodeClient client;
/**
* Constructs a node with the given settings.
@ -275,9 +279,10 @@ public class Node implements Closeable {
BigArrays bigArrays = createBigArrays(settings, circuitBreakerService);
resourcesToClose.add(bigArrays);
modules.add(settingsModule);
client = new NodeClient(settings, threadPool);
modules.add(b -> {
b.bind(PluginsService.class).toInstance(pluginsService);
b.bind(Client.class).to(NodeClient.class).asEagerSingleton();
b.bind(Client.class).toInstance(client);
b.bind(Environment.class).toInstance(environment);
b.bind(ThreadPool.class).toInstance(threadPool);
b.bind(NodeEnvironment.class).toInstance(nodeEnvironment);
@ -290,7 +295,7 @@ public class Node implements Closeable {
}
);
injector = modules.createInjector();
client = injector.getInstance(Client.class);
client.intialize(injector.getInstance(new Key<Map<GenericAction, TransportAction>>() {}));
success = true;
} catch (IOException ex) {
throw new ElasticsearchException("failed to bind service", ex);

View File

@ -25,8 +25,11 @@ import org.elasticsearch.action.GenericAction;
import org.elasticsearch.action.support.ActionFilter;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.action.support.TransportActions;
import org.elasticsearch.common.Strings;
import org.elasticsearch.rest.RestHandler;
import java.util.List;
import java.util.Objects;
import static java.util.Collections.emptyList;
@ -55,6 +58,12 @@ public interface ActionPlugin {
default List<Class<? extends ActionFilter>> getActionFilters() {
return emptyList();
}
/**
* Rest handlers added by this plugin.
*/
default List<Class<? extends RestHandler>> getRestHandlers() {
return emptyList();
}
public static final class ActionHandler<Request extends ActionRequest<Request>, Response extends ActionResponse> {
private final GenericAction<Request, Response> action;
@ -83,5 +92,30 @@ public interface ActionPlugin {
public Class<?>[] getSupportTransportActions() {
return supportTransportActions;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder().append(action.name()).append(" is handled by ").append(transportAction.getName());
if (supportTransportActions.length > 0) {
b.append('[').append(Strings.arrayToCommaDelimitedString(supportTransportActions)).append(']');
}
return b.toString();
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != ActionHandler.class) {
return false;
}
ActionHandler<?, ?> other = (ActionHandler<?, ?>) obj;
return Objects.equals(action, other.action)
&& Objects.equals(transportAction, other.transportAction)
&& Objects.deepEquals(supportTransportActions, other.supportTransportActions);
}
@Override
public int hashCode() {
return Objects.hash(action, transportAction, supportTransportActions);
}
}
}

View File

@ -22,7 +22,6 @@ package org.elasticsearch.rest;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.path.PathTrie;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
@ -59,7 +58,6 @@ public class RestController extends AbstractLifecycleComponent<RestController> {
// non volatile since the assumption is that pre processors are registered on startup
private RestFilter[] filters = new RestFilter[0];
@Inject
public RestController(Settings settings) {
super(settings);
}

View File

@ -0,0 +1,129 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.action;
import org.elasticsearch.action.main.MainAction;
import org.elasticsearch.action.main.TransportMainAction;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.ActionPlugin.ActionHandler;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.main.RestMainAction;
import org.elasticsearch.tasks.TaskManager;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.ThreadPool;
import java.util.List;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasItem;
public class ActionModuleTests extends ESTestCase {
public void testSetupActionsContainsKnownBuiltin() {
assertThat(ActionModule.setupActions(emptyList()),
hasEntry(MainAction.INSTANCE.name(), new ActionHandler<>(MainAction.INSTANCE, TransportMainAction.class)));
}
public void testPluginCantOverwriteBuiltinAction() {
ActionPlugin dupsMainAction = new ActionPlugin() {
@Override
public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
return singletonList(new ActionHandler<>(MainAction.INSTANCE, TransportMainAction.class));
}
};
Exception e = expectThrows(IllegalArgumentException.class, () -> ActionModule.setupActions(singletonList(dupsMainAction)));
assertEquals("action for name [" + MainAction.NAME + "] already registered", e.getMessage());
}
public void testPluginCanRegisterAction() {
class FakeRequest extends ActionRequest<FakeRequest> {
@Override
public ActionRequestValidationException validate() {
return null;
}
}
class FakeTransportAction extends TransportAction<FakeRequest, ActionResponse> {
protected FakeTransportAction(Settings settings, String actionName, ThreadPool threadPool, ActionFilters actionFilters,
IndexNameExpressionResolver indexNameExpressionResolver, TaskManager taskManager) {
super(settings, actionName, threadPool, actionFilters, indexNameExpressionResolver, taskManager);
}
@Override
protected void doExecute(FakeRequest request, ActionListener<ActionResponse> listener) {
}
}
class FakeAction extends GenericAction<FakeRequest, ActionResponse> {
protected FakeAction() {
super("fake");
}
@Override
public ActionResponse newResponse() {
return null;
}
}
FakeAction action = new FakeAction();
ActionPlugin registersFakeAction = new ActionPlugin() {
@Override
public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
return singletonList(new ActionHandler<>(action, FakeTransportAction.class));
}
};
assertThat(ActionModule.setupActions(singletonList(registersFakeAction)),
hasEntry("fake", new ActionHandler<>(action, FakeTransportAction.class)));
}
public void testSetupRestHandlerContainsKnownBuiltin() {
assertThat(ActionModule.setupRestHandlers(emptyList()), hasItem(RestMainAction.class));
}
public void testPluginCantOverwriteBuiltinRestHandler() {
ActionPlugin dupsMainAction = new ActionPlugin() {
@Override
public List<Class<? extends RestHandler>> getRestHandlers() {
return singletonList(RestMainAction.class);
}
};
Exception e = expectThrows(IllegalArgumentException.class, () -> ActionModule.setupRestHandlers(singletonList(dupsMainAction)));
assertEquals("can't register the same [rest_handler] more than once for [" + RestMainAction.class.getName() + "]", e.getMessage());
}
public void testPluginCanRegisterRestHandler() {
class FakeHandler implements RestHandler {
@Override
public void handleRequest(RestRequest request, RestChannel channel) throws Exception {
}
}
ActionPlugin registersFakeHandler = new ActionPlugin() {
@Override
public List<Class<? extends RestHandler>> getRestHandlers() {
return singletonList(FakeHandler.class);
}
};
assertThat(ActionModule.setupRestHandlers(singletonList(registersFakeHandler)), hasItem(FakeHandler.class));
}
}

View File

@ -46,7 +46,9 @@ public class NodeClientHeadersTests extends AbstractClientHeadersTestCase {
protected Client buildClient(Settings headersSettings, GenericAction[] testedActions) {
Settings settings = HEADER_SETTINGS;
Actions actions = new Actions(settings, threadPool, testedActions);
return new NodeClient(settings, threadPool, actions);
NodeClient client = new NodeClient(settings, threadPool);
client.intialize(actions);
return client;
}
private static class Actions extends HashMap<GenericAction, TransportAction> {

View File

@ -36,11 +36,8 @@ import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.http.HttpStats;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.cat.AbstractCatAction;
import org.elasticsearch.rest.action.cat.RestNodesAction;
import org.elasticsearch.rest.action.main.RestMainAction;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.test.transport.AssertingLocalTransport;
import org.elasticsearch.transport.Transport;
@ -163,32 +160,6 @@ public class NetworkModuleTests extends ModuleTestCase {
assertFalse(module.isTransportClient());
}
public void testRegisterRestHandler() {
Settings settings = Settings.EMPTY;
NetworkModule module = new NetworkModule(new NetworkService(settings), settings, false, new NamedWriteableRegistry());
module.registerRestHandler(FakeRestHandler.class);
// also check a builtin is bound
assertSetMultiBinding(module, RestHandler.class, FakeRestHandler.class, RestMainAction.class);
// check registration not allowed for transport only
module = new NetworkModule(new NetworkService(settings), settings, true, new NamedWriteableRegistry());
try {
module.registerRestHandler(FakeRestHandler.class);
fail();
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("Cannot register rest handler"));
assertTrue(e.getMessage().contains("for transport client"));
}
}
public void testRegisterCatRestHandler() {
Settings settings = Settings.EMPTY;
NetworkModule module = new NetworkModule(new NetworkService(settings), settings, false, new NamedWriteableRegistry());
module.registerRestHandler(FakeCatRestHandler.class);
// also check a builtin is bound
assertSetMultiBinding(module, AbstractCatAction.class, FakeCatRestHandler.class, RestNodesAction.class);
}
public void testRegisterTaskStatus() {
NamedWriteableRegistry registry = new NamedWriteableRegistry();
Settings settings = Settings.EMPTY;

View File

@ -19,12 +19,17 @@
package org.elasticsearch.plugins.responseheader;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestHandler;
public class TestResponseHeaderPlugin extends Plugin {
import java.util.List;
public void onModule(NetworkModule module) {
module.registerRestHandler(TestResponseHeaderRestAction.class);
import static java.util.Collections.singletonList;
public class TestResponseHeaderPlugin extends Plugin implements ActionPlugin {
@Override
public List<Class<? extends RestHandler>> getRestHandlers() {
return singletonList(TestResponseHeaderRestAction.class);
}
}

View File

@ -137,3 +137,6 @@ Plugins that register custom mappers should implement
Plugins that register custom actions should implement `ActionPlugin` and
remove their `onModule(ActionModule)` implementation.
Plugins that register custom `RestHandler`s should implement `ActionPlugin` and
remove their `onModule(NetworkModule)` implemnetation.

View File

@ -25,11 +25,11 @@ import org.elasticsearch.action.search.template.MultiSearchTemplateAction;
import org.elasticsearch.action.search.template.SearchTemplateAction;
import org.elasticsearch.action.search.template.TransportMultiSearchTemplateAction;
import org.elasticsearch.action.search.template.TransportSearchTemplateAction;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.ScriptPlugin;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.action.search.template.RestDeleteSearchTemplateAction;
import org.elasticsearch.rest.action.search.template.RestGetSearchTemplateAction;
import org.elasticsearch.rest.action.search.template.RestMultiSearchTemplateAction;
@ -54,14 +54,9 @@ public class MustachePlugin extends Plugin implements ScriptPlugin, ActionPlugin
new ActionHandler<>(MultiSearchTemplateAction.INSTANCE, TransportMultiSearchTemplateAction.class));
}
public void onModule(NetworkModule module) {
if (module.isTransportClient() == false) {
module.registerRestHandler(RestSearchTemplateAction.class);
module.registerRestHandler(RestMultiSearchTemplateAction.class);
module.registerRestHandler(RestGetSearchTemplateAction.class);
module.registerRestHandler(RestPutSearchTemplateAction.class);
module.registerRestHandler(RestDeleteSearchTemplateAction.class);
module.registerRestHandler(RestRenderSearchTemplateAction.class);
}
@Override
public List<Class<? extends RestHandler>> getRestHandlers() {
return Arrays.asList(RestSearchTemplateAction.class, RestMultiSearchTemplateAction.class, RestGetSearchTemplateAction.class,
RestPutSearchTemplateAction.class, RestDeleteSearchTemplateAction.class, RestRenderSearchTemplateAction.class);
}
}

View File

@ -23,13 +23,13 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.MapperPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.search.SearchModule;
import java.util.Arrays;
@ -41,11 +41,9 @@ public class PercolatorPlugin extends Plugin implements MapperPlugin, ActionPlug
public static final String NAME = "percolator";
private final boolean transportClientMode;
private final Settings settings;
public PercolatorPlugin(Settings settings) {
this.transportClientMode = transportClientMode(settings);
this.settings = settings;
}
@ -55,11 +53,9 @@ public class PercolatorPlugin extends Plugin implements MapperPlugin, ActionPlug
new ActionHandler<>(MultiPercolateAction.INSTANCE, TransportMultiPercolateAction.class));
}
public void onModule(NetworkModule module) {
if (transportClientMode == false) {
module.registerRestHandler(RestPercolateAction.class);
module.registerRestHandler(RestMultiPercolateAction.class);
}
@Override
public List<Class<? extends RestHandler>> getRestHandlers() {
return Arrays.asList(RestPercolateAction.class, RestMultiPercolateAction.class);
}
public void onModule(SearchModule module) {

View File

@ -24,6 +24,7 @@ import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestHandler;
import java.util.Arrays;
import java.util.List;
@ -39,11 +40,13 @@ public class ReindexPlugin extends Plugin implements ActionPlugin {
new ActionHandler<>(RethrottleAction.INSTANCE, TransportRethrottleAction.class));
}
@Override
public List<Class<? extends RestHandler>> getRestHandlers() {
return Arrays.asList(RestReindexAction.class, RestUpdateByQueryAction.class, RestDeleteByQueryAction.class,
RestRethrottleAction.class);
}
public void onModule(NetworkModule networkModule) {
networkModule.registerRestHandler(RestReindexAction.class);
networkModule.registerRestHandler(RestUpdateByQueryAction.class);
networkModule.registerRestHandler(RestDeleteByQueryAction.class);
networkModule.registerRestHandler(RestRethrottleAction.class);
networkModule.registerTaskStatus(BulkByScrollTask.Status.NAME, BulkByScrollTask.Status::new);
}
}