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 java.io.ByteArrayInputStream;
23  import java.io.IOException;
24  import java.net.InetSocketAddress;
25  import java.util.Iterator;
26  import java.util.Map;
27  
28  import javax.xml.bind.JAXBContext;
29  import javax.xml.bind.JAXBException;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.apache.hadoop.hbase.*;
34  import org.apache.hadoop.hbase.client.HBaseAdmin;
35  import org.apache.hadoop.hbase.client.HTable;
36  import org.apache.hadoop.hbase.client.Put;
37  import org.apache.hadoop.hbase.client.Durability;
38  import org.apache.hadoop.hbase.rest.client.Client;
39  import org.apache.hadoop.hbase.rest.client.Cluster;
40  import org.apache.hadoop.hbase.rest.client.Response;
41  import org.apache.hadoop.hbase.rest.model.TableModel;
42  import org.apache.hadoop.hbase.rest.model.TableInfoModel;
43  import org.apache.hadoop.hbase.rest.model.TableListModel;
44  import org.apache.hadoop.hbase.rest.model.TableRegionModel;
45  import org.apache.hadoop.hbase.util.Bytes;
46  import org.apache.hadoop.util.StringUtils;
47  
48  import static org.junit.Assert.*;
49  
50  import org.junit.AfterClass;
51  import org.junit.BeforeClass;
52  import org.junit.Test;
53  import org.junit.experimental.categories.Category;
54  
55  @Category(MediumTests.class)
56  public class TestTableResource {
57    private static final Log LOG = LogFactory.getLog(TestTableResource.class);
58  
59    private static String TABLE = "TestTableResource";
60    private static String COLUMN_FAMILY = "test";
61    private static String COLUMN = COLUMN_FAMILY + ":qualifier";
62    private static Map<HRegionInfo, ServerName> regionMap;
63  
64    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
65    private static final HBaseRESTTestingUtility REST_TEST_UTIL = 
66      new HBaseRESTTestingUtility();
67    private static Client client;
68    private static JAXBContext context;
69  
70    @BeforeClass
71    public static void setUpBeforeClass() throws Exception {
72      TEST_UTIL.startMiniCluster(3);
73      REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration());
74      client = new Client(new Cluster().add("localhost", 
75        REST_TEST_UTIL.getServletPort()));
76      context = JAXBContext.newInstance(
77          TableModel.class,
78          TableInfoModel.class,
79          TableListModel.class,
80          TableRegionModel.class);
81      HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
82      if (admin.tableExists(TABLE)) {
83        return;
84      }
85      HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLE));
86      htd.addFamily(new HColumnDescriptor(COLUMN_FAMILY));
87      admin.createTable(htd);
88      HTable table = new HTable(TEST_UTIL.getConfiguration(), TABLE);
89      byte[] k = new byte[3];
90      byte [][] famAndQf = KeyValue.parseColumn(Bytes.toBytes(COLUMN));
91      for (byte b1 = 'a'; b1 < 'z'; b1++) {
92        for (byte b2 = 'a'; b2 < 'z'; b2++) {
93          for (byte b3 = 'a'; b3 < 'z'; b3++) {
94            k[0] = b1;
95            k[1] = b2;
96            k[2] = b3;
97            Put put = new Put(k);
98            put.setDurability(Durability.SKIP_WAL);
99            put.add(famAndQf[0], famAndQf[1], k);
100           table.put(put);
101         }
102       }
103     }
104     table.flushCommits();
105     // get the initial layout (should just be one region)
106     Map<HRegionInfo, ServerName> m = table.getRegionLocations();
107     assertEquals(m.size(), 1);
108     // tell the master to split the table
109     admin.split(TABLE);
110     // give some time for the split to happen
111 
112     long timeout = System.currentTimeMillis() + (15 * 1000);
113     while (System.currentTimeMillis() < timeout && m.size()!=2){
114       try {
115         Thread.sleep(250);
116       } catch (InterruptedException e) {
117         LOG.warn(StringUtils.stringifyException(e));
118       }
119       // check again
120       m = table.getRegionLocations();
121     }
122 
123     // should have two regions now
124     assertEquals(m.size(), 2);
125     regionMap = m;
126     LOG.info("regions: " + regionMap);
127     table.close();
128   }
129 
130   @AfterClass
131   public static void tearDownAfterClass() throws Exception {
132     REST_TEST_UTIL.shutdownServletContainer();
133     TEST_UTIL.shutdownMiniCluster();
134   }
135 
136   private static void checkTableList(TableListModel model) {
137     boolean found = false;
138     Iterator<TableModel> tables = model.getTables().iterator();
139     assertTrue(tables.hasNext());
140     while (tables.hasNext()) {
141       TableModel table = tables.next();
142       if (table.getName().equals(TABLE)) {
143         found = true;
144         break;
145       }
146     }
147     assertTrue(found);
148   }
149 
150   void checkTableInfo(TableInfoModel model) {
151     assertEquals(model.getName(), TABLE);
152     Iterator<TableRegionModel> regions = model.getRegions().iterator();
153     assertTrue(regions.hasNext());
154     while (regions.hasNext()) {
155       TableRegionModel region = regions.next();
156       boolean found = false;
157       for (Map.Entry<HRegionInfo, ServerName> e: regionMap.entrySet()) {
158         HRegionInfo hri = e.getKey();
159         String hriRegionName = hri.getRegionNameAsString();
160         String regionName = region.getName();
161         if (hriRegionName.equals(regionName)) {
162           found = true;
163           byte[] startKey = hri.getStartKey();
164           byte[] endKey = hri.getEndKey();
165           InetSocketAddress sa = new InetSocketAddress(e.getValue().getHostname(), e.getValue().getPort());
166           String location = sa.getHostName() + ":" +
167             Integer.valueOf(sa.getPort());
168           assertEquals(hri.getRegionId(), region.getId());
169           assertTrue(Bytes.equals(startKey, region.getStartKey()));
170           assertTrue(Bytes.equals(endKey, region.getEndKey()));
171           assertEquals(location, region.getLocation());
172           break;
173         }
174       }
175       assertTrue(found);
176     }
177   }
178 
179   @Test
180   public void testTableListText() throws IOException {
181     Response response = client.get("/", Constants.MIMETYPE_TEXT);
182     assertEquals(response.getCode(), 200);
183     assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type"));
184   }
185 
186   @Test
187   public void testTableListXML() throws IOException, JAXBException {
188     Response response = client.get("/", Constants.MIMETYPE_XML);
189     assertEquals(response.getCode(), 200);
190     assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
191     TableListModel model = (TableListModel)
192       context.createUnmarshaller()
193         .unmarshal(new ByteArrayInputStream(response.getBody()));
194     checkTableList(model);
195   }
196 
197   @Test
198   public void testTableListJSON() throws IOException {
199     Response response = client.get("/", Constants.MIMETYPE_JSON);
200     assertEquals(response.getCode(), 200);
201     assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
202   }
203 
204   @Test
205   public void testTableListPB() throws IOException, JAXBException {
206     Response response = client.get("/", Constants.MIMETYPE_PROTOBUF);
207     assertEquals(response.getCode(), 200);
208     assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
209     TableListModel model = new TableListModel();
210     model.getObjectFromMessage(response.getBody());
211     checkTableList(model);
212     response = client.get("/", Constants.MIMETYPE_PROTOBUF_IETF);
213     assertEquals(response.getCode(), 200);
214     assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type"));
215     model = new TableListModel();
216     model.getObjectFromMessage(response.getBody());
217     checkTableList(model);
218   }
219 
220   @Test
221   public void testTableInfoText() throws IOException {
222     Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_TEXT);
223     assertEquals(response.getCode(), 200);
224     assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type"));
225   }
226 
227   @Test
228   public void testTableInfoXML() throws IOException, JAXBException {
229     Response response = client.get("/" + TABLE + "/regions",  Constants.MIMETYPE_XML);
230     assertEquals(response.getCode(), 200);
231     assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
232     TableInfoModel model = (TableInfoModel)
233       context.createUnmarshaller()
234         .unmarshal(new ByteArrayInputStream(response.getBody()));
235     checkTableInfo(model);
236   }
237 
238   @Test
239   public void testTableInfoJSON() throws IOException {
240     Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_JSON);
241     assertEquals(response.getCode(), 200);
242     assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
243   }
244 
245   @Test
246   public void testTableInfoPB() throws IOException, JAXBException {
247     Response response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_PROTOBUF);
248     assertEquals(response.getCode(), 200);
249     assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
250     TableInfoModel model = new TableInfoModel();
251     model.getObjectFromMessage(response.getBody());
252     checkTableInfo(model);
253     response = client.get("/" + TABLE + "/regions", Constants.MIMETYPE_PROTOBUF_IETF);
254     assertEquals(response.getCode(), 200);
255     assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type"));
256     model = new TableInfoModel();
257     model.getObjectFromMessage(response.getBody());
258     checkTableInfo(model);
259   }
260 
261 }
262