HDDS-6863. Add Group-Id & Ratis-Roles Information for OM UI (#3520)
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
index e260e2a..65a2f67 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
@@ -36,11 +36,14 @@
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.Comparator;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdds.conf.ConfigurationSource;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.ozone.conf.OMClientConfig;
@@ -49,6 +52,7 @@
import org.apache.hadoop.ozone.om.helpers.OMNodeDetails;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
import org.apache.commons.lang3.StringUtils;
@@ -795,4 +799,38 @@
printString.append("]");
return printString.toString();
}
+
+ public static String format(List<ServiceInfo> nodes, int port,
+ String leaderId) {
+ StringBuilder sb = new StringBuilder();
+ // Ensuring OM's are printed in correct order
+ List<ServiceInfo> omNodes = nodes.stream()
+ .filter(node -> node.getNodeType() == HddsProtos.NodeType.OM)
+ .sorted(Comparator.comparing(ServiceInfo::getHostname))
+ .collect(Collectors.toList());
+ int count = 0;
+ for (ServiceInfo info : omNodes) {
+ // Printing only the OM's running
+ if (info.getNodeType() == HddsProtos.NodeType.OM) {
+ String role =
+ info.getOmRoleInfo().getNodeId().equals(leaderId) ? "LEADER" :
+ "FOLLOWER";
+ sb.append(
+ String.format(
+ " { HostName: %s | Node-Id: %s | Ratis-Port : %d | Role: %s} ",
+ info.getHostname(),
+ info.getOmRoleInfo().getNodeId(),
+ port,
+ role
+ ));
+ count++;
+ }
+ }
+ // Print Stand-alone if only one OM exists
+ if (count == 1) {
+ return "STANDALONE";
+ } else {
+ return sb.toString();
+ }
+ }
}
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMXBean.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMXBean.java
index f378a8a..791379b 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMXBean.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMXBean.java
@@ -29,6 +29,8 @@
String getRpcPort();
+ String getRatisRoles();
+
String getRatisLogDirectory();
String getRocksDbDirectory();
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index 7ddaca5..2898fc8 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -279,6 +279,7 @@
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse.PrepareStatus;
import org.apache.ratis.proto.RaftProtos.RaftPeerRole;
import org.apache.ratis.protocol.RaftGroupId;
+import org.apache.ratis.protocol.RaftPeer;
import org.apache.ratis.protocol.RaftPeerId;
import org.apache.ratis.server.protocol.TermIndex;
import org.apache.ratis.util.ExitUtils;
@@ -2985,6 +2986,24 @@
}
@Override
+ public String getRatisRoles() {
+ List<ServiceInfo> serviceList = null;
+ int port = omNodeDetails.getRatisPort();
+ RaftPeer leaderId;
+ if (isRatisEnabled) {
+ try {
+ leaderId = omRatisServer.getLeader();
+ serviceList = getServiceList();
+ } catch (IOException e) {
+ LOG.error("IO-Exception Occurred", e);
+ return "Exception: " + e.toString();
+ }
+ return OmUtils.format(serviceList, port, leaderId.getId().toString());
+ } else {
+ return "Ratis-Disabled";
+ }
+ }
+
public String getRatisLogDirectory() {
return OzoneManagerRatisUtils.getOMRatisDirectory(configuration);
}
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java
index 5ee7b27..92b685d 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java
@@ -82,6 +82,7 @@
import org.apache.ratis.server.RaftServer;
import org.apache.ratis.server.RaftServerConfigKeys;
import org.apache.ratis.server.protocol.TermIndex;
+import org.apache.ratis.thirdparty.com.google.protobuf.ByteString;
import org.apache.ratis.util.LifeCycle;
import org.apache.ratis.util.SizeInBytes;
import org.apache.ratis.util.StringUtils;
@@ -728,6 +729,18 @@
.getPropsMatchPrefixAndTrimPrefix(OZONE_OM_HA_PREFIX + ".");
}
+ public RaftPeer getLeader() throws IOException {
+ RaftServer.Division division = server.getDivision(raftGroupId);
+ if (division.getInfo().isLeader()) {
+ return division.getPeer();
+ } else {
+ ByteString leaderId = division.getInfo().getRoleInfoProto()
+ .getFollowerInfo().getLeaderInfo().getId().getId();
+ return leaderId.isEmpty() ? null :
+ division.getRaftConf().getPeer(RaftPeerId.valueOf(leaderId));
+ }
+ }
+
/**
* Defines RaftServer Status.
*/
diff --git a/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/om-overview.html b/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/om-overview.html
index 66bcfd8..8a54aa0 100644
--- a/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/om-overview.html
+++ b/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/om-overview.html
@@ -22,6 +22,26 @@
<td>Rpc port</td>
<td>{{$ctrl.overview.jmx.RpcPort}}</td>
</tr>
+ <tr>
+ <td>OM Roles (HA) </td>
+ <td>{{$ctrl.overview.jmx.RatisRoles}}</td>
+ </tr>
+ <tr>
+ <td>Current-Role</td>
+ <td>{{$ctrl.role.Role}}</td>
+ </tr>
+ <tr>
+ <td>Group-Id</td>
+ <td>{{$ctrl.role.GroupId}}</td>
+ </tr>
+ <tr ng-hide="!$ctrl.electionCount.Count || $ctrl.electionCount.Count==-1">
+ <td>Election-Count</td>
+ <td>{{$ctrl.electionCount.Count}}</td>
+ </tr>
+ <tr ng-hide="!$ctrl.elapsedTime.Value || $ctrl.elapsedTime.Value==-1">
+ <td>Last Election Elapsed Time</td>
+ <td>{{$ctrl.elapsedTime.Value}}</td>
+ </tr>
</tbody>
</table>
diff --git a/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/ozoneManager.js b/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/ozoneManager.js
index 6c59a5b..bd402b1 100644
--- a/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/ozoneManager.js
+++ b/hadoop-ozone/ozone-manager/src/main/resources/webapps/ozoneManager/ozoneManager.js
@@ -113,5 +113,35 @@
require: {
overview: "^overview"
},
+ controller: function ($http) {
+ var ctrl = this;
+ $http.get("jmx?qry=Ratis:service=RaftServer,group=*,id=*")
+ .then(function (result) {
+ ctrl.role = result.data.beans[0];
+ });
+
+ $http.get("jmx?qry=ratis:name=ratis.leader_election.*electionCount")
+ .then(function (result) {
+ ctrl.electionCount = result.data.beans[0];
+ });
+
+ $http.get("jmx?qry=ratis:name=ratis.leader_election.*lastLeaderElectionElapsedTime")
+ .then(function (result) {
+ ctrl.elapsedTime = result.data.beans[0];
+ if(ctrl.elapsedTime.Value != -1){
+ ctrl.elapsedTime.Value = convertMsToTime(ctrl.elapsedTime.Value);
+ }
+ });
+ }
});
+ function convertMsToTime(ms) {
+ let seconds = (ms / 1000).toFixed(1);
+ let minutes = (ms / (1000 * 60)).toFixed(1);
+ let hours = (ms / (1000 * 60 * 60)).toFixed(1);
+ let days = (ms / (1000 * 60 * 60 * 24)).toFixed(1);
+ if (seconds < 60) return seconds + " Seconds";
+ else if (minutes < 60) return minutes + " Minutes";
+ else if (hours < 24) return hours + " Hours";
+ else return days + " Days"
+ }
})();