/** * 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.hive.metastore.messaging; import org.apache.hadoop.hive.common.JavaUtils; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.api.Database; import org.apache.hadoop.hive.metastore.api.Function; import org.apache.hadoop.hive.metastore.api.Index; import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.util.ReflectionUtils; import java.util.Iterator; import java.util.Map; /** * Abstract Factory for the construction of HCatalog message instances. */ public abstract class MessageFactory { // Common name constants for event messages public static final String ADD_PARTITION_EVENT = "ADD_PARTITION"; public static final String ALTER_PARTITION_EVENT = "ALTER_PARTITION"; public static final String DROP_PARTITION_EVENT = "DROP_PARTITION"; public static final String CREATE_TABLE_EVENT = "CREATE_TABLE"; public static final String ALTER_TABLE_EVENT = "ALTER_TABLE"; public static final String DROP_TABLE_EVENT = "DROP_TABLE"; public static final String CREATE_DATABASE_EVENT = "CREATE_DATABASE"; public static final String DROP_DATABASE_EVENT = "DROP_DATABASE"; public static final String INSERT_EVENT = "INSERT"; public static final String CREATE_FUNCTION_EVENT = "CREATE_FUNCTION"; public static final String DROP_FUNCTION_EVENT = "DROP_FUNCTION"; public static final String CREATE_INDEX_EVENT = "CREATE_INDEX"; public static final String DROP_INDEX_EVENT = "DROP_INDEX"; public static final String ALTER_INDEX_EVENT = "ALTER_INDEX"; private static MessageFactory instance = null; protected static final HiveConf hiveConf = new HiveConf(); static { hiveConf.addResource("hive-site.xml"); } // This parameter is retained for legacy reasons, in case someone implemented custom // factories. This, however, should not be the case, since this api was intended to // be internal-only, and we should manage the jms and json implementations without // needing this parameter. Marking as deprecated, for removal by 2.4 - see corresponding // note on the getDeserializer(String,String) method @Deprecated private static final String CONF_LABEL_HCAT_MESSAGE_FACTORY_IMPL_PREFIX = "hcatalog.message.factory.impl."; protected static final String MS_SERVER_URL = hiveConf.get(HiveConf.ConfVars.METASTOREURIS.name(), ""); protected static final String MS_SERVICE_PRINCIPAL = hiveConf.get(HiveConf.ConfVars.METASTORE_KERBEROS_PRINCIPAL.name(), ""); /** * Getter for MessageFactory instance. */ public static MessageFactory getInstance() { if (instance == null) { instance = getInstance(hiveConf.get(HiveConf.ConfVars.METASTORE_EVENT_MESSAGE_FACTORY.varname)); } return instance; } private static MessageFactory getInstance(String className) { try { return (MessageFactory)ReflectionUtils.newInstance(JavaUtils.loadClass(className), hiveConf); } catch (ClassNotFoundException classNotFound) { throw new IllegalStateException("Could not construct MessageFactory implementation: ", classNotFound); } } /** * Getter for MessageDeserializer, corresponding to the specified format and version. * @param format Serialization format for notifications. * @param version Version of serialization format (currently ignored.) * @return MessageDeserializer. */ public static MessageDeserializer getDeserializer(String format, String version) { return getInstance(hiveConf.get(CONF_LABEL_HCAT_MESSAGE_FACTORY_IMPL_PREFIX + format, HiveConf.ConfVars.METASTORE_EVENT_MESSAGE_FACTORY.varname)).getDeserializer(); // Note : The reason this method exists outside the no-arg getDeserializer method is in // case there is a user-implemented MessageFactory that's used, and some the messages // are in an older format and the rest in another. Then, what MessageFactory is default // is irrelevant, we should always use the one that was used to create it to deserialize. // // There exist only 2 implementations of this - json and jms // // Additional note : rather than as a config parameter, does it make sense to have // this use jdbc-like semantics that each MessageFactory made available register // itself for discoverability? Might be worth pursuing. } public abstract MessageDeserializer getDeserializer(); /** * Getter for message-format. */ public abstract String getMessageFormat(); /** * Factory method for CreateDatabaseMessage. * @param db The Database being added. * @return CreateDatabaseMessage instance. */ public abstract CreateDatabaseMessage buildCreateDatabaseMessage(Database db); /** * Factory method for DropDatabaseMessage. * @param db The Database being dropped. * @return DropDatabaseMessage instance. */ public abstract DropDatabaseMessage buildDropDatabaseMessage(Database db); /** * Factory method for CreateTableMessage. * @param table The Table being created. * @param files Iterator of files * @return CreateTableMessage instance. */ public abstract CreateTableMessage buildCreateTableMessage(Table table, Iterator<String> files); /** * Factory method for AlterTableMessage. Unlike most of these calls, this one can return null, * which means no message should be sent. This is because there are many flavors of alter * table (add column, add partition, etc.). Some are covered elsewhere (like add partition) * and some are not yet supported. * @param before The table before the alter * @param after The table after the alter * @param isTruncateOp Flag to denote truncate table * @return */ public abstract AlterTableMessage buildAlterTableMessage(Table before, Table after, boolean isTruncateOp); /** * Factory method for DropTableMessage. * @param table The Table being dropped. * @return DropTableMessage instance. */ public abstract DropTableMessage buildDropTableMessage(Table table); /** * Factory method for AddPartitionMessage. * @param table The Table to which the partitions are added. * @param partitions The iterator to set of Partitions being added. * @param partitionFiles The iterator of partition files * @return AddPartitionMessage instance. */ public abstract AddPartitionMessage buildAddPartitionMessage(Table table, Iterator<Partition> partitions, Iterator<PartitionFiles> partitionFiles); /** * Factory method for building AlterPartitionMessage * @param table The table in which the partition is being altered * @param before The partition before it was altered * @param after The partition after it was altered * @param isTruncateOp Flag to denote truncate partition * @return a new AlterPartitionMessage */ public abstract AlterPartitionMessage buildAlterPartitionMessage(Table table, Partition before, Partition after, boolean isTruncateOp); /** * Factory method for DropPartitionMessage. * @param table The Table from which the partition is dropped. * @param partitions The set of partitions being dropped. * @return DropPartitionMessage instance. */ public abstract DropPartitionMessage buildDropPartitionMessage(Table table, Iterator<Partition> partitions); /** * Factory method for CreateFunctionMessage. * @param fn The Function being added. * @return CreateFunctionMessage instance. */ public abstract CreateFunctionMessage buildCreateFunctionMessage(Function fn); /** * Factory method for DropFunctionMessage. * @param fn The Function being dropped. * @return DropFunctionMessage instance. */ public abstract DropFunctionMessage buildDropFunctionMessage(Function fn); /** * Factory method for CreateIndexMessage. * @param idx The Index being added. * @return CreateIndexMessage instance. */ public abstract CreateIndexMessage buildCreateIndexMessage(Index idx); /** * Factory method for DropIndexMessage. * @param idx The Index being dropped. * @return DropIndexMessage instance. */ public abstract DropIndexMessage buildDropIndexMessage(Index idx); /** * Factory method for AlterIndexMessage. * @param before The index before the alter * @param after The index after the alter * @return AlterIndexMessage */ public abstract AlterIndexMessage buildAlterIndexMessage(Index before, Index after); /** * Factory method for building insert message * * @param db Name of the database the insert occurred in * @param table Name of the table the insert occurred in * @param partVals Partition values for the partition that the insert occurred in, may be null if * the insert was done into a non-partitioned table * @param replace Flag to represent if INSERT OVERWRITE or INSERT INTO * @param files Iterator of file created * @return instance of InsertMessage */ public abstract InsertMessage buildInsertMessage(String db, String table, Map<String, String> partVals, boolean replace, Iterator<String> files); }