All Downloads are FREE. Search and download functionalities are using the official Maven repository.

parquet.hive.HiveBindingFactory Maven / Gradle / Ivy

The newest version!
/* 
 * 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 parquet.hive;

import java.lang.reflect.Method;

import parquet.Log;
import parquet.hive.internal.Hive010Binding;
import parquet.hive.internal.Hive012Binding;

/**
 * Factory for creating HiveBinding objects based on the version of Hive
 * available in the classpath. This class does not provide static methods
 * to enable mocking.
 */
public class HiveBindingFactory {
  private static final Log LOG = Log.getLog(HiveBindingFactory.class);
  private static final String HIVE_VERSION_CLASS_NAME = "org.apache.hive.common.util.HiveVersionInfo";
  private static final String HIVE_VERSION_METHOD_NAME = "getVersion";
  private static final String HIVE_UTILITIES_CLASS_NAME = "org.apache.hadoop.hive.ql.exec.Utilities";
  private static final String HIVE_012_INDICATOR_UTILITIES_GETMAPWORK = "getMapWork";
  private static final String HIVE_VERSION_NULL = "";
  private static final Class LATEST_BINDING = Hive012Binding.class;
  static final String HIVE_VERSION_UNKNOWN = "Unknown";
  static final String HIVE_VERSION_010 = "0.10";
  static final String HIVE_VERSION_011 = "0.11";
  static final String HIVE_VERSION_012 = "0.12";
  static final String HIVE_VERSION_013 = "0.13";

  /**
   * @return HiveBinding based on the Hive version in the classpath
   */
  public HiveBinding create() {
    Class bindingClazz = create(HiveBindingFactory.class
        .getClassLoader());
    try {
      return bindingClazz.newInstance();
    } catch (Exception e) {
      throw new HiveBindingInstantiationError("Unexpected error creating instance"
          + " of " + bindingClazz.getCanonicalName(), e);
    }
  }

  /**
   * Internal method visible for testing purposes
   */
  @SuppressWarnings("rawtypes")
  Class create(ClassLoader classLoader) {
    // HiveVersionInfo was added in 0.11, if the class does
    // not exist then return the hive binding for 0.10
    Class hiveVersionInfo;
    try {
      hiveVersionInfo = Class.forName(HIVE_VERSION_CLASS_NAME, true, classLoader);
    } catch (ClassNotFoundException e) {
      LOG.debug("Class " + HIVE_VERSION_CLASS_NAME + ", not found, returning " + 
          Hive010Binding.class.getSimpleName());
      return Hive010Binding.class;
    }
    return createInternal(hiveVersionInfo);
  }

  /**
   * Internal method visible for testing purposes
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  Class createInternal(Class hiveVersionInfo) {
    String hiveVersion;
    try {
      Method getVersionMethod = hiveVersionInfo.
          getMethod(HIVE_VERSION_METHOD_NAME, (Class[])null);
      String rawVersion = (String)getVersionMethod.invoke(null, (Object[])null);
      LOG.debug("Raw Version from " + hiveVersionInfo.getSimpleName() + " is '" +
          rawVersion + "'");
      hiveVersion = trimVersion(rawVersion);
    } catch (Exception e) {
      throw new UnexpectedHiveVersionProviderError("Unexpected error whilst " +
          "determining Hive version", e);
    }
    if(hiveVersion.equalsIgnoreCase(HIVE_VERSION_UNKNOWN)) {
      LOG.debug("Unknown hive version, attempting to guess");
      return createBindingForUnknownVersion();
    }
    if(hiveVersion.startsWith(HIVE_VERSION_010)) {
      LOG.debug("Hive version " + hiveVersion + ", returning " +
          Hive010Binding.class.getSimpleName());
      return Hive010Binding.class;
    } else if(hiveVersion.startsWith(HIVE_VERSION_011)) {
      LOG.debug("Hive version " + hiveVersion + ", returning " +
          Hive010Binding.class.getSimpleName() + " as it's expected the 0.10 " +
          "binding will work with 0.11");
      return Hive010Binding.class;
    } else if(hiveVersion.startsWith(HIVE_VERSION_013)) {
      throw new HiveBindingInstantiationError("Hive 0.13 contains native Parquet support " + 
          "and the parquet-hive jars from the parquet project should not be included " +
          "in Hive's classpath.");
    }
    LOG.debug("Hive version " + hiveVersion + ", returning " +
        Hive012Binding.class.getSimpleName());
    // as of 11/26/2013 it looks like the 0.12 binding will work for 0.13
    return Hive012Binding.class;
  }

  private Class createBindingForUnknownVersion() {
    try {
      Class utilitiesClass = Class.forName(HIVE_UTILITIES_CLASS_NAME);
      for(Method method : utilitiesClass.getDeclaredMethods()) {
        if(HIVE_012_INDICATOR_UTILITIES_GETMAPWORK.equals(method.getName())) {
          LOG.debug("Found " + HIVE_UTILITIES_CLASS_NAME + "." +
              HIVE_012_INDICATOR_UTILITIES_GETMAPWORK + " returning 0.12 binding");
          return Hive012Binding.class;
        }
      }
      // if the getMapWork method does not exist then it must be 0.10 or 0.11
      return Hive010Binding.class;
    } catch (ClassNotFoundException e) {
      LOG.debug("Could not find " + HIVE_UTILITIES_CLASS_NAME + ", returning" +
          " the latest binding since this class existed in 0.10, 0.11, and 0.12");
      return LATEST_BINDING;
    }
  }
  
  private static String trimVersion(String s) {
    if(s == null) {
      return HIVE_VERSION_NULL;
    }
    return s.trim();
  }
  static class HiveBindingInstantiationError extends Error {
    private static final long serialVersionUID = -9348060142128L;
    public HiveBindingInstantiationError(String msg) {
      super(msg);
    }
    public HiveBindingInstantiationError(String msg, Exception e) {
      super(msg, e);
    }
  }
  static class UnexpectedHiveVersionProviderError extends Error {
    private static final long serialVersionUID = -7344858060142118L;
    public UnexpectedHiveVersionProviderError(String msg, Exception e) {
      super(msg, e);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy