Return-Path: Delivered-To: apmail-hbase-commits-archive@www.apache.org Received: (qmail 81994 invoked from network); 10 Nov 2010 18:13:13 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 10 Nov 2010 18:13:13 -0000 Received: (qmail 86440 invoked by uid 500); 10 Nov 2010 18:13:44 -0000 Delivered-To: apmail-hbase-commits-archive@hbase.apache.org Received: (qmail 86384 invoked by uid 500); 10 Nov 2010 18:13:44 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 86377 invoked by uid 99); 10 Nov 2010 18:13:44 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Nov 2010 18:13:44 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Nov 2010 18:13:39 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 64D8823889EB; Wed, 10 Nov 2010 18:12:24 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1033626 - in /hbase/trunk: ./ src/main/java/org/apache/hadoop/hbase/rest/ src/main/resources/ src/test/java/org/apache/hadoop/hbase/rest/ Date: Wed, 10 Nov 2010 18:12:24 -0000 To: commits@hbase.apache.org From: stack@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101110181224.64D8823889EB@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: stack Date: Wed Nov 10 18:12:23 2010 New Revision: 1033626 URL: http://svn.apache.org/viewvc?rev=1033626&view=rev Log: HBASE-3161 Provide option for Stargate to only serve GET requests Modified: hbase/trunk/CHANGES.txt hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Constants.java hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Main.java hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RESTServlet.java hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerInstanceResource.java hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerResource.java hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/SchemaResource.java hbase/trunk/src/main/resources/hbase-default.xml hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestRowResource.java hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestScannerResource.java hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestSchemaResource.java Modified: hbase/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/CHANGES.txt (original) +++ hbase/trunk/CHANGES.txt Wed Nov 10 18:12:23 2010 @@ -1141,6 +1141,8 @@ Release 0.90.0 - Unreleased HBASE-3168 Sanity date and time check when a region server joins the cluster (Jeff Whiting and jgray) HBASE-3090 Don't include hbase-default in conf/ assembly + HBASE-3161 Provide option for Stargate to only serve GET requests + (Bennett Neale via Stack) NEW FEATURES Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Constants.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Constants.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Constants.java (original) +++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Constants.java Wed Nov 10 18:12:23 2010 @@ -28,6 +28,8 @@ public interface Constants { public static final int DEFAULT_MAX_AGE = 60 * 60 * 4; // 4 hours + public static final int DEFAULT_LISTEN_PORT = 8080; + public static final String MIMETYPE_TEXT = "text/plain"; public static final String MIMETYPE_HTML = "text/html"; public static final String MIMETYPE_XML = "text/xml"; Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Main.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Main.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Main.java (original) +++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/Main.java Wed Nov 10 18:12:23 2010 @@ -21,18 +21,18 @@ package org.apache.hadoop.hbase.rest; import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.PosixParser; +import org.apache.commons.cli.ParseException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; -import java.util.Arrays; import java.util.List; +import java.util.ArrayList; import org.mortbay.jetty.Server; import org.mortbay.jetty.servlet.Context; @@ -42,54 +42,79 @@ import com.sun.jersey.spi.container.serv /** * Main class for launching REST gateway as a servlet hosted by Jetty. - *

+ *

* The following options are supported: *

    - *
  • -p: service port
  • + *
  • -p --port : service port
  • + *
  • -ro --readonly : server mode
  • *
