package io.lumify.core.config; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import io.lumify.core.exception.LumifyException; import io.lumify.core.util.LumifyLogger; import io.lumify.core.util.LumifyLoggerFactory; import io.lumify.core.util.ProcessUtil; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.*; /** * Searches for lumify configuration directories in this order: * - ${ENV_LUMIFY_DIR} * - ${user.home}/.lumify * - ${appdata}/Lumify * - DEFAULT_UNIX_LOCATION or DEFAULT_WINDOWS_LOCATION */ public class FileConfigurationLoader extends ConfigurationLoader { /** * !!! DO NOT DEFINE A LOGGER here. This class get loaded very early in the process and we don't want to the logger to be initialized yet ** */ public static final String ENV_LUMIFY_DIR = "LUMIFY_DIR"; public static final String DEFAULT_UNIX_LOCATION = "/opt/lumify/"; public static final String DEFAULT_WINDOWS_LOCATION = "c:/opt/lumify/"; public FileConfigurationLoader(Map initParameters) { super(initParameters); } public Configuration createConfiguration() { final Map<String, String> properties = new HashMap<>(); List<File> configDirectories = getLumifyDirectoriesFromLeastPriority("config"); if (configDirectories.size() == 0) { throw new LumifyException("Could not find any valid config directories."); } for (File directory : configDirectories) { Map<String, String> directoryProperties = loadDirectory(directory); properties.putAll(directoryProperties); } return new Configuration(this, properties); } public static List<File> getLumifyDirectoriesFromMostPriority(String subDirectory) { return Lists.reverse(getLumifyDirectoriesFromLeastPriority(subDirectory)); } public static List<File> getLumifyDirectoriesFromLeastPriority(String subDirectory) { List<File> results = new ArrayList<>(); if (ProcessUtil.isWindows()) { addLumifySubDirectory(results, DEFAULT_WINDOWS_LOCATION, subDirectory); } else { addLumifySubDirectory(results, DEFAULT_UNIX_LOCATION, subDirectory); } String appData = System.getProperty("appdata"); if (appData != null && appData.length() > 0) { addLumifySubDirectory(results, new File(new File(appData), "Lumify").getAbsolutePath(), subDirectory); } String userHome = System.getProperty("user.home"); if (userHome != null && userHome.length() > 0) { addLumifySubDirectory(results, new File(new File(userHome), ".lumify").getAbsolutePath(), subDirectory); } addLumifySubDirectory(results, System.getenv(ENV_LUMIFY_DIR), subDirectory); return ImmutableList.copyOf(results); } private static void addLumifySubDirectory(List<File> results, String location, String subDirectory) { if (location == null || location.trim().length() == 0) { return; } location = location.trim(); if (location.startsWith("file://")) { location = location.substring("file://".length()); } File dir = new File(new File(location), subDirectory); if (!dir.exists()) { return; } results.add(dir); } private static Map<String, String> loadDirectory(File configDirectory) { LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(FileConfigurationLoader.class); LOGGER.debug("Attempting to load configuration from directory: %s", configDirectory); if (!configDirectory.exists()) { throw new LumifyException("Could not find config directory: " + configDirectory); } File[] files = configDirectory.listFiles(); if (files == null) { throw new LumifyException("Could not parse directory name: " + configDirectory); } Arrays.sort(files, new Comparator<File>() { @Override public int compare(File o1, File o2) { return o1.getName().compareTo(o2.getName()); } }); Map<String, String> properties = new HashMap<>(); for (File f : files) { if (!f.getAbsolutePath().endsWith(".properties")) { continue; } try { Map<String, String> fileProperties = loadFile(f.getAbsolutePath()); for (Map.Entry<String, String> filePropertyEntry : fileProperties.entrySet()) { properties.put(filePropertyEntry.getKey(), filePropertyEntry.getValue()); } } catch (IOException ex) { throw new LumifyException("Could not load config file: " + f.getAbsolutePath(), ex); } } return properties; } private static Map<String, String> loadFile(final String fileName) throws IOException { LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(FileConfigurationLoader.class); Map<String, String> results = new HashMap<>(); LOGGER.info("Loading config file: %s", fileName); try (FileInputStream in = new FileInputStream(fileName)) { Properties properties = new Properties(); properties.load(in); for (Map.Entry<Object, Object> prop : properties.entrySet()) { String key = prop.getKey().toString(); String value = prop.getValue().toString(); results.put(key, value); } } catch (Exception e) { LOGGER.info("Could not load configuration file: %s", fileName); } return results; } @Override public File resolveFileName(String fileName) { List<File> configDirectories = getLumifyDirectoriesFromMostPriority("config"); if (configDirectories.size() == 0) { throw new LumifyException("Could not find any valid config directories."); } for (File directory : configDirectories) { File f = new File(directory, fileName); if (f.exists()) { return f; } } return new File(configDirectories.get(0), fileName); } }