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("  <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("  <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("  <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("  <span class='viscontrol'>Color: <select id='color' onchange='setColor(this)'>");
- addOptions(sb, color);
+ addOptions(sb, cfg.color);
sb.append("</select></span>\n");
sb.append("  <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);
+ }
+ }
+
+}