blob: 0c83a7fdeabc0145a022f45ba0e0a30b983bcc59 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.rest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionLocator;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.rest.client.Client;
import org.apache.hadoop.hbase.rest.client.Cluster;
import org.apache.hadoop.hbase.rest.client.Response;
import org.apache.hadoop.hbase.rest.model.TableInfoModel;
import org.apache.hadoop.hbase.rest.model.TableListModel;
import org.apache.hadoop.hbase.rest.model.TableModel;
import org.apache.hadoop.hbase.rest.model.TableRegionModel;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RestTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Category({RestTests.class, MediumTests.class})
public class TestTableResource {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestTableResource.class);
private static final Logger LOG = LoggerFactory.getLogger(TestTableResource.class);
private static final TableName TABLE = TableName.valueOf("TestTableResource");
private static final String COLUMN_FAMILY = "test";
private static final String COLUMN = COLUMN_FAMILY + ":qualifier";
private static final int NUM_REGIONS = 4;
private static List<HRegionLocation> regionMap;
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
private static final HBaseRESTTestingUtility REST_TEST_UTIL =
new HBaseRESTTestingUtility();
private static Client client;
private static JAXBContext context;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
TEST_UTIL.startMiniCluster(3);
REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration());
client = new Client(new Cluster().add("localhost",
REST_TEST_UTIL.getServletPort()));
context = JAXBContext.newInstance(
TableModel.class,
TableInfoModel.class,
TableListModel.class,
TableRegionModel.class);
TEST_UTIL.createMultiRegionTable(TABLE, Bytes.toBytes(COLUMN_FAMILY), NUM_REGIONS);
byte[] k = new byte[3];
byte [][] famAndQf = CellUtil.parseColumn(Bytes.toBytes(COLUMN));
List<Put> puts = new ArrayList<>();
for (byte b1 = 'a'; b1 < 'z'; b1++) {
for (byte b2 = 'a'; b2 < 'z'; b2++) {
for (byte b3 = 'a'; b3 < 'z'; b3++) {
k[0] = b1;
k[1] = b2;
k[2] = b3;
Put put = new Put(k);
put.setDurability(Durability.SKIP_WAL);
put.addColumn(famAndQf[0], famAndQf[1], k);
puts.add(put);
}
}
}
Connection connection = TEST_UTIL.getConnection();
Table table = connection.getTable(TABLE);
table.put(puts);
table.close();
RegionLocator regionLocator = connection.getRegionLocator(TABLE);
List<HRegionLocation> m = regionLocator.getAllRegionLocations();
// should have four regions now
assertEquals(NUM_REGIONS, m.size());
regionMap = m;
LOG.error("regions: " + regionMap);
regionLocator.close();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
REST_TEST_UTIL.shutdownServletContainer();
TEST_UTIL.shutdownMiniCluster();
}
private static void checkTableList(TableListModel model) {
boolean found = false;
Iterator<TableModel> tables = model.getTables().iterator();
assertTrue(tables.hasNext());
while (tables.hasNext()) {
TableModel table = tables.next();
if (table.getName().equals(TABLE.getNameAsString())) {
found = true;
break;
}
}
assertTrue(found);
}
void checkTableInfo(TableInfoModel model) {
assertEquals(model.getName(), TABLE.getNameAsString());
Iterator<TableRegionModel> regions = model.getRegions().iterator();
assertTrue(regions.hasNext());
while (regions.hasNext()) {
TableRegionModel region = regions.next();
boolean found = false;
LOG.debug("looking for region " + region.getName());
for (HRegionLocation e: regionMap) {
RegionInfo hri = e.getRegion();
// getRegionNameAsString uses Bytes.toStringBinary which escapes some non-printable
// characters
String hriRegionName = Bytes.toString(hri.getRegionName());
String regionName = region.getName();
LOG.debug("comparing to region " + hriRegionName);
if (hriRegionName.equals(regionName)) {
found = true;
byte[] startKey = hri.getStartKey();
byte[] endKey = hri.getEndKey();
ServerName serverName = e.getServerName();
InetSocketAddress sa =
new InetSocketAddress(serverName.getHostname(), serverName.getPort());
String location = sa.getHostName() + ":" +
Integer.valueOf(sa.getPort());
assertEquals(hri.getRegionId(), region.getId());
assertTrue(Bytes.equals(startKey, region.getStartKey()));
assertTrue(Bytes.equals(endKey, region.getEndKey()));
assertEquals(location, region.getLocation());
break;
}
}
assertTrue("Couldn't find region " + region.getName(), found);
}
}
@Test
public void testTableListText() throws IOException {
Response response = client.get("/", Constants.MIMETYPE_TEXT);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type"));
}
@Test
public void testTableListXML() throws IOException, JAXBException {
Response response = client.get("/", Constants.MIMETYPE_XML);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
TableListModel model = (TableListModel)
context.createUnmarshaller()
.unmarshal(new ByteArrayInputStream(response.getBody()));
checkTableList(model);
}
@Test
public void testTableListJSON() throws IOException {
Response response = client.get("/", Constants.MIMETYPE_JSON);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
}
@Test
public void testTableListPB() throws IOException, JAXBException {
Response response = client.get("/", Constants.MIMETYPE_PROTOBUF);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
TableListModel model = new TableListModel();
model.getObjectFromMessage(response.getBody());
checkTableList(model);
response = client.get("/", Constants.MIMETYPE_PROTOBUF_IETF);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type"));
model = new TableListModel();
model.getObjectFromMessage(response.getBody());
checkTableList(model);
}
@Test
public void testTableInfoText() throws IOException {
Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_TEXT);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type"));
}
@Test
public void testTableInfoXML() throws IOException, JAXBException {
Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_XML);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
TableInfoModel model = (TableInfoModel)
context.createUnmarshaller()
.unmarshal(new ByteArrayInputStream(response.getBody()));
checkTableInfo(model);
}
@Test
public void testTableInfoJSON() throws IOException {
Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_JSON);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
}
@Test
public void testTableInfoPB() throws IOException, JAXBException {
Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_PROTOBUF);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
TableInfoModel model = new TableInfoModel();
model.getObjectFromMessage(response.getBody());
checkTableInfo(model);
response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_PROTOBUF_IETF);
assertEquals(200, response.getCode());
assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type"));
model = new TableInfoModel();
model.getObjectFromMessage(response.getBody());
checkTableInfo(model);
}
@Test
public void testTableNotFound() throws IOException {
String notExistTable = "notexist";
Response response1 = client.get("/" + notExistTable + "/schema", Constants.MIMETYPE_JSON);
assertEquals(404, response1.getCode());
Response response2 = client.get("/" + notExistTable + "/regions", Constants.MIMETYPE_XML);
assertEquals(404, response2.getCode());
}
}