/** * 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.crosssite.verifier; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableNotDisabledException; import org.apache.hadoop.hbase.TableNotEnabledException; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.crosssite.CrossSiteHBaseAdmin; import org.apache.hadoop.hbase.crosssite.ClusterInfo; import org.apache.hadoop.hbase.crosssite.CrossSiteUtil; import org.apache.hadoop.hbase.crosssite.locator.ClusterLocator; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.zookeeper.ZKUtil; /** * Util class that is used by the CSBTClusterVerifier * */ public class ClusterVerifierUtil { private static final Log LOG = LogFactory.getLog(ClusterVerifierUtil.class); /** * Helps to create the missing tables in the individual cluster along with * creaeting them in the peers. This is similar to the createTableInternal in * CrossSiteHBaseAdmin except that it does not create the table znodes and * only creates the tables using the individual cluster admin. * * @param clusterLocator * @param tableSplitKeys * @param tableDesc * @param clusterName * @param ci * @throws IOException */ public static void createTableInCluster(HTableDescriptor desc, byte[][] tableSplitKeys, ClusterLocator clusterLocator, String clusterName, ClusterInfo ci, CrossSiteHBaseAdmin crossSiteHBaseAdmin) throws IOException { String tableName = desc.getNameAsString(); boolean createTableInPeers = isReplicatedTable(desc); HBaseAdmin admin = createHBaseAmin(crossSiteHBaseAdmin.getConfiguration(), ci.getAddress()); String clusterTableName = CrossSiteUtil.getClusterTableName(tableName, clusterName); HTableDescriptor htd = new HTableDescriptor(desc); htd.setName(Bytes.toBytes(clusterTableName)); byte[][] newSplitKeys = clusterLocator.getSplitKeys(clusterName, tableSplitKeys); createTable(clusterName, admin, tableName, htd, newSplitKeys); if (createTableInPeers) { HTableDescriptor peerHtd = new HTableDescriptor(desc); for (HColumnDescriptor hcd : peerHtd.getColumnFamilies()) { // only create the CFs that have the scope as 1. if (hcd.getScope() > 0) { hcd.setScope(0); } else { peerHtd.removeFamily(hcd.getName()); } } if (ci.getPeers() != null && !ci.getPeers().isEmpty()) { for (ClusterInfo peer : ci.getPeers()) { HBaseAdmin peerAdmin = createHBaseAmin(crossSiteHBaseAdmin.getConfiguration(), peer.getAddress()); String peerTableName = CrossSiteUtil.getPeerClusterTableName(tableName, clusterName, peer.getName()); if (LOG.isDebugEnabled()) { LOG.debug("Creating table " + peerTableName + " at peer " + peer); } try { boolean peerTableExists = peerAdmin.tableExists(peerTableName); if (!peerTableExists) { LOG.debug("The table " + peerTableName + " does not exist. Hence creating"); peerHtd.setName(Bytes.toBytes(peerTableName)); createTable(peer.getName(), peerAdmin, peerTableName, peerHtd, newSplitKeys); } else { LOG.debug("The table " + peerTableName + " available already."); } } finally { try { peerAdmin.close(); } catch (IOException e) { LOG.warn("Fail to close the HBaseAdmin of peers", e); } } } } } if (LOG.isDebugEnabled()) { LOG.debug("Created table " + clusterTableName + " in the cluster " + clusterName); } LOG.info("The cross site table " + desc.getNameAsString() + " is created"); // add the znodes to the {tableName}. return; } private static void createTable(final String clusterName, HBaseAdmin admin, String clusterTableName, HTableDescriptor htd, byte[][] newSplitKeys) throws IOException { if (LOG.isDebugEnabled()) { LOG.debug("Creating table " + clusterTableName + " in the cluster " + clusterName); } admin.createTable(htd, newSplitKeys); if (LOG.isDebugEnabled()) { LOG.debug("Created table " + clusterTableName + " in the cluster " + clusterName); } } /** * Creates HBaseAdmin * @param baseConf * @param clusterAddress * @return * @throws IOException */ public static HBaseAdmin createHBaseAmin(Configuration baseConf, String clusterAddress) throws IOException { Configuration clusterConf = new Configuration(baseConf); ZKUtil.applyClusterKeyToConf(clusterConf, clusterAddress); return new HBaseAdmin(clusterConf); } /** * Replicated table * @param htd * @return */ public static boolean isReplicatedTable(HTableDescriptor htd) { boolean replicationEnabled = false; for (HColumnDescriptor hcd : htd.getColumnFamilies()) { replicationEnabled = (hcd.getScope() > 0); if (replicationEnabled) { break; } } return replicationEnabled; } public static void enableTable(HBaseAdmin admin, String tableName) throws IOException { try { admin.enableTable(tableName); } catch (TableNotDisabledException e) { // Supress the TableNotDisabledException. } } public static void disableTable(HBaseAdmin admin, String tableName) throws IOException { try { admin.disableTable(tableName); } catch (TableNotEnabledException e) { // Supress the TableNotEnabledException. } } }