You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by dd...@apache.org on 2014/07/02 22:07:21 UTC
git commit: HBASE-11344 Hide row keys and such from the web UIs
Repository: hbase
Updated Branches:
refs/heads/master 15831cefd -> 9f8d1876a
HBASE-11344 Hide row keys and such from the web UIs
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/9f8d1876
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/9f8d1876
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/9f8d1876
Branch: refs/heads/master
Commit: 9f8d1876a0412af2d751241cde511600cf7ac164
Parents: 15831ce
Author: Devaraj Das <dd...@apache.org>
Authored: Wed Jul 2 13:07:11 2014 -0700
Committer: Devaraj Das <dd...@apache.org>
Committed: Wed Jul 2 13:07:11 2014 -0700
----------------------------------------------------------------------
dev-support/findbugs-exclude.xml | 9 ++
.../org/apache/hadoop/hbase/HRegionInfo.java | 103 +++++++++++++++++++
.../src/main/resources/hbase-default.xml | 7 ++
.../master/AssignmentManagerStatusTmpl.jamon | 4 +-
.../tmpl/regionserver/RegionListTmpl.jamon | 21 ++--
.../resources/hbase-webapps/master/table.jsp | 9 +-
.../hbase/regionserver/TestHRegionInfo.java | 68 ++++++++++++
7 files changed, 210 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/9f8d1876/dev-support/findbugs-exclude.xml
----------------------------------------------------------------------
diff --git a/dev-support/findbugs-exclude.xml b/dev-support/findbugs-exclude.xml
index b2a609a..d89f9b2 100644
--- a/dev-support/findbugs-exclude.xml
+++ b/dev-support/findbugs-exclude.xml
@@ -261,4 +261,13 @@
<Bug pattern="FE_FLOATING_POINT_EQUALITY"/>
</Match>
+ <Match>
+ <Class name="org.apache.hadoop.hbase.HRegionInfo"/>
+ <Or>
+ <Method name="getEndKeyForDisplay"/>
+ <Method name="getStartKeyForDisplay"/>
+ </Or>
+ <Bug pattern="MS_EXPOSE_REP"/>
+ </Match>
+
</FindBugsFilter>
http://git-wip-us.apache.org/repos/asf/hbase/blob/9f8d1876/hbase-client/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java
index 3e5224b..0799fc8 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java
@@ -33,9 +33,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.KeyValue.KVComparator;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.master.RegionState;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionInfo;
@@ -220,6 +222,9 @@ public class HRegionInfo implements Comparable<HRegionInfo> {
// Current TableName
private TableName tableName = null;
+ final static String DISPLAY_KEYS_KEY = "hbase.display.keys";
+ public final static byte[] HIDDEN_END_KEY = Bytes.toBytes("hidden-end-key");
+ public final static byte[] HIDDEN_START_KEY = Bytes.toBytes("hidden-start-key");
/** HRegionInfo for first meta region */
public static final HRegionInfo FIRST_META_REGIONINFO =
@@ -1123,6 +1128,104 @@ public class HRegionInfo implements Comparable<HRegionInfo> {
}
/**
+ * Get the descriptive name as {@link RegionState} does it but with hidden
+ * startkey optionally
+ * @param state
+ * @param conf
+ * @return descriptive string
+ */
+ public static String getDescriptiveNameFromRegionStateForDisplay(RegionState state,
+ Configuration conf) {
+ if (conf.getBoolean(DISPLAY_KEYS_KEY, true)) return state.toDescriptiveString();
+ String descriptiveStringFromState = state.toDescriptiveString();
+ int idx = descriptiveStringFromState.lastIndexOf(" state=");
+ String regionName = getRegionNameAsStringForDisplay(state.getRegion(), conf);
+ return regionName + descriptiveStringFromState.substring(idx);
+ }
+
+ /**
+ * Get the end key for display. Optionally hide the real end key.
+ * @param hri
+ * @param conf
+ * @return the endkey
+ */
+ public static byte[] getEndKeyForDisplay(HRegionInfo hri, Configuration conf) {
+ boolean displayKey = conf.getBoolean(DISPLAY_KEYS_KEY, true);
+ if (displayKey) return hri.getEndKey();
+ return HIDDEN_END_KEY;
+ }
+
+ /**
+ * Get the start key for display. Optionally hide the real start key.
+ * @param hri
+ * @param conf
+ * @return the startkey
+ */
+ public static byte[] getStartKeyForDisplay(HRegionInfo hri, Configuration conf) {
+ boolean displayKey = conf.getBoolean(DISPLAY_KEYS_KEY, true);
+ if (displayKey) return hri.getStartKey();
+ return HIDDEN_START_KEY;
+ }
+
+ /**
+ * Get the region name for display. Optionally hide the start key.
+ * @param hri
+ * @param conf
+ * @return region name as String
+ */
+ public static String getRegionNameAsStringForDisplay(HRegionInfo hri, Configuration conf) {
+ return Bytes.toStringBinary(getRegionNameForDisplay(hri, conf));
+ }
+
+ /**
+ * Get the region name for display. Optionally hide the start key.
+ * @param hri
+ * @param conf
+ * @return region name bytes
+ */
+ public static byte[] getRegionNameForDisplay(HRegionInfo hri, Configuration conf) {
+ boolean displayKey = conf.getBoolean(DISPLAY_KEYS_KEY, true);
+ if (displayKey || hri.getTable().equals(TableName.META_TABLE_NAME)) {
+ return hri.getRegionName();
+ } else {
+ // create a modified regionname with the startkey replaced but preserving
+ // the other parts including the encodedname.
+ try {
+ byte[][]regionNameParts = parseRegionName(hri.getRegionName());
+ regionNameParts[1] = HIDDEN_START_KEY; //replace the real startkey
+ int len = 0;
+ // get the total length
+ for (byte[] b : regionNameParts) {
+ len += b.length;
+ }
+ byte[] encodedRegionName =
+ Bytes.toBytes(encodeRegionName(hri.getRegionName()));
+ len += encodedRegionName.length;
+ //allocate some extra bytes for the delimiters and the last '.'
+ byte[] modifiedName = new byte[len + regionNameParts.length + 1];
+ int lengthSoFar = 0;
+ int loopCount = 0;
+ for (byte[] b : regionNameParts) {
+ System.arraycopy(b, 0, modifiedName, lengthSoFar, b.length);
+ lengthSoFar += b.length;
+ if (loopCount++ == 2) modifiedName[lengthSoFar++] = REPLICA_ID_DELIMITER;
+ else modifiedName[lengthSoFar++] = HConstants.DELIMITER;
+ }
+ // replace the last comma with '.'
+ modifiedName[lengthSoFar - 1] = ENC_SEPARATOR;
+ System.arraycopy(encodedRegionName, 0, modifiedName, lengthSoFar,
+ encodedRegionName.length);
+ lengthSoFar += encodedRegionName.length;
+ modifiedName[lengthSoFar] = ENC_SEPARATOR;
+ return modifiedName;
+ } catch (IOException e) {
+ //LOG.warn("Encountered exception " + e);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
* Extract a HRegionInfo and ServerName from catalog table {@link Result}.
* @param r Result to pull from
* @return A pair of the {@link HRegionInfo} and the {@link ServerName}
http://git-wip-us.apache.org/repos/asf/hbase/blob/9f8d1876/hbase-common/src/main/resources/hbase-default.xml
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/resources/hbase-default.xml b/hbase-common/src/main/resources/hbase-default.xml
index 70d20a7..33dd6f6 100644
--- a/hbase-common/src/main/resources/hbase-default.xml
+++ b/hbase-common/src/main/resources/hbase-default.xml
@@ -837,6 +837,13 @@ possible configurations would overwhelm and obscure the important.
authentication, and will abort the connection.</description>
</property>
<property>
+ <name>hbase.display.keys</name>
+ <value>true</value>
+ <description>When this is set to true the webUI and such will display all start/end keys
+ as part of the table details, region names, etc. When this is set to false,
+ the keys are hidden.</description>
+ </property>
+ <property>
<name>hbase.coprocessor.region.classes</name>
<value></value>
<description>A comma-separated list of Coprocessors that are loaded by
http://git-wip-us.apache.org/repos/asf/hbase/blob/9f8d1876/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
index 08ed672..f6ea464 100644
--- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
+++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/master/AssignmentManagerStatusTmpl.jamon
@@ -85,7 +85,9 @@ if (toRemove > 0) {
<%else>
<tr>
</%if>
- <td><% entry.getKey() %></td><td><% entry.getValue().toDescriptiveString() %></td>
+ <td><% entry.getKey() %></td><td>
+ <% HRegionInfo.getDescriptiveNameFromRegionStateForDisplay(
+ entry.getValue(), conf) %></td>
<td><% (currentTime - entry.getValue().getStamp()) %> </td></tr>
</%for>
<tr BGCOLOR="#D7DF01"> <td>Total number of Regions in Transition for more than <% ritThreshold %> milliseconds</td><td> <% numOfRITOverThreshold %></td><td></td>
http://git-wip-us.apache.org/repos/asf/hbase/blob/9f8d1876/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
index 8606b4e..7c4f1f1 100644
--- a/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
+++ b/hbase-server/src/main/jamon/org/apache/hadoop/hbase/tmpl/regionserver/RegionListTmpl.jamon
@@ -93,9 +93,12 @@
<%for HRegionInfo r: onlineRegions %>
<tr>
- <td><% r.getRegionNameAsString() %></td>
- <td><% Bytes.toStringBinary(r.getStartKey()) %></td>
- <td><% Bytes.toStringBinary(r.getEndKey()) %></td>
+ <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
+ regionServer.getConfiguration()) %></td>
+ <td><% Bytes.toStringBinary(HRegionInfo.getStartKeyForDisplay(r,
+ regionServer.getConfiguration())) %></td>
+ <td><% Bytes.toStringBinary(HRegionInfo.getEndKeyForDisplay(r,
+ regionServer.getConfiguration())) %></td>
<td><% r.getReplicaId() %></td>
</tr>
</%for>
@@ -119,7 +122,8 @@
<%java>
RegionLoad load = regionServer.createRegionLoad(r.getEncodedName());
</%java>
- <td><% r.getRegionNameAsString() %></td>
+ <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
+ regionServer.getConfiguration()) %></td>
<%if load != null %>
<td><% load.getReadRequestsCount() %></td>
<td><% load.getWriteRequestsCount() %></td>
@@ -151,7 +155,8 @@
<%java>
RegionLoad load = regionServer.createRegionLoad(r.getEncodedName());
</%java>
- <td><% r.getRegionNameAsString() %></td>
+ <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
+ regionServer.getConfiguration()) %></td>
<%if load != null %>
<td><% load.getStores() %></td>
<td><% load.getStorefiles() %></td>
@@ -189,7 +194,8 @@
((float) load.getCurrentCompactedKVs() / load.getTotalCompactingKVs())) + "%";
}
</%java>
- <td><% r.getRegionNameAsString() %></td>
+ <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
+ regionServer.getConfiguration()) %></td>
<%if load != null %>
<td><% load.getTotalCompactingKVs() %></td>
<td><% load.getCurrentCompactedKVs() %></td>
@@ -216,7 +222,8 @@
<%java>
RegionLoad load = regionServer.createRegionLoad(r.getEncodedName());
</%java>
- <td><% r.getRegionNameAsString() %></td>
+ <td><% HRegionInfo.getRegionNameAsStringForDisplay(r,
+ regionServer.getConfiguration()) %></td>
<%if load != null %>
<td><% load.getMemstoreSizeMB() %>m</td>
</%if>
http://git-wip-us.apache.org/repos/asf/hbase/blob/9f8d1876/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
----------------------------------------------------------------------
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 4fa0299..3107226 100644
--- a/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/master/table.jsp
@@ -283,7 +283,8 @@
}
%>
<tr>
- <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getRegionName())) %></td>
+ <td><%= escapeXml(Bytes.toStringBinary(HRegionInfo.getRegionNameForDisplay(regionInfo,
+ conf))) %></td>
<%
if (addr != null) {
String url = "//" + addr.getHostname() + ":" + master.getRegionServerInfoPort(addr) + "/";
@@ -298,8 +299,10 @@
<%
}
%>
- <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getStartKey())) %></td>
- <td><%= escapeXml(Bytes.toStringBinary(regionInfo.getEndKey())) %></td>
+ <td><%= escapeXml(Bytes.toStringBinary(HRegionInfo.getStartKeyForDisplay(regionInfo,
+ conf))) %></td>
+ <td><%= escapeXml(Bytes.toStringBinary(HRegionInfo.getEndKeyForDisplay(regionInfo,
+ conf))) %></td>
<td><%= req%></td>
<%
if (withReplica) {
http://git-wip-us.apache.org/repos/asf/hbase/blob/9f8d1876/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java
index db4e5cf..a9aa456 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
import java.io.IOException;
+import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseTestingUtility;
@@ -34,10 +35,12 @@ import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.master.RegionState;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionInfo;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.MD5Hash;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -254,6 +257,71 @@ public class TestHRegionInfo {
assertEquals(expectedHri, convertedHri);
}
+ @Test
+ public void testRegionDetailsForDisplay() throws IOException {
+ byte[] startKey = new byte[] {0x01, 0x01, 0x02, 0x03};
+ byte[] endKey = new byte[] {0x01, 0x01, 0x02, 0x04};
+ Configuration conf = new Configuration();
+ conf.setBoolean("hbase.display.keys", false);
+ HRegionInfo h = new HRegionInfo(TableName.valueOf("foo"), startKey, endKey);
+ checkEquality(h, conf);
+ // check HRIs with non-default replicaId
+ h = new HRegionInfo(TableName.valueOf("foo"), startKey, endKey, false,
+ System.currentTimeMillis(), 1);
+ checkEquality(h, conf);
+ Assert.assertArrayEquals(HRegionInfo.HIDDEN_END_KEY,
+ HRegionInfo.getEndKeyForDisplay(h, conf));
+ Assert.assertArrayEquals(HRegionInfo.HIDDEN_START_KEY,
+ HRegionInfo.getStartKeyForDisplay(h, conf));
+
+ RegionState state = new RegionState(h, RegionState.State.OPEN);
+ String descriptiveNameForDisplay =
+ HRegionInfo.getDescriptiveNameFromRegionStateForDisplay(state, conf);
+ checkDescriptiveNameEquality(descriptiveNameForDisplay,state.toDescriptiveString(), startKey);
+
+ conf.setBoolean("hbase.display.keys", true);
+ Assert.assertArrayEquals(endKey, HRegionInfo.getEndKeyForDisplay(h, conf));
+ Assert.assertArrayEquals(startKey, HRegionInfo.getStartKeyForDisplay(h, conf));
+ Assert.assertEquals(state.toDescriptiveString(),
+ HRegionInfo.getDescriptiveNameFromRegionStateForDisplay(state, conf));
+ }
+
+ private void checkDescriptiveNameEquality(String descriptiveNameForDisplay, String origDesc,
+ byte[] startKey) {
+ // except for the "hidden-start-key" substring everything else should exactly match
+ String firstPart = descriptiveNameForDisplay.substring(0,
+ descriptiveNameForDisplay.indexOf(new String(HRegionInfo.HIDDEN_START_KEY)));
+ String secondPart = descriptiveNameForDisplay.substring(
+ descriptiveNameForDisplay.indexOf(new String(HRegionInfo.HIDDEN_START_KEY)) +
+ HRegionInfo.HIDDEN_START_KEY.length);
+ String firstPartOrig = origDesc.substring(0,
+ origDesc.indexOf(Bytes.toStringBinary(startKey)));
+ String secondPartOrig = origDesc.substring(
+ origDesc.indexOf(Bytes.toStringBinary(startKey)) +
+ Bytes.toStringBinary(startKey).length());
+ assert(firstPart.equals(firstPartOrig));
+ assert(secondPart.equals(secondPartOrig));
+ }
+ private void checkEquality(HRegionInfo h, Configuration conf) throws IOException {
+ byte[] modifiedRegionName = HRegionInfo.getRegionNameForDisplay(h, conf);
+ byte[][] modifiedRegionNameParts = HRegionInfo.parseRegionName(modifiedRegionName);
+ byte[][] regionNameParts = HRegionInfo.parseRegionName(h.getRegionName());
+
+ //same number of parts
+ assert(modifiedRegionNameParts.length == regionNameParts.length);
+
+ for (int i = 0; i < regionNameParts.length; i++) {
+ // all parts should match except for [1] where in the modified one,
+ // we should have "hidden_start_key"
+ if (i != 1) {
+ Assert.assertArrayEquals(regionNameParts[i], modifiedRegionNameParts[i]);
+ } else {
+ Assert.assertNotEquals(regionNameParts[i][0], modifiedRegionNameParts[i][0]);
+ Assert.assertArrayEquals(modifiedRegionNameParts[1],
+ HRegionInfo.getStartKeyForDisplay(h, conf));
+ }
+ }
+ }
}