1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.rest;
19
20 import static org.junit.Assert.assertEquals;
21
22 import com.fasterxml.jackson.databind.ObjectMapper;
23 import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
24
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.List;
29 import javax.ws.rs.core.MediaType;
30 import javax.xml.bind.JAXBContext;
31
32 import org.apache.commons.httpclient.Header;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.HBaseTestingUtility;
35 import org.apache.hadoop.hbase.HColumnDescriptor;
36 import org.apache.hadoop.hbase.HTableDescriptor;
37 import org.apache.hadoop.hbase.TableName;
38 import org.apache.hadoop.hbase.client.Admin;
39 import org.apache.hadoop.hbase.rest.client.Client;
40 import org.apache.hadoop.hbase.rest.client.Cluster;
41 import org.apache.hadoop.hbase.rest.client.Response;
42 import org.apache.hadoop.hbase.rest.model.CellModel;
43 import org.apache.hadoop.hbase.rest.model.CellSetModel;
44 import org.apache.hadoop.hbase.rest.model.RowModel;
45 import org.apache.hadoop.hbase.rest.provider.JacksonProvider;
46 import org.apache.hadoop.hbase.testclassification.MediumTests;
47 import org.apache.hadoop.hbase.util.Bytes;
48
49 import org.junit.AfterClass;
50 import org.junit.BeforeClass;
51 import org.junit.Test;
52 import org.junit.experimental.categories.Category;
53 import org.junit.runner.RunWith;
54 import org.junit.runners.Parameterized;
55
56 @Category(MediumTests.class)
57 @RunWith(Parameterized.class)
58 public class TestMultiRowResource {
59 private static final TableName TABLE = TableName.valueOf("TestRowResource");
60 private static final String CFA = "a";
61 private static final String CFB = "b";
62 private static final String COLUMN_1 = CFA + ":1";
63 private static final String COLUMN_2 = CFB + ":2";
64 private static final String ROW_1 = "testrow5";
65 private static final String VALUE_1 = "testvalue5";
66 private static final String ROW_2 = "testrow6";
67 private static final String VALUE_2 = "testvalue6";
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 @BeforeClass
93 public static void setUpBeforeClass() throws Exception {
94 conf = TEST_UTIL.getConfiguration();
95 conf.setBoolean(RESTServer.REST_CSRF_ENABLED_KEY, csrfEnabled);
96 extraHdr = new Header(RESTServer.REST_CSRF_CUSTOM_HEADER_DEFAULT, "");
97 TEST_UTIL.startMiniCluster();
98 REST_TEST_UTIL.startServletContainer(conf);
99 context = JAXBContext.newInstance(
100 CellModel.class,
101 CellSetModel.class,
102 RowModel.class);
103 client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort()));
104 Admin admin = TEST_UTIL.getHBaseAdmin();
105 if (admin.tableExists(TABLE)) {
106 return;
107 }
108 HTableDescriptor htd = new HTableDescriptor(TABLE);
109 htd.addFamily(new HColumnDescriptor(CFA));
110 htd.addFamily(new HColumnDescriptor(CFB));
111 admin.createTable(htd);
112 }
113
114 @AfterClass
115 public static void tearDownAfterClass() throws Exception {
116 REST_TEST_UTIL.shutdownServletContainer();
117 TEST_UTIL.shutdownMiniCluster();
118 }
119
120 @Test
121 public void testMultiCellGetJSON() throws IOException {
122 String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
123 String row_6_url = "/" + TABLE + "/" + ROW_2 + "/" + COLUMN_2;
124
125 StringBuilder path = new StringBuilder();
126 path.append("/");
127 path.append(TABLE);
128 path.append("/multiget/?row=");
129 path.append(ROW_1);
130 path.append("&row=");
131 path.append(ROW_2);
132
133 if (csrfEnabled) {
134 Response response = client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1));
135 assertEquals(400, response.getCode());
136 }
137
138 client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
139 client.post(row_6_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_2), extraHdr);
140
141 Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
142 assertEquals(200, response.getCode());
143 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
144
145 client.delete(row_5_url, extraHdr);
146 client.delete(row_6_url, extraHdr);
147 }
148
149 @Test
150 public void testMultiCellGetXML() throws IOException {
151 String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
152 String row_6_url = "/" + TABLE + "/" + ROW_2 + "/" + COLUMN_2;
153
154 StringBuilder path = new StringBuilder();
155 path.append("/");
156 path.append(TABLE);
157 path.append("/multiget/?row=");
158 path.append(ROW_1);
159 path.append("&row=");
160 path.append(ROW_2);
161
162 client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
163 client.post(row_6_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_2), extraHdr);
164
165 Response response = client.get(path.toString(), Constants.MIMETYPE_XML);
166 assertEquals(200, response.getCode());
167 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
168
169 client.delete(row_5_url, extraHdr);
170 client.delete(row_6_url, extraHdr);
171 }
172
173 @Test
174 public void testMultiCellGetWithColsJSON() throws IOException {
175 String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
176 String row_6_url = "/" + TABLE + "/" + ROW_2 + "/" + COLUMN_2;
177
178 StringBuilder path = new StringBuilder();
179 path.append("/");
180 path.append(TABLE);
181 path.append("/multiget");
182 path.append("/" + COLUMN_1 + "," + CFB);
183 path.append("?row=");
184 path.append(ROW_1);
185 path.append("&row=");
186 path.append(ROW_2);
187
188 client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
189 client.post(row_6_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_2), extraHdr);
190
191 Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
192 assertEquals(200, response.getCode());
193 ObjectMapper mapper =
194 new JacksonProvider().locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
195 CellSetModel cellSet = (CellSetModel) mapper.readValue(response.getBody(), CellSetModel.class);
196 assertEquals(2, cellSet.getRows().size());
197 assertEquals(ROW_1, Bytes.toString(cellSet.getRows().get(0).getKey()));
198 assertEquals(VALUE_1, Bytes.toString(cellSet.getRows().get(0).getCells().get(0).getValue()));
199 assertEquals(ROW_2, Bytes.toString(cellSet.getRows().get(1).getKey()));
200 assertEquals(VALUE_2, Bytes.toString(cellSet.getRows().get(1).getCells().get(0).getValue()));
201
202 client.delete(row_5_url, extraHdr);
203 client.delete(row_6_url, extraHdr);
204 }
205
206 @Test
207 public void testMultiCellGetJSONNotFound() throws IOException {
208 String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
209
210 StringBuilder path = new StringBuilder();
211 path.append("/");
212 path.append(TABLE);
213 path.append("/multiget/?row=");
214 path.append(ROW_1);
215 path.append("&row=");
216 path.append(ROW_2);
217
218 client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
219 Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
220 assertEquals(200, response.getCode());
221 ObjectMapper mapper = new JacksonProvider().locateMapper(CellSetModel.class,
222 MediaType.APPLICATION_JSON_TYPE);
223 CellSetModel cellSet = (CellSetModel) mapper.readValue(response.getBody(), CellSetModel.class);
224 assertEquals(1, cellSet.getRows().size());
225 assertEquals(ROW_1, Bytes.toString(cellSet.getRows().get(0).getKey()));
226 assertEquals(VALUE_1, Bytes.toString(cellSet.getRows().get(0).getCells().get(0).getValue()));
227 client.delete(row_5_url, extraHdr);
228 }
229
230 @Test
231 public void testMultiCellGetWithColsInQueryPathJSON() throws IOException {
232 String row_5_url = "/" + TABLE + "/" + ROW_1 + "/" + COLUMN_1;
233 String row_6_url = "/" + TABLE + "/" + ROW_2 + "/" + COLUMN_2;
234
235 StringBuilder path = new StringBuilder();
236 path.append("/");
237 path.append(TABLE);
238 path.append("/multiget/?row=");
239 path.append(ROW_1);
240 path.append("/");
241 path.append(COLUMN_1);
242 path.append("&row=");
243 path.append(ROW_2);
244 path.append("/");
245 path.append(COLUMN_1);
246
247 client.post(row_5_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_1), extraHdr);
248 client.post(row_6_url, Constants.MIMETYPE_BINARY, Bytes.toBytes(VALUE_2), extraHdr);
249
250 Response response = client.get(path.toString(), Constants.MIMETYPE_JSON);
251 assertEquals(200, response.getCode());
252 ObjectMapper mapper = new JacksonJaxbJsonProvider().locateMapper(
253 CellSetModel.class, MediaType.APPLICATION_JSON_TYPE);
254 CellSetModel cellSet = mapper.readValue(response.getBody(), CellSetModel.class);
255 assertEquals(1, cellSet.getRows().size());
256 assertEquals(ROW_1, Bytes.toString(cellSet.getRows().get(0).getKey()));
257 assertEquals(VALUE_1, Bytes.toString(cellSet.getRows().get(0).getCells().get(0).getValue()));
258
259 client.delete(row_5_url, extraHdr);
260 client.delete(row_6_url, extraHdr);
261 }
262 }