You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by vi...@apache.org on 2012/07/13 22:34:49 UTC

svn commit: r1361382 [13/16] - in /accumulo/branches/ACCUMULO-259: ./ bin/ conf/examples/1GB/native-standalone/ conf/examples/1GB/standalone/ conf/examples/2GB/native-standalone/ conf/examples/2GB/standalone/ conf/examples/3GB/native-standalone/ conf/e...

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/balancer/TabletBalancer.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/balancer/TabletBalancer.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/balancer/TabletBalancer.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/balancer/TabletBalancer.java Fri Jul 13 20:34:44 2012
@@ -22,11 +22,12 @@ import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 
+import org.apache.accumulo.cloudtrace.instrument.Tracer;
 import org.apache.accumulo.core.data.KeyExtent;
 import org.apache.accumulo.core.master.thrift.TabletServerStatus;
 import org.apache.accumulo.core.security.thrift.ThriftSecurityException;
 import org.apache.accumulo.core.tabletserver.thrift.TabletClientService;
-import org.apache.accumulo.core.tabletserver.thrift.TabletClientService.Iface;
+import org.apache.accumulo.core.tabletserver.thrift.TabletClientService.Client;
 import org.apache.accumulo.core.tabletserver.thrift.TabletStats;
 import org.apache.accumulo.core.util.ThriftUtil;
 import org.apache.accumulo.server.conf.ServerConfiguration;