*/ public class Main implements Constants { - private static final String DEFAULT_LISTEN_PORT = "8080"; private static void printUsageAndExit(Options options, int exitCode) { HelpFormatter formatter = new HelpFormatter(); - formatter.printHelp("REST", null, options, - "To start the REST server run 'bin/hbase-daemon.sh start rest'\n" + - "To shutdown the REST server run 'bin/hbase-daemon.sh stop rest' or" + - " send a kill signal to the rest server pid", - true); + formatter.printHelp("bin/hbase rest start", "", options, + "\nTo run the REST server as a daemon, execute " + + "bin/hbase-daemon.sh start|stop rest [-p ] [-ro]\n", true); System.exit(exitCode); } + /** + * The main method for the HBase rest server. + * @param args command-line arguments + * @throws Exception exception + */ public static void main(String[] args) throws Exception { Log LOG = LogFactory.getLog("RESTServer"); + + Configuration conf = HBaseConfiguration.create(); + RESTServlet servlet = RESTServlet.getInstance(conf); + Options options = new Options(); options.addOption("p", "port", true, "Port to bind to [default:" + DEFAULT_LISTEN_PORT + "]"); - CommandLineParser parser = new PosixParser(); - CommandLine cmd = parser.parse(options, args); - /** - * This is so complicated to please both bin/hbase and bin/hbase-daemon. - * hbase-daemon provides "start" and "stop" arguments - * hbase should print the help if no argument is provided - */ - List commandLine = Arrays.asList(args); - boolean stop = commandLine.contains("stop"); - boolean start = commandLine.contains("start"); - if (cmd.hasOption("help") || !start || stop) { - printUsageAndExit(options, 1); - } - // Get port to bind to - int port = 0; + options.addOption("ro", "readonly", false, "Respond only to GET HTTP " + + "method requests [default: false]"); + + CommandLine commandLine = null; try { - port = Integer.parseInt(cmd.getOptionValue("port", DEFAULT_LISTEN_PORT)); - } catch (NumberFormatException e) { - LOG.error("Could not parse the value provided for the port option", e); + commandLine = new PosixParser().parse(options, args); + } catch (ParseException e) { + LOG.error("Could not parse: ", e); printUsageAndExit(options, -1); } - // set up the Jersey servlet container for Jetty + // check for user-defined port setting, if so override the conf + if (commandLine != null && commandLine.hasOption("port")) { + String val = commandLine.getOptionValue("port"); + servlet.getConfiguration() + .setInt("hbase.rest.port", Integer.valueOf(val)); + LOG.debug("port set to " + val); + } + + // check if server should only process GET requests, if so override the conf + if (commandLine != null && commandLine.hasOption("readonly")) { + servlet.getConfiguration().setBoolean("hbase.rest.readonly", true); + LOG.debug("readonly set to true"); + } + + @SuppressWarnings("unchecked") + List remainingArgs = commandLine != null ? + commandLine.getArgList() : new ArrayList(); + if (remainingArgs.size() != 1) { + printUsageAndExit(options, 1); + } + + String command = remainingArgs.get(0); + if ("start".equals(command)) { + // continue and start container + } else if ("stop".equals(command)) { + System.exit(1); + } else { + printUsageAndExit(options, 1); + } + // set up the Jersey servlet container for Jetty ServletHolder sh = new ServletHolder(ServletContainer.class); sh.setInitParameter( "com.sun.jersey.config.property.resourceConfigClass", @@ -99,9 +124,8 @@ public class Main implements Constants { // set up Jetty and run the embedded server - Configuration conf = HBaseConfiguration.create(); - RESTServlet servlet = RESTServlet.getInstance(conf); - port = servlet.getConfiguration().getInt("hbase.rest.port", port); + int port = servlet.getConfiguration().getInt("hbase.rest.port", + DEFAULT_LISTEN_PORT); Server server = new Server(port); server.setSendServerVersion(false); Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RESTServlet.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RESTServlet.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RESTServlet.java (original) +++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RESTServlet.java Wed Nov 10 18:12:23 2010 @@ -60,7 +60,7 @@ public class RESTServlet implements Cons public synchronized static void stop() { if (INSTANCE != null) INSTANCE = null; } - + /** * Constructor with existing configuration * @param conf existing configuration @@ -82,4 +82,13 @@ public class RESTServlet implements Cons RESTMetrics getMetrics() { return metrics; } -} \ No newline at end of file + + /** + * Helper method to determine if server should + * only respond to GET HTTP method requests. + * @return boolean for server read-only state + */ + boolean isReadOnly() { + return getConfiguration().getBoolean("hbase.rest.readonly", false); + } +} Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java (original) +++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/RowResource.java Wed Nov 10 18:12:23 2010 @@ -151,6 +151,9 @@ public class RowResource extends Resourc Response update(final CellSetModel model, final boolean replace) { servlet.getMetrics().incrementRequests(1); + if (servlet.isReadOnly()) { + throw new WebApplicationException(Response.Status.FORBIDDEN); + } HTablePool pool = servlet.getTablePool(); HTableInterface table = null; try { @@ -195,8 +198,11 @@ public class RowResource extends Resourc Response updateBinary(final byte[] message, final HttpHeaders headers, final boolean replace) { servlet.getMetrics().incrementRequests(1); + if (servlet.isReadOnly()) { + throw new WebApplicationException(Response.Status.FORBIDDEN); + } HTablePool pool = servlet.getTablePool(); - HTableInterface table = null; + HTableInterface table = null; try { byte[] row = rowspec.getRow(); byte[][] columns = rowspec.getColumns(); @@ -293,6 +299,9 @@ public class RowResource extends Resourc LOG.debug("DELETE " + uriInfo.getAbsolutePath()); } servlet.getMetrics().incrementRequests(1); + if (servlet.isReadOnly()) { + throw new WebApplicationException(Response.Status.FORBIDDEN); + } Delete delete = null; if (rowspec.hasTimestamp()) delete = new Delete(rowspec.getRow(), rowspec.getTimestamp(), null); Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerInstanceResource.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerInstanceResource.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerInstanceResource.java (original) +++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerInstanceResource.java Wed Nov 10 18:12:23 2010 @@ -159,6 +159,9 @@ public class ScannerInstanceResource ext LOG.debug("DELETE " + uriInfo.getAbsolutePath()); } servlet.getMetrics().incrementRequests(1); + if (servlet.isReadOnly()) { + throw new WebApplicationException(Response.Status.FORBIDDEN); + } ScannerResource.delete(id); return Response.ok().build(); } Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerResource.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerResource.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerResource.java (original) +++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/ScannerResource.java Wed Nov 10 18:12:23 2010 @@ -70,9 +70,12 @@ public class ScannerResource extends Res } } - Response update(final ScannerModel model, final boolean replace, + Response update(final ScannerModel model, final boolean replace, final UriInfo uriInfo) { servlet.getMetrics().incrementRequests(1); + if (servlet.isReadOnly()) { + throw new WebApplicationException(Response.Status.FORBIDDEN); + } byte[] endRow = model.hasEndRow() ? model.getEndRow() : null; RowSpec spec = new RowSpec(model.getStartRow(), endRow, model.getColumns(), model.getStartTime(), model.getEndTime(), 1); Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/SchemaResource.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/SchemaResource.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/SchemaResource.java (original) +++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/rest/SchemaResource.java Wed Nov 10 18:12:23 2010 @@ -107,6 +107,9 @@ public class SchemaResource extends Reso private Response replace(final byte[] name, final TableSchemaModel model, final UriInfo uriInfo, final HBaseAdmin admin) { + if (servlet.isReadOnly()) { + throw new WebApplicationException(Response.Status.FORBIDDEN); + } try { HTableDescriptor htd = new HTableDescriptor(name); for (Map.Entry e: model.getAny().entrySet()) { @@ -133,11 +136,14 @@ public class SchemaResource extends Reso } catch (IOException e) { throw new WebApplicationException(e, Response.Status.SERVICE_UNAVAILABLE); - } - } + } + } private Response update(final byte[] name, final TableSchemaModel model, final UriInfo uriInfo, final HBaseAdmin admin) { + if (servlet.isReadOnly()) { + throw new WebApplicationException(Response.Status.FORBIDDEN); + } try { HTableDescriptor htd = admin.getTableDescriptor(name); admin.disableTable(name); Modified: hbase/trunk/src/main/resources/hbase-default.xml URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/resources/hbase-default.xml?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/main/resources/hbase-default.xml (original) +++ hbase/trunk/src/main/resources/hbase-default.xml Wed Nov 10 18:12:23 2010 @@ -560,4 +560,18 @@ + + hbase.rest.port + 8080 + The port for the HBase REST server. + + + hbase.rest.readonly + false + + Defines the mode the REST server will be started in. Possible values are: + false: All HTTP methods are permitted - GET/PUT/POST/DELETE. + true: Only the GET method is permitted. + + Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestRowResource.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestRowResource.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestRowResource.java (original) +++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestRowResource.java Wed Nov 10 18:12:23 2010 @@ -31,6 +31,7 @@ import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.apache.commons.httpclient.Header; +import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HConstants; @@ -71,11 +72,13 @@ public class TestRowResource { private static JAXBContext context; private static Marshaller marshaller; private static Unmarshaller unmarshaller; + private static Configuration conf; @BeforeClass public static void setUpBeforeClass() throws Exception { + conf = TEST_UTIL.getConfiguration(); TEST_UTIL.startMiniCluster(3); - REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); + REST_TEST_UTIL.startServletContainer(conf); context = JAXBContext.newInstance( CellModel.class, CellSetModel.class, @@ -274,6 +277,33 @@ public class TestRowResource { } @Test + public void testForbidden() throws IOException, JAXBException { + Response response; + + conf.set("hbase.rest.readonly", "true"); + + response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); + assertEquals(response.getCode(), 403); + response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); + assertEquals(response.getCode(), 403); + response = deleteValue(TABLE, ROW_1, COLUMN_1); + assertEquals(response.getCode(), 403); + response = deleteRow(TABLE, ROW_1); + assertEquals(response.getCode(), 403); + + conf.set("hbase.rest.readonly", "false"); + + response = putValueXML(TABLE, ROW_1, COLUMN_1, VALUE_1); + assertEquals(response.getCode(), 200); + response = putValuePB(TABLE, ROW_1, COLUMN_1, VALUE_1); + assertEquals(response.getCode(), 200); + response = deleteValue(TABLE, ROW_1, COLUMN_1); + assertEquals(response.getCode(), 200); + response = deleteRow(TABLE, ROW_1); + assertEquals(response.getCode(), 200); + } + + @Test public void testSingleCellGetPutXML() throws IOException, JAXBException { Response response = getValueXML(TABLE, ROW_1, COLUMN_1); assertEquals(response.getCode(), 404); @@ -286,7 +316,7 @@ public class TestRowResource { checkValueXML(TABLE, ROW_1, COLUMN_1, VALUE_2); response = deleteRow(TABLE, ROW_1); - assertEquals(response.getCode(), 200); + assertEquals(response.getCode(), 200); } @Test @@ -306,7 +336,7 @@ public class TestRowResource { checkValuePB(TABLE, ROW_1, COLUMN_1, VALUE_2); response = deleteRow(TABLE, ROW_1); - assertEquals(response.getCode(), 200); + assertEquals(response.getCode(), 200); } @Test @@ -412,7 +442,7 @@ public class TestRowResource { checkValueXML(TABLE, ROW_2, COLUMN_2, VALUE_4); response = deleteRow(TABLE, ROW_1); - assertEquals(response.getCode(), 200); + assertEquals(response.getCode(), 200); response = deleteRow(TABLE, ROW_2); assertEquals(response.getCode(), 200); } @@ -449,7 +479,7 @@ public class TestRowResource { checkValuePB(TABLE, ROW_2, COLUMN_2, VALUE_4); response = deleteRow(TABLE, ROW_1); - assertEquals(response.getCode(), 200); + assertEquals(response.getCode(), 200); response = deleteRow(TABLE, ROW_2); assertEquals(response.getCode(), 200); } Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestScannerResource.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestScannerResource.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestScannerResource.java (original) +++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestScannerResource.java Wed Nov 10 18:12:23 2010 @@ -32,6 +32,7 @@ import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.apache.commons.httpclient.Header; +import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; @@ -70,6 +71,7 @@ public class TestScannerResource { private static Unmarshaller unmarshaller; private static int expectedRows1; private static int expectedRows2; + private static Configuration conf; private static int insertData(String tableName, String column, double prob) throws IOException { @@ -146,9 +148,10 @@ public class TestScannerResource { @BeforeClass public static void setUpBeforeClass() throws Exception { + conf = TEST_UTIL.getConfiguration(); TEST_UTIL.startMiniCluster(3); - REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); - client = new Client(new Cluster().add("localhost", + REST_TEST_UTIL.startServletContainer(conf); + client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort())); context = JAXBContext.newInstance( CellModel.class, @@ -174,7 +177,7 @@ public class TestScannerResource { REST_TEST_UTIL.shutdownServletContainer(); TEST_UTIL.shutdownMiniCluster(); } - + @Test public void testSimpleScannerXML() throws IOException, JAXBException { final int BATCH_SIZE = 5; @@ -185,10 +188,21 @@ public class TestScannerResource { StringWriter writer = new StringWriter(); marshaller.marshal(model, writer); byte[] body = Bytes.toBytes(writer.toString()); + + // test put operation is forbidden in read-only mode + conf.set("hbase.rest.readonly", "true"); Response response = client.put("/" + TABLE + "/scanner", Constants.MIMETYPE_XML, body); - assertEquals(response.getCode(), 201); + assertEquals(response.getCode(), 403); String scannerURI = response.getLocation(); + assertNull(scannerURI); + + // recall previous put operation with read-only off + conf.set("hbase.rest.readonly", "false"); + response = client.put("/" + TABLE + "/scanner", Constants.MIMETYPE_XML, + body); + assertEquals(response.getCode(), 201); + scannerURI = response.getLocation(); assertNotNull(scannerURI); // get a cell set @@ -199,7 +213,13 @@ public class TestScannerResource { // confirm batch size conformance assertEquals(countCellSet(cellSet), BATCH_SIZE); - // delete the scanner + // test delete scanner operation is forbidden in read-only mode + conf.set("hbase.rest.readonly", "true"); + response = client.delete(scannerURI); + assertEquals(response.getCode(), 403); + + // recall previous delete scanner operation with read-only off + conf.set("hbase.rest.readonly", "false"); response = client.delete(scannerURI); assertEquals(response.getCode(), 200); } @@ -211,10 +231,21 @@ public class TestScannerResource { ScannerModel model = new ScannerModel(); model.setBatch(BATCH_SIZE); model.addColumn(Bytes.toBytes(COLUMN_1)); + + // test put operation is forbidden in read-only mode + conf.set("hbase.rest.readonly", "true"); Response response = client.put("/" + TABLE + "/scanner", Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput()); - assertEquals(response.getCode(), 201); + assertEquals(response.getCode(), 403); String scannerURI = response.getLocation(); + assertNull(scannerURI); + + // recall previous put operation with read-only off + conf.set("hbase.rest.readonly", "false"); + response = client.put("/" + TABLE + "/scanner", + Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput()); + assertEquals(response.getCode(), 201); + scannerURI = response.getLocation(); assertNotNull(scannerURI); // get a cell set @@ -225,7 +256,13 @@ public class TestScannerResource { // confirm batch size conformance assertEquals(countCellSet(cellSet), BATCH_SIZE); - // delete the scanner + // test delete scanner operation is forbidden in read-only mode + conf.set("hbase.rest.readonly", "true"); + response = client.delete(scannerURI); + assertEquals(response.getCode(), 403); + + // recall previous delete scanner operation with read-only off + conf.set("hbase.rest.readonly", "false"); response = client.delete(scannerURI); assertEquals(response.getCode(), 200); } @@ -236,10 +273,21 @@ public class TestScannerResource { ScannerModel model = new ScannerModel(); model.setBatch(1); model.addColumn(Bytes.toBytes(COLUMN_1)); + + // test put operation is forbidden in read-only mode + conf.set("hbase.rest.readonly", "true"); Response response = client.put("/" + TABLE + "/scanner", Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput()); - assertEquals(response.getCode(), 201); + assertEquals(response.getCode(), 403); String scannerURI = response.getLocation(); + assertNull(scannerURI); + + // recall previous put operation with read-only off + conf.set("hbase.rest.readonly", "false"); + response = client.put("/" + TABLE + "/scanner", + Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput()); + assertEquals(response.getCode(), 201); + scannerURI = response.getLocation(); assertNotNull(scannerURI); // get a cell @@ -263,7 +311,13 @@ public class TestScannerResource { assertTrue(foundColumnHeader); assertTrue(foundTimestampHeader); - // delete the scanner + // test delete scanner operation is forbidden in read-only mode + conf.set("hbase.rest.readonly", "true"); + response = client.delete(scannerURI); + assertEquals(response.getCode(), 403); + + // recall previous delete scanner operation with read-only off + conf.set("hbase.rest.readonly", "false"); response = client.delete(scannerURI); assertEquals(response.getCode(), 200); } Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestSchemaResource.java URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestSchemaResource.java?rev=1033626&r1=1033625&r2=1033626&view=diff ============================================================================== --- hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestSchemaResource.java (original) +++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/rest/TestSchemaResource.java Wed Nov 10 18:12:23 2010 @@ -27,6 +27,7 @@ import java.io.StringWriter; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; +import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.rest.client.Client; @@ -47,16 +48,18 @@ public class TestSchemaResource { private static String TABLE2 = "TestSchemaResource2"; private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); - private static final HBaseRESTTestingUtility REST_TEST_UTIL = + private static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility(); private static Client client; private static JAXBContext context; + private static Configuration conf; @BeforeClass public static void setUpBeforeClass() throws Exception { + conf = TEST_UTIL.getConfiguration(); TEST_UTIL.startMiniCluster(3); - REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); - client = new Client(new Cluster().add("localhost", + REST_TEST_UTIL.startServletContainer(conf); + client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort())); context = JAXBContext.newInstance( ColumnSchemaModel.class, @@ -96,6 +99,11 @@ public class TestSchemaResource { response = client.put(schemaPath, Constants.MIMETYPE_XML, toXML(model)); assertEquals(response.getCode(), 201); + // recall the same put operation but in read-only mode + conf.set("hbase.rest.readonly", "true"); + response = client.put(schemaPath, Constants.MIMETYPE_XML, toXML(model)); + assertEquals(response.getCode(), 403); + // make sure HBase concurs, and wait for the table to come online admin.enableTable(TABLE1); @@ -110,6 +118,9 @@ public class TestSchemaResource { // make sure HBase concurs assertFalse(admin.tableExists(TABLE1)); + + // return read-only setting back to default + conf.set("hbase.rest.readonly", "false"); } @Test @@ -128,6 +139,12 @@ public class TestSchemaResource { model.createProtobufOutput()); assertEquals(response.getCode(), 201); + // recall the same put operation but in read-only mode + conf.set("hbase.rest.readonly", "true"); + response = client.put(schemaPath, Constants.MIMETYPE_PROTOBUF, + model.createProtobufOutput()); + assertEquals(response.getCode(), 403); + // make sure HBase concurs, and wait for the table to come online admin.enableTable(TABLE2); @@ -143,5 +160,8 @@ public class TestSchemaResource { // make sure HBase concurs assertFalse(admin.tableExists(TABLE2)); + + // return read-only setting back to default + conf.set("hbase.rest.readonly", "false"); } }