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();
}
}