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 org.apache.commons.httpclient.Header;
23  import org.apache.hadoop.conf.Configuration;
24  import org.apache.hadoop.hbase.*;
25  import org.apache.hadoop.hbase.client.Admin;
26  import org.apache.hadoop.hbase.rest.client.Client;
27  import org.apache.hadoop.hbase.rest.client.Cluster;
28  import org.apache.hadoop.hbase.rest.client.Response;
29  import org.apache.hadoop.hbase.rest.model.CellModel;
30  import org.apache.hadoop.hbase.rest.model.CellSetModel;
31  import org.apache.hadoop.hbase.rest.model.RowModel;
32  import org.apache.hadoop.hbase.rest.provider.JacksonProvider;
33  import org.apache.hadoop.hbase.testclassification.MediumTests;
34  import org.apache.hadoop.hbase.util.Bytes;
35  import org.codehaus.jackson.map.ObjectMapper;
36  import org.junit.AfterClass;
37  import org.junit.BeforeClass;
38  import org.junit.Test;
39  import org.junit.experimental.categories.Category;
40  import org.junit.runner.RunWith;
41  import org.junit.runners.Parameterized;
42  
43  import javax.ws.rs.core.MediaType;
44  import javax.xml.bind.JAXBContext;
45  import javax.xml.bind.JAXBException;
46  import java.io.IOException;
47  import java.util.ArrayList;
48  import java.util.Collection;
49  import java.util.List;
50  
51  import static org.junit.Assert.assertEquals;
52  
53  
54  @Category(MediumTests.class)
55  @RunWith(Parameterized.class)
56  public class TestMultiRowResource {
57  
58    private static final TableName TABLE = TableName.valueOf("TestRowResource");
59    private static final String CFA = "a";
60    private static final String CFB = "b";
61    private static final String COLUMN_1 = CFA + ":1";
62    private static final String COLUMN_2 = CFB + ":2";
63    private static final String ROW_1 = "testrow5";
64    private static final String VALUE_1 = "testvalue5";
65    private static final String ROW_2 = "testrow6";
66    private static final String VALUE_2 = "testvalue6";
67  
68  
69    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
70    private static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility();
71  
72    private static Client client;
73    @SuppressWarnings("unused")
74    private static JAXBContext context;
75    private static Configuration conf;
76  
77    private static Header extraHdr = null;
78    private static boolean csrfEnabled = true;
79  
80    @Parameterized.Parameters
81    public static Collection<Object[]> data() {
82      List<Object[]> params = new ArrayList<Object[]>();
83      params.add(new Object[] {Boolean.TRUE});
84      params.add(new Object[] {Boolean.FALSE});
85      return params;
86    }
87  
88    public TestMultiRowResource(Boolean csrf) {
89      csrfEnabled = csrf;
90    }
91  
92  
93    @BeforeClass
94    public static void setUpBeforeClass() throws Exception {
95      conf = TEST_UTIL.getConfiguration();
96      conf.setBoolean(RESTServer.REST_CSRF_ENABLED_KEY, csrfEnabled);
97      extraHdr = new Header(RESTServer.REST_CSRF_CUSTOM_HEADER_DEFAULT, "");
98      TEST_UTIL.startMiniCluster();
99      REST_TEST_UTIL.startServletContainer(conf);
100     context = JAXBContext.newInstance(
101             CellModel.class,
102             CellSetModel.class,
103             RowModel.class);
104     client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort()));
105     Admin admin = TEST_UTIL.getHBaseAdmin();
106     if (admin.tableExists(TABLE)) {
107       return;
108     }
109     HTableDescriptor htd = new HTableDescriptor(TABLE);
110     htd.addFamily(new HColumnDescriptor(CFA));
111     htd.addFamily(new HColumnDescriptor(CFB));
112     admin.createTable(htd);
113   }
114 
115   @AfterClass
116   public static void tearDownAfterClass() throws Exception {
117     REST_TEST_UTIL.shutdownServletContainer();
118     TEST_UTIL.shutdownMiniCluster();
119   }
120 
121 
122   @Test
123   public void testMultiCellGetJSON() throws IOException, JAXBException {
124     String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
125     String row_6_url = "/" + TABLE + "/" + ROW_2 + "/" + COLUMN_2;
126 
127 
128     StringBuilder path = new StringBuilder();
129     path.append("/");
130     path.append(TABLE);
131     path.append("/multiget/?row=");
132     path.append(ROW_1);
133     path.append("&row=");
134     path.append(ROW_2);
135 
136     if (csrfEnabled) {
137       Response response = client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1));
138       assertEquals(400, response.getCode());
139     }
140 
141     client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
142     client.post(row_6_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_2), extraHdr);
143 
144 
145     Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
146     assertEquals(200, response.getCode());
147     assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
148 
149     client.delete(row_5_url, extraHdr);
150     client.delete(row_6_url, extraHdr);
151 
152   }
153 
154   @Test
155   public void testMultiCellGetXML() throws IOException, JAXBException {
156     String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
157     String row_6_url = "/" + TABLE + "/" + ROW_2 + "/" + COLUMN_2;
158 
159 
160     StringBuilder path = new StringBuilder();
161     path.append("/");
162     path.append(TABLE);
163     path.append("/multiget/?row=");
164     path.append(ROW_1);
165     path.append("&row=");
166     path.append(ROW_2);
167 
168     client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
169     client.post(row_6_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_2), extraHdr);
170 
171 
172     Response response = client.get(path.toString(), Constants.MIMETYPE_XML);
173     assertEquals(200, response.getCode());
174     assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
175 
176     client.delete(row_5_url, extraHdr);
177     client.delete(row_6_url, extraHdr);
178 
179   }
180 
181   @Test
182   public void testMultiCellGetWithColsJSON() throws IOException, JAXBException {
183     String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
184     String row_6_url = "/" + TABLE + "/" + ROW_2 + "/" + COLUMN_2;
185 
186     StringBuilder path = new StringBuilder();
187     path.append("/");
188     path.append(TABLE);
189     path.append("/multiget");
190     path.append("/" + COLUMN_1 + "," + CFB);
191     path.append("?row=");
192     path.append(ROW_1);
193     path.append("&row=");
194     path.append(ROW_2);
195 
196     client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
197     client.post(row_6_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_2), extraHdr);
198 
199     Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
200     assertEquals(200, response.getCode());
201     ObjectMapper mapper =
202         new JacksonProvider().locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
203     CellSetModel cellSet = (CellSetModel) mapper.readValue(response.getBody(), CellSetModel.class);
204     assertEquals(2, cellSet.getRows().size());
205     assertEquals(ROW_1, Bytes.toString(cellSet.getRows().get(0).getKey()));
206     assertEquals(VALUE_1, Bytes.toString(cellSet.getRows().get(0).getCells().get(0).getValue()));
207     assertEquals(ROW_2, Bytes.toString(cellSet.getRows().get(1).getKey()));
208     assertEquals(VALUE_2, Bytes.toString(cellSet.getRows().get(1).getCells().get(0).getValue()));
209 
210     client.delete(row_5_url, extraHdr);
211     client.delete(row_6_url, extraHdr);
212 
213   }
214 
215   @Test
216   public void testMultiCellGetJSONNotFound() throws IOException, JAXBException {
217     String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
218 
219     StringBuilder path = new StringBuilder();
220     path.append("/");
221     path.append(TABLE);
222     path.append("/multiget/?row=");
223     path.append(ROW_1);
224     path.append("&row=");
225     path.append(ROW_2);
226 
227     client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
228     Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
229     assertEquals(200, response.getCode());
230     ObjectMapper mapper = new JacksonProvider().locateMapper(CellSetModel.class,
231       MediaType.APPLICATION_JSON_TYPE);
232     CellSetModel cellSet = (CellSetModel) mapper.readValue(response.getBody(), CellSetModel.class);
233     assertEquals(1, cellSet.getRows().size());
234     assertEquals(ROW_1, Bytes.toString(cellSet.getRows().get(0).getKey()));
235     assertEquals(VALUE_1, Bytes.toString(cellSet.getRows().get(0).getCells().get(0).getValue()));
236     client.delete(row_5_url, extraHdr);
237   }
238 
239 }
240