Package org.apache.hadoop.hbase.avro

Source Code of org.apache.hadoop.hbase.avro.AvroServer$HBaseImpl

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

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;

import org.apache.avro.Schema;
import org.apache.avro.generic.GenericArray;
import org.apache.avro.generic.GenericData;
import org.apache.avro.ipc.HttpServer;
import org.apache.avro.specific.SpecificResponder;
import org.apache.avro.util.Utf8;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.TableExistsException;
import org.apache.hadoop.hbase.avro.generated.AClusterStatus;
import org.apache.hadoop.hbase.avro.generated.ADelete;
import org.apache.hadoop.hbase.avro.generated.AFamilyDescriptor;
import org.apache.hadoop.hbase.avro.generated.AGet;
import org.apache.hadoop.hbase.avro.generated.AIOError;
import org.apache.hadoop.hbase.avro.generated.AIllegalArgument;
import org.apache.hadoop.hbase.avro.generated.AMasterNotRunning;
import org.apache.hadoop.hbase.avro.generated.APut;
import org.apache.hadoop.hbase.avro.generated.AResult;
import org.apache.hadoop.hbase.avro.generated.AScan;
import org.apache.hadoop.hbase.avro.generated.ATableDescriptor;
import org.apache.hadoop.hbase.avro.generated.ATableExists;
import org.apache.hadoop.hbase.avro.generated.HBase;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;

/**
* Start an Avro server
*/
public class AvroServer {

  /**
   * The HBaseImpl is a glue object that connects Avro RPC calls to the
   * HBase client API primarily defined in the HBaseAdmin and HTable objects.
   */
  public static class HBaseImpl implements HBase {
    //
    // PROPERTIES
    //
    protected Configuration conf = null;
    protected HBaseAdmin admin = null;
    protected HTablePool htablePool = null;
    protected final Log LOG = LogFactory.getLog(this.getClass().getName());

    // nextScannerId and scannerMap are used to manage scanner state
    protected int nextScannerId = 0;
    protected HashMap<Integer, ResultScanner> scannerMap = null;

    //
    // UTILITY METHODS
    //

    /**
     * Assigns a unique ID to the scanner and adds the mapping to an internal
     * hash-map.
     *
     * @param scanner
     * @return integer scanner id
     */
    protected synchronized int addScanner(ResultScanner scanner) {
      int id = nextScannerId++;
      scannerMap.put(id, scanner);
      return id;
    }

    /**
     * Returns the scanner associated with the specified ID.
     *
     * @param id
     * @return a Scanner, or null if ID was invalid.
     */
    protected synchronized ResultScanner getScanner(int id) {
      return scannerMap.get(id);
    }

    /**
     * Removes the scanner associated with the specified ID from the internal
     * id->scanner hash-map.
     *
     * @param id
     * @return a Scanner, or null if ID was invalid.
     */
    protected synchronized ResultScanner removeScanner(int id) {
      return scannerMap.remove(id);
    }

    //
    // CTOR METHODS
    //

    // TODO(hammer): figure out appropriate setting of maxSize for htablePool
    /**
     * Constructs an HBaseImpl object.
     * @throws IOException
     */
    HBaseImpl() throws IOException {
      this(HBaseConfiguration.create());
    }

    HBaseImpl(final Configuration c) throws IOException {
      conf = c;
      admin = new HBaseAdmin(conf);
      htablePool = new HTablePool(conf, 10);
      scannerMap = new HashMap<Integer, ResultScanner>();
    }

    //
    // SERVICE METHODS
    //

    // TODO(hammer): Investigate use of the Command design pattern

    //
    // Cluster metadata
    //

