Updated Branches: refs/heads/master 42e790dfa -> e2aab0097
ACCUMULO-1398 added admin command dumpConfig Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/e2aab009 Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/e2aab009 Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/e2aab009 Branch: refs/heads/master Commit: e2aab00970d90c7774e9cf3cf8044ce174ac3d8b Parents: 42e790d Author: Eric Newton <[email protected]> Authored: Wed Sep 18 13:33:22 2013 -0400 Committer: Eric Newton <[email protected]> Committed: Wed Sep 18 13:33:22 2013 -0400 ---------------------------------------------------------------------- .../org/apache/accumulo/server/util/Admin.java | 154 +++++++++++++++++-- 1 file changed, 140 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/accumulo/blob/e2aab009/server/src/main/java/org/apache/accumulo/server/util/Admin.java ---------------------------------------------------------------------- diff --git a/server/src/main/java/org/apache/accumulo/server/util/Admin.java b/server/src/main/java/org/apache/accumulo/server/util/Admin.java index 8c797cd..74581a5 100644 --- a/server/src/main/java/org/apache/accumulo/server/util/Admin.java +++ b/server/src/main/java/org/apache/accumulo/server/util/Admin.java @@ -16,10 +16,21 @@ */ package org.apache.accumulo.server.util; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.net.InetSocketAddress; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import java.util.SortedSet; import java.util.concurrent.atomic.AtomicInteger; import org.apache.accumulo.core.client.AccumuloException; @@ -31,6 +42,9 @@ import org.apache.accumulo.core.client.admin.InstanceOperations; import org.apache.accumulo.core.client.impl.ClientExec; import org.apache.accumulo.core.client.impl.MasterClient; import org.apache.accumulo.core.client.security.tokens.AuthenticationToken; +import org.apache.accumulo.core.conf.AccumuloConfiguration; +import org.apache.accumulo.core.conf.DefaultConfiguration; +import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.master.thrift.MasterClientService; import org.apache.accumulo.core.metadata.MetadataTable; import org.apache.accumulo.core.security.Credentials; @@ -38,6 +52,7 @@ import org.apache.accumulo.core.util.AddressUtil; import org.apache.accumulo.server.cli.ClientOpts; import org.apache.accumulo.server.security.SystemCredentials; import org.apache.accumulo.trace.instrument.Tracer; +import org.apache.hadoop.conf.Configuration; import org.apache.log4j.Logger; import com.beust.jcommander.JCommander; @@ -72,7 +87,7 @@ public class Admin { @Parameter(names = {"-t", "--table"}, description = "Table to check, if not set checks all tables") String table = null; } - + @Parameters(commandDescription = "stop the master") static class StopMasterCommand {} @@ -86,23 +101,38 @@ public class Admin { @Parameter(names = "--print-all", description = "print information for all instances, not just those with names") boolean printAll = false; } - + + @Parameters(commandDescription = "print out non-default configuration settings") + static class DumpConfigCommand { + @Parameter(names={"-t", "--tables"}, description = "print per-table configuration") + List<String> tables = new ArrayList<String>(); + @Parameter(names={"-a", "--all"}, description = "print the system and all table configurations") + boolean allConfiguration = false; + @Parameter(names={"-s", "--system"}, description = "print the system configuration") + boolean systemConfiguration = false; + @Parameter(names={"-d", "--directory"}, description = "directory to place config files") + String directory = null; + } + public static void main(String[] args) { boolean everything; AdminOpts opts = new AdminOpts(); JCommander cl = new JCommander(opts); cl.setProgramName(Admin.class.getName()); - + CheckTabletsCommand checkTabletsCommand = new CheckTabletsCommand(); cl.addCommand("checkTablets", checkTabletsCommand); - + ListInstancesCommand listIntancesOpts = new ListInstancesCommand(); cl.addCommand("listInstances", listIntancesOpts); PingCommand pingCommand = new PingCommand(); cl.addCommand("ping", pingCommand); - + + DumpConfigCommand dumpConfigCommand = new DumpConfigCommand(); + cl.addCommand("dumpConfig", dumpConfigCommand); + StopCommand stopOpts = new StopCommand(); cl.addCommand("stop", stopOpts); StopAllCommand stopAllOpts = new StopAllCommand(); @@ -129,7 +159,7 @@ public class Admin { } int rc = 0; - + if (cl.getParsedCommand().equals("listInstances")) { ListInstances.listInstances(instance.getZooKeepers(), listIntancesOpts.printAll, listIntancesOpts.printErrors); } else if (cl.getParsedCommand().equals("ping")) { @@ -147,9 +177,11 @@ public class Admin { if (RemoveEntriesForMissingFiles.checkTable(instance, principal, token, checkTabletsCommand.table, checkTabletsCommand.fixFiles) != 0) rc = 6; } - - }else if (cl.getParsedCommand().equals("stop")) { + + } else if (cl.getParsedCommand().equals("stop")) { stopTabletServer(instance, new Credentials(principal, token), stopOpts.args, opts.force); + } else if (cl.getParsedCommand().equals("dumpConfig")) { + printConfig(instance, principal, token, dumpConfigCommand); } else { everything = cl.getParsedCommand().equals("stopAll"); @@ -174,7 +206,7 @@ public class Admin { } private static int ping(Instance instance, String principal, AuthenticationToken token, List<String> args) throws AccumuloException, - AccumuloSecurityException { + AccumuloSecurityException { InstanceOperations io = instance.getConnector(principal, token).instanceOperations(); @@ -183,7 +215,7 @@ public class Admin { } int unreachable = 0; - + for (String tserver : args) { try { io.ping(tserver); @@ -197,14 +229,14 @@ public class Admin { System.out.printf("\n%d of %d tablet servers unreachable\n\n", unreachable, args.size()); return unreachable; } - + /** * flushing during shutdown is a performance optimization, its not required. The method will make an attempt to initiate flushes of all tables and give up if * it takes too long. * */ private static void flushAll(final Instance instance, final String principal, final AuthenticationToken token) throws AccumuloException, - AccumuloSecurityException { + AccumuloSecurityException { final AtomicInteger flushesStarted = new AtomicInteger(0); @@ -252,7 +284,7 @@ public class Admin { } private static void stopServer(final Instance instance, final Credentials credentials, final boolean tabletServersToo) throws AccumuloException, - AccumuloSecurityException { + AccumuloSecurityException { MasterClient.execute(instance, new ClientExec<MasterClientService.Client>() { @Override public void execute(MasterClientService.Client client) throws Exception { @@ -262,7 +294,7 @@ public class Admin { } private static void stopTabletServer(final Instance instance, final Credentials creds, List<String> servers, final boolean force) throws AccumuloException, - AccumuloSecurityException { + AccumuloSecurityException { for (String server : servers) { InetSocketAddress address = AddressUtil.parseAddress(server); final String finalServer = org.apache.accumulo.core.util.AddressUtil.toString(address); @@ -275,4 +307,98 @@ public class Admin { }); } } + + private static final String ACCUMULO_SITE_BACKUP_FILE = "accumulo-site.xml.bak"; + private static final MessageFormat format = new MessageFormat("config -t {0} -s {1}\n"); + + private static DefaultConfiguration defaultConfig; + private static Map<String,String> siteConfig, systemConfig; + + public static void printConfig(Instance instance, String principal, AuthenticationToken token, DumpConfigCommand opts) throws Exception { + + File outputDirectory = null; + if (opts.directory != null) { + outputDirectory = new File(opts.directory); + if (!outputDirectory.isDirectory()) { + throw new IllegalArgumentException(opts.directory + " does not exist on the local filesystem."); + } + if (!outputDirectory.canWrite()) { + throw new IllegalArgumentException(opts.directory + " is not writable"); + } + } + Connector connector = instance.getConnector(principal, token); + defaultConfig = AccumuloConfiguration.getDefaultConfiguration(); + siteConfig = connector.instanceOperations().getSiteConfiguration(); + systemConfig = connector.instanceOperations().getSystemConfiguration(); + if (opts.allConfiguration) { + printSystemConfiguration(outputDirectory); + SortedSet<String> tableNames = connector.tableOperations().list(); + for (String tableName : tableNames) { + printTableConfiguration(connector, tableName, outputDirectory); + } + + } else { + if (opts.systemConfiguration) { + printSystemConfiguration(outputDirectory); + } + + for (String tableName : opts.tables) { + printTableConfiguration(connector, tableName, outputDirectory); + } + } + } + + private static String getDefaultConfigValue (String key) { + if (null == key) return null; + + String defaultValue = null; + try { + Property p = Property.getPropertyByKey(key); + if (null == p) + return defaultValue; + defaultValue = defaultConfig.get(p); + } catch (IllegalArgumentException e) { + } + return defaultValue; + } + + private static void printSystemConfiguration(File outputDirectory) throws IOException { + Configuration conf = new Configuration(false); + for (Entry<String,String> prop : siteConfig.entrySet()) { + String defaultValue = getDefaultConfigValue(prop.getKey()); + if (!prop.getValue().equals(defaultValue) && !systemConfig.containsKey(prop.getKey())) { + conf.set(prop.getKey(), prop.getValue()); + } + } + for (Entry<String,String> prop : systemConfig.entrySet()) { + String defaultValue = getDefaultConfigValue(prop.getKey()); + if (!prop.getValue().equals(defaultValue)) { + conf.set(prop.getKey(), prop.getValue()); + } + } + File siteBackup = new File(outputDirectory, ACCUMULO_SITE_BACKUP_FILE); + FileOutputStream fos = new FileOutputStream(siteBackup); + try { + conf.writeXml(fos); + } finally { + fos.close(); + } + } + + private static void printTableConfiguration(Connector connector, String tableName, File outputDirectory) throws AccumuloException, TableNotFoundException, IOException { + Iterable<Entry<String,String>> tableConfig = connector.tableOperations().getProperties(tableName); + File tableBackup = new File(outputDirectory, tableName+".cfg"); + FileWriter writer = new FileWriter(tableBackup); + for (Entry<String,String> prop : tableConfig) { + if (prop.getKey().startsWith(Property.TABLE_PREFIX.getKey())) { + String defaultValue = getDefaultConfigValue(prop.getKey()); + if (defaultValue == null || !defaultValue.equals(prop.getValue())) { + if (!prop.getValue().equals(siteConfig.get(prop.getKey())) && !prop.getValue().equals(systemConfig.get(prop.getKey()))) { + writer.write(format.format(new String[] {tableName, prop.getKey() + "=" + prop.getValue() } )); + } + } + } + } + writer.close(); + } }
