org.apache.hadoop.hbase.index.client.IndexAdmin.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hbase.index.client.IndexAdmin.java

Source

/**
 * 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.index.client;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.TableNotEnabledException;
import org.apache.hadoop.hbase.TableNotFoundException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.MetaScanner;
import org.apache.hadoop.hbase.client.RegionOfflineException;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitor;
import org.apache.hadoop.hbase.index.Constants;
import org.apache.hadoop.hbase.index.util.IndexUtils;
import org.apache.hadoop.hbase.util.Bytes;

/**
 * Extension of HBaseAdmin to perform index related operations. This also should be used when we
 * create table with index details, and other admin operations on indexed table.
 */
public class IndexAdmin extends HBaseAdmin {
    private final Log LOG = LogFactory.getLog(this.getClass().getName());

    public IndexAdmin(Configuration c) throws IOException {
        super(c);
    }

    public IndexAdmin(HConnection connection) throws MasterNotRunningException, ZooKeeperConnectionException {
        super(connection);
    }

    @Override
    public void createTable(final HTableDescriptor desc, byte[][] splitKeys) throws IOException {
        try {
            createTableAsync(desc, splitKeys);
        } catch (SocketTimeoutException ste) {
            LOG.warn("Creating " + desc.getNameAsString() + " took too long", ste);
        }
        int numRegs = splitKeys == null ? 1 : splitKeys.length + 1;
        int prevRegCount = 0;

        MetaScannerVisitorBaseWithTableName userTableVisitor = null;
        MetaScannerVisitorBaseWithTableName indexTableVisitor = null;
        boolean indexedHTD = desc.getValue(Constants.INDEX_SPEC_KEY) != null;

        for (int tries = 0; tries < this.numRetries * this.retryLongerMultiplier; ++tries) {

            AtomicInteger actualRegCount = null;
            // Wait for new table to come on-line
            if (userTableVisitor == null) {
                userTableVisitor = new MetaScannerVisitorBaseWithTableName(desc.getNameAsString());
            }
            actualRegCount = userTableVisitor.getActualRgnCnt();
            actualRegCount.set(0);
            MetaScanner.metaScan(getConfiguration(), getConnection(), userTableVisitor, desc.getTableName());
            if (actualRegCount.get() != numRegs) {
                if (tries == this.numRetries * this.retryLongerMultiplier - 1) {
                    throw new RegionOfflineException("Only " + actualRegCount.get() + " of " + numRegs
                            + " regions are online; retries exhausted.");
                }
                try { // Sleep
                    Thread.sleep(getPauseTime(tries));
                } catch (InterruptedException e) {
                    throw new InterruptedIOException("Interrupted when opening" + " regions; "
                            + actualRegCount.get() + " of " + numRegs + " regions processed so far");
                }
                if (actualRegCount.get() > prevRegCount) { // Making progress
                    prevRegCount = actualRegCount.get();
                    tries = -1;
                }
            } else {
                if (indexedHTD) {
                    TableName indexTableName = TableName.valueOf(IndexUtils.getIndexTableName(desc.getName()));
                    if (indexTableVisitor == null) {
                        indexTableVisitor = new MetaScannerVisitorBaseWithTableName(
                                indexTableName.getNameAsString());
                    }
                    actualRegCount = indexTableVisitor.getActualRgnCnt();
                    actualRegCount.set(0);
                    MetaScanner.metaScan(getConfiguration(), getConnection(), indexTableVisitor, indexTableName);
                    if (actualRegCount.get() != numRegs) {
                        if (tries == this.numRetries * this.retryLongerMultiplier - 1) {
                            throw new RegionOfflineException("Only " + actualRegCount.get() + " of " + numRegs
                                    + " regions are online; retries exhausted.");
                        }
                        try { // Sleep
                            Thread.sleep(getPauseTime(tries));
                        } catch (InterruptedException e) {
                            throw new InterruptedIOException("Interrupted when opening" + " regions; "
                                    + actualRegCount.get() + " of " + numRegs + " regions processed so far");
                        }
                        if (actualRegCount.get() > prevRegCount) { // Making progress
                            prevRegCount = actualRegCount.get();
                            tries = -1;
                        }
                    } else if (isTableEnabled(indexTableName)) {
                        return;
                    }
                } else if (isTableEnabled(desc.getName())) {
                    return;
                }
            }
        }
        throw new TableNotEnabledException(
                "Retries exhausted while still waiting for table: " + desc.getNameAsString() + " to be enabled");
    }

    static class MetaScannerVisitorBaseWithTableName implements MetaScannerVisitor {
        byte[] tableName = null;
        AtomicInteger actualRegCount = new AtomicInteger(0);

        MetaScannerVisitorBaseWithTableName(String tableName) {
            this.tableName = Bytes.toBytes(tableName);
        }

        AtomicInteger getActualRgnCnt() {
            return actualRegCount;
        }

        @Override
        public void close() throws IOException {
        }

        @Override
        public boolean processRow(Result rowResult) throws IOException {
            HRegionInfo info = HRegionInfo.getHRegionInfo(rowResult);
            // If regioninfo is null, skip this row
            if (info == null) {
                return true;
            }
            if (!(Bytes.equals(info.getTable().getName(), tableName))) {
                return false;
            }
            ServerName serverName = HRegionInfo.getServerName(rowResult);
            // Make sure that regions are assigned to server
            if (!(info.isOffline() || info.isSplit()) && serverName != null
                    && serverName.getHostAndPort() != null) {
                actualRegCount.incrementAndGet();
            }
            return true;
        }
    }

    @Override
    public boolean isTableEnabled(TableName tableName) throws IOException {
        if (!tableExists(tableName)) {
            throw new TableNotFoundException(tableName);
        }
        boolean indexEnabled = getConfiguration().getBoolean("hbase.use.secondary.index", false);
        if (!indexEnabled) {
            return getConnection().isTableEnabled(tableName);
        } else {
            boolean isTableEnabled = getConnection().isTableEnabled(tableName);
            if (isTableEnabled && !IndexUtils.isIndexTable(tableName.getNameAsString())) {
                TableName indexTableName = TableName
                        .valueOf(IndexUtils.getIndexTableName(tableName.getNameAsString()));
                if (getConnection().isTableAvailable(indexTableName)) {
                    return getConnection().isTableEnabled(indexTableName);
                }
                return true;
            }
            return isTableEnabled;
        }
    }

    @Override
    public boolean isTableDisabled(TableName tableName) throws IOException {
        if (!tableExists(tableName)) {
            throw new TableNotFoundException(tableName);
        }
        boolean indexEnabled = getConfiguration().getBoolean("hbase.use.secondary.index", false);
        if (!indexEnabled) {
            return getConnection().isTableDisabled(tableName);
        } else {
            boolean isTableDisabled = getConnection().isTableDisabled(tableName);
            if (isTableDisabled && !IndexUtils.isIndexTable(tableName.getNameAsString())) {
                TableName indexTableName = TableName
                        .valueOf(IndexUtils.getIndexTableName(tableName.getNameAsString()));
                if (getConnection().isTableAvailable(indexTableName)) {
                    return getConnection().isTableDisabled(indexTableName);
                }
                return true;
            }
            return isTableDisabled;
        }
    }

}