javadoc and small improvements

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@790777 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew Kyle Purtell 2009-07-03 02:05:53 +00:00
parent ea200a9e5c
commit a6c48ab299
26 changed files with 835 additions and 172 deletions

View File

@ -20,6 +20,9 @@
package org.apache.hadoop.hbase.stargate; package org.apache.hadoop.hbase.stargate;
/**
* Common constants for org.apache.hadoop.hbase.stargate
*/
public interface Constants { public interface Constants {
public static final String MIMETYPE_TEXT = "text/plain"; public static final String MIMETYPE_TEXT = "text/plain";
public static final String MIMETYPE_XML = "text/xml"; public static final String MIMETYPE_XML = "text/xml";

View File

@ -24,7 +24,6 @@ import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser; import org.apache.commons.cli.PosixParser;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.mortbay.jetty.Connector; import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Handler; import org.mortbay.jetty.Handler;
import org.mortbay.jetty.NCSARequestLog; import org.mortbay.jetty.NCSARequestLog;
@ -37,6 +36,15 @@ import org.mortbay.jetty.handler.RequestLogHandler;
import org.mortbay.jetty.nio.SelectChannelConnector; import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.thread.QueuedThreadPool; import org.mortbay.thread.QueuedThreadPool;
/**
* Main class for launching Stargate as a servlet hosted by an embedded Jetty
* servlet container.
* <p>
* The following options are supported:
* <ul>
* <li>-p: service port</li>
* </ul>
*/
public class Main { public class Main {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -50,17 +58,6 @@ public class Main {
port = Integer.valueOf(cmd.getOptionValue("p")); port = Integer.valueOf(cmd.getOptionValue("p"));
} }
HBaseConfiguration conf = new HBaseConfiguration();
if (cmd.hasOption("m")) {
conf.set("hbase.master", cmd.getOptionValue("m"));
}
/*
* RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); if (runtime
* != null) { LOG.info("vmName=" + runtime.getVmName() + ", vmVendor=" +
* runtime.getVmVendor() + ", vmVersion=" + runtime.getVmVersion());
* LOG.info("vmInputArguments=" + runtime.getInputArguments()); }
*/
/* /*
* poached from: * poached from:
* http://jetty.mortbay.org/xref/org/mortbay/jetty/example/LikeJettyXml.html * http://jetty.mortbay.org/xref/org/mortbay/jetty/example/LikeJettyXml.html

View File

@ -32,8 +32,10 @@ import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import com.sun.jersey.server.impl.container.servlet.ServletAdaptor; import com.sun.jersey.server.impl.container.servlet.ServletAdaptor;
import com.sun.jersey.spi.container.servlet.ServletContainer;
/**
* Singleton class encapsulating global REST servlet state and functions.
*/
public class RESTServlet extends ServletAdaptor { public class RESTServlet extends ServletAdaptor {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -46,6 +48,10 @@ public class RESTServlet extends ServletAdaptor {
protected Map<String,Integer> maxAgeMap = protected Map<String,Integer> maxAgeMap =
Collections.synchronizedMap(new HashMap<String,Integer>()); Collections.synchronizedMap(new HashMap<String,Integer>());
/**
* @return the RESTServlet singleton instance
* @throws IOException
*/
public synchronized static RESTServlet getInstance() throws IOException { public synchronized static RESTServlet getInstance() throws IOException {
if (instance == null) { if (instance == null) {
instance = new RESTServlet(); instance = new RESTServlet();
@ -53,21 +59,33 @@ public class RESTServlet extends ServletAdaptor {
return instance; return instance;
} }
/**
* Constructor
* @throws IOException
*/
public RESTServlet() throws IOException { public RESTServlet() throws IOException {
this.conf = new HBaseConfiguration(); this.conf = new HBaseConfiguration();
} }
/**
* Get or create a table pool for the given table.
* @param name the table name
* @return the table pool
*/
protected HTablePool getTablePool(String name) { protected HTablePool getTablePool(String name) {
return HTablePool.getPool(conf, Bytes.toBytes(name)); return HTablePool.getPool(conf, Bytes.toBytes(name));
} }
/**
* @return the servlet's global HBase configuration
*/
protected HBaseConfiguration getConfiguration() { protected HBaseConfiguration getConfiguration() {
return conf; return conf;
} }
/** /**
* @param tableName * @param tableName the table name
* @return the maximum cache age suitable for use with this table, in * @return the maximum cache age suitable for use with this table, in
* seconds * seconds
* @throws IOException * @throws IOException
@ -97,30 +115,12 @@ public class RESTServlet extends ServletAdaptor {
return DEFAULT_MAX_AGE; return DEFAULT_MAX_AGE;
} }
/**
* Signal that a previously calculated maximum cache age has been
* invalidated by a schema change.
* @param tableName the table name
*/
public void invalidateMaxAge(String tableName) { public void invalidateMaxAge(String tableName) {
maxAgeMap.remove(tableName); maxAgeMap.remove(tableName);
} }
public static final String getVersion() {
StringBuilder version = new StringBuilder();
version.append("Stargate ");
version.append(VERSION_STRING);
version.append(" [JVM: ");
version.append(System.getProperty("java.vm.vendor"));
version.append(' ');
version.append(System.getProperty("java.version"));
version.append('-');
version.append(System.getProperty("java.vm.version"));
version.append("] [OS: ");
version.append(System.getProperty("os.name"));
version.append(' ');
version.append(System.getProperty("os.version"));
version.append(' ');
version.append(System.getProperty("os.arch"));
version.append("] [Jersey: ");
version.append(ServletContainer.class.getPackage()
.getImplementationVersion());
version.append(']');
return version.toString();
}
} }

View File

@ -27,6 +27,12 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
/**
* Parses a path based row/column/timestamp specification into its component
* elements.
* <p>
*
*/
public class RowSpec { public class RowSpec {
public static final long DEFAULT_START_TIMESTAMP = 0; public static final long DEFAULT_START_TIMESTAMP = 0;
public static final long DEFAULT_END_TIMESTAMP = Long.MAX_VALUE; public static final long DEFAULT_END_TIMESTAMP = Long.MAX_VALUE;

View File

@ -34,6 +34,13 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.stargate.model.VersionModel; import org.apache.hadoop.hbase.stargate.model.VersionModel;
/**
* Implements Stargate software version reporting via
* <p>
* <tt>/version/stargate</tt>
* <p>
* <tt>/version</tt> (alias for <tt>/version/stargate</tt>)
*/
@Path(Constants.PATH_VERSION) @Path(Constants.PATH_VERSION)
public class VersionResource implements Constants { public class VersionResource implements Constants {
private static final Log LOG = LogFactory.getLog(VersionResource.class); private static final Log LOG = LogFactory.getLog(VersionResource.class);
@ -46,6 +53,12 @@ public class VersionResource implements Constants {
cacheControl.setNoTransform(false); cacheControl.setNoTransform(false);
} }
/**
* Build a response for a version request.
* @param context servlet context
* @param uriInfo (JAX-RS context variable) request URL
* @return a response for a version request
*/
@GET @GET
@Produces({MIMETYPE_TEXT, MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_JAVASCRIPT, @Produces({MIMETYPE_TEXT, MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_JAVASCRIPT,
MIMETYPE_PROTOBUF}) MIMETYPE_PROTOBUF})
@ -58,6 +71,9 @@ public class VersionResource implements Constants {
return response.build(); return response.build();
} }
/**
* Dispatch <tt>/version/stargate</tt> to self.
*/
// "/version/stargate" is an alias for "/version" // "/version/stargate" is an alias for "/version"
@Path("stargate") @Path("stargate")
public VersionResource getVersionResource() { public VersionResource getVersionResource() {

View File

@ -39,6 +39,10 @@ import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
/**
* A wrapper around HttpClient which provides some useful function and
* semantics for interacting with the Stargate REST gateway.
*/
public class Client { public class Client {
public static final Header[] EMPTY_HEADER_ARRAY = new Header[0]; public static final Header[] EMPTY_HEADER_ARRAY = new Header[0];
@ -47,10 +51,17 @@ public class Client {
private HttpClient httpClient; private HttpClient httpClient;
private Cluster cluster; private Cluster cluster;
/**
* Default Constructor
*/
public Client() { public Client() {
this(null); this(null);
} }
/**
* Constructor
* @param cluster the cluster definition
*/
public Client(Cluster cluster) { public Client(Cluster cluster) {
this.cluster = cluster; this.cluster = cluster;
httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
@ -61,37 +72,61 @@ public class Client {
clientParams.setVersion(HttpVersion.HTTP_1_1); clientParams.setVersion(HttpVersion.HTTP_1_1);
} }
/**
* Shut down the client. Close any open persistent connections.
*/
public void shutdown() { public void shutdown() {
MultiThreadedHttpConnectionManager manager = MultiThreadedHttpConnectionManager manager =
(MultiThreadedHttpConnectionManager) httpClient.getHttpConnectionManager(); (MultiThreadedHttpConnectionManager) httpClient.getHttpConnectionManager();
manager.shutdown(); manager.shutdown();
} }
/**
* Execute a transaction method given only the path. Will select at random
* one of the members of the supplied cluster definition and iterate through
* the list until a transaction can be successfully completed. The
* definition of success here is a complete HTTP transaction, irrespective
* of result code.
* @param cluster the cluster definition
* @param method the transaction method
* @param headers HTTP header values to send
* @param path the path
* @return the HTTP response code
* @throws IOException
*/
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int executePathOnly(Cluster c, HttpMethod method, Header[] headers, public int executePathOnly(Cluster cluster, HttpMethod method,
String path) throws IOException { Header[] headers, String path) throws IOException {
IOException lastException; IOException lastException;
if (c.nodes.size() < 1) { if (cluster.nodes.size() < 1) {
throw new IOException("Cluster is empty"); throw new IOException("Cluster is empty");
} }
int start = (int)Math.round((c.nodes.size() - 1) * Math.random()); int start = (int)Math.round((cluster.nodes.size() - 1) * Math.random());
int i = start; int i = start;
do { do {
c.lastHost = c.nodes.get(i); cluster.lastHost = cluster.nodes.get(i);
try { try {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
sb.append("http://"); sb.append("http://");
sb.append(c.lastHost); sb.append(cluster.lastHost);
sb.append(path); sb.append(path);
URI uri = new URI(sb.toString()); URI uri = new URI(sb.toString());
return executeURI(method, headers, uri.toString()); return executeURI(method, headers, uri.toString());
} catch (IOException e) { } catch (IOException e) {
lastException = e; lastException = e;
} }
} while (++i != start && i < c.nodes.size()); } while (++i != start && i < cluster.nodes.size());
throw lastException; throw lastException;
} }
/**
* Execute a transaction method given a complete URI.
* @param method the transaction method
* @param headers HTTP header values to send
* @param uri the URI
* @return the HTTP response code
* @throws IOException
*/
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int executeURI(HttpMethod method, Header[] headers, String uri) public int executeURI(HttpMethod method, Header[] headers, String uri)
throws IOException { throws IOException {
@ -111,57 +146,133 @@ public class Client {
return code; return code;
} }
public int execute(Cluster c, HttpMethod method, Header[] headers, /**
* Execute a transaction method. Will call either <tt>executePathOnly</tt>
* or <tt>executeURI</tt> depending on whether a path only is supplied in
* 'path', or if a complete URI is passed instead, respectively.
* @param cluster the cluster definition
* @param method the HTTP method
* @param headers HTTP header values to send
* @param path the path or URI
* @return the HTTP response code
* @throws IOException
*/
public int execute(Cluster cluster, HttpMethod method, Header[] headers,
String path) throws IOException { String path) throws IOException {
if (path.startsWith("/")) { if (path.startsWith("/")) {
return executePathOnly(c, method, headers, path); return executePathOnly(cluster, method, headers, path);
} }
return executeURI(method, headers, path); return executeURI(method, headers, path);
} }
/**
* @return the cluster definition
*/
public Cluster getCluster() { public Cluster getCluster() {
return cluster; return cluster;
} }
/**
* @param cluster the cluster definition
*/
public void setCluster(Cluster cluster) { public void setCluster(Cluster cluster) {
this.cluster = cluster; this.cluster = cluster;
} }
/**
* Send a HEAD request
* @param path the path or URI
* @return a Response object with response detail
* @throws IOException
*/
public Response head(String path) throws IOException { public Response head(String path) throws IOException {
return head(cluster, path); return head(cluster, path, null);
} }
public Response head(Cluster c, String path) throws IOException { /**
* Send a HEAD request
* @param cluster the cluster definition
* @param path the path or URI
* @param headers the HTTP headers to include in the request
* @return a Response object with response detail
* @throws IOException
*/
public Response head(Cluster cluster, String path, Header[] headers)
throws IOException {
HeadMethod method = new HeadMethod(); HeadMethod method = new HeadMethod();
int code = execute(c, method, null, path); int code = execute(cluster, method, null, path);
Header[] headers = method.getResponseHeaders(); headers = method.getResponseHeaders();
method.releaseConnection(); method.releaseConnection();
return new Response(code, headers, null); return new Response(code, headers, null);
} }
/**
* Send a GET request
* @param path the path or URI
* @return a Response object with response detail
* @throws IOException
*/
public Response get(String path) throws IOException { public Response get(String path) throws IOException {
return get(cluster, path); return get(cluster, path);
} }
public Response get(Cluster c, String path) throws IOException { /**
return get(c, path, EMPTY_HEADER_ARRAY); * Send a GET request
* @param cluster the cluster definition
* @param path the path or URI
* @return a Response object with response detail
* @throws IOException
*/
public Response get(Cluster cluster, String path) throws IOException {
return get(cluster, path, EMPTY_HEADER_ARRAY);
} }
/**
* Send a GET request
* @param path the path or URI
* @param accept Accept header value
* @return a Response object with response detail
* @throws IOException
*/
public Response get(String path, String accept) throws IOException { public Response get(String path, String accept) throws IOException {
return get(cluster, path, accept); return get(cluster, path, accept);
} }
public Response get(Cluster c, String path, String accept) /**
* Send a GET request
* @param cluster the cluster definition
* @param path the path or URI
* @param accept Accept header value
* @return a Response object with response detail
* @throws IOException
*/
public Response get(Cluster cluster, String path, String accept)
throws IOException { throws IOException {
Header[] headers = new Header[1]; Header[] headers = new Header[1];
headers[0] = new Header("Accept", accept); headers[0] = new Header("Accept", accept);
return get(c, path, headers); return get(cluster, path, headers);
} }
/**
* Send a GET request
* @param path the path or URI
* @param headers the HTTP headers to include in the request,
* <tt>Accept</tt> must be supplied
* @return a Response object with response detail
* @throws IOException
*/
public Response get(String path, Header[] headers) throws IOException { public Response get(String path, Header[] headers) throws IOException {
return get(cluster, path, headers); return get(cluster, path, headers);
} }
/**
* Send a GET request
* @param cluster the cluster definition
* @param path the path or URI
* @param headers the HTTP headers to include in the request
* @return a Response object with response detail
* @throws IOException
*/
public Response get(Cluster c, String path, Header[] headers) public Response get(Cluster c, String path, Header[] headers)
throws IOException { throws IOException {
GetMethod method = new GetMethod(); GetMethod method = new GetMethod();
@ -172,69 +283,154 @@ public class Client {
return new Response(code, headers, body); return new Response(code, headers, body);
} }
/**
* Send a PUT request
* @param path the path or URI
* @param contentType the content MIME type
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response put(String path, String contentType, byte[] content) public Response put(String path, String contentType, byte[] content)
throws IOException { throws IOException {
return put(cluster, path, contentType, content); return put(cluster, path, contentType, content);
} }
public Response put(Cluster c, String path, String contentType, /**
* Send a PUT request
* @param cluster the cluster definition
* @param path the path or URI
* @param contentType the content MIME type
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response put(Cluster cluster, String path, String contentType,
byte[] content) throws IOException { byte[] content) throws IOException {
Header[] headers = new Header[1]; Header[] headers = new Header[1];
headers[0] = new Header("Content-Type", contentType); headers[0] = new Header("Content-Type", contentType);
return put(c, path, headers, content); return put(cluster, path, headers, content);
} }
public Response put(String path, Header[] headers, byte[] body) /**
* Send a PUT request
* @param path the path or URI
* @param headers the HTTP headers to include, <tt>Content-Type</tt> must be
* supplied
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response put(String path, Header[] headers, byte[] content)
throws IOException { throws IOException {
return put(cluster, path, headers, body); return put(cluster, path, headers, content);
} }
public Response put(Cluster c, String path, Header[] headers, /**
byte[] body) throws IOException { * Send a PUT request
* @param cluster the cluster definition
* @param path the path or URI
* @param headers the HTTP headers to include, <tt>Content-Type</tt> must be
* supplied
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response put(Cluster cluster, String path, Header[] headers,
byte[] content) throws IOException {
PutMethod method = new PutMethod(); PutMethod method = new PutMethod();
method.setRequestEntity(new ByteArrayRequestEntity(body));
int code = execute(c, method, headers, path);
headers = method.getResponseHeaders();
body = method.getResponseBody();
method.releaseConnection();
return new Response(code, headers, body);
}
public Response post(String path, String contentType, byte[] content)
throws IOException {
return post(cluster, path, contentType, content);
}
public Response post(Cluster c, String path, String contentType,
byte[] content) throws IOException {
Header[] headers = new Header[1];
headers[0] = new Header("Content-Type", contentType);
return post(c, path, headers, content);
}
public Response post(String path, Header[] headers, byte[] content)
throws IOException {
return post(cluster, path, headers, content);
}
public Response post(Cluster c, String path, Header[] headers,
byte[] content) throws IOException {
PostMethod method = new PostMethod();
method.setRequestEntity(new ByteArrayRequestEntity(content)); method.setRequestEntity(new ByteArrayRequestEntity(content));
int code = execute(c, method, headers, path); int code = execute(cluster, method, headers, path);
headers = method.getResponseHeaders(); headers = method.getResponseHeaders();
content = method.getResponseBody(); content = method.getResponseBody();
method.releaseConnection(); method.releaseConnection();
return new Response(code, headers, content); return new Response(code, headers, content);
} }
/**
* Send a POST request
* @param path the path or URI
* @param contentType the content MIME type
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response post(String path, String contentType, byte[] content)
throws IOException {
return post(cluster, path, contentType, content);
}
/**
* Send a POST request
* @param cluster the cluster definition
* @param path the path or URI
* @param contentType the content MIME type
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response post(Cluster cluster, String path, String contentType,
byte[] content) throws IOException {
Header[] headers = new Header[1];
headers[0] = new Header("Content-Type", contentType);
return post(cluster, path, headers, content);
}
/**
* Send a POST request
* @param path the path or URI
* @param headers the HTTP headers to include, <tt>Content-Type</tt> must be
* supplied
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response post(String path, Header[] headers, byte[] content)
throws IOException {
return post(cluster, path, headers, content);
}
/**
* Send a POST request
* @param cluster the cluster definition
* @param path the path or URI
* @param headers the HTTP headers to include, <tt>Content-Type</tt> must be
* supplied
* @param content the content bytes
* @return a Response object with response detail
* @throws IOException
*/
public Response post(Cluster cluster, String path, Header[] headers,
byte[] content) throws IOException {
PostMethod method = new PostMethod();
method.setRequestEntity(new ByteArrayRequestEntity(content));
int code = execute(cluster, method, headers, path);
headers = method.getResponseHeaders();
content = method.getResponseBody();
method.releaseConnection();
return new Response(code, headers, content);
}
/**
* Send a DELETE request
* @param path the path or URI
* @return a Response object with response detail
* @throws IOException
*/
public Response delete(String path) throws IOException { public Response delete(String path) throws IOException {
return delete(cluster, path); return delete(cluster, path);
} }
public Response delete(Cluster c, String path) throws IOException { /**
* Send a DELETE request
* @param cluster the cluster definition
* @param path the path or URI
* @return a Response object with response detail
* @throws IOException
*/
public Response delete(Cluster cluster, String path) throws IOException {
DeleteMethod method = new DeleteMethod(); DeleteMethod method = new DeleteMethod();
int code = execute(c, method, null, path); int code = execute(cluster, method, null, path);
Header[] headers = method.getResponseHeaders(); Header[] headers = method.getResponseHeaders();
method.releaseConnection(); method.releaseConnection();
return new Response(code, headers); return new Response(code, headers);

View File

@ -24,6 +24,10 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
/**
* A list of 'host:port' addresses of HTTP servers operating as a single
* entity, for example multiple redundant web service gateways.
*/
public class Cluster { public class Cluster {
protected List<String> nodes = protected List<String> nodes =
Collections.synchronizedList(new ArrayList<String>()); Collections.synchronizedList(new ArrayList<String>());

View File

@ -22,6 +22,9 @@ package org.apache.hadoop.hbase.stargate.client;
import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.Header;
/**
* The HTTP result code, response headers, and body of a HTTP response.
*/
public class Response { public class Response {
private int code; private int code;
private Header[] headers; private Header[] headers;

View File

@ -33,34 +33,41 @@ import org.apache.hadoop.hbase.stargate.protobuf.generated.CellMessage.Cell;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
/**
* Representation of a cell. A cell is a single value associated a column and
* optional qualifier, and either the timestamp when it was stored or the user-
* provided timestamp if one was explicitly supplied.
*/
@XmlRootElement(name="Cell") @XmlRootElement(name="Cell")
@XmlType(propOrder={"column","timestamp"}) @XmlType(propOrder={"column","timestamp"})
public class CellModel implements IProtobufWrapper, Serializable { public class CellModel implements IProtobufWrapper, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private long timestamp = HConstants.LATEST_TIMESTAMP; private long timestamp;
private byte[] column; private byte[] column;
private byte[] value; private byte[] value;
/**
* Default constructor
*/
public CellModel() {} public CellModel() {}
/** /**
* Constructor
* @param column * @param column
* @param value * @param value
*/ */
public CellModel(byte[] column, byte[] value) { public CellModel(byte[] column, byte[] value) {
super(); this(column, HConstants.LATEST_TIMESTAMP, value);
this.column = column;
this.value = value;
} }
/** /**
* Constructor
* @param column * @param column
* @param timestamp * @param timestamp
* @param value * @param value
*/ */
public CellModel(byte[] column, long timestamp, byte[] value) { public CellModel(byte[] column, long timestamp, byte[] value) {
super();
this.column = column; this.column = column;
this.timestamp = timestamp; this.timestamp = timestamp;
this.value = value; this.value = value;

View File

@ -34,6 +34,10 @@ import org.apache.hadoop.hbase.stargate.protobuf.generated.CellSetMessage.CellSe
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
/**
* Representation of a grouping of cells. May contain cells from more than
* one row. Encapsulates RowModel and CellModel models.
*/
@XmlRootElement(name="CellSet") @XmlRootElement(name="CellSet")
public class CellSetModel implements Serializable, IProtobufWrapper { public class CellSetModel implements Serializable, IProtobufWrapper {
@ -41,15 +45,16 @@ public class CellSetModel implements Serializable, IProtobufWrapper {
private List<RowModel> rows; private List<RowModel> rows;
/**
* Constructor
*/
public CellSetModel() { public CellSetModel() {
this.rows = new ArrayList<RowModel>(); this.rows = new ArrayList<RowModel>();
} }
/** /**
* @param rows * @param rows the rows
*/ */
public CellSetModel(List<RowModel> rows) { public CellSetModel(List<RowModel> rows) {
super(); super();
this.rows = rows; this.rows = rows;
@ -57,8 +62,7 @@ public class CellSetModel implements Serializable, IProtobufWrapper {
/** /**
* Add a row to this cell set * Add a row to this cell set
* * @param row the row
* @param row
*/ */
public void addRow(RowModel row) { public void addRow(RowModel row) {
rows.add(row); rows.add(row);

View File

@ -33,6 +33,9 @@ import javax.xml.namespace.QName;
import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
/**
* Representation of a column family schema.
*/
@XmlRootElement(name="ColumnSchema") @XmlRootElement(name="ColumnSchema")
@XmlType(propOrder = {"name"}) @XmlType(propOrder = {"name"})
public class ColumnSchemaModel implements Serializable { public class ColumnSchemaModel implements Serializable {
@ -48,14 +51,27 @@ public class ColumnSchemaModel implements Serializable {
private String name; private String name;
private Map<QName,Object> attrs = new HashMap<QName,Object>(); private Map<QName,Object> attrs = new HashMap<QName,Object>();
/**
* Default constructor
*/
public ColumnSchemaModel() {} public ColumnSchemaModel() {}
/**
* Add an attribute to the column family schema
* @param name the attribute name
* @param value the attribute value
*/
public void addAttribute(String name, Object value) { public void addAttribute(String name, Object value) {
attrs.put(new QName(name), value); attrs.put(new QName(name), value);
} }
/**
* @param name the attribute name
* @return the attribute value
*/
public String getAttribute(String name) { public String getAttribute(String name) {
return attrs.get(new QName(name)).toString(); Object o = attrs.get(new QName(name));
return o != null ? o.toString(): null;
} }
/** /**
@ -106,51 +122,78 @@ public class ColumnSchemaModel implements Serializable {
// cannot be standard bean type getters and setters, otherwise this would // cannot be standard bean type getters and setters, otherwise this would
// confuse JAXB // confuse JAXB
/**
* @return true if the BLOCKCACHE attribute is present and true
*/
public boolean __getBlockcache() { public boolean __getBlockcache() {
Object o = attrs.get(BLOCKCACHE); Object o = attrs.get(BLOCKCACHE);
return o != null ? return o != null ?
Boolean.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_BLOCKCACHE; Boolean.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_BLOCKCACHE;
} }
/**
* @return the value of the BLOCKSIZE attribute or its default if it is unset
*/
public int __getBlocksize() { public int __getBlocksize() {
Object o = attrs.get(BLOCKSIZE); Object o = attrs.get(BLOCKSIZE);
return o != null ? return o != null ?
Integer.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_BLOCKSIZE; Integer.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_BLOCKSIZE;
} }
/**
* @return true if the BLOOMFILTER attribute is present and true
*/
public boolean __getBloomfilter() { public boolean __getBloomfilter() {
Object o = attrs.get(BLOOMFILTER); Object o = attrs.get(BLOOMFILTER);
return o != null ? return o != null ?
Boolean.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_BLOOMFILTER; Boolean.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_BLOOMFILTER;
} }
/**
* @return the value of the COMPRESSION attribute or its default if it is unset
*/
public String __getCompression() { public String __getCompression() {
Object o = attrs.get(COMPRESSION); Object o = attrs.get(COMPRESSION);
return o != null ? o.toString() : HColumnDescriptor.DEFAULT_COMPRESSION; return o != null ? o.toString() : HColumnDescriptor.DEFAULT_COMPRESSION;
} }
/**
* @return true if the IN_MEMORY attribute is present and true
*/
public boolean __getInMemory() { public boolean __getInMemory() {
Object o = attrs.get(IN_MEMORY); Object o = attrs.get(IN_MEMORY);
return o != null ? return o != null ?
Boolean.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_IN_MEMORY; Boolean.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_IN_MEMORY;
} }
/**
* @return the value of the TTL attribute or its default if it is unset
*/
public int __getTTL() { public int __getTTL() {
Object o = attrs.get(TTL); Object o = attrs.get(TTL);
return o != null ? return o != null ?
Integer.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_TTL; Integer.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_TTL;
} }
/**
* @return the value of the VERSIONS attribute or its default if it is unset
*/
public int __getVersions() { public int __getVersions() {
Object o = attrs.get(VERSIONS); Object o = attrs.get(VERSIONS);
return o != null ? return o != null ?
Integer.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_VERSIONS; Integer.valueOf(o.toString()) : HColumnDescriptor.DEFAULT_VERSIONS;
} }
/**
* @param value the desired value of the BLOCKSIZE attribute
*/
public void __setBlocksize(int value) { public void __setBlocksize(int value) {
attrs.put(BLOCKSIZE, Integer.toString(value)); attrs.put(BLOCKSIZE, Integer.toString(value));
} }
/**
* @param value the desired value of the BLOCKCACHE attribute
*/
public void __setBlockcache(boolean value) { public void __setBlockcache(boolean value) {
attrs.put(BLOCKCACHE, Boolean.toString(value)); attrs.put(BLOCKCACHE, Boolean.toString(value));
} }
@ -159,18 +202,30 @@ public class ColumnSchemaModel implements Serializable {
attrs.put(BLOOMFILTER, Boolean.toString(value)); attrs.put(BLOOMFILTER, Boolean.toString(value));
} }
/**
* @param value the desired value of the COMPRESSION attribute
*/
public void __setCompression(String value) { public void __setCompression(String value) {
attrs.put(COMPRESSION, value); attrs.put(COMPRESSION, value);
} }
/**
* @param value the desired value of the IN_MEMORY attribute
*/
public void __setInMemory(boolean value) { public void __setInMemory(boolean value) {
attrs.put(IN_MEMORY, Boolean.toString(value)); attrs.put(IN_MEMORY, Boolean.toString(value));
} }
/**
* @param value the desired value of the TTL attribute
*/
public void __setTTL(int value) { public void __setTTL(int value) {
attrs.put(TTL, Integer.toString(value)); attrs.put(TTL, Integer.toString(value));
} }
/**
* @param value the desired value of the VERSIONS attribute
*/
public void __setVersions(int value) { public void __setVersions(int value) {
attrs.put(VERSIONS, Integer.toString(value)); attrs.put(VERSIONS, Integer.toString(value));
} }

View File

@ -22,8 +22,23 @@ package org.apache.hadoop.hbase.stargate.model;
import java.io.IOException; import java.io.IOException;
/**
* Common interface for models capable of supporting protobuf marshalling
* and unmarshalling. Hooks up to the ProtobufMessageBodyConsumer and
* ProtobufMessageBodyProducer adapters.
*/
public abstract interface IProtobufWrapper { public abstract interface IProtobufWrapper {
/**
* @return the protobuf represention of the model
*/
public byte[] createProtobufOutput(); public byte[] createProtobufOutput();
/**
* Initialize the model from a protobuf representation.
* @param message the raw bytes of the protobuf message
* @return reference to self for convenience
* @throws IOException
*/
public IProtobufWrapper getObjectFromMessage(byte[] message) public IProtobufWrapper getObjectFromMessage(byte[] message)
throws IOException; throws IOException;
} }

View File

@ -29,60 +29,69 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
/**
* Representation of a row. A row is a related set of cells, grouped by common
* row key. RowModels do not appear in results by themselves. They are always
* encapsulated within CellSetModels.
*/
@XmlRootElement(name="Row") @XmlRootElement(name="Row")
public class RowModel implements IProtobufWrapper, Serializable { public class RowModel implements IProtobufWrapper, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private byte[] key; private byte[] key;
private List<CellModel> cells = new ArrayList<CellModel>(); private List<CellModel> cells = new ArrayList<CellModel>();
/**
* Default constructor
*/
public RowModel() { } public RowModel() { }
/** /**
* @param key * Constructor
* @param key the row key
*/ */
public RowModel(final String key) { public RowModel(final String key) {
this(key.getBytes()); this(key.getBytes());
} }
/** /**
* @param key * Constructor
* @param key the row key
*/ */
public RowModel(final byte[] key) { public RowModel(final byte[] key) {
super();
this.key = key; this.key = key;
cells = new ArrayList<CellModel>(); cells = new ArrayList<CellModel>();
} }
/** /**
* @param key * Constructor
* @param cells * @param key the row key
* @param cells the cells
*/ */
public RowModel(final String key, final List<CellModel> cells) { public RowModel(final String key, final List<CellModel> cells) {
this(key.getBytes(), cells); this(key.getBytes(), cells);
} }
/** /**
* @param key * Constructor
* @param cells * @param key the row key
* @param cells the cells
*/ */
public RowModel(final byte[] key, final List<CellModel> cells) { public RowModel(final byte[] key, final List<CellModel> cells) {
super();
this.key = key; this.key = key;
this.cells = cells; this.cells = cells;
} }
/** /**
* Adds a cell to the list of cells for this row * Adds a cell to the list of cells for this row
* * @param cell the cell
* @param cell
*/ */
public void addCell(CellModel cell) { public void addCell(CellModel cell) {
cells.add(cell); cells.add(cell);
} }
/** /**
* @return the key * @return the row key
*/ */
@XmlAttribute @XmlAttribute
public byte[] getKey() { public byte[] getKey() {
@ -90,7 +99,7 @@ public class RowModel implements IProtobufWrapper, Serializable {
} }
/** /**
* @param key the key to set * @param key the row key
*/ */
public void setKey(byte[] key) { public void setKey(byte[] key) {
this.key = key; this.key = key;
@ -118,5 +127,4 @@ public class RowModel implements IProtobufWrapper, Serializable {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"no protobuf equivalent to RowModel"); "no protobuf equivalent to RowModel");
} }
} }

View File

@ -34,6 +34,9 @@ import org.apache.hadoop.hbase.util.Bytes;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
/**
* A representation of Scanner parameters.
*/
@XmlRootElement(name="Scanner") @XmlRootElement(name="Scanner")
public class ScannerModel implements IProtobufWrapper, Serializable { public class ScannerModel implements IProtobufWrapper, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -45,8 +48,20 @@ public class ScannerModel implements IProtobufWrapper, Serializable {
private long startTime = 0; private long startTime = 0;
private long endTime = Long.MAX_VALUE; private long endTime = Long.MAX_VALUE;
/**
* Default constructor
*/
public ScannerModel() {} public ScannerModel() {}
/**
* Constructor
* @param startRow the start key of the row-range
* @param endRow the end key of the row-range
* @param columns the columns to scan
* @param batch the number of values to return in batch
* @param endTime the upper bound on timestamps of values of interest
* (values with timestamps later than this are excluded)
*/
public ScannerModel(byte[] startRow, byte[] endRow, List<byte[]> columns, public ScannerModel(byte[] startRow, byte[] endRow, List<byte[]> columns,
int batch, long endTime) { int batch, long endTime) {
super(); super();
@ -57,6 +72,17 @@ public class ScannerModel implements IProtobufWrapper, Serializable {
this.endTime = endTime; this.endTime = endTime;
} }
/**
* Constructor
* @param startRow the start key of the row-range
* @param endRow the end key of the row-range
* @param columns the columns to scan
* @param batch the number of values to return in batch
* @param startTime the lower bound on timestamps of values of interest
* (values with timestamps earlier than this are excluded)
* @param endTime the upper bound on timestamps of values of interest
* (values with timestamps later than this are excluded)
*/
public ScannerModel(byte[] startRow, byte[] endRow, List<byte[]> columns, public ScannerModel(byte[] startRow, byte[] endRow, List<byte[]> columns,
int batch, long startTime, long endTime) { int batch, long startTime, long endTime) {
super(); super();
@ -68,6 +94,10 @@ public class ScannerModel implements IProtobufWrapper, Serializable {
this.endTime = endTime; this.endTime = endTime;
} }
/**
* Add a column to the column set
* @param column the column name, as &lt;column&gt;(:&lt;qualifier&gt;)?
*/
public void addColumn(byte[] column) { public void addColumn(byte[] column) {
columns.add(column); columns.add(column);
} }
@ -156,14 +186,14 @@ public class ScannerModel implements IProtobufWrapper, Serializable {
} }
/** /**
* @param startTime the lower bound on timestamps of items of interest * @param startTime the lower bound on timestamps of values of interest
*/ */
public void setStartTime(long startTime) { public void setStartTime(long startTime) {
this.startTime = startTime; this.startTime = startTime;
} }
/** /**
* @param endTime the upper bound on timestamps of items of interest * @param endTime the upper bound on timestamps of values of interest
*/ */
public void setEndTime(long endTime) { public void setEndTime(long endTime) {
this.endTime = endTime; this.endTime = endTime;

View File

@ -35,27 +35,58 @@ import org.apache.hadoop.hbase.util.Bytes;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
/**
* Representation of the status of a storage cluster:
* <p>
* <ul>
* <li>regions: the total number of regions served by the cluster</li>
* <li>requests: the total number of requests per second handled by the
* cluster in the last reporting interval</li>
* <li>averageLoad: the average load of the region servers in the cluster</li>
* <li>liveNodes: detailed status of the live region servers</li>
* <li>deadNodes: the names of region servers declared dead</li>
* </ul>
*/
@XmlRootElement(name="ClusterStatus") @XmlRootElement(name="ClusterStatus")
public class StorageClusterStatusModel public class StorageClusterStatusModel
implements Serializable, IProtobufWrapper { implements Serializable, IProtobufWrapper {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* Represents a region server.
*/
public static class Node { public static class Node {
/**
* Represents a region hosted on a region server.
*/
public static class Region { public static class Region {
private byte[] name; private byte[] name;
/**
* Default constructor
*/
public Region() {} public Region() {}
/**
* Constructor
* @param name the region name
*/
public Region(byte[] name) { public Region(byte[] name) {
this.name = name; this.name = name;
} }
/**
* @return the region name
*/
@XmlAttribute @XmlAttribute
public byte[] getName() { public byte[] getName() {
return name; return name;
} }
/**
* @param name the region name
*/
public void setName(byte[] name) { public void setName(byte[] name) {
this.name = name; this.name = name;
} }
@ -66,53 +97,94 @@ public class StorageClusterStatusModel
private int requests; private int requests;
private List<Region> regions = new ArrayList<Region>(); private List<Region> regions = new ArrayList<Region>();
/**
* Add a region name to the list
* @param name the region name
*/
public void addRegion(byte[] name) { public void addRegion(byte[] name) {
regions.add(new Region(name)); regions.add(new Region(name));
} }
public Region getRegion(int i) { /**
return regions.get(i); * @param index the index
* @return the region name
*/
public Region getRegion(int index) {
return regions.get(index);
} }
/**
* Default constructor
*/
public Node() {} public Node() {}
/**
* Constructor
* @param name the region server name
* @param startCode the region server's start code
*/
public Node(String name, long startCode) { public Node(String name, long startCode) {
this.name = name; this.name = name;
this.startCode = startCode; this.startCode = startCode;
} }
/**
* @return the region server's name
*/
@XmlAttribute @XmlAttribute
public String getName() { public String getName() {
return name; return name;
} }
/**
* @return the region server's start code
*/
@XmlAttribute @XmlAttribute
public long getStartCode() { public long getStartCode() {
return startCode; return startCode;
} }
/**
* @return the list of regions served by the region server
*/
@XmlElement(name="Region") @XmlElement(name="Region")
public List<Region> getRegions() { public List<Region> getRegions() {
return regions; return regions;
} }
/**
* @return the number of requests per second processed by the region server
*/
@XmlAttribute @XmlAttribute
public int getRequests() { public int getRequests() {
return requests; return requests;
} }
/**
* @param name the region server's hostname
*/
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
/**
* @param startCode the region server's start code
*/
public void setStartCode(long startCode) { public void setStartCode(long startCode) {
this.startCode = startCode; this.startCode = startCode;
} }
/**
* @param regions a list of regions served by the region server
*/
public void setRegions(List<Region> regions) { public void setRegions(List<Region> regions) {
this.regions = regions; this.regions = regions;
} }
/**
* @param requests the number of requests per second processed by the
* region server
*/
public void setRequests(int requests) { public void setRequests(int requests) {
this.requests = requests; this.requests = requests;
} }
@ -124,69 +196,121 @@ public class StorageClusterStatusModel
private int requests; private int requests;
private double averageLoad; private double averageLoad;
/**
* Add a live node to the cluster representation.
* @param name the region server name
* @param startCode the region server's start code
*/
public Node addLiveNode(String name, long startCode) { public Node addLiveNode(String name, long startCode) {
Node node = new Node(name, startCode); Node node = new Node(name, startCode);
liveNodes.add(node); liveNodes.add(node);
return node; return node;
} }
public Node getLiveNode(int i) { /**
return liveNodes.get(i); * @param index the index
* @return the region server model
*/
public Node getLiveNode(int index) {
return liveNodes.get(index);
} }
/**
* Add a dead node to the cluster representation.
* @param node the dead region server's name
*/
public void addDeadNode(String node) { public void addDeadNode(String node) {
deadNodes.add(node); deadNodes.add(node);
} }
public String getDeadNode(int i) { /**
return deadNodes.get(i); * @param index the index
* @return the dead region server's name
*/
public String getDeadNode(int index) {
return deadNodes.get(index);
} }
/**
* Default constructor
*/
public StorageClusterStatusModel() {} public StorageClusterStatusModel() {}
/**
* @return the list of live nodes
*/
@XmlElement(name="Node") @XmlElement(name="Node")
@XmlElementWrapper(name="LiveNodes") @XmlElementWrapper(name="LiveNodes")
public List<Node> getLiveNodes() { public List<Node> getLiveNodes() {
return liveNodes; return liveNodes;
} }
/**
* @return the list of dead nodes
*/
@XmlElement(name="Node") @XmlElement(name="Node")
@XmlElementWrapper(name="DeadNodes") @XmlElementWrapper(name="DeadNodes")
public List<String> getDeadNodes() { public List<String> getDeadNodes() {
return deadNodes; return deadNodes;
} }
/**
* @return the total number of regions served by the cluster
*/
@XmlAttribute @XmlAttribute
public int getRegions() { public int getRegions() {
return regions; return regions;
} }
/**
* @return the total number of requests per second handled by the cluster in
* the last reporting interval
*/
@XmlAttribute @XmlAttribute
public int getRequests() { public int getRequests() {
return requests; return requests;
} }
/**
* @return the average load of the region servers in the cluster
*/
@XmlAttribute @XmlAttribute
public double getAverageLoad() { public double getAverageLoad() {
return averageLoad; return averageLoad;
} }
/**
* @param nodes the list of live node models
*/
public void setLiveNodes(List<Node> nodes) { public void setLiveNodes(List<Node> nodes) {
this.liveNodes = nodes; this.liveNodes = nodes;
} }
/**
* @param nodes the list of dead node names
*/
public void setDeadNodes(List<String> nodes) { public void setDeadNodes(List<String> nodes) {
this.deadNodes = nodes; this.deadNodes = nodes;
} }
/**
* @param regions the total number of regions served by the cluster
*/
public void setRegions(int regions) { public void setRegions(int regions) {
this.regions = regions; this.regions = regions;
} }
/**
* @param requests the total number of requests per second handled by the
* cluster
*/
public void setRequests(int requests) { public void setRequests(int requests) {
this.requests = requests; this.requests = requests;
} }
/**
* @param averageLoad the average load of region servers in the cluster
*/
public void setAverageLoad(double averageLoad) { public void setAverageLoad(double averageLoad) {
this.averageLoad = averageLoad; this.averageLoad = averageLoad;
} }

View File

@ -25,17 +25,26 @@ import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue; import javax.xml.bind.annotation.XmlValue;
/**
* Simple representation of the version of the storage cluster (HBase)
*/
@XmlRootElement(name="ClusterVersion") @XmlRootElement(name="ClusterVersion")
public class StorageClusterVersionModel implements Serializable { public class StorageClusterVersionModel implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String version; private String version;
/**
* @return the storage cluster version
*/
@XmlValue @XmlValue
public String getVersion() { public String getVersion() {
return version; return version;
} }
/**
* @param version the storage cluster version
*/
public void setVersion(String version) { public void setVersion(String version) {
this.version = version; this.version = version;
} }

View File

@ -34,6 +34,9 @@ import org.apache.hadoop.hbase.stargate.protobuf.generated.TableInfoMessage.Tabl
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
/**
* Representation of a list of table regions.
*/
@XmlRootElement(name="TableInfo") @XmlRootElement(name="TableInfo")
@XmlType(propOrder = {"name","regions"}) @XmlType(propOrder = {"name","regions"})
public class TableInfoModel implements Serializable, IProtobufWrapper { public class TableInfoModel implements Serializable, IProtobufWrapper {
@ -42,16 +45,31 @@ public class TableInfoModel implements Serializable, IProtobufWrapper {
private String name; private String name;
private List<TableRegionModel> regions = new ArrayList<TableRegionModel>(); private List<TableRegionModel> regions = new ArrayList<TableRegionModel>();
/**
* Default constructor
*/
public TableInfoModel() {} public TableInfoModel() {}
/**
* Constructor
* @param name
*/
public TableInfoModel(String name) { public TableInfoModel(String name) {
this.name = name; this.name = name;
} }
public void add(TableRegionModel object) { /**
regions.add(object); * Add a region model to the list
* @param region the region
*/
public void add(TableRegionModel region) {
regions.add(region);
} }
/**
* @param index the index
* @return the region model
*/
public TableRegionModel get(int index) { public TableRegionModel get(int index) {
return regions.get(index); return regions.get(index);
} }

View File

@ -30,6 +30,9 @@ import javax.xml.bind.annotation.XmlRootElement;
import org.apache.hadoop.hbase.stargate.protobuf.generated.TableListMessage.TableList; import org.apache.hadoop.hbase.stargate.protobuf.generated.TableListMessage.TableList;
/**
* Simple representation of a list of table names.
*/
@XmlRootElement(name="TableList") @XmlRootElement(name="TableList")
public class TableListModel implements Serializable, IProtobufWrapper { public class TableListModel implements Serializable, IProtobufWrapper {
@ -37,12 +40,23 @@ public class TableListModel implements Serializable, IProtobufWrapper {
private List<TableModel> tables = new ArrayList<TableModel>(); private List<TableModel> tables = new ArrayList<TableModel>();
/**
* Default constructor
*/
public TableListModel() {} public TableListModel() {}
public void add(TableModel object) { /**
tables.add(object); * Add the table name model to the list
* @param table the table model
*/
public void add(TableModel table) {
tables.add(table);
} }
/**
* @param index the index
* @return the table model
*/
public TableModel get(int index) { public TableModel get(int index) {
return tables.get(index); return tables.get(index);
} }

View File

@ -25,6 +25,9 @@ import java.io.Serializable;
import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
/**
* Simple representation of a table name.
*/
@XmlRootElement(name="table") @XmlRootElement(name="table")
public class TableModel implements Serializable { public class TableModel implements Serializable {
@ -32,9 +35,13 @@ public class TableModel implements Serializable {
private String name; private String name;
/**
* Default constructor
*/
public TableModel() {} public TableModel() {}
/** /**
* Constructor
* @param name * @param name
*/ */
public TableModel(String name) { public TableModel(String name) {

View File

@ -28,6 +28,10 @@ import javax.xml.bind.annotation.XmlType;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
/**
* Representation of a region of a table and its current location on the
* storage cluster.
*/
@XmlRootElement(name="Region") @XmlRootElement(name="Region")
@XmlType(propOrder = {"name","id","startKey","endKey","location"}) @XmlType(propOrder = {"name","id","startKey","endKey","location"})
public class TableRegionModel implements Serializable { public class TableRegionModel implements Serializable {

View File

@ -41,6 +41,9 @@ import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.stargate.protobuf.generated.ColumnSchemaMessage.ColumnSchema; import org.apache.hadoop.hbase.stargate.protobuf.generated.ColumnSchemaMessage.ColumnSchema;
import org.apache.hadoop.hbase.stargate.protobuf.generated.TableSchemaMessage.TableSchema; import org.apache.hadoop.hbase.stargate.protobuf.generated.TableSchemaMessage.TableSchema;
/**
* A representation of HBase table descriptors.
*/
@XmlRootElement(name="TableSchema") @XmlRootElement(name="TableSchema")
@XmlType(propOrder = {"name","columns"}) @XmlType(propOrder = {"name","columns"})
public class TableSchemaModel implements Serializable, IProtobufWrapper { public class TableSchemaModel implements Serializable, IProtobufWrapper {
@ -58,20 +61,44 @@ public class TableSchemaModel implements Serializable, IProtobufWrapper {
private Map<QName,Object> attrs = new HashMap<QName,Object>(); private Map<QName,Object> attrs = new HashMap<QName,Object>();
private List<ColumnSchemaModel> columns = new ArrayList<ColumnSchemaModel>(); private List<ColumnSchemaModel> columns = new ArrayList<ColumnSchemaModel>();
/**
* Default constructor.
*/
public TableSchemaModel() {} public TableSchemaModel() {}
/**
* Add an attribute to the table descriptor
* @param name attribute name
* @param value attribute value
*/
public void addAttribute(String name, Object value) { public void addAttribute(String name, Object value) {
attrs.put(new QName(name), value); attrs.put(new QName(name), value);
} }
/**
* Return a table descriptor value as a string. Calls toString() on the
* object stored in the descriptor value map.
* @param name the attribute name
* @return the attribute value
*/
public String getAttribute(String name) { public String getAttribute(String name) {
return attrs.get(new QName(name)).toString(); Object o = attrs.get(new QName(name));
return o != null ? o.toString() : null;
} }
public void addColumnFamily(ColumnSchemaModel object) { /**
columns.add(object); * Add a column family to the table descriptor
* @param object the column family model
*/
public void addColumnFamily(ColumnSchemaModel family) {
columns.add(family);
} }
/**
* Retrieve the column family at the given index from the table descriptor
* @param index the index
* @return the column family model
*/
public ColumnSchemaModel getColumnFamily(int index) { public ColumnSchemaModel getColumnFamily(int index) {
return columns.get(index); return columns.get(index);
} }
@ -149,40 +176,64 @@ public class TableSchemaModel implements Serializable, IProtobufWrapper {
// cannot be standard bean type getters and setters, otherwise this would // cannot be standard bean type getters and setters, otherwise this would
// confuse JAXB // confuse JAXB
/**
* @return true if IN_MEMORY attribute exists and is true
*/
public boolean __getInMemory() { public boolean __getInMemory() {
Object o = attrs.get(IN_MEMORY); Object o = attrs.get(IN_MEMORY);
return o != null ? return o != null ?
Boolean.valueOf(o.toString()) : HTableDescriptor.DEFAULT_IN_MEMORY; Boolean.valueOf(o.toString()) : HTableDescriptor.DEFAULT_IN_MEMORY;
} }
/**
* @return true if IS_META attribute exists and is truel
*/
public boolean __getIsMeta() { public boolean __getIsMeta() {
Object o = attrs.get(IS_META); Object o = attrs.get(IS_META);
return o != null ? Boolean.valueOf(o.toString()) : false; return o != null ? Boolean.valueOf(o.toString()) : false;
} }
/**
* @return true if IS_ROOT attribute exists and is truel
*/
public boolean __getIsRoot() { public boolean __getIsRoot() {
Object o = attrs.get(IS_ROOT); Object o = attrs.get(IS_ROOT);
return o != null ? Boolean.valueOf(o.toString()) : false; return o != null ? Boolean.valueOf(o.toString()) : false;
} }
/**
* @return true if READONLY attribute exists and is truel
*/
public boolean __getReadOnly() { public boolean __getReadOnly() {
Object o = attrs.get(READONLY); Object o = attrs.get(READONLY);
return o != null ? return o != null ?
Boolean.valueOf(o.toString()) : HTableDescriptor.DEFAULT_READONLY; Boolean.valueOf(o.toString()) : HTableDescriptor.DEFAULT_READONLY;
} }
/**
* @param value desired value of IN_MEMORY attribute
*/
public void __setInMemory(boolean value) { public void __setInMemory(boolean value) {
attrs.put(IN_MEMORY, Boolean.toString(value)); attrs.put(IN_MEMORY, Boolean.toString(value));
} }
/**
* @param value desired value of IS_META attribute
*/
public void __setIsMeta(boolean value) { public void __setIsMeta(boolean value) {
attrs.put(IS_META, Boolean.toString(value)); attrs.put(IS_META, Boolean.toString(value));
} }
/**
* @param value desired value of IS_ROOT attribute
*/
public void __setIsRoot(boolean value) { public void __setIsRoot(boolean value) {
attrs.put(IS_ROOT, Boolean.toString(value)); attrs.put(IS_ROOT, Boolean.toString(value));
} }
/**
* @param value desired value of READONLY attribute
*/
public void __setReadOnly(boolean value) { public void __setReadOnly(boolean value) {
attrs.put(READONLY, Boolean.toString(value)); attrs.put(READONLY, Boolean.toString(value));
} }

View File

@ -32,6 +32,17 @@ import org.apache.hadoop.hbase.stargate.protobuf.generated.VersionMessage.Versio
import com.sun.jersey.spi.container.servlet.ServletContainer; import com.sun.jersey.spi.container.servlet.ServletContainer;
/**
* A representation of the collection of versions of the Stargate software
* components.
* <ul>
* <li>stargateVersion: Stargate revision</li>
* <li>jvmVersion: the JVM vendor and version information</li>
* <li>osVersion: the OS type, version, and hardware architecture</li>
* <li>serverVersion: the name and version of the servlet container</li>
* <li>jerseyVersion: the version of the embedded Jersey framework</li>
* </ul>
*/
@XmlRootElement(name="Version") @XmlRootElement(name="Version")
public class VersionModel implements Serializable, IProtobufWrapper { public class VersionModel implements Serializable, IProtobufWrapper {
@ -43,8 +54,15 @@ public class VersionModel implements Serializable, IProtobufWrapper {
private String serverVersion; private String serverVersion;
private String jerseyVersion; private String jerseyVersion;
/**
* Default constructor. Do not use.
*/
public VersionModel() {} public VersionModel() {}
/**
* Constructor
* @param context the servlet context
*/
public VersionModel(ServletContext context) { public VersionModel(ServletContext context) {
stargateVersion = RESTServlet.VERSION_STRING; stargateVersion = RESTServlet.VERSION_STRING;
jvmVersion = System.getProperty("java.vm.vendor") + ' ' + jvmVersion = System.getProperty("java.vm.vendor") + ' ' +
@ -58,47 +76,77 @@ public class VersionModel implements Serializable, IProtobufWrapper {
.getImplementationVersion(); .getImplementationVersion();
} }
/**
* @return the Stargate version
*/
@XmlAttribute(name="Stargate") @XmlAttribute(name="Stargate")
public String getStargateVersion() { public String getStargateVersion() {
return stargateVersion; return stargateVersion;
} }
/**
* @return the JVM vendor and version
*/
@XmlAttribute(name="JVM") @XmlAttribute(name="JVM")
public String getJvmVersion() { public String getJvmVersion() {
return jvmVersion; return jvmVersion;
} }
/**
* @return the OS name, version, and hardware architecture
*/
@XmlAttribute(name="OS") @XmlAttribute(name="OS")
public String getOsVersion() { public String getOsVersion() {
return osVersion; return osVersion;
} }
/**
* @return the servlet container version
*/
@XmlAttribute(name="Server") @XmlAttribute(name="Server")
public String getServerVersion() { public String getServerVersion() {
return serverVersion; return serverVersion;
} }
/**
* @return the version of the embedded Jersey framework
*/
@XmlAttribute(name="Jersey") @XmlAttribute(name="Jersey")
public String getJerseyVersion() { public String getJerseyVersion() {
return jerseyVersion; return jerseyVersion;
} }
/**
* @param version the Stargate version string
*/
public void setStargateVersion(String version) { public void setStargateVersion(String version) {
this.stargateVersion = version; this.stargateVersion = version;
} }
/**
* @param version the OS version string
*/
public void setOsVersion(String version) { public void setOsVersion(String version) {
this.osVersion = version; this.osVersion = version;
} }
/**
* @param version the JVM version string
*/
public void setJvmVersion(String version) { public void setJvmVersion(String version) {
this.jvmVersion = version; this.jvmVersion = version;
} }
/**
* @param version the servlet container version string
*/
public void setServerVersion(String version) { public void setServerVersion(String version) {
this.serverVersion = version; this.serverVersion = version;
} }
/**
* @param version the Jersey framework version string
*/
public void setJerseyVersion(String version) { public void setJerseyVersion(String version) {
this.jerseyVersion = version; this.jerseyVersion = version;
} }

View File

@ -45,6 +45,12 @@ import org.apache.hadoop.hbase.stargate.model.VersionModel;
import com.sun.jersey.api.json.JSONConfiguration; import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.api.json.JSONJAXBContext; import com.sun.jersey.api.json.JSONJAXBContext;
/**
* Plumbing for hooking up Jersey's JSON entity body encoding and decoding
* support to JAXB. Modify how the context is created (by using e.g. a
* different configuration builder) to control how JSON is processed and
* created.
*/
@Provider @Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> { public class JAXBContextResolver implements ContextResolver<JAXBContext> {
@ -72,7 +78,7 @@ public class JAXBContextResolver implements ContextResolver<JAXBContext> {
public JAXBContextResolver() throws Exception { public JAXBContextResolver() throws Exception {
this.types = new HashSet(Arrays.asList(cTypes)); this.types = new HashSet(Arrays.asList(cTypes));
this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), this.context = new JSONJAXBContext(JSONConfiguration.natural().build(),
cTypes); cTypes);
} }
@Override @Override

View File

@ -38,9 +38,14 @@ import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.stargate.Constants; import org.apache.hadoop.hbase.stargate.Constants;
import org.apache.hadoop.hbase.stargate.model.IProtobufWrapper; import org.apache.hadoop.hbase.stargate.model.IProtobufWrapper;
/**
* Adapter for hooking up Jersey content processing dispatch to
* IProtobufWrapper interface capable handlers for decoding protobuf input.
*/
@Provider @Provider
@Consumes(Constants.MIMETYPE_PROTOBUF) @Consumes(Constants.MIMETYPE_PROTOBUF)
public class ProtobufMessageBodyConsumer implements MessageBodyReader<IProtobufWrapper> { public class ProtobufMessageBodyConsumer
implements MessageBodyReader<IProtobufWrapper> {
private static final Log LOG = private static final Log LOG =
LogFactory.getLog(ProtobufMessageBodyConsumer.class); LogFactory.getLog(ProtobufMessageBodyConsumer.class);
@ -79,5 +84,4 @@ public class ProtobufMessageBodyConsumer implements MessageBodyReader<IProtobufW
} }
return obj; return obj;
} }
} }

View File

@ -38,35 +38,43 @@ import javax.ws.rs.ext.Provider;
import org.apache.hadoop.hbase.stargate.Constants; import org.apache.hadoop.hbase.stargate.Constants;
import org.apache.hadoop.hbase.stargate.model.IProtobufWrapper; import org.apache.hadoop.hbase.stargate.model.IProtobufWrapper;
/**
* An adapter between Jersey and IProtobufWrapper implementors. Hooks up
* protobuf output producing methods to the Jersey content handling framework.
* Jersey will first call getSize() to learn the number of bytes that will be
* sent, then writeTo to perform the actual I/O.
*/
@Provider @Provider
@Produces(Constants.MIMETYPE_PROTOBUF) @Produces(Constants.MIMETYPE_PROTOBUF)
public class ProtobufMessageBodyProducer implements MessageBodyWriter<IProtobufWrapper> { public class ProtobufMessageBodyProducer
implements MessageBodyWriter<IProtobufWrapper> {
private Map<Object, byte[]> buffer = new WeakHashMap<Object, byte[]>();
@Override @Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { public boolean isWriteable(Class<?> type, Type genericType,
return IProtobufWrapper.class.isAssignableFrom(type); Annotation[] annotations, MediaType mediaType) {
} return IProtobufWrapper.class.isAssignableFrom(type);
}
private Map<Object, byte[]> buffer = new WeakHashMap<Object, byte[]>();
@Override
public long getSize(IProtobufWrapper m, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(m.createProtobufOutput());
} catch (IOException e) {
return -1;
}
byte[] bytes = baos.toByteArray();
buffer.put(m, bytes);
return bytes.length;
}
public void writeTo(IProtobufWrapper m, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException {
entityStream.write(buffer.remove(m));
}
@Override
public long getSize(IProtobufWrapper m, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(m.createProtobufOutput());
} catch (IOException e) {
return -1;
}
byte[] bytes = baos.toByteArray();
buffer.put(m, bytes);
return bytes.length;
}
public void writeTo(IProtobufWrapper m, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
entityStream.write(buffer.remove(m));
}
} }

View File

@ -33,6 +33,9 @@ import org.apache.hadoop.hbase.stargate.client.Cluster;
import org.apache.hadoop.hbase.stargate.client.Response; import org.apache.hadoop.hbase.stargate.client.Response;
import org.apache.hadoop.hbase.stargate.model.StorageClusterVersionModel; import org.apache.hadoop.hbase.stargate.model.StorageClusterVersionModel;
import org.apache.hadoop.hbase.stargate.model.VersionModel; import org.apache.hadoop.hbase.stargate.model.VersionModel;
import org.apache.hadoop.hbase.util.Bytes;
import com.sun.jersey.spi.container.servlet.ServletContainer;
public class TestVersionResource extends MiniClusterTestCase { public class TestVersionResource extends MiniClusterTestCase {
private static final Log LOG = private static final Log LOG =
@ -63,15 +66,38 @@ public class TestVersionResource extends MiniClusterTestCase {
private static void validate(VersionModel model) { private static void validate(VersionModel model) {
assertNotNull(model); assertNotNull(model);
assertNotNull(model.getStargateVersion()); assertNotNull(model.getStargateVersion());
assertNotNull(model.getOsVersion()); assertEquals(model.getStargateVersion(), RESTServlet.VERSION_STRING);
assertNotNull(model.getJvmVersion()); String osVersion = model.getOsVersion();
assertNotNull(osVersion);
assertTrue(osVersion.contains(System.getProperty("os.name")));
assertTrue(osVersion.contains(System.getProperty("os.version")));
assertTrue(osVersion.contains(System.getProperty("os.arch")));
String jvmVersion = model.getJvmVersion();
assertNotNull(jvmVersion);
assertTrue(jvmVersion.contains(System.getProperty("java.vm.vendor")));
assertTrue(jvmVersion.contains(System.getProperty("java.version")));
assertTrue(jvmVersion.contains(System.getProperty("java.vm.version")));
assertNotNull(model.getServerVersion()); assertNotNull(model.getServerVersion());
assertNotNull(model.getJerseyVersion()); String jerseyVersion = model.getJerseyVersion();
assertNotNull(jerseyVersion);
assertEquals(jerseyVersion, ServletContainer.class.getPackage()
.getImplementationVersion());
} }
public void testGetStargateVersionText() throws IOException { public void testGetStargateVersionText() throws IOException {
Response response = client.get(Constants.PATH_VERSION, MIMETYPE_PLAIN); Response response = client.get(Constants.PATH_VERSION, MIMETYPE_PLAIN);
assertTrue(response.getCode() == 200); assertTrue(response.getCode() == 200);
String body = Bytes.toString(response.getBody());
assertTrue(body.length() > 0);
assertTrue(body.contains(RESTServlet.VERSION_STRING));
assertTrue(body.contains(System.getProperty("java.vm.vendor")));
assertTrue(body.contains(System.getProperty("java.version")));
assertTrue(body.contains(System.getProperty("java.vm.version")));
assertTrue(body.contains(System.getProperty("os.name")));
assertTrue(body.contains(System.getProperty("os.version")));
assertTrue(body.contains(System.getProperty("os.arch")));
assertTrue(body.contains(ServletContainer.class.getPackage()
.getImplementationVersion()));
} }
public void testGetStargateVersionXML() throws IOException, JAXBException { public void testGetStargateVersionXML() throws IOException, JAXBException {