This is an automated email from the ASF dual-hosted git repository.

nihaljain pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-3 by this push:
     new 5129cbe3a6a HBASE-27814 Add support for dump and process metrics 
servlet in REST InfoServer (#5215)
5129cbe3a6a is described below

commit 5129cbe3a6aa90e8e5112b65d007893bcec126a8
Author: Nihal Jain <nihalj...@apache.org>
AuthorDate: Sun Jan 14 11:59:26 2024 +0530

    HBASE-27814 Add support for dump and process metrics servlet in REST 
InfoServer (#5215)
    
    Other changes:
    - Ensure info server stops during stop()
    - Extract header and footer. This would fix the log level page layout for 
rest web UI (See HBASE-20693)
    - Add hostname in the landing page instead of just port similar to other 
web UIs
    
    Signed-off-by: Nick Dimiduk <ndimi...@apache.org>
    (cherry picked from commit a683fcfbe8c5c84e58fa8670f4414f9d01ff43ed)
---
 .../apache/hadoop/hbase/rest/RESTDumpServlet.java  |  80 +++++++++
 .../org/apache/hadoop/hbase/rest/RESTServer.java   |  39 ++++-
 .../main/resources/hbase-webapps/rest/footer.jsp   |  32 ++++
 .../main/resources/hbase-webapps/rest/header.jsp   |  74 +++++++++
 .../resources/hbase-webapps/rest/processRest.jsp   | 184 +++++++++++++++++++++
 .../src/main/resources/hbase-webapps/rest/rest.jsp |  80 ++-------
 6 files changed, 422 insertions(+), 67 deletions(-)

diff --git 
a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTDumpServlet.java 
b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTDumpServlet.java
new file mode 100644
index 00000000000..8bb306f7829
--- /dev/null
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTDumpServlet.java
@@ -0,0 +1,80 @@
+/*
+ * 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.hadoop.hbase.rest;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.Date;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.http.HttpServer;
+import org.apache.hadoop.hbase.monitoring.StateDumpServlet;
+import org.apache.hadoop.hbase.util.LogMonitoring;
+import org.apache.hadoop.hbase.util.Threads;
+import org.apache.yetus.audience.InterfaceAudience;
+
+@InterfaceAudience.Private
+public class RESTDumpServlet extends StateDumpServlet {
+  private static final long serialVersionUID = 1L;
+  private static final String LINE = 
"===========================================================";
+
+  @Override
+  public void doGet(HttpServletRequest request, HttpServletResponse response) 
throws IOException {
+    if (!HttpServer.isInstrumentationAccessAllowed(getServletContext(), 
request, response)) {
+      return;
+    }
+
+    RESTServer restServer = (RESTServer) 
getServletContext().getAttribute(RESTServer.REST_SERVER);
+    assert restServer != null : "No REST Server in context!";
+
+    response.setContentType("text/plain");
+    OutputStream os = response.getOutputStream();
+    try (PrintWriter out = new PrintWriter(os)) {
+
+      out.println("REST Server status for " + restServer.getServerName() + " 
as of " + new Date());
+
+      out.println("\n\nVersion Info:");
+      out.println(LINE);
+      dumpVersionInfo(out);
+
+      out.println("\n\nStacks:");
+      out.println(LINE);
+      out.flush();
+      PrintStream ps = new PrintStream(response.getOutputStream(), false, 
"UTF-8");
+      Threads.printThreadInfo(ps, "");
+      ps.flush();
+
+      out.println("\n\nREST Server configuration:");
+      out.println(LINE);
+      Configuration conf = restServer.conf;
+      out.flush();
+      conf.writeXml(os);
+      os.flush();
+
+      out.println("\n\nLogs");
+      out.println(LINE);
+      long tailKb = getTailKbParam(request);
+      LogMonitoring.dumpTailOfLogs(out, tailKb);
+
+      out.flush();
+    }
+  }
+}
diff --git 
a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java 
b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
index 886c81dc668..42c00480526 100644
--- a/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
+++ b/hbase-rest/src/main/java/org/apache/hadoop/hbase/rest/RESTServer.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hbase.rest;
 
 import java.lang.management.ManagementFactory;
+import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
@@ -29,6 +30,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseInterfaceAudience;
+import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.http.ClickjackingPreventionFilter;
 import org.apache.hadoop.hbase.http.HttpServerUtil;
 import org.apache.hadoop.hbase.http.InfoServer;
@@ -83,6 +85,7 @@ import 
org.apache.hbase.thirdparty.org.glassfish.jersey.servlet.ServletContainer
 @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
 public class RESTServer implements Constants {
   static Logger LOG = LoggerFactory.getLogger("RESTServer");
+  public static final String REST_SERVER = "rest";
 
   static final String REST_CSRF_ENABLED_KEY = "hbase.rest.csrf.enabled";
   static final boolean REST_CSRF_ENABLED_DEFAULT = false;
@@ -112,6 +115,7 @@ public class RESTServer implements Constants {
   private final UserProvider userProvider;
   private Server server;
   private InfoServer infoServer;
+  private ServerName serverName;
 
   public RESTServer(Configuration conf) {
     RESTServer.conf = conf;
@@ -163,8 +167,7 @@ public class RESTServer implements Constants {
     loginServerPrincipal(UserProvider userProvider, Configuration conf) throws 
Exception {
     Class<? extends ServletContainer> containerClass = ServletContainer.class;
     if (userProvider.isHadoopSecurityEnabled() && 
userProvider.isHBaseSecurityEnabled()) {
-      String machineName = 
Strings.domainNamePointerToHostName(DNS.getDefaultHost(
-        conf.get(REST_DNS_INTERFACE, "default"), conf.get(REST_DNS_NAMESERVER, 
"default")));
+      String machineName = getHostName(conf);
       String keytabFilename = conf.get(REST_KEYTAB_FILE);
       Preconditions.checkArgument(keytabFilename != null && 
!keytabFilename.isEmpty(),
         REST_KEYTAB_FILE + " should be set if security is enabled");
@@ -402,9 +405,14 @@ public class RESTServer implements Constants {
     // Put up info server.
     int port = conf.getInt("hbase.rest.info.port", 8085);
     if (port >= 0) {
-      conf.setLong("startcode", EnvironmentEdgeManager.currentTime());
-      String a = conf.get("hbase.rest.info.bindAddress", "0.0.0.0");
-      this.infoServer = new InfoServer("rest", a, port, false, conf);
+      final long startCode = EnvironmentEdgeManager.currentTime();
+      conf.setLong("startcode", startCode);
+      this.serverName = ServerName.valueOf(getHostName(conf), servicePort, 
startCode);
+
+      String addr = conf.get("hbase.rest.info.bindAddress", "0.0.0.0");
+      this.infoServer = new InfoServer(REST_SERVER, addr, port, false, conf);
+      this.infoServer.addPrivilegedServlet("dump", "/dump", 
RESTDumpServlet.class);
+      this.infoServer.setAttribute(REST_SERVER, this);
       this.infoServer.setAttribute("hbase.conf", conf);
       this.infoServer.start();
     }
@@ -412,6 +420,11 @@ public class RESTServer implements Constants {
     server.start();
   }
 
+  private static String getHostName(Configuration conf) throws 
UnknownHostException {
+    return Strings.domainNamePointerToHostName(DNS.getDefaultHost(
+      conf.get(REST_DNS_INTERFACE, "default"), conf.get(REST_DNS_NAMESERVER, 
"default")));
+  }
+
   public synchronized void join() throws Exception {
     if (server == null) {
       throw new IllegalStateException("Server is not running");
@@ -419,7 +432,19 @@ public class RESTServer implements Constants {
     server.join();
   }
 
+  private void stopInfoServer() {
+    if (this.infoServer != null) {
+      LOG.info("Stop info server");
+      try {
+        this.infoServer.stop();
+      } catch (Exception e) {
+        LOG.error("Failed to stop infoServer", e);
+      }
+    }
+  }
+
   public synchronized void stop() throws Exception {
+    stopInfoServer();
     if (server == null) {
       throw new IllegalStateException("Server is not running");
     }
@@ -443,6 +468,10 @@ public class RESTServer implements Constants {
     return infoServer.getPort();
   }
 
+  public ServerName getServerName() {
+    return serverName;
+  }
+
   public Configuration getConf() {
     return conf;
   }
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/footer.jsp 
b/hbase-rest/src/main/resources/hbase-webapps/rest/footer.jsp
new file mode 100644
index 00000000000..a642ac36eff
--- /dev/null
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/footer.jsp
@@ -0,0 +1,32 @@
+<%--
+/**
+* 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.
+*/
+--%>
+
+    <script src="/static/js/jquery.min.js" type="text/javascript"></script>
+    <script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
+    <script src="/static/js/tab.js" type="text/javascript"></script>
+    <script type="text/javascript">
+      $(document).ready(function() {
+        $('div.navbar li.active').removeClass('active');
+        $('a[href="' + location.pathname + 
'"]').closest('li').addClass('active');
+      });
+    </script>
+</body>
+</html>
+
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/header.jsp 
b/hbase-rest/src/main/resources/hbase-webapps/rest/header.jsp
new file mode 100644
index 00000000000..67f7656de59
--- /dev/null
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/header.jsp
@@ -0,0 +1,74 @@
+<%--
+/**
+* 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.
+*/
+--%>
+<%@ page contentType="text/html;charset=UTF-8"
+         import="org.apache.hadoop.hbase.HBaseConfiguration"%>
+
+<!DOCTYPE html>
+<?xml version="1.0" encoding="UTF-8" ?>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <title><%= request.getParameter("pageTitle")%></title>
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta name="description" content="">
+
+  <link href="/static/css/bootstrap.min.css" rel="stylesheet">
+  <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
+  <link href="/static/css/hbase.css" rel="stylesheet">
+</head>
+
+<body>
+<div class="navbar  navbar-fixed-top navbar-default">
+  <div class="container-fluid">
+    <div class="navbar-header">
+      <button type="button" class="navbar-toggle" data-toggle="collapse" 
data-target=".navbar-collapse">
+        <span class="icon-bar"></span>
+        <span class="icon-bar"></span>
+        <span class="icon-bar"></span>
+      </button>
+      <a class="navbar-brand" href="/rest.jsp"><img 
src="/static/hbase_logo_small.png" alt="HBase Logo"/></a>
+    </div>
+    <div class="collapse navbar-collapse">
+      <ul class="nav navbar-nav">
+        <li class="active"><a href="/rest.jsp">Home</a></li>
+        <li><a href="/logs/">Local logs</a></li>
+        <li><a href="/processRest.jsp">Process Metrics</a></li>
+        <li><a href="/logLevel">Log Level</a></li>
+        <li><a href="/dump">Debug Dump</a></li>
+        <li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" 
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" 
aria-expanded="false">
+            Metrics <span class="caret"></span>
+          </a>
+          <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
+            <li><a target="_blank" href="/jmx">JMX</a></li>
+            <li><a target="_blank" href="/jmx?description=true">JMX with 
description</a></li>
+            <li><a target="_blank" href="/prometheus">Prometheus</a></li>
+            <li><a target="_blank" 
href="/prometheus?description=true">Prometheus with description</a></li>
+          </ul>
+        </li>
+        <li><a href="/prof">Profiler</a></li>
+        <% if (HBaseConfiguration.isShowConfInServlet()) { %>
+        <li><a href="/conf">HBase Configuration</a></li>
+        <% } %>
+      </ul>
+    </div><!--/.nav-collapse -->
+  </div>
+</div>
+
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/processRest.jsp 
b/hbase-rest/src/main/resources/hbase-webapps/rest/processRest.jsp
new file mode 100644
index 00000000000..2b2d35fbfb3
--- /dev/null
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/processRest.jsp
@@ -0,0 +1,184 @@
+<%--
+/**
+ * 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.
+ */
+--%>
+<%@ page contentType="text/html;charset=UTF-8"
+  import="java.util.Date"
+  import="java.util.List"
+  import="javax.management.ObjectName"
+  import="java.lang.management.ManagementFactory"
+  import="java.lang.management.MemoryPoolMXBean"
+  import="java.lang.management.RuntimeMXBean"
+  import="java.lang.management.GarbageCollectorMXBean"
+  import="org.apache.hadoop.hbase.util.JSONMetricUtil"
+  import="org.apache.hadoop.hbase.procedure2.util.StringUtils"
+  import="org.apache.hadoop.util.StringUtils.TraditionalBinaryPrefix"
+%>
+
+<%
+RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
+ObjectName jvmMetrics = new ObjectName("Hadoop:service=HBase,name=JvmMetrics");
+
+// There is always two of GC collectors
+List<GarbageCollectorMXBean> gcBeans = JSONMetricUtil.getGcCollectorBeans();
+GarbageCollectorMXBean collector1 = null;
+GarbageCollectorMXBean collector2 = null;
+try {
+collector1 = gcBeans.get(0);
+collector2 = gcBeans.get(1);
+} catch(IndexOutOfBoundsException e) {}
+List<MemoryPoolMXBean> mPools = JSONMetricUtil.getMemoryPools();
+pageContext.setAttribute("pageTitle", "Process info for PID: " + 
JSONMetricUtil.getProcessPID());
+%>
+
+<jsp:include page="header.jsp">
+  <jsp:param name="pageTitle" value="${pageTitle}"/>
+</jsp:include>
+
+<div class="container-fluid content">
+  <div class="row">
+      <div class="page-header">
+          <h1><%= JSONMetricUtil.getCommmand().split(" ")[0] %></h1>
+      </div>
+  </div>
+  <table class="table table-striped" width="90%" >
+    <tr>
+        <th>Started</th>
+        <th>Uptime</th>
+        <th>PID</th>
+        <th>Owner</th>
+    </tr>
+    <tr>
+      <tr>
+        <td><%= new Date(runtimeBean.getStartTime()) %></td>
+        <td><%= StringUtils.humanTimeDiff(runtimeBean.getUptime()) %></td>
+        <td><%= JSONMetricUtil.getProcessPID() %></td>
+        <td><%= runtimeBean.getSystemProperties().get("user.name") %></td>
+      </tr>
+  </table>
+</div>
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+    <h2>Threads</h2>
+    </div>
+    </div>
+  <table class="table table-striped" width="90%" >
+    <tr>
+        <th>ThreadsNew</th>
+        <th>ThreadsRunable</th>
+        <th>ThreadsBlocked</th>
+        <th>ThreadsWaiting</th>
+        <th>ThreadsTimeWaiting</th>
+        <th>ThreadsTerminated</th>
+    </tr>
+     <tr>
+        <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics, "ThreadsNew")  
%></td>
+        <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics, 
"ThreadsRunnable")%></td>
+        <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics, 
"ThreadsBlocked")%></td>
+        <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics, 
"ThreadsWaiting")%></td>
+        <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics, 
"ThreadsTimedWaiting")%></td>
+        <td><%= JSONMetricUtil.getValueFromMBean(jvmMetrics, 
"ThreadsTerminated")%></td>
+     </tr>
+  </table>
+</div>
+<div class="container-fluid content">
+  <div class="row">
+    <div class="page-header">
+    <h2>GC Collectors</h2>
+    </div>
+    </div>
+    <% if (gcBeans.size() == 2) { %>
+<div class="tabbable">
+  <ul class="nav nav-pills">
+    <li class="active">
+      <a href="#tab_gc1" data-toggle="tab"><%=collector1.getName() %></a>
+    </li>
+    <li class="">
+      <a href="#tab_gc2" data-toggle="tab"><%=collector2.getName() %></a>
+     </li>
+  </ul>
+    <div class="tab-content" style="padding-bottom: 9px; border-bottom: 1px 
solid #ddd;">
+      <div class="tab-pane active" id="tab_gc1">
+          <table class="table table-striped">
+            <tr>
+              <th>Collection Count</th>
+              <th>Collection Time</th>
+              <th>Last duration</th>
+            </tr>
+            <tr>
+              <td> <%= collector1.getCollectionCount() %></td>
+              <td> <%= 
StringUtils.humanTimeDiff(collector1.getCollectionTime()) %> </td>
+              <td> <%= 
StringUtils.humanTimeDiff(JSONMetricUtil.getLastGcDuration(
+                collector1.getObjectName())) %></td>
+            </tr>
+          </table>
+      </div>
+      <div class="tab-pane" id="tab_gc2">
+        <table class="table table-striped">
+          <tr>
+            <th>Collection Count</th>
+            <th>Collection Time</th>
+             <th>Last duration</th>
+          </tr>
+          <tr>
+            <td> <%= collector2.getCollectionCount()  %></td>
+            <td> <%= StringUtils.humanTimeDiff(collector2.getCollectionTime()) 
%> </td>
+            <td> <%= 
StringUtils.humanTimeDiff(JSONMetricUtil.getLastGcDuration(
+              collector2.getObjectName())) %></td>
+          </tr>
+          </table>
+      </div>
+      </div>
+  </div>
+  <%} else { %>
+  <p> Can not display GC Collector stats.</p>
+  <%} %>
+  Total GC Collection time: <%= 
StringUtils.humanTimeDiff(collector1.getCollectionTime() +
+    collector2.getCollectionTime())%>
+</div>
+<% for(MemoryPoolMXBean mp:mPools) {
+if(mp.getName().contains("Cache")) continue;%>
+<div class="container-fluid content">
+  <div class="row">
+      <div class="page-header">
+          <h2><%= mp.getName() %></h2>
+      </div>
+  </div>
+  <table class="table table-striped" width="90%" >
+    <tr>
+        <th>Commited</th>
+        <th>Init</th>
+        <th>Max</th>
+        <th>Used</th>
+        <th>Utilization [%]</th>
+    </tr>
+    <tr>
+      <tr>
+        <td><%= 
TraditionalBinaryPrefix.long2String(mp.getUsage().getCommitted(), "B", 1) 
%></td>
+        <td><%= TraditionalBinaryPrefix.long2String(mp.getUsage().getInit(), 
"B", 1) %></td>
+        <td><%= TraditionalBinaryPrefix.long2String(mp.getUsage().getMax(), 
"B", 1) %></td>
+        <td><%= TraditionalBinaryPrefix.long2String(mp.getUsage().getUsed(), 
"B", 1) %></td>
+        <td><%= JSONMetricUtil.calcPercentage(mp.getUsage().getUsed(),
+          mp.getUsage().getCommitted()) %></td>
+      </tr>
+  </table>
+</div>
+<% } %>
+
+<jsp:include page="footer.jsp" />
diff --git a/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp 
b/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp
index df8f0838d6c..ce6725f283a 100644
--- a/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp
+++ b/hbase-rest/src/main/resources/hbase-webapps/rest/rest.jsp
@@ -18,70 +18,29 @@
  */
 --%>
 <%@ page contentType="text/html;charset=UTF-8"
