package com.taobao.zeus.store; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.HiveMetaStoreClient; import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.api.Table; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.taobao.zeus.client.ZeusException; import com.taobao.zeus.jobs.sub.conf.ConfUtil; /** * @author gufei.wzy 2012-9-17 */ public class CliTableManager implements TableManager { private static Logger log = LoggerFactory.getLogger(CliTableManager.class); private HiveMetaStoreClient client; public static String DEFAULT_DB = "default"; public CliTableManager() throws Exception { HiveConf conf=new HiveConf(); File f=new File(ConfUtil.getHiveConfDir()+File.separator+"hive-site.xml"); log.debug("hive conf file:"+f.toString()); if(f.exists()){ conf.addResource(f.toURI().toURL()); } client=new HiveMetaStoreClient(conf); } public CliTableManager(Configuration conf) throws Exception { client = new HiveMetaStoreClient(new HiveConf(conf, this.getClass())); } /** * 获取一个自定义hive配置的manager实例,吞掉了异常 * * @param conf * @return null if an exception was caught. */ public static TableManager getInstance(Configuration conf) { try { return new CliTableManager(conf); } catch (Exception e) { log.error("获取tableManager实例失败", e); } return null; } /* * (non-Javadoc) * * @see com.taobao.zeus.store.TableManager#getAllTables() */ @Override public List<String> getAllTables(String dbName) throws ZeusException { try { return client.getAllTables(dbName); } catch (Exception e) { throw new ZeusException("获取所有表信息失败", e); } } @Override public List<Table> getPagingTables(String dbName, String pattern, int offset, int limit) throws ZeusException { if (offset < 0 || limit < 0) { throw new ZeusException("获取分页表信息失败,参数不正确"); } if (pattern == null) { pattern = ""; } List<Table> tables = new ArrayList<Table>(); try { List<String> tbs = null; tbs = client.getTables(dbName,getPatternFromQuery(pattern)); limit = offset + limit > tbs.size() ? tbs.size() - offset : limit; for (String t : tbs.subList(offset, offset + limit)) { tables.add(client.getTable(dbName, t)); } } catch (Exception e) { log.error("获取分页表信息失败", e); throw new ZeusException("获取所有表信息失败", e); } return tables; } /* * (non-Javadoc) * * @see com.taobao.zeus.store.TableManager#getTable(java.lang.String) */ @Override public Table getTable(String dbName, String tableName) { try { return client.getTable(dbName, tableName); } catch (Exception e) { log.warn("找不到该表:" + dbName+":" + tableName, e); } return null; } @Override public List<Partition> getPartitions(String dbName, String tableName, Integer limit) throws ZeusException { List<Partition> l = null; try { l = client.listPartitions(dbName, tableName, (short) -1); if (limit != null && limit > 0) { limit = limit > l.size() ? l.size() : limit; l = l.subList(l.size() - limit, l.size()); } Collections.reverse(l); } catch (NoSuchObjectException e) { log.error("找不到该表:" + tableName, e); throw new ZeusException("没找到这张表!", e); } catch (Exception e) { log.error("取所有分区失败:" + tableName, e); throw new ZeusException("获取所有分区失败!", e); } return l; } @Override public Integer getTotalNumber(String dbName, String pattern) throws ZeusException { if (pattern == null) { throw new ZeusException("参数不正确"); } try { int size = 0; size = client.getTables(dbName, getPatternFromQuery(pattern)).size(); return size; } catch (Exception e) { throw new ZeusException("获取表数量信息失败", e); } } @Override public boolean dropPartition(String tableName, List<String> partVals, boolean deleteData) { try { return client.dropPartition(DEFAULT_DB, tableName, partVals, deleteData); } catch (NoSuchObjectException e) { log.error("表" + tableName + "不存在", e); } catch (Exception e) { log.error("drop partition failed. table[" + tableName + "] part_vals=" + partVals, e); } return false; } /** * <ul> * <li>把检索表的query处理为HiveMetaStoreClient.getTables(String, String * pattern)使用的格式 * <li>Query用空格隔开,或逻辑 * <p> * 如 <code>gufei*test click</code> * </ul> * * @see HiveMetaStoreClient#getTables(String, String) * @param query * @return */ private String getPatternFromQuery(String query) { String[] subs = StringUtils.split(query, ' '); boolean first = true; StringBuffer pattern = new StringBuffer(); for (String sub : subs) { sub = sub.trim() + "*"; if (!first) { pattern.append('|'); } pattern.append(sub); first = false; } return pattern.toString(); } public HiveMetaStoreClient getClient() { return client; } /** * 指定HiveMetaStoreClient * * @param client */ public void setClient(HiveMetaStoreClient client) { this.client = client; } @Override public List<String> getAllDataBases() throws ZeusException { try { return client.getAllDatabases(); } catch (Exception e) { throw new ZeusException("获取所有数据库名称失败", e); } } }