Browse Source

Refactor RestMainAction into separate module (#95881)

we want to allow overriding info (GET /) api in serverless, therefore this commit moves the RestMainAction and is transport classes into a module that has a rest plugin

Main endpoint is often used in testing to verfiy that a cluster is ready, hence this commit also has to add a testing dependency on main to a lot of modules

relates #95422
Przemyslaw Gomulka 2 years ago
parent
commit
dc03c47ada
41 changed files with 200 additions and 47 deletions
  1. 3 1
      modules/reindex/build.gradle
  2. 7 1
      modules/reindex/src/test/java/org/elasticsearch/reindex/ReindexFromRemoteWithAuthTests.java
  3. 2 1
      modules/reindex/src/test/java/org/elasticsearch/reindex/RetryTests.java
  4. 28 0
      modules/rest-root/build.gradle
  5. 15 0
      modules/rest-root/src/main/java/module-info.java
  6. 1 1
      modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainAction.java
  7. 1 1
      modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRequest.java
  8. 1 1
      modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainResponse.java
  9. 45 0
      modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRestPlugin.java
  10. 2 4
      modules/rest-root/src/main/java/org/elasticsearch/rest/root/RestMainAction.java
  11. 1 1
      modules/rest-root/src/main/java/org/elasticsearch/rest/root/TransportMainAction.java
  12. 2 2
      modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainActionTests.java
  13. 1 1
      modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainResponseTests.java
  14. 1 2
      modules/rest-root/src/test/java/org/elasticsearch/rest/root/RestMainActionTests.java
  15. 37 0
      modules/rest-root/src/yamlRestTest/java/org/elasticsearch/rest/root/RestMainClientYamlTestSuiteIT.java
  16. 0 0
      modules/rest-root/src/yamlRestTest/resources/rest-api-spec/test/info/10_info.yml
  17. 0 0
      modules/rest-root/src/yamlRestTest/resources/rest-api-spec/test/info/20_lucene_version.yml
  18. 0 0
      modules/rest-root/src/yamlRestTest/resources/rest-api-spec/test/ping/10_ping.yml
  19. 7 1
      modules/transport-netty4/build.gradle
  20. 2 0
      qa/smoke-test-http/build.gradle
  21. 2 1
      qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/HttpSmokeTestCase.java
  22. 4 0
      qa/verify-version-constants/build.gradle
  23. 1 0
      rest-api-spec/build.gradle
  24. 1 0
      rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java
  25. 6 6
      server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/InitialClusterStateIT.java
  26. 0 1
      server/src/main/java/module-info.java
  27. 0 5
      server/src/main/java/org/elasticsearch/action/ActionModule.java
  28. 10 10
      server/src/test/java/org/elasticsearch/action/ActionModuleTests.java
  29. 1 0
      x-pack/plugin/core/build.gradle
  30. 1 1
      x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java
  31. 1 0
      x-pack/plugin/security/build.gradle
  32. 1 0
      x-pack/plugin/security/qa/service-account/build.gradle
  33. 1 0
      x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java
  34. 3 3
      x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java
  35. 3 1
      x-pack/plugin/security/src/test/java/org/elasticsearch/test/SecuritySettingsSource.java
  36. 1 0
      x-pack/plugin/sql/jdbc/build.gradle
  37. 1 1
      x-pack/plugin/sql/jdbc/src/test/java/org/elasticsearch/xpack/sql/jdbc/VersionParityTests.java
  38. 1 1
      x-pack/plugin/sql/jdbc/src/test/java/org/elasticsearch/xpack/sql/jdbc/WebServerTestCase.java
  39. 2 0
      x-pack/plugin/sql/qa/server/build.gradle
  40. 2 0
      x-pack/qa/full-cluster-restart/build.gradle
  41. 2 0
      x-pack/qa/security-example-spi-extension/build.gradle

+ 3 - 1
modules/reindex/build.gradle

@@ -29,6 +29,7 @@ testClusters.configureEach {
   // Modules who's integration is explicitly tested in integration tests
   module ':modules:parent-join'
   module ':modules:lang-painless'
+  module ':modules:rest-root'
   // Whitelist reindexing from the local node so we can test reindex-from-remote.
   setting 'reindex.remote.whitelist', '127.0.0.1:*'
   requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
@@ -39,12 +40,13 @@ dependencies {
   api project(":libs:elasticsearch-ssl-config")
   // for parent/child testing
   testImplementation project(':modules:parent-join')
+  testImplementation project(':modules:rest-root')
 }
 
 restResources {
   restApi {
     include '_common', 'cluster', 'nodes', 'indices', 'index', 'get', 'search', 'mget', 'count',
-                'update_by_query', 'delete_by_query', 'reindex_rethrottle', 'tasks', 'reindex', 'put_script', 'bulk'
+                'update_by_query', 'delete_by_query', 'reindex_rethrottle', 'tasks', 'reindex', 'put_script', 'bulk', 'info'
   }
 }
 

+ 7 - 1
modules/reindex/src/test/java/org/elasticsearch/reindex/ReindexFromRemoteWithAuthTests.java

@@ -41,6 +41,7 @@ import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.repositories.RepositoriesService;
 import org.elasticsearch.rest.RestHeaderDefinition;
 import org.elasticsearch.rest.RestStatus;
+import org.elasticsearch.rest.root.MainRestPlugin;
 import org.elasticsearch.script.ScriptService;
 import org.elasticsearch.tasks.Task;
 import org.elasticsearch.test.ESSingleNodeTestCase;
@@ -69,7 +70,12 @@ public class ReindexFromRemoteWithAuthTests extends ESSingleNodeTestCase {
 
     @Override
     protected Collection<Class<? extends Plugin>> getPlugins() {
-        return Arrays.asList(Netty4Plugin.class, ReindexFromRemoteWithAuthTests.TestPlugin.class, ReindexPlugin.class);
+        return Arrays.asList(
+            Netty4Plugin.class,
+            ReindexFromRemoteWithAuthTests.TestPlugin.class,
+            ReindexPlugin.class,
+            MainRestPlugin.class
+        );
     }
 
     @Override

+ 2 - 1
modules/reindex/src/test/java/org/elasticsearch/reindex/RetryTests.java

@@ -33,6 +33,7 @@ import org.elasticsearch.index.reindex.RemoteInfo;
 import org.elasticsearch.index.reindex.UpdateByQueryAction;
 import org.elasticsearch.index.reindex.UpdateByQueryRequestBuilder;
 import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.rest.root.MainRestPlugin;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.transport.netty4.Netty4Plugin;
@@ -70,7 +71,7 @@ public class RetryTests extends ESIntegTestCase {
 
     @Override
     protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Arrays.asList(ReindexPlugin.class, Netty4Plugin.class);
+        return Arrays.asList(ReindexPlugin.class, Netty4Plugin.class, MainRestPlugin.class);
     }
 
     /**

+ 28 - 0
modules/rest-root/build.gradle

@@ -0,0 +1,28 @@
+import org.elasticsearch.gradle.internal.info.BuildParams
+
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+apply plugin: 'elasticsearch.internal-yaml-rest-test'
+apply plugin: 'elasticsearch.yaml-rest-compat-test'
+apply plugin: 'elasticsearch.internal-cluster-test'
+
+esplugin {
+  description 'Adds HEAD and GET / endpoint to Elasticsearch'
+  classname 'org.elasticsearch.rest.root.MainRestPlugin'
+}
+
+restResources {
+  restApi {
+    include '_common','info', 'ping'
+  }
+}
+
+artifacts {
+  restTests(new File(projectDir, "src/yamlRestTest/resources/rest-api-spec/test"))
+}
+

+ 15 - 0
modules/rest-root/src/main/java/module-info.java

@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+module org.elasticsearch.rest.root {
+    requires org.elasticsearch.server;
+    requires org.elasticsearch.xcontent;
+    requires org.apache.lucene.core;
+
+    exports org.elasticsearch.rest.root;
+}

+ 1 - 1
server/src/main/java/org/elasticsearch/action/main/MainAction.java → modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainAction.java

@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.action.main;
+package org.elasticsearch.rest.root;
 
 import org.elasticsearch.action.ActionType;
 

+ 1 - 1
server/src/main/java/org/elasticsearch/action/main/MainRequest.java → modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRequest.java

@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.action.main;
+package org.elasticsearch.rest.root;
 
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestValidationException;

+ 1 - 1
server/src/main/java/org/elasticsearch/action/main/MainResponse.java → modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainResponse.java

@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.action.main;
+package org.elasticsearch.rest.root;
 
 import org.elasticsearch.Build;
 import org.elasticsearch.Version;

+ 45 - 0
modules/rest-root/src/main/java/org/elasticsearch/rest/root/MainRestPlugin.java

@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.rest.root;
+
+import org.elasticsearch.action.ActionRequest;
+import org.elasticsearch.action.ActionResponse;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.node.DiscoveryNodes;
+import org.elasticsearch.common.settings.ClusterSettings;
+import org.elasticsearch.common.settings.IndexScopedSettings;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.settings.SettingsFilter;
+import org.elasticsearch.plugins.ActionPlugin;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.rest.RestController;
+import org.elasticsearch.rest.RestHandler;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+public class MainRestPlugin extends Plugin implements ActionPlugin {
+    @Override
+    public List<RestHandler> getRestHandlers(
+        Settings settings,
+        RestController restController,
+        ClusterSettings clusterSettings,
+        IndexScopedSettings indexScopedSettings,
+        SettingsFilter settingsFilter,
+        IndexNameExpressionResolver indexNameExpressionResolver,
+        Supplier<DiscoveryNodes> nodesInCluster
+    ) {
+        return List.of(new RestMainAction());
+    }
+
+    @Override
+    public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
+        return List.of(new ActionHandler<>(MainAction.INSTANCE, TransportMainAction.class));
+    }
+}

+ 2 - 4
server/src/main/java/org/elasticsearch/rest/action/RestMainAction.java → modules/rest-root/src/main/java/org/elasticsearch/rest/root/RestMainAction.java

@@ -6,11 +6,8 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.rest.action;
+package org.elasticsearch.rest.root;
 
-import org.elasticsearch.action.main.MainAction;
-import org.elasticsearch.action.main.MainRequest;
-import org.elasticsearch.action.main.MainResponse;
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
@@ -18,6 +15,7 @@ import org.elasticsearch.rest.RestResponse;
 import org.elasticsearch.rest.RestStatus;
 import org.elasticsearch.rest.Scope;
 import org.elasticsearch.rest.ServerlessScope;
+import org.elasticsearch.rest.action.RestBuilderListener;
 import org.elasticsearch.xcontent.XContentBuilder;
 
 import java.io.IOException;

+ 1 - 1
server/src/main/java/org/elasticsearch/action/main/TransportMainAction.java → modules/rest-root/src/main/java/org/elasticsearch/rest/root/TransportMainAction.java

@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.action.main;
+package org.elasticsearch.rest.root;
 
 import org.elasticsearch.Build;
 import org.elasticsearch.Version;

+ 2 - 2
server/src/test/java/org/elasticsearch/action/main/MainActionTests.java → modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainActionTests.java

@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.action.main;
+package org.elasticsearch.rest.root;
 
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.support.ActionFilters;
@@ -86,7 +86,7 @@ public class MainActionTests extends ESTestCase {
         );
         TransportMainAction action = new TransportMainAction(settings, transportService, mock(ActionFilters.class), clusterService);
         AtomicReference<MainResponse> responseRef = new AtomicReference<>();
-        action.doExecute(mock(Task.class), new MainRequest(), new ActionListener<MainResponse>() {
+        action.doExecute(mock(Task.class), new MainRequest(), new ActionListener<>() {
             @Override
             public void onResponse(MainResponse mainResponse) {
                 responseRef.set(mainResponse);

+ 1 - 1
server/src/test/java/org/elasticsearch/action/main/MainResponseTests.java → modules/rest-root/src/test/java/org/elasticsearch/rest/root/MainResponseTests.java

@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.action.main;
+package org.elasticsearch.rest.root;
 
 import org.elasticsearch.Build;
 import org.elasticsearch.Version;

+ 1 - 2
server/src/test/java/org/elasticsearch/rest/action/RestMainActionTests.java → modules/rest-root/src/test/java/org/elasticsearch/rest/root/RestMainActionTests.java

@@ -6,11 +6,10 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.rest.action;
+package org.elasticsearch.rest.root;
 
 import org.elasticsearch.Build;
 import org.elasticsearch.Version;
-import org.elasticsearch.action.main.MainResponse;
 import org.elasticsearch.cluster.ClusterName;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.rest.RestRequest;

+ 37 - 0
modules/rest-root/src/yamlRestTest/java/org/elasticsearch/rest/root/RestMainClientYamlTestSuiteIT.java

@@ -0,0 +1,37 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.rest.root;
+
+import com.carrotsearch.randomizedtesting.annotations.Name;
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+
+import org.elasticsearch.test.cluster.ElasticsearchCluster;
+import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
+import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
+import org.junit.ClassRule;
+
+/** Runs yaml rest tests */
+public class RestMainClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
+    @ClassRule
+    public static ElasticsearchCluster cluster = ElasticsearchCluster.local().module("rest-root").build();
+
+    public RestMainClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
+        super(testCandidate);
+    }
+
+    @ParametersFactory
+    public static Iterable<Object[]> parameters() throws Exception {
+        return ESClientYamlSuiteTestCase.createParameters();
+    }
+
+    @Override
+    protected String getTestRestCluster() {
+        return cluster.getHttpAddresses();
+    }
+}

+ 0 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/info/10_info.yml → modules/rest-root/src/yamlRestTest/resources/rest-api-spec/test/info/10_info.yml


+ 0 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/info/20_lucene_version.yml → modules/rest-root/src/yamlRestTest/resources/rest-api-spec/test/info/20_lucene_version.yml


+ 0 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/ping/10_ping.yml → modules/rest-root/src/yamlRestTest/resources/rest-api-spec/test/ping/10_ping.yml


+ 7 - 1
modules/transport-netty4/build.gradle

@@ -45,11 +45,13 @@ dependencies {
   api "io.netty:netty-resolver:${versions.netty}"
   api "io.netty:netty-transport:${versions.netty}"
   api "io.netty:netty-transport-native-unix-common:${versions.netty}"
+
+  testImplementation project(':modules:rest-root')
 }
 
 restResources {
   restApi {
-    include '_common', 'cluster', 'nodes'
+    include '_common', 'cluster', 'nodes', 'ping'
   }
 }
 
@@ -90,6 +92,10 @@ tasks.named("internalClusterTest").configure {
   systemProperty 'es.insecure_network_trace_enabled', 'true'
 }
 
+testClusters.configureEach {
+  module ':modules:rest-root'
+}
+
 tasks.named("check").configure {
   dependsOn(pooledTest, pooledJavaRestTest, pooledInternalClusterTest)
 }

+ 2 - 0
qa/smoke-test-http/build.gradle

@@ -11,8 +11,10 @@ apply plugin: 'elasticsearch.legacy-java-rest-test'
 
 dependencies {
   javaRestTestImplementation "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}"
+  javaRestTestImplementation project(':modules:rest-root')
 }
 
 testClusters.configureEach {
+  module ':modules:rest-root'
   setting 'xpack.security.enabled', 'false'
 }

+ 2 - 1
qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/HttpSmokeTestCase.java

@@ -10,6 +10,7 @@ package org.elasticsearch.http;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.rest.root.MainRestPlugin;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.elasticsearch.transport.netty4.Netty4Plugin;
 
@@ -34,7 +35,7 @@ public abstract class HttpSmokeTestCase extends ESIntegTestCase {
 
     @Override
     protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return List.of(getTestTransportPlugin());
+        return List.of(getTestTransportPlugin(), MainRestPlugin.class);
     }
 
     @Override

+ 4 - 0
qa/verify-version-constants/build.gradle

@@ -14,6 +14,10 @@ apply plugin: 'elasticsearch.internal-testclusters'
 apply plugin: 'elasticsearch.standalone-rest-test'
 apply plugin: 'elasticsearch.bwc-test'
 
+dependencies {
+  testImplementation project(':modules:rest-root')
+}
+
 BuildParams.bwcVersions.withIndexCompatible { bwcVersion, baseName ->
   def baseCluster = testClusters.register(baseName) {
       version = bwcVersion.toString()

+ 1 - 0
rest-api-spec/build.gradle

@@ -35,6 +35,7 @@ artifacts {
 
 dependencies {
   clusterModules project(":modules:mapper-extras")
+  clusterModules project(":modules:rest-root")
 }
 
 tasks.named("yamlRestTestV7CompatTransform").configure { task ->

+ 1 - 0
rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java

@@ -28,6 +28,7 @@ public class ClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
     @ClassRule
     public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
         .module("mapper-extras")
+        .module("rest-root")
         .feature(FeatureFlag.TIME_SERIES_MODE)
         .feature(FeatureFlag.DLM_ENABLED)
         .build();

+ 6 - 6
server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/InitialClusterStateIT.java

@@ -8,9 +8,9 @@
 
 package org.elasticsearch.cluster.coordination;
 
-import org.elasticsearch.action.main.MainAction;
-import org.elasticsearch.action.main.MainRequest;
-import org.elasticsearch.action.main.MainResponse;
+import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
+import org.elasticsearch.action.admin.cluster.stats.ClusterStatsRequest;
+import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
 import org.elasticsearch.action.support.PlainActionFuture;
 import org.elasticsearch.cluster.metadata.Metadata;
 import org.elasticsearch.cluster.service.ClusterService;
@@ -40,12 +40,12 @@ public class InitialClusterStateIT extends ESIntegTestCase {
             assertEquals(expectCommitted, metadata.clusterUUIDCommitted());
             assertEquals(expectedValue, metadata.clusterUUID());
 
-            final MainResponse mainResponse = PlainActionFuture.get(
-                fut -> client(nodeName).execute(MainAction.INSTANCE, new MainRequest(), fut),
+            final ClusterStatsResponse response = PlainActionFuture.get(
+                fut -> client(nodeName).execute(ClusterStatsAction.INSTANCE, new ClusterStatsRequest(), fut),
                 10,
                 TimeUnit.SECONDS
             );
-            assertEquals(expectedValue, mainResponse.getClusterUuid());
+            assertEquals(expectedValue, response.getClusterUUID());
         }
     }
 

+ 0 - 1
server/src/main/java/module-info.java

@@ -134,7 +134,6 @@ module org.elasticsearch.server {
     exports org.elasticsearch.action.get;
     exports org.elasticsearch.action.index;
     exports org.elasticsearch.action.ingest;
-    exports org.elasticsearch.action.main;
     exports org.elasticsearch.action.resync;
     exports org.elasticsearch.action.search;
     exports org.elasticsearch.action.support;

+ 0 - 5
server/src/main/java/org/elasticsearch/action/ActionModule.java

@@ -229,8 +229,6 @@ import org.elasticsearch.action.ingest.PutPipelineAction;
 import org.elasticsearch.action.ingest.PutPipelineTransportAction;
 import org.elasticsearch.action.ingest.SimulatePipelineAction;
 import org.elasticsearch.action.ingest.SimulatePipelineTransportAction;
-import org.elasticsearch.action.main.MainAction;
-import org.elasticsearch.action.main.TransportMainAction;
 import org.elasticsearch.action.search.ClearScrollAction;
 import org.elasticsearch.action.search.ClosePointInTimeAction;
 import org.elasticsearch.action.search.MultiSearchAction;
@@ -299,7 +297,6 @@ import org.elasticsearch.rest.RestHandler;
 import org.elasticsearch.rest.RestHeaderDefinition;
 import org.elasticsearch.rest.RestUtils;
 import org.elasticsearch.rest.action.RestFieldCapabilitiesAction;
-import org.elasticsearch.rest.action.RestMainAction;
 import org.elasticsearch.rest.action.admin.cluster.RestAddVotingConfigExclusionAction;
 import org.elasticsearch.rest.action.admin.cluster.RestCancelTasksAction;
 import org.elasticsearch.rest.action.admin.cluster.RestCleanupRepositoryAction;
@@ -608,7 +605,6 @@ public class ActionModule extends AbstractModule {
         }
         ActionRegistry actions = new ActionRegistry();
 
-        actions.register(MainAction.INSTANCE, TransportMainAction.class);
         actions.register(NodesInfoAction.INSTANCE, TransportNodesInfoAction.class);
         actions.register(RemoteInfoAction.INSTANCE, TransportRemoteInfoAction.class);
         actions.register(RemoteClusterNodesAction.INSTANCE, RemoteClusterNodesAction.TransportAction.class);
@@ -798,7 +794,6 @@ public class ActionModule extends AbstractModule {
         };
         registerHandler.accept(new RestAddVotingConfigExclusionAction());
         registerHandler.accept(new RestClearVotingConfigExclusionsAction());
-        registerHandler.accept(new RestMainAction());
         registerHandler.accept(new RestNodesInfoAction(settingsFilter));
         registerHandler.accept(new RestRemoteClusterInfoAction());
         registerHandler.accept(new RestNodesStatsAction());

+ 10 - 10
server/src/test/java/org/elasticsearch/action/ActionModuleTests.java

@@ -8,8 +8,8 @@
 
 package org.elasticsearch.action;
 
-import org.elasticsearch.action.main.MainAction;
-import org.elasticsearch.action.main.TransportMainAction;
+import org.elasticsearch.action.admin.cluster.node.info.NodesInfoAction;
+import org.elasticsearch.action.admin.cluster.node.info.TransportNodesInfoAction;
 import org.elasticsearch.action.support.ActionFilters;
 import org.elasticsearch.action.support.TransportAction;
 import org.elasticsearch.client.internal.node.NodeClient;
@@ -30,7 +30,7 @@ import org.elasticsearch.rest.RestChannel;
 import org.elasticsearch.rest.RestController;
 import org.elasticsearch.rest.RestHandler;
 import org.elasticsearch.rest.RestRequest;
-import org.elasticsearch.rest.action.RestMainAction;
+import org.elasticsearch.rest.action.admin.cluster.RestNodesInfoAction;
 import org.elasticsearch.tasks.Task;
 import org.elasticsearch.tasks.TaskManager;
 import org.elasticsearch.test.ESTestCase;
@@ -56,7 +56,7 @@ public class ActionModuleTests extends ESTestCase {
     public void testSetupActionsContainsKnownBuiltin() {
         assertThat(
             ActionModule.setupActions(emptyList()),
-            hasEntry(MainAction.INSTANCE.name(), new ActionHandler<>(MainAction.INSTANCE, TransportMainAction.class))
+            hasEntry(NodesInfoAction.INSTANCE.name(), new ActionHandler<>(NodesInfoAction.INSTANCE, TransportNodesInfoAction.class))
         );
     }
 
@@ -64,11 +64,11 @@ public class ActionModuleTests extends ESTestCase {
         ActionPlugin dupsMainAction = new ActionPlugin() {
             @Override
             public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
-                return singletonList(new ActionHandler<>(MainAction.INSTANCE, TransportMainAction.class));
+                return singletonList(new ActionHandler<>(NodesInfoAction.INSTANCE, TransportNodesInfoAction.class));
             }
         };
         Exception e = expectThrows(IllegalArgumentException.class, () -> ActionModule.setupActions(singletonList(dupsMainAction)));
-        assertEquals("action for name [" + MainAction.NAME + "] already registered", e.getMessage());
+        assertEquals("action for name [" + NodesInfoAction.NAME + "] already registered", e.getMessage());
     }
 
     public void testPluginCanRegisterAction() {
@@ -133,11 +133,11 @@ public class ActionModuleTests extends ESTestCase {
 
                 @Override
                 public List<Route> routes() {
-                    return List.of(new Route(GET, "/"));
+                    return List.of(new Route(GET, "/_nodes"));
                 }
             })
         );
-        assertThat(e.getMessage(), startsWith("Cannot replace existing handler for [/] for method: GET"));
+        assertThat(e.getMessage(), startsWith("Cannot replace existing handler for [/_nodes] for method: GET"));
     }
 
     public void testPluginCantOverwriteBuiltinRestHandler() throws IOException {
@@ -152,7 +152,7 @@ public class ActionModuleTests extends ESTestCase {
                 IndexNameExpressionResolver indexNameExpressionResolver,
                 Supplier<DiscoveryNodes> nodesInCluster
             ) {
-                return singletonList(new RestMainAction() {
+                return singletonList(new RestNodesInfoAction(new SettingsFilter(emptyList())) {
 
                     @Override
                     public String getName() {
@@ -183,7 +183,7 @@ public class ActionModuleTests extends ESTestCase {
                 List.of()
             );
             Exception e = expectThrows(IllegalArgumentException.class, () -> actionModule.initRestHandlers(null));
-            assertThat(e.getMessage(), startsWith("Cannot replace existing handler for [/] for method: GET"));
+            assertThat(e.getMessage(), startsWith("Cannot replace existing handler for [/_nodes] for method: GET"));
         } finally {
             threadPool.shutdown();
         }

+ 1 - 0
x-pack/plugin/core/build.gradle

@@ -54,6 +54,7 @@ dependencies {
   testImplementation project(path: ':modules:parent-join')
   testImplementation project(path: ':modules:lang-mustache')
   testImplementation project(path: ':modules:analysis-common')
+  testImplementation project(path: ':modules:rest-root')
   testImplementation project(":client:rest-high-level")
   // Needed for Fips140ProviderVerificationTests
   testCompileOnly('org.bouncycastle:bc-fips:1.0.2')

+ 1 - 1
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java

@@ -52,7 +52,6 @@ import org.elasticsearch.action.ingest.DeletePipelineAction;
 import org.elasticsearch.action.ingest.GetPipelineAction;
 import org.elasticsearch.action.ingest.PutPipelineAction;
 import org.elasticsearch.action.ingest.SimulatePipelineAction;
-import org.elasticsearch.action.main.MainAction;
 import org.elasticsearch.action.search.MultiSearchAction;
 import org.elasticsearch.action.search.SearchAction;
 import org.elasticsearch.action.support.WriteRequest;
@@ -63,6 +62,7 @@ import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.Metadata;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.set.Sets;
+import org.elasticsearch.rest.root.MainAction;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.transport.TcpTransport;
 import org.elasticsearch.transport.TransportRequest;

+ 1 - 0
x-pack/plugin/security/build.gradle

@@ -26,6 +26,7 @@ dependencies {
   testImplementation project(path: ':modules:analysis-common')
   testImplementation project(path: ':modules:reindex')
   testImplementation project(':modules:data-streams')
+  testImplementation project(':modules:rest-root')
   testImplementation project(":client:rest-high-level")
 
   testImplementation(testArtifact(project(xpackModule('core'))))

+ 1 - 0
x-pack/plugin/security/qa/service-account/build.gradle

@@ -6,6 +6,7 @@ dependencies {
   javaRestTestImplementation project(':client:rest-high-level')
   javaRestTestImplementation project(':x-pack:plugin:security')
   clusterModules(project(":modules:analysis-common"))
+  clusterModules(project(":modules:rest-root"))
 }
 
 testArtifacts {

+ 1 - 0
x-pack/plugin/security/qa/service-account/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/service/ServiceAccountIT.java

@@ -214,6 +214,7 @@ public class ServiceAccountIT extends ESRestTestCase {
     public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
         .nodes(2)
         .module("analysis-common")
+        .module("rest-root")
         .setting("xpack.license.self_generated.type", "trial")
         .setting("xpack.security.enabled", "true")
         .setting("xpack.security.authc.token.enabled", "true")

+ 3 - 3
x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/apikey/ApiKeySingleNodeTests.java

@@ -11,6 +11,8 @@ import org.elasticsearch.ElasticsearchSecurityException;
 import org.elasticsearch.ElasticsearchStatusException;
 import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction;
 import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
+import org.elasticsearch.action.admin.cluster.node.info.NodesInfoAction;
+import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest;
 import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
 import org.elasticsearch.action.get.GetAction;
@@ -18,8 +20,6 @@ import org.elasticsearch.action.get.GetRequest;
 import org.elasticsearch.action.get.GetResponse;
 import org.elasticsearch.action.ingest.GetPipelineAction;
 import org.elasticsearch.action.ingest.GetPipelineRequest;
-import org.elasticsearch.action.main.MainAction;
-import org.elasticsearch.action.main.MainRequest;
 import org.elasticsearch.action.support.PlainActionFuture;
 import org.elasticsearch.client.RequestOptions;
 import org.elasticsearch.client.internal.Client;
@@ -174,7 +174,7 @@ public class ApiKeySingleNodeTests extends SecuritySingleNodeTestCase {
         final ElasticsearchSecurityException e1 = expectThrows(
             ElasticsearchSecurityException.class,
             () -> client().filterWithHeader(Map.of("Authorization", "ApiKey " + base64ApiKeyKeyValue))
-                .execute(MainAction.INSTANCE, new MainRequest())
+                .execute(NodesInfoAction.INSTANCE, new NodesInfoRequest())
                 .actionGet()
         );
         assertThat(e1.status().getStatus(), equalTo(403));

+ 3 - 1
x-pack/plugin/security/src/test/java/org/elasticsearch/test/SecuritySettingsSource.java

@@ -19,6 +19,7 @@ import org.elasticsearch.env.Environment;
 import org.elasticsearch.index.mapper.extras.MapperExtrasPlugin;
 import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.reindex.ReindexPlugin;
+import org.elasticsearch.rest.root.MainRestPlugin;
 import org.elasticsearch.test.ESIntegTestCase.Scope;
 import org.elasticsearch.transport.netty4.Netty4Plugin;
 import org.elasticsearch.xpack.core.XPackSettings;
@@ -186,7 +187,8 @@ public class SecuritySettingsSource extends NodeConfigurationSource {
             ReindexPlugin.class,
             CommonAnalysisPlugin.class,
             InternalSettingsPlugin.class,
-            MapperExtrasPlugin.class
+            MapperExtrasPlugin.class,
+            MainRestPlugin.class
         );
     }
 

+ 1 - 0
x-pack/plugin/sql/jdbc/build.gradle

@@ -14,6 +14,7 @@ dependencies {
   api project(':x-pack:plugin:sql:sql-client')
   testImplementation project(":test:framework")
   testImplementation(testArtifact(project(xpackModule('core'))))
+  testImplementation project(':modules:rest-root')
 }
 
 tasks.named("compileJava").configure {

+ 1 - 1
x-pack/plugin/sql/jdbc/src/test/java/org/elasticsearch/xpack/sql/jdbc/VersionParityTests.java

@@ -8,8 +8,8 @@
 package org.elasticsearch.xpack.sql.jdbc;
 
 import org.elasticsearch.Version;
-import org.elasticsearch.action.main.MainResponse;
 import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.rest.root.MainResponse;
 import org.elasticsearch.test.VersionUtils;
 import org.elasticsearch.test.http.MockResponse;
 import org.elasticsearch.xcontent.XContentType;

+ 1 - 1
x-pack/plugin/sql/jdbc/src/test/java/org/elasticsearch/xpack/sql/jdbc/WebServerTestCase.java

@@ -9,8 +9,8 @@ package org.elasticsearch.xpack.sql.jdbc;
 
 import org.elasticsearch.Build;
 import org.elasticsearch.Version;
-import org.elasticsearch.action.main.MainResponse;
 import org.elasticsearch.cluster.ClusterName;
+import org.elasticsearch.rest.root.MainResponse;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.test.http.MockWebServer;
 import org.junit.After;

+ 2 - 0
x-pack/plugin/sql/qa/server/build.gradle

@@ -102,6 +102,8 @@ subprojects {
     javaRestTestRuntimeOnly project(path: xpackModule('spatial'))
     javaRestTestRuntimeOnly project(path: ':modules:legacy-geo')
 
+    javaRestTestRuntimeOnly project(path: ':modules:rest-root')
+
     javaRestTestRuntimeOnly "org.slf4j:slf4j-api:1.7.25"
   }
   }

+ 2 - 0
x-pack/qa/full-cluster-restart/build.gradle

@@ -11,6 +11,8 @@ dependencies {
   javaRestTestImplementation(testArtifact(project(xpackModule('core'))))
   javaRestTestImplementation(testArtifact(project(":qa:full-cluster-restart"), "javaRestTest"))
   javaRestTestImplementation project(':x-pack:qa')
+  javaRestTestImplementation project(':modules:rest-root')
+
 }
 
 BuildParams.bwcVersions.withIndexCompatible { bwcVersion, baseName ->

+ 2 - 0
x-pack/qa/security-example-spi-extension/build.gradle

@@ -15,6 +15,8 @@ dependencies {
   javaRestTestImplementation project(':client:rest-high-level')
   // let the javaRestTest see the classpath of main
   javaRestTestImplementation project.sourceSets.main.runtimeClasspath
+  javaRestTestImplementation project(':modules:rest-root')
+
 }
 
 testClusters.configureEach {