-  import="org.apache.hadoop.conf.Configuration"
-  import="org.apache.hadoop.hbase.HBaseConfiguration"
-  import="org.apache.hadoop.hbase.rest.model.VersionModel"
-  import="org.apache.hadoop.hbase.util.VersionInfo"
-  import="java.util.Date"%>
+         import="org.apache.hadoop.conf.Configuration"
+         import="org.apache.hadoop.hbase.rest.RESTServer"
+         import="org.apache.hadoop.hbase.rest.model.VersionModel"
+         import="org.apache.hadoop.hbase.util.VersionInfo"
+         import="java.util.Date"%>
+
 <%
-Configuration conf = 
(Configuration)getServletContext().getAttribute("hbase.conf");
-long startcode = conf.getLong("startcode", System.currentTimeMillis());
-String listenPort = conf.get("hbase.rest.port", "8080");
-%>
-<!DOCTYPE html>
-<?xml version="1.0" encoding="UTF-8" ?>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <title>HBase REST Server: <%= listenPort %></title>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <meta name="description" content="">
+  Configuration conf = (Configuration) 
getServletContext().getAttribute("hbase.conf");
+  long startcode = conf.getLong("startcode", System.currentTimeMillis());
 
-    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
-    <link href="/static/css/bootstrap-theme.min.css" rel="stylesheet">
-    <link href="/static/css/hbase.css" rel="stylesheet">
-  </head>
+  final RESTServer restServer = (RESTServer) 
getServletContext().getAttribute(RESTServer.REST_SERVER);
+  final String hostName = restServer.getServerName().getHostname();
+  pageContext.setAttribute("pageTitle", "HBase REST Server" + hostName);
+%>
 
