Yuta HIGUCHI

tablet-leader command to check current Raft leader

Change-Id: Id360db21988a50c3e2895c5194d59b0ba4cb49e4
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed 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.onlab.onos.cli;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cluster.ControllerNode;
import org.onlab.onos.store.service.DatabaseAdminService;
import java.util.Optional;
/**
* Lists mastership roles of nodes for each device.
*/
@Command(scope = "onos", name = "tablet-leader",
description = "Prints the current leader of a tablet.")
public class TabletLeaderCommand extends AbstractShellCommand {
@Override
protected void execute() {
final DatabaseAdminService dbAdminService = get(DatabaseAdminService.class);
Optional<ControllerNode> leader = dbAdminService.leader();
if (leader.isPresent()) {
print("Leader: %s", leader.get());
} else {
print("No Leader");
}
}
}
......@@ -27,6 +27,11 @@
<command>
<action class="org.onlab.onos.cli.TabletMemberCommand"/>
</command>
<command>
<action class="org.onlab.onos.cli.TabletLeaderCommand"/>
</command>
<command>
<action class="org.onlab.onos.cli.TabletAddCommand"/>
<completers>
......
package org.onlab.onos.store.service;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import org.onlab.onos.cluster.ControllerNode;
......@@ -67,4 +68,11 @@ public interface DatabaseAdminService {
* @return Copied collection of members forming default Tablet.
*/
public Collection<ControllerNode> listMembers();
/**
* Returns the current Leader of the default Tablet.
*
* @return leader node
*/
public Optional<ControllerNode> leader();
}
......
......@@ -151,4 +151,8 @@ public class DatabaseClient implements ClusterMessageHandler {
public Map<String, VersionedValue> getAll(String tableName) {
return submit("getAll", tableName);
}
Member getCurrentLeader() {
return currentLeader;
}
}
......
......@@ -10,6 +10,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
......@@ -38,7 +39,6 @@ import org.onlab.onos.cluster.ClusterEventListener;
import org.onlab.onos.cluster.ClusterService;
import org.onlab.onos.cluster.ControllerNode;
import org.onlab.onos.cluster.DefaultControllerNode;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
import org.onlab.onos.store.cluster.messaging.ClusterMessage;
import org.onlab.onos.store.cluster.messaging.MessageSubject;
......@@ -433,6 +433,18 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService {
}
}
@Override
public Optional<ControllerNode> leader() {
if (copycat != null) {
if (copycat.isLeader()) {
return Optional.of(clusterService.getLocalNode());
}
Member leader = copycat.cluster().remoteMember(copycat.leader());
return Optional.ofNullable(getNodeIdFromMember(leader));
}
return Optional.ofNullable(getNodeIdFromMember(client.getCurrentLeader()));
}
private final class LeaderAdvertiser implements Runnable {
@Override
......@@ -549,28 +561,28 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService {
}
Set<ControllerNode> members = new HashSet<>();
for (Member member : copycat.cluster().members()) {
if (member instanceof TcpMember) {
final TcpMember tcpMember = (TcpMember) member;
// TODO assuming tcpMember#host to be IP address,
// but if not lookup DNS, etc. first
IpAddress ip = IpAddress.valueOf(tcpMember.host());
int tcpPort = tcpMember.port();
NodeId id = getNodeIdFromIp(ip, tcpPort);
if (id == null) {
log.info("No NodeId found for {}:{}", ip, tcpPort);
ControllerNode node = getNodeIdFromMember(member);
if (node == null) {
log.info("No Node found for {}", member);
continue;
}
members.add(new DefaultControllerNode(id, ip, tcpPort));
}
members.add(node);
}
return members;
}
private NodeId getNodeIdFromIp(IpAddress ip, int tcpPort) {
private ControllerNode getNodeIdFromMember(Member member) {
if (member instanceof TcpMember) {
final TcpMember tcpMember = (TcpMember) member;
// TODO assuming tcpMember#host to be IP address,
// but if not lookup DNS, etc. first
IpAddress ip = IpAddress.valueOf(tcpMember.host());
int tcpPort = tcpMember.port();
for (ControllerNode node : clusterService.getNodes()) {
if (node.ip().equals(ip) &&
node.tcpPort() == tcpPort) {
return node.id();
return node;
}
}
}
return null;
......