From d115205c13105484f2d314ba3427e1c640c0ebd9 Mon Sep 17 00:00:00 2001 From: eclark Date: Mon, 22 Oct 2012 17:09:58 +0000 Subject: [PATCH] HBASE-6951 Allow the master info server to be started in a read only mode. git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1400956 13f79535-47bb-0310-9956-ffa450edef68 --- .../resources/hbase-webapps/master/table.jsp | 6 +- .../apache/hadoop/hbase/TestInfoServers.java | 59 +++++++++++++++---- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp index 8d06aa3cff9..492052f3f15 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp @@ -42,6 +42,7 @@ String tableHeader = "

Table Regions

"; ServerName rl = master.getCatalogTracker().getRootLocation(); boolean showFragmentation = conf.getBoolean("hbase.master.ui.fragmentation.enabled", false); + boolean readOnly = conf.getBoolean("hbase.master.ui.readonly", false); Map frags = null; if (showFragmentation) { frags = FSUtils.getTableFragmentation(master); @@ -62,7 +63,7 @@ <% String action = request.getParameter("action"); String key = request.getParameter("key"); - if ( action != null ) { + if ( !readOnly && action != null ) { %> @@ -320,6 +321,8 @@ HConnectionManager.deleteConnection(hbadmin.getConfiguration(), false); %> + +<% if (!readOnly) { %>


Actions:

@@ -357,6 +360,7 @@ Actions:

+<% } %> <% } %> diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestInfoServers.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestInfoServers.java index 3aac5db3f05..4bb53cca2e5 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestInfoServers.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestInfoServers.java @@ -27,6 +27,7 @@ import java.net.URL; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.util.Bytes; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -47,6 +48,9 @@ public class TestInfoServers { // Set them to ephemeral ports so they will start UTIL.getConfiguration().setInt(HConstants.MASTER_INFO_PORT, 0); UTIL.getConfiguration().setInt(HConstants.REGIONSERVER_INFO_PORT, 0); + + //We need to make sure that the server can be started as read only. + UTIL.getConfiguration().setBoolean("hbase.master.ui.readonly", true); UTIL.startMiniCluster(); } @@ -63,12 +67,12 @@ public class TestInfoServers { // give the cluster time to start up new HTable(UTIL.getConfiguration(), ".META.").close(); int port = UTIL.getHBaseCluster().getMaster().getInfoServer().getPort(); - assertHasExpectedContent(new URL("http://localhost:" + port + - "/index.html"), "master-status"); + assertContainsContent(new URL("http://localhost:" + port + + "/index.html"), "master-status"); port = UTIL.getHBaseCluster().getRegionServerThreads().get(0).getRegionServer(). getInfoServer().getPort(); - assertHasExpectedContent(new URL("http://localhost:" + port + - "/index.html"), "rs-status"); + assertContainsContent(new URL("http://localhost:" + port + + "/index.html"), "rs-status"); } /** @@ -83,17 +87,49 @@ public class TestInfoServers { // give the cluster time to start up new HTable(UTIL.getConfiguration(), ".META.").close(); int port = UTIL.getHBaseCluster().getMaster().getInfoServer().getPort(); - assertHasExpectedContent(new URL("http://localhost:" + port + - "/master-status"), "META"); + assertContainsContent(new URL("http://localhost:" + port + + "/master-status"), "META"); port = UTIL.getHBaseCluster().getRegionServerThreads().get(0).getRegionServer(). getInfoServer().getPort(); - assertHasExpectedContent(new URL("http://localhost:" + port + - "/rs-status"), "META"); + assertContainsContent(new URL("http://localhost:" + port + + "/rs-status"), "META"); } - private void assertHasExpectedContent(final URL u, final String expected) + @Test + public void testMasterServerReadOnly() throws Exception { + String sTableName = "testMasterServerReadOnly"; + byte[] tableName = Bytes.toBytes(sTableName); + byte[] cf = Bytes.toBytes("d"); + UTIL.createTable(tableName, cf); + new HTable(UTIL.getConfiguration(), tableName).close(); + int port = UTIL.getHBaseCluster().getMaster().getInfoServer().getPort(); + assertDoesNotContainContent( + new URL("http://localhost:" + port + "/table.jsp?name=" + sTableName + "&action=split&key="), + "Table action request accepted"); + assertDoesNotContainContent( + new URL("http://localhost:" + port + "/table.jsp?name=" + sTableName), + "Actions:"); + } + + private void assertContainsContent(final URL u, final String expected) throws IOException { LOG.info("Testing " + u.toString() + " has " + expected); + String content = getUrlContent(u); + assertTrue("expected=" + expected + ", content=" + content, + content.contains(expected)); + } + + + + private void assertDoesNotContainContent(final URL u, final String expected) + throws IOException { + LOG.info("Testing " + u.toString() + " has " + expected); + String content = getUrlContent(u); + assertTrue("Does Not Contain =" + expected + ", content=" + content, + !content.contains(expected)); + } + + private String getUrlContent(URL u) throws IOException { java.net.URLConnection c = u.openConnection(); c.connect(); StringBuilder sb = new StringBuilder(); @@ -103,9 +139,6 @@ public class TestInfoServers { sb.append(new String(bytes, 0, read)); } bis.close(); - String content = sb.toString(); - assertTrue("expected=" + expected + ", content=" + content, - content.contains(expected)); + return sb.toString(); } - }

NameRegion ServerStart KeyEnd KeyRequests