-  <body>
-  <div class="navbar  navbar-fixed-top navbar-default">
-      <div class="container-fluid">
-          <div class="navbar-header">
-              <button type="button" class="navbar-toggle" 
data-toggle="collapse" data-target=".navbar-collapse">
-                  <span class="icon-bar"></span>
-                  <span class="icon-bar"></span>
-                  <span class="icon-bar"></span>
-              </button>
-              <a class="navbar-brand" href="/rest.jsp"><img 
src="/static/hbase_logo_small.png" alt="HBase Logo"/></a>
-          </div>
-          <div class="collapse navbar-collapse">
-              <ul class="nav navbar-nav">
-                  <li class="active"><a href="/rest.jsp">Home</a></li>
-                  <li><a href="/logs/">Local logs</a></li>
-                  <li><a href="/logLevel">Log Level</a></li>
-                  <li class="nav-item dropdown">
-                    <a class="nav-link dropdown-toggle" href="#" 
id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" 
aria-expanded="false">
-                      Metrics <span class="caret"></span>
-                    </a>
-                    <ul class="dropdown-menu" 
aria-labelledby="navbarDropdownMenuLink">
-                      <li><a target="_blank" href="/jmx">JMX</a></li>
-                      <li><a target="_blank" href="/jmx?description=true">JMX 
with description</a></li>
-                      <li><a target="_blank" 
href="/prometheus">Prometheus</a></li>
-                      <li><a target="_blank" 
href="/prometheus?description=true">Prometheus with description</a></li>
-                    </ul>
-                  </li>
-                  <li><a href="/prof">Profiler</a></li>
-                  <% if (HBaseConfiguration.isShowConfInServlet()) { %>
-                  <li><a href="/conf">HBase Configuration</a></li>
-                  <% } %>
-              </ul>
-          </div><!--/.nav-collapse -->
-      </div>
-  </div>
+<jsp:include page="header.jsp">
+  <jsp:param name="pageTitle" value="${pageTitle}"/>
+</jsp:include>
 
 <div class="container-fluid content">
     <div class="row inner_header">
         <div class="page-header">
-            <h1>RESTServer <small><%= listenPort %></small></h1>
+            <h1>RESTServer <small><%= hostName %></small></h1>
         </div>
     </div>
     <div class="row">
@@ -124,9 +83,6 @@ String listenPort = conf.get("hbase.rest.port", "8080");
     </section>
     </div>
 </div>
-<script src="/static/js/jquery.min.js" type="text/javascript"></script>
-<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
-<script src="/static/js/tab.js" type="text/javascript"></script>
-</body>
-</html>
+
+<jsp:include page="footer.jsp" />
 

Reply via email to