You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by an...@apache.org on 2013/12/18 17:55:18 UTC
svn commit: r1552021 - in /hbase/trunk/hbase-server/src:
main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java
test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java
Author: anoopsamjohn
Date: Wed Dec 18 16:55:18 2013
New Revision: 1552021
URL: http://svn.apache.org/r1552021
Log:
HBASE-10148 [VisibilityController] Tolerate regions in recovery
Modified:
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java?rev=1552021&r1=1552020&r2=1552021&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java Wed Dec 18 16:55:18 2013
@@ -45,6 +45,7 @@ import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
@@ -62,6 +63,7 @@ import org.apache.hadoop.hbase.client.Pu
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
+import org.apache.hadoop.hbase.coprocessor.CoprocessorException;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
@@ -141,6 +143,7 @@ public class VisibilityController extend
// Flag denoting whether AcessController is available or not.
private boolean acOn = false;
private Configuration conf;
+ private volatile boolean initialized = false;
/** Mapping of scanner instances to the user who created them */
private Map<InternalScanner,String> scannerOwners =
@@ -209,6 +212,8 @@ public class VisibilityController extend
// the system.
labelsTable.setValue(HTableDescriptor.SPLIT_POLICY,
DisabledRegionSplitPolicy.class.getName());
+ labelsTable.setValue(Bytes.toBytes(HConstants.DISALLOW_WRITES_IN_RECOVERING),
+ Bytes.toBytes(true));
master.createTable(labelsTable, null);
}
}
@@ -535,32 +540,48 @@ public class VisibilityController extend
if (e.getEnvironment().getRegion().getRegionInfo().getTable().equals(LABELS_TABLE_NAME)) {
this.labelsRegion = true;
this.acOn = CoprocessorHost.getLoadedCoprocessors().contains(AccessController.class.getName());
- try {
- Pair<Map<String, Integer>, Map<String, List<Integer>>> labelsAndUserAuths =
- extractLabelsAndAuths(getExistingLabelsWithAuths());
- Map<String, Integer> labels = labelsAndUserAuths.getFirst();
- Map<String, List<Integer>> userAuths = labelsAndUserAuths.getSecond();
- // Add the "system" label if it is not added into the system yet
- addSystemLabel(e.getEnvironment().getRegion(), labels, userAuths);
- int ordinal = 1; // Ordinal 1 is reserved for "system" label.
- for (Integer i : labels.values()) {
- if (i > ordinal) {
- ordinal = i;
- }
- }
- this.ordinalCounter = ordinal + 1;
- if (labels.size() > 0) {
- // If there is no data need not write to zk
- byte[] serialized = VisibilityUtils.getDataToWriteToZooKeeper(labels);
- this.visibilityManager.writeToZookeeper(serialized, true);
- }
- if (userAuths.size() > 0) {
- byte[] serialized = VisibilityUtils.getUserAuthsDataToWriteToZooKeeper(userAuths);
- this.visibilityManager.writeToZookeeper(serialized, false);
+ if (!e.getEnvironment().getRegion().isRecovering()) {
+ initialize(e);
+ }
+ } else {
+ this.initialized = true;
+ }
+ }
+
+ @Override
+ public void postLogReplay(ObserverContext<RegionCoprocessorEnvironment> e) {
+ if (this.labelsRegion) {
+ initialize(e);
+ }
+ }
+
+ private void initialize(ObserverContext<RegionCoprocessorEnvironment> e) {
+ try {
+ Pair<Map<String, Integer>, Map<String, List<Integer>>> labelsAndUserAuths =
+ extractLabelsAndAuths(getExistingLabelsWithAuths());
+ Map<String, Integer> labels = labelsAndUserAuths.getFirst();
+ Map<String, List<Integer>> userAuths = labelsAndUserAuths.getSecond();
+ // Add the "system" label if it is not added into the system yet
+ addSystemLabel(e.getEnvironment().getRegion(), labels, userAuths);
+ int ordinal = 1; // Ordinal 1 is reserved for "system" label.
+ for (Integer i : labels.values()) {
+ if (i > ordinal) {
+ ordinal = i;
}
- } catch (IOException ioe) {
- LOG.error("Error while updating the zk with the exisiting labels data", ioe);
}
+ this.ordinalCounter = ordinal + 1;
+ if (labels.size() > 0) {
+ // If there is no data need not write to zk
+ byte[] serialized = VisibilityUtils.getDataToWriteToZooKeeper(labels);
+ this.visibilityManager.writeToZookeeper(serialized, true);
+ }
+ if (userAuths.size() > 0) {
+ byte[] serialized = VisibilityUtils.getUserAuthsDataToWriteToZooKeeper(userAuths);
+ this.visibilityManager.writeToZookeeper(serialized, false);
+ }
+ initialized = true;
+ } catch (IOException ioe) {
+ LOG.error("Error while updating the zk with the exisiting labels data", ioe);
}
}
@@ -1025,6 +1046,10 @@ public class VisibilityController extend
RpcCallback<VisibilityLabelsResponse> done) {
VisibilityLabelsResponse.Builder response = VisibilityLabelsResponse.newBuilder();
List<VisibilityLabel> labels = request.getVisLabelList();
+ if (!initialized) {
+ setExceptionResults(labels.size(), new CoprocessorException(
+ "VisibilityController not yet initialized"), response);
+ }
try {
checkCallingUserAuth();
List<Mutation> puts = new ArrayList<Mutation>(labels.size());
@@ -1072,16 +1097,21 @@ public class VisibilityController extend
}
} catch (IOException e) {
LOG.error(e);
- RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
- failureResultBuilder.setException(ResponseConverter.buildException(e));
- RegionActionResult failureResult = failureResultBuilder.build();
- for (int i = 0; i < labels.size(); i++) {
- response.addResult(i, failureResult);
- }
+ setExceptionResults(labels.size(), e, response);
}
done.run(response.build());
}
+ private void setExceptionResults(int size, IOException e,
+ VisibilityLabelsResponse.Builder response) {
+ RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
+ failureResultBuilder.setException(ResponseConverter.buildException(e));
+ RegionActionResult failureResult = failureResultBuilder.build();
+ for (int i = 0; i < size; i++) {
+ response.addResult(i, failureResult);
+ }
+ }
+
private void performACLCheck() throws IOException {
// Do ACL check only when the security is enabled.
if (this.acOn && !isSystemOrSuperUser()) {
@@ -1115,6 +1145,10 @@ public class VisibilityController extend
RpcCallback<VisibilityLabelsResponse> done) {
VisibilityLabelsResponse.Builder response = VisibilityLabelsResponse.newBuilder();
List<ByteString> auths = request.getAuthList();
+ if (!initialized) {
+ setExceptionResults(auths.size(), new CoprocessorException(
+ "VisibilityController not yet initialized"), response);
+ }
byte[] user = request.getUser().toByteArray();
try {
checkCallingUserAuth();
@@ -1153,12 +1187,7 @@ public class VisibilityController extend
}
} catch (IOException e) {
LOG.error(e);
- RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
- failureResultBuilder.setException(ResponseConverter.buildException(e));
- RegionActionResult failureResult = failureResultBuilder.build();
- for (int i = 0; i < auths.size(); i++) {
- response.addResult(i, failureResult);
- }
+ setExceptionResults(auths.size(), e, response);
}
done.run(response.build());
}
@@ -1211,6 +1240,10 @@ public class VisibilityController extend
RpcCallback<VisibilityLabelsResponse> done) {
VisibilityLabelsResponse.Builder response = VisibilityLabelsResponse.newBuilder();
List<ByteString> auths = request.getAuthList();
+ if (!initialized) {
+ setExceptionResults(auths.size(), new CoprocessorException(
+ "VisibilityController not yet initialized"), response);
+ }
byte[] user = request.getUser().toByteArray();
try {
checkCallingUserAuth();
@@ -1251,12 +1284,7 @@ public class VisibilityController extend
}
} catch (IOException e) {
LOG.error(e);
- RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
- failureResultBuilder.setException(ResponseConverter.buildException(e));
- RegionActionResult failureResult = failureResultBuilder.build();
- for (int i = 0; i < auths.size(); i++) {
- response.addResult(i, failureResult);
- }
+ setExceptionResults(auths.size(), e, response);
}
done.run(response.build());
}
Modified: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java?rev=1552021&r1=1552020&r2=1552021&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java (original)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java Wed Dec 18 16:55:18 2013
@@ -331,7 +331,7 @@ public class TestVisibilityLabels {
}
}
- @Test
+ @Test(timeout = 60 * 1000)
public void testVisibilityLabelsOnRSRestart() throws Exception {
final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
@@ -341,19 +341,7 @@ public class TestVisibilityLabels {
}
// Start one new RS
RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
- HRegionServer regionServer = rs.getRegionServer();
- while (!regionServer.isOnline()) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- while (regionServer.getOnlineRegions(LABELS_TABLE_NAME).isEmpty()) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
+ waitForLabelsRegionAvailability(rs.getRegionServer());
HTable table = createTableAndWriteDataWithLabels(tableName, "(" + SECRET + "|" + CONFIDENTIAL
+ ")", PRIVATE);
try {
@@ -369,7 +357,7 @@ public class TestVisibilityLabels {
}
}
- @Test
+ @Test(timeout = 60 * 1000)
public void testAddVisibilityLabelsOnRSRestart() throws Exception {
List<RegionServerThread> regionServerThreads = TEST_UTIL.getHBaseCluster()
.getRegionServerThreads();
@@ -378,20 +366,7 @@ public class TestVisibilityLabels {
}
// Start one new RS
RegionServerThread rs = TEST_UTIL.getHBaseCluster().startRegionServer();
- HRegionServer regionServer = rs.getRegionServer();
- while (!regionServer.isOnline()) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- while (regionServer.getOnlineRegions(LABELS_TABLE_NAME).isEmpty()) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
-
+ waitForLabelsRegionAvailability(rs.getRegionServer());
String[] labels = { SECRET, CONFIDENTIAL, PRIVATE, "ABC", "XYZ" };
try {
VisibilityClient.addLabels(conf, labels);
@@ -421,6 +396,28 @@ public class TestVisibilityLabels {
Assert.assertEquals("The count should be 8", 8, i);
}
+ private void waitForLabelsRegionAvailability(HRegionServer regionServer) {
+ while (!regionServer.isOnline()) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ while (regionServer.getOnlineRegions(LABELS_TABLE_NAME).isEmpty()) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ HRegion labelsTableRegion = regionServer.getOnlineRegions(LABELS_TABLE_NAME).get(0);
+ while (labelsTableRegion.isRecovering()) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
@Test
public void testVisibilityLabelsInGetThatDoesNotMatchAnyDefinedLabels() throws Exception {
TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());