/******************************************************************************* * * Pentaho Big Data * * Copyright (C) 2002-2015 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * Licensed 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.pentaho.hadoop.shim; import org.apache.commons.vfs2.FileObject; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.hadoop.shim.api.Configuration; import org.pentaho.hadoop.shim.api.process.Processable; import org.pentaho.hadoop.shim.spi.HadoopShim; import org.pentaho.hadoop.shim.spi.PentahoHadoopShim; import org.pentaho.hadoop.shim.spi.PigShim; import org.pentaho.hadoop.shim.spi.SnappyShim; import org.pentaho.hadoop.shim.spi.SqoopShim; import org.pentaho.hbase.shim.spi.HBaseShim; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; import java.util.Properties; /** * A collection of Hadoop shim implementations for interactive with a Hadoop cluster. */ public class HadoopConfiguration { private static final Class<?> PKG = HadoopConfiguration.class; private String identifier; private String name; /** * Root directory for this configuration */ private FileObject location; private HadoopShim hadoopShim; private List<PentahoHadoopShim> availableShims; private Properties configProperties; /** * Create a new Hadoop configuration with the provided shims. Only * * @param location Location where this configuration resides * @param identifier Unique identifier for this configuration * @param name Friendly name for this configuration * @param hadoopShim Hadoop shim * @param shims Available shims for this Hadoop configuration * @throws NullPointerException when {@code identifier}, {@code name}. * @throws NullPointerException when {@code identifier}, {@code name}, or {@code hadoopShim} are {@code null} */ public HadoopConfiguration( FileObject location, String identifier, String name, HadoopShim hadoopShim, PentahoHadoopShim... shims ) { this( new Properties(), location, identifier, name, hadoopShim, shims ); } public HadoopConfiguration( Properties configProperties, FileObject location, String identifier, String name, HadoopShim hadoopShim, PentahoHadoopShim... shims ) { if ( location == null || identifier == null || name == null || hadoopShim == null ) { throw new NullPointerException(); } this.location = location; this.identifier = identifier; this.name = name; this.hadoopShim = hadoopShim; this.configProperties = configProperties; // Register all provided shims availableShims = new ArrayList<PentahoHadoopShim>(); // Add the hadoop shim to the list so we don't have to handle it special in getShim() availableShims.add( hadoopShim ); for ( PentahoHadoopShim shim : shims ) { if ( shim == null ) { // Skip null shims continue; } availableShims.add( shim ); } } public Properties getConfigProperties() { return configProperties; } /** * @return the location (root directory) of this Hadoop configuration */ public FileObject getLocation() { return location; } /** * @return this configuration's identifier */ public String getIdentifier() { return identifier; } /** * @return the friendly name for this configuration */ public String getName() { return name; } /** * @return the Hadoop shim for this configuration */ public HadoopShim getHadoopShim() { return getWrappedHadoopShim(); } private HadoopShim getWrappedHadoopShim() { return (HadoopShim) Proxy .newProxyInstance( hadoopShim.getClass().getClassLoader(), new Class[] { HadoopShim.class }, new InvocationHandler() { @Override public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable { if ( method.getName().equals( "submitJob" ) ) { process( (Configuration) args[ 0 ] ); } return method.invoke( hadoopShim, args ); } } ); } /** * Retrieve the Sqoop shim for this configuration if it's available * * @return the Sqoop shim * @throws ConfigurationException No Sqoop shim available for this configuration */ public SqoopShim getSqoopShim() throws ConfigurationException { return getShim( SqoopShim.class ); } /** * Retrieve the Pig shim for this configuration if it's available * * @return the Pig shim * @throws ConfigurationException No Pig shim available for this configuration */ public PigShim getPigShim() throws ConfigurationException { return getShim( PigShim.class ); } /** * Retrieve the Snappy shim for this configuration if it's available * * @return the Snappy shim * @throws ConfigurationException No Snappy shim available for this configuration */ public SnappyShim getSnappyShim() throws ConfigurationException { return getShim( SnappyShim.class ); } /** * Retrieve the first registered shim that matches the shim type provided. * * @param shimType The type of {@code PentahoHadoopShim} to get from this configuration. * @return A shim that matches the type * @throws ConfigurationException This configuration does not contain a shim that matches the type requested */ public <T extends PentahoHadoopShim> T getShim( Class<T> shimType ) throws ConfigurationException { for ( PentahoHadoopShim shim : availableShims ) { if ( shimType.isAssignableFrom( shim.getClass() ) ) { @SuppressWarnings( "unchecked" ) T t = (T) shim; return t; } } throw new ConfigurationException( BaseMessages.getString( PKG, "Error.UnsupportedShim", getName(), shimType.getSimpleName() ) ); } /** * Retrieve the HBase shim for this configuration if it's available * * @return the HBase shim * @throws ConfigurationException No HBase shim available for this configuration */ public HBaseShim getHBaseShim() throws ConfigurationException { return getShim( HBaseShim.class ); } /** * The identifier for this configuration */ @Override public String toString() { return getIdentifier(); } public List<PentahoHadoopShim> getAvailableShims() { return availableShims; } public void process( Configuration configuration ) { Processable processable; for ( PentahoHadoopShim shim : getAvailableShims() ) { if ( Processable.class.isInstance( shim ) ) { processable = (Processable) shim; processable.process( configuration ); } } } }