hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From st...@apache.org
Subject svn commit: r1511591 [10/23] - in /hbase/branches/0.95: hbase-client/src/main/java/org/apache/hadoop/hbase/ hbase-client/src/main/java/org/apache/hadoop/hbase/catalog/ hbase-client/src/main/java/org/apache/hadoop/hbase/client/ hbase-client/src/main/jav...
Date Thu, 08 Aug 2013 06:08:31 GMT
Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java Thu Aug  8 06:08:23 2013
@@ -28,6 +28,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -40,6 +41,8 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.management.ObjectName;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.classification.InterfaceAudience;
@@ -49,7 +52,11 @@ import org.apache.hadoop.hbase.Abortable
 import org.apache.hadoop.hbase.Chore;
 import org.apache.hadoop.hbase.ClusterId;
 import org.apache.hadoop.hbase.ClusterStatus;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HBaseIOException;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.constraint.ConstraintException;
+import org.apache.hadoop.hbase.exceptions.DeserializationException;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
@@ -72,12 +79,7 @@ import org.apache.hadoop.hbase.client.Me
 import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitorBase;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
-import org.apache.hadoop.hbase.exceptions.DeserializationException;
-import org.apache.hadoop.hbase.MasterNotRunningException;
 import org.apache.hadoop.hbase.exceptions.MergeRegionException;
-import org.apache.hadoop.hbase.PleaseHoldException;
-import org.apache.hadoop.hbase.TableNotDisabledException;
-import org.apache.hadoop.hbase.TableNotFoundException;
 import org.apache.hadoop.hbase.exceptions.UnknownProtocolException;
 import org.apache.hadoop.hbase.executor.ExecutorService;
 import org.apache.hadoop.hbase.executor.ExecutorType;
@@ -108,6 +110,7 @@ import org.apache.hadoop.hbase.protobuf.
 import org.apache.hadoop.hbase.protobuf.ResponseConverter;
 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
 import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos;
+import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameStringPair;
 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
@@ -205,6 +208,7 @@ import org.apache.hadoop.hbase.zookeeper
 import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
 import org.apache.hadoop.hbase.zookeeper.RegionServerTracker;
 import org.apache.hadoop.hbase.zookeeper.ZKClusterId;
+import org.apache.hadoop.hbase.zookeeper.ZKTable;
 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
 import org.apache.hadoop.hbase.zookeeper.ZooKeeperListener;
 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
