HBASE-2273 [stargate] export metrics via Hadoop metrics, JMX, and zookeeper

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@916882 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew Kyle Purtell 2010-02-27 00:29:27 +00:00
parent 831d072e99
commit db9ca36fb3
19 changed files with 411 additions and 73 deletions

View File

@ -361,12 +361,15 @@ Release 0.21.0 - Unreleased
(bulk loading)
HBASE-2153 Publish generated HTML documentation for Thrift on the website
(Lars Francke via Stack)
HBASE-1373 Update Thrift to use compact/framed protocol (Lars Francke via Stack)
HBASE-1373 Update Thrift to use compact/framed protocol (Lars Francke via
Stack)
HBASE-2172 Add constructor to Put for row key and timestamp
(Lars Francke via Stack)
HBASE-2178 Hooks for replication
HBASE-2180 Bad random read performance from synchronizing hfile.fddatainputstream
HBASE-2194 HTable - put(Put) , put(List<Put) code duplication (Kay Kay via Stack)
HBASE-2180 Bad random read performance from synchronizing
hfile.fddatainputstream
HBASE-2194 HTable - put(Put) , put(List<Put) code duplication (Kay Kay via
Stack)
HBASE-2185 Add html version of default hbase-site.xml (Kay Kay via Stack)
HBASE-2198 SingleColumnValueFilter should be able to find the column value
even when it's not specifically added as input on the sc
@ -412,6 +415,7 @@ Release 0.21.0 - Unreleased
HBASE-2221 MR to copy a table
HBASE-2257 [stargate] multiuser mode
HBASE-2263 [stargate] multiuser mode: authenticator for zookeeper
HBASE-2273 [stargate] export metrics via Hadoop metrics, JMX, and zookeeper
OPTIMIZATIONS
HBASE-410 [testing] Speed up the test suite

View File

