View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.rest;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  
25  import java.io.ByteArrayInputStream;
26  import java.io.IOException;
27  import java.net.InetSocketAddress;
28  import java.util.ArrayList;
29  import java.util.Iterator;
30  import java.util.List;
31  
32  import javax.xml.bind.JAXBContext;
33  import javax.xml.bind.JAXBException;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.apache.hadoop.hbase.HBaseTestingUtility;
38  import org.apache.hadoop.hbase.HRegionInfo;
39  import org.apache.hadoop.hbase.HRegionLocation;
40  import org.apache.hadoop.hbase.KeyValue;
41  import org.apache.hadoop.hbase.ServerName;
42  import org.apache.hadoop.hbase.TableName;
43  import org.apache.hadoop.hbase.client.Connection;
44  import org.apache.hadoop.hbase.client.Durability;
45  import org.apache.hadoop.hbase.client.Put;
46  import org.apache.hadoop.hbase.client.RegionLocator;
47  import org.apache.hadoop.hbase.client.Table;
48  import org.apache.hadoop.hbase.rest.client.Client;
49  import org.apache.hadoop.hbase.rest.client.Cluster;
50  import org.apache.hadoop.hbase.rest.client.Response;
51  import org.apache.hadoop.hbase.rest.model.TableInfoModel;
52  import org.apache.hadoop.hbase.rest.model.TableListModel;
53  import org.apache.hadoop.hbase.rest.model.TableModel;
54  import org.apache.hadoop.hbase.rest.model.TableRegionModel;
55  import org.apache.hadoop.hbase.testclassification.MediumTests;
56  import org.apache.hadoop.hbase.util.Bytes;
57  import org.junit.AfterClass;
58  import org.junit.BeforeClass;
59  import org.junit.Test;
60  import org.junit.experimental.categories.Category;
61  
62  @Category(MediumTests.class)
63  public class TestTableResource {
64    private static final Log LOG = LogFactory.getLog(TestTableResource.class);
65  
66    private static final TableName TABLE = TableName.valueOf("TestTableResource");
67    private static final String COLUMN_FAMILY = "test";
68    private static final String COLUMN = COLUMN_FAMILY + ":qualifier";
69    private static final int NUM_REGIONS = 4;
70    private static List<HRegionLocation> regionMap;
71  
72    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
73    private static final HBaseRESTTestingUtility REST_TEST_UTIL =
74      new HBaseRESTTestingUtility();
75    private static Client client;
76    private static JAXBContext context;
77  
78    @BeforeClass
79    public static void setUpBeforeClass() throws Exception {
80      TEST_UTIL.startMiniCluster(3);
81      REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration());
82      client = new Client(new Cluster().add("localhost",
83        REST_TEST_UTIL.getServletPort()));
84      context = JAXBContext.newInstance(
85          TableModel.class,
86          TableInfoModel.class,
87          TableListModel.class,
88          TableRegionModel.class);
89      TEST_UTIL.createMultiRegionTable(TABLE, Bytes.toBytes(COLUMN_FAMILY), NUM_REGIONS);
90      byte[] k = new byte[3];
91      byte [][] famAndQf = KeyValue.parseColumn(Bytes.toBytes(COLUMN));
92      List<Put> puts = new ArrayList<>();
93      for (byte b1 = 'a'; b1 < 'z'; b1++) {
94        for (byte b2 = 'a'; b2 < 'z'; b2++) {
95          for (byte b3 = 'a'; b3 < 'z'; b3++) {
96            k[0] = b1;
97            k[1] = b2;
98            k[2] = b3;
99            Put put = new Put(k);
100           put.setDurability(Durability.SKIP_WAL);
101           put.add(famAndQf[0], famAndQf[1], k);
102           puts.add(put);
103         }
104       }
105     }
106 
107     Connection connection = TEST_UTIL.getConnection();
108     
109     Table table =  connection.getTable(TABLE);
110     table.put(puts);
111     table.close();
112 
113     RegionLocator regionLocator = connection.getRegionLocator(TABLE);
114     List<HRegionLocation> m = regionLocator.getAllRegionLocations();
115 
116     // should have four regions now
117     assertEquals(NUM_REGIONS, m.size());
118     regionMap = m;
119     LOG.error("regions: " + regionMap);
120     regionLocator.close();
121   }
122 
123   @AfterClass
124   public static void tearDownAfterClass() throws Exception {
125     REST_TEST_UTIL.shutdownServletContainer();
126     TEST_UTIL.shutdownMiniCluster();
127   }
128 
129   private static void checkTableList(TableListModel model) {
130     boolean found = false;
131     Iterator<TableModel> tables = model.getTables().iterator();
132     assertTrue(tables.hasNext());
133     while (tables.hasNext()) {
134       TableModel table = tables.next();
135       if (table.getName().equals(TABLE.getNameAsString())) {
136         found = true;
137         break;
138       }
139     }
140     assertTrue(found);
141   }
142 
143   void checkTableInfo(TableInfoModel model) {
144     assertEquals(model.getName(), TABLE.getNameAsString());
145     Iterator<TableRegionModel> regions = model.getRegions().iterator();
146     assertTrue(regions.hasNext());
147     while (regions.hasNext()) {
148       TableRegionModel region = regions.next();
149       boolean found = false;
150       LOG.debug("looking for region " + region.getName());
151       for (HRegionLocation e: regionMap) {
152         HRegionInfo hri = e.getRegionInfo();
153         // getRegionNameAsString uses Bytes.toStringBinary which escapes some non-printable
154         // characters
155         String hriRegionName = Bytes.toString(hri.getRegionName());
156         String regionName = region.getName();
157         LOG.debug("comparing to region " + hriRegionName);
158         if (hriRegionName.equals(regionName)) {
159           found = true;
160           byte[] startKey = hri.getStartKey();
161           byte[] endKey = hri.getEndKey();
162           ServerName serverName = e.getServerName();
163           InetSocketAddress sa =
164               new InetSocketAddress(serverName.getHostname(), serverName.getPort());
165           String location = sa.getHostName() + ":" +
166             Integer.valueOf(sa.getPort());
167           assertEquals(hri.getRegionId(), region.getId());
168           assertTrue(Bytes.equals(startKey, region.getStartKey()));
169           assertTrue(Bytes.equals(endKey, region.getEndKey()));
170           assertEquals(location, region.getLocation());
171           break;
172         }
173       }
174       assertTrue("Couldn't find region " + region.getName(), found);
175     }
176   }
177 
178   @Test
179   public void testTableListText() throws IOException {
180     Response response = client.get("/", Constants.MIMETYPE_TEXT);
181     assertEquals(200, response.getCode());
182     assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type"));
183   }
184 
185   @Test
186   public void testTableListXML() throws IOException, JAXBException {
187     Response response = client.get("/", Constants.MIMETYPE_XML);
188     assertEquals(200, response.getCode());
189     assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
190     TableListModel model = (TableListModel)
191       context.createUnmarshaller()
192         .unmarshal(new ByteArrayInputStream(response.getBody()));
193     checkTableList(model);
194   }
195 
196   @Test
197   public void testTableListJSON() throws IOException {
198     Response response = client.get("/", Constants.MIMETYPE_JSON);
199     assertEquals(200, response.getCode());
200     assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
201   }
202 
203   @Test
204   public void testTableListPB() throws IOException, JAXBException {
205     Response response = client.get("/", Constants.MIMETYPE_PROTOBUF);
206     assertEquals(200, response.getCode());
207     assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
208     TableListModel model = new TableListModel();
209     model.getObjectFromMessage(response.getBody());
210     checkTableList(model);
211     response = client.get("/", Constants.MIMETYPE_PROTOBUF_IETF);
212     assertEquals(200, response.getCode());
213     assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type"));
214     model = new TableListModel();
215     model.getObjectFromMessage(response.getBody());
216     checkTableList(model);
217   }
218 
219   @Test
220   public void testTableInfoText() throws IOException {
221     Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_TEXT);
222     assertEquals(200, response.getCode());
223     assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type"));
224   }
225 
226   @Test
227   public void testTableInfoXML() throws IOException, JAXBException {
228     Response response = client.get("/" + TABLE + "/regions",  Constants.MIMETYPE_XML);
229     assertEquals(200, response.getCode());
230     assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
231     TableInfoModel model = (TableInfoModel)
232       context.createUnmarshaller()
233         .unmarshal(new ByteArrayInputStream(response.getBody()));
234     checkTableInfo(model);
235   }
236 
237   @Test
238   public void testTableInfoJSON() throws IOException {
239     Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_JSON);
240     assertEquals(200, response.getCode());
241     assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
242   }
243 
244   @Test
245   public void testTableInfoPB() throws IOException, JAXBException {
246     Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_PROTOBUF);
247     assertEquals(200, response.getCode());
248     assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
249     TableInfoModel model = new TableInfoModel();
250     model.getObjectFromMessage(response.getBody());
251     checkTableInfo(model);
252     response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_PROTOBUF_IETF);
253     assertEquals(200, response.getCode());
254     assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type"));
255     model = new TableInfoModel();
256     model.getObjectFromMessage(response.getBody());
257     checkTableInfo(model);
258   }
259 
260   @Test
261   public void testTableNotFound() throws IOException {
262     String notExistTable = "notexist";
263     Response response1 = client.get("/" + notExistTable + "/schema", Constants.MIMETYPE_JSON);
264     assertEquals(404, response1.getCode());
265     Response response2 = client.get("/" + notExistTable + "/regions", Constants.MIMETYPE_XML);
266     assertEquals(404, response2.getCode());
267   }
268 
269 }