This is an automated email from the ASF dual-hosted git repository.
apolovtsev 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 e2628892e43 IGNITE-27990 Make cluster name editable (#7669)
e2628892e43 is described below
commit e2628892e4319760e8e50d49326aa479a00dd2d9
Author: Aditya Mukhopadhyay <[email protected]>
AuthorDate: Fri Feb 27 16:23:50 2026 +0530
IGNITE-27990 Make cluster name editable (#7669)
---
.../management/raft/ItCmgRaftServiceTest.java | 28 +++++++++++++++
.../management/ClusterManagementGroupManager.java | 17 +++++++++
.../network/messages/CmgMessageGroup.java | 6 ++++
.../management/raft/CmgRaftGroupListener.java | 28 +++++++++++++++
.../cluster/management/raft/CmgRaftService.java | 13 +++++++
.../raft/commands/ChangeClusterNameCommand.java | 30 ++++++++++++++++
.../management/raft/CmgRaftGroupListenerTest.java | 41 ++++++++++++++++++++--
.../commands/CmgCommandsCompatibilityTest.java | 15 ++++++++
.../rest/api/cluster/ClusterManagementApi.java | 16 +++++++++
.../ignite/internal/rest/AbstractRestTestBase.java | 2 +-
.../cluster/ItClusterManagementControllerTest.java | 35 ++++++++++++++++++
.../rest/cluster/ClusterManagementController.java | 25 +++++++++++++
12 files changed, 253 insertions(+), 3 deletions(-)
diff --git
a/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
b/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
index b344f1386f9..e4c0d086467 100644
---
a/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
+++
b/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/raft/ItCmgRaftServiceTest.java
@@ -361,6 +361,34 @@ public class ItCmgRaftServiceTest extends
BaseIgniteAbstractTest {
assertThat(cluster.get(1).raftService.nodeNames(),
containsInAnyOrder(topology));
}
+ /**
+ * Tests saving and reading a cluster name.
+ */
+ @Test
+ void testClusterName() {
+ Node node1 = cluster.get(0);
+ Node node2 = cluster.get(1);
+
+ assertThat(node1.raftService.readClusterState(),
willCompleteSuccessfully());
+ assertThat(node2.raftService.readClusterState(),
willCompleteSuccessfully());
+
+ ClusterTag clusterTag = ClusterTag.randomClusterTag(msgFactory,
"cluster");
+ ClusterState state = msgFactory.clusterState()
+ .cmgNodes(Set.copyOf(List.of("foo")))
+ .metaStorageNodes(Set.copyOf(List.of("bar")))
+ .version(IgniteProductVersion.CURRENT_VERSION.toString())
+ .clusterTag(clusterTag)
+ .build();
+
+ assertThat(node1.raftService.initClusterState(state),
willCompleteSuccessfully());
+
+ assertThat(node1.raftService.changeClusterName("cluster2"),
willCompleteSuccessfully());
+
+ ClusterTag clusterTag2 = ClusterTag.clusterTag(msgFactory, "cluster2",
clusterTag.clusterId());
+
assertThat(node1.raftService.readClusterState().thenApply(ClusterState::clusterTag),
willBe(clusterTag2));
+
assertThat(node2.raftService.readClusterState().thenApply(ClusterState::clusterTag),
willBe(clusterTag2));
+ }
+
/**
* Tests saving and reading a {@link ClusterState}.
*/
diff --git
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
index 71dafbe4098..8943cc9fc3f 100644
---
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
+++
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java
@@ -29,6 +29,7 @@ import static
org.apache.ignite.internal.util.ExceptionUtils.hasCause;
import static org.apache.ignite.internal.util.ExceptionUtils.unwrapCause;
import static org.apache.ignite.internal.util.IgniteUtils.failOrConsume;
import static org.apache.ignite.lang.ErrorGroups.Common.NODE_STOPPING_ERR;
+import static org.apache.ignite.lang.ErrorGroups.Rest.CLUSTER_NOT_INIT_ERR;
import java.util.Collection;
import java.util.List;
@@ -103,6 +104,7 @@ import org.apache.ignite.internal.util.ExceptionUtils;
import org.apache.ignite.internal.util.IgniteSpinBusyLock;
import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.internal.vault.VaultManager;
+import org.apache.ignite.lang.IgniteException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -559,6 +561,21 @@ public class ClusterManagementGroupManager extends
AbstractEventProducer<Cluster
return serviceFuture == null ? nullCompletedFuture() :
serviceFuture.thenCompose(CmgRaftService::readClusterState);
}
+ /**
+ * Renames the cluster with the provided name.
+ *
+ * @param newName the new name for the cluster.
+ * @return Completable future that will be completed when cluster is
initialized.
+ */
+ public CompletableFuture<Void> renameCluster(String newName) {
+ CompletableFuture<CmgRaftService> serviceFuture = raftService;
+
+ return serviceFuture == null
+ ? failedFuture(new IgniteException(CLUSTER_NOT_INIT_ERR,
+ "Cluster has not yet been initialized or the node is in the
process of being stopped."))
+ : serviceFuture.thenCompose(cmgRaftService ->
cmgRaftService.changeClusterName(newName));
+ }
+
/**
* Extracts the local state (if any) and starts the CMG.
*
diff --git
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java
index 286f497417d..3d3caa19278 100644
---
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java
+++
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java
@@ -20,6 +20,7 @@ package
org.apache.ignite.internal.cluster.management.network.messages;
import org.apache.ignite.internal.cluster.management.ClusterState;
import org.apache.ignite.internal.cluster.management.ClusterTag;
import org.apache.ignite.internal.cluster.management.MetaStorageInfo;
+import
org.apache.ignite.internal.cluster.management.raft.commands.ChangeClusterNameCommand;
import
org.apache.ignite.internal.cluster.management.raft.commands.ChangeMetaStorageInfoCommand;
import
org.apache.ignite.internal.cluster.management.raft.commands.ClusterNodeMessage;
import
org.apache.ignite.internal.cluster.management.raft.commands.InitCmgStateCommand;
@@ -146,6 +147,11 @@ public class CmgMessageGroup {
*/
int CLUSTER_TAG = 62;
+ /**
+ * Message type for {@link ChangeClusterNameCommand}.
+ */
+ int CHANGE_CLUSTER_NAME = 63;
+
/**
* Do not delete this code for compatibility.
*/
diff --git
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListener.java
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListener.java
index b9b96d93082..93b0453faa4 100644
---
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListener.java
+++
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListener.java
@@ -35,8 +35,10 @@ import java.util.function.LongConsumer;
import java.util.stream.Collectors;
import org.apache.ignite.internal.cluster.management.ClusterIdStore;
import org.apache.ignite.internal.cluster.management.ClusterState;
+import org.apache.ignite.internal.cluster.management.ClusterTag;
import org.apache.ignite.internal.cluster.management.MetaStorageInfo;
import
org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesFactory;
+import
org.apache.ignite.internal.cluster.management.raft.commands.ChangeClusterNameCommand;
import
org.apache.ignite.internal.cluster.management.raft.commands.ChangeMetaStorageInfoCommand;
import
org.apache.ignite.internal.cluster.management.raft.commands.ClusterNodeMessage;
import
org.apache.ignite.internal.cluster.management.raft.commands.InitCmgStateCommand;
@@ -216,6 +218,10 @@ public class CmgRaftGroupListener implements
RaftGroupListener {
} else if (command instanceof ChangeMetaStorageInfoCommand) {
changeMetastorageNodes((ChangeMetaStorageInfoCommand)
command);
+ clo.result(null);
+ } else if (command instanceof ChangeClusterNameCommand) {
+ changeClusterName((ChangeClusterNameCommand) command);
+
clo.result(null);
}
} catch (Throwable e) {
@@ -323,6 +329,28 @@ public class CmgRaftGroupListener implements
RaftGroupListener {
}
}
+ private void changeClusterName(ChangeClusterNameCommand command) {
+ ClusterState existingState = storageManager.getClusterState();
+
+ assert existingState != null : "Cluster state was not initialized when
got " + command;
+
+ ClusterTag newTag = cmgMessagesFactory.clusterTag()
+ .clusterName(command.clusterName())
+ .clusterId(existingState.clusterTag().clusterId())
+ .build();
+
+ ClusterState newState = cmgMessagesFactory.clusterState()
+ .cmgNodes(Set.copyOf(existingState.cmgNodes()))
+ .metaStorageNodes(Set.copyOf(existingState.metaStorageNodes()))
+ .version(existingState.version())
+ .clusterTag(newTag)
+
.initialClusterConfiguration(existingState.initialClusterConfiguration())
+ .formerClusterIds(existingState.formerClusterIds())
+ .build();
+
+ storageManager.putClusterState(newState);
+ }
+
private void changeMetastorageNodes(ChangeMetaStorageInfoCommand command) {
ClusterState existingState = storageManager.getClusterState();
diff --git
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftService.java
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftService.java
index a9e37b70a75..acd0c1e042d 100644
---
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftService.java
+++
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftService.java
@@ -33,6 +33,7 @@ import
org.apache.ignite.internal.cluster.management.InvalidNodeConfigurationExc
import org.apache.ignite.internal.cluster.management.MetaStorageInfo;
import org.apache.ignite.internal.cluster.management.NodeAttributes;
import
org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesFactory;
+import
org.apache.ignite.internal.cluster.management.raft.commands.ChangeClusterNameCommand;
import
org.apache.ignite.internal.cluster.management.raft.commands.ChangeMetaStorageInfoCommand;
import
org.apache.ignite.internal.cluster.management.raft.commands.ClusterNodeMessage;
import
org.apache.ignite.internal.cluster.management.raft.commands.JoinReadyCommand;
@@ -346,6 +347,18 @@ public class CmgRaftService implements ManuallyCloseable {
}
}
+ /**
+ * Changes cluster name.
+ *
+ * @return Future that completes when the change is finished.
+ */
+ public CompletableFuture<Void> changeClusterName(String clusterName) {
+ ChangeClusterNameCommand command =
msgFactory.changeClusterNameCommand()
+ .clusterName(clusterName)
+ .build();
+ return raftService.run(command);
+ }
+
/**
* Changes Metastorage nodes.
*
diff --git
a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/commands/ChangeClusterNameCommand.java
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/commands/ChangeClusterNameCommand.java
new file mode 100644
index 00000000000..f87b60170c7
--- /dev/null
+++
b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/raft/commands/ChangeClusterNameCommand.java
@@ -0,0 +1,30 @@
+/*
+ * 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.cluster.management.raft.commands;
+
+import
org.apache.ignite.internal.cluster.management.network.messages.CmgMessageGroup;
+import org.apache.ignite.internal.network.annotations.Transferable;
+import org.apache.ignite.internal.raft.WriteCommand;
+
+/**
+ * Message for updating the cluster name.
+ */
+@Transferable(CmgMessageGroup.Commands.CHANGE_CLUSTER_NAME)
+public interface ChangeClusterNameCommand extends WriteCommand {
+ String clusterName();
+}
diff --git
a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListenerTest.java
b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListenerTest.java
index f075367efc1..eac2a79649e 100644
---
a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListenerTest.java
+++
b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/CmgRaftGroupListenerTest.java
@@ -25,6 +25,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -178,9 +179,35 @@ public class CmgRaftGroupListenerTest extends
BaseIgniteAbstractTest {
verify(logicalTopology).fireTopologyLeap();
}
+ @Test
+ void changeClusterNameChangesClusterName() {
+ initCmg();
+ changeClusterName();
+
+ ClusterState updatedState =
listener.storageManager().getClusterState();
+ assertNotNull(updatedState);
+
+ ClusterTag expectedTag = msgFactory.clusterTag()
+ .clusterName("cluster2")
+ .clusterId(state.clusterTag().clusterId())
+ .build();
+
+ ClusterState expectedState = msgFactory.clusterState()
+ .cmgNodes(Set.copyOf(state.cmgNodes()))
+ .metaStorageNodes(Set.copyOf(state.metaStorageNodes()))
+ .version(state.version())
+ .clusterTag(expectedTag)
+
.initialClusterConfiguration(state.initialClusterConfiguration())
+ .formerClusterIds(state.formerClusterIds())
+ .build();
+
+ assertThat(updatedState, is(expectedState));
+ }
+
@Test
void changeMetastorageInfoChangesMsInfo() {
- initCmgAndChangeMgInfo();
+ initCmg();
+ changeMgInfo();
ClusterState updatedState =
listener.storageManager().getClusterState();
assertThat(updatedState, is(notNullValue()));
@@ -195,14 +222,24 @@ public class CmgRaftGroupListenerTest extends
BaseIgniteAbstractTest {
assertThat(listener.storageManager().getMetastorageRepairingConfigIndex(),
is(123L));
}
- private void initCmgAndChangeMgInfo() {
+ private void initCmg() {
listener.onWrite(iterator(
msgFactory.initCmgStateCommand()
.clusterState(state)
.node(node)
.build()
));
+ }
+
+ private void changeClusterName() {
+ listener.onWrite(iterator(
+ msgFactory.changeClusterNameCommand()
+ .clusterName("cluster2")
+ .build()
+ ));
+ }
+ private void changeMgInfo() {
listener.onWrite(iterator(
msgFactory.changeMetaStorageInfoCommand()
.metaStorageNodes(Set.of("new-ms-1", "new-ms-2"))
diff --git
a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
index e6eca66bce7..7c0bef8f683 100644
---
a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
+++
b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
@@ -49,6 +49,7 @@ public class CmgCommandsCompatibilityTest extends
BaseCommandsCompatibilityTest
protected Collection<Command> commandsToSerialize() {
return List.of(
createChangeMetaStorageInfoCommand(),
+ createChangeClusterNameCommand(),
createInitCmgStateCommand(),
createJoinReadyCommand(),
createJoinRequestCommand(),
@@ -60,6 +61,14 @@ public class CmgCommandsCompatibilityTest extends
BaseCommandsCompatibilityTest
);
}
+ @Test
+ @TestForCommand(ChangeClusterNameCommand.class)
+ void testChangeClusterNameCommand() {
+ ChangeClusterNameCommand command =
decodeCommand("CEANY2x1c3Rlck5hbWUy");
+
+ assertEquals("clusterName2", command.clusterName());
+ }
+
@Test
@TestForCommand(ChangeMetaStorageInfoCommand.class)
void testChangeMetaStorageInfoCommand() {
@@ -213,6 +222,12 @@ public class CmgCommandsCompatibilityTest extends
BaseCommandsCompatibilityTest
.build();
}
+ private ChangeClusterNameCommand createChangeClusterNameCommand() {
+ return factory.changeClusterNameCommand()
+ .clusterName("clusterName2")
+ .build();
+ }
+
private ChangeMetaStorageInfoCommand createChangeMetaStorageInfoCommand() {
return factory.changeMetaStorageInfoCommand()
.metaStorageNodes(Set.of("msNode1", "msNode2"))
diff --git
a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/api/cluster/ClusterManagementApi.java
b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/api/cluster/ClusterManagementApi.java
index 8ab84e363bc..25c547e32dc 100644
---
a/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/api/cluster/ClusterManagementApi.java
+++
b/modules/rest-api/src/main/java/org/apache/ignite/internal/rest/api/cluster/ClusterManagementApi.java
@@ -66,4 +66,20 @@ public interface ClusterManagementApi {
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.PROBLEM_JSON)
CompletableFuture<Void> init(@Body InitCommand initCommand);
+
+ /**
+ * Renames the cluster.
+ *
+ * @param newName the new name of the cluster.
+ * @return Completable future that will be completed when the cluster is
renamed.
+ */
+ @Post("rename")
+ @Operation(operationId = "rename", summary = "Rename cluster", description
= "Assigns a new name to the cluster.")
+ @ApiResponse(responseCode = "200", description = "Cluster renamed.",
+ content = @Content(mediaType = MediaType.APPLICATION_JSON, schema
= @Schema(implementation = ClusterTag.class)))
+ @ApiResponse(responseCode = "500", description = "Internal error.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Produces({MediaType.APPLICATION_JSON, MediaType.PROBLEM_JSON})
+ CompletableFuture<ClusterTag> rename(@Body String newName);
}
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 50859c83e7e..8577a27d9e6 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
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.TestInfo;
*/
public abstract class AbstractRestTestBase extends
ClusterPerTestIntegrationTest {
/** HTTP host and port url part. */
- private static final String HTTP_HOST_PORT = "http://localhost:10300";
+ protected static final String HTTP_HOST_PORT = "http://localhost:10300";
protected ObjectMapper objectMapper = new ObjectMapper();
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 1041a3c04df..511f6568d96 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
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.rest.cluster;
+import static org.apache.ignite.internal.rest.constants.MediaType.TEXT_PLAIN;
import static
org.apache.ignite.internal.rest.matcher.ProblemHttpResponseMatcher.isProblemResponse;
import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -25,9 +26,13 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import io.micronaut.http.HttpStatus;
+import java.net.URI;
+import java.net.http.HttpRequest;
+import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import org.apache.ignite.internal.rest.AbstractRestTestBase;
import org.apache.ignite.internal.rest.api.cluster.ClusterState;
+import org.apache.ignite.internal.rest.api.cluster.ClusterTag;
import org.junit.jupiter.api.Test;
/**
@@ -119,4 +124,34 @@ public class ItClusterManagementControllerTest extends
AbstractRestTestBase {
.withDetail(containsString("Init CMG request denied, reason:
CMG node names do not match."))
);
}
+
+ @Test
+ void testClusterRename() throws Exception {
+ String initRequestBody = "{\n"
+ + " \"metaStorageNodes\": [\n"
+ + " \"" + cluster.nodeName(0) + "\"\n"
+ + " ],\n"
+ + " \"cmgNodes\": [\n"
+ + " \"" + cluster.nodeName(0) + "\"\n"
+ + " ],\n"
+ + " \"clusterName\": \"cluster\"\n"
+ + "}";
+ HttpResponse<String> initResponse =
send(post("/management/v1/cluster/init", initRequestBody));
+ assertThat(initResponse.statusCode(), is(HttpStatus.OK.getCode()));
+ assertThat(cluster.server(0).waitForInitAsync(),
willCompleteSuccessfully());
+
+ HttpResponse<String> stateResponse =
send(get("/management/v1/cluster/state"));
+ ClusterState state = objectMapper.readValue(stateResponse.body(),
ClusterState.class);
+
+ HttpRequest renameRequest =
HttpRequest.newBuilder(URI.create(HTTP_HOST_PORT +
"/management/v1/cluster/rename"))
+ .header("content-type", TEXT_PLAIN)
+ .POST(BodyPublishers.ofString("cluster2"))
+ .build();
+ HttpResponse<String> renameResponse = send(renameRequest);
+ assertThat(renameResponse.statusCode(), is(HttpStatus.OK.getCode()));
+
+ ClusterTag clusterTag2 = objectMapper.readValue(renameResponse.body(),
ClusterTag.class);
+ assertThat(clusterTag2.clusterName(), is("cluster2"));
+ assertThat(clusterTag2.clusterId(),
is(state.clusterTag().clusterId()));
+ }
}
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 009bbcb5370..ecc1cc81c07 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
@@ -99,6 +99,31 @@ public class ClusterManagementController implements
ClusterManagementApi, Resour
});
}
+ @Override
+ public CompletableFuture<ClusterTag> rename(String newName) {
+ LOG.info("Received rename command with new name = '{}'", newName);
+
+ return clusterManagementGroupManager.renameCluster(newName)
+ .thenCompose(unused ->
clusterManagementGroupManager.clusterState())
+ .thenApply(ClusterManagementController::mapClusterTag)
+ .exceptionally(ex -> {
+ throw mapException(ex);
+ });
+ }
+
+ private static ClusterTag mapClusterTag(@Nullable
org.apache.ignite.internal.cluster.management.ClusterState clusterState) {
+ if (clusterState == null) {
+ throw new IgniteException(
+ CLUSTER_NOT_INIT_ERR,
+ "Cluster has not yet been initialized or the node is in
the process of being stopped."
+ );
+ }
+
+ var clusterTag = clusterState.clusterTag();
+
+ return new ClusterTag(clusterTag.clusterName(),
clusterTag.clusterId());
+ }
+
private static ClusterState mapClusterState(@Nullable
org.apache.ignite.internal.cluster.management.ClusterState clusterState) {
if (clusterState == null) {
throw new IgniteException(