| /** |
| * 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()); |
| } |
| |
| } |
| |