Java tutorial
/** * (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)); } }