diff --git a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java index 91b2615b81b9..611316d9ec67 100644 --- a/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java +++ b/hbase-http/src/main/java/org/apache/hadoop/hbase/http/log/LogLevel.java @@ -22,8 +22,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; +import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.Objects; import java.util.regex.Pattern; @@ -41,6 +41,7 @@ import org.apache.hadoop.security.authentication.client.AuthenticatedURL; import org.apache.hadoop.security.authentication.client.KerberosAuthenticator; import org.apache.hadoop.security.ssl.SSLFactory; +import org.apache.hadoop.util.HttpExceptionUtils; import org.apache.hadoop.util.ServletUtil; import org.apache.hadoop.util.Tool; import org.apache.yetus.audience.InterfaceAudience; @@ -59,6 +60,8 @@ public final class LogLevel { public static final String PROTOCOL_HTTP = "http"; public static final String PROTOCOL_HTTPS = "https"; + public static final String READONLY_LOGGERS_CONF_KEY = "hbase.ui.logLevels.readonly.loggers"; + /** * A command line implementation */ @@ -247,11 +250,11 @@ private void doSetLevel() throws Exception { * @return a connected connection * @throws Exception if it can not establish a connection. */ - private URLConnection connect(URL url) throws Exception { + private HttpURLConnection connect(URL url) throws Exception { AuthenticatedURL.Token token = new AuthenticatedURL.Token(); AuthenticatedURL aUrl; SSLFactory clientSslFactory; - URLConnection connection; + HttpURLConnection connection; // If https is chosen, configures SSL client. if (PROTOCOL_HTTPS.equals(url.getProtocol())) { clientSslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, this.getConf()); @@ -280,7 +283,9 @@ private void process(String urlString) throws Exception { URL url = new URL(urlString); System.out.println("Connecting to " + url); - URLConnection connection = connect(url); + HttpURLConnection connection = connect(url); + + HttpExceptionUtils.validateResponse(connection, 200); // read from the servlet @@ -317,8 +322,10 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) Configuration conf = (Configuration) getServletContext().getAttribute( HttpServer.CONF_CONTEXT_ATTRIBUTE); if (conf.getBoolean("hbase.master.ui.readonly", false)) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Modification of HBase via" - + " the UI is disallowed in configuration."); + sendError( + response, + HttpServletResponse.SC_FORBIDDEN, + "Modification of HBase via the UI is disallowed in configuration."); return; } response.setContentType("text/html"); @@ -336,6 +343,8 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) String logName = ServletUtil.getParameter(request, "log"); String level = ServletUtil.getParameter(request, "level"); + String[] readOnlyLogLevels = conf.getStrings(READONLY_LOGGERS_CONF_KEY); + if (logName != null) { out.println("
Results:
"); out.println(MARKER @@ -345,6 +354,14 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) out.println(MARKER + "Log Class: " + log.getClass().getName() +""
diff --git a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java
index 421cbbde6935..acbcb55d5dbb 100644
--- a/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java
+++ b/hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java
@@ -24,12 +24,14 @@
 import static org.junit.Assert.fail;
 
 import java.io.File;
+import java.io.IOException;
 import java.net.BindException;
 import java.net.SocketException;
 import java.net.URI;
 import java.security.PrivilegedExceptionAction;
 import java.util.Properties;
 import javax.net.ssl.SSLException;
+import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.io.FileUtils;
 import org.apache.hadoop.HadoopIllegalArgumentException;
 import org.apache.hadoop.conf.Configuration;
@@ -73,6 +75,8 @@ public class TestLogLevel {
   private static Configuration clientConf;
   private static Configuration sslConf;
   private static final String logName = TestLogLevel.class.getName();
+  private static final String protectedPrefix = "protected";
+  private static final String protectedLogName = protectedPrefix + "." + logName;
   private static final org.apache.logging.log4j.Logger log =
     org.apache.logging.log4j.LogManager.getLogger(logName);
   private final static String PRINCIPAL = "loglevel.principal";
@@ -89,6 +93,7 @@ public class TestLogLevel {
   @BeforeClass
   public static void setUp() throws Exception {
     serverConf = new Configuration();
+    serverConf.setStrings(LogLevel.READONLY_LOGGERS_CONF_KEY, protectedPrefix);
     HTU = new HBaseCommonTestingUtil(serverConf);
 
     File keystoreDir = new File(HTU.getDataTestDir("keystore").toString());
@@ -259,9 +264,17 @@ private HttpServer createServer(String protocol, boolean isSpnego) throws Except
   private void testDynamicLogLevel(final String bindProtocol, final String connectProtocol,
     final boolean isSpnego) throws Exception {
     testDynamicLogLevel(bindProtocol, connectProtocol, isSpnego,
+      logName,
       org.apache.logging.log4j.Level.DEBUG.toString());
   }
 
+  private void testDynamicLogLevel(final String bindProtocol, final String connectProtocol,
+    final boolean isSpnego, final String newLevel) throws Exception {
+    testDynamicLogLevel(bindProtocol, connectProtocol, isSpnego,
+      logName,
+      newLevel);
+  }
+
   /**
    * Run both client and server using the given protocol.
    * @param bindProtocol specify either http or https for server
@@ -270,13 +283,14 @@ private void testDynamicLogLevel(final String bindProtocol, final String connect
    * @throws Exception if client can't accesss server.
    */
   private void testDynamicLogLevel(final String bindProtocol, final String connectProtocol,
-    final boolean isSpnego, final String newLevel) throws Exception {
+    final boolean isSpnego, final String loggerName, final String newLevel) throws Exception {
     if (!LogLevel.isValidProtocol(bindProtocol)) {
       throw new Exception("Invalid server protocol " + bindProtocol);
     }
     if (!LogLevel.isValidProtocol(connectProtocol)) {
       throw new Exception("Invalid client protocol " + connectProtocol);
     }
+    org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(loggerName);
     org.apache.logging.log4j.Level oldLevel = log.getLevel();
     assertNotEquals("Get default Log Level which shouldn't be ERROR.",
       org.apache.logging.log4j.Level.ERROR, oldLevel);
@@ -305,8 +319,8 @@ private void testDynamicLogLevel(final String bindProtocol, final String connect
     try {
       clientUGI.doAs((PrivilegedExceptionAction