    public Utf8 getHBaseVersion() throws AIOError {
      try {
  return new Utf8(admin.getClusterStatus().getHBaseVersion());
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    public AClusterStatus getClusterStatus() throws AIOError {
      try {
  return AvroUtil.csToACS(admin.getClusterStatus());
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    public GenericArray<ATableDescriptor> listTables() throws AIOError {
      try {
        HTableDescriptor[] tables = admin.listTables();
  Schema atdSchema = Schema.createArray(ATableDescriptor.SCHEMA$);
        GenericData.Array<ATableDescriptor> result = null;
  result = new GenericData.Array<ATableDescriptor>(tables.length, atdSchema);
        for (HTableDescriptor table : tables) {
    result.add(AvroUtil.htdToATD(table));
  }
        return result;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    //
    // Table metadata
    //

    // TODO(hammer): Handle the case where the table does not exist explicitly?
    public ATableDescriptor describeTable(ByteBuffer table) throws AIOError {
      try {
  return AvroUtil.htdToATD(admin.getTableDescriptor(Bytes.toBytes(table)));
      } catch (IOException e) {
        AIOError ioe = new AIOError();
        ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    public boolean isTableEnabled(ByteBuffer table) throws AIOError {
      try {
  return admin.isTableEnabled(Bytes.toBytes(table));
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    public boolean tableExists(ByteBuffer table) throws AIOError {
      try {
  return admin.tableExists(Bytes.toBytes(table));
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    //
    // Family metadata
    //

    // TODO(hammer): Handle the case where the family does not exist explicitly?
    public AFamilyDescriptor describeFamily(ByteBuffer table, ByteBuffer family) throws AIOError {
      try {
  HTableDescriptor htd = admin.getTableDescriptor(Bytes.toBytes(table));
  return AvroUtil.hcdToAFD(htd.getFamily(Bytes.toBytes(family)));
      } catch (IOException e) {
        AIOError ioe = new AIOError();
        ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    //
    // Table admin
    //

    public Void createTable(ATableDescriptor table) throws AIOError,
                                                           AIllegalArgument,
                                                           ATableExists,
                                                           AMasterNotRunning {
      try {
        admin.createTable(AvroUtil.atdToHTD(table));
  return null;
      } catch (IllegalArgumentException e) {
  AIllegalArgument iae = new AIllegalArgument();
  iae.message = new Utf8(e.getMessage());
        throw iae;
      } catch (TableExistsException e) {
  ATableExists tee = new ATableExists();
  tee.message = new Utf8(e.getMessage());
        throw tee;
      } catch (MasterNotRunningException e) {
  AMasterNotRunning mnre = new AMasterNotRunning();
  mnre.message = new Utf8(e.getMessage());
        throw mnre;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    // Note that disable, flush and major compaction of .META. needed in client
    // TODO(hammer): more selective cache dirtying than flush?
    public Void deleteTable(ByteBuffer table) throws AIOError {
      try {
  admin.deleteTable(Bytes.toBytes(table));
  return null;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    // NB: Asynchronous operation
    public Void modifyTable(ByteBuffer tableName, ATableDescriptor tableDescriptor) throws AIOError {
      try {
  admin.modifyTable(Bytes.toBytes(tableName),
                          AvroUtil.atdToHTD(tableDescriptor));
  return null;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    public Void enableTable(ByteBuffer table) throws AIOError {
      try {
  admin.enableTable(Bytes.toBytes(table));
  return null;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }
   
    public Void disableTable(ByteBuffer table) throws AIOError {
      try {
  admin.disableTable(Bytes.toBytes(table));
  return null;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }
   
    // NB: Asynchronous operation
    public Void flush(ByteBuffer table) throws AIOError {
      try {
  admin.flush(Bytes.toBytes(table));
  return null;
      } catch (InterruptedException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    // NB: Asynchronous operation
    public Void split(ByteBuffer table) throws AIOError {
      try {
  admin.split(Bytes.toBytes(table));
  return null;
      } catch (InterruptedException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    //
    // Family admin
    //

    public Void addFamily(ByteBuffer table, AFamilyDescriptor family) throws AIOError {
      try {
  admin.addColumn(Bytes.toBytes(table),
                        AvroUtil.afdToHCD(family));
  return null;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    // NB: Asynchronous operation
    public Void deleteFamily(ByteBuffer table, ByteBuffer family) throws AIOError {
      try {
  admin.deleteColumn(Bytes.toBytes(table), Bytes.toBytes(family));
  return null;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    // NB: Asynchronous operation
    public Void modifyFamily(ByteBuffer table, ByteBuffer familyName, AFamilyDescriptor familyDescriptor) throws AIOError {
      try {
  admin.modifyColumn(Bytes.toBytes(table), AvroUtil.afdToHCD(familyDescriptor));
  return null;
      } catch (IOException e) {
  AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    //
    // Single-row DML
    //

    // TODO(hammer): Java with statement for htablepool concision?
    // TODO(hammer): Can Get have timestamp and timerange simultaneously?
    // TODO(hammer): Do I need to catch the RuntimeException of getTable?
    // TODO(hammer): Handle gets with no results
    // TODO(hammer): Uses exists(Get) to ensure columns exist
    public AResult get(ByteBuffer table, AGet aget) throws AIOError {
      HTableInterface htable = htablePool.getTable(Bytes.toBytes(table));
      try {
        return AvroUtil.resultToAResult(htable.get(AvroUtil.agetToGet(aget)));
      } catch (IOException e) {
      AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } finally {
        htablePool.putTable(htable);
      }
    }

    public boolean exists(ByteBuffer table, AGet aget) throws AIOError {
      HTableInterface htable = htablePool.getTable(Bytes.toBytes(table));
      try {
        return htable.exists(AvroUtil.agetToGet(aget));
      } catch (IOException e) {
      AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } finally {
        htablePool.putTable(htable);
      }
    }

    public Void put(ByteBuffer table, APut aput) throws AIOError {
      HTableInterface htable = htablePool.getTable(Bytes.toBytes(table));
      try {
  htable.put(AvroUtil.aputToPut(aput));
        return null;
      } catch (IOException e) {
        AIOError ioe = new AIOError();
        ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } finally {
        htablePool.putTable(htable);
      }
    }

    public Void delete(ByteBuffer table, ADelete adelete) throws AIOError {
      HTableInterface htable = htablePool.getTable(Bytes.toBytes(table));
      try {
        htable.delete(AvroUtil.adeleteToDelete(adelete));
        return null;
      } catch (IOException e) {
      AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } finally {
        htablePool.putTable(htable);
      }
    }

    public long incrementColumnValue(ByteBuffer table, ByteBuffer row, ByteBuffer family, ByteBuffer qualifier, long amount, boolean writeToWAL) throws AIOError {
      HTableInterface htable = htablePool.getTable(Bytes.toBytes(table));
      try {
  return htable.incrementColumnValue(Bytes.toBytes(row), Bytes.toBytes(family), Bytes.toBytes(qualifier), amount, writeToWAL);
      } catch (IOException e) {
        AIOError ioe = new AIOError();
        ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } finally {
        htablePool.putTable(htable);
      }
    }

    //
    // Multi-row DML
    //

    public int scannerOpen(ByteBuffer table, AScan ascan) throws AIOError {
      HTableInterface htable = htablePool.getTable(Bytes.toBytes(table));
      try {
        Scan scan = AvroUtil.ascanToScan(ascan);
        return addScanner(htable.getScanner(scan));
      } catch (IOException e) {
      AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      } finally {
        htablePool.putTable(htable);
      }
    }

    public Void scannerClose(int scannerId) throws AIOError, AIllegalArgument {
      try {
        ResultScanner scanner = getScanner(scannerId);
        if (scanner == null) {
          AIllegalArgument aie = new AIllegalArgument();
    aie.message = new Utf8("scanner ID is invalid: " + scannerId);
          throw aie;
        }
        scanner.close();
        removeScanner(scannerId);
        return null;
      } catch (IOException e) {
      AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }

    public GenericArray<AResult> scannerGetRows(int scannerId, int numberOfRows) throws AIOError, AIllegalArgument {
      try {
        ResultScanner scanner = getScanner(scannerId);
        if (scanner == null) {
          AIllegalArgument aie = new AIllegalArgument();
    aie.message = new Utf8("scanner ID is invalid: " + scannerId);
          throw aie;
        }
        return AvroUtil.resultsToAResults(scanner.next(numberOfRows));
      } catch (IOException e) {
      AIOError ioe = new AIOError();
  ioe.message = new Utf8(e.getMessage());
        throw ioe;
      }
    }
  }

  //
  // MAIN PROGRAM
  //

  private static void printUsageAndExit() {
    printUsageAndExit(null);
  }
 
  private static void printUsageAndExit(final String message) {
    if (message != null) {
      System.err.println(message);
    }
    System.out.println("Usage: java org.apache.hadoop.hbase.avro.AvroServer " +
      "--help | [--port=PORT] start");
    System.out.println("Arguments:");
    System.out.println(" start Start Avro server");
    System.out.println(" stop  Stop Avro server");
    System.out.println("Options:");
    System.out.println(" port  Port to listen on. Default: 9090");
    System.out.println(" help  Print this message and exit");
    System.exit(0);
  }

  // TODO(hammer): Figure out a better way to keep the server alive!
  protected static void doMain(final String[] args) throws Exception {
    if (args.length < 1) {
      printUsageAndExit();
    }
    int port = 9090;
    final String portArgKey = "--port=";
    for (String cmd: args) {
      if (cmd.startsWith(portArgKey)) {
        port = Integer.parseInt(cmd.substring(portArgKey.length()));
        continue;
      } else if (cmd.equals("--help") || cmd.equals("-h")) {
        printUsageAndExit();
      } else if (cmd.equals("start")) {
        continue;
      } else if (cmd.equals("stop")) {
        printUsageAndExit("To shutdown the Avro server run " +
          "bin/hbase-daemon.sh stop avro or send a kill signal to " +
          "the Avro server pid");
      }
     
      // Print out usage if we get to here.
      printUsageAndExit();
    }
    Log LOG = LogFactory.getLog("AvroServer");
    LOG.info("starting HBase Avro server on port " + Integer.toString(port));
    SpecificResponder r = new SpecificResponder(HBase.class, new HBaseImpl());
    new HttpServer(r, 9090);
    Thread.sleep(1000000);
  }

  // TODO(hammer): Look at Cassandra's daemonization and integration with JSVC
  // TODO(hammer): Don't eat it after a single exception
  // TODO(hammer): Figure out why we do doMain()
  // TODO(hammer): Figure out if we want String[] or String [] syntax
  public static void main(String[] args) throws Exception {
    doMain(args);
  }
}
TOP

Related Classes of org.apache.hadoop.hbase.avro.AvroServer$HBaseImpl

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.