PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/release-0.0.0-rc0/hive/external/hbase-handler/src/java/org/apache/hadoop/hive/hbase/HBaseStorageHandler.java

#
Java | 317 lines | 238 code | 39 blank | 40 comment | 32 complexity | 637a6c248263cc487ed90a2b221b7712 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, JSON, CPL-1.0
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.hive.hbase;
  19. import java.io.IOException;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.HashSet;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.Properties;
  26. import java.util.Set;
  27. import org.apache.hadoop.conf.Configuration;
  28. import org.apache.hadoop.hbase.HBaseConfiguration;
  29. import org.apache.hadoop.hbase.HColumnDescriptor;
  30. import org.apache.hadoop.hbase.HTableDescriptor;
  31. import org.apache.hadoop.hbase.MasterNotRunningException;
  32. import org.apache.hadoop.hbase.ZooKeeperConnectionException;
  33. import org.apache.hadoop.hbase.client.HBaseAdmin;
  34. import org.apache.hadoop.hbase.client.HTable;
  35. import org.apache.hadoop.hbase.util.Bytes;
  36. import org.apache.hadoop.hive.metastore.HiveMetaHook;
  37. import org.apache.hadoop.hive.metastore.MetaStoreUtils;
  38. import org.apache.hadoop.hive.metastore.api.Constants;
  39. import org.apache.hadoop.hive.metastore.api.MetaException;
  40. import org.apache.hadoop.hive.metastore.api.Table;
  41. import org.apache.hadoop.hive.ql.index.IndexPredicateAnalyzer;
  42. import org.apache.hadoop.hive.ql.index.IndexSearchCondition;
  43. import org.apache.hadoop.hive.ql.metadata.DefaultStorageHandler;
  44. import org.apache.hadoop.hive.ql.metadata.Hive;
  45. import org.apache.hadoop.hive.ql.metadata.HiveStoragePredicateHandler;
  46. import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
  47. import org.apache.hadoop.hive.ql.plan.TableDesc;
  48. import org.apache.hadoop.hive.serde2.Deserializer;
  49. import org.apache.hadoop.hive.serde2.SerDe;
  50. import org.apache.hadoop.hive.serde2.SerDeException;
  51. import org.apache.hadoop.mapred.InputFormat;
  52. import org.apache.hadoop.mapred.JobConf;
  53. import org.apache.hadoop.mapred.OutputFormat;
  54. import org.apache.hadoop.util.StringUtils;
  55. /**
  56. * HBaseStorageHandler provides a HiveStorageHandler implementation for
  57. * HBase.
  58. */
  59. public class HBaseStorageHandler extends DefaultStorageHandler
  60. implements HiveMetaHook, HiveStoragePredicateHandler {
  61. final static public String DEFAULT_PREFIX = "default.";
  62. private HBaseConfiguration hbaseConf;
  63. private HBaseAdmin admin;
  64. private HBaseAdmin getHBaseAdmin() throws MetaException {
  65. try {
  66. if (admin == null) {
  67. admin = new HBaseAdmin(hbaseConf);
  68. }
  69. return admin;
  70. } catch (MasterNotRunningException mnre) {
  71. throw new MetaException(StringUtils.stringifyException(mnre));
  72. } catch (ZooKeeperConnectionException zkce) {
  73. throw new MetaException(StringUtils.stringifyException(zkce));
  74. }
  75. }
  76. private String getHBaseTableName(Table tbl) {
  77. // Give preference to TBLPROPERTIES over SERDEPROPERTIES
  78. // (really we should only use TBLPROPERTIES, so this is just
  79. // for backwards compatibility with the original specs).
  80. String tableName = tbl.getParameters().get(HBaseSerDe.HBASE_TABLE_NAME);
  81. if (tableName == null) {
  82. tableName = tbl.getSd().getSerdeInfo().getParameters().get(
  83. HBaseSerDe.HBASE_TABLE_NAME);
  84. }
  85. if (tableName == null) {
  86. tableName = tbl.getDbName() + "." + tbl.getTableName();
  87. if (tableName.startsWith(DEFAULT_PREFIX)) {
  88. tableName = tableName.substring(DEFAULT_PREFIX.length());
  89. }
  90. }
  91. return tableName;
  92. }
  93. @Override
  94. public void preDropTable(Table table) throws MetaException {
  95. // nothing to do
  96. }
  97. @Override
  98. public void rollbackDropTable(Table table) throws MetaException {
  99. // nothing to do
  100. }
  101. @Override
  102. public void commitDropTable(
  103. Table tbl, boolean deleteData) throws MetaException {
  104. try {
  105. String tableName = getHBaseTableName(tbl);
  106. boolean isExternal = MetaStoreUtils.isExternalTable(tbl);
  107. if (deleteData && !isExternal) {
  108. if (getHBaseAdmin().isTableEnabled(tableName)) {
  109. getHBaseAdmin().disableTable(tableName);
  110. }
  111. getHBaseAdmin().deleteTable(tableName);
  112. }
  113. } catch (IOException ie) {
  114. throw new MetaException(StringUtils.stringifyException(ie));
  115. }
  116. }
  117. @Override
  118. public void preCreateTable(Table tbl) throws MetaException {
  119. boolean isExternal = MetaStoreUtils.isExternalTable(tbl);
  120. // We'd like to move this to HiveMetaStore for any non-native table, but
  121. // first we need to support storing NULL for location on a table
  122. if (tbl.getSd().getLocation() != null) {
  123. throw new MetaException("LOCATION may not be specified for HBase.");
  124. }
  125. try {
  126. String tableName = getHBaseTableName(tbl);
  127. Map<String, String> serdeParam = tbl.getSd().getSerdeInfo().getParameters();
  128. String hbaseColumnsMapping = serdeParam.get(HBaseSerDe.HBASE_COLUMNS_MAPPING);
  129. if (hbaseColumnsMapping == null) {
  130. throw new MetaException("No hbase.columns.mapping defined in Serde.");
  131. }
  132. List<String> hbaseColumnFamilies = new ArrayList<String>();
  133. List<String> hbaseColumnQualifiers = new ArrayList<String>();
  134. List<byte []> hbaseColumnFamiliesBytes = new ArrayList<byte []>();
  135. List<byte []> hbaseColumnQualifiersBytes = new ArrayList<byte []>();
  136. int iKey = HBaseSerDe.parseColumnMapping(hbaseColumnsMapping, hbaseColumnFamilies,
  137. hbaseColumnFamiliesBytes, hbaseColumnQualifiers, hbaseColumnQualifiersBytes);
  138. HTableDescriptor tableDesc;
  139. if (!getHBaseAdmin().tableExists(tableName)) {
  140. // if it is not an external table then create one
  141. if (!isExternal) {
  142. // Create the column descriptors
  143. tableDesc = new HTableDescriptor(tableName);
  144. Set<String> uniqueColumnFamilies = new HashSet<String>(hbaseColumnFamilies);
  145. uniqueColumnFamilies.remove(hbaseColumnFamilies.get(iKey));
  146. for (String columnFamily : uniqueColumnFamilies) {
  147. tableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes(columnFamily)));
  148. }
  149. getHBaseAdmin().createTable(tableDesc);
  150. } else {
  151. // an external table
  152. throw new MetaException("HBase table " + tableName +
  153. " doesn't exist while the table is declared as an external table.");
  154. }
  155. } else {
  156. if (!isExternal) {
  157. throw new MetaException("Table " + tableName + " already exists"
  158. + " within HBase; use CREATE EXTERNAL TABLE instead to"
  159. + " register it in Hive.");
  160. }
  161. // make sure the schema mapping is right
  162. tableDesc = getHBaseAdmin().getTableDescriptor(Bytes.toBytes(tableName));
  163. for (int i = 0; i < hbaseColumnFamilies.size(); i++) {
  164. if (i == iKey) {
  165. continue;
  166. }
  167. if (!tableDesc.hasFamily(hbaseColumnFamiliesBytes.get(i))) {
  168. throw new MetaException("Column Family " + hbaseColumnFamilies.get(i)
  169. + " is not defined in hbase table " + tableName);
  170. }
  171. }
  172. }
  173. // ensure the table is online
  174. new HTable(hbaseConf, tableDesc.getName());
  175. } catch (MasterNotRunningException mnre) {
  176. throw new MetaException(StringUtils.stringifyException(mnre));
  177. } catch (IOException ie) {
  178. throw new MetaException(StringUtils.stringifyException(ie));
  179. } catch (SerDeException se) {
  180. throw new MetaException(StringUtils.stringifyException(se));
  181. }
  182. }
  183. @Override
  184. public void rollbackCreateTable(Table table) throws MetaException {
  185. boolean isExternal = MetaStoreUtils.isExternalTable(table);
  186. String tableName = getHBaseTableName(table);
  187. try {
  188. if (!isExternal && getHBaseAdmin().tableExists(tableName)) {
  189. // we have created an HBase table, so we delete it to roll back;
  190. if (getHBaseAdmin().isTableEnabled(tableName)) {
  191. getHBaseAdmin().disableTable(tableName);
  192. }
  193. getHBaseAdmin().deleteTable(tableName);
  194. }
  195. } catch (IOException ie) {
  196. throw new MetaException(StringUtils.stringifyException(ie));
  197. }
  198. }
  199. @Override
  200. public void commitCreateTable(Table table) throws MetaException {
  201. // nothing to do
  202. }
  203. @Override
  204. public Configuration getConf() {
  205. return hbaseConf;
  206. }
  207. @Override
  208. public void setConf(Configuration conf) {
  209. hbaseConf = new HBaseConfiguration(conf);
  210. }
  211. @Override
  212. public Class<? extends InputFormat> getInputFormatClass() {
  213. return HiveHBaseTableInputFormat.class;
  214. }
  215. @Override
  216. public Class<? extends OutputFormat> getOutputFormatClass() {
  217. return HiveHBaseTableOutputFormat.class;
  218. }
  219. @Override
  220. public Class<? extends SerDe> getSerDeClass() {
  221. return HBaseSerDe.class;
  222. }
  223. @Override
  224. public HiveMetaHook getMetaHook() {
  225. return this;
  226. }
  227. @Override
  228. public void configureTableJobProperties(
  229. TableDesc tableDesc,
  230. Map<String, String> jobProperties) {
  231. Properties tableProperties = tableDesc.getProperties();
  232. jobProperties.put(
  233. HBaseSerDe.HBASE_COLUMNS_MAPPING,
  234. tableProperties.getProperty(HBaseSerDe.HBASE_COLUMNS_MAPPING));
  235. String tableName =
  236. tableProperties.getProperty(HBaseSerDe.HBASE_TABLE_NAME);
  237. if (tableName == null) {
  238. tableName =
  239. tableProperties.getProperty(Constants.META_TABLE_NAME);
  240. if (tableName.startsWith(DEFAULT_PREFIX)) {
  241. tableName = tableName.substring(DEFAULT_PREFIX.length());
  242. }
  243. }
  244. jobProperties.put(HBaseSerDe.HBASE_TABLE_NAME, tableName);
  245. }
  246. @Override
  247. public DecomposedPredicate decomposePredicate(
  248. JobConf jobConf,
  249. Deserializer deserializer,
  250. ExprNodeDesc predicate)
  251. {
  252. String columnNameProperty = jobConf.get(
  253. org.apache.hadoop.hive.serde.Constants.LIST_COLUMNS);
  254. List<String> columnNames =
  255. Arrays.asList(columnNameProperty.split(","));
  256. HBaseSerDe hbaseSerde = (HBaseSerDe) deserializer;
  257. IndexPredicateAnalyzer analyzer =
  258. HiveHBaseTableInputFormat.newIndexPredicateAnalyzer(
  259. columnNames.get(hbaseSerde.getKeyColumnOffset()));
  260. List<IndexSearchCondition> searchConditions =
  261. new ArrayList<IndexSearchCondition>();
  262. ExprNodeDesc residualPredicate =
  263. analyzer.analyzePredicate(predicate, searchConditions);
  264. if (searchConditions.size() != 1) {
  265. // Either there was nothing which could be pushed down (size = 0),
  266. // or more than one predicate (size > 1); in the latter case,
  267. // we bail out for now since multiple lookups on the key are
  268. // either contradictory or redundant. We'll need to handle
  269. // this better later when we support more interesting predicates.
  270. return null;
  271. }
  272. DecomposedPredicate decomposedPredicate = new DecomposedPredicate();
  273. decomposedPredicate.pushedPredicate = analyzer.translateSearchConditions(
  274. searchConditions);
  275. decomposedPredicate.residualPredicate = residualPredicate;
  276. return decomposedPredicate;
  277. }
  278. }