This is an automated email from the ASF dual-hosted git repository. apkhmv pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push: new 616bacb67a IGNITE-21337 Remove unused ClusterNotInitializedException (#3083) 616bacb67a is described below commit 616bacb67ae312eab3814a861d8c55ab6536c00f Author: Vadim Pakhnushev <8614891+valep...@users.noreply.github.com> AuthorDate: Wed Jan 24 15:16:11 2024 +0300 IGNITE-21337 Remove unused ClusterNotInitializedException (#3083) --- .../exception/ClusterNotInitializedException.java | 24 ---- .../ClusterNotInitializedExceptionHandler.java | 45 -------- .../ignite/internal/rest/AbstractRestTestBase.java | 30 +++-- .../rest/ItInitializedClusterRestTest.java | 60 +++------- .../rest/ItNotInitializedClusterRestTest.java | 121 +++++++------------ .../cluster/ItClusterManagementControllerTest.java | 128 ++++++--------------- .../ignite/internal/rest/cluster/RestTestBase.java | 79 ------------- .../ignite/internal/rest/PathAvailability.java | 21 +++- .../apache/ignite/internal/rest/RestComponent.java | 1 - .../apache/ignite/internal/rest/RestManager.java | 14 ++- .../ClusterStateHttpServerFilter.java | 3 +- .../rest/cluster/ClusterManagementController.java | 9 +- .../internal/rest/cluster/TopologyController.java | 9 +- .../ClusterConfigurationController.java | 20 +--- .../ClusterConfigurationControllerTest.java | 2 + .../ConfigurationControllerBaseTest.java | 11 -- 16 files changed, 154 insertions(+), 423 deletions(-) diff --git a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/exception/ClusterNotInitializedException.java b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/exception/ClusterNotInitializedException.java deleted file mode 100644 index d9e349ec58..0000000000 --- a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/exception/ClusterNotInitializedException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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.apache.ignite.internal.rest.exception; - -/** - * Exception that is thrown when the cluster is not initialized. - */ -public class ClusterNotInitializedException extends RuntimeException { -} diff --git a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/exception/handler/ClusterNotInitializedExceptionHandler.java b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/exception/handler/ClusterNotInitializedExceptionHandler.java deleted file mode 100644 index 471594d5a6..0000000000 --- a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/exception/handler/ClusterNotInitializedExceptionHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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.apache.ignite.internal.rest.exception.handler; - -import io.micronaut.context.annotation.Requires; -import io.micronaut.http.HttpRequest; -import io.micronaut.http.HttpResponse; -import io.micronaut.http.server.exceptions.ExceptionHandler; -import jakarta.inject.Singleton; -import org.apache.ignite.internal.rest.api.Problem; -import org.apache.ignite.internal.rest.constants.HttpCode; -import org.apache.ignite.internal.rest.exception.ClusterNotInitializedException; -import org.apache.ignite.internal.rest.problem.HttpProblemResponse; - -/** - * Handles {@link ClusterNotInitializedException} and represents it as a rest response. - */ -@Singleton -@Requires(classes = {ClusterNotInitializedException.class, ExceptionHandler.class}) -public class ClusterNotInitializedExceptionHandler implements - ExceptionHandler<ClusterNotInitializedException, HttpResponse<? extends Problem>> { - @Override - public HttpResponse<? extends Problem> handle(HttpRequest request, ClusterNotInitializedException exception) { - return HttpProblemResponse.from( - Problem.fromHttpCode(HttpCode.CONFLICT) - .title("Cluster not initialized") - .detail("Cluster not initialized. Call /management/v1/cluster/init in order to initialize cluster") - ); - } -} diff --git a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/AbstractRestTestBase.java b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/AbstractRestTestBase.java index c8d51b1a43..ab8a4f3e4d 100644 --- a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/AbstractRestTestBase.java +++ b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/AbstractRestTestBase.java @@ -21,11 +21,15 @@ import static org.apache.ignite.internal.testframework.IgniteTestUtils.testNodeN import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully; import static org.hamcrest.MatcherAssert.assertThat; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; import java.nio.file.Path; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -37,6 +41,7 @@ import java.util.stream.Collectors; import org.apache.ignite.Ignite; import org.apache.ignite.IgnitionManager; import org.apache.ignite.internal.IgniteIntegrationTest; +import org.apache.ignite.internal.rest.api.Problem; import org.apache.ignite.internal.testframework.TestIgnitionManager; import org.apache.ignite.internal.testframework.WorkDirectory; import org.apache.ignite.internal.util.IgniteUtils; @@ -47,7 +52,7 @@ import org.junit.jupiter.api.TestInfo; /** * Base class for integration REST test. */ -abstract class AbstractRestTestBase extends IgniteIntegrationTest { +public abstract class AbstractRestTestBase extends IgniteIntegrationTest { /** Network ports of the test nodes. */ static final int[] NETWORK_PORTS = {3344, 3345, 3346}; @@ -64,32 +69,34 @@ abstract class AbstractRestTestBase extends IgniteIntegrationTest { final Map<String, String> nodesBootstrapCfg = new LinkedHashMap<>(); /** Node names that is starting (before init) or started (after init). */ - final List<String> nodeNames = new ArrayList<>(); + protected final List<String> nodeNames = new ArrayList<>(); /** Collection of started nodes. */ final List<Ignite> startedNodes = new ArrayList<>(); /** Collection of starting nodes. */ - final List<CompletableFuture<Ignite>> startingNodes = new ArrayList<CompletableFuture<Ignite>>(); + protected final List<CompletableFuture<Ignite>> startingNodes = new ArrayList<CompletableFuture<Ignite>>(); + + protected ObjectMapper objectMapper; /** HTTP client that is expected to be defined in subclasses. */ - HttpClient client; + private HttpClient client; /** Path to the working directory. */ @WorkDirectory private Path workDir; - static HttpRequest get(String path) { + protected static HttpRequest get(String path) { return HttpRequest.newBuilder(URI.create(HTTP_HOST_PORT + path)).build(); } - static HttpRequest patch(String path, String body) { + protected static HttpRequest patch(String path, String body) { return HttpRequest.newBuilder(URI.create(HTTP_HOST_PORT + path)) .method("PATCH", BodyPublishers.ofString(body)) .build(); } - static HttpRequest post(String path, String body) { + protected static HttpRequest post(String path, String body) { return HttpRequest.newBuilder(URI.create(HTTP_HOST_PORT + path)) .header("content-type", "application/json") .POST(BodyPublishers.ofString(body)) @@ -101,6 +108,7 @@ abstract class AbstractRestTestBase extends IgniteIntegrationTest { */ @BeforeEach void setUp(TestInfo testInfo) throws IOException, InterruptedException { + objectMapper = new ObjectMapper(); client = HttpClient.newBuilder().build(); startAllNodesWithoutInit(testInfo); @@ -184,4 +192,12 @@ abstract class AbstractRestTestBase extends IgniteIntegrationTest { void checkAllNodesStarted() { startingNodes.forEach(future -> assertThat(future, willCompleteSuccessfully())); } + + protected HttpResponse<String> send(HttpRequest request) throws IOException, InterruptedException { + return client.send(request, BodyHandlers.ofString()); + } + + protected Problem getProblem(HttpResponse<String> initResponse) throws JsonProcessingException { + return objectMapper.readValue(initResponse.body(), Problem.class); + } } diff --git a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItInitializedClusterRestTest.java b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItInitializedClusterRestTest.java index c0d1718e23..cce082d4c3 100644 --- a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItInitializedClusterRestTest.java +++ b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItInitializedClusterRestTest.java @@ -31,7 +31,6 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import java.io.IOException; import java.net.http.HttpResponse; -import java.net.http.HttpResponse.BodyHandlers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -62,7 +61,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { + " }\n" + "}"; - HttpResponse<String> response = client.send(post("/management/v1/cluster/init", requestBody), BodyHandlers.ofString()); + HttpResponse<String> response = send(post("/management/v1/cluster/init", requestBody)); assertThat(response.statusCode(), is(200)); checkAllNodesStarted(); @@ -72,10 +71,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Node configuration is available when the cluster is initialized") void nodeConfiguration() throws IOException, InterruptedException { // When GET /management/v1/configuration/node - HttpResponse<String> response = client.send( - get("/management/v1/configuration/node"), - BodyHandlers.ofString() - ); + HttpResponse<String> response = send(get("/management/v1/configuration/node")); // Expect node configuration can be parsed to hocon format Config config = ConfigFactory.parseString(response.body()); @@ -87,10 +83,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Node configuration by path is available when the cluster is initialized") void nodeConfigurationByPath() throws IOException, InterruptedException { // When GET /management/v1/configuration/node and path selector is "rest" - HttpResponse<String> response = client.send( - get("/management/v1/configuration/node/rest"), - BodyHandlers.ofString() - ); + HttpResponse<String> response = send(get("/management/v1/configuration/node/rest")); // Expect node configuration can be parsed to hocon format Config config = ConfigFactory.parseString(response.body()); @@ -102,18 +95,12 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Node configuration can be changed when the cluster is initialized") void nodeConfigurationUpdate() throws IOException, InterruptedException { // When PATCH /management/v1/configuration/node rest.port=10333 - HttpResponse<String> pathResponce = client.send( - patch("/management/v1/configuration/node", "rest.port=10333"), - BodyHandlers.ofString() - ); + HttpResponse<String> pathResponse = send(patch("/management/v1/configuration/node", "rest.port=10333")); // Then - assertThat(pathResponce.statusCode(), is(200)); + assertThat(pathResponse.statusCode(), is(200)); // And GET /management/v1/configuration/node - HttpResponse<String> getResponse = client.send( - get("/management/v1/configuration/node"), - BodyHandlers.ofString() - ); + HttpResponse<String> getResponse = send(get("/management/v1/configuration/node")); // Then node configuration can be parsed to hocon format Config config = ConfigFactory.parseString(getResponse.body()); @@ -125,7 +112,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Cluster configuration is available when the cluster is initialized") void clusterConfiguration() throws IOException, InterruptedException { // When GET /management/v1/configuration/cluster - HttpResponse<String> response = client.send(get("/management/v1/configuration/cluster"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/configuration/cluster")); // Then cluster configuration is not available assertThat(response.statusCode(), is(200)); @@ -139,15 +126,12 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Cluster configuration can be updated when the cluster is initialized") void clusterConfigurationUpdate() throws IOException, InterruptedException { // When PATCH /management/v1/configuration/cluster - HttpResponse<String> patchRequest = client.send( - patch("/management/v1/configuration/cluster", "gc.batchSize=1"), - BodyHandlers.ofString() - ); + HttpResponse<String> patchRequest = send(patch("/management/v1/configuration/cluster", "gc.batchSize=1")); // Then assertThat(patchRequest.statusCode(), is(200)); // And value was updated - HttpResponse<String> getResponse = client.send(get("/management/v1/configuration/cluster"), BodyHandlers.ofString()); + HttpResponse<String> getResponse = send(get("/management/v1/configuration/cluster")); assertThat(getResponse.statusCode(), is(200)); // And Config config = ConfigFactory.parseString(getResponse.body()); @@ -158,13 +142,10 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Cluster configuration can not be updated if provided config did not pass the validation") void clusterConfigurationUpdateValidation() throws IOException, InterruptedException { // When PATCH /management/v1/configuration/cluster invalid with invalid value - HttpResponse<String> patchRequest = client.send( - patch("/management/v1/configuration/cluster", "{\n" - + " security.enabled:true, \n" - + " security.authentication.providers:null\n" - + "}"), - BodyHandlers.ofString() - ); + HttpResponse<String> patchRequest = send(patch("/management/v1/configuration/cluster", "{\n" + + " security.enabled:true, \n" + + " security.authentication.providers:null\n" + + "}")); // Then assertThat( @@ -183,10 +164,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Cluster configuration by path is available when the cluster is initialized") void clusterConfigurationByPath() throws IOException, InterruptedException { // When GET /management/v1/configuration/cluster and path selector is "rocksDb.defaultRegion" - HttpResponse<String> response = client.send( - get("/management/v1/configuration/cluster/gc"), - BodyHandlers.ofString() - ); + HttpResponse<String> response = send(get("/management/v1/configuration/cluster/gc")); // Then cluster configuration is not available assertThat(response.statusCode(), is(200)); @@ -200,7 +178,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Logical topology is available on initialized cluster") void logicalTopology() throws IOException, InterruptedException { // When GET /management/v1/cluster/topology/logical - HttpResponse<String> response = client.send(get("/management/v1/cluster/topology/logical"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/cluster/topology/logical")); // Then assertThat(response.statusCode(), is(200)); @@ -217,7 +195,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Physical topology is available on initialized cluster") void physicalTopology() throws IOException, InterruptedException { // When GET /management/v1/cluster/topology/physical - HttpResponse<String> response = client.send(get("/management/v1/cluster/topology/physical"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/cluster/topology/physical")); // Then assertThat(response.statusCode(), is(200)); @@ -234,7 +212,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Cluster state is available on initialized cluster") void clusterState() throws IOException, InterruptedException { // When GET /management/v1/cluster/status - HttpResponse<String> response = client.send(get("/management/v1/cluster/state"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/cluster/state")); // Then assertThat(response.statusCode(), is(200)); @@ -251,7 +229,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Node state is available on initialized cluster") void nodeState() throws IOException, InterruptedException { // When GET /management/v1/node/status - HttpResponse<String> response = client.send(get("/management/v1/node/state"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/node/state")); // Then assertThat(response.statusCode(), is(200)); @@ -265,7 +243,7 @@ public class ItInitializedClusterRestTest extends AbstractRestTestBase { @DisplayName("Node version is available on initialized cluster") void nodeVersion() throws IOException, InterruptedException { // When GET /management/v1/node/version/ - HttpResponse<String> response = client.send(get("/management/v1/node/version/"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/node/version/")); // Then assertThat(response.statusCode(), is(200)); diff --git a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItNotInitializedClusterRestTest.java b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItNotInitializedClusterRestTest.java index 71e92549da..c4aa1ab6c9 100644 --- a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItNotInitializedClusterRestTest.java +++ b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/ItNotInitializedClusterRestTest.java @@ -27,18 +27,14 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.matchesRegex; import static org.junit.jupiter.api.Assertions.assertAll; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonProcessingException; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; -import java.io.IOException; import java.net.http.HttpResponse; -import java.net.http.HttpResponse.BodyHandlers; import org.apache.ignite.internal.rest.api.Problem; import org.apache.ignite.internal.testframework.WorkDirectoryExtension; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.extension.ExtendWith; /** @@ -50,23 +46,11 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { private static final String IGNITE_SEMVER_REGEX = "(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<maintenance>\\d+)((?<snapshot>-SNAPSHOT)|-(?<alpha>alpha\\d+)|--(?<beta>beta\\d+))?"; - private ObjectMapper objectMapper; - - @BeforeEach - @Override - void setUp(TestInfo testInfo) throws IOException, InterruptedException { - super.setUp(testInfo); - objectMapper = new ObjectMapper(); - } - @Test @DisplayName("Node configuration is available when the cluster in not initialized") - void nodeConfiguration() throws IOException, InterruptedException { + void nodeConfiguration() throws Exception { // When GET /management/v1/configuration/node. - HttpResponse<String> response = client.send( - get("/management/v1/configuration/node"), - BodyHandlers.ofString() - ); + HttpResponse<String> response = send(get("/management/v1/configuration/node")); // Expect node configuration can be parsed to hocon format. Config config = ConfigFactory.parseString(response.body()); @@ -76,20 +60,14 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { @Test @DisplayName("Node configuration can be changed when the cluster in not initialized") - void nodeConfigurationUpdate() throws IOException, InterruptedException { + void nodeConfigurationUpdate() throws Exception { // When PATCH /management/v1/configuration/node rest.port=10333. - HttpResponse<String> pathResponce = client.send( - patch("/management/v1/configuration/node", "rest.port=10333"), - BodyHandlers.ofString() - ); + HttpResponse<String> patchResponse = send(patch("/management/v1/configuration/node", "rest.port=10333")); // Then - assertThat(pathResponce.statusCode(), is(200)); + assertThat(patchResponse.statusCode(), is(200)); // And GET /management/v1/configuration/node. - HttpResponse<String> getResponse = client.send( - get("/management/v1/configuration/node"), - BodyHandlers.ofString() - ); + HttpResponse<String> getResponse = send(get("/management/v1/configuration/node")); // Then node configuration can be parsed to hocon format. Config config = ConfigFactory.parseString(getResponse.body()); @@ -99,60 +77,39 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { @Test @DisplayName("Cluster configuration is not available on not initialized cluster") - void clusterConfiguration() throws IOException, InterruptedException { + void clusterConfiguration() throws Exception { // When GET /management/v1/configuration/cluster. - HttpResponse<String> response = client.send(get("/management/v1/configuration/cluster"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/configuration/cluster")); // Expect cluster configuration is not available. - Problem problem = objectMapper.readValue(response.body(), Problem.class); - assertAll( - () -> assertThat(problem.status(), is(409)), - () -> assertThat(problem.title(), is("Conflict")), - () -> assertThat(problem.detail(), - is("Cluster is not initialized. Call /management/v1/cluster/init in order to initialize cluster.")) - ); + assertRespondsWithConflictNotInitializedCluster(response); } @Test @DisplayName("Cluster configuration could not be updated on not initialized cluster") - void clusterConfigurationUpdate() throws IOException, InterruptedException { + void clusterConfigurationUpdate() throws Exception { // When PATCH /management/v1/configuration/cluster. - HttpResponse<String> response = client.send( - patch("/management/v1/configuration/cluster", "any.key=any-value"), - BodyHandlers.ofString() - ); + HttpResponse<String> response = send(patch("/management/v1/configuration/cluster", "any.key=any-value")); // Expect cluster configuration could not be updated. - Problem problem = objectMapper.readValue(response.body(), Problem.class); - assertAll( - () -> assertThat(problem.status(), is(409)), - () -> assertThat(problem.title(), is("Conflict")), - () -> assertThat(problem.detail(), - is("Cluster is not initialized. Call /management/v1/cluster/init in order to initialize cluster.")) - ); + assertRespondsWithConflictNotInitializedCluster(response); } @Test @DisplayName("Logical topology is not available on not initialized cluster") - void logicalTopology() throws IOException, InterruptedException { + void logicalTopology() throws Exception { // When GET /management/v1/cluster/topology/logical. - HttpResponse<String> response = client.send(get("/management/v1/cluster/topology/logical"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/cluster/topology/logical")); // Then. - Problem problem = objectMapper.readValue(response.body(), Problem.class); - assertAll( - () -> assertThat(problem.status(), is(409)), - () -> assertThat(problem.title(), is("Conflict")), - () -> assertThat(problem.detail(), - is("Cluster is not initialized. Call /management/v1/cluster/init in order to initialize cluster.")) - ); + assertRespondsWithConflictNotInitializedCluster(response); } @Test @DisplayName("Physical topology is available on not initialized cluster") - void physicalTopology() throws IOException, InterruptedException { + void physicalTopology() throws Exception { // When GET /management/v1/cluster/topology/physical. - HttpResponse<String> response = client.send(get("/management/v1/cluster/topology/physical"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/cluster/topology/physical")); // Then assertThat(response.statusCode(), is(200)); @@ -169,9 +126,9 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { @Test @DisplayName("Node state is available on not initialized cluster and it is STARTING") - void nodeState() throws IOException, InterruptedException { + void nodeState() throws Exception { // When GET /management/v1/node/state. - HttpResponse<String> response = client.send(get("/management/v1/node/state"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/node/state")); // Then assertThat(response.statusCode(), is(200)); @@ -183,25 +140,19 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { @Test @DisplayName("Cluster state is not available on not initialized cluster") - void clusterState() throws IOException, InterruptedException { + void clusterState() throws Exception { // When GET /management/v1/cluster/state. - HttpResponse<String> response = client.send(get("/management/v1/cluster/state"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/cluster/state")); // Then - Problem problem = objectMapper.readValue(response.body(), Problem.class); - assertAll( - () -> assertThat(problem.status(), is(409)), - () -> assertThat(problem.title(), is("Conflict")), - () -> assertThat(problem.detail(), - is("Cluster is not initialized. Call /management/v1/cluster/init in order to initialize cluster.")) - ); + assertRespondsWithConflictNotInitializedCluster(response); } @Test @DisplayName("Node version is available on not initialized cluster") - void nodeVersion() throws IOException, InterruptedException { + void nodeVersion() throws Exception { // When GET /management/v1/node/version/. - HttpResponse<String> response = client.send(get("/management/v1/node/version/"), BodyHandlers.ofString()); + HttpResponse<String> response = send(get("/management/v1/node/version/")); // Then. assertThat(response.statusCode(), is(200)); @@ -211,7 +162,7 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { @Test @DisplayName("Cluster is not initialized, if config has a syntax error") - void initClusterWithInvalidHoconConfig() throws IOException, InterruptedException { + void initClusterWithInvalidHoconConfig() throws Exception { // When POST /management/v1/cluster/init with invalid config. String requestBody = "{\n" + " \"metaStorageNodes\": [\n" @@ -225,8 +176,8 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { + " }"; // Then. - HttpResponse<String> initResponse = client.send(post("/management/v1/cluster/init", requestBody), BodyHandlers.ofString()); - Problem initProblem = objectMapper.readValue(initResponse.body(), Problem.class); + HttpResponse<String> initResponse = send(post("/management/v1/cluster/init", requestBody)); + Problem initProblem = getProblem(initResponse); assertThat(initResponse.statusCode(), is(400)); assertAll( @@ -244,7 +195,7 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { @Test @DisplayName("Cluster is not initialized, if config has logic error") - void initClusterWithInvalidConfig() throws IOException, InterruptedException { + void initClusterWithInvalidConfig() throws Exception { // When POST /management/v1/cluster/init with invalid config. String requestBody = "{\n" + " \"metaStorageNodes\": [\n" @@ -258,8 +209,8 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { + " }"; // Then. - HttpResponse<String> initResponse = client.send(post("/management/v1/cluster/init", requestBody), BodyHandlers.ofString()); - Problem initProblem = objectMapper.readValue(initResponse.body(), Problem.class); + HttpResponse<String> initResponse = send(post("/management/v1/cluster/init", requestBody)); + Problem initProblem = getProblem(initResponse); assertThat(initResponse.statusCode(), is(400)); assertAll( @@ -274,4 +225,14 @@ public class ItNotInitializedClusterRestTest extends AbstractRestTestBase { // And cluster is not initialized. startingNodes.forEach(it -> assertThat(it, willTimeoutFast())); } + + private void assertRespondsWithConflictNotInitializedCluster(HttpResponse<String> response) throws JsonProcessingException { + Problem problem = getProblem(response); + assertAll( + () -> assertThat(problem.status(), is(409)), + () -> assertThat(problem.title(), is("Cluster is not initialized")), + () -> assertThat(problem.detail(), + is("Cluster is not initialized. Call /management/v1/cluster/init in order to initialize cluster.")) + ); + } } diff --git a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/ItClusterManagementControllerTest.java b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/ItClusterManagementControllerTest.java index 9f7312ae72..7852a315f1 100644 --- a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/ItClusterManagementControllerTest.java +++ b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/ItClusterManagementControllerTest.java @@ -19,32 +19,15 @@ package org.apache.ignite.internal.rest.cluster; import static org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import io.micronaut.context.annotation.Bean; -import io.micronaut.context.annotation.Factory; -import io.micronaut.context.annotation.Replaces; -import io.micronaut.http.HttpRequest; -import io.micronaut.http.HttpResponse; + import io.micronaut.http.HttpStatus; -import io.micronaut.http.client.HttpClient; -import io.micronaut.http.client.annotation.Client; -import io.micronaut.http.client.exceptions.HttpClientResponseException; -import jakarta.inject.Inject; +import java.net.http.HttpResponse; import java.util.List; import org.apache.ignite.internal.configuration.testframework.ConfigurationExtension; -import org.apache.ignite.internal.configuration.testframework.InjectConfiguration; -import org.apache.ignite.internal.rest.RestManager; -import org.apache.ignite.internal.rest.RestManagerFactory; -import org.apache.ignite.internal.rest.api.cluster.ClusterManagementApi; +import org.apache.ignite.internal.rest.AbstractRestTestBase; +import org.apache.ignite.internal.rest.api.Problem; import org.apache.ignite.internal.rest.api.cluster.ClusterState; -import org.apache.ignite.internal.rest.authentication.AuthenticationProviderFactory; -import org.apache.ignite.internal.security.authentication.AuthenticationManagerImpl; -import org.apache.ignite.internal.security.configuration.SecurityConfiguration; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @@ -54,121 +37,78 @@ import org.mockito.junit.jupiter.MockitoExtension; */ @ExtendWith(MockitoExtension.class) @ExtendWith(ConfigurationExtension.class) -public class ItClusterManagementControllerTest extends RestTestBase { - @Inject - @Client("/management/v1/cluster") - private HttpClient client; - - @InjectConfiguration - private SecurityConfiguration securityConfiguration; - +public class ItClusterManagementControllerTest extends AbstractRestTestBase { @Test - void testControllerLoaded() { - assertNotNull(server.getApplicationContext().getBean(ClusterManagementApi.class)); - } - - @Test - void testInitNoSuchNode() { + void testInitNoSuchNode() throws Exception { // Given body with nodename that does not exist String givenInvalidBody = "{\"metaStorageNodes\": [\"nodename\"], \"cmgNodes\": [], \"clusterName\": \"cluster\"}"; // When - var thrown = assertThrows( - HttpClientResponseException.class, - () -> client.toBlocking().exchange(HttpRequest.POST("init", givenInvalidBody)) - ); + HttpResponse<String> initResponse = send(post("/management/v1/cluster/init", givenInvalidBody)); + Problem initProblem = getProblem(initResponse); // Then - assertThat(thrown.getResponse().getStatus(), is(equalTo((HttpStatus.BAD_REQUEST)))); - // And - var problem = getProblem(thrown); - assertEquals(400, problem.status()); - assertEquals("Node \"nodename\" is not present in the physical topology", problem.detail()); + assertThat(initResponse.statusCode(), is(HttpStatus.BAD_REQUEST.getCode())); + assertThat(initProblem.status(), is(HttpStatus.BAD_REQUEST.getCode())); + assertThat(initProblem.title(), is("Bad Request")); + assertThat(initProblem.detail(), is("Node \"nodename\" is not present in the physical topology")); } @Test - void testInitAlreadyInitializedWithAnotherNodes() { + void testInitAlreadyInitializedWithAnotherNodes() throws Exception { // Given cluster is not initialized - HttpClientResponseException thrownBeforeInit = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().retrieve("state", ClusterState.class)); + HttpResponse<String> stateResponseBeforeInit = send(get("/management/v1/cluster/state")); + Problem beforeInitProblem = getProblem(stateResponseBeforeInit); - // Then status is 409: cluster not initialized - assertThat(thrownBeforeInit.getStatus(), is(equalTo(HttpStatus.CONFLICT))); + // Then status is 409: Cluster is not initialized + assertThat(stateResponseBeforeInit.statusCode(), is(HttpStatus.CONFLICT.getCode())); + assertThat(beforeInitProblem.title(), is("Cluster is not initialized")); assertThat( - getProblem(thrownBeforeInit).detail(), - is(equalTo("Cluster not initialized. Call /management/v1/cluster/init in order to initialize cluster")) + beforeInitProblem.detail(), + is("Cluster is not initialized. Call /management/v1/cluster/init in order to initialize cluster.") ); // Given cluster initialized String givenFirstRequestBody = "{\n" + " \"metaStorageNodes\": [\n" - + " \"" + cluster.get(0).clusterService().nodeName() + "\"\n" + + " \"" + nodeNames.get(0) + "\"\n" + " ],\n" + " \"cmgNodes\": [],\n" + " \"clusterName\": \"cluster\"\n" + "}"; // When - HttpResponse<Object> response = client.toBlocking().exchange(HttpRequest.POST("init", givenFirstRequestBody)); + HttpResponse<String> initResponse = send(post("/management/v1/cluster/init", givenFirstRequestBody)); // Then - assertThat(response.getStatus(), is(equalTo((HttpStatus.OK)))); + assertThat(initResponse.statusCode(), is(HttpStatus.OK.getCode())); // And - assertThat(cluster.get(0).startFuture(), willCompleteSuccessfully()); + assertThat(startingNodes.get(0), willCompleteSuccessfully()); // When get cluster state - ClusterState state = - client.toBlocking().retrieve("state", ClusterState.class); + HttpResponse<String> stateResponse = send(get("/management/v1/cluster/state")); + ClusterState state = objectMapper.readValue(stateResponse.body(), ClusterState.class); // Then cluster state is valid - assertThat(state.msNodes(), is(equalTo(List.of(cluster.get(0).clusterService().nodeName())))); - assertThat(state.cmgNodes(), is(equalTo(List.of(cluster.get(0).clusterService().nodeName())))); - assertThat(state.clusterTag().clusterName(), is(equalTo("cluster"))); + assertThat(state.msNodes(), is(List.of(nodeNames.get(0)))); + assertThat(state.cmgNodes(), is(List.of(nodeNames.get(0)))); + assertThat(state.clusterTag().clusterName(), is("cluster")); // Given second request with different node name String givenSecondRequestBody = "{\n" + " \"metaStorageNodes\": [\n" - + " \"" + cluster.get(1).clusterService().nodeName() + "\"\n" + + " \"" + nodeNames.get(1) + "\"\n" + " ],\n" + " \"cmgNodes\": [],\n" + " \"clusterName\": \"cluster\"\n" + "}"; // When - var thrown = assertThrows( - HttpClientResponseException.class, - () -> client.toBlocking().exchange(HttpRequest.POST("init", givenSecondRequestBody)) - ); + HttpResponse<String> secondInitResponse = send(post("/management/v1/cluster/init", givenSecondRequestBody)); + Problem secondInitProblem = getProblem(secondInitResponse); // Then - assertThat(thrown.getResponse().getStatus(), is(equalTo((HttpStatus.INTERNAL_SERVER_ERROR)))); - // And - var problem = getProblem(thrown); - assertEquals(500, problem.status()); - } - - @Factory - @Bean - @Replaces(ClusterManagementRestFactory.class) - public ClusterManagementRestFactory clusterManagementRestFactory() { - return new ClusterManagementRestFactory(clusterService, clusterInitializer, clusterManager); - } - - @Factory - @Bean - @Replaces(AuthenticationProviderFactory.class) - public AuthenticationProviderFactory authProviderFactory() { - return new AuthenticationProviderFactory(authenticationManager()); - } - - @Factory - @Bean - @Replaces(RestManagerFactory.class) - public RestManagerFactory restManagerProvider() { - return new RestManagerFactory(new RestManager()); - } - - private AuthenticationManagerImpl authenticationManager() { - return new AuthenticationManagerImpl(securityConfiguration); + assertThat(secondInitResponse.statusCode(), is(HttpStatus.INTERNAL_SERVER_ERROR.getCode())); + assertThat(secondInitProblem.status(), is(HttpStatus.INTERNAL_SERVER_ERROR.getCode())); } } diff --git a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/RestTestBase.java b/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/RestTestBase.java deleted file mode 100644 index ced23b5154..0000000000 --- a/modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/RestTestBase.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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.apache.ignite.internal.rest.cluster; - -import io.micronaut.http.client.exceptions.HttpClientResponseException; -import io.micronaut.runtime.server.EmbeddedServer; -import io.micronaut.test.extensions.junit5.annotation.MicronautTest; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import org.apache.ignite.internal.cluster.management.BaseItClusterManagementTest; -import org.apache.ignite.internal.cluster.management.ClusterInitializer; -import org.apache.ignite.internal.cluster.management.ClusterManagementGroupManager; -import org.apache.ignite.internal.cluster.management.MockNode; -import org.apache.ignite.internal.rest.api.Problem; -import org.apache.ignite.internal.testframework.WorkDirectory; -import org.apache.ignite.internal.testframework.WorkDirectoryExtension; -import org.apache.ignite.network.ClusterService; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.api.extension.ExtendWith; - -/** - * Cluster management REST test. - */ -@MicronautTest -@ExtendWith(WorkDirectoryExtension.class) -public abstract class RestTestBase extends BaseItClusterManagementTest { - static final List<MockNode> cluster = new ArrayList<>(); - - static ClusterService clusterService; - - static ClusterInitializer clusterInitializer; - - static ClusterManagementGroupManager clusterManager; - - @WorkDirectory - static Path workDir; - - @Inject - EmbeddedServer server; - - @BeforeAll - static void setUp(TestInfo testInfo) { - cluster.addAll(createNodes(2, testInfo, workDir)); - - cluster.parallelStream().forEach(MockNode::start); - - clusterService = cluster.get(0).clusterService(); - clusterInitializer = cluster.get(0).clusterInitializer(); - clusterManager = cluster.get(0).clusterManager(); - } - - @AfterAll - static void tearDown() throws Exception { - stopNodes(cluster); - } - - static Problem getProblem(HttpClientResponseException exception) { - return exception.getResponse().getBody(Problem.class).orElseThrow(); - } -} diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/PathAvailability.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/PathAvailability.java index 7f33097b20..37f8161085 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/PathAvailability.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/PathAvailability.java @@ -25,11 +25,15 @@ import org.jetbrains.annotations.Nullable; public class PathAvailability { private final boolean isAvailable; + @Nullable + private final String unavailableTitle; + @Nullable private final String unavailableReason; - private PathAvailability(boolean isAvailable, @Nullable String unavailableReason) { + private PathAvailability(boolean isAvailable, @Nullable String unavailableTitle, @Nullable String unavailableReason) { this.isAvailable = isAvailable; + this.unavailableTitle = unavailableTitle; this.unavailableReason = unavailableReason; } @@ -37,17 +41,22 @@ public class PathAvailability { return isAvailable; } + @Nullable + public String unavailableTitle() { + return unavailableTitle; + } + @Nullable public String unavailableReason() { return unavailableReason; } public static PathAvailability available() { - return new PathAvailability(true, null); + return new PathAvailability(true, null, null); } - public static PathAvailability unavailable(String reason) { - return new PathAvailability(false, reason); + public static PathAvailability unavailable(String title, String reason) { + return new PathAvailability(false, title, reason); } @Override @@ -64,12 +73,16 @@ public class PathAvailability { if (isAvailable != that.isAvailable) { return false; } + if (unavailableTitle != null ? !unavailableTitle.equals(that.unavailableTitle) : that.unavailableTitle != null) { + return false; + } return unavailableReason != null ? unavailableReason.equals(that.unavailableReason) : that.unavailableReason == null; } @Override public int hashCode() { int result = (isAvailable ? 1 : 0); + result = 31 * result + (unavailableTitle != null ? unavailableTitle.hashCode() : 0); result = 31 * result + (unavailableReason != null ? unavailableReason.hashCode() : 0); return result; } diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java index 48a18f38f1..8a3144eeb4 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestComponent.java @@ -222,7 +222,6 @@ public class RestComponent implements IgniteComponent { result.put("micronaut.server.cors.configurations.web.allowed-headers", "Authorization"); result.put("micronaut.security.intercept-url-map[0].pattern", "/**"); result.put("micronaut.security.intercept-url-map[0].access", "isAuthenticated()"); - result.put("ignite.endpoints.filter-non-initialized", "true"); if (sslEnabled) { KeyStoreView keyStore = restSslView.keyStore(); diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestManager.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestManager.java index 2a1df5b804..7945d4a81b 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestManager.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/RestManager.java @@ -29,9 +29,13 @@ import org.apache.ignite.internal.logger.Loggers; public class RestManager { private static final IgniteLogger LOG = Loggers.forClass(RestManager.class); - private static final String DURING_INITIALIZATION = "REST temporary unavailable"; + private static final String DURING_INITIALIZATION_TITLE = "REST temporarily unavailable"; - private static final String CLUSTER_NOT_INITIALIZED = "Cluster is not initialized. " + private static final String DURING_INITIALIZATION_REASON = "REST services are unavailable during cluster initialization"; + + private static final String CLUSTER_NOT_INITIALIZED_TITLE = "Cluster is not initialized"; + + private static final String CLUSTER_NOT_INITIALIZED_REASON = "Cluster is not initialized. " + "Call /management/v1/cluster/init in order to initialize cluster."; private static final String[] DEFAULT_ENDPOINTS = { @@ -64,9 +68,11 @@ public class RestManager { case INITIALIZED: return available(); case INITIALIZATION: - return unavailable(DURING_INITIALIZATION); + return unavailable(DURING_INITIALIZATION_TITLE, DURING_INITIALIZATION_REASON); case NOT_INITIALIZED: - return pathDisabledForNotInitializedCluster(requestPath) ? unavailable(CLUSTER_NOT_INITIALIZED) : available(); + return pathDisabledForNotInitializedCluster(requestPath) + ? unavailable(CLUSTER_NOT_INITIALIZED_TITLE, CLUSTER_NOT_INITIALIZED_REASON) + : available(); default: throw new IllegalStateException("Unrecognized state " + state); } diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/ClusterStateHttpServerFilter.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/ClusterStateHttpServerFilter.java index 3ebc48f98e..1c7c313228 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/ClusterStateHttpServerFilter.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/authentication/ClusterStateHttpServerFilter.java @@ -34,7 +34,7 @@ import reactor.core.publisher.Mono; * Filters out endpoints that are not allowed to be accessed. * */ @Filter(Filter.MATCH_ALL_PATTERN) -@Requires(property = "ignite.endpoints.filter-non-initialized", value = "true", defaultValue = "false") +@Requires(property = "ignite.endpoints.filter-non-initialized", value = "true", defaultValue = "true") public class ClusterStateHttpServerFilter implements HttpServerFilter { private final RestManager restManager; @@ -48,6 +48,7 @@ public class ClusterStateHttpServerFilter implements HttpServerFilter { if (!availability.isAvailable()) { return Mono.just(HttpProblemResponse.from( Problem.fromHttpCode(HttpCode.CONFLICT) + .title(availability.unavailableTitle()) .detail(availability.unavailableReason()) .build())); } diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/ClusterManagementController.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/ClusterManagementController.java index 800650b055..bb8e204e5a 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/ClusterManagementController.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/ClusterManagementController.java @@ -31,7 +31,6 @@ import org.apache.ignite.internal.rest.api.cluster.ClusterState; import org.apache.ignite.internal.rest.api.cluster.ClusterTag; import org.apache.ignite.internal.rest.api.cluster.InitCommand; import org.apache.ignite.internal.rest.cluster.exception.InvalidArgumentClusterInitializationException; -import org.apache.ignite.internal.rest.exception.ClusterNotInitializedException; import org.apache.ignite.internal.util.ExceptionUtils; import org.apache.ignite.lang.IgniteException; @@ -63,7 +62,7 @@ public class ClusterManagementController implements ClusterManagementApi { /** {@inheritDoc} */ @Override public CompletableFuture<ClusterState> clusterState() { - return clusterManagementGroupManager.clusterState().thenApply(this::mapClusterState); + return clusterManagementGroupManager.clusterState().thenApply(ClusterManagementController::mapClusterState); } /** {@inheritDoc} */ @@ -84,11 +83,7 @@ public class ClusterManagementController implements ClusterManagementApi { }); } - private ClusterState mapClusterState(org.apache.ignite.internal.cluster.management.ClusterState clusterState) { - if (clusterState == null) { - throw new ClusterNotInitializedException(); - } - + private static ClusterState mapClusterState(org.apache.ignite.internal.cluster.management.ClusterState clusterState) { return new ClusterState( clusterState.cmgNodes(), clusterState.metaStorageNodes(), diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/TopologyController.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/TopologyController.java index b776550afb..0722949db8 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/TopologyController.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/TopologyController.java @@ -30,7 +30,6 @@ import org.apache.ignite.internal.rest.api.cluster.ClusterNode; import org.apache.ignite.internal.rest.api.cluster.NetworkAddress; import org.apache.ignite.internal.rest.api.cluster.NodeMetadata; import org.apache.ignite.internal.rest.api.cluster.TopologyApi; -import org.apache.ignite.internal.rest.exception.ClusterNotInitializedException; import org.apache.ignite.network.TopologyService; /** @@ -59,13 +58,7 @@ public class TopologyController implements TopologyApi { // TODO: IGNITE-18277 - return an object containing both nodes and topology version. return cmgManager.clusterState() - .thenCompose(state -> { - if (state == null) { - throw new ClusterNotInitializedException(); - } - - return cmgManager.logicalTopology(); - }) + .thenCompose(state -> cmgManager.logicalTopology()) .thenApply(LogicalTopologySnapshot::nodes) .thenApply(TopologyController::toClusterNodeDtosFromLogicalNodes); } diff --git a/modules/rest/src/main/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationController.java b/modules/rest/src/main/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationController.java index 6152dfe3c5..0aa1bd6dad 100644 --- a/modules/rest/src/main/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationController.java +++ b/modules/rest/src/main/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationController.java @@ -21,10 +21,8 @@ import io.micronaut.context.annotation.Requires; import io.micronaut.http.annotation.Controller; import jakarta.inject.Named; import java.util.concurrent.CompletableFuture; -import org.apache.ignite.internal.configuration.ComponentNotStartedException; import org.apache.ignite.internal.configuration.presentation.ConfigurationPresentation; import org.apache.ignite.internal.rest.api.configuration.ClusterConfigurationApi; -import org.apache.ignite.internal.rest.exception.ClusterNotInitializedException; import org.apache.ignite.internal.rest.exception.handler.IgniteExceptionHandler; /** @@ -44,11 +42,7 @@ public class ClusterConfigurationController extends AbstractConfigurationControl */ @Override public String getConfiguration() { - try { - return super.getConfiguration(); - } catch (ComponentNotStartedException e) { - throw new ClusterNotInitializedException(); - } + return super.getConfiguration(); } /** @@ -59,11 +53,7 @@ public class ClusterConfigurationController extends AbstractConfigurationControl */ @Override public String getConfigurationByPath(String path) { - try { - return super.getConfigurationByPath(path); - } catch (ComponentNotStartedException e) { - throw new ClusterNotInitializedException(); - } + return super.getConfigurationByPath(path); } /** @@ -73,10 +63,6 @@ public class ClusterConfigurationController extends AbstractConfigurationControl */ @Override public CompletableFuture<Void> updateConfiguration(String updatedConfiguration) { - try { - return super.updateConfiguration(updatedConfiguration); - } catch (ComponentNotStartedException e) { - throw new ClusterNotInitializedException(); - } + return super.updateConfiguration(updatedConfiguration); } } diff --git a/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationControllerTest.java b/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationControllerTest.java index 1cf72710b3..47d236f7cf 100644 --- a/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationControllerTest.java +++ b/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ClusterConfigurationControllerTest.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.rest.configuration; import io.micronaut.context.annotation.Bean; import io.micronaut.context.annotation.Factory; +import io.micronaut.context.annotation.Property; import io.micronaut.context.annotation.Replaces; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; @@ -42,6 +43,7 @@ import org.junit.jupiter.api.extension.ExtendWith; */ @MicronautTest @ExtendWith(ConfigurationExtension.class) +@Property(name = "ignite.endpoints.filter-non-initialized", value = "false") class ClusterConfigurationControllerTest extends ConfigurationControllerBaseTest { @InjectConfiguration SecurityConfiguration securityConfiguration; diff --git a/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ConfigurationControllerBaseTest.java b/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ConfigurationControllerBaseTest.java index ce98aec9ae..2836101fd6 100644 --- a/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ConfigurationControllerBaseTest.java +++ b/modules/rest/src/test/java/org/apache/ignite/internal/rest/configuration/ConfigurationControllerBaseTest.java @@ -26,16 +26,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import io.micronaut.context.ApplicationContext; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpStatus; import io.micronaut.http.MediaType; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import io.micronaut.runtime.server.EmbeddedServer; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import jakarta.inject.Inject; -import java.util.Set; import org.apache.ignite.internal.configuration.ConfigurationRegistry; import org.apache.ignite.internal.configuration.presentation.ConfigurationPresentation; import org.apache.ignite.internal.rest.api.InvalidParam; @@ -49,20 +46,12 @@ import org.junit.jupiter.api.Test; @MicronautTest public abstract class ConfigurationControllerBaseTest { - private final Set<String> secretKeys = Set.of("password"); - - @Inject - private EmbeddedServer server; - @Inject private ConfigurationPresentation<String> cfgPresentation; @Inject private ConfigurationRegistry configurationRegistry; - @Inject - private ApplicationContext context; - abstract HttpClient client(); @BeforeEach