This is an automated email from the ASF dual-hosted git repository.
szetszwo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ratis.git
The following commit(s) were added to refs/heads/master by this push:
new 069f9d8 RATIS-1526. Add ratis-shell pause&resume leader election
command (#603)
069f9d8 is described below
commit 069f9d89879bb03636d31bbdad924ffa4578194e
Author: Yaolong Liu <[email protected]>
AuthorDate: Thu Feb 24 02:09:20 2022 +0800
RATIS-1526. Add ratis-shell pause&resume leader election command (#603)
---
...shotCommand.java => AbstractParentCommand.java} | 59 ++----------
.../shell/cli/sh/command/AbstractRatisCommand.java | 15 +++
.../shell/cli/sh/command/ElectionCommand.java | 57 ++++++++++++
.../ratis/shell/cli/sh/command/GroupCommand.java | 41 +-------
.../ratis/shell/cli/sh/command/PeerCommand.java | 103 +++------------------
.../shell/cli/sh/command/SnapshotCommand.java | 41 +-------
.../PauseCommand.java} | 76 +++++----------
.../ResumeCommand.java} | 76 +++++----------
.../TransferCommand.java} | 21 +++--
.../AddCommand.java} | 75 +++++++--------
.../ratis/shell/cli/sh/peer/RemoveCommand.java | 99 ++++++++++++++++++++
.../sh/{command => peer}/SetPriorityCommand.java | 34 +++----
12 files changed, 309 insertions(+), 388 deletions(-)
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SnapshotCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/AbstractParentCommand.java
similarity index 50%
copy from
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SnapshotCommand.java
copy to
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/AbstractParentCommand.java
index ecc52ad..2129d18 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SnapshotCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/AbstractParentCommand.java
@@ -17,78 +17,35 @@
*/
package org.apache.ratis.shell.cli.sh.command;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
import org.apache.ratis.shell.cli.Command;
-import org.apache.ratis.shell.cli.sh.snapshot.TakeSnapshotCommand;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
-/**
- * Command for the ratis snapshot
- */
-public class SnapshotCommand extends AbstractRatisCommand {
-
- private static final List<Function<Context, AbstractRatisCommand>>
SUB_COMMAND_CONSTRUCTORS
- = Collections.unmodifiableList(Arrays.asList(TakeSnapshotCommand::new));
-
+public abstract class AbstractParentCommand extends AbstractRatisCommand{
private final Map<String, Command> subs;
- /**
- * @param context command context
- */
- public SnapshotCommand(Context context) {
+ public AbstractParentCommand(Context context, List<Function<Context,
AbstractRatisCommand>> subCommandConstructors) {
super(context);
- this.subs = Collections.unmodifiableMap(SUB_COMMAND_CONSTRUCTORS.stream()
+ this.subs = Collections.unmodifiableMap(subCommandConstructors.stream()
.map(constructor -> constructor.apply(context))
.collect(Collectors.toMap(Command::getCommandName,
Function.identity())));
}
@Override
- public String getCommandName() {
- return "snapshot";
+ public final Map<String, Command> getSubCommands() {
+ return subs;
}
@Override
- public String getUsage() {
-
- StringBuilder usage = new StringBuilder(getCommandName());
- for (String cmd : subs.keySet()) {
+ public final String getUsage() {
+ final StringBuilder usage = new StringBuilder(getCommandName());
+ for (String cmd : getSubCommands().keySet()) {
usage.append(" [").append(cmd).append("]");
}
return usage.toString();
}
-
- @Override
- public String getDescription() {
- return description();
- }
-
- @Override
- public Map<String, Command> getSubCommands() {
- return subs;
- }
-
- @Override
- public Options getOptions() {
- return super.getOptions().addOption(
- Option.builder()
- .option(GROUPID_OPTION_NAME)
- .hasArg()
- .required()
- .desc("the group id")
- .build());
- }
-
- /**
- * @return command's description
- */
- public static String description() {
- return "Manage ratis snapshot; see the sub-commands for the details.";
- }
}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/AbstractRatisCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/AbstractRatisCommand.java
index c2b9e4d..a39dad6 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/AbstractRatisCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/AbstractRatisCommand.java
@@ -35,6 +35,7 @@ import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.util.*;
+import java.util.function.BiConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -196,4 +197,18 @@ public abstract class AbstractRatisCommand implements
Command {
throw new IOException(message, e);
}
}
+
+ protected List<RaftPeerId> getIds(String[] optionValues,
BiConsumer<RaftPeerId, InetSocketAddress> consumer) {
+ if (optionValues == null) {
+ return Collections.emptyList();
+ }
+ final List<RaftPeerId> ids = new ArrayList<>();
+ for (String address : optionValues) {
+ final InetSocketAddress serverAddress = parseInetSocketAddress(address);
+ final RaftPeerId peerId = RaftUtils.getPeerId(serverAddress);
+ consumer.accept(peerId, serverAddress);
+ ids.add(peerId);
+ }
+ return ids;
+ }
}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectionCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectionCommand.java
new file mode 100644
index 0000000..47ed3b0
--- /dev/null
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectionCommand.java
@@ -0,0 +1,57 @@
+/*
+ * 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.ratis.shell.cli.sh.command;
+
+import org.apache.ratis.shell.cli.sh.election.PauseCommand;
+import org.apache.ratis.shell.cli.sh.election.ResumeCommand;
+import org.apache.ratis.shell.cli.sh.election.TransferCommand;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+public class ElectionCommand extends AbstractParentCommand {
+ private static final List<Function<Context, AbstractRatisCommand>>
SUB_COMMAND_CONSTRUCTORS
+ = Collections.unmodifiableList(Arrays.asList(
+ TransferCommand::new, PauseCommand::new, ResumeCommand::new));
+
+ /**
+ * @param context command context
+ */
+ public ElectionCommand(Context context) {
+ super(context, SUB_COMMAND_CONSTRUCTORS);
+ }
+
+ @Override
+ public String getCommandName() {
+ return "election";
+ }
+
+ @Override
+ public String getDescription() {
+ return description();
+ }
+
+ /**
+ * @return command's description
+ */
+ public static String description() {
+ return "Manage ratis leader election; see the sub-commands for the
details.";
+ }
+}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/GroupCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/GroupCommand.java
index dd87dc0..e1d7ec0 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/GroupCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/GroupCommand.java
@@ -17,38 +17,27 @@
*/
package org.apache.ratis.shell.cli.sh.command;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.ratis.shell.cli.Command;
import org.apache.ratis.shell.cli.sh.group.GroupInfoCommand;
import org.apache.ratis.shell.cli.sh.group.GroupListCommand;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.function.Function;
-import java.util.stream.Collectors;
/**
* Command for the ratis group
*/
-public class GroupCommand extends AbstractRatisCommand {
+public class GroupCommand extends AbstractParentCommand {
private static final List<Function<Context, AbstractRatisCommand>>
SUB_COMMAND_CONSTRUCTORS
= Collections.unmodifiableList(Arrays.asList(
GroupInfoCommand::new, GroupListCommand::new));
-
- private final Map<String, Command> subs;
-
/**
* @param context command context
*/
public GroupCommand(Context context) {
- super(context);
- this.subs = Collections.unmodifiableMap(SUB_COMMAND_CONSTRUCTORS.stream()
- .map(constructor -> constructor.apply(context))
- .collect(Collectors.toMap(Command::getCommandName,
Function.identity())));
+ super(context, SUB_COMMAND_CONSTRUCTORS);
}
@Override
@@ -57,36 +46,10 @@ public class GroupCommand extends AbstractRatisCommand {
}
@Override
- public String getUsage() {
-
- StringBuilder usage = new StringBuilder(getCommandName());
- for (String cmd : subs.keySet()) {
- usage.append(" [").append(cmd).append("]");
- }
- return usage.toString();
- }
-
- @Override
public String getDescription() {
return description();
}
- @Override
- public Map<String, Command> getSubCommands() {
- return subs;
- }
-
- @Override
- public Options getOptions() {
- return super.getOptions().addOption(
- Option.builder()
- .option(GROUPID_OPTION_NAME)
- .hasArg()
- .required()
- .desc("the group id")
- .build());
- }
-
/**
* @return command's description
*/
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/PeerCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/PeerCommand.java
index 6bd59e9..6cb2796 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/PeerCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/PeerCommand.java
@@ -17,38 +17,29 @@
*/
package org.apache.ratis.shell.cli.sh.command;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.ratis.client.RaftClient;
-import org.apache.ratis.protocol.RaftClientReply;
-import org.apache.ratis.protocol.RaftPeer;
-import org.apache.ratis.protocol.RaftPeerId;
-import org.apache.ratis.shell.cli.RaftUtils;
+import org.apache.ratis.shell.cli.sh.peer.AddCommand;
+import org.apache.ratis.shell.cli.sh.peer.RemoveCommand;
+import org.apache.ratis.shell.cli.sh.peer.SetPriorityCommand;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.function.BiConsumer;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import java.util.function.Function;
/**
- * Command for remove and add ratis server.
+ * Command for the ratis peer
*/
-public class PeerCommand extends AbstractRatisCommand {
- public static final String REMOVE_OPTION_NAME = "remove";
- public static final String ADD_OPTION_NAME = "add";
+public class PeerCommand extends AbstractParentCommand{
+
+ private static final List<Function<Context, AbstractRatisCommand>>
SUB_COMMAND_CONSTRUCTORS
+ = Collections.unmodifiableList(Arrays.asList(AddCommand::new,
RemoveCommand::new,
+ SetPriorityCommand::new));
/**
* @param context command context
*/
public PeerCommand(Context context) {
- super(context);
+ super(context, SUB_COMMAND_CONSTRUCTORS);
}
@Override
@@ -57,82 +48,14 @@ public class PeerCommand extends AbstractRatisCommand {
}
@Override
- public int run(CommandLine cl) throws IOException {
- super.run(cl);
- final Map<RaftPeerId, InetSocketAddress> peersInfo = new HashMap<>();
- final List<RaftPeerId> toRemove =
getIds(cl.getOptionValues(REMOVE_OPTION_NAME), (a, b) -> {});
- final List<RaftPeerId> toAdd = getIds(cl.getOptionValues(ADD_OPTION_NAME),
peersInfo::put);
- if (toRemove.isEmpty() && toAdd.isEmpty()) {
- throw new IllegalArgumentException(String.format("Both -%s and -%s
options are empty",
- REMOVE_OPTION_NAME, ADD_OPTION_NAME));
- }
-
- try (RaftClient client = RaftUtils.createClient(getRaftGroup())) {
- final Stream<RaftPeer> remaining = getRaftGroup().getPeers().stream()
- .filter(raftPeer -> !toRemove.contains(raftPeer.getId()))
- .filter(raftPeer -> !toAdd.contains(raftPeer.getId()));
- final Stream<RaftPeer> adding = toAdd.stream().map(raftPeerId ->
RaftPeer.newBuilder()
- .setId(raftPeerId)
- .setAddress(peersInfo.get(raftPeerId))
- .setPriority(0)
- .build());
- final List<RaftPeer> peers = Stream.concat(remaining,
adding).collect(Collectors.toList());
- System.out.println("New peer list: " + peers);
- RaftClientReply reply = client.admin().setConfiguration(peers);
- processReply(reply, () -> "failed to change raft peer");
- }
- return 0;
- }
-
- private static List<RaftPeerId> getIds(String[] optionValues,
BiConsumer<RaftPeerId, InetSocketAddress> consumer) {
- if (optionValues == null) {
- return Collections.emptyList();
- }
- final List<RaftPeerId> ids = new ArrayList<>();
- for (String address : optionValues) {
- final InetSocketAddress serverAddress = parseInetSocketAddress(address);
- final RaftPeerId peerId = RaftUtils.getPeerId(serverAddress);
- consumer.accept(peerId, serverAddress);
- ids.add(peerId);
- }
- return ids;
- }
-
- @Override
- public String getUsage() {
- return String.format("%s"
- + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
- + " [-%s <RAFT_GROUP_ID>]"
- + " -%s <PEER_HOST:PEER_PORT>"
- + " -%s <PEER_HOST:PEER_PORT>",
- getCommandName(), PEER_OPTION_NAME, GROUPID_OPTION_NAME,
- REMOVE_OPTION_NAME, ADD_OPTION_NAME);
- }
-
- @Override
public String getDescription() {
return description();
}
- @Override
- public Options getOptions() {
- return super.getOptions()
- .addOption(Option.builder()
- .option(REMOVE_OPTION_NAME)
- .hasArg()
- .desc("peer address to be removed")
- .build())
- .addOption(Option.builder()
- .option(ADD_OPTION_NAME)
- .hasArg()
- .desc("peer address to be added")
- .build());
- }
-
/**
* @return command's description
*/
public static String description() {
- return "Remove or Add peers of a ratis group";
+ return "Manage ratis peers; see the sub-commands for the details.";
}
}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SnapshotCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SnapshotCommand.java
index ecc52ad..4dd5842 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SnapshotCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SnapshotCommand.java
@@ -17,36 +17,25 @@
*/
package org.apache.ratis.shell.cli.sh.command;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.ratis.shell.cli.Command;
import org.apache.ratis.shell.cli.sh.snapshot.TakeSnapshotCommand;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.function.Function;
-import java.util.stream.Collectors;
/**
* Command for the ratis snapshot
*/
-public class SnapshotCommand extends AbstractRatisCommand {
-
+public class SnapshotCommand extends AbstractParentCommand {
private static final List<Function<Context, AbstractRatisCommand>>
SUB_COMMAND_CONSTRUCTORS
= Collections.unmodifiableList(Arrays.asList(TakeSnapshotCommand::new));
- private final Map<String, Command> subs;
-
/**
* @param context command context
*/
public SnapshotCommand(Context context) {
- super(context);
- this.subs = Collections.unmodifiableMap(SUB_COMMAND_CONSTRUCTORS.stream()
- .map(constructor -> constructor.apply(context))
- .collect(Collectors.toMap(Command::getCommandName,
Function.identity())));
+ super(context, SUB_COMMAND_CONSTRUCTORS);
}
@Override
@@ -55,36 +44,10 @@ public class SnapshotCommand extends AbstractRatisCommand {
}
@Override
- public String getUsage() {
-
- StringBuilder usage = new StringBuilder(getCommandName());
- for (String cmd : subs.keySet()) {
- usage.append(" [").append(cmd).append("]");
- }
- return usage.toString();
- }
-
- @Override
public String getDescription() {
return description();
}
- @Override
- public Map<String, Command> getSubCommands() {
- return subs;
- }
-
- @Override
- public Options getOptions() {
- return super.getOptions().addOption(
- Option.builder()
- .option(GROUPID_OPTION_NAME)
- .hasArg()
- .required()
- .desc("the group id")
- .build());
- }
-
/**
* @return command's description
*/
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/PauseCommand.java
similarity index 50%
copy from
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
copy to
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/PauseCommand.java
index 6b7eb0e..4ea2969 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/PauseCommand.java
@@ -15,38 +15,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.ratis.shell.cli.sh.command;
+package org.apache.ratis.shell.cli.sh.election;
-import org.apache.commons.cli.Option;
-import org.apache.ratis.shell.cli.RaftUtils;
import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.ratis.client.RaftClient;
import org.apache.ratis.protocol.RaftClientReply;
import org.apache.ratis.protocol.RaftPeer;
import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.shell.cli.RaftUtils;
+import org.apache.ratis.shell.cli.sh.command.AbstractRatisCommand;
+import org.apache.ratis.shell.cli.sh.command.Context;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
/**
- * Command for transferring the leadership to another peer.
+ * Command for pause leader election on specific server
*/
-public class ElectCommand extends AbstractRatisCommand {
- public static final String ADDRESS_OPTION_NAME = "address";
+public class PauseCommand extends AbstractRatisCommand {
+ public static final String ADDRESS_OPTION_NAME = "address";
/**
* @param context command context
*/
- public ElectCommand(Context context) {
+ public PauseCommand(Context context) {
super(context);
}
@Override
public String getCommandName() {
- return "elect";
+ return "pause";
}
@Override
@@ -54,43 +53,18 @@ public class ElectCommand extends AbstractRatisCommand {
super.run(cl);
String strAddr = cl.getOptionValue(ADDRESS_OPTION_NAME);
-
- RaftPeerId newLeaderId = null;
- // update priorities to enable transfer
- List<RaftPeer> peersWithNewPriorities = new ArrayList<>();
- for (RaftPeer peer : getRaftGroup().getPeers()) {
- peersWithNewPriorities.add(
- RaftPeer.newBuilder(peer)
- .setPriority(peer.getAddress().equals(strAddr) ? 2 : 1)
- .build()
- );
- if (peer.getAddress().equals(strAddr)) {
- newLeaderId = peer.getId();
- }
- }
- if (newLeaderId == null) {
- return -2;
+ final RaftPeerId peerId = getRaftGroup().getPeers().stream()
+ .filter(p -> p.getAddress().equals(strAddr)).findAny()
+ .map(RaftPeer::getId)
+ .orElse(null);
+ if (peerId == null) {
+ printf("Peer not found: %s", strAddr);
+ return -1;
}
- try (RaftClient client = RaftUtils.createClient(getRaftGroup())) {
- String stringPeers = "[" +
peersWithNewPriorities.stream().map(RaftPeer::toString)
- .collect(Collectors.joining(", ")) + "]";
- printf("Applying new peer state before transferring leadership: %n%s%n",
stringPeers);
- RaftClientReply setConfigurationReply =
- client.admin().setConfiguration(peersWithNewPriorities);
- processReply(setConfigurationReply,
- () -> "failed to set priorities before initiating election");
- // transfer leadership
- printf("Transferring leadership to server with address <%s> %n",
strAddr);
- try {
- Thread.sleep(3_000);
- RaftClientReply transferLeadershipReply =
- client.admin().transferLeadership(newLeaderId, 60_000);
- processReply(transferLeadershipReply, () -> "election failed");
- } catch (Throwable t) {
- printf("caught an error when executing transfer: %s%n",
t.getMessage());
- return -1;
- }
- println("Transferring leadership initiated");
+ try(final RaftClient raftClient = RaftUtils.createClient(getRaftGroup())) {
+ RaftClientReply reply =
raftClient.getLeaderElectionManagementApi(peerId).pause();
+ processReply(reply, () -> String.format("Failed to pause leader election
on peer %s", strAddr));
+ printf(String.format("Successful pause leader election on peer %s",
strAddr));
}
return 0;
}
@@ -98,8 +72,8 @@ public class ElectCommand extends AbstractRatisCommand {
@Override
public String getUsage() {
return String.format("%s -%s <HOSTNAME:PORT>"
- + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
- + " [-%s <RAFT_GROUP_ID>]",
+ + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
+ + " [-%s <RAFT_GROUP_ID>]",
getCommandName(), ADDRESS_OPTION_NAME, PEER_OPTION_NAME,
GROUPID_OPTION_NAME);
}
@@ -116,7 +90,7 @@ public class ElectCommand extends AbstractRatisCommand {
.option(ADDRESS_OPTION_NAME)
.hasArg()
.required()
- .desc("Server address that will take over as leader")
+ .desc("Server address that will be paused its leader election")
.build()
);
}
@@ -125,6 +99,6 @@ public class ElectCommand extends AbstractRatisCommand {
* @return command's description
*/
public static String description() {
- return "Transfers leadership to the <hostname>:<port>";
+ return "Pause leader election to the server <hostname>:<port>";
}
}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/ResumeCommand.java
similarity index 50%
copy from
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
copy to
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/ResumeCommand.java
index 6b7eb0e..4b4dc22 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/ResumeCommand.java
@@ -15,38 +15,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.ratis.shell.cli.sh.command;
+package org.apache.ratis.shell.cli.sh.election;
-import org.apache.commons.cli.Option;
-import org.apache.ratis.shell.cli.RaftUtils;
import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.ratis.client.RaftClient;
import org.apache.ratis.protocol.RaftClientReply;
import org.apache.ratis.protocol.RaftPeer;
import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.shell.cli.RaftUtils;
+import org.apache.ratis.shell.cli.sh.command.AbstractRatisCommand;
+import org.apache.ratis.shell.cli.sh.command.Context;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
/**
- * Command for transferring the leadership to another peer.
+ * Command for resuming leader election on specific server
*/
-public class ElectCommand extends AbstractRatisCommand {
- public static final String ADDRESS_OPTION_NAME = "address";
+public class ResumeCommand extends AbstractRatisCommand {
+ public static final String ADDRESS_OPTION_NAME = "address";
/**
* @param context command context
*/
- public ElectCommand(Context context) {
+ public ResumeCommand(Context context) {
super(context);
}
@Override
public String getCommandName() {
- return "elect";
+ return "resume";
}
@Override
@@ -54,43 +53,18 @@ public class ElectCommand extends AbstractRatisCommand {
super.run(cl);
String strAddr = cl.getOptionValue(ADDRESS_OPTION_NAME);
-
- RaftPeerId newLeaderId = null;
- // update priorities to enable transfer
- List<RaftPeer> peersWithNewPriorities = new ArrayList<>();
- for (RaftPeer peer : getRaftGroup().getPeers()) {
- peersWithNewPriorities.add(
- RaftPeer.newBuilder(peer)
- .setPriority(peer.getAddress().equals(strAddr) ? 2 : 1)
- .build()
- );
- if (peer.getAddress().equals(strAddr)) {
- newLeaderId = peer.getId();
- }
- }
- if (newLeaderId == null) {
- return -2;
+ final RaftPeerId peerId = getRaftGroup().getPeers().stream()
+ .filter(p -> p.getAddress().equals(strAddr)).findAny()
+ .map(RaftPeer::getId)
+ .orElse(null);
+ if (peerId == null) {
+ printf("Can't find a sever with the address:%s", strAddr);
+ return -1;
}
- try (RaftClient client = RaftUtils.createClient(getRaftGroup())) {
- String stringPeers = "[" +
peersWithNewPriorities.stream().map(RaftPeer::toString)
- .collect(Collectors.joining(", ")) + "]";
- printf("Applying new peer state before transferring leadership: %n%s%n",
stringPeers);
- RaftClientReply setConfigurationReply =
- client.admin().setConfiguration(peersWithNewPriorities);
- processReply(setConfigurationReply,
- () -> "failed to set priorities before initiating election");
- // transfer leadership
- printf("Transferring leadership to server with address <%s> %n",
strAddr);
- try {
- Thread.sleep(3_000);
- RaftClientReply transferLeadershipReply =
- client.admin().transferLeadership(newLeaderId, 60_000);
- processReply(transferLeadershipReply, () -> "election failed");
- } catch (Throwable t) {
- printf("caught an error when executing transfer: %s%n",
t.getMessage());
- return -1;
- }
- println("Transferring leadership initiated");
+ try(final RaftClient raftClient = RaftUtils.createClient(getRaftGroup())) {
+ RaftClientReply reply =
raftClient.getLeaderElectionManagementApi(peerId).resume();
+ processReply(reply, () -> String.format("Failed to resume leader
election on peer %s", strAddr));
+ printf(String.format("Successful pause leader election on peer %s",
strAddr));
}
return 0;
}
@@ -98,8 +72,8 @@ public class ElectCommand extends AbstractRatisCommand {
@Override
public String getUsage() {
return String.format("%s -%s <HOSTNAME:PORT>"
- + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
- + " [-%s <RAFT_GROUP_ID>]",
+ + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
+ + " [-%s <RAFT_GROUP_ID>]",
getCommandName(), ADDRESS_OPTION_NAME, PEER_OPTION_NAME,
GROUPID_OPTION_NAME);
}
@@ -116,7 +90,7 @@ public class ElectCommand extends AbstractRatisCommand {
.option(ADDRESS_OPTION_NAME)
.hasArg()
.required()
- .desc("Server address that will take over as leader")
+ .desc("Server address that will be resumed its leader election")
.build()
);
}
@@ -125,6 +99,6 @@ public class ElectCommand extends AbstractRatisCommand {
* @return command's description
*/
public static String description() {
- return "Transfers leadership to the <hostname>:<port>";
+ return "Resume leader election to the server <hostname>:<port>";
}
}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/TransferCommand.java
similarity index 88%
rename from
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
rename to
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/TransferCommand.java
index 6b7eb0e..a1de4db 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/ElectCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/election/TransferCommand.java
@@ -15,16 +15,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.ratis.shell.cli.sh.command;
+package org.apache.ratis.shell.cli.sh.election;
-import org.apache.commons.cli.Option;
-import org.apache.ratis.shell.cli.RaftUtils;
import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.ratis.client.RaftClient;
import org.apache.ratis.protocol.RaftClientReply;
import org.apache.ratis.protocol.RaftPeer;
import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.shell.cli.RaftUtils;
+import org.apache.ratis.shell.cli.sh.command.AbstractRatisCommand;
+import org.apache.ratis.shell.cli.sh.command.Context;
import java.io.IOException;
import java.util.ArrayList;
@@ -32,21 +34,20 @@ import java.util.List;
import java.util.stream.Collectors;
/**
- * Command for transferring the leadership to another peer.
+ * Command for transferring the ratis leader to specific server.
*/
-public class ElectCommand extends AbstractRatisCommand {
+public class TransferCommand extends AbstractRatisCommand {
public static final String ADDRESS_OPTION_NAME = "address";
-
/**
* @param context command context
*/
- public ElectCommand(Context context) {
+ public TransferCommand(Context context) {
super(context);
}
@Override
public String getCommandName() {
- return "elect";
+ return "transfer";
}
@Override
@@ -98,8 +99,8 @@ public class ElectCommand extends AbstractRatisCommand {
@Override
public String getUsage() {
return String.format("%s -%s <HOSTNAME:PORT>"
- + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
- + " [-%s <RAFT_GROUP_ID>]",
+ + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
+ + " [-%s <RAFT_GROUP_ID>]",
getCommandName(), ADDRESS_OPTION_NAME, PEER_OPTION_NAME,
GROUPID_OPTION_NAME);
}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SetPriorityCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/AddCommand.java
similarity index 51%
copy from
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SetPriorityCommand.java
copy to
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/AddCommand.java
index 0d9cd00..9c87f69 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SetPriorityCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/AddCommand.java
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.ratis.shell.cli.sh.command;
+package org.apache.ratis.shell.cli.sh.peer;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
@@ -23,59 +23,54 @@ import org.apache.commons.cli.Options;
import org.apache.ratis.client.RaftClient;
import org.apache.ratis.protocol.RaftClientReply;
import org.apache.ratis.protocol.RaftPeer;
+import org.apache.ratis.protocol.RaftPeerId;
import org.apache.ratis.shell.cli.RaftUtils;
+import org.apache.ratis.shell.cli.sh.command.AbstractRatisCommand;
+import org.apache.ratis.shell.cli.sh.command.Context;
import java.io.IOException;
-import java.util.ArrayList;
+import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
- * Command for setting priority of the specific ratis server.
+ * Command for add ratis server.
*/
-public class SetPriorityCommand extends AbstractRatisCommand {
- public static final String PEER_WITH_NEW_PRIORITY_OPTION_NAME =
"addressPriority";
+public class AddCommand extends AbstractRatisCommand {
+ public static final String ADDRESS_OPTION_NAME = "address";
/**
* @param context command context
*/
- public SetPriorityCommand(Context context) {
+ public AddCommand(Context context) {
super(context);
}
@Override
public String getCommandName() {
- return "setPriority";
+ return "add";
}
@Override
public int run(CommandLine cl) throws IOException {
super.run(cl);
- Map<String, Integer> addressPriorityMap = new HashMap<>();
- for (String optionValue :
cl.getOptionValues(PEER_WITH_NEW_PRIORITY_OPTION_NAME)) {
- String[] str = optionValue.split("[|]");
- if(str.length < 2) {
- println("The format of the parameter is wrong");
- return -1;
- }
- addressPriorityMap.put(str[0], Integer.parseInt(str[1]));
- }
-
+ final Map<RaftPeerId, InetSocketAddress> peersInfo = new HashMap<>();
+ final List<RaftPeerId> ids =
+ getIds(cl.getOptionValue(ADDRESS_OPTION_NAME).split(","),
peersInfo::put);
try (RaftClient client = RaftUtils.createClient(getRaftGroup())) {
- List<RaftPeer> peers = new ArrayList<>();
- for (RaftPeer peer : getRaftGroup().getPeers()) {
- if (!addressPriorityMap.containsKey(peer.getAddress())) {
- peers.add(RaftPeer.newBuilder(peer).build());
- } else {
- peers.add(RaftPeer.newBuilder(peer)
-
.setPriority(addressPriorityMap.get(peer.getAddress()))
- .build()
- );
- }
- }
+ final Stream<RaftPeer> remaining = getRaftGroup().getPeers().stream();
+ final Stream<RaftPeer> adding = ids.stream().map(raftPeerId ->
RaftPeer.newBuilder()
+ .setId(raftPeerId)
+ .setAddress(peersInfo.get(raftPeerId))
+ .setPriority(0)
+ .build());
+ final List<RaftPeer> peers = Stream.concat(remaining,
adding).collect(Collectors.toList());
+ System.out.println("New peer list: " + peers);
RaftClientReply reply = client.admin().setConfiguration(peers);
- processReply(reply, () -> "failed to set master priorities ");
+ processReply(reply, () -> "Failed to change raft peer");
}
return 0;
}
@@ -83,10 +78,10 @@ public class SetPriorityCommand extends
AbstractRatisCommand {
@Override
public String getUsage() {
return String.format("%s"
- + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
- + " [-%s <RAFT_GROUP_ID>]"
- + " -%s <PEER_HOST:PEER_PORT|PRIORITY>",
- getCommandName(), PEER_OPTION_NAME, GROUPID_OPTION_NAME,
PEER_WITH_NEW_PRIORITY_OPTION_NAME);
+ + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
+ + " [-%s <RAFT_GROUP_ID>]"
+ + " -%s <PEER_HOST:PEER_PORT>",
+ getCommandName(), PEER_OPTION_NAME, GROUPID_OPTION_NAME,
ADDRESS_OPTION_NAME);
}
@Override
@@ -97,18 +92,18 @@ public class SetPriorityCommand extends
AbstractRatisCommand {
@Override
public Options getOptions() {
return super.getOptions().addOption(
- Option.builder()
- .option(PEER_WITH_NEW_PRIORITY_OPTION_NAME)
- .hasArg()
- .required()
- .desc("Peers information with priority")
- .build());
+ Option.builder()
+ .option(ADDRESS_OPTION_NAME)
+ .hasArg()
+ .required()
+ .desc("The address information of ratis peers")
+ .build());
}
/**
* @return command's description
*/
public static String description() {
- return "Set priority to ratis peers";
+ return "Add peers to a ratis group";
}
}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/RemoveCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/RemoveCommand.java
new file mode 100644
index 0000000..0ab198d
--- /dev/null
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/RemoveCommand.java
@@ -0,0 +1,99 @@
+/*
+ * 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.ratis.shell.cli.sh.peer;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.ratis.client.RaftClient;
+import org.apache.ratis.protocol.RaftClientReply;
+import org.apache.ratis.protocol.RaftPeer;
+import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.shell.cli.RaftUtils;
+import org.apache.ratis.shell.cli.sh.command.AbstractRatisCommand;
+import org.apache.ratis.shell.cli.sh.command.Context;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Command for remove ratis server.
+ */
+public class RemoveCommand extends AbstractRatisCommand {
+
+ public static final String ADDRESS_OPTION_NAME = "address";
+ /**
+ * @param context command context
+ */
+ public RemoveCommand(Context context) {
+ super(context);
+ }
+
+ @Override
+ public String getCommandName() {
+ return "remove";
+ }
+
+ @Override
+ public int run(CommandLine cl) throws IOException {
+ super.run(cl);
+ final List<RaftPeerId> ids =
+ getIds(cl.getOptionValue(ADDRESS_OPTION_NAME).split(","), (a, b) ->
{});
+ try (RaftClient client = RaftUtils.createClient(getRaftGroup())) {
+ final List<RaftPeer> remaining = getRaftGroup().getPeers().stream()
+ .filter(raftPeer ->
!ids.contains(raftPeer.getId())).collect(Collectors.toList());
+ System.out.println("New peer list: " + remaining);
+ RaftClientReply reply = client.admin().setConfiguration(remaining);
+ processReply(reply, () -> "Failed to change raft peer");
+ }
+ return 0;
+ }
+
+ @Override
+ public String getUsage() {
+ return String.format("%s"
+ + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
+ + " [-%s <RAFT_GROUP_ID>]"
+ + " -%s <PEER_HOST:PEER_PORT>",
+ getCommandName(), PEER_OPTION_NAME, GROUPID_OPTION_NAME,
ADDRESS_OPTION_NAME);
+ }
+
+ @Override
+ public String getDescription() {
+ return description();
+ }
+
+ @Override
+ public Options getOptions() {
+ return super.getOptions().addOption(
+ Option.builder()
+ .option(ADDRESS_OPTION_NAME)
+ .hasArg()
+ .required()
+ .desc("The address information of ratis peers")
+ .build());
+ }
+
+ /**
+ * @return command's description
+ */
+ public static String description() {
+ return "Remove peers to a ratis group";
+ }
+}
diff --git
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SetPriorityCommand.java
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/SetPriorityCommand.java
similarity index 77%
rename from
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SetPriorityCommand.java
rename to
ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/SetPriorityCommand.java
index 0d9cd00..43206f8 100644
---
a/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/command/SetPriorityCommand.java
+++
b/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/peer/SetPriorityCommand.java
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.ratis.shell.cli.sh.command;
+package org.apache.ratis.shell.cli.sh.peer;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
@@ -24,6 +24,8 @@ import org.apache.ratis.client.RaftClient;
import org.apache.ratis.protocol.RaftClientReply;
import org.apache.ratis.protocol.RaftPeer;
import org.apache.ratis.shell.cli.RaftUtils;
+import org.apache.ratis.shell.cli.sh.command.AbstractRatisCommand;
+import org.apache.ratis.shell.cli.sh.command.Context;
import java.io.IOException;
import java.util.ArrayList;
@@ -31,10 +33,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-/**
- * Command for setting priority of the specific ratis server.
- */
public class SetPriorityCommand extends AbstractRatisCommand {
+
public static final String PEER_WITH_NEW_PRIORITY_OPTION_NAME =
"addressPriority";
/**
@@ -69,13 +69,13 @@ public class SetPriorityCommand extends
AbstractRatisCommand {
peers.add(RaftPeer.newBuilder(peer).build());
} else {
peers.add(RaftPeer.newBuilder(peer)
-
.setPriority(addressPriorityMap.get(peer.getAddress()))
- .build()
+ .setPriority(addressPriorityMap.get(peer.getAddress()))
+ .build()
);
}
}
RaftClientReply reply = client.admin().setConfiguration(peers);
- processReply(reply, () -> "failed to set master priorities ");
+ processReply(reply, () -> "Failed to set master priorities ");
}
return 0;
}
@@ -83,10 +83,10 @@ public class SetPriorityCommand extends
AbstractRatisCommand {
@Override
public String getUsage() {
return String.format("%s"
- + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
- + " [-%s <RAFT_GROUP_ID>]"
- + " -%s <PEER_HOST:PEER_PORT|PRIORITY>",
- getCommandName(), PEER_OPTION_NAME, GROUPID_OPTION_NAME,
PEER_WITH_NEW_PRIORITY_OPTION_NAME);
+ + " -%s
<PEER0_HOST:PEER0_PORT,PEER1_HOST:PEER1_PORT,PEER2_HOST:PEER2_PORT>"
+ + " [-%s <RAFT_GROUP_ID>]"
+ + " -%s <PEER_HOST:PEER_PORT|PRIORITY>",
+ getCommandName(), PEER_OPTION_NAME, GROUPID_OPTION_NAME,
PEER_WITH_NEW_PRIORITY_OPTION_NAME);
}
@Override
@@ -97,12 +97,12 @@ public class SetPriorityCommand extends
AbstractRatisCommand {
@Override
public Options getOptions() {
return super.getOptions().addOption(
- Option.builder()
- .option(PEER_WITH_NEW_PRIORITY_OPTION_NAME)
- .hasArg()
- .required()
- .desc("Peers information with priority")
- .build());
+ Option.builder()
+ .option(PEER_WITH_NEW_PRIORITY_OPTION_NAME)
+ .hasArg()
+ .required()
+ .desc("Peers information with priority")
+ .build());
}
/**