Package org.kiji.schema.tools

Source Code of org.kiji.schema.tools.SchemaTableTool

/**
* (c) Copyright 2013 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.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import com.google.common.base.Preconditions;
import org.apache.avro.Schema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.kiji.annotations.ApiAudience;
import org.kiji.common.flags.Flag;
import org.kiji.schema.InternalKijiError;
import org.kiji.schema.Kiji;
import org.kiji.schema.KijiSchemaTable;
import org.kiji.schema.KijiSchemaTable.SchemaEntry;
import org.kiji.schema.KijiURI;
import org.kiji.schema.util.ByteArrayFormatter;
import org.kiji.schema.util.BytesKey;
/**
* Command-line tool for inspecting and modifying the Schema table.
*
* To register a new schema from a file:
* <pre>
*   kiji schema-table kiji://hbase-address/instance-name/ \
*       --register=path/to/schema/definition
* </pre>
*
* To look up a schema's id and hash from a schema definition:
* <pre>
*   kiji schema-table kiji://hbase-address/instance-name/ \
*       --lookup=path/to/schema/definition
* </pre>
*
* To get a schema definition and hash from a UID:
* <pre>
*   kiji schema-table kiji://hbase-address/instance-name/ \
*       --get-schema-by-id=2 \
*       [--output=path/to/schema/write/definition]
* </pre>
*
* To get a schema definition and UID from a hash:
* <pre>
*   kiji schema-table kiji://hbase-address/instance-name/ \
*       --get-schema-by-hash=ef:52:4e:a1:b9:1e:73:17:3d:93:8a:de:36:c1:db:32 \
*       [--output=path/to/schema/write/definition]
* </pre>
*
* To list all schemas in an instance:
* <pre>
*   kiji schema-table kiji://hbase-address/instance-name/ \
*       --list=true
* </pre>
*
* --interactive=false will suppress existing file warnings (old files will be overwritten by new
* schema definition files).  Only UIDs and schema hashes will be printed to the console if
* interactive is false.
*/

@ApiAudience.Private
public final class SchemaTableTool extends BaseTool {
  private static final Logger LOG = LoggerFactory.getLogger(SchemaTableTool.class);

  @Flag(name="register", usage="Path to a file containing a schema defintion "
      + "to add the given schema to the schema table and return it's UID and hash.")
  private String mRegisterFlag = null;

  @Flag(name="lookup", usage="Path to a file containing a schema defintion "
      + "to look up in the schema table and return it's UID and hash.")
  private String mLookupFlag = null;

  @Flag(name="get-schema-by-id", usage="ID of the schema to retrieve from the schema table.")
  private Long mGetByIdFlag = null;

  @Flag(name="get-schema-by-hash", usage="hash of the schema to retrieve from the schema table.")
  private String mGetByHashFlag = null;

  @Flag(name="list", usage="Set to true to list all the registered schemas in the kiji instance.")
  private Boolean mListFlag = null;

  @Flag(name="output", usage="Path to the file to write schema definitions retrieved from the "
      + "schema table (will overwrite if the file already exists, pending confirmation). "
      + "If not provided will output to standard out instead.")
  private String mOutputFlag = null;

  /** URI of the Kiji instance housing the target schema table. */
  private KijiURI mURI = null;

  /** Kiji instance housing the target schema table. */
  private Kiji mKiji = null;

  /** {@inheritDoc} */
  @Override
  public String getName() {
    return "schema-table";
  }

  /** {@inheritDoc} */
  @Override
  public String getDescription() {
    return "Inspect and modify a Kiji schema table.";
  }

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

  /** {@inheritDoc} */
  @Override
  protected void validateFlags() throws Exception {
    // Ensures that only one operation flag is specified at a time.
    int count = 0;
    count += (mRegisterFlag != null && !mRegisterFlag.isEmpty()) ? 1 : 0;
    count += (mLookupFlag != null && !mLookupFlag.isEmpty()) ? 1 : 0;
    count += (mGetByIdFlag != null) ? 1 : 0;
    count += (mGetByHashFlag != null && !mGetByHashFlag.isEmpty()) ? 1 : 0;
    count += (mListFlag != null && mListFlag) ? 1 : 0;
    Preconditions.checkArgument(
        count == 1, "Specify exactly one operation.");
  }

  /**
   * Writes a given schema to a file.
   *
   * @param schema The Avro Schema to write.
   * @return true if the file is written, false if it is not.
   * @throws IOException in case of an error writing the file.
   */
  private boolean writeDefinitionToFile(Schema schema) throws IOException {
    final File file = new File(mOutputFlag);
    final boolean fileCreated = file.createNewFile();
    if (!fileCreated && !mayProceed("File: %s already exists, do you wish to overwrite the file?",
          mOutputFlag)) {
        return false;
    } else {
      final FileOutputStream fop = new FileOutputStream(file.getAbsoluteFile());
      try {
        fop.write(schema.toString().getBytes("utf-8"));
        fop.flush();
      } finally {
        fop.close();
      }
    }
    return true;
  }

