org.kiji.schema.tools.LsTool.java Source code

Java tutorial

Introduction

Here is the source code for org.kiji.schema.tools.LsTool.java

Source

/**
 * (c) Copyright 2012 WibiData, Inc.
 *
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * Licensed 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.kiji.schema.tools;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import com.google.common.base.Joiner;
import com.google.common.collect.Sets;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.kiji.annotations.ApiAudience;
import org.kiji.schema.KConstants;
import org.kiji.schema.Kiji;
import org.kiji.schema.KijiColumnName;
import org.kiji.schema.KijiTable;
import org.kiji.schema.KijiURI;
import org.kiji.schema.hbase.HBaseFactory;
import org.kiji.schema.layout.KijiTableLayout;
import org.kiji.schema.layout.KijiTableLayout.LocalityGroupLayout.FamilyLayout;
import org.kiji.schema.layout.KijiTableLayout.LocalityGroupLayout.FamilyLayout.ColumnLayout;
import org.kiji.schema.util.ResourceUtils;

/**
 * Command-line tool to explore kiji table data like the 'ls' command of a unix shell.
 *
 * List all kiji instances:
 * <pre>
 *   kiji ls
 *   kiji ls kiji://.env
 *   kiji ls kiji://localhost:2181
 *   kiji ls kiji://{host1,host2}:2181
 * </pre>
 *
 * List all kiji tables:
 * <pre>
 *   kiji ls default
 *   kiji ls kiji://.env/default
 * </pre>
 *
 * List all columns in a kiji table 'table_foo':
 * <pre>
 *   kiji ls default/table_foo
 *   kiji ls kiji://.env/default/table_foo
 * </pre>
 *
 */
@ApiAudience.Private
public final class LsTool extends BaseTool {
    private static final Logger LOG = LoggerFactory.getLogger(LsTool.class);

    /** {@inheritDoc} */
    @Override
    public String getName() {
        return "ls";
    }

    /** {@inheritDoc} */
    @Override
    public String getDescription() {
        return "List Kiji instances, tables and columns.";
    }

    /** {@inheritDoc} */
    @Override
    public String getCategory() {
        return "Data";
    }

    /** {@inheritDoc} */
    @Override
    public String getUsageString() {
        return "Usage:\n" + "    kiji ls [flags...] [<kiji-uri>...] \n" + "\n" + "Example:\n"
                + "  Listing the Kiji instances from the default HBase cluster:\n" + "    kiji ls\n"
                + "    kiji ls kiji://.env\n" + "\n"
                + "  Listing the Kiji tables from the Kiji instance named 'default':\n" + "    kiji ls default\n"
                + "    kiji ls kiji://.env/default\n" + "\n" + "  Listing the columns in the Kiji table 'table':\n"
                + "    kiji ls default/table\n" + "    kiji ls kiji://.env/default/table\n"
                + "    kiji ls kiji://localhost:2181/default/table\n";
    }

    /**
     * Lists all kiji instances.
     *
     * @param hbaseURI URI of the HBase instance to list the content of.
     * @return A program exit code (zero on success).
     * @throws IOException If there is an error.
     */
    private int listInstances(KijiURI hbaseURI) throws IOException {
        for (String instanceName : getInstanceNames(hbaseURI)) {
            getPrintStream().println(KijiURI.newBuilder(hbaseURI).withInstanceName(instanceName).build());
        }
        return SUCCESS;
    }