@@ -95,9 +96,9 @@ public abstract class TabletBalancer {
    */
   public List<TabletStats> getOnlineTabletsForTable(TServerInstance tserver, String tableId) throws ThriftSecurityException, TException {
     log.debug("Scanning tablet server " + tserver + " for table " + tableId);
-    Iface client = ThriftUtil.getClient(new TabletClientService.Client.Factory(), tserver.getLocation(), configuration.getConfiguration());
+    Client client = ThriftUtil.getClient(new TabletClientService.Client.Factory(), tserver.getLocation(), configuration.getConfiguration());
     try {
-      List<TabletStats> onlineTabletsForTable = client.getTabletStats(null, SecurityConstants.getSystemCredentials(), tableId);
+      List<TabletStats> onlineTabletsForTable = client.getTabletStats(Tracer.traceInfo(), SecurityConstants.getSystemCredentials(), tableId);
       return onlineTabletsForTable;
     } catch (TTransportException e) {
       log.error("Unable to connect to " + tserver + ": " + e);

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/recovery/SubmitFileForRecovery.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/recovery/SubmitFileForRecovery.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/recovery/SubmitFileForRecovery.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/recovery/SubmitFileForRecovery.java Fri Jul 13 20:34:44 2012
@@ -21,9 +21,9 @@ import java.io.IOException;
 import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.zookeeper.ZooUtil;
 import org.apache.accumulo.fate.Repo;
-import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeExistsPolicy;
 import org.apache.accumulo.server.master.Master;
 import org.apache.accumulo.server.master.tableOps.MasterRepo;
+import org.apache.accumulo.server.zookeeper.DistributedWorkQueue;
 import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -48,18 +48,19 @@ public class SubmitFileForRecovery exten
   public Repo<Master> call(long tid, final Master master) throws Exception {
     master.updateRecoveryInProgress(file);
     String source = RecoverLease.getSource(master, server, file).toString();
+    new DistributedWorkQueue(ZooUtil.getRoot(master.getInstance()) + Constants.ZRECOVERY).addWork(file, source.getBytes());
+    
     ZooReaderWriter zoo = ZooReaderWriter.getInstance();
     final String path = ZooUtil.getRoot(master.getInstance()) + Constants.ZRECOVERY + "/" + file;
-    zoo.putPersistentData(path, source.getBytes(), NodeExistsPolicy.SKIP);
     log.info("Created zookeeper entry " + path + " with data " + source);
     zoo.exists(path, new Watcher() {
       @Override
       public void process(WatchedEvent event) {
         switch (event.getType()) {
-          case NodeDataChanged:
+          case NodeDeleted:
             log.info("noticed recovery entry for " + file + " was removed");
             FileSystem fs = master.getFileSystem();
-            Path finished = new Path(Constants.getRecoveryDir(master.getSystemConfiguration()), "finished");
+            Path finished = new Path(Constants.getRecoveryDir(master.getSystemConfiguration()) + "/" + file, "finished");
             try {
               if (fs.exists(finished))
                 log.info("log recovery for " + file + " successful");

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tableOps/BulkImport.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tableOps/BulkImport.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tableOps/BulkImport.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tableOps/BulkImport.java Fri Jul 13 20:34:44 2012
@@ -16,13 +16,19 @@
  */
 package org.apache.accumulo.server.master.tableOps;
 
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
@@ -30,22 +36,28 @@ import java.util.concurrent.Future;
 import java.util.concurrent.ThreadPoolExecutor;
 
 import org.apache.accumulo.cloudtrace.instrument.TraceExecutorService;
+import org.apache.accumulo.cloudtrace.instrument.Tracer;
 import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.Connector;
 import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.IsolatedScanner;
+import org.apache.accumulo.core.client.Scanner;
 import org.apache.accumulo.core.client.impl.ServerClient;
 import org.apache.accumulo.core.client.impl.Tables;
 import org.apache.accumulo.core.client.impl.thrift.ClientService;
+import org.apache.accumulo.core.client.impl.thrift.ClientService.Client;
 import org.apache.accumulo.core.client.impl.thrift.ClientService.Iface;
 import org.apache.accumulo.core.client.impl.thrift.TableOperation;
 import org.apache.accumulo.core.client.impl.thrift.TableOperationExceptionType;
 import org.apache.accumulo.core.client.impl.thrift.ThriftTableOperationException;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.conf.SiteConfiguration;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.KeyExtent;
+import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.core.file.FileOperations;
 import org.apache.accumulo.core.master.state.tables.TableState;
 import org.apache.accumulo.core.security.thrift.AuthInfo;
-import org.apache.accumulo.core.util.CachedConfiguration;
 import org.apache.accumulo.core.util.Pair;
 import org.apache.accumulo.core.util.SimpleThreadPool;
 import org.apache.accumulo.core.util.UtilWaitThread;
@@ -58,14 +70,16 @@ import org.apache.accumulo.server.master
 import org.apache.accumulo.server.master.state.TServerInstance;
 import org.apache.accumulo.server.security.SecurityConstants;
 import org.apache.accumulo.server.tabletserver.UniqueNameAllocator;
-import org.apache.accumulo.server.trace.TraceFileSystem;
 import org.apache.accumulo.server.util.MetadataTable;
+import org.apache.accumulo.server.zookeeper.DistributedWorkQueue;
 import org.apache.accumulo.server.zookeeper.TransactionWatcher.ZooArbitrator;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.FileUtil;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.MapFile;
+import org.apache.hadoop.io.Text;
 import org.apache.log4j.Logger;
 import org.apache.thrift.TException;
 
@@ -133,9 +147,8 @@ public class BulkImport extends MasterRe
     Utils.getReadLock(tableId, tid).lock();
     
     // check that the error directory exists and is empty
-    FileSystem fs = TraceFileSystem.wrap(org.apache.accumulo.core.file.FileUtil.getFileSystem(CachedConfiguration.getInstance(),
-        ServerConfiguration.getSiteConfiguration()));
-    ;
+    FileSystem fs = master.getFileSystem();
+
     Path errorPath = new Path(errorDir);
     FileStatus errorStatus = fs.getFileStatus(errorPath);
     if (errorStatus == null)
@@ -273,24 +286,6 @@ class CleanUpBulkImport extends MasterRe
   }
   
   @Override
-  public long isReady(long tid, Master master) throws Exception {
-    Set<TServerInstance> finished = new HashSet<TServerInstance>();
-    Set<TServerInstance> running = master.onlineTabletServers();
-    for (TServerInstance server : running) {
-      try {
-        TServerConnection client = master.getConnection(server);
-        if (client != null && !client.isActive(tid))
-          finished.add(server);
-      } catch (TException ex) {
-        log.info("Ignoring error trying to check on tid " + tid + " from server " + server + ": " + ex);
-      }
-    }
-    if (finished.containsAll(running))
-      return 0;
-    return 1000;
-  }
-  
-  @Override
   public Repo<Master> call(long tid, Master master) throws Exception {
     log.debug("removing the bulk processing flag file in " + bulk);
     Path bulkDir = new Path(bulk);
@@ -327,8 +322,124 @@ class CompleteBulkImport extends MasterR
   @Override
   public Repo<Master> call(long tid, Master master) throws Exception {
     ZooArbitrator.stop(Constants.BULK_ARBITRATOR_TYPE, tid);
+    return new CopyFailed(tableId, source, bulk, error);
+  }
+}
+
+class CopyFailed extends MasterRepo {
+  
+  private static final long serialVersionUID = 1L;
+
+  private String tableId;
+  private String source;
+  private String bulk;
+  private String error;
+  
+  public CopyFailed(String tableId, String source, String bulk, String error) {
+    this.tableId = tableId;
+    this.source = source;
+    this.bulk = bulk;
+    this.error = error;
+  }
+  
+  @Override
+  public long isReady(long tid, Master master) throws Exception {
+    Set<TServerInstance> finished = new HashSet<TServerInstance>();
+    Set<TServerInstance> running = master.onlineTabletServers();
+    for (TServerInstance server : running) {
+      try {
+        TServerConnection client = master.getConnection(server);
+        if (client != null && !client.isActive(tid))
+          finished.add(server);
+      } catch (TException ex) {
+        log.info("Ignoring error trying to check on tid " + tid + " from server " + server + ": " + ex);
+      }
+    }
+    if (finished.containsAll(running))
+      return 0;
+    return 500;
+  }
+  
+  @Override
+  public Repo<Master> call(long tid, Master environment) throws Exception {
+	//This needs to execute after the arbiter is stopped  
+	  
+    FileSystem fs = environment.getFileSystem();
+	  
+    if (!fs.exists(new Path(error, "failures.txt")))
+      return new CleanUpBulkImport(tableId, source, bulk, error);
+    
+    HashMap<String,String> failures = new HashMap<String,String>();
+    HashMap<String,String> loadedFailures = new HashMap<String,String>();
+    
+    FSDataInputStream failFile = fs.open(new Path(error, "failures.txt"));
+    BufferedReader in = new BufferedReader(new InputStreamReader(failFile));
+    try {
+      String line = null;
+      while ((line = in.readLine()) != null) {
+        Path path = new Path(line);
+        if (!fs.exists(new Path(error, path.getName())))
+          failures.put("/" + path.getParent().getName() + "/" + path.getName(), line);
+      }
+    } finally {
+      failFile.close();
+    }
+    
+    /*
+     * I thought I could move files that have no file references in the table. However its possible a clone references a file. Therefore only move files that
+     * have no loaded markers.
+     */
+
+    // determine which failed files were loaded
+    AuthInfo creds = SecurityConstants.getSystemCredentials();
+    Connector conn = HdfsZooInstance.getInstance().getConnector(creds.user, creds.password);
+    Scanner mscanner = new IsolatedScanner(conn.createScanner(Constants.METADATA_TABLE_NAME, Constants.NO_AUTHS));
+    mscanner.setRange(new KeyExtent(new Text(tableId), null, null).toMetadataRange());
+    mscanner.fetchColumnFamily(Constants.METADATA_BULKFILE_COLUMN_FAMILY);
+    
+    for (Entry<Key,Value> entry : mscanner) {
+      if (Long.parseLong(entry.getValue().toString()) == tid) {
+        String loadedFile = entry.getKey().getColumnQualifierData().toString();
+        String absPath = failures.remove(loadedFile);
+        if (absPath != null) {
+          loadedFailures.put(loadedFile, absPath);
+        }
+      }
+    }
+    
+    // move failed files that were not loaded
+    for (String failure : failures.values()) {
+      Path orig = new Path(failure);
+      Path dest = new Path(error, orig.getName());
+      fs.rename(orig, dest);
+      log.debug("tid " + tid + " renamed " + orig + " to " + dest + ": failed");
+    }
+    
+    if (loadedFailures.size() > 0) {
+      DistributedWorkQueue bifCopyQueue = new DistributedWorkQueue(Constants.ZROOT + "/" + HdfsZooInstance.getInstance().getInstanceID()
+          + Constants.ZBULK_FAILED_COPYQ);
+      
+      HashSet<String> workIds = new HashSet<String>();
+      
+      for (String failure : loadedFailures.values()) {
+        Path orig = new Path(failure);
+        Path dest = new Path(error, orig.getName());
+        
+        if (fs.exists(dest))
+          continue;
+        
+        bifCopyQueue.addWork(orig.getName(), (failure + "," + dest).getBytes());
+        workIds.add(orig.getName());
+        log.debug("tid " + tid + " added to copyq: " + orig + " to " + dest + ": failed");
+      }
+      
+      bifCopyQueue.waitUntilDone(workIds);
+    }
+
+    fs.delete(new Path(error, "failures.txt"), true);
     return new CleanUpBulkImport(tableId, source, bulk, error);
   }
+  
 }
 
 class LoadFiles extends MasterRepo {
@@ -375,8 +486,7 @@ class LoadFiles extends MasterRepo {
   public Repo<Master> call(final long tid, final Master master) throws Exception {
     initializeThreadPool(master);
     final SiteConfiguration conf = ServerConfiguration.getSiteConfiguration();
-    FileSystem fs = TraceFileSystem.wrap(org.apache.accumulo.core.file.FileUtil.getFileSystem(CachedConfiguration.getInstance(),
-        ServerConfiguration.getSiteConfiguration()));
+    FileSystem fs = master.getFileSystem();
     List<FileStatus> files = new ArrayList<FileStatus>();
     for (FileStatus entry : fs.listStatus(new Path(bulk))) {
       files.add(entry);
@@ -414,18 +524,18 @@ class LoadFiles extends MasterRepo {
           @Override
           public List<String> call() {
             List<String> failures = new ArrayList<String>();
-            ClientService.Iface client = null;
+            ClientService.Client client = null;
             String server = null;
             try {
               // get a connection to a random tablet server, do not prefer cached connections because
               // this is running on the master and there are lots of connections to tablet servers
               // serving the !METADATA tablets
-              Pair<String,Iface> pair = ServerClient.getConnection(master.getInstance(), false);
+              Pair<String,Client> pair = ServerClient.getConnection(master.getInstance(), false);
               client = pair.getSecond();
               server = pair.getFirst();
               List<String> attempt = Collections.singletonList(file);
               log.debug("Asking " + pair.getFirst() + " to bulk import " + file);
-              List<String> fail = client.bulkImportFiles(null, SecurityConstants.getSystemCredentials(), tid, tableId, attempt, errorDir, setTime);
+              List<String> fail = client.bulkImportFiles(Tracer.traceInfo(), SecurityConstants.getSystemCredentials(), tid, tableId, attempt, errorDir, setTime);
               if (fail.isEmpty()) {
                 filesToLoad.remove(file);
               } else {
@@ -448,23 +558,18 @@ class LoadFiles extends MasterRepo {
         UtilWaitThread.sleep(100);
       }
     }
-    // Copy/Create failed file markers
-    for (String f : filesToLoad) {
-      Path orig = new Path(f);
-      Path dest = new Path(errorDir, orig.getName());
-      try {
-        FileUtil.copy(fs, orig, fs, dest, false, true, CachedConfiguration.getInstance());
-        log.debug("tid " + tid + " copied " + orig + " to " + dest + ": failed");
-      } catch (IOException ex) {
-        try {
-          fs.create(dest).close();
-          log.debug("tid " + tid + " marked " + dest + " failed");
-        } catch (IOException e) {
-          log.error("Unable to create failure flag file " + dest, e);
-        }
+    
+    FSDataOutputStream failFile = fs.create(new Path(errorDir, "failures.txt"), true);
+    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(failFile));
+    try {
+      for (String f : filesToLoad) {
+        out.write(f);
+        out.write("\n");
       }
+    } finally {
+      out.close();
     }
-    
+
     // return the next step, which will perform cleanup
     return new CompleteBulkImport(tableId, source, bulk, errorDir);
   }

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tserverOps/ShutdownTServer.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tserverOps/ShutdownTServer.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tserverOps/ShutdownTServer.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/master/tserverOps/ShutdownTServer.java Fri Jul 13 20:34:44 2012
@@ -66,7 +66,7 @@ public class ShutdownTServer extends Mas
     // TODO move this to isReady() and drop while loop?
     Listener listener = m.getEventCoordinator().getListener();
     m.shutdownTServer(server);
-    while (m.stillMaster() && m.onlineTabletServers().contains(server)) {
+    while (m.onlineTabletServers().contains(server)) {
       TServerConnection connection = m.getConnection(server);
       if (connection != null) {
         try {

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java Fri Jul 13 20:34:44 2012
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import org.apache.accumulo.cloudtrace.instrument.Tracer;
 import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.Instance;
 import org.apache.accumulo.core.client.impl.MasterClient;
@@ -292,7 +293,7 @@ public class Monitor {
         try {
           client = MasterClient.getConnection(HdfsZooInstance.getInstance());
           if (client != null) {
-            mmi = client.getMasterStats(null, SecurityConstants.getSystemCredentials());
+            mmi = client.getMasterStats(Tracer.traceInfo(), SecurityConstants.getSystemCredentials());
           } else {
             mmi = null;
           }
@@ -429,9 +430,9 @@ public class Monitor {
         if (locks != null && locks.size() > 0) {
           Collections.sort(locks);
           InetSocketAddress address = new ServerServices(new String(zk.getData(path + "/" + locks.get(0), null, null))).getAddress(Service.GC_CLIENT);
-          GCMonitorService.Iface client = ThriftUtil.getClient(new GCMonitorService.Client.Factory(), address, config.getConfiguration());
+          GCMonitorService.Client client = ThriftUtil.getClient(new GCMonitorService.Client.Factory(), address, config.getConfiguration());
           try {
-            result = client.getStatus(null, SecurityConstants.getSystemCredentials());
+            result = client.getStatus(Tracer.traceInfo(), SecurityConstants.getSystemCredentials());
           } finally {
             ThriftUtil.returnClient(client);
           }

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java Fri Jul 13 20:34:44 2012
@@ -44,9 +44,9 @@ abstract public class BasicServlet exten
   private static final long serialVersionUID = 1L;
   protected static final Logger log = Logger.getLogger(BasicServlet.class);
   static String cachedInstanceName = null;
-  private String bannerText;
-  private String bannerColor;
-  private String bannerBackground;
+  private static String bannerText;
+  private static String bannerColor;
+  private static String bannerBackground;
   
   abstract protected String getTitle(HttpServletRequest req);
   

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/DefaultServlet.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/DefaultServlet.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/DefaultServlet.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/DefaultServlet.java Fri Jul 13 20:34:44 2012
@@ -83,13 +83,17 @@ public class DefaultServlet extends Basi
       path = path.substring(1);
       InputStream data = BasicServlet.class.getClassLoader().getResourceAsStream(path);
       ServletOutputStream out = resp.getOutputStream();
-      if (data != null) {
-        byte[] buffer = new byte[1024];
-        int n;
-        while ((n = data.read(buffer)) > 0)
-          out.write(buffer, 0, n);
-      } else {
-        out.write(("could not get resource " + path + "").getBytes());
+      try {
+    	  if (data != null) {
+    		  byte[] buffer = new byte[1024];
+    		  int n;
+    		  while ((n = data.read(buffer)) > 0)
+    			  out.write(buffer, 0, n);
+    	  } else {
+    		  out.write(("could not get resource " + path + "").getBytes());
+    	  }
+      } finally {
+    	  data.close();
       }
     } catch (Throwable t) {
       log.error(t, t);
@@ -113,9 +117,10 @@ public class DefaultServlet extends Basi
       
       @Override
       public IOException run() {
+    	InputStream data = null;
         try {
           File file = new File(aHome + path);
-          InputStream data = new FileInputStream(file.getAbsolutePath());
+          data = new FileInputStream(file.getAbsolutePath());
           byte[] buffer = new byte[1024];
           int n;
           ServletOutputStream out = resp.getOutputStream();
@@ -124,6 +129,14 @@ public class DefaultServlet extends Basi
           return null;
         } catch (IOException e) {
           return e;
+        } finally {
+          if (data != null) {
+            try {
+              data.close();
+            } catch (IOException ex) {
+              log.error(ex, ex);
+            }
+          } 
         }
       }
     }, acc);

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/TServersServlet.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/TServersServlet.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/TServersServlet.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/TServersServlet.java Fri Jul 13 20:34:44 2012
@@ -27,6 +27,7 @@ import java.util.Map.Entry;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.accumulo.cloudtrace.instrument.Tracer;
 import org.apache.accumulo.core.data.KeyExtent;
 import org.apache.accumulo.core.master.thrift.DeadServer;
 import org.apache.accumulo.core.master.thrift.MasterMonitorInfo;
@@ -122,12 +123,12 @@ public class TServersServlet extends Bas
     TabletStats historical = new TabletStats(null, new ActionStats(), new ActionStats(), new ActionStats(), 0, 0, 0, 0);
     List<TabletStats> tsStats = new ArrayList<TabletStats>();
     try {
-      TabletClientService.Iface client = ThriftUtil.getClient(new TabletClientService.Client.Factory(), address, Monitor.getSystemConfiguration());
+      TabletClientService.Client client = ThriftUtil.getClient(new TabletClientService.Client.Factory(), address, Monitor.getSystemConfiguration());
       try {
         for (String tableId : Monitor.getMmi().tableMap.keySet()) {
-          tsStats.addAll(client.getTabletStats(null, SecurityConstants.getSystemCredentials(), tableId));
+          tsStats.addAll(client.getTabletStats(Tracer.traceInfo(), SecurityConstants.getSystemCredentials(), tableId));
         }
-        historical = client.getHistoricalStats(null, SecurityConstants.getSystemCredentials());
+        historical = client.getHistoricalStats(Tracer.traceInfo(), SecurityConstants.getSystemCredentials());
       } finally {
         ThriftUtil.returnClient(client);
       }

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/VisServlet.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/VisServlet.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/VisServlet.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/monitor/servlets/VisServlet.java Fri Jul 13 20:34:44 2012
@@ -32,11 +32,6 @@ public class VisServlet extends BasicSer
   private static final int concurrentScans = Monitor.getSystemConfiguration().getCount(Property.TSERV_READ_AHEAD_MAXCONCURRENT);
   
   private static final long serialVersionUID = 1L;
-  boolean useCircles;
-  StatType motion;
-  StatType color;
-  int spacing;
-  String url;
   
   public enum StatType {
     osload(ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors(), true, 100, "OS Load"),
@@ -106,6 +101,14 @@ public class VisServlet extends BasicSer
       return count;
     }
   }
+
+  public static class VisualizationConfig {
+	  boolean useCircles = true;
+	  StatType motion  = StatType.allmax;
+	  StatType color = StatType.allavg;
+	  int spacing = 40;
+	  String url;
+  }
   
   @Override
   protected String getTitle(HttpServletRequest req) {
@@ -116,39 +119,36 @@ public class VisServlet extends BasicSer
   protected void pageBody(HttpServletRequest req, HttpServletResponse response, StringBuilder sb) throws IOException {
     StringBuffer urlsb = req.getRequestURL();
     urlsb.setLength(urlsb.lastIndexOf("/") + 1);
-    url = urlsb.toString();
+    String url = urlsb.toString();
+    VisualizationConfig cfg = new VisualizationConfig();
     
-    useCircles = true;
     String s = req.getParameter("shape");
     if (s != null && (s.equals("square") || s.equals("squares"))) {
-      useCircles = false;
+      cfg.useCircles = false;
     }
     
     s = req.getParameter("motion");
-    motion = StatType.allmax;
     if (s != null) {
       try {
-        motion = StatType.valueOf(s);
+        cfg.motion = StatType.valueOf(s);
       } catch (Exception e) {}
     }
     
     s = req.getParameter("color");
-    color = StatType.allavg;
     if (s != null) {
       try {
-        color = StatType.valueOf(s);
+        cfg.color = StatType.valueOf(s);
       } catch (Exception e) {}
     }
     
-    spacing = 40;
     String size = req.getParameter("size");
     if (size != null) {
       if (size.equals("10"))
-        spacing = 10;
+        cfg.spacing = 10;
       else if (size.equals("20"))
-        spacing = 20;
+        cfg.spacing = 20;
       else if (size.equals("80"))
-        spacing = 80;
+        cfg.spacing = 80;
     }
     
     ArrayList<TabletServerStatus> tservers = new ArrayList<TabletServerStatus>();
@@ -158,30 +158,30 @@ public class VisServlet extends BasicSer
     if (tservers.size() == 0)
       return;
     
-    int width = (int) Math.ceil(Math.sqrt(tservers.size())) * spacing;
-    int height = (int) Math.ceil(tservers.size() / width) * spacing;
-    doSettings(sb, width < 640 ? 640 : width, height < 640 ? 640 : height);
-    doScript(sb, tservers);
+    int width = (int) Math.ceil(Math.sqrt(tservers.size())) * cfg.spacing;
+    int height = (int) Math.ceil(tservers.size() / width) * cfg.spacing;
+    doSettings(sb, cfg, width < 640 ? 640 : width, height < 640 ? 640 : height);
+    doScript(sb, cfg, tservers);
   }
   
-  private void doSettings(StringBuilder sb, int width, int height) {
+  private void doSettings(StringBuilder sb, VisualizationConfig cfg, int width, int height) {
     sb.append("<div class='left'>\n");
     sb.append("<div id='parameters' class='nowrap'>\n");
     // shape select box
     sb.append("<span class='viscontrol'>Shape: <select id='shape' onchange='setShape(this)'><option>Circles</option><option")
-        .append(!useCircles ? " selected='true'" : "").append(">Squares</option></select></span>\n");
+        .append(!cfg.useCircles ? " selected='true'" : "").append(">Squares</option></select></span>\n");
     // size select box
-    sb.append("&nbsp;&nbsp<span class='viscontrol'>Size: <select id='size' onchange='setSize(this)'><option").append(spacing == 10 ? " selected='true'" : "")
-        .append(">10</option><option").append(spacing == 20 ? " selected='true'" : "").append(">20</option><option")
-        .append(spacing == 40 ? " selected='true'" : "").append(">40</option><option").append(spacing == 80 ? " selected='true'" : "")
+    sb.append("&nbsp;&nbsp<span class='viscontrol'>Size: <select id='size' onchange='setSize(this)'><option").append(cfg.spacing == 10 ? " selected='true'" : "")
+        .append(">10</option><option").append(cfg.spacing == 20 ? " selected='true'" : "").append(">20</option><option")
+        .append(cfg.spacing == 40 ? " selected='true'" : "").append(">40</option><option").append(cfg.spacing == 80 ? " selected='true'" : "")
         .append(">80</option></select></span>\n");
     // motion select box
     sb.append("&nbsp;&nbsp<span class='viscontrol'>Motion: <select id='motion' onchange='setMotion(this)'>");
-    addOptions(sb, motion);
+    addOptions(sb, cfg.motion);
     sb.append("</select></span>\n");
     // color select box
     sb.append("&nbsp;&nbsp<span class='viscontrol'>Color: <select id='color' onchange='setColor(this)'>");
-    addOptions(sb, color);
+    addOptions(sb, cfg.color);
     sb.append("</select></span>\n");
     sb.append("&nbsp;&nbsp<span class='viscontrol'>(hover for info, click for details)</span>");
     sb.append("</div>\n\n");
@@ -200,13 +200,13 @@ public class VisServlet extends BasicSer
     }
   }
   
-  private void doScript(StringBuilder sb, ArrayList<TabletServerStatus> tservers) {
+  private void doScript(StringBuilder sb, VisualizationConfig cfg, ArrayList<TabletServerStatus> tservers) {
     // initialization of some javascript variables
     sb.append("<script type='text/javascript'>\n");
     sb.append("var numCores = " + ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors() + ";\n");
-    sb.append("var jsonurl = '" + url + "json';\n");
-    sb.append("var visurl = '" + url + "vis';\n");
-    sb.append("var serverurl = '" + url + "tservers?s=';\n\n");
+    sb.append("var jsonurl = '" + cfg.url + "json';\n");
+    sb.append("var visurl = '" + cfg.url + "vis';\n");
+    sb.append("var serverurl = '" + cfg.url + "tservers?s=';\n\n");
     sb.append("// observable stats that can be connected to motion or color\n");
     sb.append("var statNames = {");
     for (StatType st : StatType.values())

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java Fri Jul 13 20:34:44 2012
@@ -544,23 +544,4 @@ public class AuditedSecurityOperation im
     impl.initializeSecurity(credentials, rootuser, rootpass);
     log.info("Initialized root user with username: " + rootuser + " at the request of user " + credentials.user);
   }
-  
-  @Override
-  public void clearCache(String user, boolean password, boolean auths, boolean system, Set<String> tables) {
-    // TODO Auto-generated method stub
-    
-  }
-  
-  @Override
-  public void clearCache(String table) {
-    // TODO Auto-generated method stub
-    
-  }
-  
-  @Override
-  public boolean cachesToClear() {
-    // TODO Auto-generated method stub
-    return false;
-  }
-
 }

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java Fri Jul 13 20:34:44 2012
@@ -354,10 +354,4 @@ public interface SecurityOperation {
    * @throws ThriftSecurityException
    */
   public void deleteTable(AuthInfo credentials, String tableId) throws ThriftSecurityException;
-  
-  public void clearCache(String user, boolean password, boolean auths, boolean system, Set<String> tables) throws ThriftSecurityException;
-  
-  public void clearCache(String table) throws ThriftSecurityException;
-  
-  public boolean cachesToClear() throws ThriftSecurityException;
 }

Modified: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperationImpl.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperationImpl.java?rev=1361382&r1=1361381&r2=1361382&view=diff
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperationImpl.java (original)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/SecurityOperationImpl.java Fri Jul 13 20:34:44 2012
@@ -35,6 +35,12 @@ import org.apache.accumulo.core.security
 import org.apache.accumulo.core.security.thrift.ThriftSecurityException;
 import org.apache.accumulo.server.client.HdfsZooInstance;
 import org.apache.accumulo.server.master.Master;
+import org.apache.accumulo.server.security.handler.Authenticator;
+import org.apache.accumulo.server.security.handler.Authorizor;
+import org.apache.accumulo.server.security.handler.PermissionHandler;
+import org.apache.accumulo.server.security.handler.ZKAuthenticator;
+import org.apache.accumulo.server.security.handler.ZKAuthorizor;
+import org.apache.accumulo.server.security.handler.ZKPermHandler;
 import org.apache.accumulo.server.zookeeper.ZooCache;
 import org.apache.log4j.Logger;
 
@@ -46,6 +52,7 @@ public class SecurityOperationImpl imple
 
   private static Authorizor authorizor;
   private static Authenticator authenticator;
+  private static PermissionHandler permHandle;
   private static String rootUserName = null;
   private final ZooCache zooCache;
   private final String ZKUserPath;
@@ -59,7 +66,8 @@ public class SecurityOperationImpl imple
   
   public static synchronized SecurityOperation getInstance(String instanceId) {
     if (instance == null) {
-      instance = new AuditedSecurityOperation(new SecurityOperationImpl(getAuthorizor(instanceId), getAuthenticator(instanceId), instanceId));
+      instance = new AuditedSecurityOperation(new SecurityOperationImpl(getAuthorizor(instanceId), getAuthenticator(instanceId), getPermHandler(instanceId),
+          instanceId));
     }
     return instance;
   }
@@ -80,12 +88,22 @@ public class SecurityOperationImpl imple
     return toRet;
   }
 
-  public SecurityOperationImpl(Authorizor author, Authenticator authent, String instanceId) {
+  @SuppressWarnings("deprecation")
+  private static PermissionHandler getPermHandler(String instanceId) {
+    PermissionHandler toRet = Master.createInstanceFromPropertyName(AccumuloConfiguration.getSiteConfiguration(),
+        Property.INSTANCE_SECURITY_PERMISSION_HANDLER, PermissionHandler.class, ZKPermHandler.getInstance());
+    toRet.initialize(instanceId);
+    return toRet;
+  }
+
+  public SecurityOperationImpl(Authorizor author, Authenticator authent, PermissionHandler pm, String instanceId) {
     authorizor = author;
     authenticator = authent;
+    permHandle = pm;
     
-    if (!authorizor.validAuthenticator(authenticator) || !authenticator.validAuthorizor(authorizor))
-      throw new RuntimeException(authorizor + " and " + authenticator
+    if (!authorizor.validSecurityHandlers(authenticator, pm) || !authenticator.validSecurityHandlers(authorizor, pm)
+        || !permHandle.validSecurityHandlers(authent, author))
+      throw new RuntimeException(authorizor + ", " + authenticator + ", and " + pm
           + " do not play nice with eachother. Please choose authentication and authorization mechanisms that are compatible with one another.");
     
     ZKUserPath = Constants.ZROOT + "/" + instanceId + "/users";
@@ -100,8 +118,9 @@ public class SecurityOperationImpl imple
 
     authenticator.initializeSecurity(credentials, rootuser, rootpass);
     authorizor.initializeSecurity(rootuser);
+    permHandle.initializeSecurity(rootuser);
     try {
-      authorizor.grantTablePermission(rootuser, Constants.METADATA_TABLE_ID, TablePermission.ALTER_TABLE);
+      permHandle.grantTablePermission(rootuser, Constants.METADATA_TABLE_ID, TablePermission.ALTER_TABLE);
     } catch (TableNotFoundException e) {
       // Shouldn't happen
       throw new RuntimeException(e);
@@ -165,7 +184,7 @@ public class SecurityOperationImpl imple
     
     targetUserExists(user);
 
-    if (!credentials.user.equals(user) && !hasSystemPermission(credentials.user, SystemPermission.SYSTEM))
+    if (!credentials.user.equals(user) && !hasSystemPermission(credentials.user, SystemPermission.SYSTEM, false))
       throw new ThriftSecurityException(credentials.user, SecurityErrorCode.PERMISSION_DENIED);
     
     // system user doesn't need record-level authorizations for the tables it reads (for now)
@@ -173,7 +192,7 @@ public class SecurityOperationImpl imple
       return Constants.NO_AUTHS;
     
     try {
-      return authorizor.getUserAuthorizations(user);
+      return authorizor.getCachedUserAuthorizations(user);
     } catch (AccumuloSecurityException e) {
       throw e.asThriftException();
     }
@@ -193,14 +212,16 @@ public class SecurityOperationImpl imple
    * 
    * @return true if a user exists and has permission; false otherwise
    */
-  private boolean hasSystemPermission(String user, SystemPermission permission) throws ThriftSecurityException {
+  private boolean hasSystemPermission(String user, SystemPermission permission, boolean useCached) throws ThriftSecurityException {
     if (user.equals(getRootUsername()) || user.equals(SecurityConstants.SYSTEM_USERNAME))
       return true;
     
     targetUserExists(user);
 
     try {
-      return authorizor.hasSystemPermission(user, permission);
+      if (useCached)
+        return permHandle.hasCachedSystemPermission(user, permission);
+      return permHandle.hasSystemPermission(user, permission);
     } catch (AccumuloSecurityException e) {
       throw e.asThriftException();
     }
@@ -212,7 +233,7 @@ public class SecurityOperationImpl imple
    * @return true if a user exists and has permission; false otherwise
    * @throws ThriftTableOperationException
    */
-  private boolean hasTablePermission(String user, String table, TablePermission permission) throws ThriftSecurityException {
+  private boolean hasTablePermission(String user, String table, TablePermission permission, boolean useCached) throws ThriftSecurityException {
     if (user.equals(SecurityConstants.SYSTEM_USERNAME))
       return true;
     
@@ -222,7 +243,9 @@ public class SecurityOperationImpl imple
       return true;
 
     try {
-      return authorizor.hasTablePermission(user, table, permission);
+      if (useCached)
+        return permHandle.hasCachedTablePermission(user, table, permission);
+      return permHandle.hasTablePermission(user, table, permission);
     } catch (AccumuloSecurityException e) {
       throw e.asThriftException();
     } catch (TableNotFoundException e) {
@@ -233,7 +256,7 @@ public class SecurityOperationImpl imple
   // some people just aren't allowed to ask about other users; here are those who can ask
   private boolean canAskAboutOtherUsers(AuthInfo credentials, String user) throws ThriftSecurityException {
     authenticate(credentials);
-    return credentials.user.equals(user) || hasSystemPermission(credentials.user, SystemPermission.SYSTEM)
+    return credentials.user.equals(user) || hasSystemPermission(credentials.user, SystemPermission.SYSTEM, false)
         || hasSystemPermission(credentials, credentials.user, SystemPermission.CREATE_USER)
         || hasSystemPermission(credentials, credentials.user, SystemPermission.ALTER_USER)
         || hasSystemPermission(credentials, credentials.user, SystemPermission.DROP_USER);
@@ -260,7 +283,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canScan(AuthInfo credentials, String table) throws ThriftSecurityException {
     authenticate(credentials);
-    return hasTablePermission(credentials.user, table, TablePermission.READ);
+    return hasTablePermission(credentials.user, table, TablePermission.READ, true);
   }
 
   /**
@@ -272,7 +295,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canWrite(AuthInfo credentials, String table) throws ThriftSecurityException {
     authenticate(credentials);
-    return hasTablePermission(credentials.user, table, TablePermission.WRITE);
+    return hasTablePermission(credentials.user, table, TablePermission.WRITE, true);
   }
 
   /**
@@ -284,8 +307,8 @@ public class SecurityOperationImpl imple
    */
   public boolean canSplitTablet(AuthInfo credentials, String table) throws ThriftSecurityException {
     authenticate(credentials);
-    return hasSystemPermission(credentials.user, SystemPermission.ALTER_TABLE) || hasSystemPermission(credentials.user, SystemPermission.SYSTEM)
-        || hasTablePermission(credentials.user, table, TablePermission.ALTER_TABLE);
+    return hasSystemPermission(credentials.user, SystemPermission.ALTER_TABLE, false) || hasSystemPermission(credentials.user, SystemPermission.SYSTEM, false)
+        || hasTablePermission(credentials.user, table, TablePermission.ALTER_TABLE, false);
   }
   
   /**
@@ -298,7 +321,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canPerformSystemActions(AuthInfo credentials) throws ThriftSecurityException {
     authenticate(credentials);
-    return hasSystemPermission(credentials.user, SystemPermission.SYSTEM);
+    return hasSystemPermission(credentials.user, SystemPermission.SYSTEM, false);
   }
 
   /**
@@ -309,7 +332,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canFlush(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasTablePermission(c.user, tableId, TablePermission.WRITE) || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE);
+    return hasTablePermission(c.user, tableId, TablePermission.WRITE, false) || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE, false);
   }
   
   /**
@@ -320,7 +343,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canAlterTable(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE);
+    return hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE, false) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false);
   }
   
   /**
@@ -329,7 +352,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canCreateTable(AuthInfo c) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.CREATE_TABLE);
+    return hasSystemPermission(c.user, SystemPermission.CREATE_TABLE, false);
   }
   
   /**
@@ -341,7 +364,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canRenameTable(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE) || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE);
+    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE, false);
   }
   
   /**
@@ -352,7 +375,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canCloneTable(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.CREATE_TABLE) && hasTablePermission(c.user, tableId, TablePermission.READ);
+    return hasSystemPermission(c.user, SystemPermission.CREATE_TABLE, false) && hasTablePermission(c.user, tableId, TablePermission.READ, false);
   }
   
   /**
@@ -364,7 +387,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canDeleteTable(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.DROP_TABLE) || hasTablePermission(c.user, tableId, TablePermission.DROP_TABLE);
+    return hasSystemPermission(c.user, SystemPermission.DROP_TABLE, false) || hasTablePermission(c.user, tableId, TablePermission.DROP_TABLE, false);
   }
   
   /**
@@ -376,8 +399,8 @@ public class SecurityOperationImpl imple
    */
   public boolean canOnlineOfflineTable(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.SYSTEM) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE)
-        || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE);
+    return hasSystemPermission(c.user, SystemPermission.SYSTEM, false) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false)
+        || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE, false);
   }
   
   /**
@@ -389,8 +412,8 @@ public class SecurityOperationImpl imple
    */
   public boolean canMerge(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.SYSTEM) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE)
-        || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE);
+    return hasSystemPermission(c.user, SystemPermission.SYSTEM, false) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false)
+        || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE, false);
   }
   
   /**
@@ -402,7 +425,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canDeleteRange(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.SYSTEM) || hasTablePermission(c.user, tableId, TablePermission.WRITE);
+    return hasSystemPermission(c.user, SystemPermission.SYSTEM, false) || hasTablePermission(c.user, tableId, TablePermission.WRITE, false);
   }
   
   /**
@@ -414,7 +437,7 @@ public class SecurityOperationImpl imple
    */
   public boolean canBulkImport(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasTablePermission(c.user, tableId, TablePermission.BULK_IMPORT);
+    return hasTablePermission(c.user, tableId, TablePermission.BULK_IMPORT, false);
   }
   
   /**
@@ -426,8 +449,8 @@ public class SecurityOperationImpl imple
    */
   public boolean canCompact(AuthInfo c, String tableId) throws ThriftSecurityException {
     authenticate(c);
-    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE) || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE)
-        || hasTablePermission(c.user, tableId, TablePermission.WRITE);
+    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c.user, tableId, TablePermission.ALTER_TABLE, false)
+        || hasTablePermission(c.user, tableId, TablePermission.WRITE, false);
   }
   
   /**
@@ -439,7 +462,7 @@ public class SecurityOperationImpl imple
     authenticate(c);
     if (user.equals(SecurityConstants.SYSTEM_USERNAME))
       throw new ThriftSecurityException(c.user, SecurityErrorCode.PERMISSION_DENIED);
-    return hasSystemPermission(c.user, SystemPermission.ALTER_USER);
+    return hasSystemPermission(c.user, SystemPermission.ALTER_USER, false);
   }
 
   /**
@@ -452,7 +475,7 @@ public class SecurityOperationImpl imple
     authenticate(c);
     if (user.equals(SecurityConstants.SYSTEM_USERNAME))
       throw new ThriftSecurityException(c.user, SecurityErrorCode.PERMISSION_DENIED);
-    return c.user.equals(user) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE);
+    return c.user.equals(user) || hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false);
   }
   
   /**
@@ -468,7 +491,7 @@ public class SecurityOperationImpl imple
     if (user.equals(SecurityConstants.SYSTEM_USERNAME))
       throw new ThriftSecurityException(user, SecurityErrorCode.PERMISSION_DENIED);
 
-    return hasSystemPermission(c.user, SystemPermission.CREATE_USER);
+    return hasSystemPermission(c.user, SystemPermission.CREATE_USER, false);
   }
 
   /**
@@ -484,7 +507,7 @@ public class SecurityOperationImpl imple
     if (user.equals(getRootUsername()) || user.equals(SecurityConstants.SYSTEM_USERNAME))
       throw new ThriftSecurityException(user, SecurityErrorCode.PERMISSION_DENIED);
 
-    return hasSystemPermission(c.user, SystemPermission.DROP_USER);
+    return hasSystemPermission(c.user, SystemPermission.DROP_USER, false);
   }
   
   /**
@@ -505,7 +528,7 @@ public class SecurityOperationImpl imple
     if (sysPerm.equals(SystemPermission.GRANT))
       throw new ThriftSecurityException(c.user, SecurityErrorCode.GRANT_INVALID);
 
-    return hasSystemPermission(c.user, SystemPermission.GRANT);
+    return hasSystemPermission(c.user, SystemPermission.GRANT, false);
   }
   
   /**
@@ -522,7 +545,7 @@ public class SecurityOperationImpl imple
     if (user.equals(SecurityConstants.SYSTEM_USERNAME))
       throw new ThriftSecurityException(c.user, SecurityErrorCode.PERMISSION_DENIED);
     
-    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE) || hasTablePermission(c.user, table, TablePermission.GRANT);
+    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c.user, table, TablePermission.GRANT, false);
   }
   
   /**
@@ -543,7 +566,7 @@ public class SecurityOperationImpl imple
     if (sysPerm.equals(SystemPermission.GRANT))
       throw new ThriftSecurityException(c.user, SecurityErrorCode.GRANT_INVALID);
     
-    return hasSystemPermission(c.user, SystemPermission.GRANT);
+    return hasSystemPermission(c.user, SystemPermission.GRANT, false);
   }
   
   /**
@@ -560,7 +583,7 @@ public class SecurityOperationImpl imple
     if (user.equals(SecurityConstants.SYSTEM_USERNAME))
       throw new ThriftSecurityException(c.user, SecurityErrorCode.PERMISSION_DENIED);
     
-    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE) || hasTablePermission(c.user, table, TablePermission.GRANT);
+    return hasSystemPermission(c.user, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c.user, table, TablePermission.GRANT, false);
   }
   
   /**
@@ -613,6 +636,7 @@ public class SecurityOperationImpl imple
     try {
       authenticator.createUser(user, pass);
       authorizor.initUser(user);
+      permHandle.initUser(user);
       log.info("Created user " + user + " at the request of user " + credentials.user);
       if (canChangeAuthorizations(credentials, user))
         authorizor.changeAuthorizations(user, authorizations);
@@ -632,6 +656,7 @@ public class SecurityOperationImpl imple
     try {
       authorizor.dropUser(user);
       authenticator.dropUser(user);
+      permHandle.dropUser(user);
       log.info("Deleted user " + user + " at the request of user " + credentials.user);
     } catch (AccumuloSecurityException e) {
       throw e.asThriftException();
@@ -651,7 +676,7 @@ public class SecurityOperationImpl imple
     targetUserExists(user);
 
     try {
-      authorizor.grantSystemPermission(user, permissionById);
+      permHandle.grantSystemPermission(user, permissionById);
       log.info("Granted system permission " + permissionById + " for user " + user + " at the request of user " + credentials.user);
     } catch (AccumuloSecurityException e) {
       throw e.asThriftException();
@@ -672,7 +697,7 @@ public class SecurityOperationImpl imple
     targetUserExists(user);
 
     try {
-      authorizor.grantTablePermission(user, tableId, permission);
+      permHandle.grantTablePermission(user, tableId, permission);
       log.info("Granted table permission " + permission + " for user " + user + " on the table " + tableId + " at the request of user " + c.user);
     } catch (AccumuloSecurityException e) {
       throw e.asThriftException();
@@ -694,7 +719,7 @@ public class SecurityOperationImpl imple
     targetUserExists(user);
 
     try {
-      authorizor.revokeSystemPermission(user, permission);
+      permHandle.revokeSystemPermission(user, permission);
       log.info("Revoked system permission " + permission + " for user " + user + " at the request of user " + credentials.user);
 
     } catch (AccumuloSecurityException e) {
@@ -716,7 +741,7 @@ public class SecurityOperationImpl imple
     targetUserExists(user);
 
     try {
-      authorizor.revokeTablePermission(user, tableId, permission);
+      permHandle.revokeTablePermission(user, tableId, permission);
       log.info("Revoked table permission " + permission + " for user " + user + " on the table " + tableId + " at the request of user " + c.user);
 
     } catch (AccumuloSecurityException e) {
@@ -736,7 +761,7 @@ public class SecurityOperationImpl imple
   public boolean hasSystemPermission(AuthInfo credentials, String user, SystemPermission permissionById) throws ThriftSecurityException {
     if (!canAskAboutOtherUsers(credentials, user))
       throw new ThriftSecurityException(credentials.user, SecurityErrorCode.PERMISSION_DENIED);
-    return hasSystemPermission(user, permissionById);
+    return hasSystemPermission(user, permissionById, false);
   }
   
   /**
@@ -750,7 +775,7 @@ public class SecurityOperationImpl imple
   public boolean hasTablePermission(AuthInfo credentials, String user, String tableId, TablePermission permissionById) throws ThriftSecurityException {
     if (!canAskAboutOtherUsers(credentials, user))
       throw new ThriftSecurityException(credentials.user, SecurityErrorCode.PERMISSION_DENIED);
-    return hasTablePermission(user, tableId, permissionById);
+    return hasTablePermission(user, tableId, permissionById, false);
   }
   
   /**
@@ -776,7 +801,7 @@ public class SecurityOperationImpl imple
     if (!canDeleteTable(credentials, tableId))
       throw new ThriftSecurityException(credentials.user, SecurityErrorCode.PERMISSION_DENIED);
     try {
-      authorizor.cleanTablePermissions(tableId);
+      permHandle.cleanTablePermissions(tableId);
     } catch (AccumuloSecurityException e) {
       e.setUser(credentials.user);
       throw e.asThriftException();
@@ -784,40 +809,4 @@ public class SecurityOperationImpl imple
       throw new ThriftSecurityException(credentials.user, SecurityErrorCode.TABLE_DOESNT_EXIST);
     }
   }
-  
-  @Override
-  public void clearCache(String user, boolean password, boolean auths, boolean system, Set<String> tables) throws ThriftSecurityException {
-    if (password)
-      authenticator.clearCache(user);
-
-    if (auths || system || tables.size() > 0)
-      try {
-        authorizor.clearCache(user, auths, system, tables);
-      } catch (TableNotFoundException e) {
-        throw new ThriftSecurityException(user, SecurityErrorCode.TABLE_DOESNT_EXIST);
-      } catch (AccumuloSecurityException e) {
-        throw e.asThriftException();
-      }
-    
-  }
-  
-  @Override
-  public void clearCache(String table) throws ThriftSecurityException {
-    try {
-      authorizor.clearTableCache(table);
-    } catch (AccumuloSecurityException e) {
-      throw e.asThriftException();
-    } catch (TableNotFoundException e) {
-      throw new ThriftSecurityException(table, SecurityErrorCode.TABLE_DOESNT_EXIST);
-    }
-  }
-  
-  @Override
-  public boolean cachesToClear() throws ThriftSecurityException {
-    try {
-      return authenticator.cachesToClear() || authorizor.cachesToClear();
-    } catch (AccumuloSecurityException e) {
-      throw e.asThriftException();
-    }
-  }
 }

Added: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authenticator.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authenticator.java?rev=1361382&view=auto
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authenticator.java (added)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authenticator.java Fri Jul 13 20:34:44 2012
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.accumulo.server.security.handler;
+
+import java.nio.ByteBuffer;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.thrift.AuthInfo;
+
+/**
+ * This interface is used for the system which will be used for authenticating a user. If the implementation does not support configuration through Accumulo, it
+ * should throw an AccumuloSecurityException with the error code UNSUPPORTED_OPERATION
+ */
+
+public interface Authenticator {
+  
+  public void initialize(String instanceId);
+
+  public boolean validSecurityHandlers(Authorizor auth, PermissionHandler pm);
+
+  public void initializeSecurity(AuthInfo credentials, String rootuser, byte[] rootpass) throws AccumuloSecurityException;
+
+  public boolean authenticateUser(String user, ByteBuffer password, String instanceId);
+  
+  public Set<String> listUsers() throws AccumuloSecurityException;
+  
+  public void createUser(String user, byte[] pass) throws AccumuloSecurityException;
+  
+  public void dropUser(String user) throws AccumuloSecurityException;
+  
+  public void changePassword(String user, byte[] pass) throws AccumuloSecurityException;
+  
+  public void clearCache(String user);
+  
+  public boolean cachesToClear();
+  
+  public boolean userExists(String user);
+}

Added: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java?rev=1361382&view=auto
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java (added)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/Authorizor.java Fri Jul 13 20:34:44 2012
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.accumulo.server.security.handler;
+
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+
+/**
+ * This interface is used for the system which will be used for getting a users Authorizations. If the implementation does not support configuration through
+ * Accumulo, it should throw an AccumuloSecurityException with the error code UNSUPPORTED_OPERATION
+ */
+public interface Authorizor {
+  /**
+   * Sets up the authorizor for a new instance of Accumulo
+   * 
+   * @param instanceId
+   */
+  public void initialize(String instanceId);
+
+  /**
+   * Used to validate that the Authorizor, Authenticator, and permission handler can coexist
+   * 
+   * @param auth
+   * @return
+   */
+  public boolean validSecurityHandlers(Authenticator auth, PermissionHandler pm);
+  
+  /**
+   * Used to initialize security for the root user
+   * 
+   * @param rootuser
+   * @throws AccumuloSecurityException
+   */
+  public void initializeSecurity(String rootuser) throws AccumuloSecurityException;
+  
+  /**
+   * Used to change the authorizations for the user
+   * 
+   * @param user
+   * @param authorizations
+   * @throws AccumuloSecurityException
+   */
+  public void changeAuthorizations(String user, Authorizations authorizations) throws AccumuloSecurityException;
+  
+  /**
+   * Used to get the authorizations for the user
+   * 
+   * @param user
+   * @return
+   * @throws AccumuloSecurityException
+   */
+  public Authorizations getCachedUserAuthorizations(String user) throws AccumuloSecurityException;
+  
+  /**
+   * Initializes a new user
+   * 
+   * @param user
+   * @throws AccumuloSecurityException
+   */
+  public void initUser(String user) throws AccumuloSecurityException;
+  
+  /**
+   * Deletes a user
+   * 
+   * @param user
+   * @throws AccumuloSecurityException
+   */
+  public void dropUser(String user) throws AccumuloSecurityException;
+}

Added: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java?rev=1361382&view=auto
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java (added)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java Fri Jul 13 20:34:44 2012
@@ -0,0 +1,161 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.accumulo.server.security.handler;
+
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+
+/**
+ * This interface is used for the system which will be used for getting a users permissions. If the implementation does not support configuration through
+ * Accumulo, it should throw an AccumuloSecurityException with the error code UNSUPPORTED_OPERATION
+ */
+public interface PermissionHandler {
+  /**
+   * Sets up the permission handler for a new instance of Accumulo
+   * 
+   * @param instanceId
+   */
+  public void initialize(String instanceId);
+  
+  /**
+   * Used to validate that the Authorizor, Authenticator, and permission handler can coexist
+   * 
+   * @param auth
+   * @return
+   */
+  public boolean validSecurityHandlers(Authenticator authent, Authorizor author);
+  
+  /**
+   * Used to initialize security for the root user
+   * 
+   * @param rootuser
+   * @throws AccumuloSecurityException
+   */
+  public void initializeSecurity(String rootuser) throws AccumuloSecurityException;
+  
+  /**
+   * Used to get the system permission for the user
+   * 
+   * @param user
+   * @param permission
+   * @return
+   * @throws AccumuloSecurityException
+   */
+  public boolean hasSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException;
+  
+  /**
+   * Used to get the system permission for the user, with caching due to high frequency operation. NOTE: At this time, this method is unused but is included
+   * just in case we need it in the future.
+   * 
+   * @param user
+   * @param permission
+   * @return
+   * @throws AccumuloSecurityException
+   */
+  public boolean hasCachedSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException;
+  
+  /**
+   * Used to get the table permission of a user for a table
+   * 
+   * @param user
+   * @param table
+   * @param permission
+   * @return
+   * @throws AccumuloSecurityException
+   * @throws TableNotFoundException
+   */
+  public boolean hasTablePermission(String user, String table, TablePermission permission) throws AccumuloSecurityException, TableNotFoundException;
+  
+  /**
+   * Used to get the table permission of a user for a table, with caching. This method is for high frequency operations
+   * 
+   * @param user
+   * @param table
+   * @param permission
+   * @return
+   * @throws AccumuloSecurityException
+   * @throws TableNotFoundException
+   */
+  public boolean hasCachedTablePermission(String user, String table, TablePermission permission) throws AccumuloSecurityException, TableNotFoundException;
+  
+  /**
+   * Gives the user the given system permission
+   * 
+   * @param user
+   * @param permission
+   * @throws AccumuloSecurityException
+   */
+  public void grantSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException;
+  
+  /**
+   * Denies the user the given system permission
+   * 
+   * @param user
+   * @param permission
+   * @throws AccumuloSecurityException
+   */
+  public void revokeSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException;
+  
+  /**
+   * Gives the user the given table permission
+   * 
+   * @param user
+   * @param table
+   * @param permission
+   * @throws AccumuloSecurityException
+   * @throws TableNotFoundException
+   */
+  public void grantTablePermission(String user, String table, TablePermission permission) throws AccumuloSecurityException, TableNotFoundException;
+  
+  /**
+   * Denies the user the given table permission.
+   * 
+   * @param user
+   * @param table
+   * @param permission
+   * @throws AccumuloSecurityException
+   * @throws TableNotFoundException
+   */
+  public void revokeTablePermission(String user, String table, TablePermission permission) throws AccumuloSecurityException, TableNotFoundException;
+  
+  /**
+   * Cleans up the permissions for a table. Used when a table gets deleted.
+   * 
+   * @param table
+   * @throws AccumuloSecurityException
+   * @throws TableNotFoundException
+   */
+  public void cleanTablePermissions(String table) throws AccumuloSecurityException, TableNotFoundException;
+  
+  /**
+   * Initializes a new user
+   * 
+   * @param user
+   * @throws AccumuloSecurityException
+   */
+  public void initUser(String user) throws AccumuloSecurityException;
+  
+  /**
+   * Deletes a user
+   * 
+   * @param user
+   * @throws AccumuloSecurityException
+   */
+  public void dropUser(String user) throws AccumuloSecurityException;
+}

Added: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java?rev=1361382&view=auto
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java (added)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java Fri Jul 13 20:34:44 2012
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.accumulo.server.security.handler;
+
+import java.nio.ByteBuffer;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.thrift.AuthInfo;
+import org.apache.accumulo.core.security.thrift.SecurityErrorCode;
+import org.apache.accumulo.core.util.ByteBufferUtil;
+import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
+import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeExistsPolicy;
+import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeMissingPolicy;
+import org.apache.accumulo.server.zookeeper.ZooCache;
+import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.KeeperException;
+
+// Utility class for adding all authentication info into ZK
+public final class ZKAuthenticator implements Authenticator {
+  static final Logger log = Logger.getLogger(ZKAuthenticator.class);
+  private static Authenticator zkAuthenticatorInstance = null;
+
+  private String ZKUserPath;
+  private final ZooCache zooCache;
+  
+  public static synchronized Authenticator getInstance() {
+    if (zkAuthenticatorInstance == null)
+      zkAuthenticatorInstance = new ZKAuthenticator();
+    return zkAuthenticatorInstance;
+  }
+  
+  public ZKAuthenticator() {
+    zooCache = new ZooCache();
+  }
+  
+  public void initialize(String instanceId) {
+    ZKUserPath = Constants.ZROOT + "/" + instanceId + "/users";
+  }
+
+  @Override
+  public void initializeSecurity(AuthInfo credentials, String rootuser, byte[] rootpass) throws AccumuloSecurityException {
+    try {
+      // remove old settings from zookeeper first, if any
+      IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+      synchronized (zooCache) {
+        zooCache.clear();
+        if (zoo.exists(ZKUserPath)) {
+          zoo.recursiveDelete(ZKUserPath, NodeMissingPolicy.SKIP);
+          log.info("Removed " + ZKUserPath + "/" + " from zookeeper");
+        }
+        
+        // prep parent node of users with root username
+        zoo.putPersistentData(ZKUserPath, rootuser.getBytes(), NodeExistsPolicy.FAIL);
+        
+        constructUser(rootuser, ZKSecurityTool.createPass(rootpass));
+      }
+    } catch (KeeperException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    } catch (InterruptedException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    } catch (AccumuloException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    }
+  }
+  
+  /**
+   * Sets up the user in ZK for the provided user. No checking for existence is done here, it should be done before calling.
+   */
+  private void constructUser(String user, byte[] pass)
+      throws KeeperException, InterruptedException {
+    synchronized (zooCache) {
+      zooCache.clear();
+      IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+      zoo.putPrivatePersistentData(ZKUserPath + "/" + user, pass, NodeExistsPolicy.FAIL);
+    }
+  }
+  
+  @Override
+  public Set<String> listUsers() {
+    return new TreeSet<String>(zooCache.getChildren(ZKUserPath));
+  }
+  
+  /**
+   * Creates a user with no permissions whatsoever
+   */
+  @Override
+  public void createUser(String user, byte[] pass) throws AccumuloSecurityException {
+    try {
+      constructUser(user, ZKSecurityTool.createPass(pass));
+    } catch (KeeperException e) {
+      log.error(e, e);
+      if (e.code().equals(KeeperException.Code.NODEEXISTS))
+        throw new AccumuloSecurityException(user, SecurityErrorCode.USER_EXISTS, e);
+      throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+    } catch (InterruptedException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    } catch (AccumuloException e) {
+      log.error(e, e);
+      throw new AccumuloSecurityException(user, SecurityErrorCode.DEFAULT_SECURITY_ERROR, e);
+    }
+  }
+  
+  @Override
+  public void dropUser(String user) throws AccumuloSecurityException {
+    try {
+      synchronized (zooCache) {
+        zooCache.clear();
+        ZooReaderWriter.getRetryingInstance().recursiveDelete(ZKUserPath + "/" + user, NodeMissingPolicy.FAIL);
+      }
+    } catch (InterruptedException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    } catch (KeeperException e) {
+      log.error(e, e);
+      if (e.code().equals(KeeperException.Code.NONODE))
+        throw new AccumuloSecurityException(user, SecurityErrorCode.USER_DOESNT_EXIST, e);
+      throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+    }
+  }
+  
+  @Override
+  public void changePassword(String user, byte[] pass) throws AccumuloSecurityException {
+    if (userExists(user)) {
+      try {
+        synchronized (zooCache) {
+          zooCache.clear(ZKUserPath + "/" + user);
+          ZooReaderWriter.getRetryingInstance().putPrivatePersistentData(ZKUserPath + "/" + user, ZKSecurityTool.createPass(pass), NodeExistsPolicy.OVERWRITE);
+        }
+      } catch (KeeperException e) {
+        log.error(e, e);
+        throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+      } catch (InterruptedException e) {
+        log.error(e, e);
+        throw new RuntimeException(e);
+      } catch (AccumuloException e) {
+        log.error(e, e);
+        throw new AccumuloSecurityException(user, SecurityErrorCode.DEFAULT_SECURITY_ERROR, e);
+      }
+    } else
+      throw new AccumuloSecurityException(user, SecurityErrorCode.USER_DOESNT_EXIST); // user doesn't exist
+  }
+  
+  /**
+   * Checks if a user exists
+   */
+  @Override
+  public boolean userExists(String user) {
+    return zooCache.get(ZKUserPath + "/" + user) != null;
+  }
+  
+  @Override
+  public void clearCache(String user) {
+    zooCache.clear(ZKUserPath + "/" + user);
+  }
+
+  @Override
+  public boolean validSecurityHandlers(Authorizor auth, PermissionHandler pm) {
+    return true;
+  }
+  
+  @Override
+  public boolean authenticateUser(String user, ByteBuffer password, String instanceId) {
+    byte[] pass;
+    String zpath = ZKUserPath + "/" + user;
+    pass = zooCache.get(zpath);
+    boolean result = ZKSecurityTool.checkPass(ByteBufferUtil.toBytes(password), pass);
+    if (!result) {
+      zooCache.clear(zpath);
+      pass = zooCache.get(zpath);
+      result = ZKSecurityTool.checkPass(ByteBufferUtil.toBytes(password), pass);
+    }
+    return result;
+  }
+  
+  @Override
+  public boolean cachesToClear() {
+    return true;
+  }
+}

Added: accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java
URL: http://svn.apache.org/viewvc/accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java?rev=1361382&view=auto
==============================================================================
--- accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java (added)
+++ accumulo/branches/ACCUMULO-259/server/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java Fri Jul 13 20:34:44 2012
@@ -0,0 +1,152 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.accumulo.server.security.handler;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.security.thrift.SecurityErrorCode;
+import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
+import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeExistsPolicy;
+import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeMissingPolicy;
+import org.apache.accumulo.server.zookeeper.ZooCache;
+import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.KeeperException;
+
+public class ZKAuthorizor implements Authorizor {
+  private static final Logger log = Logger.getLogger(ZKAuthorizor.class);
+  private static Authorizor zkAuthorizorInstance = null;
+
+  private final String ZKUserAuths = "/Authorizations";
+
+  private String ZKUserPath;
+  private final ZooCache zooCache;
+  
+  public static synchronized Authorizor getInstance() {
+    if (zkAuthorizorInstance == null)
+      zkAuthorizorInstance = new ZKAuthorizor();
+    return zkAuthorizorInstance;
+  }
+
+  public ZKAuthorizor() {
+    zooCache = new ZooCache();
+  }
+  
+  public void initialize(String instanceId) {
+    ZKUserPath = ZKSecurityTool.getInstancePath(instanceId) + "/users";
+  }
+
+  public Authorizations getCachedUserAuthorizations(String user) {
+    byte[] authsBytes = zooCache.get(ZKUserPath + "/" + user + ZKUserAuths);
+    if (authsBytes != null)
+      return ZKSecurityTool.convertAuthorizations(authsBytes);
+    return Constants.NO_AUTHS;
+  }
+
+  @Override
+  public boolean validSecurityHandlers(Authenticator auth, PermissionHandler pm) {
+    return true;
+  }
+  
+  @Override
+  public void initializeSecurity(String rootuser) throws AccumuloSecurityException {
+    IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+
+    // create the root user with all system privileges, no table privileges, and no record-level authorizations
+    Set<SystemPermission> rootPerms = new TreeSet<SystemPermission>();
+    for (SystemPermission p : SystemPermission.values())
+      rootPerms.add(p);
+    Map<String,Set<TablePermission>> tablePerms = new HashMap<String,Set<TablePermission>>();
+    // Allow the root user to flush the !METADATA table
+    tablePerms.put(Constants.METADATA_TABLE_ID, Collections.singleton(TablePermission.ALTER_TABLE));
+    
+    try {
+      initUser(rootuser);
+      zoo.putPersistentData(ZKUserPath + "/" + rootuser + ZKUserAuths, ZKSecurityTool.convertAuthorizations(Constants.NO_AUTHS), NodeExistsPolicy.FAIL);
+    } catch (KeeperException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    } catch (InterruptedException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    }
+  }
+  
+  /**
+   * @param user
+   * @throws AccumuloSecurityException
+   */
+  public void initUser(String user) throws AccumuloSecurityException {
+    IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+    try {
+      zoo.putPersistentData(ZKUserPath + "/" + user, new byte[0], NodeExistsPolicy.SKIP);
+    } catch (KeeperException e) {
+      log.error(e, e);
+      throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+    } catch (InterruptedException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    }
+  }
+  
+  @Override
+  public void dropUser(String user) throws AccumuloSecurityException {
+    try {
+      synchronized (zooCache) {
+        IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+        zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserAuths, NodeMissingPolicy.SKIP);
+        zooCache.clear(ZKUserPath + "/" + user);
+      }
+    } catch (InterruptedException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    } catch (KeeperException e) {
+      log.error(e, e);
+      if (e.code().equals(KeeperException.Code.NONODE))
+        throw new AccumuloSecurityException(user, SecurityErrorCode.USER_DOESNT_EXIST, e);
+      throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+      
+    }
+  }
+  
+  @Override
+  public void changeAuthorizations(String user, Authorizations authorizations) throws AccumuloSecurityException {
+    try {
+      synchronized (zooCache) {
+        zooCache.clear();
+        ZooReaderWriter.getRetryingInstance().putPersistentData(ZKUserPath + "/" + user + ZKUserAuths, ZKSecurityTool.convertAuthorizations(authorizations),
+            NodeExistsPolicy.OVERWRITE);
+      }
+    } catch (KeeperException e) {
+      log.error(e, e);
+      throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+    } catch (InterruptedException e) {
+      log.error(e, e);
+      throw new RuntimeException(e);
+    }
+  }
+
+}