1
0
Эх сурвалжийг харах

Pull actions from plugins

Instead of implementing onModule(ActionModule) to register actions,
this has plugins implement ActionPlugin to declare actions. This is
yet another step in cleaning up the plugin infrastructure.

While I was in there I switched AutoCreateIndex and DestructiveOperations
to be eagerly constructed which makes them easier to use when
de-guice-ing the code base.
Nik Everett 9 жил өмнө
parent
commit
fa4844c3f4
17 өөрчлөгдсөн 415 нэмэгдсэн , 239 устгасан
  1. 163 145
      core/src/main/java/org/elasticsearch/action/ActionModule.java
  2. 0 1
      core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java
  3. 0 2
      core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java
  4. 12 9
      core/src/main/java/org/elasticsearch/client/transport/TransportClient.java
  5. 7 2
      core/src/main/java/org/elasticsearch/cluster/ClusterModule.java
  6. 59 0
      core/src/main/java/org/elasticsearch/common/NamedRegistry.java
  7. 9 38
      core/src/main/java/org/elasticsearch/indices/analysis/AnalysisModule.java
  8. 7 3
      core/src/main/java/org/elasticsearch/node/Node.java
  9. 87 0
      core/src/main/java/org/elasticsearch/plugins/ActionPlugin.java
  10. 9 0
      core/src/main/java/org/elasticsearch/plugins/Plugin.java
  11. 9 5
      core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java
  12. 7 6
      core/src/test/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java
  13. 6 4
      core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java
  14. 3 0
      docs/reference/migration/migrate_5_0/plugins.asciidoc
  15. 11 7
      modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustachePlugin.java
  16. 13 10
      modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorPlugin.java
  17. 13 7
      modules/reindex/src/main/java/org/elasticsearch/index/reindex/ReindexPlugin.java

+ 163 - 145
core/src/main/java/org/elasticsearch/action/ActionModule.java

@@ -64,6 +64,12 @@ import org.elasticsearch.action.admin.cluster.state.ClusterStateAction;
 import org.elasticsearch.action.admin.cluster.state.TransportClusterStateAction;
 import org.elasticsearch.action.admin.cluster.state.TransportClusterStateAction;
 import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
 import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
 import org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction;
 import org.elasticsearch.action.admin.cluster.stats.TransportClusterStatsAction;
+import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptAction;
+import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptAction;
+import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptAction;
+import org.elasticsearch.action.admin.cluster.storedscripts.TransportDeleteStoredScriptAction;
+import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetStoredScriptAction;
+import org.elasticsearch.action.admin.cluster.storedscripts.TransportPutStoredScriptAction;
 import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksAction;
 import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksAction;
 import org.elasticsearch.action.admin.cluster.tasks.TransportPendingClusterTasksAction;
 import org.elasticsearch.action.admin.cluster.tasks.TransportPendingClusterTasksAction;
 import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction;
 import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction;
@@ -151,18 +157,12 @@ import org.elasticsearch.action.get.TransportMultiGetAction;
 import org.elasticsearch.action.get.TransportShardMultiGetAction;
 import org.elasticsearch.action.get.TransportShardMultiGetAction;
 import org.elasticsearch.action.index.IndexAction;
 import org.elasticsearch.action.index.IndexAction;
 import org.elasticsearch.action.index.TransportIndexAction;
 import org.elasticsearch.action.index.TransportIndexAction;
-import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptAction;
-import org.elasticsearch.action.admin.cluster.storedscripts.TransportDeleteStoredScriptAction;
-import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptAction;
-import org.elasticsearch.action.admin.cluster.storedscripts.TransportGetStoredScriptAction;
-import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptAction;
-import org.elasticsearch.action.admin.cluster.storedscripts.TransportPutStoredScriptAction;
-import org.elasticsearch.action.ingest.IngestActionFilter;
-import org.elasticsearch.action.ingest.IngestProxyActionFilter;
 import org.elasticsearch.action.ingest.DeletePipelineAction;
 import org.elasticsearch.action.ingest.DeletePipelineAction;
 import org.elasticsearch.action.ingest.DeletePipelineTransportAction;
 import org.elasticsearch.action.ingest.DeletePipelineTransportAction;
 import org.elasticsearch.action.ingest.GetPipelineAction;
 import org.elasticsearch.action.ingest.GetPipelineAction;
 import org.elasticsearch.action.ingest.GetPipelineTransportAction;
 import org.elasticsearch.action.ingest.GetPipelineTransportAction;
+import org.elasticsearch.action.ingest.IngestActionFilter;
+import org.elasticsearch.action.ingest.IngestProxyActionFilter;
 import org.elasticsearch.action.ingest.PutPipelineAction;
 import org.elasticsearch.action.ingest.PutPipelineAction;
 import org.elasticsearch.action.ingest.PutPipelineTransportAction;
 import org.elasticsearch.action.ingest.PutPipelineTransportAction;
 import org.elasticsearch.action.ingest.SimulatePipelineAction;
 import org.elasticsearch.action.ingest.SimulatePipelineAction;
@@ -189,186 +189,204 @@ import org.elasticsearch.action.termvectors.TransportShardMultiTermsVectorAction
 import org.elasticsearch.action.termvectors.TransportTermVectorsAction;
 import org.elasticsearch.action.termvectors.TransportTermVectorsAction;
 import org.elasticsearch.action.update.TransportUpdateAction;
 import org.elasticsearch.action.update.TransportUpdateAction;
 import org.elasticsearch.action.update.UpdateAction;
 import org.elasticsearch.action.update.UpdateAction;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.common.NamedRegistry;
 import org.elasticsearch.common.inject.AbstractModule;
 import org.elasticsearch.common.inject.AbstractModule;
 import org.elasticsearch.common.inject.multibindings.MapBinder;
 import org.elasticsearch.common.inject.multibindings.MapBinder;
 import org.elasticsearch.common.inject.multibindings.Multibinder;
 import org.elasticsearch.common.inject.multibindings.Multibinder;