  /**
   * Register a schema.
   *
   * @return Tool exit code.
   * @throws IOException in case of an error.
   */
  private int registerSchema() throws IOException {
    final KijiSchemaTable table = mKiji.getSchemaTable();
    final File file = new File(mRegisterFlag);
    final Schema schema = new Schema.Parser().parse(file);
    final long id = table.getOrCreateSchemaId(schema);
    final String hash = table.getSchemaHash(schema).toString();
    if (isInteractive()) {
      getPrintStream().print("Schema ID for the given schema is: ");
    }
    getPrintStream().println(id);
    if (isInteractive()) {
      getPrintStream().print("Schema hash for the given schema is: ");
    }
    getPrintStream().println(hash);
    return SUCCESS;
  }

  /**
   * Lookup a schema.
   *
   * @return Tool exit code.
   * @throws IOException in case of an error.
   */
  private int lookupSchema() throws IOException {
    final KijiSchemaTable table = mKiji.getSchemaTable();
    final File file = new File(mLookupFlag);
    final Schema schema = new Schema.Parser().parse(file);
    final SchemaEntry sEntry = table.getSchemaEntry(schema);
    final long id = sEntry.getId();
    final BytesKey hash = sEntry.getHash();
    if (isInteractive()) {
      getPrintStream().print("Schema ID for the given schema is: ");
    }
    getPrintStream().println(id);
    if (isInteractive()) {
      getPrintStream().print("Schema hash for the given schema is: ");
    }
    getPrintStream().println(hash);
    return SUCCESS;
  }

  /**
   * Get a Schema by UID.
   *
   * @return Tool exit code.
   * @throws IOException in case of an error.
   */
  private int getById() throws IOException {
    final KijiSchemaTable table = mKiji.getSchemaTable();
    final Schema schema = table.getSchema(mGetByIdFlag);
    Preconditions.checkArgument(
        schema != null, "No schema definition with ID: %s", mGetByIdFlag);

    if (isInteractive()) {
      getPrintStream().print("Schema hash of the given schema is: ");
    }
    getPrintStream().println(table.getSchemaHash(schema));
    if (mOutputFlag != null && !mOutputFlag.isEmpty()) {
      // Attempt to write to the output file.
      try {
        if (writeDefinitionToFile(schema)) {
          if (isInteractive()) {
            getPrintStream().printf("Schema definition written to: %s%n", mOutputFlag);
          }
          return SUCCESS;
        } else {
          return FAILURE;
        }
      } catch (IOException ioe) {
        LOG.error("Error writing to file: {}", mOutputFlag);
        throw ioe;
      }
    } else {
      // Print the schema to standard out.
      if (isInteractive()) {
        getPrintStream().println("Schema:");
      }
      getPrintStream().println(schema.toString());
      return SUCCESS;
    }
  }

  /**
   * Get a Schema by hash.
   *
   * @return Tool exit code.
   * @throws IOException in case of an error.
   */
  private int getByHash() throws IOException {
    final KijiSchemaTable table = mKiji.getSchemaTable();
    final BytesKey bytesKey = new BytesKey(ByteArrayFormatter.parseHex(mGetByHashFlag, ':'));
    final SchemaEntry sEntry = table.getSchemaEntry(bytesKey);
    final Schema schema = sEntry.getSchema();

    if (isInteractive()) {
      getPrintStream().print("Schema ID for the given schema is: ");
    }
    getPrintStream().println(sEntry.getId());
    if (mOutputFlag != null && !mOutputFlag.isEmpty()) {
      // Attempt to write the definition to the output file.
      try {
        if (writeDefinitionToFile(schema)) {
          if (isInteractive()) {
            getPrintStream().printf("Schema definition written to: %s%n", mOutputFlag);
          }
          return SUCCESS;
        } else {
          return FAILURE;
        }
      } catch (IOException ioe) {
        LOG.error("Error writing to file: {}", mOutputFlag);
        throw ioe;
      }
    } else {
      // Print the schema to standard out.
      if (isInteractive()) {
        getPrintStream().println("Schema:");
      }
      getPrintStream().println(schema.toString());
      return SUCCESS;
    }
  }

  /**
   * List all schemas in the table.
   *
   * @return The Tool exit code.
   * @throws IOException in case of an error.
   */
  private int list() throws IOException {
    final KijiSchemaTable schemaTable = mKiji.getSchemaTable();
    long id = 0;
    Schema schema = schemaTable.getSchema(id);
    while (null != schema) {
      getPrintStream().printf("%d: %s%n", id, schema.toString());
      schema = schemaTable.getSchema(++id);
    }

    return SUCCESS;
  }

  /** {@inheritDoc} */
  @Override
  protected int run(List<String> nonFlagArgs) throws Exception {
    Preconditions.checkArgument(nonFlagArgs.size() != 0, "Specify the KijiURI of your target "
        + "instance with `kiji get kiji://hbase-cluster/instance`");
    mURI = KijiURI.newBuilder(Preconditions.checkNotNull(nonFlagArgs.get(0))).build();
    mKiji = Kiji.Factory.open(mURI, getConf());
    try {
      if (mRegisterFlag != null && !mRegisterFlag.isEmpty()) {
        return registerSchema();
      } else if (mLookupFlag != null && !mLookupFlag.isEmpty()) {
        return lookupSchema();
      } else if (mGetByIdFlag != null) {
        return getById();
      } else if (mGetByHashFlag != null && !mGetByHashFlag.isEmpty()) {
        return getByHash();
      } else if (mListFlag) {
        return list();
      } else {
        throw new InternalKijiError("No operation specified.");
      }
    } finally {
      mKiji.release();
    }
  }
}
TOP

Related Classes of org.kiji.schema.tools.SchemaTableTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.