HBASE-3161 Provide option for Stargate to only serve GET requests
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1033626 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e4e423bd83
commit
6b7055eb24
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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.servlet.ServletContainer;
|
|||
|
||||
/**
|
||||
* Main class for launching REST gateway as a servlet hosted by Jetty.
|
||||
* <p>
|
||||
* <p>
|
||||
* The following options are supported:
|
||||
* <ul>
|
||||
* <li>-p: service port</li>
|
||||
* <li>-p --port : service port</li>
|
||||
* <li>-ro --readonly : server mode</li>
|
||||
* </ul>
|
||||
*/
|
||||
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 <port>] [-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<String> 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<String> remainingArgs = commandLine != null ?
|
||||
commandLine.getArgList() : new ArrayList<String>();
|
||||
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);
|
||||
|
|
|
@ -60,7 +60,7 @@ public class RESTServlet implements Constants {
|
|||
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 Constants {
|
|||
RESTMetrics getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,6 +151,9 @@ public class RowResource extends ResourceBase {
|
|||
|
||||
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 ResourceBase {
|
|||
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 ResourceBase {
|
|||
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);
|
||||
|
|
|
@ -159,6 +159,9 @@ public class ScannerInstanceResource extends ResourceBase {
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -70,9 +70,12 @@ public class ScannerResource extends ResourceBase {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -107,6 +107,9 @@ public class SchemaResource extends ResourceBase {
|
|||
|
||||
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<QName,Object> e: model.getAny().entrySet()) {
|
||||
|
@ -133,11 +136,14 @@ public class SchemaResource extends ResourceBase {
|
|||
} 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);
|
||||
|
|
|
@ -560,4 +560,18 @@
|
|||
</description>
|
||||
</property>
|
||||
<!-- End of properties that are directly mapped from ZooKeeper's zoo.cfg -->
|
||||
<property>
|
||||
<name>hbase.rest.port</name>
|
||||
<value>8080</value>
|
||||
<description>The port for the HBase REST server.</description>
|
||||
</property>
|
||||
<property>
|
||||
<name>hbase.rest.readonly</name>
|
||||
<value>false</value>
|
||||
<description>
|
||||
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.
|
||||
</description>
|
||||
</property>
|
||||
</configuration>
|
||||
|
|
|
@ -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,
|
||||
|
@ -273,6 +276,33 @@ public class TestRowResource {
|
|||
assertEquals(response.getCode(), 404);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue