Yuta HIGUCHI

tablet-leader command to check current Raft leader

Change-Id: Id360db21988a50c3e2895c5194d59b0ba4cb49e4
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.cli;
17 +
18 +import org.apache.karaf.shell.commands.Command;
19 +import org.onlab.onos.cluster.ControllerNode;
20 +import org.onlab.onos.store.service.DatabaseAdminService;
21 +
22 +import java.util.Optional;
23 +
24 +/**
25 + * Lists mastership roles of nodes for each device.
26 + */
27 +@Command(scope = "onos", name = "tablet-leader",
28 + description = "Prints the current leader of a tablet.")
29 +public class TabletLeaderCommand extends AbstractShellCommand {
30 +
31 + @Override
32 + protected void execute() {
33 + final DatabaseAdminService dbAdminService = get(DatabaseAdminService.class);
34 +
35 + Optional<ControllerNode> leader = dbAdminService.leader();
36 + if (leader.isPresent()) {
37 + print("Leader: %s", leader.get());
38 + } else {
39 + print("No Leader");
40 + }
41 + }
42 +}
...@@ -27,6 +27,11 @@ ...@@ -27,6 +27,11 @@
27 <command> 27 <command>
28 <action class="org.onlab.onos.cli.TabletMemberCommand"/> 28 <action class="org.onlab.onos.cli.TabletMemberCommand"/>
29 </command> 29 </command>
30 +
31 + <command>
32 + <action class="org.onlab.onos.cli.TabletLeaderCommand"/>
33 + </command>
34 +
30 <command> 35 <command>
31 <action class="org.onlab.onos.cli.TabletAddCommand"/> 36 <action class="org.onlab.onos.cli.TabletAddCommand"/>
32 <completers> 37 <completers>
......
1 package org.onlab.onos.store.service; 1 package org.onlab.onos.store.service;
2 2
3 import java.util.Collection; 3 import java.util.Collection;
4 +import java.util.Optional;
4 import java.util.Set; 5 import java.util.Set;
5 6
6 import org.onlab.onos.cluster.ControllerNode; 7 import org.onlab.onos.cluster.ControllerNode;
...@@ -67,4 +68,11 @@ public interface DatabaseAdminService { ...@@ -67,4 +68,11 @@ public interface DatabaseAdminService {
67 * @return Copied collection of members forming default Tablet. 68 * @return Copied collection of members forming default Tablet.
68 */ 69 */
69 public Collection<ControllerNode> listMembers(); 70 public Collection<ControllerNode> listMembers();
71 +
72 + /**
73 + * Returns the current Leader of the default Tablet.
74 + *
75 + * @return leader node
76 + */
77 + public Optional<ControllerNode> leader();
70 } 78 }
......
...@@ -151,4 +151,8 @@ public class DatabaseClient implements ClusterMessageHandler { ...@@ -151,4 +151,8 @@ public class DatabaseClient implements ClusterMessageHandler {
151 public Map<String, VersionedValue> getAll(String tableName) { 151 public Map<String, VersionedValue> getAll(String tableName) {
152 return submit("getAll", tableName); 152 return submit("getAll", tableName);
153 } 153 }
154 +
155 + Member getCurrentLeader() {
156 + return currentLeader;
157 + }
154 } 158 }
......
...@@ -10,6 +10,7 @@ import java.util.Collection; ...@@ -10,6 +10,7 @@ import java.util.Collection;
10 import java.util.Collections; 10 import java.util.Collections;
11 import java.util.HashSet; 11 import java.util.HashSet;
12 import java.util.Map; 12 import java.util.Map;
13 +import java.util.Optional;
13 import java.util.Set; 14 import java.util.Set;
14 import java.util.concurrent.CountDownLatch; 15 import java.util.concurrent.CountDownLatch;
15 import java.util.concurrent.ExecutionException; 16 import java.util.concurrent.ExecutionException;
...@@ -38,7 +39,6 @@ import org.onlab.onos.cluster.ClusterEventListener; ...@@ -38,7 +39,6 @@ import org.onlab.onos.cluster.ClusterEventListener;
38 import org.onlab.onos.cluster.ClusterService; 39 import org.onlab.onos.cluster.ClusterService;
39 import org.onlab.onos.cluster.ControllerNode; 40 import org.onlab.onos.cluster.ControllerNode;
40 import org.onlab.onos.cluster.DefaultControllerNode; 41 import org.onlab.onos.cluster.DefaultControllerNode;
41 -import org.onlab.onos.cluster.NodeId;
42 import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; 42 import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
43 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 43 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
44 import org.onlab.onos.store.cluster.messaging.MessageSubject; 44 import org.onlab.onos.store.cluster.messaging.MessageSubject;
...@@ -433,6 +433,18 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { ...@@ -433,6 +433,18 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService {
433 } 433 }
434 } 434 }
435 435
436 + @Override
437 + public Optional<ControllerNode> leader() {
438 + if (copycat != null) {
439 + if (copycat.isLeader()) {
440 + return Optional.of(clusterService.getLocalNode());
441 + }
442 + Member leader = copycat.cluster().remoteMember(copycat.leader());
443 + return Optional.ofNullable(getNodeIdFromMember(leader));
444 + }
445 + return Optional.ofNullable(getNodeIdFromMember(client.getCurrentLeader()));
446 + }
447 +
436 private final class LeaderAdvertiser implements Runnable { 448 private final class LeaderAdvertiser implements Runnable {
437 449
438 @Override 450 @Override
...@@ -549,28 +561,28 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService { ...@@ -549,28 +561,28 @@ public class DatabaseManager implements DatabaseService, DatabaseAdminService {
549 } 561 }
550 Set<ControllerNode> members = new HashSet<>(); 562 Set<ControllerNode> members = new HashSet<>();
551 for (Member member : copycat.cluster().members()) { 563 for (Member member : copycat.cluster().members()) {
552 - if (member instanceof TcpMember) { 564 + ControllerNode node = getNodeIdFromMember(member);
553 - final TcpMember tcpMember = (TcpMember) member; 565 + if (node == null) {
554 - // TODO assuming tcpMember#host to be IP address, 566 + log.info("No Node found for {}", member);
555 - // but if not lookup DNS, etc. first
556 - IpAddress ip = IpAddress.valueOf(tcpMember.host());
557 - int tcpPort = tcpMember.port();
558 - NodeId id = getNodeIdFromIp(ip, tcpPort);
559 - if (id == null) {
560 - log.info("No NodeId found for {}:{}", ip, tcpPort);
561 continue; 567 continue;
562 } 568 }
563 - members.add(new DefaultControllerNode(id, ip, tcpPort)); 569 + members.add(node);
564 - }
565 } 570 }
566 return members; 571 return members;
567 } 572 }
568 573
569 - private NodeId getNodeIdFromIp(IpAddress ip, int tcpPort) { 574 + private ControllerNode getNodeIdFromMember(Member member) {
575 + if (member instanceof TcpMember) {
576 + final TcpMember tcpMember = (TcpMember) member;
577 + // TODO assuming tcpMember#host to be IP address,
578 + // but if not lookup DNS, etc. first
579 + IpAddress ip = IpAddress.valueOf(tcpMember.host());
580 + int tcpPort = tcpMember.port();
570 for (ControllerNode node : clusterService.getNodes()) { 581 for (ControllerNode node : clusterService.getNodes()) {
571 if (node.ip().equals(ip) && 582 if (node.ip().equals(ip) &&
572 node.tcpPort() == tcpPort) { 583 node.tcpPort() == tcpPort) {
573 - return node.id(); 584 + return node;
585 + }
574 } 586 }
575 } 587 }
576 return null; 588 return null;
......