package com.manning.hip.ch1; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapred.JobConf; import java.lang.reflect.Field; import java.util.*; public final class ConfigComparer { private final Configuration defaultConfig; private final Configuration siteConfig; private Map<String, String> invalidSiteConfigEntries = new HashMap<String, String>(); private List<ConfigProperty> configProperties; private final String defaultFile; private final String siteFile; public ConfigComparer(String defaultFile, String siteFile) throws NoSuchFieldException, IllegalAccessException { this.defaultFile = defaultFile; this.siteFile = siteFile; defaultConfig = loadConfiguration(defaultFile); siteConfig = loadConfiguration(siteFile); load(); } private void load() throws NoSuchFieldException, IllegalAccessException { Map<String, String> siteConfMap = toMap(siteConfig); Set<String> finalParameters = getConfigFinalProperties(defaultConfig); configProperties = new ArrayList<ConfigProperty>(); for(Map.Entry<String, String> entry: defaultConfig) { String key = entry.getKey(); String defaultValue = entry.getValue(); boolean mutable = !finalParameters.contains(key); String value = null; if(siteConfMap.containsKey(key)) { value = siteConfMap.get(key); siteConfMap.remove(key); } configProperties.add(new ConfigProperty(key, mutable, value, defaultValue)); } Collections.sort(configProperties); invalidSiteConfigEntries = siteConfMap; } Map<String, String> toMap(Configuration c) throws NoSuchFieldException, IllegalAccessException { Map<String, String> props = new HashMap<String, String>(); for(Map.Entry<String, String> entry: c) { props.put(entry.getKey(), entry.getValue()); } return props; } public static Set<String> getConfigFinalProperties(Configuration c) throws NoSuchFieldException, IllegalAccessException { Field privateStringField = Configuration.class. getDeclaredField("finalParameters"); privateStringField.setAccessible(true); return (Set<String>) privateStringField.get(c); } public static Configuration loadConfiguration(String file) { Configuration c = new Configuration(false); c.addResource(file); //c.reloadConfiguration(); return c; } public static void main(String... args) throws Exception { Configuration conf = new Configuration(); conf.writeXml(System.out); System.out.println("\n\n"); JobConf jobConf = new JobConf(conf); jobConf.writeXml(System.out); } @Override public String toString() { return new ToStringBuilder(this). append("configProperties", configProperties). append("invalidSiteConfigEntries", invalidSiteConfigEntries). toString(); } public String multiLineOutput() { StringBuilder sb = new StringBuilder(); sb.append("Default file: ").append(defaultFile); sb.append("\n"); sb.append("Site file: ").append(siteFile); sb.append("\n"); sb.append(String.format("%42s %7s %42s %42s", "Name", "Final", "Default File Value", "Site File Value")); sb.append("\n"); for(ConfigProperty c: configProperties) { sb.append(String.format("%42s %7b %42s %42s", StringUtils.abbreviate(c.getName(), 40), !c.isMutable(), StringUtils.abbreviate(c.getDefaultValue(), 40), StringUtils.abbreviate(c.getValue(), 40))); sb.append("\n"); } for(Map.Entry<String, String> entry: invalidSiteConfigEntries.entrySet()) { sb.append(String.format("%42s %7s %42s %42s", StringUtils.abbreviate(entry.getKey(), 40), "-", "-", StringUtils.abbreviate(entry.getValue(), 40))); sb.append("\n"); } return sb.toString(); } }