@@ -273,6 +277,10 @@ MasterServices, Server {
   // Set back to false after we stop rpcServer.  Used by tests.
   private volatile boolean rpcServerOpen = false;
 
+  /** Namespace stuff */
+  private TableNamespaceManager tableNamespaceManager;
+  private NamespaceJanitor namespaceJanitorChore;
+
   /**
    * This servers address.
    */
@@ -744,6 +752,7 @@ MasterServices, Server {
      */
 
     status.setStatus("Initializing Master file system");
+
     this.masterActiveTime = System.currentTimeMillis();
     // TODO: Do this using Dependency Injection, using PicoContainer, Guice or Spring.
     this.fileSystemManager = new MasterFileSystem(this, this, metricsMaster, masterRecovery);
@@ -841,6 +850,10 @@ MasterServices, Server {
       this.fileSystemManager.splitMetaLog(previouslyFailedMetaRSs);
     }
 
+    status.setStatus("Assigning System tables");
+    // Make sure system tables are assigned before proceeding.
+    assignSystemTables(status);
+
     enableServerShutdownHandler();
 
     status.setStatus("Submitting log splitting work for previously failed region servers");
@@ -870,7 +883,9 @@ MasterServices, Server {
       this.clusterStatusChore = getAndStartClusterStatusChore(this);
       this.balancerChore = getAndStartBalancerChore(this);
       this.catalogJanitorChore = new CatalogJanitor(this, this);
+      this.namespaceJanitorChore = new NamespaceJanitor(this);
       startCatalogJanitorChore();
+      startNamespaceJanitorChore();
     }
 
     status.markComplete("Initialization successful");
@@ -902,6 +917,14 @@ MasterServices, Server {
   }
 
   /**
+   * Useful for testing purpose also where we have
+   * master restart scenarios.
+   */
+  protected void startNamespaceJanitorChore() {
+    Threads.setDaemonThreadRunning(namespaceJanitorChore.getThread());
+  }
+
+  /**
    * Create a {@link ServerManager} instance.
    * @param master
    * @param services
@@ -974,9 +997,9 @@ MasterServices, Server {
         this.catalogTracker.getMetaLocation());
     }
 
-    enableCatalogTables(Bytes.toString(HConstants.META_TABLE_NAME));
-    LOG.info(".META. assigned=" + assigned + ", rit=" + rit + ", location="
-        + catalogTracker.getMetaLocation());
+    enableMeta(TableName.META_TABLE_NAME);
+    LOG.info(".META. assigned=" + assigned + ", rit=" + rit +
+      ", location=" + catalogTracker.getMetaLocation());
     status.setStatus("META assigned.");
   }
 
@@ -992,6 +1015,82 @@ MasterServices, Server {
     }
   }
 
+  private void splitLogBeforeAssignment(ServerName currentServer,
+                                        Set<HRegionInfo> regions) throws IOException {
+    if (this.distributedLogReplay) {
+      this.fileSystemManager.prepareLogReplay(currentServer, regions);
+    } else {
+      // In recovered.edits mode: create recovered edits file for region server
+      this.fileSystemManager.splitLog(currentServer);
+    }
+  }
+
+  void assignSystemTables(MonitoredTask status)
+      throws InterruptedException, IOException, KeeperException {
+    // Skip assignment for regions of tables in DISABLING state because during clean cluster startup
+    // no RS is alive and regions map also doesn't have any information about the regions.
+    // See HBASE-6281.
+    Set<TableName> disabledOrDisablingOrEnabling = ZKTable.getDisabledOrDisablingTables(zooKeeper);
+    disabledOrDisablingOrEnabling.addAll(ZKTable.getEnablingTables(zooKeeper));
+    // Scan META for all system regions, skipping any disabled tables
+    Map<HRegionInfo, ServerName> allRegions =
+        MetaReader.fullScan(catalogTracker, disabledOrDisablingOrEnabling, true);
+    for(Iterator<HRegionInfo> iter = allRegions.keySet().iterator();
+        iter.hasNext();) {
+      if (!HTableDescriptor.isSystemTable(iter.next().getTableName())) {
+        iter.remove();
+      }
+    }
+
+    int assigned = 0;
+    boolean beingExpired = false;
+
+    status.setStatus("Assigning System Regions");
+
+    for(Map.Entry<HRegionInfo, ServerName> entry: allRegions.entrySet()) {
+      HRegionInfo regionInfo = entry.getKey();
+      ServerName currServer = entry.getValue();
+
+      assignmentManager.getRegionStates().createRegionState(regionInfo);
+      boolean rit = this.assignmentManager
+          .processRegionInTransitionAndBlockUntilAssigned(regionInfo);
+      boolean regionLocation = false;
+      if (currServer != null) {
+        regionLocation = verifyRegionLocation(currServer, regionInfo);
+      }
+
+      if (!rit && !regionLocation) {
+        beingExpired = expireIfOnline(currServer);
+        if (beingExpired) {
+          splitLogBeforeAssignment(currServer, Sets.newHashSet(regionInfo));
+        }
+        assignmentManager.assign(regionInfo, true);
+        // Make sure a region location is set.
+        this.assignmentManager.waitForAssignment(regionInfo);
+        assigned++;
+        if (beingExpired && this.distributedLogReplay) {
+          // In Replay WAL Mode, we need the new region server online
+          this.fileSystemManager.splitLog(currServer);
+        }
+      } else if (rit && !regionLocation) {
+        if (!waitVerifiedRegionLocation(regionInfo)) return;
+        assigned++;
+      } else {
+        // Region already assigned. We didn't assign it. Add to in-memory state.
+        this.assignmentManager.regionOnline(regionInfo, currServer);
+      }
+
+      if (!this.assignmentManager.getZKTable().isEnabledTable(regionInfo.getTableName())) {
+        this.assignmentManager.setEnabledTable(regionInfo.getTableName());
+      }
+      LOG.info("System Regions assigned=" + assigned + ", rit=" + rit +
+        ", location=" + catalogTracker.getMetaLocation());
+    }
+    status.setStatus("System Regions assigned.");
+
+    initNamespace();
+  }
+
   private void enableSSHandWaitForMeta() throws IOException, InterruptedException {
     enableServerShutdownHandler();
     this.catalogTracker.waitForMeta();
@@ -1000,9 +1099,31 @@ MasterServices, Server {
     this.assignmentManager.waitForAssignment(HRegionInfo.FIRST_META_REGIONINFO);
   }
 
-  private void enableCatalogTables(String catalogTableName) {
-    if (!this.assignmentManager.getZKTable().isEnabledTable(catalogTableName)) {
-      this.assignmentManager.setEnabledTable(catalogTableName);
+  private boolean waitVerifiedRegionLocation(HRegionInfo regionInfo) throws IOException {
+    while (!this.stopped) {
+      Pair<HRegionInfo, ServerName> p = MetaReader.getRegion(catalogTracker,
+          regionInfo.getRegionName());
+      if (verifyRegionLocation(p.getSecond(), p.getFirst())) break;
+    }
+    // We got here because we came of above loop.
+    return !this.stopped;
+  }
+
+  private boolean verifyRegionLocation(ServerName currServer, HRegionInfo regionInfo) {
+    try {
+      return
+          ProtobufUtil.getRegionInfo(HConnectionManager.getConnection(conf)
+              .getAdmin(currServer),
+              regionInfo.getRegionName()) != null;
+    } catch (IOException e) {
+      LOG.info("Failed to contact server: "+currServer, e);
+    }
+    return false;
+  }
+
+  private void enableMeta(TableName metaTableName) {
+    if (!this.assignmentManager.getZKTable().isEnabledTable(metaTableName)) {
+      this.assignmentManager.setEnabledTable(metaTableName);
     }
   }
 
@@ -1022,6 +1143,12 @@ MasterServices, Server {
     return true;
   }
 
+  void initNamespace() throws IOException {
+    //create namespace manager
+    tableNamespaceManager = new TableNamespaceManager(this);
+    tableNamespaceManager.start();
+  }
+
   /**
    * This function returns a set of region server names under .META. recovering region ZK node
    * @return Set of meta server names which were recorded in ZK
@@ -1199,6 +1326,9 @@ MasterServices, Server {
     if (this.clusterStatusPublisherChore != null){
       clusterStatusPublisherChore.interrupt();
     }
+    if (this.namespaceJanitorChore != null){
+      namespaceJanitorChore.interrupt();
+    }
   }
 
   @Override
@@ -1380,7 +1510,7 @@ MasterServices, Server {
         }
       }
 
-      Map<String, Map<ServerName, List<HRegionInfo>>> assignmentsByTable =
+      Map<TableName, Map<ServerName, List<HRegionInfo>>> assignmentsByTable =
         this.assignmentManager.getRegionStates().getAssignmentsByTable();
 
       List<RegionPlan> plans = new ArrayList<RegionPlan>();
@@ -1639,13 +1769,18 @@ MasterServices, Server {
       throw new MasterNotRunningException();
     }
 
-    HRegionInfo [] newRegions = getHRegionInfos(hTableDescriptor, splitKeys);
+    String namespace = hTableDescriptor.getTableName().getNamespaceAsString();
+    if (getNamespaceDescriptor(namespace) == null) {
+      throw new ConstraintException("Namespace " + namespace + " does not exist");
+    }
+    
+    HRegionInfo[] newRegions = getHRegionInfos(hTableDescriptor, splitKeys);
     checkInitialized();
     checkCompression(hTableDescriptor);
     if (cpHost != null) {
       cpHost.preCreateTable(hTableDescriptor, newRegions);
     }
-
+    
     this.executorService.submit(new CreateTableHandler(this,
       this.fileSystemManager, hTableDescriptor, conf,
       newRegions, this).prepare());
@@ -1688,7 +1823,7 @@ MasterServices, Server {
     HRegionInfo[] hRegionInfos = null;
     if (splitKeys == null || splitKeys.length == 0) {
       hRegionInfos = new HRegionInfo[]{
-          new HRegionInfo(hTableDescriptor.getName(), null, null)};
+          new HRegionInfo(hTableDescriptor.getTableName(), null, null)};
     } else {
       int numRegions = splitKeys.length + 1;
       hRegionInfos = new HRegionInfo[numRegions];
@@ -1697,19 +1832,19 @@ MasterServices, Server {
       for (int i = 0; i < numRegions; i++) {
         endKey = (i == splitKeys.length) ? null : splitKeys[i];
         hRegionInfos[i] =
-            new HRegionInfo(hTableDescriptor.getName(), startKey, endKey);
+            new HRegionInfo(hTableDescriptor.getTableName(), startKey, endKey);
         startKey = endKey;
       }
     }
     return hRegionInfos;
   }
 
-  private static boolean isCatalogTable(final byte [] tableName) {
-    return Bytes.equals(tableName, HConstants.META_TABLE_NAME);
+  private static boolean isCatalogTable(final TableName tableName) {
+    return tableName.equals(TableName.META_TABLE_NAME);
   }
 
   @Override
-  public void deleteTable(final byte[] tableName) throws IOException {
+  public void deleteTable(final TableName tableName) throws IOException {
     checkInitialized();
     if (cpHost != null) {
       cpHost.preDeleteTable(tableName);
@@ -1724,7 +1859,7 @@ MasterServices, Server {
   public DeleteTableResponse deleteTable(RpcController controller, DeleteTableRequest request)
   throws ServiceException {
     try {
-      deleteTable(request.getTableName().toByteArray());
+      deleteTable(ProtobufUtil.toTableName(request.getTableName()));
     } catch (IOException ioe) {
       throw new ServiceException(ioe);
     }
@@ -1746,7 +1881,7 @@ MasterServices, Server {
     // may overlap with other table operations or the table operation may
     // have completed before querying this API. We need to refactor to a
     // transaction system in the future to avoid these ambiguities.
-    byte [] tableName = req.getTableName().toByteArray();
+    TableName tableName = ProtobufUtil.toTableName(req.getTableName());
 
     try {
       Pair<Integer,Integer> pair = this.assignmentManager.getReopenStatus(tableName);
@@ -1760,7 +1895,7 @@ MasterServices, Server {
   }
 
   @Override
-  public void addColumn(final byte[] tableName, final HColumnDescriptor column)
+  public void addColumn(final TableName tableName, final HColumnDescriptor column)
       throws IOException {
     checkInitialized();
     if (cpHost != null) {
@@ -1780,7 +1915,7 @@ MasterServices, Server {
   public AddColumnResponse addColumn(RpcController controller, AddColumnRequest req)
   throws ServiceException {
     try {
-      addColumn(req.getTableName().toByteArray(),
+      addColumn(ProtobufUtil.toTableName(req.getTableName()),
         HColumnDescriptor.convert(req.getColumnFamilies()));
     } catch (IOException ioe) {
       throw new ServiceException(ioe);
@@ -1789,7 +1924,7 @@ MasterServices, Server {
   }
 
   @Override
-  public void modifyColumn(byte[] tableName, HColumnDescriptor descriptor)
+  public void modifyColumn(TableName tableName, HColumnDescriptor descriptor)
       throws IOException {
     checkInitialized();
     checkCompression(descriptor);
@@ -1809,7 +1944,7 @@ MasterServices, Server {
   public ModifyColumnResponse modifyColumn(RpcController controller, ModifyColumnRequest req)
   throws ServiceException {
     try {
-      modifyColumn(req.getTableName().toByteArray(),
+      modifyColumn(ProtobufUtil.toTableName(req.getTableName()),
         HColumnDescriptor.convert(req.getColumnFamilies()));
     } catch (IOException ioe) {
       throw new ServiceException(ioe);
@@ -1818,7 +1953,7 @@ MasterServices, Server {
   }
 
   @Override
-  public void deleteColumn(final byte[] tableName, final byte[] columnName)
+  public void deleteColumn(final TableName tableName, final byte[] columnName)
       throws IOException {
     checkInitialized();
     if (cpHost != null) {
@@ -1836,7 +1971,8 @@ MasterServices, Server {
   public DeleteColumnResponse deleteColumn(RpcController controller, DeleteColumnRequest req)
   throws ServiceException {
     try {
-      deleteColumn(req.getTableName().toByteArray(), req.getColumnName().toByteArray());
+      deleteColumn(ProtobufUtil.toTableName(req.getTableName()),
+          req.getColumnName().toByteArray());
     } catch (IOException ioe) {
       throw new ServiceException(ioe);
     }
@@ -1844,7 +1980,7 @@ MasterServices, Server {
   }
 
   @Override
-  public void enableTable(final byte[] tableName) throws IOException {
+  public void enableTable(final TableName tableName) throws IOException {
     checkInitialized();
     if (cpHost != null) {
       cpHost.preEnableTable(tableName);
@@ -1860,7 +1996,7 @@ MasterServices, Server {
   public EnableTableResponse enableTable(RpcController controller, EnableTableRequest request)
   throws ServiceException {
     try {
-      enableTable(request.getTableName().toByteArray());
+      enableTable(ProtobufUtil.toTableName(request.getTableName()));
     } catch (IOException ioe) {
       throw new ServiceException(ioe);
     }
@@ -1868,7 +2004,7 @@ MasterServices, Server {
   }
 
   @Override
-  public void disableTable(final byte[] tableName) throws IOException {
+  public void disableTable(final TableName tableName) throws IOException {
     checkInitialized();
     if (cpHost != null) {
       cpHost.preDisableTable(tableName);
@@ -1884,7 +2020,7 @@ MasterServices, Server {
   public DisableTableResponse disableTable(RpcController controller, DisableTableRequest request)
   throws ServiceException {
     try {
-      disableTable(request.getTableName().toByteArray());
+      disableTable(ProtobufUtil.toTableName(request.getTableName()));
     } catch (IOException ioe) {
       throw new ServiceException(ioe);
     }
@@ -1898,7 +2034,7 @@ MasterServices, Server {
    * may be null.
    */
   Pair<HRegionInfo, ServerName> getTableRegionForRow(
-      final byte [] tableName, final byte [] rowKey)
+      final TableName tableName, final byte [] rowKey)
   throws IOException {
     final AtomicReference<Pair<HRegionInfo, ServerName>> result =
       new AtomicReference<Pair<HRegionInfo, ServerName>>(null);
@@ -1914,7 +2050,7 @@ MasterServices, Server {
           if (pair == null) {
             return false;
           }
-          if (!Bytes.equals(pair.getFirst().getTableName(), tableName)) {
+          if (!pair.getFirst().getTableName().equals(tableName)) {
             return false;
           }
           result.set(pair);
@@ -1927,7 +2063,7 @@ MasterServices, Server {
   }
 
   @Override
-  public void modifyTable(final byte[] tableName, final HTableDescriptor descriptor)
+  public void modifyTable(final TableName tableName, final HTableDescriptor descriptor)
       throws IOException {
     checkInitialized();
     checkCompression(descriptor);
@@ -1944,7 +2080,7 @@ MasterServices, Server {
   public ModifyTableResponse modifyTable(RpcController controller, ModifyTableRequest req)
   throws ServiceException {
     try {
-      modifyTable(req.getTableName().toByteArray(),
+      modifyTable(ProtobufUtil.toTableName(req.getTableName()),
         HTableDescriptor.convert(req.getTableSchema()));
     } catch (IOException ioe) {
       throw new ServiceException(ioe);
@@ -1953,17 +2089,16 @@ MasterServices, Server {
   }
 
   @Override
-  public void checkTableModifiable(final byte [] tableName)
+  public void checkTableModifiable(final TableName tableName)
       throws IOException, TableNotFoundException, TableNotDisabledException {
-    String tableNameStr = Bytes.toString(tableName);
     if (isCatalogTable(tableName)) {
       throw new IOException("Can't modify catalog tables");
     }
-    if (!MetaReader.tableExists(getCatalogTracker(), tableNameStr)) {
-      throw new TableNotFoundException(tableNameStr);
+    if (!MetaReader.tableExists(getCatalogTracker(), tableName)) {
+      throw new TableNotFoundException(tableName);
     }
     if (!getAssignmentManager().getZKTable().
-        isDisabledTable(Bytes.toString(tableName))) {
+        isDisabledTable(tableName)) {
       throw new TableNotDisabledException(tableName);
     }
   }
@@ -2430,11 +2565,14 @@ MasterServices, Server {
   public GetTableDescriptorsResponse getTableDescriptors(
 	      RpcController controller, GetTableDescriptorsRequest req) throws ServiceException {
     List<HTableDescriptor> descriptors = new ArrayList<HTableDescriptor>();
-
+    List<TableName> tableNameList = new ArrayList<TableName>();
+    for(HBaseProtos.TableName tableNamePB: req.getTableNamesList()) {
+      tableNameList.add(ProtobufUtil.toTableName(tableNamePB));
+    }
     boolean bypass = false;
     if (this.cpHost != null) {
       try {
-        bypass = this.cpHost.preGetTableDescriptors(req.getTableNamesList(), descriptors);
+        bypass = this.cpHost.preGetTableDescriptors(tableNameList, descriptors);
       } catch (IOException ioe) {
         throw new ServiceException(ioe);
       }
@@ -2450,10 +2588,14 @@ MasterServices, Server {
           LOG.warn("Failed getting all descriptors", e);
         }
         if (descriptorMap != null) {
-          descriptors.addAll(descriptorMap.values());
+          for(HTableDescriptor desc: descriptorMap.values()) {
+            if(!HTableDescriptor.isSystemTable(desc.getTableName())) {
+              descriptors.add(desc);
+            }
+          }
         }
       } else {
-        for (String s: req.getTableNamesList()) {
+        for (TableName s: tableNameList) {
           try {
             HTableDescriptor desc = this.tableDescriptors.get(s);
             if (desc != null) {
@@ -2803,9 +2945,136 @@ MasterServices, Server {
     }
   }
 
+  @Override
+  public MasterAdminProtos.ModifyNamespaceResponse modifyNamespace(RpcController controller,
+      MasterAdminProtos.ModifyNamespaceRequest request) throws ServiceException {
+    try {
+      modifyNamespace(ProtobufUtil.toNamespaceDescriptor(request.getNamespaceDescriptor()));
+      return MasterAdminProtos.ModifyNamespaceResponse.getDefaultInstance();
+    } catch (IOException e) {
+      throw new ServiceException(e);
+    }
+  }
+
+  @Override
+  public MasterAdminProtos.CreateNamespaceResponse createNamespace(RpcController controller,
+     MasterAdminProtos.CreateNamespaceRequest request) throws ServiceException {
+    try {
+      createNamespace(ProtobufUtil.toNamespaceDescriptor(request.getNamespaceDescriptor()));
+      return MasterAdminProtos.CreateNamespaceResponse.getDefaultInstance();
+    } catch (IOException e) {
+      throw new ServiceException(e);
+    }
+  }
+
+  @Override
+  public MasterAdminProtos.DeleteNamespaceResponse deleteNamespace(RpcController controller, MasterAdminProtos.DeleteNamespaceRequest request) throws ServiceException {
+    try {
+      deleteNamespace(request.getNamespaceName());
+      return MasterAdminProtos.DeleteNamespaceResponse.getDefaultInstance();
+    } catch (IOException e) {
+      throw new ServiceException(e);
+    }
+  }
+
+  @Override
+  public MasterAdminProtos.GetNamespaceDescriptorResponse getNamespaceDescriptor(
+      RpcController controller, MasterAdminProtos.GetNamespaceDescriptorRequest request)
+      throws ServiceException {
+    try {
+      return MasterAdminProtos.GetNamespaceDescriptorResponse.newBuilder()
+          .setNamespaceDescriptor(
+              ProtobufUtil.toProtoNamespaceDescriptor(getNamespaceDescriptor(request.getNamespaceName())))
+          .build();
+    } catch (IOException e) {
+      throw new ServiceException(e);
+    }
+  }
+
+  @Override
+  public MasterAdminProtos.ListNamespaceDescriptorsResponse listNamespaceDescriptors(
+      RpcController controller, MasterAdminProtos.ListNamespaceDescriptorsRequest request)
+      throws ServiceException {
+    try {
+      MasterAdminProtos.ListNamespaceDescriptorsResponse.Builder response =
+          MasterAdminProtos.ListNamespaceDescriptorsResponse.newBuilder();
+      for(NamespaceDescriptor ns: listNamespaceDescriptors()) {
+        response.addNamespaceDescriptor(ProtobufUtil.toProtoNamespaceDescriptor(ns));
+      }
+      return response.build();
+    } catch (IOException e) {
+      throw new ServiceException(e);
+    }
+  }
+
+  @Override
+  public MasterAdminProtos.GetTableDescriptorsByNamespaceResponse getTableDescriptorsByNamespace(
+      RpcController controller, MasterAdminProtos.GetTableDescriptorsByNamespaceRequest request)
+      throws ServiceException {
+    try {
+      MasterAdminProtos.GetTableDescriptorsByNamespaceResponse.Builder b =
+          MasterAdminProtos.GetTableDescriptorsByNamespaceResponse.newBuilder();
+      for(HTableDescriptor htd: getTableDescriptorsByNamespace(request.getNamespaceName())) {
+        b.addTableSchema(htd.convert());
+      }
+      return b.build();
+    } catch (IOException e) {
+      throw new ServiceException(e);
+    }
+  }
+
   private boolean isHealthCheckerConfigured() {
     String healthScriptLocation = this.conf.get(HConstants.HEALTH_SCRIPT_LOC);
     return org.apache.commons.lang.StringUtils.isNotBlank(healthScriptLocation);
   }
 
+  public void createNamespace(NamespaceDescriptor descriptor) throws IOException {
+    TableName.isLegalNamespaceName(Bytes.toBytes(descriptor.getName()));
+    if (cpHost != null) {
+      if (cpHost.preCreateNamespace(descriptor)) {
+        return;
+      }
+    }
+    tableNamespaceManager.create(descriptor);
+    if (cpHost != null) {
+      cpHost.postCreateNamespace(descriptor);
+    }
+  }
+
+  public void modifyNamespace(NamespaceDescriptor descriptor) throws IOException {
+    TableName.isLegalNamespaceName(Bytes.toBytes(descriptor.getName()));
+    if (cpHost != null) {
+      if (cpHost.preModifyNamespace(descriptor)) {
+        return;
+      }
+    }
+    tableNamespaceManager.update(descriptor);
+    if (cpHost != null) {
+      cpHost.postModifyNamespace(descriptor);
+    }
+  }
+
+  public void deleteNamespace(String name) throws IOException {
+    if (cpHost != null) {
+      if (cpHost.preDeleteNamespace(name)) {
+        return;
+      }
+    }
+    tableNamespaceManager.remove(name);
+    if (cpHost != null) {
+      cpHost.postDeleteNamespace(name);
+    }
+  }
+
+  public NamespaceDescriptor getNamespaceDescriptor(String name) throws IOException {
+      return tableNamespaceManager.get(name);
+  }
+
+  public List<NamespaceDescriptor> listNamespaceDescriptors() throws IOException {
+    return Lists.newArrayList(tableNamespaceManager.list());
+  }
+
+  public List<HTableDescriptor> getTableDescriptorsByNamespace(String name) throws IOException {
+    return Lists.newArrayList(tableDescriptors.getByNamespace(name).values());
+  }
 }

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java Thu Aug  8 06:08:23 2013
@@ -87,6 +87,124 @@ public class MasterCoprocessorHost
     abortServer("master", masterServices, env, e);
   }
 
+  boolean preCreateNamespace(NamespaceDescriptor ns)
+    throws IOException {
+    boolean bypass = false;
+    ObserverContext<MasterCoprocessorEnvironment> ctx = null;
+    for (MasterEnvironment env: coprocessors) {
+      if (env.getInstance() instanceof MasterObserver) {
+        ctx = ObserverContext.createAndPrepare(env, ctx);
+        try {
+          ((MasterObserver)env.getInstance()).preCreateNamespace(
+              ctx, ns);
+        } catch (Throwable e) {
+          handleCoprocessorThrowable(env, e);
+        }
+        bypass |= ctx.shouldBypass();
+        if (ctx.shouldComplete()) {
+          break;
+        }
+      }
+    }
+    return bypass;
+  }
+
+  void postCreateNamespace(NamespaceDescriptor ns)
+    throws IOException {
+    ObserverContext<MasterCoprocessorEnvironment> ctx = null;
+    for (MasterEnvironment env: coprocessors) {
+      if (env.getInstance() instanceof MasterObserver) {
+        ctx = ObserverContext.createAndPrepare(env, ctx);
+        try {
+            ((MasterObserver)env.getInstance()).postCreateNamespace(ctx, ns);
+        } catch (Throwable e) {
+          handleCoprocessorThrowable(env, e);
+        }
+        if (ctx.shouldComplete()) {
+          break;
+        }
+      }
+    }
+  }
+
+  boolean preDeleteNamespace(String namespaceName) throws IOException {
+    boolean bypass = false;
+    ObserverContext<MasterCoprocessorEnvironment> ctx = null;
+    for (MasterEnvironment env: coprocessors) {
+      if (env.getInstance() instanceof MasterObserver) {
+        ctx = ObserverContext.createAndPrepare(env, ctx);
+        try {
+          ((MasterObserver)env.getInstance()).preDeleteNamespace(
+              ctx, namespaceName);
+        } catch (Throwable e) {
+          handleCoprocessorThrowable(env, e);
+        }
+        bypass |= ctx.shouldBypass();
+        if (ctx.shouldComplete()) {
+          break;
+        }
+      }
+    }
+    return bypass;
+  }
+
+  void postDeleteNamespace(String namespaceName) throws IOException {
+    ObserverContext<MasterCoprocessorEnvironment> ctx = null;
+    for (MasterEnvironment env: coprocessors) {
+      if (env.getInstance() instanceof MasterObserver) {
+        ctx = ObserverContext.createAndPrepare(env, ctx);
+        try {
+          ((MasterObserver)env.getInstance()).postDeleteNamespace(ctx, namespaceName);
+        } catch (Throwable e) {
+          handleCoprocessorThrowable(env, e);
+        }
+        if (ctx.shouldComplete()) {
+          break;
+        }
+      }
+    }
+  }
+
+  boolean preModifyNamespace(NamespaceDescriptor ns)
+      throws IOException {
+    boolean bypass = false;
+    ObserverContext<MasterCoprocessorEnvironment> ctx = null;
+    for (MasterEnvironment env: coprocessors) {
+      if (env.getInstance() instanceof MasterObserver) {
+        ctx = ObserverContext.createAndPrepare(env, ctx);
+        try {
+          ((MasterObserver)env.getInstance()).preModifyNamespace(
+              ctx, ns);
+        } catch (Throwable e) {
+          handleCoprocessorThrowable(env, e);
+        }
+        bypass |= ctx.shouldBypass();
+        if (ctx.shouldComplete()) {
+          break;
+        }
+      }
+    }
+    return bypass;
+  }
+
+  void postModifyNamespace(NamespaceDescriptor ns)
+      throws IOException {
+    ObserverContext<MasterCoprocessorEnvironment> ctx = null;
+    for (MasterEnvironment env: coprocessors) {
+      if (env.getInstance() instanceof MasterObserver) {
+        ctx = ObserverContext.createAndPrepare(env, ctx);
+        try {
+          ((MasterObserver)env.getInstance()).postModifyNamespace(ctx, ns);
+        } catch (Throwable e) {
+          handleCoprocessorThrowable(env, e);
+        }
+        if (ctx.shouldComplete()) {
+          break;
+        }
+      }
+    }
+  }
+
   /* Implementation of hooks for invoking MasterObservers */
   public void preCreateTable(HTableDescriptor htd, HRegionInfo[] regions)
     throws IOException {
@@ -162,7 +280,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void preDeleteTable(byte[] tableName) throws IOException {
+  public void preDeleteTable(TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -179,7 +297,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postDeleteTable(byte[] tableName) throws IOException {
+  public void postDeleteTable(TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -196,7 +314,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void preDeleteTableHandler(byte[] tableName) throws IOException {
+  public void preDeleteTableHandler(TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -214,7 +332,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postDeleteTableHandler(byte[] tableName) throws IOException {
+  public void postDeleteTableHandler(TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -231,7 +349,7 @@ public class MasterCoprocessorHost
       }
     }
   }
-  public void preModifyTable(final byte[] tableName, HTableDescriptor htd)
+  public void preModifyTable(final TableName tableName, HTableDescriptor htd)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
@@ -250,7 +368,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postModifyTable(final byte[] tableName, HTableDescriptor htd)
+  public void postModifyTable(final TableName tableName, HTableDescriptor htd)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
@@ -269,7 +387,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void preModifyTableHandler(final byte[] tableName, HTableDescriptor htd)
+  public void preModifyTableHandler(final TableName tableName, HTableDescriptor htd)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
@@ -288,7 +406,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postModifyTableHandler(final byte[] tableName,
+  public void postModifyTableHandler(final TableName tableName,
       HTableDescriptor htd) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
@@ -307,7 +425,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public boolean preAddColumn(byte [] tableName, HColumnDescriptor column)
+  public boolean preAddColumn(TableName tableName, HColumnDescriptor column)
       throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
@@ -328,7 +446,7 @@ public class MasterCoprocessorHost
     return bypass;
   }
 
-  public void postAddColumn(byte [] tableName, HColumnDescriptor column)
+  public void postAddColumn(TableName tableName, HColumnDescriptor column)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
@@ -347,7 +465,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public boolean preAddColumnHandler(byte[] tableName, HColumnDescriptor column)
+  public boolean preAddColumnHandler(TableName tableName, HColumnDescriptor column)
       throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
@@ -369,7 +487,7 @@ public class MasterCoprocessorHost
     return bypass;
   }
 
-  public void postAddColumnHandler(byte[] tableName, HColumnDescriptor column)
+  public void postAddColumnHandler(TableName tableName, HColumnDescriptor column)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
@@ -388,7 +506,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public boolean preModifyColumn(byte [] tableName, HColumnDescriptor descriptor)
+  public boolean preModifyColumn(TableName tableName, HColumnDescriptor descriptor)
       throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
@@ -410,7 +528,7 @@ public class MasterCoprocessorHost
     return bypass;
   }
 
-  public void postModifyColumn(byte [] tableName, HColumnDescriptor descriptor)
+  public void postModifyColumn(TableName tableName, HColumnDescriptor descriptor)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
@@ -429,7 +547,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public boolean preModifyColumnHandler(byte[] tableName,
+  public boolean preModifyColumnHandler(TableName tableName,
       HColumnDescriptor descriptor) throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
@@ -451,7 +569,7 @@ public class MasterCoprocessorHost
     return bypass;
   }
 
-  public void postModifyColumnHandler(byte[] tableName,
+  public void postModifyColumnHandler(TableName tableName,
       HColumnDescriptor descriptor) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
@@ -470,7 +588,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  boolean preDeleteColumn(final byte [] tableName, final byte [] c)
+  boolean preDeleteColumn(final TableName tableName, final byte [] c)
       throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
@@ -491,7 +609,7 @@ public class MasterCoprocessorHost
     return bypass;
   }
 
-  public void postDeleteColumn(final byte [] tableName, final byte [] c)
+  public void postDeleteColumn(final TableName tableName, final byte [] c)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
@@ -510,7 +628,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public boolean preDeleteColumnHandler(final byte[] tableName, final byte[] c)
+  public boolean preDeleteColumnHandler(final TableName tableName, final byte[] c)
       throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
@@ -532,7 +650,7 @@ public class MasterCoprocessorHost
     return bypass;
   }
 
-  public void postDeleteColumnHandler(final byte[] tableName, final byte[] c)
+  public void postDeleteColumnHandler(final TableName tableName, final byte[] c)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
@@ -551,7 +669,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void preEnableTable(final byte [] tableName) throws IOException {
+  public void preEnableTable(final TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -568,7 +686,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postEnableTable(final byte [] tableName) throws IOException {
+  public void postEnableTable(final TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -585,7 +703,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void preEnableTableHandler(final byte[] tableName) throws IOException {
+  public void preEnableTableHandler(final TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -603,7 +721,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postEnableTableHandler(final byte[] tableName) throws IOException {
+  public void postEnableTableHandler(final TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -621,7 +739,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void preDisableTable(final byte [] tableName) throws IOException {
+  public void preDisableTable(final TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -638,7 +756,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postDisableTable(final byte [] tableName) throws IOException {
+  public void postDisableTable(final TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -655,7 +773,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void preDisableTableHandler(final byte[] tableName) throws IOException {
+  public void preDisableTableHandler(final TableName tableName) throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
@@ -673,7 +791,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public void postDisableTableHandler(final byte[] tableName)
+  public void postDisableTableHandler(final TableName tableName)
       throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env : coprocessors) {
@@ -1114,7 +1232,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  public boolean preGetTableDescriptors(final List<String> tableNamesList,
+  public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
       final List<HTableDescriptor> descriptors) throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java Thu Aug  8 06:08:23 2013
@@ -36,6 +36,7 @@ import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.PathFilter;
 import org.apache.hadoop.hbase.ClusterId;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
@@ -529,41 +530,32 @@ public class MasterFileSystem {
     HFileArchiver.archiveRegion(conf, fs, region);
   }
 
-  public void deleteTable(byte[] tableName) throws IOException {
-    fs.delete(new Path(rootdir, Bytes.toString(tableName)), true);
+  public void deleteTable(TableName tableName) throws IOException {
+    fs.delete(FSUtils.getTableDir(rootdir, tableName), true);
   }
 
   /**
-   * Move the specified file/directory to the hbase temp directory.
-   * @param path The path of the file/directory to move
-   * @return The temp location of the file/directory moved
+   * Move the specified table to the hbase temp directory
+   * @param tableName Table name to move
+   * @return The temp location of the table moved
    * @throws IOException in case of file-system failure
    */
-  public Path moveToTemp(final Path path) throws IOException {
-    Path tempPath = new Path(this.tempdir, path.getName());
+  public Path moveTableToTemp(TableName tableName) throws IOException {
+    Path srcPath = FSUtils.getTableDir(rootdir, tableName);
+    Path tempPath = FSUtils.getTableDir(this.tempdir, tableName);
 
     // Ensure temp exists
-    if (!fs.exists(tempdir) && !fs.mkdirs(tempdir)) {
-      throw new IOException("HBase temp directory '" + tempdir + "' creation failure.");
+    if (!fs.exists(tempPath.getParent()) && !fs.mkdirs(tempPath.getParent())) {
+      throw new IOException("HBase temp directory '" + tempPath.getParent() + "' creation failure.");
     }
 
-    if (!fs.rename(path, tempPath)) {
-      throw new IOException("Unable to move '" + path + "' to temp '" + tempPath + "'");
+    if (!fs.rename(srcPath, tempPath)) {
+      throw new IOException("Unable to move '" + srcPath + "' to temp '" + tempPath + "'");
     }
 
     return tempPath;
   }
 
-  /**
-   * Move the specified table to the hbase temp directory
-   * @param tableName Table name to move
-   * @return The temp location of the table moved
-   * @throws IOException in case of file-system failure
-   */
-  public Path moveTableToTemp(byte[] tableName) throws IOException {
-    return moveToTemp(HTableDescriptor.getTableDir(this.rootdir, tableName));
-  }
-
   public void updateRegionInfo(HRegionInfo region) {
     // TODO implement this.  i think this is currently broken in trunk i don't
     //      see this getting updated.
@@ -573,7 +565,7 @@ public class MasterFileSystem {
   public void deleteFamilyFromFS(HRegionInfo region, byte[] familyName)
       throws IOException {
     // archive family store files
-    Path tableDir = new Path(rootdir, region.getTableNameAsString());
+    Path tableDir = FSUtils.getTableDir(rootdir, region.getTableName());
     HFileArchiver.archiveFamily(fs, conf, region, tableDir, familyName);
 
     // delete the family folder
@@ -600,9 +592,9 @@ public class MasterFileSystem {
    * @return Modified HTableDescriptor with requested column deleted.
    * @throws IOException
    */
-  public HTableDescriptor deleteColumn(byte[] tableName, byte[] familyName)
+  public HTableDescriptor deleteColumn(TableName tableName, byte[] familyName)
       throws IOException {
-    LOG.info("DeleteColumn. Table = " + Bytes.toString(tableName)
+    LOG.info("DeleteColumn. Table = " + tableName
         + " family = " + Bytes.toString(familyName));
     HTableDescriptor htd = this.services.getTableDescriptors().get(tableName);
     htd.removeFamily(familyName);
@@ -617,9 +609,9 @@ public class MasterFileSystem {
    * @return Modified HTableDescriptor with the column modified.
    * @throws IOException
    */
-  public HTableDescriptor modifyColumn(byte[] tableName, HColumnDescriptor hcd)
+  public HTableDescriptor modifyColumn(TableName tableName, HColumnDescriptor hcd)
       throws IOException {
-    LOG.info("AddModifyColumn. Table = " + Bytes.toString(tableName)
+    LOG.info("AddModifyColumn. Table = " + tableName
         + " HCD = " + hcd.toString());
 
     HTableDescriptor htd = this.services.getTableDescriptors().get(tableName);
@@ -640,9 +632,9 @@ public class MasterFileSystem {
    * @return Modified HTableDescriptor with new column added.
    * @throws IOException
    */
-  public HTableDescriptor addColumn(byte[] tableName, HColumnDescriptor hcd)
+  public HTableDescriptor addColumn(TableName tableName, HColumnDescriptor hcd)
       throws IOException {
-    LOG.info("AddColumn. Table = " + Bytes.toString(tableName) + " HCD = " +
+    LOG.info("AddColumn. Table = " + tableName + " HCD = " +
       hcd.toString());
     HTableDescriptor htd = this.services.getTableDescriptors().get(tableName);
     if (htd == null) {

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java Thu Aug  8 06:08:23 2013
@@ -19,11 +19,14 @@
 package org.apache.hadoop.hbase.master;
 
 import java.io.IOException;
+import java.util.List;
 
 import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
 import org.apache.hadoop.hbase.Server;
 import org.apache.hadoop.hbase.TableDescriptors;
 import org.apache.hadoop.hbase.TableNotDisabledException;
@@ -75,7 +78,7 @@ public interface MasterServices extends 
    * @throws IOException
    */
   // We actually throw the exceptions mentioned in the
-  void checkTableModifiable(final byte[] tableName)
+  void checkTableModifiable(final TableName tableName)
       throws IOException, TableNotFoundException, TableNotDisabledException;
 
   /**
@@ -92,7 +95,7 @@ public interface MasterServices extends 
    * @param tableName The table name
    * @throws IOException
    */
-  void deleteTable(final byte[] tableName) throws IOException;
+  void deleteTable(final TableName tableName) throws IOException;
 
   /**
    * Modify the descriptor of an existing table
@@ -100,7 +103,7 @@ public interface MasterServices extends 
    * @param descriptor The updated table descriptor
    * @throws IOException
    */
-  void modifyTable(final byte[] tableName, final HTableDescriptor descriptor)
+  void modifyTable(final TableName tableName, final HTableDescriptor descriptor)
       throws IOException;
 
   /**
@@ -108,14 +111,15 @@ public interface MasterServices extends 
    * @param tableName The table name
    * @throws IOException
    */
-  void enableTable(final byte[] tableName) throws IOException;
+  void enableTable(final TableName tableName) throws IOException;
 
   /**
    * Disable an existing table
    * @param tableName The table name
    * @throws IOException
    */
-  void disableTable(final byte[] tableName) throws IOException;
+  void disableTable(final TableName tableName) throws IOException;
+
 
   /**
    * Add a new column to an existing table
@@ -123,7 +127,7 @@ public interface MasterServices extends 
    * @param column The column definition
    * @throws IOException
    */
-  void addColumn(final byte[] tableName, final HColumnDescriptor column)
+  void addColumn(final TableName tableName, final HColumnDescriptor column)
       throws IOException;
 
   /**
@@ -132,7 +136,7 @@ public interface MasterServices extends 
    * @param descriptor The updated column definition
    * @throws IOException
    */
-  void modifyColumn(byte[] tableName, HColumnDescriptor descriptor)
+  void modifyColumn(TableName tableName, HColumnDescriptor descriptor)
       throws IOException;
 
   /**
@@ -141,7 +145,7 @@ public interface MasterServices extends 
    * @param columnName The column name
    * @throws IOException
    */
-  void deleteColumn(final byte[] tableName, final byte[] columnName)
+  void deleteColumn(final TableName tableName, final byte[] columnName)
       throws IOException;
 
   /**
@@ -187,4 +191,47 @@ public interface MasterServices extends 
    */
   boolean isInitialized();
 
+  /**
+   * Create a new namespace
+   * @param descriptor descriptor which describes the new namespace
+   * @throws IOException
+   */
+  public void createNamespace(NamespaceDescriptor descriptor) throws IOException;
+
+  /**
+   * Modify an existing namespace
+   * @param descriptor descriptor which updates the existing namespace
+   * @throws IOException
+   */
+  public void modifyNamespace(NamespaceDescriptor descriptor) throws IOException;
+
+  /**
+   * Delete an existing namespace. Only empty namespaces (no tables) can be removed.
+   * @param name namespace name
+   * @throws IOException
+   */
+  public void deleteNamespace(String name) throws IOException;
+
+  /**
+   * Get a namespace descriptor by name
+   * @param name name of namespace descriptor
+   * @return
+   * @throws IOException
+   */
+  public NamespaceDescriptor getNamespaceDescriptor(String name) throws IOException;
+
+  /**
+   * List available namespace descriptors
+   * @return
+   * @throws IOException
+   */
+  public List<NamespaceDescriptor> listNamespaceDescriptors() throws IOException;
+
+  /**
+   * Get list of table descriptors by namespace
+   * @param name namespace name
+   * @return
+   * @throws IOException
+   */
+  public List<HTableDescriptor> getTableDescriptorsByNamespace(String name) throws IOException;
 }

Added: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/NamespaceJanitor.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/NamespaceJanitor.java?rev=1511591&view=auto
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/NamespaceJanitor.java (added)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/NamespaceJanitor.java Thu Aug  8 06:08:23 2013
@@ -0,0 +1,150 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master;
+
+import com.google.common.collect.Sets;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.Chore;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.util.FSUtils;
+import org.apache.hadoop.hbase.zookeeper.ZKUtil;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
+import org.apache.zookeeper.KeeperException;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A janitor for the namespace artifacts.
+ * Traverses hdfs and zk to remove orphaned directories/znodes
+ */
+@InterfaceAudience.Private
+public class NamespaceJanitor extends Chore {
+  private static final Log LOG = LogFactory.getLog(NamespaceJanitor.class.getName());
+  private final MasterServices services;
+  private AtomicBoolean enabled = new AtomicBoolean(true);
+  private AtomicBoolean alreadyRunning = new AtomicBoolean(false);
+
+  public NamespaceJanitor(final MasterServices services) {
+    super("NamespaceJanitor-" + services.getServerName().toShortString(),
+      services.getConfiguration().getInt("hbase.namespacejanitor.interval", 30000),
+      services);
+    this.services = services;
+  }
+
+  @Override
+  protected boolean initialChore() {
+    try {
+      if (this.enabled.get()) removeOrphans();
+    } catch (IOException e) {
+      LOG.warn("Failed NamespaceJanitor chore", e);
+      return false;
+    } catch (KeeperException e) {
+      LOG.warn("Failed NamespaceJanitor chore", e);
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * @param enabled
+   */
+  public boolean setEnabled(final boolean enabled) {
+    return this.enabled.getAndSet(enabled);
+  }
+
+  boolean getEnabled() {
+    return this.enabled.get();
+  }
+
+  @Override
+  protected void chore() {
+    try {
+      if (this.enabled.get()) {
+        removeOrphans();
+      } else {
+        LOG.warn("NamepsaceJanitor disabled! Not running scan.");
+      }
+    } catch (IOException e) {
+      LOG.warn("Failed NamespaceJanitor chore", e);
+    } catch (KeeperException e) {
+      LOG.warn("Failed NamespaceJanitor chore", e);
+    }
+  }
+
+  private void removeOrphans() throws IOException, KeeperException {
+    //cache the info so we don't need to keep the master nsLock for long
+    //and not be wasteful with rpc calls
+    FileSystem fs = services.getMasterFileSystem().getFileSystem();
+    Set<String> descs = Sets.newHashSet();
+    for(NamespaceDescriptor ns : services.listNamespaceDescriptors()) {
+      descs.add(ns.getName());
+    }
+
+    //cleanup hdfs orphans
+    for (FileStatus nsStatus : FSUtils.listStatus(fs,
+        new Path(FSUtils.getRootDir(services.getConfiguration()), HConstants.BASE_NAMESPACE_DIR))) {
+      if (!descs.contains(nsStatus.getPath().getName()) &&
+          !NamespaceDescriptor.RESERVED_NAMESPACES.contains(nsStatus.getPath().getName())) {
+        boolean isEmpty = true;
+        for(FileStatus status : fs.listStatus(nsStatus.getPath())) {
+          if (!HConstants.HBASE_NON_TABLE_DIRS.contains(status.getPath().getName())) {
+            isEmpty = false;
+            break;
+          }
+        }
+        if(isEmpty) {
+          try {
+            if (!fs.delete(nsStatus.getPath(), true)) {
+              LOG.error("Failed to remove namespace directory: " + nsStatus.getPath());
+            }
+          } catch (IOException ex) {
+            LOG.error("Failed to remove namespace directory: " + nsStatus.getPath(),
+                ex);
+          }
+          LOG.debug("Removed namespace directory: "+nsStatus.getPath());
+        } else {
+          LOG.debug("Skipping non-empty namespace directory: " + nsStatus.getPath());
+        }
+      }
+    }
+
+    String baseZnode = ZooKeeperWatcher.namespaceZNode;
+    for(String child : ZKUtil.listChildrenNoWatch(services.getZooKeeper(), baseZnode)) {
+      if (!descs.contains(child) &&
+          !NamespaceDescriptor.RESERVED_NAMESPACES.contains(child)) {
+        String znode = ZKUtil.joinZNode(baseZnode, child);
+        try {
+          ZKUtil.deleteNode(services.getZooKeeper(), znode);
+          LOG.debug("Removed namespace znode: " + znode);
+        } catch (KeeperException ex) {
+          LOG.debug("Failed to remove namespace znode: " + znode, ex);
+        }
+      }
+    }
+
+  }
+}

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java Thu Aug  8 06:08:23 2013
@@ -29,6 +29,7 @@ import java.util.TreeMap;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.RegionTransition;
 import org.apache.hadoop.hbase.Server;
@@ -417,13 +418,13 @@ public class RegionStates {
    * @param tableName
    * @return Online regions from <code>tableName</code>
    */
-  public synchronized List<HRegionInfo> getRegionsOfTable(byte[] tableName) {
+  public synchronized List<HRegionInfo> getRegionsOfTable(TableName tableName) {
     List<HRegionInfo> tableRegions = new ArrayList<HRegionInfo>();
     // boundary needs to have table's name but regionID 0 so that it is sorted
     // before all table's regions.
     HRegionInfo boundary = new HRegionInfo(tableName, null, null, false, 0L);
     for (HRegionInfo hri: regionAssignments.tailMap(boundary).keySet()) {
-      if(!Bytes.equals(hri.getTableName(), tableName)) break;
+      if(!hri.getTableName().equals(tableName)) break;
       tableRegions.add(hri);
     }
     return tableRegions;
@@ -503,9 +504,10 @@ public class RegionStates {
    *
    * @return A clone of current assignments by table.
    */
-  protected Map<String, Map<ServerName, List<HRegionInfo>>> getAssignmentsByTable() {
-    Map<String, Map<ServerName, List<HRegionInfo>>> result =
-      new HashMap<String, Map<ServerName,List<HRegionInfo>>>();
+  protected Map<TableName, Map<ServerName, List<HRegionInfo>>>
+      getAssignmentsByTable() {
+    Map<TableName, Map<ServerName, List<HRegionInfo>>> result =
+      new HashMap<TableName, Map<ServerName,List<HRegionInfo>>>();
     synchronized (this) {
       if (!server.getConfiguration().getBoolean("hbase.master.loadbalance.bytable", false)) {
         Map<ServerName, List<HRegionInfo>> svrToRegions =
@@ -513,12 +515,12 @@ public class RegionStates {
         for (Map.Entry<ServerName, Set<HRegionInfo>> e: serverHoldings.entrySet()) {
           svrToRegions.put(e.getKey(), new ArrayList<HRegionInfo>(e.getValue()));
         }
-        result.put("ensemble", svrToRegions);
+        result.put(TableName.valueOf("ensemble"), svrToRegions);
       } else {
         for (Map.Entry<ServerName, Set<HRegionInfo>> e: serverHoldings.entrySet()) {
           for (HRegionInfo hri: e.getValue()) {
             if (hri.isMetaRegion()) continue;
-            String tablename = hri.getTableNameAsString();
+            TableName tablename = hri.getTableName();
             Map<ServerName, List<HRegionInfo>> svrToRegions = result.get(tablename);
             if (svrToRegions == null) {
               svrToRegions = new HashMap<ServerName, List<HRegionInfo>>(serverHoldings.size());

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableLockManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableLockManager.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableLockManager.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableLockManager.java Thu Aug  8 06:08:23 2013
@@ -27,6 +27,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.InterProcessLock;
 import org.apache.hadoop.hbase.InterProcessLock.MetadataHandler;
 import org.apache.hadoop.hbase.InterProcessReadWriteLock;
@@ -41,7 +42,6 @@ import org.apache.hadoop.hbase.zookeeper
 import org.apache.hadoop.hbase.zookeeper.lock.ZKInterProcessReadWriteLock;
 import org.apache.zookeeper.KeeperException;
 
-import com.google.protobuf.ByteString;
 import com.google.protobuf.InvalidProtocolBufferException;
 
 /**
@@ -104,7 +104,7 @@ public abstract class TableLockManager {
    * @param purpose Human readable reason for locking the table
    * @return A new TableLock object for acquiring a write lock
    */
-  public abstract TableLock writeLock(byte[] tableName, String purpose);
+  public abstract TableLock writeLock(TableName tableName, String purpose);
 
   /**
    * Returns a TableLock for locking the table for shared access among read-lock holders
@@ -112,7 +112,7 @@ public abstract class TableLockManager {
    * @param purpose Human readable reason for locking the table
    * @return A new TableLock object for acquiring a read lock
    */
-  public abstract TableLock readLock(byte[] tableName, String purpose);
+  public abstract TableLock readLock(TableName tableName, String purpose);
 
   /**
    * Visits all table locks(read and write), and lock attempts with the given callback
@@ -148,7 +148,7 @@ public abstract class TableLockManager {
    * @param tableName name of the table
    * @throws IOException If there is an unrecoverable error releasing the lock
    */
-  public abstract void tableDeleted(byte[] tableName)
+  public abstract void tableDeleted(TableName tableName)
       throws IOException;
 
   /**
@@ -186,11 +186,11 @@ public abstract class TableLockManager {
       }
     }
     @Override
-    public TableLock writeLock(byte[] tableName, String purpose) {
+    public TableLock writeLock(TableName tableName, String purpose) {
       return new NullTableLock();
     }
     @Override
-    public TableLock readLock(byte[] tableName, String purpose) {
+    public TableLock readLock(TableName tableName, String purpose) {
       return new NullTableLock();
     }
     @Override
@@ -200,7 +200,7 @@ public abstract class TableLockManager {
     public void reapWriteLocks() throws IOException {
     }
     @Override
-    public void tableDeleted(byte[] tableName) throws IOException {
+    public void tableDeleted(TableName tableName) throws IOException {
     }
     @Override
     public void visitAllLocks(MetadataHandler handler) throws IOException {
@@ -249,18 +249,16 @@ public abstract class TableLockManager {
 
     private static class TableLockImpl implements TableLock {
       long lockTimeoutMs;
-      byte[] tableName;
-      String tableNameStr;
+      TableName tableName;
       InterProcessLock lock;
       boolean isShared;
       ZooKeeperWatcher zkWatcher;
       ServerName serverName;
       String purpose;
 
-      public TableLockImpl(byte[] tableName, ZooKeeperWatcher zkWatcher,
+      public TableLockImpl(TableName tableName, ZooKeeperWatcher zkWatcher,
           ServerName serverName, long lockTimeoutMs, boolean isShared, String purpose) {
         this.tableName = tableName;
-        tableNameStr = Bytes.toString(tableName);
         this.zkWatcher = zkWatcher;
         this.serverName = serverName;
         this.lockTimeoutMs = lockTimeoutMs;
@@ -272,7 +270,7 @@ public abstract class TableLockManager {
       public void acquire() throws IOException {
         if (LOG.isTraceEnabled()) {
           LOG.trace("Attempt to acquire table " + (isShared ? "read" : "write") +
-            " lock on: " + tableNameStr + " for:" + purpose);
+            " lock on: " + tableName + " for:" + purpose);
         }
 
         lock = createTableLock();
@@ -283,47 +281,48 @@ public abstract class TableLockManager {
           } else {
             if (!lock.tryAcquire(lockTimeoutMs)) {
               throw new LockTimeoutException("Timed out acquiring " +
-                (isShared ? "read" : "write") + "lock for table:" + tableNameStr +
+                (isShared ? "read" : "write") + "lock for table:" + tableName +
                 "for:" + purpose + " after " + lockTimeoutMs + " ms.");
             }
           }
         } catch (InterruptedException e) {
-          LOG.warn("Interrupted acquiring a lock for " + tableNameStr, e);
+          LOG.warn("Interrupted acquiring a lock for " + tableName, e);
           Thread.currentThread().interrupt();
           throw new InterruptedIOException("Interrupted acquiring a lock");
         }
         if (LOG.isTraceEnabled()) LOG.trace("Acquired table " + (isShared ? "read" : "write")
-            + " lock on " + tableNameStr + " for " + purpose);
+            + " lock on " + tableName + " for " + purpose);
       }
 
       @Override
       public void release() throws IOException {
         if (LOG.isTraceEnabled()) {
           LOG.trace("Attempt to release table " + (isShared ? "read" : "write")
-              + " lock on " + tableNameStr);
+              + " lock on " + tableName);
         }
         if (lock == null) {
-          throw new IllegalStateException("Table " + tableNameStr +
+          throw new IllegalStateException("Table " + tableName +
             " is not locked!");
         }
 
         try {
           lock.release();
         } catch (InterruptedException e) {
-          LOG.warn("Interrupted while releasing a lock for " + tableNameStr);
+          LOG.warn("Interrupted while releasing a lock for " + tableName);
           Thread.currentThread().interrupt();
           throw new InterruptedIOException();
         }
         if (LOG.isTraceEnabled()) {
-          LOG.trace("Released table lock on " + tableNameStr);
+          LOG.trace("Released table lock on " + tableName);
         }
       }
 
       private InterProcessLock createTableLock() {
-        String tableLockZNode = ZKUtil.joinZNode(zkWatcher.tableLockZNode, tableNameStr);
+        String tableLockZNode = ZKUtil.joinZNode(zkWatcher.tableLockZNode,
+            tableName.getNameAsString());
 
         ZooKeeperProtos.TableLock data = ZooKeeperProtos.TableLock.newBuilder()
-          .setTableName(ByteString.copyFrom(tableName))
+          .setTableName(ProtobufUtil.toProtoTableName(tableName))
           .setLockOwner(ProtobufUtil.toServerName(serverName))
           .setThreadId(Thread.currentThread().getId())
           .setPurpose(purpose)
@@ -367,12 +366,12 @@ public abstract class TableLockManager {
     }
 
     @Override
-    public TableLock writeLock(byte[] tableName, String purpose) {
+    public TableLock writeLock(TableName tableName, String purpose) {
       return new TableLockImpl(tableName, zkWatcher,
           serverName, writeLockTimeoutMs, false, purpose);
     }
 
-    public TableLock readLock(byte[] tableName, String purpose) {
+    public TableLock readLock(TableName tableName, String purpose) {
       return new TableLockImpl(tableName, zkWatcher,
           serverName, readLockTimeoutMs, true, purpose);
     }
@@ -435,9 +434,9 @@ public abstract class TableLockManager {
     }
 
     @Override
-    public void tableDeleted(byte[] tableName) throws IOException {
+    public void tableDeleted(TableName tableName) throws IOException {
       //table write lock from DeleteHandler is already released, just delete the parent znode
-      String tableNameStr = Bytes.toString(tableName);
+      String tableNameStr = tableName.getNameAsString();
       String tableLockZNode = ZKUtil.joinZNode(zkWatcher.tableLockZNode, tableNameStr);
       try {
         ZKUtil.deleteNode(zkWatcher, tableLockZNode);

Added: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableNamespaceManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableNamespaceManager.java?rev=1511591&view=auto
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableNamespaceManager.java (added)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/TableNamespaceManager.java Thu Aug  8 06:08:23 2013
@@ -0,0 +1,224 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.master;
+
+import java.io.IOException;
+import java.util.NavigableSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.ZKNamespaceManager;
+import org.apache.hadoop.hbase.catalog.MetaReader;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.constraint.ConstraintException;
+import org.apache.hadoop.hbase.master.handler.CreateTableHandler;
+import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
+import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
+import org.apache.hadoop.hbase.util.Bytes;
+
+import com.google.common.collect.Sets;
+import org.apache.hadoop.hbase.util.FSUtils;
+
+/**
+ * This is a helper class used to manage the namespace
+ * metadata that is stored in {@see HConstants.NAMESPACE_TABLE_NAME}
+ * It also mirrors updates to the ZK store by forwarding updates to
+ * {@link org.apache.hadoop.hbase.ZKNamespaceManager}
+ */
+@InterfaceAudience.Private
+public class TableNamespaceManager {
+  private static final Log LOG = LogFactory.getLog(TableNamespaceManager.class);
+
+  private Configuration conf;
+  private MasterServices masterServices;
+  private HTable table;
+  private ZKNamespaceManager zkNamespaceManager;
+
+  public TableNamespaceManager(MasterServices masterServices) throws IOException {
+    this.masterServices = masterServices;
+    this.conf = masterServices.getConfiguration();
+  }
+
+  public void start() throws IOException {
+    TableName tableName = TableName.NAMESPACE_TABLE_NAME;
+    try {
+      if (!MetaReader.tableExists(masterServices.getCatalogTracker(),
+          tableName)) {
+        LOG.info("Namespace table not found. Creating...");
+        createNamespaceTable(masterServices);
+      }
+    } catch (InterruptedException e) {
+      throw new IOException("Wait for namespace table assignment interrupted", e);
+    }
+    table = new HTable(conf, tableName);
+    zkNamespaceManager = new ZKNamespaceManager(masterServices.getZooKeeper());
+    zkNamespaceManager.start();
+
+    if (get(NamespaceDescriptor.DEFAULT_NAMESPACE.getName()) == null) {
+      create(NamespaceDescriptor.DEFAULT_NAMESPACE);
+    }
+    if (get(NamespaceDescriptor.SYSTEM_NAMESPACE.getName()) == null) {
+      create(NamespaceDescriptor.SYSTEM_NAMESPACE);
+    }
+
+    ResultScanner scanner = table.getScanner(HTableDescriptor.NAMESPACE_FAMILY_INFO_BYTES);
+    try {
+      for(Result result : scanner) {
+        NamespaceDescriptor ns =
+            ProtobufUtil.toNamespaceDescriptor(
+                HBaseProtos.NamespaceDescriptor.parseFrom(
+                    result.getColumnLatest(HTableDescriptor.NAMESPACE_FAMILY_INFO_BYTES,
+                        HTableDescriptor.NAMESPACE_COL_DESC_BYTES).getValue()));
+        zkNamespaceManager.update(ns);
+      }
+    } finally {
+      scanner.close();
+    }
+  }
+
+
+  public synchronized NamespaceDescriptor get(String name) throws IOException {
+    Result res = table.get(new Get(Bytes.toBytes(name)));
+    if (res.isEmpty()) {
+      return null;
+    }
+    return
+        ProtobufUtil.toNamespaceDescriptor(
+            HBaseProtos.NamespaceDescriptor.parseFrom(
+                res.getColumnLatest(HTableDescriptor.NAMESPACE_FAMILY_INFO_BYTES,
+                    HTableDescriptor.NAMESPACE_COL_DESC_BYTES).getValue()));
+  }
+
+  public synchronized void create(NamespaceDescriptor ns) throws IOException {
+    if (get(ns.getName()) != null) {
+      throw new ConstraintException("Namespace "+ns.getName()+" already exists");
+    }
+    FileSystem fs = masterServices.getMasterFileSystem().getFileSystem();
+    fs.mkdirs(FSUtils.getNamespaceDir(
+        masterServices.getMasterFileSystem().getRootDir(), ns.getName()));
+    upsert(ns);
+  }
+
+  public synchronized void update(NamespaceDescriptor ns) throws IOException {
+    if (get(ns.getName()) == null) {
+      throw new ConstraintException("Namespace "+ns.getName()+" does not exist");
+    }
+    upsert(ns);
+  }
+
+  private void upsert(NamespaceDescriptor ns) throws IOException {
+    Put p = new Put(Bytes.toBytes(ns.getName()));
+    p.add(HTableDescriptor.NAMESPACE_FAMILY_INFO_BYTES,
+        HTableDescriptor.NAMESPACE_COL_DESC_BYTES,
+        ProtobufUtil.toProtoNamespaceDescriptor(ns).toByteArray());
+    table.put(p);
+    try {
+      zkNamespaceManager.update(ns);
+    } catch(IOException ex) {
+      String msg = "Failed to update namespace information in ZK. Aborting.";
+      LOG.fatal(msg, ex);
+      masterServices.abort(msg, ex);
+    }
+  }
+
+  public synchronized void remove(String name) throws IOException {
+    if (NamespaceDescriptor.RESERVED_NAMESPACES.contains(name)) {
+      throw new ConstraintException("Reserved namespace "+name+" cannot be removed.");
+    }
+    int tableCount = masterServices.getTableDescriptorsByNamespace(name).size();
+    if (tableCount > 0) {
+      throw new ConstraintException("Only empty namespaces can be removed. " +
+          "Namespace "+name+" has "+tableCount+" tables");
+    }
+    Delete d = new Delete(Bytes.toBytes(name));
+    table.delete(d);
+    //don't abort if cleanup isn't complete
+    //it will be replaced on new namespace creation
+    zkNamespaceManager.remove(name);
+    FileSystem fs = masterServices.getMasterFileSystem().getFileSystem();
+    for(FileStatus status :
+            fs.listStatus(FSUtils.getNamespaceDir(
+                masterServices.getMasterFileSystem().getRootDir(), name))) {
+      if (!HConstants.HBASE_NON_TABLE_DIRS.contains(status.getPath().getName())) {
+        throw new IOException("Namespace directory contains table dir: "+status.getPath());
+      }
+    }
+    if (!fs.delete(FSUtils.getNamespaceDir(
+        masterServices.getMasterFileSystem().getRootDir(), name), true)) {
+      throw new IOException("Failed to remove namespace: "+name);
+    }
+  }
+
+  public synchronized NavigableSet<NamespaceDescriptor> list() throws IOException {
+    NavigableSet<NamespaceDescriptor> ret =
+        Sets.newTreeSet(NamespaceDescriptor.NAMESPACE_DESCRIPTOR_COMPARATOR);
+    ResultScanner scanner = table.getScanner(HTableDescriptor.NAMESPACE_FAMILY_INFO_BYTES);
+    try {
+      for(Result r : scanner) {
+          ret.add(ProtobufUtil.toNamespaceDescriptor(
+              HBaseProtos.NamespaceDescriptor.parseFrom(
+                r.getColumnLatest(HTableDescriptor.NAMESPACE_FAMILY_INFO_BYTES,
+                    HTableDescriptor.NAMESPACE_COL_DESC_BYTES).getValue())));
+      }
+    } finally {
+      scanner.close();
+    }
+    return ret;
+  }
+
+  private void createNamespaceTable(MasterServices masterServices) throws IOException, InterruptedException {
+    HRegionInfo newRegions[] = new HRegionInfo[]{
+        new HRegionInfo(HTableDescriptor.NAMESPACE_TABLEDESC.getTableName(), null, null)};
+
+    //we need to create the table this way to bypass
+    //checkInitialized
+    masterServices.getExecutorService()
+        .submit(new CreateTableHandler(masterServices,
+            masterServices.getMasterFileSystem(),
+            HTableDescriptor.NAMESPACE_TABLEDESC,
+            masterServices.getConfiguration(),
+            newRegions,
+            masterServices).prepare());
+    //wait for region to be online
+    int tries = conf.getInt("hbase.master.namespace.init.timeout", 600);
+    while(masterServices.getAssignmentManager()
+        .getRegionStates().getRegionServerOfRegion(newRegions[0]) == null &&
+        tries > 0) {
+      Thread.sleep(100);
+      tries--;
+    }
+    if (tries <= 0) {
+      throw new IOException("Failed to create namespace table.");
+    }
+  }
+}

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java Thu Aug  8 06:08:23 2013
@@ -39,7 +39,6 @@ import org.apache.hadoop.hbase.ServerNam
 import org.apache.hadoop.hbase.master.AssignmentManager;
 import org.apache.hadoop.hbase.master.LoadBalancer;
 import org.apache.hadoop.hbase.master.MasterServices;
-import org.apache.hadoop.hbase.util.Bytes;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ArrayListMultimap;
@@ -145,7 +144,7 @@ public abstract class BaseLoadBalancer i
         regionPerServerIndex = 0;
 
         for (HRegionInfo region : entry.getValue()) {
-          String tableName = region.getTableNameAsString();
+          String tableName = region.getTableName().getNameAsString();
           Integer idx = tablesToIndex.get(tableName);
           if (idx == null) {
             tables.add(tableName);

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredNodeAssignmentHelper.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredNodeAssignmentHelper.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredNodeAssignmentHelper.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/FavoredNodeAssignmentHelper.java Thu Aug  8 06:08:23 2013
@@ -33,6 +33,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.ServerName;
@@ -100,7 +101,7 @@ public class FavoredNodeAssignmentHelper
    * @throws IOException
    */
   public static Map<HRegionInfo, ServerName> fullScan(
-      CatalogTracker catalogTracker, final Set<String> disabledTables,
+      CatalogTracker catalogTracker, final Set<TableName> disabledTables,
       final boolean excludeOfflinedSplitParents,
       FavoredNodeLoadBalancer balancer) throws IOException {
     final Map<HRegionInfo, ServerName> regions =
@@ -114,9 +115,9 @@ public class FavoredNodeAssignmentHelper
         Pair<HRegionInfo, ServerName> region = HRegionInfo.getHRegionInfoAndServerName(r);
         HRegionInfo hri = region.getFirst();
         if (hri  == null) return true;
-        if (hri.getTableNameAsString() == null) return true;
+        if (hri.getTableName() == null) return true;
         if (disabledTables.contains(
-            hri.getTableNameAsString())) return true;
+            hri.getTableName())) return true;
         // Are we to include split parents in the list?
         if (excludeOfflinedSplitParents && hri.isSplitParent()) return true;
         regions.put(hri, region.getSecond());

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/RegionLocationFinder.java Thu Aug  8 06:08:23 2013
@@ -31,13 +31,13 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.ClusterStatus;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HDFSBlocksDistribution;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.master.MasterServices;
 import org.apache.hadoop.hbase.regionserver.HRegion;
-import org.apache.hadoop.hbase.util.Bytes;
 
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
@@ -144,15 +144,15 @@ class RegionLocationFinder {
    * @return HTableDescriptor
    * @throws IOException
    */
-  protected HTableDescriptor getTableDescriptor(byte[] tableName) throws IOException {
+  protected HTableDescriptor getTableDescriptor(TableName tableName) throws IOException {
     HTableDescriptor tableDescriptor = null;
     try {
       if (this.services != null) {
-        tableDescriptor = this.services.getTableDescriptors().get(Bytes.toString(tableName));
+        tableDescriptor = this.services.getTableDescriptors().get(tableName);
       }
     } catch (FileNotFoundException fnfe) {
       LOG.debug("FileNotFoundException during getTableDescriptors." + " Current table name = "
-          + Bytes.toStringBinary(tableName), fnfe);
+          + tableName, fnfe);
     }
 
     return tableDescriptor;

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java?rev=1511591&r1=1511590&r2=1511591&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java Thu Aug  8 06:08:23 2013
@@ -92,7 +92,7 @@ public class ClosedRegionHandler extends
     LOG.debug("Handling CLOSED event for " + regionInfo.getEncodedName());
     // Check if this table is being disabled or not
     if (this.assignmentManager.getZKTable().
-        isDisablingOrDisabledTable(this.regionInfo.getTableNameAsString())) {
+        isDisablingOrDisabledTable(this.regionInfo.getTableName())) {
       assignmentManager.offlineDisabledRegion(regionInfo);
       return;
     }



Mime
View raw message