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());