+import org.elasticsearch.common.settings.ClusterSettings;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.plugins.ActionPlugin;
+import org.elasticsearch.plugins.ActionPlugin.ActionHandler;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableMap;
+
 /**
 /**
- *
+ * Builds and binds the generic action map, all {@link TransportAction}s, and {@link ActionFilters}.
  */
  */
 public class ActionModule extends AbstractModule {
 public class ActionModule extends AbstractModule {
 
 
-    private final Map<String, ActionEntry> actions = new HashMap<>();
-    private final List<Class<? extends ActionFilter>> actionFilters = new ArrayList<>();
+    private final boolean transportClient;
+    private final Map<String, ActionHandler<?, ?>> actions;
+    private final List<Class<? extends ActionFilter>> actionFilters;
+    private final AutoCreateIndex autoCreateIndex;
+    private final DestructiveOperations destructiveOperations;
 
 
-    static class ActionEntry<Request extends ActionRequest<Request>, Response extends ActionResponse> {
-        public final GenericAction<Request, Response> action;
-        public final Class<? extends TransportAction<Request, Response>> transportAction;
-        public final Class[] supportTransportActions;
+    public ActionModule(boolean ingestEnabled, boolean transportClient, Settings settings, IndexNameExpressionResolver resolver,
+            ClusterSettings clusterSettings, List<ActionPlugin> actionPlugins) {
+        this.transportClient = transportClient;
+        actions = setupActions(actionPlugins);
+        actionFilters = setupActionFilters(actionPlugins, ingestEnabled);
+        autoCreateIndex = transportClient ? null : new AutoCreateIndex(settings, resolver);
+        destructiveOperations = new DestructiveOperations(settings, clusterSettings);
+    }
+
+    private Map<String, ActionHandler<?, ?>> setupActions(List<ActionPlugin> actionPlugins) {
+        // Subclass NamedRegistry for easy registration
+        class ActionRegistry extends NamedRegistry<ActionHandler<?, ?>> {
+            public ActionRegistry() {
+                super("action");
+            }
 
 
-        ActionEntry(GenericAction<Request, Response> action, Class<? extends TransportAction<Request, Response>> transportAction, Class... supportTransportActions) {
-            this.action = action;
-            this.transportAction = transportAction;
-            this.supportTransportActions = supportTransportActions;
+            public void register(ActionHandler<?, ?> handler) {
+                register(handler.getAction().name(), handler);
+            }
+
+            public <Request extends ActionRequest<Request>, Response extends ActionResponse> void register(
+                    GenericAction<Request, Response> action, Class<? extends TransportAction<Request, Response>> transportAction,
+                    Class<?>... supportTransportActions) {
+                register(new ActionHandler<>(action, transportAction, supportTransportActions));
+            }
         }
         }
-    }
+        ActionRegistry actions = new ActionRegistry();
 
 
-    private final boolean ingestEnabled;
-    private final boolean proxy;
+        actions.register(MainAction.INSTANCE, TransportMainAction.class);
+        actions.register(NodesInfoAction.INSTANCE, TransportNodesInfoAction.class);
+        actions.register(NodesStatsAction.INSTANCE, TransportNodesStatsAction.class);
+        actions.register(NodesHotThreadsAction.INSTANCE, TransportNodesHotThreadsAction.class);
+        actions.register(ListTasksAction.INSTANCE, TransportListTasksAction.class);
+        actions.register(GetTaskAction.INSTANCE, TransportGetTaskAction.class);
+        actions.register(CancelTasksAction.INSTANCE, TransportCancelTasksAction.class);
 
 
-    public ActionModule(boolean ingestEnabled, boolean proxy) {
-        this.ingestEnabled = ingestEnabled;
-        this.proxy = proxy;
-    }
+        actions.register(ClusterAllocationExplainAction.INSTANCE, TransportClusterAllocationExplainAction.class);
+        actions.register(ClusterStatsAction.INSTANCE, TransportClusterStatsAction.class);
+        actions.register(ClusterStateAction.INSTANCE, TransportClusterStateAction.class);
+        actions.register(ClusterHealthAction.INSTANCE, TransportClusterHealthAction.class);
+        actions.register(ClusterUpdateSettingsAction.INSTANCE, TransportClusterUpdateSettingsAction.class);
+        actions.register(ClusterRerouteAction.INSTANCE, TransportClusterRerouteAction.class);
+        actions.register(ClusterSearchShardsAction.INSTANCE, TransportClusterSearchShardsAction.class);
+        actions.register(PendingClusterTasksAction.INSTANCE, TransportPendingClusterTasksAction.class);
+        actions.register(PutRepositoryAction.INSTANCE, TransportPutRepositoryAction.class);
+        actions.register(GetRepositoriesAction.INSTANCE, TransportGetRepositoriesAction.class);
+        actions.register(DeleteRepositoryAction.INSTANCE, TransportDeleteRepositoryAction.class);
+        actions.register(VerifyRepositoryAction.INSTANCE, TransportVerifyRepositoryAction.class);
+        actions.register(GetSnapshotsAction.INSTANCE, TransportGetSnapshotsAction.class);
+        actions.register(DeleteSnapshotAction.INSTANCE, TransportDeleteSnapshotAction.class);
+        actions.register(CreateSnapshotAction.INSTANCE, TransportCreateSnapshotAction.class);
+        actions.register(RestoreSnapshotAction.INSTANCE, TransportRestoreSnapshotAction.class);
+        actions.register(SnapshotsStatusAction.INSTANCE, TransportSnapshotsStatusAction.class);
 
 
-    /**
-     * Registers an action.
-     *
-     * @param action                  The action type.
-     * @param transportAction         The transport action implementing the actual action.
-     * @param supportTransportActions Any support actions that are needed by the transport action.
-     * @param <Request>               The request type.
-     * @param <Response>              The response type.
-     */
-    public <Request extends ActionRequest<Request>, Response extends ActionResponse> void registerAction(GenericAction<Request, Response> action, Class<? extends TransportAction<Request, Response>> transportAction, Class... supportTransportActions) {
-        actions.put(action.name(), new ActionEntry<>(action, transportAction, supportTransportActions));
-    }
+        actions.register(IndicesStatsAction.INSTANCE, TransportIndicesStatsAction.class);
+        actions.register(IndicesSegmentsAction.INSTANCE, TransportIndicesSegmentsAction.class);
+        actions.register(IndicesShardStoresAction.INSTANCE, TransportIndicesShardStoresAction.class);
+        actions.register(CreateIndexAction.INSTANCE, TransportCreateIndexAction.class);
+        actions.register(ShrinkAction.INSTANCE, TransportShrinkAction.class);
+        actions.register(RolloverAction.INSTANCE, TransportRolloverAction.class);
+        actions.register(DeleteIndexAction.INSTANCE, TransportDeleteIndexAction.class);
+        actions.register(GetIndexAction.INSTANCE, TransportGetIndexAction.class);
+        actions.register(OpenIndexAction.INSTANCE, TransportOpenIndexAction.class);
+        actions.register(CloseIndexAction.INSTANCE, TransportCloseIndexAction.class);
+        actions.register(IndicesExistsAction.INSTANCE, TransportIndicesExistsAction.class);
+        actions.register(TypesExistsAction.INSTANCE, TransportTypesExistsAction.class);
+        actions.register(GetMappingsAction.INSTANCE, TransportGetMappingsAction.class);
+        actions.register(GetFieldMappingsAction.INSTANCE, TransportGetFieldMappingsAction.class,
+                TransportGetFieldMappingsIndexAction.class);
+        actions.register(PutMappingAction.INSTANCE, TransportPutMappingAction.class);
+        actions.register(IndicesAliasesAction.INSTANCE, TransportIndicesAliasesAction.class);
+        actions.register(UpdateSettingsAction.INSTANCE, TransportUpdateSettingsAction.class);
+        actions.register(AnalyzeAction.INSTANCE, TransportAnalyzeAction.class);
+        actions.register(PutIndexTemplateAction.INSTANCE, TransportPutIndexTemplateAction.class);
+        actions.register(GetIndexTemplatesAction.INSTANCE, TransportGetIndexTemplatesAction.class);
+        actions.register(DeleteIndexTemplateAction.INSTANCE, TransportDeleteIndexTemplateAction.class);
+        actions.register(ValidateQueryAction.INSTANCE, TransportValidateQueryAction.class);
+        actions.register(RefreshAction.INSTANCE, TransportRefreshAction.class);
+        actions.register(FlushAction.INSTANCE, TransportFlushAction.class);
+        actions.register(SyncedFlushAction.INSTANCE, TransportSyncedFlushAction.class);
+        actions.register(ForceMergeAction.INSTANCE, TransportForceMergeAction.class);
+        actions.register(UpgradeAction.INSTANCE, TransportUpgradeAction.class);
+        actions.register(UpgradeStatusAction.INSTANCE, TransportUpgradeStatusAction.class);
+        actions.register(UpgradeSettingsAction.INSTANCE, TransportUpgradeSettingsAction.class);
+        actions.register(ClearIndicesCacheAction.INSTANCE, TransportClearIndicesCacheAction.class);
+        actions.register(GetAliasesAction.INSTANCE, TransportGetAliasesAction.class);
+        actions.register(AliasesExistAction.INSTANCE, TransportAliasesExistAction.class);
+        actions.register(GetSettingsAction.INSTANCE, TransportGetSettingsAction.class);
 
 
-    public ActionModule registerFilter(Class<? extends ActionFilter> actionFilter) {
-        actionFilters.add(actionFilter);
-        return this;
+        actions.register(IndexAction.INSTANCE, TransportIndexAction.class);
+        actions.register(GetAction.INSTANCE, TransportGetAction.class);
+        actions.register(TermVectorsAction.INSTANCE, TransportTermVectorsAction.class);
+        actions.register(MultiTermVectorsAction.INSTANCE, TransportMultiTermVectorsAction.class,
+                TransportShardMultiTermsVectorAction.class);
+        actions.register(DeleteAction.INSTANCE, TransportDeleteAction.class);
+        actions.register(UpdateAction.INSTANCE, TransportUpdateAction.class);
+        actions.register(MultiGetAction.INSTANCE, TransportMultiGetAction.class,
+                TransportShardMultiGetAction.class);
+        actions.register(BulkAction.INSTANCE, TransportBulkAction.class,
+                TransportShardBulkAction.class);
+        actions.register(SearchAction.INSTANCE, TransportSearchAction.class);
+        actions.register(SearchScrollAction.INSTANCE, TransportSearchScrollAction.class);
+        actions.register(MultiSearchAction.INSTANCE, TransportMultiSearchAction.class);
+        actions.register(ExplainAction.INSTANCE, TransportExplainAction.class);
+        actions.register(ClearScrollAction.INSTANCE, TransportClearScrollAction.class);
+        actions.register(RecoveryAction.INSTANCE, TransportRecoveryAction.class);
+
+        //Indexed scripts
+        actions.register(PutStoredScriptAction.INSTANCE, TransportPutStoredScriptAction.class);
+        actions.register(GetStoredScriptAction.INSTANCE, TransportGetStoredScriptAction.class);
+        actions.register(DeleteStoredScriptAction.INSTANCE, TransportDeleteStoredScriptAction.class);
+
+        actions.register(FieldStatsAction.INSTANCE, TransportFieldStatsAction.class);
+
+        actions.register(PutPipelineAction.INSTANCE, PutPipelineTransportAction.class);
+        actions.register(GetPipelineAction.INSTANCE, GetPipelineTransportAction.class);
+        actions.register(DeletePipelineAction.INSTANCE, DeletePipelineTransportAction.class);
+        actions.register(SimulatePipelineAction.INSTANCE, SimulatePipelineTransportAction.class);
+
+        actionPlugins.stream().flatMap(p -> p.getActions().stream()).forEach(actions::register);
+
+        return unmodifiableMap(actions.getRegistry());
     }
     }
 
 
-    @Override
-    protected void configure() {
-        if (proxy == false) {
+    private List<Class<? extends ActionFilter>> setupActionFilters(List<ActionPlugin> actionPlugins, boolean ingestEnabled) {
+        List<Class<? extends ActionFilter>> filters = new ArrayList<>();
+        if (transportClient == false) {
             if (ingestEnabled) {
             if (ingestEnabled) {
-                registerFilter(IngestActionFilter.class);
+                filters.add(IngestActionFilter.class);
             } else {
             } else {
-                registerFilter(IngestProxyActionFilter.class);
+                filters.add(IngestProxyActionFilter.class);
             }
             }
         }
         }
 
 
+        for (ActionPlugin plugin : actionPlugins) {
+            filters.addAll(plugin.getActionFilters());
+        }
+        return unmodifiableList(filters);
+    }
+
+    @Override
+    protected void configure() {
         Multibinder<ActionFilter> actionFilterMultibinder = Multibinder.newSetBinder(binder(), ActionFilter.class);
         Multibinder<ActionFilter> actionFilterMultibinder = Multibinder.newSetBinder(binder(), ActionFilter.class);
         for (Class<? extends ActionFilter> actionFilter : actionFilters) {
         for (Class<? extends ActionFilter> actionFilter : actionFilters) {
             actionFilterMultibinder.addBinding().to(actionFilter);
             actionFilterMultibinder.addBinding().to(actionFilter);
         }
         }
         bind(ActionFilters.class).asEagerSingleton();
         bind(ActionFilters.class).asEagerSingleton();
-        bind(AutoCreateIndex.class).asEagerSingleton();
-        bind(DestructiveOperations.class).asEagerSingleton();
-        registerAction(MainAction.INSTANCE, TransportMainAction.class);
-        registerAction(NodesInfoAction.INSTANCE, TransportNodesInfoAction.class);
-        registerAction(NodesStatsAction.INSTANCE, TransportNodesStatsAction.class);
-        registerAction(NodesHotThreadsAction.INSTANCE, TransportNodesHotThreadsAction.class);
-        registerAction(ListTasksAction.INSTANCE, TransportListTasksAction.class);
-        registerAction(GetTaskAction.INSTANCE, TransportGetTaskAction.class);
-        registerAction(CancelTasksAction.INSTANCE, TransportCancelTasksAction.class);
-
-        registerAction(ClusterAllocationExplainAction.INSTANCE, TransportClusterAllocationExplainAction.class);
-        registerAction(ClusterStatsAction.INSTANCE, TransportClusterStatsAction.class);
-        registerAction(ClusterStateAction.INSTANCE, TransportClusterStateAction.class);
-        registerAction(ClusterHealthAction.INSTANCE, TransportClusterHealthAction.class);
-        registerAction(ClusterUpdateSettingsAction.INSTANCE, TransportClusterUpdateSettingsAction.class);
-        registerAction(ClusterRerouteAction.INSTANCE, TransportClusterRerouteAction.class);
-        registerAction(ClusterSearchShardsAction.INSTANCE, TransportClusterSearchShardsAction.class);
-        registerAction(PendingClusterTasksAction.INSTANCE, TransportPendingClusterTasksAction.class);
-        registerAction(PutRepositoryAction.INSTANCE, TransportPutRepositoryAction.class);
-        registerAction(GetRepositoriesAction.INSTANCE, TransportGetRepositoriesAction.class);
-        registerAction(DeleteRepositoryAction.INSTANCE, TransportDeleteRepositoryAction.class);
-        registerAction(VerifyRepositoryAction.INSTANCE, TransportVerifyRepositoryAction.class);
-        registerAction(GetSnapshotsAction.INSTANCE, TransportGetSnapshotsAction.class);
-        registerAction(DeleteSnapshotAction.INSTANCE, TransportDeleteSnapshotAction.class);
-        registerAction(CreateSnapshotAction.INSTANCE, TransportCreateSnapshotAction.class);
-        registerAction(RestoreSnapshotAction.INSTANCE, TransportRestoreSnapshotAction.class);
-        registerAction(SnapshotsStatusAction.INSTANCE, TransportSnapshotsStatusAction.class);
-
-        registerAction(IndicesStatsAction.INSTANCE, TransportIndicesStatsAction.class);
-        registerAction(IndicesSegmentsAction.INSTANCE, TransportIndicesSegmentsAction.class);
-        registerAction(IndicesShardStoresAction.INSTANCE, TransportIndicesShardStoresAction.class);
-        registerAction(CreateIndexAction.INSTANCE, TransportCreateIndexAction.class);
-        registerAction(ShrinkAction.INSTANCE, TransportShrinkAction.class);
-        registerAction(RolloverAction.INSTANCE, TransportRolloverAction.class);
-        registerAction(DeleteIndexAction.INSTANCE, TransportDeleteIndexAction.class);
-        registerAction(GetIndexAction.INSTANCE, TransportGetIndexAction.class);
-        registerAction(OpenIndexAction.INSTANCE, TransportOpenIndexAction.class);
-        registerAction(CloseIndexAction.INSTANCE, TransportCloseIndexAction.class);
-        registerAction(IndicesExistsAction.INSTANCE, TransportIndicesExistsAction.class);
-        registerAction(TypesExistsAction.INSTANCE, TransportTypesExistsAction.class);
-        registerAction(GetMappingsAction.INSTANCE, TransportGetMappingsAction.class);
-        registerAction(GetFieldMappingsAction.INSTANCE, TransportGetFieldMappingsAction.class, TransportGetFieldMappingsIndexAction.class);
-        registerAction(PutMappingAction.INSTANCE, TransportPutMappingAction.class);
-        registerAction(IndicesAliasesAction.INSTANCE, TransportIndicesAliasesAction.class);
-        registerAction(UpdateSettingsAction.INSTANCE, TransportUpdateSettingsAction.class);
-        registerAction(AnalyzeAction.INSTANCE, TransportAnalyzeAction.class);
-        registerAction(PutIndexTemplateAction.INSTANCE, TransportPutIndexTemplateAction.class);
-        registerAction(GetIndexTemplatesAction.INSTANCE, TransportGetIndexTemplatesAction.class);
-        registerAction(DeleteIndexTemplateAction.INSTANCE, TransportDeleteIndexTemplateAction.class);
-        registerAction(ValidateQueryAction.INSTANCE, TransportValidateQueryAction.class);
-        registerAction(RefreshAction.INSTANCE, TransportRefreshAction.class);
-        registerAction(FlushAction.INSTANCE, TransportFlushAction.class);
-        registerAction(SyncedFlushAction.INSTANCE, TransportSyncedFlushAction.class);
-        registerAction(ForceMergeAction.INSTANCE, TransportForceMergeAction.class);
-        registerAction(UpgradeAction.INSTANCE, TransportUpgradeAction.class);
-        registerAction(UpgradeStatusAction.INSTANCE, TransportUpgradeStatusAction.class);
-        registerAction(UpgradeSettingsAction.INSTANCE, TransportUpgradeSettingsAction.class);
-        registerAction(ClearIndicesCacheAction.INSTANCE, TransportClearIndicesCacheAction.class);
-        registerAction(GetAliasesAction.INSTANCE, TransportGetAliasesAction.class);
-        registerAction(AliasesExistAction.INSTANCE, TransportAliasesExistAction.class);
-        registerAction(GetSettingsAction.INSTANCE, TransportGetSettingsAction.class);
-
-        registerAction(IndexAction.INSTANCE, TransportIndexAction.class);
-        registerAction(GetAction.INSTANCE, TransportGetAction.class);
-        registerAction(TermVectorsAction.INSTANCE, TransportTermVectorsAction.class);
-        registerAction(MultiTermVectorsAction.INSTANCE, TransportMultiTermVectorsAction.class,
-                TransportShardMultiTermsVectorAction.class);
-        registerAction(DeleteAction.INSTANCE, TransportDeleteAction.class);
-        registerAction(UpdateAction.INSTANCE, TransportUpdateAction.class);
-        registerAction(MultiGetAction.INSTANCE, TransportMultiGetAction.class,
-                TransportShardMultiGetAction.class);
-        registerAction(BulkAction.INSTANCE, TransportBulkAction.class,
-                TransportShardBulkAction.class);
-        registerAction(SearchAction.INSTANCE, TransportSearchAction.class);
-        registerAction(SearchScrollAction.INSTANCE, TransportSearchScrollAction.class);
-        registerAction(MultiSearchAction.INSTANCE, TransportMultiSearchAction.class);
-        registerAction(ExplainAction.INSTANCE, TransportExplainAction.class);
-        registerAction(ClearScrollAction.INSTANCE, TransportClearScrollAction.class);
-        registerAction(RecoveryAction.INSTANCE, TransportRecoveryAction.class);
-
-        //Indexed scripts
-        registerAction(PutStoredScriptAction.INSTANCE, TransportPutStoredScriptAction.class);
-        registerAction(GetStoredScriptAction.INSTANCE, TransportGetStoredScriptAction.class);
-        registerAction(DeleteStoredScriptAction.INSTANCE, TransportDeleteStoredScriptAction.class);
-
-        registerAction(FieldStatsAction.INSTANCE, TransportFieldStatsAction.class);
-
-        registerAction(PutPipelineAction.INSTANCE, PutPipelineTransportAction.class);
-        registerAction(GetPipelineAction.INSTANCE, GetPipelineTransportAction.class);
-        registerAction(DeletePipelineAction.INSTANCE, DeletePipelineTransportAction.class);
-        registerAction(SimulatePipelineAction.INSTANCE, SimulatePipelineTransportAction.class);
+        bind(DestructiveOperations.class).toInstance(destructiveOperations);
 
 
         // register Name -> GenericAction Map that can be injected to instances.
         // register Name -> GenericAction Map that can be injected to instances.
+        @SuppressWarnings("rawtypes")
         MapBinder<String, GenericAction> actionsBinder
         MapBinder<String, GenericAction> actionsBinder
                 = MapBinder.newMapBinder(binder(), String.class, GenericAction.class);
                 = MapBinder.newMapBinder(binder(), String.class, GenericAction.class);
 
 
-        for (Map.Entry<String, ActionEntry> entry : actions.entrySet()) {
-            actionsBinder.addBinding(entry.getKey()).toInstance(entry.getValue().action);
+        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.
         // register GenericAction -> transportAction Map that can be injected to instances.
         // also register any supporting classes
         // also register any supporting classes
-        if (!proxy) {
+        if (false == transportClient) {
+            bind(AutoCreateIndex.class).toInstance(autoCreateIndex);
             bind(TransportLivenessAction.class).asEagerSingleton();
             bind(TransportLivenessAction.class).asEagerSingleton();
+            @SuppressWarnings("rawtypes")
             MapBinder<GenericAction, TransportAction> transportActionsBinder
             MapBinder<GenericAction, TransportAction> transportActionsBinder
                     = MapBinder.newMapBinder(binder(), GenericAction.class, TransportAction.class);
                     = MapBinder.newMapBinder(binder(), GenericAction.class, TransportAction.class);
-            for (Map.Entry<String, ActionEntry> entry : actions.entrySet()) {
+            for (ActionHandler<?, ?> action : actions.values()) {
                 // bind the action as eager singleton, so the map binder one will reuse it
                 // bind the action as eager singleton, so the map binder one will reuse it
-                bind(entry.getValue().transportAction).asEagerSingleton();
-                transportActionsBinder.addBinding(entry.getValue().action).to(entry.getValue().transportAction).asEagerSingleton();
-                for (Class supportAction : entry.getValue().supportTransportActions) {
+                bind(action.getTransportAction()).asEagerSingleton();
+                transportActionsBinder.addBinding(action.getAction()).to(action.getTransportAction()).asEagerSingleton();
+                for (Class<?> supportAction : action.getSupportTransportActions()) {
                     bind(supportAction).asEagerSingleton();
                     bind(supportAction).asEagerSingleton();
                 }
                 }
             }
             }

+ 0 - 1
core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java

@@ -47,7 +47,6 @@ public final class AutoCreateIndex {
     private final IndexNameExpressionResolver resolver;
     private final IndexNameExpressionResolver resolver;
     private final AutoCreate autoCreate;
     private final AutoCreate autoCreate;
 
 
-    @Inject
     public AutoCreateIndex(Settings settings, IndexNameExpressionResolver resolver) {
     public AutoCreateIndex(Settings settings, IndexNameExpressionResolver resolver) {
         this.resolver = resolver;
         this.resolver = resolver;
         dynamicMappingDisabled = !MapperService.INDEX_MAPPER_DYNAMIC_SETTING.get(settings);
         dynamicMappingDisabled = !MapperService.INDEX_MAPPER_DYNAMIC_SETTING.get(settings);

+ 0 - 2
core/src/main/java/org/elasticsearch/action/support/DestructiveOperations.java

@@ -20,7 +20,6 @@
 package org.elasticsearch.action.support;
 package org.elasticsearch.action.support;
 
 
 import org.elasticsearch.common.component.AbstractComponent;
 import org.elasticsearch.common.component.AbstractComponent;
-import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.settings.ClusterSettings;
 import org.elasticsearch.common.settings.ClusterSettings;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Setting.Property;
 import org.elasticsearch.common.settings.Setting.Property;
@@ -38,7 +37,6 @@ public final class DestructiveOperations extends AbstractComponent {
         Setting.boolSetting("action.destructive_requires_name", false, Property.Dynamic, Property.NodeScope);
         Setting.boolSetting("action.destructive_requires_name", false, Property.Dynamic, Property.NodeScope);
     private volatile boolean destructiveRequiresName;
     private volatile boolean destructiveRequiresName;
 
 
-    @Inject
     public DestructiveOperations(Settings settings, ClusterSettings clusterSettings) {
     public DestructiveOperations(Settings settings, ClusterSettings clusterSettings) {
         super(settings);
         super(settings);
         destructiveRequiresName = REQUIRES_NAME_SETTING.get(settings);
         destructiveRequiresName = REQUIRES_NAME_SETTING.get(settings);

+ 12 - 9
core/src/main/java/org/elasticsearch/client/transport/TransportClient.java

@@ -44,6 +44,7 @@ import org.elasticsearch.common.util.BigArrays;
 import org.elasticsearch.indices.breaker.CircuitBreakerService;
 import org.elasticsearch.indices.breaker.CircuitBreakerService;
 import org.elasticsearch.node.Node;
 import org.elasticsearch.node.Node;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.PluginsService;
 import org.elasticsearch.plugins.PluginsService;
 import org.elasticsearch.search.SearchModule;
 import org.elasticsearch.search.SearchModule;
@@ -125,6 +126,15 @@ public class TransportClient extends AbstractClient {
             final NetworkService networkService = new NetworkService(settings);
             final NetworkService networkService = new NetworkService(settings);
             NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
             NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
             try {
             try {
+                final List<Setting<?>> additionalSettings = new ArrayList<>();
+                final List<String> additionalSettingsFilter = new ArrayList<>();
+                additionalSettings.addAll(pluginsService.getPluginSettings());
+                additionalSettingsFilter.addAll(pluginsService.getPluginSettingsFilter());
+                for (final ExecutorBuilder<?> builder : threadPool.builders()) {
+                    additionalSettings.addAll(builder.getRegisteredSettings());
+                }
+                SettingsModule settingsModule = new SettingsModule(settings, additionalSettings, additionalSettingsFilter);
+
                 ModulesBuilder modules = new ModulesBuilder();
                 ModulesBuilder modules = new ModulesBuilder();
                 // plugin modules must be added here, before others or we can get crazy injection errors...
                 // plugin modules must be added here, before others or we can get crazy injection errors...
                 for (Module pluginModule : pluginsService.nodeModules()) {
                 for (Module pluginModule : pluginsService.nodeModules()) {
@@ -138,17 +148,10 @@ public class TransportClient extends AbstractClient {
                         // noop
                         // noop
                     }
                     }
                 });
                 });
-                modules.add(new ActionModule(false, true));
+                modules.add(new ActionModule(false, true, settings, null, settingsModule.getClusterSettings(),
+                        pluginsService.filterPlugins(ActionPlugin.class)));
 
 
                 pluginsService.processModules(modules);
                 pluginsService.processModules(modules);
-                final List<Setting<?>> additionalSettings = new ArrayList<>();
-                final List<String> additionalSettingsFilter = new ArrayList<>();
-                additionalSettings.addAll(pluginsService.getPluginSettings());
-                additionalSettingsFilter.addAll(pluginsService.getPluginSettingsFilter());
-                for (final ExecutorBuilder<?> builder : threadPool.builders()) {
-                    additionalSettings.addAll(builder.getRegisteredSettings());
-                }
-                SettingsModule settingsModule = new SettingsModule(settings, additionalSettings, additionalSettingsFilter);
                 CircuitBreakerService circuitBreakerService = Node.createCircuitBreakerService(settingsModule.getSettings(),
                 CircuitBreakerService circuitBreakerService = Node.createCircuitBreakerService(settingsModule.getSettings(),
                     settingsModule.getClusterSettings());
                     settingsModule.getClusterSettings());
                 resourcesToClose.add(circuitBreakerService);
                 resourcesToClose.add(circuitBreakerService);

+ 7 - 2
core/src/main/java/org/elasticsearch/cluster/ClusterModule.java

@@ -33,7 +33,6 @@ import org.elasticsearch.cluster.metadata.MetaDataMappingService;
 import org.elasticsearch.cluster.metadata.MetaDataUpdateSettingsService;
 import org.elasticsearch.cluster.metadata.MetaDataUpdateSettingsService;
 import org.elasticsearch.cluster.node.DiscoveryNodeService;
 import org.elasticsearch.cluster.node.DiscoveryNodeService;
 import org.elasticsearch.cluster.routing.DelayedAllocationService;
 import org.elasticsearch.cluster.routing.DelayedAllocationService;
-import org.elasticsearch.cluster.routing.OperationRouting;
 import org.elasticsearch.cluster.routing.RoutingService;
 import org.elasticsearch.cluster.routing.RoutingService;
 import org.elasticsearch.cluster.routing.allocation.AllocationService;
 import org.elasticsearch.cluster.routing.allocation.AllocationService;
 import org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator;
 import org.elasticsearch.cluster.routing.allocation.allocator.BalancedShardsAllocator;
@@ -101,6 +100,7 @@ public class ClusterModule extends AbstractModule {
     private final ExtensionPoint.ClassSet<AllocationDecider> allocationDeciders = new ExtensionPoint.ClassSet<>("allocation_decider", AllocationDecider.class, AllocationDeciders.class);
     private final ExtensionPoint.ClassSet<AllocationDecider> allocationDeciders = new ExtensionPoint.ClassSet<>("allocation_decider", AllocationDecider.class, AllocationDeciders.class);
     private final ExtensionPoint.ClassSet<IndexTemplateFilter> indexTemplateFilters = new ExtensionPoint.ClassSet<>("index_template_filter", IndexTemplateFilter.class);
     private final ExtensionPoint.ClassSet<IndexTemplateFilter> indexTemplateFilters = new ExtensionPoint.ClassSet<>("index_template_filter", IndexTemplateFilter.class);
     private final ClusterService clusterService;
     private final ClusterService clusterService;
+    private final IndexNameExpressionResolver indexNameExpressionResolver;
 
 
     // pkg private so tests can mock
     // pkg private so tests can mock
     Class<? extends ClusterInfoService> clusterInfoServiceImpl = InternalClusterInfoService.class;
     Class<? extends ClusterInfoService> clusterInfoServiceImpl = InternalClusterInfoService.class;
@@ -113,6 +113,7 @@ public class ClusterModule extends AbstractModule {
         registerShardsAllocator(ClusterModule.BALANCED_ALLOCATOR, BalancedShardsAllocator.class);
         registerShardsAllocator(ClusterModule.BALANCED_ALLOCATOR, BalancedShardsAllocator.class);
         registerShardsAllocator(ClusterModule.EVEN_SHARD_COUNT_ALLOCATOR, BalancedShardsAllocator.class);
         registerShardsAllocator(ClusterModule.EVEN_SHARD_COUNT_ALLOCATOR, BalancedShardsAllocator.class);
         this.clusterService = clusterService;
         this.clusterService = clusterService;
+        indexNameExpressionResolver = new IndexNameExpressionResolver(settings);
     }
     }
 
 
     public void registerAllocationDecider(Class<? extends AllocationDecider> allocationDecider) {
     public void registerAllocationDecider(Class<? extends AllocationDecider> allocationDecider) {
@@ -127,6 +128,10 @@ public class ClusterModule extends AbstractModule {
         indexTemplateFilters.registerExtension(indexTemplateFilter);
         indexTemplateFilters.registerExtension(indexTemplateFilter);
     }
     }
 
 
+    public IndexNameExpressionResolver getIndexNameExpressionResolver() {
+        return indexNameExpressionResolver;
+    }
+
     @Override
     @Override
     protected void configure() {
     protected void configure() {
         // bind ShardsAllocator
         // bind ShardsAllocator
@@ -151,7 +156,7 @@ public class ClusterModule extends AbstractModule {
         bind(MetaDataIndexAliasesService.class).asEagerSingleton();
         bind(MetaDataIndexAliasesService.class).asEagerSingleton();
         bind(MetaDataUpdateSettingsService.class).asEagerSingleton();
         bind(MetaDataUpdateSettingsService.class).asEagerSingleton();
         bind(MetaDataIndexTemplateService.class).asEagerSingleton();
         bind(MetaDataIndexTemplateService.class).asEagerSingleton();
-        bind(IndexNameExpressionResolver.class).asEagerSingleton();
+        bind(IndexNameExpressionResolver.class).toInstance(indexNameExpressionResolver);
         bind(RoutingService.class).asEagerSingleton();
         bind(RoutingService.class).asEagerSingleton();
         bind(DelayedAllocationService.class).asEagerSingleton();
         bind(DelayedAllocationService.class).asEagerSingleton();
         bind(ShardStateAction.class).asEagerSingleton();
         bind(ShardStateAction.class).asEagerSingleton();

+ 59 - 0
core/src/main/java/org/elasticsearch/common/NamedRegistry.java

@@ -0,0 +1,59 @@
+/*
+ * 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.common;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A registry from String to some class implementation. Used to ensure implementations are registered only once.
+ */
+public class NamedRegistry<T> {
+    private final Map<String, T> registry = new HashMap<>();
+    private final String targetName;
+
+    public NamedRegistry(String targetName) {
+        this.targetName = targetName;
+    }
+
+    public Map<String, T> getRegistry() {
+        return registry;
+    }
+
+    public void register(String name, T 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");
+        }
+    }
+
+    public <P> void extractAndRegister(List<P> plugins, Function<P, Map<String, T>> lookup) {
+        for (P plugin : plugins) {
+            for (Map.Entry<String, T> entry : lookup.apply(plugin).entrySet()) {
+                register(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+}

+ 9 - 38
core/src/main/java/org/elasticsearch/indices/analysis/AnalysisModule.java

@@ -21,6 +21,7 @@ package org.elasticsearch.indices.analysis;
 
 
 import org.elasticsearch.Version;
 import org.elasticsearch.Version;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
+import org.elasticsearch.common.NamedRegistry;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.index.IndexSettings;
 import org.elasticsearch.index.IndexSettings;
@@ -143,12 +144,7 @@ import org.elasticsearch.index.analysis.compound.HyphenationCompoundWordTokenFil
 import org.elasticsearch.plugins.AnalysisPlugin;
 import org.elasticsearch.plugins.AnalysisPlugin;
 
 
 import java.io.IOException;
 import java.io.IOException;
-import java.util.HashMap;
 import java.util.List;
 import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import static java.util.Objects.requireNonNull;
 
 
 /**
 /**
  * Sets up {@link AnalysisRegistry}.
  * Sets up {@link AnalysisRegistry}.
@@ -170,12 +166,12 @@ public final class AnalysisModule {
     public AnalysisModule(Environment environment, List<AnalysisPlugin> plugins) throws IOException {
     public AnalysisModule(Environment environment, List<AnalysisPlugin> plugins) throws IOException {
         NamedRegistry<AnalysisProvider<CharFilterFactory>> charFilters = setupCharFilters(plugins);
         NamedRegistry<AnalysisProvider<CharFilterFactory>> charFilters = setupCharFilters(plugins);
         NamedRegistry<org.apache.lucene.analysis.hunspell.Dictionary> hunspellDictionaries = setupHunspellDictionaries(plugins);
         NamedRegistry<org.apache.lucene.analysis.hunspell.Dictionary> hunspellDictionaries = setupHunspellDictionaries(plugins);
-        hunspellService = new HunspellService(environment.settings(), environment, hunspellDictionaries.registry);
+        hunspellService = new HunspellService(environment.settings(), environment, hunspellDictionaries.getRegistry());
         NamedRegistry<AnalysisProvider<TokenFilterFactory>> tokenFilters = setupTokenFilters(plugins, hunspellService);
         NamedRegistry<AnalysisProvider<TokenFilterFactory>> tokenFilters = setupTokenFilters(plugins, hunspellService);
         NamedRegistry<AnalysisProvider<TokenizerFactory>> tokenizers = setupTokenizers(plugins);
         NamedRegistry<AnalysisProvider<TokenizerFactory>> tokenizers = setupTokenizers(plugins);
         NamedRegistry<AnalysisProvider<AnalyzerProvider<?>>> analyzers = setupAnalyzers(plugins);
         NamedRegistry<AnalysisProvider<AnalyzerProvider<?>>> analyzers = setupAnalyzers(plugins);
-        analysisRegistry = new AnalysisRegistry(environment, charFilters.registry, tokenFilters.registry,
-                tokenizers.registry, analyzers.registry);
+        analysisRegistry = new AnalysisRegistry(environment, charFilters.getRegistry(), tokenFilters.getRegistry(),
+                tokenizers.getRegistry(), analyzers.getRegistry());
     }
     }
 
 
     HunspellService getHunspellService() {
     HunspellService getHunspellService() {
@@ -191,13 +187,13 @@ public final class AnalysisModule {
         charFilters.register("html_strip", HtmlStripCharFilterFactory::new);
         charFilters.register("html_strip", HtmlStripCharFilterFactory::new);
         charFilters.register("pattern_replace", requriesAnalysisSettings(PatternReplaceCharFilterFactory::new));
         charFilters.register("pattern_replace", requriesAnalysisSettings(PatternReplaceCharFilterFactory::new));
         charFilters.register("mapping", requriesAnalysisSettings(MappingCharFilterFactory::new));
         charFilters.register("mapping", requriesAnalysisSettings(MappingCharFilterFactory::new));
-        charFilters.registerPlugins(plugins, AnalysisPlugin::getCharFilters);
+        charFilters.extractAndRegister(plugins, AnalysisPlugin::getCharFilters);
         return charFilters;
         return charFilters;
     }
     }
 
 
     public NamedRegistry<org.apache.lucene.analysis.hunspell.Dictionary> setupHunspellDictionaries(List<AnalysisPlugin> plugins) {
     public NamedRegistry<org.apache.lucene.analysis.hunspell.Dictionary> setupHunspellDictionaries(List<AnalysisPlugin> plugins) {
         NamedRegistry<org.apache.lucene.analysis.hunspell.Dictionary> hunspellDictionaries = new NamedRegistry<>("dictionary");
         NamedRegistry<org.apache.lucene.analysis.hunspell.Dictionary> hunspellDictionaries = new NamedRegistry<>("dictionary");
-        hunspellDictionaries.registerPlugins(plugins, AnalysisPlugin::getHunspellDictionaries);
+        hunspellDictionaries.extractAndRegister(plugins, AnalysisPlugin::getHunspellDictionaries);
         return hunspellDictionaries;
         return hunspellDictionaries;
     }
     }
 
 
@@ -262,7 +258,7 @@ public final class AnalysisModule {
         tokenFilters.register("classic", ClassicFilterFactory::new);
         tokenFilters.register("classic", ClassicFilterFactory::new);
         tokenFilters.register("decimal_digit", DecimalDigitFilterFactory::new);
         tokenFilters.register("decimal_digit", DecimalDigitFilterFactory::new);
         tokenFilters.register("fingerprint", FingerprintTokenFilterFactory::new);
         tokenFilters.register("fingerprint", FingerprintTokenFilterFactory::new);
-        tokenFilters.registerPlugins(plugins, AnalysisPlugin::getTokenFilters);
+        tokenFilters.extractAndRegister(plugins, AnalysisPlugin::getTokenFilters);
         return tokenFilters;
         return tokenFilters;
     }
     }
 
 
@@ -283,7 +279,7 @@ public final class AnalysisModule {
         tokenizers.register("pattern", PatternTokenizerFactory::new);
         tokenizers.register("pattern", PatternTokenizerFactory::new);
         tokenizers.register("classic", ClassicTokenizerFactory::new);
         tokenizers.register("classic", ClassicTokenizerFactory::new);
         tokenizers.register("thai", ThaiTokenizerFactory::new);
         tokenizers.register("thai", ThaiTokenizerFactory::new);
-        tokenizers.registerPlugins(plugins, AnalysisPlugin::getTokenizers);
+        tokenizers.extractAndRegister(plugins, AnalysisPlugin::getTokenizers);
         return tokenizers;
         return tokenizers;
     }
     }
 
 
@@ -333,7 +329,7 @@ public final class AnalysisModule {
         analyzers.register("turkish", TurkishAnalyzerProvider::new);
         analyzers.register("turkish", TurkishAnalyzerProvider::new);
         analyzers.register("thai", ThaiAnalyzerProvider::new);
         analyzers.register("thai", ThaiAnalyzerProvider::new);
         analyzers.register("fingerprint", FingerprintAnalyzerProvider::new);
         analyzers.register("fingerprint", FingerprintAnalyzerProvider::new);
-        analyzers.registerPlugins(plugins, AnalysisPlugin::getAnalyzers);
+        analyzers.extractAndRegister(plugins, AnalysisPlugin::getAnalyzers);
         return analyzers;
         return analyzers;
     }
     }
 
 
@@ -392,29 +388,4 @@ public final class AnalysisModule {
             return false;
             return false;
         }
         }
     }
     }
-
-    private static class NamedRegistry<T> {
-        private final Map<String, T> registry = new HashMap<>();
-        private final String targetName;
-
-        public NamedRegistry(String targetName) {
-            this.targetName = targetName;
-        }
-
-        private void register(String name, T 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");
-            }
-        }
-
-        private <P> void registerPlugins(List<P> plugins, Function<P, Map<String, T>> lookup) {
-            for (P plugin : plugins) {
-                for (Map.Entry<String, T> entry : lookup.apply(plugin).entrySet()) {
-                    register(entry.getKey(), entry.getValue());
-                }
-            }
-        }
-    }
 }
 }

+ 7 - 3
core/src/main/java/org/elasticsearch/node/Node.java

@@ -86,8 +86,9 @@ import org.elasticsearch.monitor.MonitorService;
 import org.elasticsearch.monitor.jvm.JvmInfo;
 import org.elasticsearch.monitor.jvm.JvmInfo;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
 import org.elasticsearch.node.service.NodeService;
 import org.elasticsearch.node.service.NodeService;
-import org.elasticsearch.plugins.MapperPlugin;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.AnalysisPlugin;
 import org.elasticsearch.plugins.AnalysisPlugin;
+import org.elasticsearch.plugins.MapperPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.PluginsService;
 import org.elasticsearch.plugins.PluginsService;
 import org.elasticsearch.plugins.ScriptPlugin;
 import org.elasticsearch.plugins.ScriptPlugin;
@@ -258,10 +259,13 @@ public class Node implements Closeable {
             modules.add(new NodeModule(this, monitorService));
             modules.add(new NodeModule(this, monitorService));
             modules.add(new NetworkModule(networkService, settings, false, namedWriteableRegistry));
             modules.add(new NetworkModule(networkService, settings, false, namedWriteableRegistry));
             modules.add(new DiscoveryModule(this.settings));
             modules.add(new DiscoveryModule(this.settings));
-            modules.add(new ClusterModule(this.settings, clusterService));
+            ClusterModule clusterModule = new ClusterModule(settings, clusterService);
+            modules.add(clusterModule);
             modules.add(new IndicesModule(namedWriteableRegistry, pluginsService.filterPlugins(MapperPlugin.class)));
             modules.add(new IndicesModule(namedWriteableRegistry, pluginsService.filterPlugins(MapperPlugin.class)));
             modules.add(new SearchModule(settings, namedWriteableRegistry));
             modules.add(new SearchModule(settings, namedWriteableRegistry));
-            modules.add(new ActionModule(DiscoveryNode.isIngestNode(settings), false));
+            modules.add(new ActionModule(DiscoveryNode.isIngestNode(settings), false, settings,
+                    clusterModule.getIndexNameExpressionResolver(), settingsModule.getClusterSettings(),
+                    pluginsService.filterPlugins(ActionPlugin.class)));
             modules.add(new GatewayModule());
             modules.add(new GatewayModule());
             modules.add(new RepositoriesModule());
             modules.add(new RepositoriesModule());
             pluginsService.processModules(modules);
             pluginsService.processModules(modules);

+ 87 - 0
core/src/main/java/org/elasticsearch/plugins/ActionPlugin.java

@@ -0,0 +1,87 @@
+/*
+ * 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.plugins;
+
+import org.elasticsearch.action.ActionRequest;
+import org.elasticsearch.action.ActionResponse;
+import org.elasticsearch.action.GenericAction;
+import org.elasticsearch.action.support.ActionFilter;
+import org.elasticsearch.action.support.TransportAction;
+import org.elasticsearch.action.support.TransportActions;
+
+import java.util.List;
+
+import static java.util.Collections.emptyList;
+
+/**
+ * An additional extension point for {@link Plugin}s that extends Elasticsearch's scripting functionality. Implement it like this:
+ * <pre>{@code
+ *   {@literal @}Override
+ *   public List<ActionHandler<?, ?>> getActions() {
+ *       return Arrays.asList(new ActionHandler<>(ReindexAction.INSTANCE, TransportReindexAction.class),
+ *               new ActionHandler<>(UpdateByQueryAction.INSTANCE, TransportUpdateByQueryAction.class),
+ *               new ActionHandler<>(DeleteByQueryAction.INSTANCE, TransportDeleteByQueryAction.class),
+ *               new ActionHandler<>(RethrottleAction.INSTANCE, TransportRethrottleAction.class));
+ *   }
+ * }</pre>
+ */
+public interface ActionPlugin {
+    /**
+     * Actions added by this plugin.
+     */
+    default List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
+        return emptyList();
+    }
+    /**
+     * Action filters added by this plugin.
+     */
+    default List<Class<? extends ActionFilter>> getActionFilters() {
+        return emptyList();
+    }
+
+    public static final class ActionHandler<Request extends ActionRequest<Request>, Response extends ActionResponse> {
+        private final GenericAction<Request, Response> action;
+        private final Class<? extends TransportAction<Request, Response>> transportAction;
+        private final Class<?>[] supportTransportActions;
+
+        /**
+         * Create a record of an action, the {@linkplain TransportAction} that handles it, and any supporting {@linkplain TransportActions}
+         * that are needed by that {@linkplain TransportAction}.
+         */
+        public ActionHandler(GenericAction<Request, Response> action, Class<? extends TransportAction<Request, Response>> transportAction,
+                Class<?>... supportTransportActions) {
+            this.action = action;
+            this.transportAction = transportAction;
+            this.supportTransportActions = supportTransportActions;
+        }
+
+        public GenericAction<Request, Response> getAction() {
+            return action;
+        }
+
+        public Class<? extends TransportAction<Request, Response>> getTransportAction() {
+            return transportAction;
+        }
+
+        public Class<?>[] getSupportTransportActions() {
+            return supportTransportActions;
+        }
+    }
+}

+ 9 - 0
core/src/main/java/org/elasticsearch/plugins/Plugin.java

@@ -19,6 +19,7 @@
 
 
 package org.elasticsearch.plugins;
 package org.elasticsearch.plugins;
 
 
+import org.elasticsearch.action.ActionModule;
 import org.elasticsearch.common.component.LifecycleComponent;
 import org.elasticsearch.common.component.LifecycleComponent;
 import org.elasticsearch.common.inject.Module;
 import org.elasticsearch.common.inject.Module;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Setting;
@@ -112,6 +113,14 @@ public abstract class Plugin {
     @Deprecated
     @Deprecated
     public final void onModule(AnalysisModule module) {}
     public final void onModule(AnalysisModule module) {}
 
 
+    /**
+     * Old-style action extension point.
+     *
+     * @deprecated implement {@link ActionPlugin} instead
+     */
+    @Deprecated
+    public final void onModule(ActionModule module) {}
+
     /**
     /**
      * Provides the list of this plugin's custom thread pools, empty if
      * Provides the list of this plugin's custom thread pools, empty if
      * none.
      * none.

+ 9 - 5
core/src/test/java/org/elasticsearch/action/admin/cluster/node/tasks/TestTaskPlugin.java

@@ -20,8 +20,9 @@ package org.elasticsearch.action.admin.cluster.node.tasks;
 
 
 import org.elasticsearch.action.Action;
 import org.elasticsearch.action.Action;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.ActionModule;
+import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestBuilder;
 import org.elasticsearch.action.ActionRequestBuilder;
+import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.FailedNodeException;
 import org.elasticsearch.action.FailedNodeException;
 import org.elasticsearch.action.TaskOperationFailure;
 import org.elasticsearch.action.TaskOperationFailure;
 import org.elasticsearch.action.support.ActionFilters;
 import org.elasticsearch.action.support.ActionFilters;
@@ -46,6 +47,7 @@ import org.elasticsearch.common.io.stream.Writeable;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.ToXContent;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.tasks.CancellableTask;
 import org.elasticsearch.tasks.CancellableTask;
 import org.elasticsearch.tasks.Task;
 import org.elasticsearch.tasks.Task;
@@ -55,6 +57,7 @@ import org.elasticsearch.transport.TransportService;
 
 
 import java.io.IOException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.List;
@@ -64,11 +67,12 @@ import static org.elasticsearch.test.ESTestCase.awaitBusy;
 /**
 /**
  * A plugin that adds a cancellable blocking test task of integration testing of the task manager.
  * A plugin that adds a cancellable blocking test task of integration testing of the task manager.
  */
  */
-public class TestTaskPlugin extends Plugin {
+public class TestTaskPlugin extends Plugin implements ActionPlugin {
 
 
-    public void onModule(ActionModule module) {
-        module.registerAction(TestTaskAction.INSTANCE, TransportTestTaskAction.class);
-        module.registerAction(UnblockTestTasksAction.INSTANCE, TransportUnblockTestTasksAction.class);
+    @Override
+    public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
+        return Arrays.asList(new ActionHandler<>(TestTaskAction.INSTANCE, TransportTestTaskAction.class),
+                new ActionHandler<>(UnblockTestTasksAction.INSTANCE, TransportUnblockTestTasksAction.class));
     }
     }
 
 
     static class TestTask extends CancellableTask {
     static class TestTask extends CancellableTask {

+ 7 - 6
core/src/test/java/org/elasticsearch/cluster/ClusterInfoServiceIT.java

@@ -22,7 +22,6 @@ package org.elasticsearch.cluster;
 import com.carrotsearch.hppc.cursors.ObjectCursor;
 import com.carrotsearch.hppc.cursors.ObjectCursor;
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.ActionModule;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsAction;
 import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsAction;
@@ -31,7 +30,6 @@ import org.elasticsearch.action.support.ActionFilter;
 import org.elasticsearch.action.support.ActionFilters;
 import org.elasticsearch.action.support.ActionFilters;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.node.DiscoveryNode;
-import org.elasticsearch.cluster.routing.RoutingNodes;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.routing.ShardRouting;
 import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
 import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -44,6 +42,7 @@ import org.elasticsearch.index.IndexService;
 import org.elasticsearch.index.shard.IndexShard;
 import org.elasticsearch.index.shard.IndexShard;
 import org.elasticsearch.index.store.Store;
 import org.elasticsearch.index.store.Store;
 import org.elasticsearch.indices.IndicesService;
 import org.elasticsearch.indices.IndicesService;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.elasticsearch.test.InternalTestCluster;
 import org.elasticsearch.test.InternalTestCluster;
@@ -56,11 +55,13 @@ import org.hamcrest.Matchers;
 
 
 import java.io.IOException;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collection;
+import java.util.List;
 import java.util.Set;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 
 import static java.util.Collections.emptySet;
 import static java.util.Collections.emptySet;
+import static java.util.Collections.singletonList;
 import static java.util.Collections.unmodifiableSet;
 import static java.util.Collections.unmodifiableSet;
 import static org.elasticsearch.common.util.set.Sets.newHashSet;
 import static org.elasticsearch.common.util.set.Sets.newHashSet;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@@ -74,10 +75,10 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0)
 @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0)
 public class ClusterInfoServiceIT extends ESIntegTestCase {
 public class ClusterInfoServiceIT extends ESIntegTestCase {
 
 
-    public static class TestPlugin extends Plugin {
-
-        public void onModule(ActionModule module) {
-            module.registerFilter(BlockingActionFilter.class);
+    public static class TestPlugin extends Plugin implements ActionPlugin {
+        @Override
+        public List<Class<? extends ActionFilter>> getActionFilters() {
+            return singletonList(BlockingActionFilter.class);
         }
         }
     }
     }
 
 

+ 6 - 4
core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java

@@ -21,7 +21,6 @@ package org.elasticsearch.transport;
 
 
 import org.apache.http.message.BasicHeader;
 import org.apache.http.message.BasicHeader;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.ActionModule;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
 import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
@@ -45,6 +44,7 @@ import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.TermsQueryBuilder;
 import org.elasticsearch.index.query.TermsQueryBuilder;
 import org.elasticsearch.indices.TermsLookup;
 import org.elasticsearch.indices.TermsLookup;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.rest.RestController;
 import org.elasticsearch.rest.RestController;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.elasticsearch.test.ESIntegTestCase;
@@ -61,6 +61,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 
+import static java.util.Collections.singletonList;
 import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
 import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
 import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
 import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
 import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE;
 import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE;
@@ -284,15 +285,16 @@ public class ContextAndHeaderTransportIT extends ESIntegTestCase {
         return internalCluster().transportClient().filterWithHeader(Collections.singletonMap(randomHeaderKey, randomHeaderValue));
         return internalCluster().transportClient().filterWithHeader(Collections.singletonMap(randomHeaderKey, randomHeaderValue));
     }
     }
 
 
-    public static class ActionLoggingPlugin extends Plugin {
+    public static class ActionLoggingPlugin extends Plugin implements ActionPlugin {
 
 
         @Override
         @Override
         public Collection<Module> nodeModules() {
         public Collection<Module> nodeModules() {
             return Collections.<Module>singletonList(new ActionLoggingModule());
             return Collections.<Module>singletonList(new ActionLoggingModule());
         }
         }
 
 
-        public void onModule(ActionModule module) {
-            module.registerFilter(LoggingFilter.class);
+        @Override
+        public List<Class<? extends ActionFilter>> getActionFilters() {
+            return singletonList(LoggingFilter.class);
         }
         }
     }
     }
 
 

+ 3 - 0
docs/reference/migration/migrate_5_0/plugins.asciidoc

@@ -133,4 +133,7 @@ Plugins that register custom analysis components should implement
 Plugins that register custom mappers should implement
 Plugins that register custom mappers should implement
 `MapperPlugin` and remove their `onModule(IndicesModule)` implementation.
 `MapperPlugin` and remove their `onModule(IndicesModule)` implementation.
 
 
+==== ActionPlugin
 
 
+Plugins that register custom actions should implement `ActionPlugin` and
+remove their `onModule(ActionModule)` implementation.

+ 11 - 7
modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/MustachePlugin.java

@@ -19,13 +19,15 @@
 
 
 package org.elasticsearch.script.mustache;
 package org.elasticsearch.script.mustache;
 
 
-import org.elasticsearch.action.ActionModule;
+import org.elasticsearch.action.ActionRequest;
+import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.action.search.template.MultiSearchTemplateAction;
 import org.elasticsearch.action.search.template.MultiSearchTemplateAction;
 import org.elasticsearch.action.search.template.SearchTemplateAction;
 import org.elasticsearch.action.search.template.SearchTemplateAction;
 import org.elasticsearch.action.search.template.TransportMultiSearchTemplateAction;
 import org.elasticsearch.action.search.template.TransportMultiSearchTemplateAction;
 import org.elasticsearch.action.search.template.TransportSearchTemplateAction;
 import org.elasticsearch.action.search.template.TransportSearchTemplateAction;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.ScriptPlugin;
 import org.elasticsearch.plugins.ScriptPlugin;
 import org.elasticsearch.rest.action.search.template.RestDeleteSearchTemplateAction;
 import org.elasticsearch.rest.action.search.template.RestDeleteSearchTemplateAction;
@@ -34,20 +36,22 @@ import org.elasticsearch.rest.action.search.template.RestMultiSearchTemplateActi
 import org.elasticsearch.rest.action.search.template.RestPutSearchTemplateAction;
 import org.elasticsearch.rest.action.search.template.RestPutSearchTemplateAction;
 import org.elasticsearch.rest.action.search.template.RestRenderSearchTemplateAction;
 import org.elasticsearch.rest.action.search.template.RestRenderSearchTemplateAction;
 import org.elasticsearch.rest.action.search.template.RestSearchTemplateAction;
 import org.elasticsearch.rest.action.search.template.RestSearchTemplateAction;
-import org.elasticsearch.script.ScriptEngineRegistry;
 import org.elasticsearch.script.ScriptEngineService;
 import org.elasticsearch.script.ScriptEngineService;
-import org.elasticsearch.script.ScriptModule;
 
 
-public class MustachePlugin extends Plugin implements ScriptPlugin {
+import java.util.Arrays;
+import java.util.List;
+
+public class MustachePlugin extends Plugin implements ScriptPlugin, ActionPlugin {
 
 
     @Override
     @Override
     public ScriptEngineService getScriptEngineService(Settings settings) {
     public ScriptEngineService getScriptEngineService(Settings settings) {
         return new MustacheScriptEngineService(settings);
         return new MustacheScriptEngineService(settings);
     }
     }
 
 
-    public void onModule(ActionModule module) {
-        module.registerAction(SearchTemplateAction.INSTANCE, TransportSearchTemplateAction.class);
-        module.registerAction(MultiSearchTemplateAction.INSTANCE, TransportMultiSearchTemplateAction.class);
+    @Override
+    public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
+        return Arrays.asList(new ActionHandler<>(SearchTemplateAction.INSTANCE, TransportSearchTemplateAction.class),
+                new ActionHandler<>(MultiSearchTemplateAction.INSTANCE, TransportMultiSearchTemplateAction.class));
     }
     }
 
 
     public void onModule(NetworkModule module) {
     public void onModule(NetworkModule module) {

+ 13 - 10
modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorPlugin.java

@@ -19,23 +19,25 @@
 
 
 package org.elasticsearch.percolator;
 package org.elasticsearch.percolator;
 
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.elasticsearch.action.ActionModule;
+import org.elasticsearch.action.ActionRequest;
+import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.client.transport.TransportClient;
 import org.elasticsearch.client.transport.TransportClient;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.index.mapper.Mapper;
 import org.elasticsearch.index.mapper.Mapper;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.MapperPlugin;
 import org.elasticsearch.plugins.MapperPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.search.SearchModule;
 import org.elasticsearch.search.SearchModule;
 
 
-public class PercolatorPlugin extends Plugin implements MapperPlugin {
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class PercolatorPlugin extends Plugin implements MapperPlugin, ActionPlugin {
 
 
     public static final String NAME = "percolator";
     public static final String NAME = "percolator";
 
 
@@ -47,9 +49,10 @@ public class PercolatorPlugin extends Plugin implements MapperPlugin {
         this.settings = settings;
         this.settings = settings;
     }
     }
 
 
-    public void onModule(ActionModule module) {
-        module.registerAction(PercolateAction.INSTANCE, TransportPercolateAction.class);
-        module.registerAction(MultiPercolateAction.INSTANCE, TransportMultiPercolateAction.class);
+    @Override
+    public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
+        return Arrays.asList(new ActionHandler<>(PercolateAction.INSTANCE, TransportPercolateAction.class),
+                new ActionHandler<>(MultiPercolateAction.INSTANCE, TransportMultiPercolateAction.class));
     }
     }
 
 
     public void onModule(NetworkModule module) {
     public void onModule(NetworkModule module) {

+ 13 - 7
modules/reindex/src/main/java/org/elasticsearch/index/reindex/ReindexPlugin.java

@@ -19,18 +19,24 @@
 
 
 package org.elasticsearch.index.reindex;
 package org.elasticsearch.index.reindex;
 
 
-import org.elasticsearch.action.ActionModule;
+import org.elasticsearch.action.ActionRequest;
+import org.elasticsearch.action.ActionResponse;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.network.NetworkModule;
+import org.elasticsearch.plugins.ActionPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.plugins.Plugin;
 
 
-public class ReindexPlugin extends Plugin {
+import java.util.Arrays;
+import java.util.List;
+
+public class ReindexPlugin extends Plugin implements ActionPlugin {
     public static final String NAME = "reindex";
     public static final String NAME = "reindex";
 
 
-    public void onModule(ActionModule actionModule) {
-        actionModule.registerAction(ReindexAction.INSTANCE, TransportReindexAction.class);
-        actionModule.registerAction(UpdateByQueryAction.INSTANCE, TransportUpdateByQueryAction.class);
-        actionModule.registerAction(DeleteByQueryAction.INSTANCE, TransportDeleteByQueryAction.class);
-        actionModule.registerAction(RethrottleAction.INSTANCE, TransportRethrottleAction.class);
+    @Override
+    public List<ActionHandler<? extends ActionRequest<?>, ? extends ActionResponse>> getActions() {
+        return Arrays.asList(new ActionHandler<>(ReindexAction.INSTANCE, TransportReindexAction.class),
+                new ActionHandler<>(UpdateByQueryAction.INSTANCE, TransportUpdateByQueryAction.class),
+                new ActionHandler<>(DeleteByQueryAction.INSTANCE, TransportDeleteByQueryAction.class),
+                new ActionHandler<>(RethrottleAction.INSTANCE, TransportRethrottleAction.class));
     }
     }
 
 
     public void onModule(NetworkModule networkModule) {
     public void onModule(NetworkModule networkModule) {