/**
* 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.hive.hcatalog.api;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.common.classification.InterfaceAudience;
import org.apache.hadoop.hive.common.classification.InterfaceStability;
import org.apache.hadoop.hive.metastore.IMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.PartitionEventType;
import org.apache.hadoop.hive.ql.exec.Utilities;
import org.apache.hive.hcatalog.api.repl.ReplicationTask;
import org.apache.hive.hcatalog.common.HCatException;
import org.apache.hive.hcatalog.data.schema.HCatFieldSchema;
/**
* The abstract class HCatClient containing APIs for HCatalog DDL commands.
*/
public abstract class HCatClient {
public enum DropDBMode {RESTRICT, CASCADE}
public static final String HCAT_CLIENT_IMPL_CLASS = "hcat.client.impl.class";
/**
* Creates an instance of HCatClient.
*
* @param conf An instance of configuration.
* @return An instance of HCatClient.
* @throws HCatException
*/
public static HCatClient create(Configuration conf) throws HCatException {
HCatClient client = null;
String className = conf.get(HCAT_CLIENT_IMPL_CLASS,
HCatClientHMSImpl.class.getName());
try {
Class<? extends HCatClient> clientClass = Class.forName(className,
true, Utilities.getSessionSpecifiedClassLoader()).asSubclass(
HCatClient.class);
client = (HCatClient) clientClass.newInstance();
} catch (ClassNotFoundException e) {
throw new HCatException(
"ClassNotFoundException while creating client class.", e);
} catch (InstantiationException e) {
throw new HCatException(
"InstantiationException while creating client class.", e);
} catch (IllegalAccessException e) {
throw new HCatException(
"IllegalAccessException while creating client class.", e);
}
if (client != null) {
client.initialize(conf);
}
return client;
}
abstract void initialize(Configuration conf) throws HCatException;
/**
* Fetch configuration value on conf that the HCatClient is instantiated
* against. We do not want to expose the conf itself via a getConf(), because
* we do not want it modifiable after instantiation of the HCatClient, but
* modules that get called from HCatClient often need to know about how
* HCatClient is configured, so we want a read-only interface for it.
*
* @param key keyname to look up
* @param defaultVal default value to furnish in case the key does not exist
* @return value for given key, and defaultVal if key is not present in conf
*/
public abstract String getConfVal(String key, String defaultVal);
/**
* Get all existing databases that match the given
* pattern. The matching occurs as per Java regular expressions
*
* @param pattern java re pattern
* @return list of database names
* @throws HCatException
*/
public abstract List<String> listDatabaseNamesByPattern(String pattern)
throws HCatException;
/**
* Gets the database.
*
* @param dbName The name of the database.
* @return An instance of HCatDatabaseInfo.
* @throws HCatException
*/
public abstract HCatDatabase getDatabase(String dbName) throws HCatException;
/**
* Creates the database.
*
* @param dbInfo An instance of HCatCreateDBDesc.
* @throws HCatException
*/
public abstract void createDatabase(HCatCreateDBDesc dbInfo)
throws HCatException;
/**
* Drops a database.
*
* @param dbName The name of the database to delete.
* @param ifExists Hive returns an error if the database specified does not exist,
* unless ifExists is set to true.
* @param mode This is set to either "restrict" or "cascade". Restrict will
* remove the schema if all the tables are empty. Cascade removes
* everything including data and definitions.
* @throws HCatException
*/
public abstract void dropDatabase(String dbName, boolean ifExists,
DropDBMode mode) throws HCatException;
/**
* Returns all existing tables from the specified database which match the given
* pattern. The matching occurs as per Java regular expressions.
* @param dbName The name of the DB (to be searched)
* @param tablePattern The regex for the table-name
* @return list of table names
* @throws HCatException
*/
public abstract List<String> listTableNamesByPattern(String dbName, String tablePattern)
throws HCatException;
/**
* Gets the table.
*
* @param dbName The name of the database.
* @param tableName The name of the table.
* @return An instance of HCatTableInfo.
* @throws HCatException
*/
public abstract HCatTable getTable(String dbName, String tableName)
throws HCatException;
/**
* Creates the table.
*
* @param createTableDesc An instance of HCatCreateTableDesc class.
* @throws HCatException
*/
public abstract void createTable(HCatCreateTableDesc createTableDesc) throws HCatException;
/**
* Updates the Table's column schema to the specified definition.
*
* @param dbName The name of the database.
* @param tableName The name of the table.
* @param columnSchema The (new) definition of the column schema (i.e. list of fields).
*
*/
public abstract void updateTableSchema(String dbName, String tableName, List<HCatFieldSchema> columnSchema)
throws HCatException;
/**
* Updates the Table's whole schema (including column schema, I/O Formats, SerDe definitions, etc.)
* @param dbName The name of the database.
* @param tableName The name of the table.
* @param newTableDefinition The (new) definition of the table.
* @throws HCatException
*/
public abstract void updateTableSchema(String dbName, String tableName, HCatTable newTableDefinition)
throws HCatException;
/**
* Serializer for HCatTable.
* @param hcatTable The HCatTable to be serialized into string form
* @return String representation of the HCatTable.
* @throws HCatException, on failure to serialize.
*/
public abstract String serializeTable(HCatTable hcatTable) throws HCatException;
/**
* Deserializer for HCatTable.
* @param hcatTableStringRep The String representation of an HCatTable, presumably retrieved from {@link #serializeTable(HCatTable)}
* @return HCatTable reconstructed from the string
* throws HCatException, on failure to deserialize.
*/
public abstract HCatTable deserializeTable(String hcatTableStringRep) throws HCatException;
/**
* Serializer for HCatPartition.
* @param hcatPartition The HCatPartition instance to be serialized.
* @return String representation of the HCatPartition.
* @throws HCatException, on failure to serialize.
*/
public abstract String serializePartition(HCatPartition hcatPartition) throws HCatException;
/**
* Serializer for a list of HCatPartition.
* @param hcatPartitions The HCatPartitions to be serialized.
* @return A list of Strings, each representing an HCatPartition.
* @throws HCatException, on failure to serialize.
*/
public abstract List<String> serializePartitions(List<HCatPartition> hcatPartitions) throws HCatException;
/**
* Deserializer for an HCatPartition.
* @param hcatPartitionStringRep The String representation of the HCatPartition, presumably retrieved from {@link #serializePartition(HCatPartition)}
* @return HCatPartition instance reconstructed from the string.
* @throws HCatException, on failure to deserialze.
*/
public abstract HCatPartition deserializePartition(String hcatPartitionStringRep) throws HCatException;
/**
* Deserializer for a list of HCatPartition strings.
* @param hcatPartitionStringReps The list of HCatPartition strings to be deserialized.
* @return A list of HCatPartition instances, each reconstructed from an entry in the string-list.
* @throws HCatException, on failure to deserialize.
*/
public abstract List<HCatPartition> deserializePartitions(List<String> hcatPartitionStringReps) throws HCatException;
/**
* Serializer for HCatPartitionSpec.
* @param partitionSpec HCatPartitionSpec to be serialized.
* @return A list of Strings, representing the HCatPartitionSpec as a whole.
* @throws HCatException On failure to serialize.
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract List<String> serializePartitionSpec(HCatPartitionSpec partitionSpec) throws HCatException;
/**
* Deserializer for HCatPartitionSpec.
* @param hcatPartitionSpecStrings List of strings, representing the HCatPartitionSpec as a whole.
* @return HCatPartitionSpec, reconstructed from the list of strings.
* @throws HCatException On failure to deserialize.
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract HCatPartitionSpec deserializePartitionSpec(List<String> hcatPartitionSpecStrings) throws HCatException;
/**
* Creates the table like an existing table.
*
* @param dbName The name of the database.
* @param existingTblName The name of the existing table.
* @param newTableName The name of the new table.
* @param ifNotExists If true, then error related to already table existing is skipped.
* @param isExternal Set to "true", if table has be created at a different
* location other than default.
* @param location The location for the table.
* @throws HCatException
*/
public abstract void createTableLike(String dbName, String existingTblName,
String newTableName, boolean ifNotExists, boolean isExternal,
String location) throws HCatException;
/**
* Drop table.
*
* @param dbName The name of the database.
* @param tableName The name of the table.
* @param ifExists Hive returns an error if the database specified does not exist,
* unless ifExists is set to true.
* @throws HCatException
*/
public abstract void dropTable(String dbName, String tableName,
boolean ifExists) throws HCatException;
/**
* Renames a table.
*
* @param dbName The name of the database.
* @param oldName The name of the table to be renamed.
* @param newName The new name of the table.
* @throws HCatException
*/
public abstract void renameTable(String dbName, String oldName,
String newName) throws HCatException;
/**
* Gets all the partitions.
*
* @param dbName The name of the database.
* @param tblName The name of the table.
* @return A list of partitions.
* @throws HCatException
*/
public abstract List<HCatPartition> getPartitions(String dbName, String tblName)
throws HCatException;
/**
* Gets all the partitions that match the specified (and possibly partial) partition specification.
* A partial partition-specification is one where not all partition-keys have associated values. For example,
* for a table ('myDb.myTable') with 2 partition keys (dt string, region string),
* if for each dt ('20120101', '20120102', etc.) there can exist 3 regions ('us', 'uk', 'in'), then,
* 1. Complete partition spec: getPartitions('myDb', 'myTable', {dt='20120101', region='us'}) would return 1 partition.
* 2. Partial partition spec: getPartitions('myDb', 'myTable', {dt='20120101'}) would return all 3 partitions,
* with dt='20120101' (i.e. region = 'us', 'uk' and 'in').
* @param dbName The name of the database.
* @param tblName The name of the table.
* @param partitionSpec The partition specification. (Need not include all partition keys.)
* @return A list of partitions.
* @throws HCatException
*/
public abstract List<HCatPartition> getPartitions(String dbName, String tblName, Map<String, String> partitionSpec)
throws HCatException;
/**
* Gets partitions in terms of generic HCatPartitionSpec instances.
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract HCatPartitionSpec getPartitionSpecs(String dbName, String tableName, int maxPartitions) throws HCatException;
/**
* Gets partitions in terms of generic HCatPartitionSpec instances.
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract HCatPartitionSpec getPartitionSpecs(String dbName, String tableName, Map<String, String> partitionSelector, int maxPartitions)
throws HCatException;
/**
* Gets the partition.
*
* @param dbName The database name.
* @param tableName The table name.
* @param partitionSpec The partition specification, {[col_name,value],[col_name2,value2]}. All partition-key-values
* must be specified.
* @return An instance of HCatPartitionInfo.
* @throws HCatException
*/
public abstract HCatPartition getPartition(String dbName, String tableName,
Map<String, String> partitionSpec) throws HCatException;
/**
* Adds the partition.
*
* @param partInfo An instance of HCatAddPartitionDesc.
* @throws HCatException
*/
public abstract void addPartition(HCatAddPartitionDesc partInfo)
throws HCatException;
/**
* Adds a list of partitions.
*
* @param partInfoList A list of HCatAddPartitionDesc.
* @return The number of partitions added.
* @throws HCatException
*/
public abstract int addPartitions(List<HCatAddPartitionDesc> partInfoList)
throws HCatException;
/**
* Adds partitions using HCatPartitionSpec.
* @param partitionSpec The HCatPartitionSpec representing the set of partitions added.
* @return The number of partitions added.
* @throws HCatException On failure to add partitions.
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract int addPartitionSpec(HCatPartitionSpec partitionSpec)
throws HCatException;
/**
* Drops partition(s) that match the specified (and possibly partial) partition specification.
* A partial partition-specification is one where not all partition-keys have associated values. For example,
* for a table ('myDb.myTable') with 2 partition keys (dt string, region string),
* if for each dt ('20120101', '20120102', etc.) there can exist 3 regions ('us', 'uk', 'in'), then,
* 1. Complete partition spec: dropPartitions('myDb', 'myTable', {dt='20120101', region='us'}) would drop 1 partition.
* 2. Partial partition spec: dropPartitions('myDb', 'myTable', {dt='20120101'}) would drop all 3 partitions,
* with dt='20120101' (i.e. region = 'us', 'uk' and 'in').
* @param dbName The database name.
* @param tableName The table name.
* @param partitionSpec The partition specification, {[col_name,value],[col_name2,value2]}.
* @param ifExists Hive returns an error if the partition specified does not exist, unless ifExists is set to true.
* @throws HCatException,ConnectionFailureException
*/
public abstract void dropPartitions(String dbName, String tableName,
Map<String, String> partitionSpec, boolean ifExists)
throws HCatException;
/**
* Drops partition(s) that match the specified (and possibly partial) partition specification.
* A partial partition-specification is one where not all partition-keys have associated values. For example,
* for a table ('myDb.myTable') with 2 partition keys (dt string, region string),
* if for each dt ('20120101', '20120102', etc.) there can exist 3 regions ('us', 'uk', 'in'), then,
* 1. Complete partition spec: dropPartitions('myDb', 'myTable', {dt='20120101', region='us'}) would drop 1 partition.
* 2. Partial partition spec: dropPartitions('myDb', 'myTable', {dt='20120101'}) would drop all 3 partitions,
* with dt='20120101' (i.e. region = 'us', 'uk' and 'in').
* @param dbName The database name.
* @param tableName The table name.
* @param partitionSpec The partition specification, {[col_name,value],[col_name2,value2]}.
* @param ifExists Hive returns an error if the partition specified does not exist, unless ifExists is set to true.
* @param deleteData Whether to delete the underlying data.
* @throws HCatException,ConnectionFailureException
*/
public abstract void dropPartitions(String dbName, String tableName,
Map<String, String> partitionSpec, boolean ifExists, boolean deleteData)
throws HCatException;
/**
* List partitions by filter.
*
* @param dbName The database name.
* @param tblName The table name.
* @param filter The filter string,
* for example "part1 = \"p1_abc\" and part2 <= "\p2_test\"". Filtering can
* be done only on string partition keys.
* @return list of partitions
* @throws HCatException
*/
public abstract List<HCatPartition> listPartitionsByFilter(String dbName, String tblName,
String filter) throws HCatException;
/**
* List partitions by filter, but as HCatPartitionSpecs.
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract HCatPartitionSpec listPartitionSpecsByFilter(String dbName, String tblName,
String filter, int maxPartitions) throws HCatException;
/**
* Mark partition for event.
*
* @param dbName The database name.
* @param tblName The table name.
* @param partKVs the key-values associated with the partition.
* @param eventType the event type
* @throws HCatException
*/
public abstract void markPartitionForEvent(String dbName, String tblName,
Map<String, String> partKVs, PartitionEventType eventType)
throws HCatException;
/**
* Checks if a partition is marked for event.
*
* @param dbName the db name
* @param tblName the table name
* @param partKVs the key-values associated with the partition.
* @param eventType the event type
* @return true, if is partition marked for event
* @throws HCatException
*/
public abstract boolean isPartitionMarkedForEvent(String dbName, String tblName,
Map<String, String> partKVs, PartitionEventType eventType)
throws HCatException;
/**
* Gets the delegation token.
*
* @param owner the owner
* @param renewerKerberosPrincipalName the renewer kerberos principal name
* @return the delegation token
* @throws HCatException,ConnectionFailureException
*/
public abstract String getDelegationToken(String owner,
String renewerKerberosPrincipalName) throws HCatException;
/**
* Renew delegation token.
*
* @param tokenStrForm the token string
* @return the new expiration time
* @throws HCatException
*/
public abstract long renewDelegationToken(String tokenStrForm)
throws HCatException;
/**
* Cancel delegation token.
*
* @param tokenStrForm the token string
* @throws HCatException
*/
public abstract void cancelDelegationToken(String tokenStrForm)
throws HCatException;
/**
* Retrieve Message-bus topic for a table.
*
* @param dbName The name of the DB.
* @param tableName The name of the table.
* @return Topic-name for the message-bus on which messages will be sent for the specified table.
* By default, this is set to <db-name>.<table-name>. Returns null when not set.
*/
public abstract String getMessageBusTopicName(String dbName, String tableName) throws HCatException;
/**
* Get an iterator that iterates over a list of replication tasks needed to replicate all the
* events that have taken place for a given db/table.
* @param lastEventId : The last event id that was processed for this reader. The returned
* replication tasks will start from this point forward
* @param maxEvents : Maximum number of events to consider for generating the
* replication tasks. If < 1, then all available events will be considered.
* @param dbName : The database name for which we're interested in the events for.
* @param tableName : The table name for which we're interested in the events for - if null,
* then this function will behave as if it were running at a db level.
* @return an iterator over a list of replication events that can be processed one by one.
* @throws HCatException
*/
@InterfaceStability.Evolving
public abstract Iterator<ReplicationTask> getReplicationTasks(
long lastEventId, int maxEvents, String dbName, String tableName) throws HCatException;
/**
* Get a list of notifications
* @param lastEventId The last event id that was consumed by this reader. The returned
* notifications will start at the next eventId available this eventId that
* matches the filter.
* @param maxEvents Maximum number of events to return. If < 1, then all available events will
* be returned.
* @param filter Filter to determine if message should be accepted. If null, then all
* available events up to maxEvents will be returned.
* @return list of notifications, sorted by eventId. It is guaranteed that the events are in
* the order that the operations were done on the database.
* @throws HCatException
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract List<HCatNotificationEvent> getNextNotification(long lastEventId,
int maxEvents,
IMetaStoreClient.NotificationFilter filter)
throws HCatException;
/**
* Get the most recently used notification id.
* @return
* @throws HCatException
*/
@InterfaceAudience.LimitedPrivate({"Hive"})
@InterfaceStability.Evolving
public abstract long getCurrentNotificationEventId() throws HCatException;
/**
* Close the hcatalog client.
*
* @throws HCatException
*/
public abstract void close() throws HCatException;
}