    /**
     * Returns a set of instance names.
     *
     * @param hbaseURI URI of the HBase instance to list the content of.
     * @return ordered set of instance names.
     * @throws IOException on I/O error.
     */
    protected static Set<String> getInstanceNames(KijiURI hbaseURI) throws IOException {
        // TODO(SCHEMA-188): Consolidate this logic in a single central place:
        final Configuration conf = HBaseConfiguration.create();
        conf.set(HConstants.ZOOKEEPER_QUORUM, Joiner.on(",").join(hbaseURI.getZookeeperQuorumOrdered()));
        conf.setInt(HConstants.ZOOKEEPER_CLIENT_PORT, hbaseURI.getZookeeperClientPort());
        final HBaseAdmin hbaseAdmin = HBaseFactory.Provider.get().getHBaseAdminFactory(hbaseURI).create(conf);

        try {
            final Set<String> instanceNames = Sets.newTreeSet();
            for (HTableDescriptor hTableDescriptor : hbaseAdmin.listTables()) {
                final String instanceName = parseInstanceName(hTableDescriptor.getNameAsString());
                if (null != instanceName) {
                    instanceNames.add(instanceName);
                }
            }
            return instanceNames;
        } finally {
            ResourceUtils.closeOrLog(hbaseAdmin);
        }
    }

    /**
     * Parses a table name for a kiji instance name.
     *
     * @param kijiTableName The table name to parse
     * @return instance name (or null if none found)
     */
    protected static String parseInstanceName(String kijiTableName) {
        final String[] parts = StringUtils.split(kijiTableName, '\u0000', '.');
        if (parts.length < 3 || !KijiURI.KIJI_SCHEME.equals(parts[0])) {
            return null;
        }
        return parts[1];
    }

    /**
     * Lists all the tables in a kiji instance.
     *
     * @param kiji Kiji instance to list the tables of.
     * @return A program exit code (zero on success).
     * @throws IOException If there is an error.
     */
    private int listTables(Kiji kiji) throws IOException {
        for (String name : kiji.getTableNames()) {
            getPrintStream().println(kiji.getURI() + name);
        }
        return SUCCESS;
    }

    /** {@inheritDoc} */
    @Override
    protected int run(List<String> nonFlagArgs) throws Exception {
        if (nonFlagArgs.isEmpty()) {
            nonFlagArgs.add(KConstants.DEFAULT_HBASE_URI);
        }

        int status = SUCCESS;
        for (String arg : nonFlagArgs) {
            status = (run(KijiURI.newBuilder(arg).build()) == SUCCESS) ? status : FAILURE;
        }
        return status;
    }

    /**
     * Lists instances, tables, or columns in a kiji URI.
     * Can be recursively called by run(List<String>).
     *
     * @param argURI Kiji URI from which to list instances, tables, or columns.
     * @return A program exit code (zero on success).
     * @throws Exception If there is an error.
     */
    private int run(final KijiURI argURI) throws Exception {
        if (argURI.getZookeeperQuorum() == null) {
            getPrintStream().printf("Specify a cluster with argument: kiji://zookeeper-quorum%n");
            return FAILURE;
        }

        if (argURI.getInstance() == null) {
            // List instances in this kiji instance.
            return listInstances(argURI);
        }

        final Kiji kiji = Kiji.Factory.open(argURI, getConf());
        try {
            if (argURI.getTable() == null) {
                // List tables in this kiji instance.
                return listTables(kiji);
            }

            final KijiTable table = kiji.openTable(argURI.getTable());
            try {
                final KijiTableLayout tableLayout = table.getLayout();
                for (FamilyLayout family : tableLayout.getFamilies()) {
                    if (family.isMapType()) {
                        getPrintStream().println(KijiURI.newBuilder(table.getURI())
                                .addColumnName(KijiColumnName.create(family.getName())).build());
                    } else {
                        for (ColumnLayout column : family.getColumns()) {
                            getPrintStream().println(KijiURI.newBuilder(table.getURI())
                                    .addColumnName(KijiColumnName.create(family.getName(), column.getName()))
                                    .build());
                        }
                    }
                }
                return SUCCESS;
            } finally {
                ResourceUtils.releaseOrLog(table);
            }
        } finally {
            ResourceUtils.releaseOrLog(kiji);
        }
    }

    /**
     * Program entry point.
     *
     * @param args The command-line arguments.
     * @throws Exception If there is an error.
     */
    public static void main(String[] args) throws Exception {
        System.exit(new KijiToolLauncher().run(new LsTool(), args));
    }
}