Return-Path: X-Original-To: apmail-hbase-commits-archive@www.apache.org Delivered-To: apmail-hbase-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 1B64A10694 for ; Thu, 8 Aug 2013 06:09:54 +0000 (UTC) Received: (qmail 41112 invoked by uid 500); 8 Aug 2013 06:09:53 -0000 Delivered-To: apmail-hbase-commits-archive@hbase.apache.org Received: (qmail 41067 invoked by uid 500); 8 Aug 2013 06:09:53 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 41058 invoked by uid 99); 8 Aug 2013 06:09:53 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Aug 2013 06:09:53 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_FRT_STOCK2 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Aug 2013 06:09:48 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 1705D2388B46; Thu, 8 Aug 2013 06:08:54 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@hbase.apache.org From: stack@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130808060854.1705D2388B46@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 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 disabledOrDisablingOrEnabling = ZKTable.getDisabledOrDisablingTables(zooKeeper); + disabledOrDisablingOrEnabling.addAll(ZKTable.getEnablingTables(zooKeeper)); + // Scan META for all system regions, skipping any disabled tables + Map allRegions = + MetaReader.fullScan(catalogTracker, disabledOrDisablingOrEnabling, true); + for(Iterator 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 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 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>> assignmentsByTable = + Map>> assignmentsByTable = this.assignmentManager.getRegionStates().getAssignmentsByTable(); List plans = new ArrayList(); @@ -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 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 getTableRegionForRow( - final byte [] tableName, final byte [] rowKey) + final TableName tableName, final byte [] rowKey) throws IOException { final AtomicReference> result = new AtomicReference>(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 descriptors = new ArrayList(); - + List tableNameList = new ArrayList(); + 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 listNamespaceDescriptors() throws IOException { + return Lists.newArrayList(tableNamespaceManager.list()); + } + + public List 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ctx = null; for (MasterEnvironment env : coprocessors) { @@ -1114,7 +1232,7 @@ public class MasterCoprocessorHost } } - public boolean preGetTableDescriptors(final List tableNamesList, + public boolean preGetTableDescriptors(final List tableNamesList, final List descriptors) throws IOException { boolean bypass = false; ObserverContext 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 listNamespaceDescriptors() throws IOException; + + /** + * Get list of table descriptors by namespace + * @param name namespace name + * @return + * @throws IOException + */ + public List 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 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 tableName */ - public synchronized List getRegionsOfTable(byte[] tableName) { + public synchronized List getRegionsOfTable(TableName tableName) { List tableRegions = new ArrayList(); // 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>> getAssignmentsByTable() { - Map>> result = - new HashMap>>(); + protected Map>> + getAssignmentsByTable() { + Map>> result = + new HashMap>>(); synchronized (this) { if (!server.getConfiguration().getBoolean("hbase.master.loadbalance.bytable", false)) { Map> svrToRegions = @@ -513,12 +515,12 @@ public class RegionStates { for (Map.Entry> e: serverHoldings.entrySet()) { svrToRegions.put(e.getKey(), new ArrayList(e.getValue())); } - result.put("ensemble", svrToRegions); + result.put(TableName.valueOf("ensemble"), svrToRegions); } else { for (Map.Entry> e: serverHoldings.entrySet()) { for (HRegionInfo hri: e.getValue()) { if (hri.isMetaRegion()) continue; - String tablename = hri.getTableNameAsString(); + TableName tablename = hri.getTableName(); Map> svrToRegions = result.get(tablename); if (svrToRegions == null) { svrToRegions = new HashMap>(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 list() throws IOException { + NavigableSet 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 fullScan( - CatalogTracker catalogTracker, final Set disabledTables, + CatalogTracker catalogTracker, final Set disabledTables, final boolean excludeOfflinedSplitParents, FavoredNodeLoadBalancer balancer) throws IOException { final Map regions = @@ -114,9 +115,9 @@ public class FavoredNodeAssignmentHelper Pair 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; }