@ -28,6 +28,11 @@ public interface Constants {
public static final String AUTHENTICATOR_KEY = "stargate.authenticator";
public static final String MULTIUSER_KEY = "stargate.multiuser";
public static final String STATUS_REPORT_PERIOD_KEY =
"stargate.status.period";
public static final String INSTANCE_ZNODE_ROOT = "/stargate/instance";
public static final String USERS_ZNODE_ROOT = "/stargate/users";
public static final int DEFAULT_MAX_AGE = 60 * 60 * 4; // 4 hours

View File

@ -24,6 +24,7 @@ import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
@ -54,11 +55,6 @@ public class Main implements Constants {
port = Integer.valueOf(cmd.getOptionValue("p"));
}
// configure the Stargate singleton
RESTServlet servlet = RESTServlet.getInstance();
servlet.setMultiUser(cmd.hasOption("m"));
// set up the Jersey servlet container for Jetty
ServletHolder sh = new ServletHolder(ServletContainer.class);
@ -77,6 +73,15 @@ public class Main implements Constants {
// set up context
Context context = new Context(server, "/", Context.SESSIONS);
context.addServlet(sh, "/*");
// configure the Stargate singleton
RESTServlet servlet = RESTServlet.getInstance();
servlet.setMultiUser(cmd.hasOption("m"));
for (Connector conn: server.getConnectors()) {
servlet.addConnectorAddress(conn.getHost(), conn.getLocalPort());
}
server.start();
server.join();
}

View File

@ -21,38 +21,103 @@
package org.apache.hadoop.hbase.stargate;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Chore;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.stargate.auth.Authenticator;
import org.apache.hadoop.hbase.stargate.auth.HBCAuthenticator;
import org.apache.hadoop.hbase.stargate.auth.HTableAuthenticator;
import org.apache.hadoop.hbase.stargate.auth.JDBCAuthenticator;
import org.apache.hadoop.hbase.stargate.auth.ZooKeeperAuthenticator;
import org.apache.hadoop.hbase.stargate.metrics.StargateMetrics;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWrapper;
import org.apache.hadoop.util.StringUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
import org.json.JSONStringer;
import com.sun.jersey.server.impl.container.servlet.ServletAdaptor;
/**
* Singleton class encapsulating global REST servlet state and functions.
*/
public class RESTServlet extends ServletAdaptor implements Constants {
public class RESTServlet extends ServletAdaptor
implements Constants, Watcher {
private static final Log LOG = LogFactory.getLog(RESTServlet.class);
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private static RESTServlet instance;
class StatusReporter extends Chore {
public StatusReporter(int period, AtomicBoolean stopping) {
super(period, stopping);
}
@Override
protected void chore() {
if (wrapper != null) try {
JSONStringer status = new JSONStringer();
status.object();
status.key("requests").value(metrics.getRequests());
status.key("connectors").array();
for (Pair<String,Integer> e: connectors) {
status.object()
.key("host").value(e.getFirst())
.key("port").value(e.getSecond())
.endObject();
}
status.endArray();
status.endObject();
updateNode(wrapper, znode, CreateMode.EPHEMERAL,
Bytes.toBytes(status.toString()));
} catch (Exception e) {
LOG.error(StringUtils.stringifyException(e));
}
}
}
final String znode = INSTANCE_ZNODE_ROOT + "/" + System.currentTimeMillis();
transient final Configuration conf;
transient final HTablePool pool;
transient volatile ZooKeeperWrapper wrapper;
transient Chore statusReporter;
transient Authenticator authenticator;
AtomicBoolean stopping = new AtomicBoolean(false);
boolean multiuser;
Map<String,Integer> maxAgeMap =
Collections.synchronizedMap(new HashMap<String,Integer>());
boolean multiuser;
Authenticator authenticator;
List<Pair<String,Integer>> connectors =
Collections.synchronizedList(new ArrayList<Pair<String,Integer>>());
StargateMetrics metrics = new StargateMetrics();
/**
* @return the RESTServlet singleton instance
@ -65,6 +130,55 @@ public class RESTServlet extends ServletAdaptor implements Constants {
return instance;
}
static boolean ensureExists(final ZooKeeperWrapper zkw, final String znode,
final CreateMode mode) throws IOException {
ZooKeeper zk = zkw.getZooKeeper();
try {
Stat stat = zk.exists(znode, false);
if (stat != null) {
return true;
}
zk.create(znode, new byte[0], Ids.OPEN_ACL_UNSAFE, mode);
LOG.debug("Created ZNode " + znode);
return true;
} catch (KeeperException.NodeExistsException e) {
return true; // ok, move on.
} catch (KeeperException.NoNodeException e) {
return ensureParentExists(zkw, znode, mode) &&
ensureExists(zkw, znode, mode);
} catch (KeeperException e) {
throw new IOException(e);
} catch (InterruptedException e) {
throw new IOException(e);
}
}
static boolean ensureParentExists(final ZooKeeperWrapper zkw,
final String znode, final CreateMode mode) throws IOException {
int index = znode.lastIndexOf("/");
if (index <= 0) { // Parent is root, which always exists.
return true;
}
return ensureExists(zkw, znode.substring(0, index), mode);
}
static void updateNode(final ZooKeeperWrapper zkw, final String znode,
final CreateMode mode, final byte[] data) throws IOException {
ensureExists(zkw, znode, mode);
ZooKeeper zk = zkw.getZooKeeper();
try {
zk.setData(znode, data, -1);
} catch (KeeperException e) {
throw new IOException(e);
} catch (InterruptedException e) {
throw new IOException(e);
}
}
ZooKeeperWrapper initZooKeeperWrapper() throws IOException {
return new ZooKeeperWrapper(conf, this);
}
/**
* Constructor
* @throws IOException
@ -72,23 +186,54 @@ public class RESTServlet extends ServletAdaptor implements Constants {
public RESTServlet() throws IOException {
this.conf = HBaseConfiguration.create();
this.pool = new HTablePool(conf, 10);
this.wrapper = initZooKeeperWrapper();
this.statusReporter = new StatusReporter(
conf.getInt(STATUS_REPORT_PERIOD_KEY, 1000 * 60), stopping);
}
/**
* Get a table pool for the given table.
* @return the table pool
*/
protected HTablePool getTablePool() {
@Override
public void process(WatchedEvent event) {
LOG.debug(("ZooKeeper.Watcher event " + event.getType() + " with path " +
event.getPath()));
// handle disconnection (or manual delete to test disconnection scenario)
if (event.getState() == KeeperState.Expired ||
(event.getType().equals(EventType.NodeDeleted) &&
event.getPath().equals(znode))) {
wrapper.close();
wrapper = null;
while (!stopping.get()) try {
wrapper = initZooKeeperWrapper();
break;
} catch (IOException e) {
LOG.error(StringUtils.stringifyException(e));
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException ex) {
}
}
}
}
HTablePool getTablePool() {
return pool;
}
/**
* @return the servlet's global HBase configuration
*/
protected Configuration getConfiguration() {
ZooKeeperWrapper getZooKeeperWrapper() {
return wrapper;
}
Configuration getConfiguration() {
return conf;
}
StargateMetrics getMetrics() {
return metrics;
}
void addConnectorAddress(String host, int port) {
connectors.add(new Pair<String,Integer>(host, port));
}
/**
* @param tableName the table name
* @return the maximum cache age suitable for use with this table, in
@ -148,10 +293,24 @@ public class RESTServlet extends ServletAdaptor implements Constants {
*/
public Authenticator getAuthenticator() {
if (authenticator == null) {
String className = conf.get("stargate.auth.authenticator");
if (className != null) try {
String className = conf.get(AUTHENTICATOR_KEY,
HBCAuthenticator.class.getCanonicalName());
try {
Class<?> c = getClass().getClassLoader().loadClass(className);
authenticator = (Authenticator)c.newInstance();
if (className.endsWith(HBCAuthenticator.class.getName()) ||
className.endsWith(HTableAuthenticator.class.getName()) ||
className.endsWith(JDBCAuthenticator.class.getName())) {
Constructor<?> cons = c.getConstructor(Configuration.class);
authenticator = (Authenticator)
cons.newInstance(new Object[] { conf });
} else if (className.endsWith(ZooKeeperAuthenticator.class.getName())) {
Constructor<?> cons = c.getConstructor(Configuration.class,
ZooKeeperWrapper.class);
authenticator = (Authenticator)
cons.newInstance(new Object[] { conf, wrapper });
} else {
authenticator = (Authenticator)c.newInstance();
}
} catch (Exception e) {
LOG.error(StringUtils.stringifyException(e));
}

View File

@ -83,6 +83,7 @@ public class RegionsResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
try {
TableInfoModel model = new TableInfoModel(table);
Map<HRegionInfo,HServerAddress> regions = getTableRegions();

View File

@ -91,6 +91,7 @@ public class RootResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
if (servlet.isMultiUser()) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
@ -114,7 +115,7 @@ public class RootResource implements Constants {
}
@Path("version")
public VersionResource getVersionResource() {
public VersionResource getVersionResource() throws IOException {
return new VersionResource();
}

View File

@ -87,6 +87,7 @@ public class RowResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
try {
ResultGenerator generator =
ResultGenerator.fromRowSpec(actualTableName, rowspec);
@ -124,6 +125,7 @@ public class RowResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath() + " as "+ MIMETYPE_BINARY);
}
servlet.getMetrics().incrementRequests(1);
// doesn't make sense to use a non specific coordinate as this can only
// return a single cell
if (!rowspec.hasColumns() || rowspec.getColumns().length > 1) {
@ -146,7 +148,8 @@ public class RowResource implements Constants {
}
}
private Response update(CellSetModel model, boolean replace) {
Response update(CellSetModel model, boolean replace) {
servlet.getMetrics().incrementRequests(1);
HTablePool pool = servlet.getTablePool();
HTableInterface table = null;
try {
@ -180,8 +183,9 @@ public class RowResource implements Constants {
}
}
private Response updateBinary(byte[] message, HttpHeaders headers,
Response updateBinary(byte[] message, HttpHeaders headers,
boolean replace) {
servlet.getMetrics().incrementRequests(1);
HTablePool pool = servlet.getTablePool();
HTableInterface table = null;
try {
@ -276,7 +280,7 @@ public class RowResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("DELETE " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
Delete delete = null;
if (rowspec.hasTimestamp())
delete = new Delete(rowspec.getRow(), rowspec.getTimestamp(), null);

View File

@ -47,16 +47,18 @@ public class ScannerInstanceResource implements Constants {
private static final Log LOG =
LogFactory.getLog(ScannerInstanceResource.class);
protected ResultGenerator generator;
private String id;
private int batch;
private CacheControl cacheControl;
ResultGenerator generator;
String id;
int batch;
RESTServlet servlet;
CacheControl cacheControl;
public ScannerInstanceResource(String table, String id,
ResultGenerator generator, int batch) throws IOException {
this.id = id;
this.generator = generator;
this.batch = batch;
servlet = RESTServlet.getInstance();
cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoTransform(false);
@ -68,6 +70,7 @@ public class ScannerInstanceResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
CellSetModel model = new CellSetModel();
RowModel rowModel = null;
byte[] rowKey = null;
@ -115,6 +118,7 @@ public class ScannerInstanceResource implements Constants {
LOG.debug("GET " + uriInfo.getAbsolutePath() + " as " +
MIMETYPE_BINARY);
}
servlet.getMetrics().incrementRequests(1);
try {
KeyValue value = generator.next();
if (value == null) {
@ -140,6 +144,7 @@ public class ScannerInstanceResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("DELETE " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
ScannerResource.delete(id);
return Response.ok().build();
}

View File

@ -54,8 +54,9 @@ public class ScannerResource implements Constants {
User user;
String tableName;
String actualTableName;
RESTServlet servlet;
public ScannerResource(User user, String table) {
public ScannerResource(User user, String table) throws IOException {
if (user != null) {
this.user = user;
this.actualTableName =
@ -64,14 +65,24 @@ public class ScannerResource implements Constants {
this.actualTableName = table;
}
this.tableName = table;
servlet = RESTServlet.getInstance();
}
private Response update(ScannerModel model, boolean replace,
UriInfo uriInfo) {
static void delete(String id) {
synchronized (scanners) {
ScannerInstanceResource instance = scanners.remove(id);
if (instance != null) {
instance.generator.close();
}
}
}
Response update(ScannerModel model, boolean replace, UriInfo uriInfo) {
servlet.getMetrics().incrementRequests(1);
byte[] endRow = model.hasEndRow() ? model.getEndRow() : null;
RowSpec spec = new RowSpec(model.getStartRow(), endRow,
model.getColumns(), model.getStartTime(), model.getEndTime(), 1);
try {
byte[] endRow = model.hasEndRow() ? model.getEndRow() : null;
RowSpec spec = new RowSpec(model.getStartRow(), endRow,
model.getColumns(), model.getStartTime(), model.getEndTime(), 1);
ScannerResultGenerator gen = new ScannerResultGenerator(actualTableName, spec);
String id = gen.getID();
ScannerInstanceResource instance =
@ -123,12 +134,4 @@ public class ScannerResource implements Constants {
}
}
static void delete(String id) {
synchronized (scanners) {
ScannerInstanceResource instance = scanners.remove(id);
if (instance != null) {
instance.generator.close();
}
}
}
}

View File

@ -70,10 +70,10 @@ public class SchemaResource implements Constants {
this.actualTableName = table;
}
this.tableName = table;
servlet = RESTServlet.getInstance();
cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoTransform(false);
servlet = RESTServlet.getInstance();
}
private HTableDescriptor getTableSchema() throws IOException,
@ -93,6 +93,7 @@ public class SchemaResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
try {
HTableDescriptor htd = getTableSchema();
TableSchemaModel model = new TableSchemaModel();
@ -207,6 +208,7 @@ public class SchemaResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("PUT " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
// use the name given in the path, but warn if the name on the path and
// the name in the schema are different
if (model.getName() != tableName) {
@ -222,6 +224,7 @@ public class SchemaResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("PUT " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
// use the name given in the path, but warn if the name on the path and
// the name in the schema are different
if (model.getName() != tableName) {
@ -236,6 +239,7 @@ public class SchemaResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("DELETE " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
try {
HBaseAdmin admin = new HBaseAdmin(servlet.getConfiguration());
admin.disableTable(actualTableName);

View File

@ -48,10 +48,10 @@ public class StorageClusterStatusResource implements Constants {
private RESTServlet servlet;
public StorageClusterStatusResource() throws IOException {
servlet = RESTServlet.getInstance();
cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoTransform(false);
servlet = RESTServlet.getInstance();
}
@GET
@ -60,6 +60,7 @@ public class StorageClusterStatusResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
try {
HBaseAdmin admin = new HBaseAdmin(servlet.getConfiguration());
ClusterStatus status = admin.getClusterStatus();

View File

@ -42,8 +42,10 @@ public class StorageClusterVersionResource implements Constants {
LogFactory.getLog(StorageClusterVersionResource.class);
private CacheControl cacheControl;
private RESTServlet servlet;
public StorageClusterVersionResource() {
public StorageClusterVersionResource() throws IOException {
servlet = RESTServlet.getInstance();
cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoTransform(false);
@ -55,10 +57,10 @@ public class StorageClusterVersionResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
Configuration conf = servlet.getConfiguration();
try {
RESTServlet server = RESTServlet.getInstance();
Configuration hconf = server.getConfiguration();
HBaseAdmin admin = new HBaseAdmin(hconf);
HBaseAdmin admin = new HBaseAdmin(conf);
StorageClusterVersionModel model = new StorageClusterVersionModel();
model.setVersion(admin.getClusterStatus().getHBaseVersion());
ResponseBuilder response = Response.ok(model);

View File

@ -46,7 +46,7 @@ public class TableResource implements Constants {
}
@Path("scanner")
public ScannerResource getScannerResource() {
public ScannerResource getScannerResource() throws IOException {
return new ScannerResource(user, table);
}

View File

@ -20,6 +20,8 @@
package org.apache.hadoop.hbase.stargate;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@ -45,8 +47,10 @@ public class VersionResource implements Constants {
private static final Log LOG = LogFactory.getLog(VersionResource.class);
private CacheControl cacheControl;
private RESTServlet servlet;
public VersionResource() {
public VersionResource() throws IOException {
servlet = RESTServlet.getInstance();
cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoTransform(false);
@ -65,6 +69,7 @@ public class VersionResource implements Constants {
if (LOG.isDebugEnabled()) {
LOG.debug("GET " + uriInfo.getAbsolutePath());
}
servlet.getMetrics().incrementRequests(1);
ResponseBuilder response = Response.ok(new VersionModel(context));
response.cacheControl(cacheControl);
return response.build();
@ -74,7 +79,8 @@ public class VersionResource implements Constants {
* Dispatch to StorageClusterVersionResource
*/
@Path("cluster")
public StorageClusterVersionResource getClusterVersionResource() {
public StorageClusterVersionResource getClusterVersionResource()
throws IOException {
return new StorageClusterVersionResource();
}

View File

@ -7,6 +7,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.util.StringUtils;
import org.mortbay.log.Log;
@ -24,12 +25,13 @@ public class JDBCAuthenticator extends Authenticator {
/**
* Constructor
* @param url
* @param user
* @param password
* @param conf
*/
public JDBCAuthenticator(String url, String user, String password) {
this(url, "users", user, password);
public JDBCAuthenticator(HBaseConfiguration conf) {
this(conf.get("stargate.auth.jdbc.url"),
conf.get("stargate.auth.jdbc.table"),
conf.get("stargate.auth.jdbc.user"),
conf.get("stargate.auth.jdbc.password"));
}
/**

View File

@ -23,6 +23,7 @@ package org.apache.hadoop.hbase.stargate.auth;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.stargate.Constants;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWrapper;
import org.apache.zookeeper.CreateMode;
@ -45,10 +46,10 @@ import org.json.JSONObject;
* 'name' (String, required), 'token' (String, optional), 'admin' (boolean,
* optional), and 'disabled' (boolean, optional).
*/
public class ZooKeeperAuthenticator extends Authenticator {
static final String USERS_ROOT_ZNODE = "/stargate/users";
public class ZooKeeperAuthenticator extends Authenticator
implements Constants {
final String usersZNode;
ZooKeeperWrapper wrapper;
private boolean ensureParentExists(final String znode) {
@ -85,17 +86,20 @@ public class ZooKeeperAuthenticator extends Authenticator {
* @throws IOException
*/
public ZooKeeperAuthenticator(Configuration conf) throws IOException {
this(new ZooKeeperWrapper(conf, new Watcher() {
this(conf, new ZooKeeperWrapper(conf, new Watcher() {
public void process(WatchedEvent event) { }
}));
ensureExists(USERS_ROOT_ZNODE);
ensureExists(USERS_ZNODE_ROOT);
}
/**
* Constructor
* @param conf
* @param wrapper
*/
public ZooKeeperAuthenticator(ZooKeeperWrapper wrapper) {
public ZooKeeperAuthenticator(Configuration conf,
ZooKeeperWrapper wrapper) {
this.usersZNode = conf.get("stargate.auth.zk.users", USERS_ZNODE_ROOT);
this.wrapper = wrapper;
}
@ -103,7 +107,7 @@ public class ZooKeeperAuthenticator extends Authenticator {
public User getUserForToken(String token) throws IOException {
ZooKeeper zk = wrapper.getZooKeeper();
try {
byte[] data = zk.getData(USERS_ROOT_ZNODE + "/" + token, null, null);
byte[] data = zk.getData(usersZNode + "/" + token, null, null);
if (data == null) {
return null;
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2010 The Apache Software Foundation
*
* 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.hadoop.hbase.stargate.metrics;
import org.apache.hadoop.hbase.metrics.MetricsRate;
import org.apache.hadoop.metrics.MetricsContext;
import org.apache.hadoop.metrics.MetricsRecord;
import org.apache.hadoop.metrics.MetricsUtil;
import org.apache.hadoop.metrics.Updater;
import org.apache.hadoop.metrics.jvm.JvmMetrics;
import org.apache.hadoop.metrics.util.MetricsRegistry;
public class StargateMetrics implements Updater {
private final MetricsRecord metricsRecord;
private final MetricsRegistry registry = new MetricsRegistry();
private final StargateStatistics stargateStatistics;
private MetricsRate requests = new MetricsRate("requests", registry);
public StargateMetrics() {
MetricsContext context = MetricsUtil.getContext("stargate");
metricsRecord = MetricsUtil.createRecord(context, "stargate");
String name = Thread.currentThread().getName();
metricsRecord.setTag("Master", name);
context.registerUpdater(this);
JvmMetrics.init("Stargate", name);
// expose the MBean for metrics
stargateStatistics = new StargateStatistics(registry);
}
public void shutdown() {
if (stargateStatistics != null) {
stargateStatistics.shutdown();
}
}
/**
* Since this object is a registered updater, this method will be called
* periodically, e.g. every 5 seconds.
* @param unused
*/
public void doUpdates(MetricsContext unused) {
synchronized (this) {
requests.pushMetric(metricsRecord);
}
this.metricsRecord.update();
}
public void resetAllMinMax() {
// Nothing to do
}
/**
* @return Count of requests.
*/
public float getRequests() {
return requests.getPreviousIntervalValue();
}
/**
* @param inc How much to add to requests.
*/
public void incrementRequests(final int inc) {
requests.inc(inc);
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2010 The Apache Software Foundation
*
* 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.hadoop.hbase.stargate.metrics;
import javax.management.ObjectName;
import org.apache.hadoop.hbase.metrics.MetricsMBeanBase;
import org.apache.hadoop.metrics.util.MBeanUtil;
import org.apache.hadoop.metrics.util.MetricsRegistry;
public class StargateStatistics extends MetricsMBeanBase {
private final ObjectName mbeanName;
public StargateStatistics(MetricsRegistry registry) {
super(registry, "StargateStatistics");
mbeanName = MBeanUtil.registerMBean("Stargate",
"StargateStatistics", this);
}
public void shutdown() {
if (mbeanName != null) {
MBeanUtil.unregisterMBean(mbeanName);
}
}
}

View File

@ -45,9 +45,9 @@ public class TestZooKeeperAuthenticator extends MiniClusterTestBase {
public void setUp() throws Exception {
authenticator = new ZooKeeperAuthenticator(conf);
ZooKeeper zk = authenticator.wrapper.getZooKeeper();
if (zk.exists(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +
if (zk.exists(ZooKeeperAuthenticator.USERS_ZNODE_ROOT + "/" +
ADMIN_TOKEN, null) == null) {
zk.create(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" + ADMIN_TOKEN,
zk.create(ZooKeeperAuthenticator.USERS_ZNODE_ROOT + "/" + ADMIN_TOKEN,
Bytes.toBytes(new JSONStringer()
.object()
.key("name").value(ADMIN_USERNAME)
@ -55,9 +55,9 @@ public class TestZooKeeperAuthenticator extends MiniClusterTestBase {
.endObject().toString()),
Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
if (zk.exists(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +
if (zk.exists(ZooKeeperAuthenticator.USERS_ZNODE_ROOT + "/" +
USER_TOKEN, null) == null) {
zk.create(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" + USER_TOKEN,
zk.create(ZooKeeperAuthenticator.USERS_ZNODE_ROOT + "/" + USER_TOKEN,
Bytes.toBytes(new JSONStringer()
.object()
.key("name").value(USER_USERNAME)
@ -65,9 +65,9 @@ public class TestZooKeeperAuthenticator extends MiniClusterTestBase {
.endObject().toString()),
Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
if (zk.exists(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +
if (zk.exists(ZooKeeperAuthenticator.USERS_ZNODE_ROOT + "/" +
DISABLED_TOKEN, null) == null) {
zk.create(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +DISABLED_TOKEN,
zk.create(ZooKeeperAuthenticator.USERS_ZNODE_ROOT + "/" +DISABLED_TOKEN,
Bytes.toBytes(new JSONStringer()
.object()
.key("name").value(DISABLED_USERNAME)