/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* 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 com.asakusafw.testdriver.hadoop;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.LocalFileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.asakusafw.runtime.util.hadoop.ConfigurationProvider;
import com.asakusafw.testdriver.core.TestingEnvironmentConfigurator;
/**
* Creates {@link Configuration}s with system defaults.
* @since 0.2.5
* @version 0.6.0
*/
public class ConfigurationFactory extends ConfigurationProvider {
static final Logger LOG = LoggerFactory.getLogger(ConfigurationFactory.class);
/**
* The system property key of {@link LocalFileSystem} implementation class name.
* @since 0.6.0
*/
public static final String KEY_LOCAL_FILE_SYSTEM = "asakusa.testdriver.fs"; //$NON-NLS-1$
/**
* The system property key of Hadoop configuration path.
* @since 0.6.0
*/
public static final String KEY_EXPLICIT_HADOOP_CONF = "asakusa.testdriver.hadoop.conf"; //$NON-NLS-1$
/**
* The system property key of Hadoop command path.
* @since 0.6.0
*/
public static final String KEY_EXPLICIT_HADOOP_COMMAND = "asakusa.testdriver.hadoop.command"; //$NON-NLS-1$
/**
* The default value of {@link LocalFileSystem} implementation class name.
*/
static final String DEFAULT_LOCAL_FILE_SYSTEM = AsakusaTestLocalFileSystem.class.getName();
static {
TestingEnvironmentConfigurator.initialize();
}
private final Preferences preferences;
/**
* Creates a new instance.
* @see #getDefault()
*/
private ConfigurationFactory() {
this(Preferences.getDefault());
}
/**
* Creates a new instance.
* @param defaultConfigPath the default configuration path
* @see #getDefault()
*/
public ConfigurationFactory(URL defaultConfigPath) {
super(defaultConfigPath);
this.preferences = Preferences.getDefault();
}
/**
* Creates a new instance.
* @param preferences the preferences for this instance
* @see #getDefault()
* @since 0.6.0
*/
public ConfigurationFactory(Preferences preferences) {
super(preferences.getConfigurationPath());
this.preferences = preferences;
}
/**
* Returns a default factory which refers the System Hadoop configuration path.
* <p>
* If Hadoop installation is not found in your system,
* this returns a factory which use the current context classloader.
* </p>
* @return a default factory object
*/
public static ConfigurationFactory getDefault() {
return new ConfigurationFactory();
}
/**
* Returns the Hadoop command path for this configuration.
* @return the Hadoop command path, or {@code null} if it is not found
*/
public File getHadoopCommand() {
return preferences.getHadoopCommand();
}
@Override
protected void configure(Configuration configuration) {
if (preferences.getLocalFileSystemClassName() != null) {
configuration.set("fs.file.impl", preferences.getLocalFileSystemClassName()); //$NON-NLS-1$
configuration.setBoolean("fs.file.impl.disable.cache", true); //$NON-NLS-1$
}
}
/**
* Preferences for {@link ConfigurationFactory}.
* @since 0.6.0
*/
public static class Preferences {
private String localFileSystemClassName;
private File explicitConfigurationPath;
private File explicitCommandPath;
private final Map<String, String> environmentVariables = new HashMap<>(System.getenv());
/**
* Sets the implementation class name of {@link LocalFileSystem}.
* @param className the class name
*/
public void setLocalFileSystemClassName(String className) {
this.localFileSystemClassName = className;
}
/**
* Sets the explicit Hadoop configuration path.
* @param path the Hadoop configuration path, or {@code null} if it should be inferred
*/
public void setExplicitConfigurationPath(File path) {
this.explicitConfigurationPath = path;
}
/**
* Sets the explicit Hadoop command path.
* @param path the Hadoop command path, or {@code null} if it should be inferred
*/
public void setExplicitCommandPath(File path) {
this.explicitCommandPath = path;
}
/**
* Returns the implementation class name of {@link LocalFileSystem}.
* @return the class name, or {@code null} if it is not defined
*/
public String getLocalFileSystemClassName() {
return localFileSystemClassName;
}
/**
* Returns the current environment variables.
* Clients can modify the returned map.
* @return the environment variables
*/
public Map<String, String> getEnvironmentVariables() {
return environmentVariables;
}
/**
* Returns the explicitly defined Hadoop configuration path.
* @return the explicit Hadoop configuration path, or {@code null} if it is not defined
*/
public File getExplicitConfigurationPath() {
return explicitConfigurationPath;
}
/**
* Returns the explicitly defined Hadoop command path.
* @return the explicit Hadoop command path, or {@code null} if it is not defined
*/
public File getExplicitCommandPath() {
return explicitCommandPath;
}
/**
* Returns the Hadoop configuration path.
* @return the Hadoop configuration path, or {@code null} if it is not found
* @see #getExplicitConfigurationPath()
*/
public URL getConfigurationPath() {
if (explicitConfigurationPath != null) {
try {
return explicitConfigurationPath.toURI().toURL();
} catch (MalformedURLException e) {
LOG.error(MessageFormat.format(
Messages.getString(
"ConfigurationFactory.errorInvalidHadoopConfigurationPath"), //$NON-NLS-1$
explicitConfigurationPath), e);
}
}
return ConfigurationProvider.getConfigurationPath(environmentVariables);
}
/**
* Returns the Hadoop command path.
* @return the Hadoop command path, or {@code null} if it is not found
*/
public File getHadoopCommand() {
if (explicitCommandPath != null) {
return explicitCommandPath;
}
return ConfigurationProvider.findHadoopCommand(environmentVariables);
}
/**
* Returns a {@link Preferences} with default values.
* @return default preferences
*/
public static Preferences getDefault() {
Preferences prefs = new Preferences();
prefs.setLocalFileSystemClassName(System.getProperty(KEY_LOCAL_FILE_SYSTEM, DEFAULT_LOCAL_FILE_SYSTEM));
prefs.setExplicitConfigurationPath(getFile(KEY_EXPLICIT_HADOOP_CONF));
prefs.setExplicitCommandPath(getFile(KEY_EXPLICIT_HADOOP_COMMAND));
return prefs;
}
private static File getFile(String key) {
String value = System.getProperty(key);
if (value == null) {
return null;
}
return new File(value);
}
}
}