1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.rest;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.IOException;
23 import java.io.StringWriter;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import javax.ws.rs.core.MediaType;
31 import javax.xml.bind.JAXBContext;
32 import javax.xml.bind.JAXBException;
33
34 import org.apache.hadoop.conf.Configuration;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.HColumnDescriptor;
37 import org.apache.hadoop.hbase.HTableDescriptor;
38 import org.apache.hadoop.hbase.NamespaceDescriptor;
39 import org.apache.hadoop.hbase.TableName;
40 import org.apache.hadoop.hbase.client.Admin;
41 import org.apache.hadoop.hbase.rest.client.Client;
42 import org.apache.hadoop.hbase.rest.client.Cluster;
43 import org.apache.hadoop.hbase.rest.client.Response;
44 import org.apache.hadoop.hbase.rest.model.NamespacesInstanceModel;
45 import org.apache.hadoop.hbase.rest.model.TableListModel;
46 import org.apache.hadoop.hbase.rest.model.TableModel;
47 import org.apache.hadoop.hbase.rest.model.TestNamespacesInstanceModel;
48 import org.apache.hadoop.hbase.rest.provider.JacksonProvider;
49 import org.apache.hadoop.hbase.testclassification.MediumTests;
50 import org.apache.hadoop.hbase.util.Bytes;
51 import org.codehaus.jackson.map.ObjectMapper;
52
53 import static org.junit.Assert.*;
54
55 import org.junit.AfterClass;
56 import org.junit.BeforeClass;
57 import org.junit.Test;
58 import org.junit.experimental.categories.Category;
59
60 @Category(MediumTests.class)
61 public class TestNamespacesInstanceResource {
62 private static String NAMESPACE1 = "TestNamespacesInstanceResource1";
63 private static Map<String,String> NAMESPACE1_PROPS = new HashMap<String,String>();
64 private static String NAMESPACE2 = "TestNamespacesInstanceResource2";
65 private static Map<String,String> NAMESPACE2_PROPS = new HashMap<String,String>();
66 private static String NAMESPACE3 = "TestNamespacesInstanceResource3";
67 private static Map<String,String> NAMESPACE3_PROPS = new HashMap<String,String>();
68 private static String NAMESPACE4 = "TestNamespacesInstanceResource4";
69 private static Map<String,String> NAMESPACE4_PROPS = new HashMap<String,String>();
70
71 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
72 private static final HBaseRESTTestingUtility REST_TEST_UTIL =
73 new HBaseRESTTestingUtility();
74 private static Client client;
75 private static JAXBContext context;
76 private static Configuration conf;
77 private static TestNamespacesInstanceModel testNamespacesInstanceModel;
78 protected static ObjectMapper jsonMapper;
79
80 @BeforeClass
81 public static void setUpBeforeClass() throws Exception {
82 conf = TEST_UTIL.getConfiguration();
83 TEST_UTIL.startMiniCluster();
84 REST_TEST_UTIL.startServletContainer(conf);
85 client = new Client(new Cluster().add("localhost",
86 REST_TEST_UTIL.getServletPort()));
87 testNamespacesInstanceModel = new TestNamespacesInstanceModel();
88 context = JAXBContext.newInstance(NamespacesInstanceModel.class, TableListModel.class);
89 jsonMapper = new JacksonProvider()
90 .locateMapper(NamespacesInstanceModel.class, MediaType.APPLICATION_JSON_TYPE);
91 NAMESPACE1_PROPS.put("key1", "value1");
92 NAMESPACE2_PROPS.put("key2a", "value2a");
93 NAMESPACE2_PROPS.put("key2b", "value2b");
94 NAMESPACE3_PROPS.put("key3", "value3");
95 NAMESPACE4_PROPS.put("key4a", "value4a");
96 NAMESPACE4_PROPS.put("key4b", "value4b");
97 }
98
99 @AfterClass
100 public static void tearDownAfterClass() throws Exception {
101 REST_TEST_UTIL.shutdownServletContainer();
102 TEST_UTIL.shutdownMiniCluster();
103 }
104
105 private static byte[] toXML(NamespacesInstanceModel model) throws JAXBException {
106 StringWriter writer = new StringWriter();
107 context.createMarshaller().marshal(model, writer);
108 return Bytes.toBytes(writer.toString());
109 }
110
111 @SuppressWarnings("unchecked")
112 private static <T> T fromXML(byte[] content)
113 throws JAXBException {
114 return (T) context.createUnmarshaller().unmarshal(new ByteArrayInputStream(content));
115 }
116
117 private NamespaceDescriptor findNamespace(Admin admin, String namespaceName) throws IOException{
118 NamespaceDescriptor[] nd = admin.listNamespaceDescriptors();
119 for(int i = 0; i < nd.length; i++){
120 if(nd[i].getName().equals(namespaceName)){
121 return nd[i];
122 }
123 }
124 return null;
125 }
126
127 private void checkNamespaceProperties(NamespaceDescriptor nd, Map<String,String> testProps){
128 checkNamespaceProperties(nd.getConfiguration(), testProps);
129 }
130
131 private void checkNamespaceProperties(Map<String,String> namespaceProps,
132 Map<String,String> testProps){
133 assertTrue(namespaceProps.size() == testProps.size());
134 for(String key: testProps.keySet()){
135 assertEquals(testProps.get(key), namespaceProps.get(key));
136 }
137 }
138
139 private void checkNamespaceTables(List<TableModel> namespaceTables, List<String> testTables){
140 assertEquals(namespaceTables.size(), testTables.size());
141 for(int i = 0 ; i < namespaceTables.size() ; i++){
142 String tableName = ((TableModel) namespaceTables.get(i)).getName();
143 assertTrue(testTables.contains(tableName));
144 }
145 }
146
147 @Test
148 public void testCannotDeleteDefaultAndHbaseNamespaces() throws IOException {
149 String defaultPath = "/namespaces/default";
150 String hbasePath = "/namespaces/hbase";
151 Response response;
152
153
154 Admin admin = TEST_UTIL.getHBaseAdmin();
155 assertNotNull(findNamespace(admin, "default"));
156 assertNotNull(findNamespace(admin, "hbase"));
157
158
159 response = client.delete(defaultPath);
160 assertEquals(503, response.getCode());
161 response = client.delete(hbasePath);
162 assertEquals(503, response.getCode());
163
164 assertNotNull(findNamespace(admin, "default"));
165 assertNotNull(findNamespace(admin, "hbase"));
166 }
167
168 @Test
169 public void testGetNamespaceTablesAndCannotDeleteNamespace() throws IOException, JAXBException {
170 Admin admin = TEST_UTIL.getHBaseAdmin();
171 String nsName = "TestNamespacesInstanceResource5";
172 Response response;
173
174
175 NamespaceDescriptor.Builder nsBuilder = NamespaceDescriptor.create(nsName);
176 NamespaceDescriptor nsd = nsBuilder.build();
177 nsd.setConfiguration("key1", "value1");
178 admin.createNamespace(nsd);
179
180
181 HColumnDescriptor colDesc = new HColumnDescriptor("cf1");
182 TableName tn1 = TableName.valueOf(nsName + ":table1");
183 HTableDescriptor table = new HTableDescriptor(tn1);
184 table.addFamily(colDesc);
185 admin.createTable(table);
186 TableName tn2 = TableName.valueOf(nsName + ":table2");
187 table = new HTableDescriptor(tn2);
188 table.addFamily(colDesc);
189 admin.createTable(table);
190
191 Map<String, String> nsProperties = new HashMap<String,String>();
192 nsProperties.put("key1", "value1");
193 List<String> nsTables = Arrays.asList("table1", "table2");
194
195
196 String namespacePath = "/namespaces/" + nsName;
197 response = client.get(namespacePath);
198 assertEquals(200, response.getCode());
199
200 response = client.get(namespacePath, Constants.MIMETYPE_XML);
201 assertEquals(200, response.getCode());
202 NamespacesInstanceModel model = fromXML(response.getBody());
203 checkNamespaceProperties(model.getProperties(), nsProperties);
204
205 response = client.get(namespacePath, Constants.MIMETYPE_JSON);
206 assertEquals(200, response.getCode());
207 model = jsonMapper.readValue(response.getBody(), NamespacesInstanceModel.class);
208 checkNamespaceProperties(model.getProperties(), nsProperties);
209
210 response = client.get(namespacePath, Constants.MIMETYPE_PROTOBUF);
211 assertEquals(200, response.getCode());
212 model.getObjectFromMessage(response.getBody());
213 checkNamespaceProperties(model.getProperties(), nsProperties);
214
215
216 namespacePath = "/namespaces/" + nsName + "/tables";
217 response = client.get(namespacePath);
218 assertEquals(200, response.getCode());
219
220 response = client.get(namespacePath, Constants.MIMETYPE_XML);
221 assertEquals(200, response.getCode());
222 TableListModel tablemodel = fromXML(response.getBody());
223 checkNamespaceTables(tablemodel.getTables(), nsTables);
224
225 response = client.get(namespacePath, Constants.MIMETYPE_JSON);
226 assertEquals(200, response.getCode());
227 tablemodel = jsonMapper.readValue(response.getBody(), TableListModel.class);
228 checkNamespaceTables(tablemodel.getTables(), nsTables);
229
230 response = client.get(namespacePath, Constants.MIMETYPE_PROTOBUF);
231 assertEquals(200, response.getCode());
232 tablemodel.setTables(new ArrayList<TableModel>());
233 tablemodel.getObjectFromMessage(response.getBody());
234 checkNamespaceTables(tablemodel.getTables(), nsTables);
235
236
237 response = client.delete(namespacePath);
238 namespacePath = "/namespaces/" + nsName;
239 assertEquals(503, response.getCode());
240 }
241
242 @Test
243 public void testInvalidNamespacePostsAndPuts() throws IOException, JAXBException {
244 String namespacePath1 = "/namespaces/" + NAMESPACE1;
245 String namespacePath2 = "/namespaces/" + NAMESPACE2;
246 String namespacePath3 = "/namespaces/" + NAMESPACE3;
247 NamespacesInstanceModel model1;
248 NamespacesInstanceModel model2;
249 NamespacesInstanceModel model3;
250 Response response;
251
252
253 Admin admin = TEST_UTIL.getHBaseAdmin();
254 assertNull(findNamespace(admin, NAMESPACE1));
255 assertNull(findNamespace(admin, NAMESPACE2));
256 assertNull(findNamespace(admin, NAMESPACE3));
257
258 model1 = testNamespacesInstanceModel.buildTestModel(NAMESPACE1, NAMESPACE1_PROPS);
259 testNamespacesInstanceModel.checkModel(model1, NAMESPACE1, NAMESPACE1_PROPS);
260 model2 = testNamespacesInstanceModel.buildTestModel(NAMESPACE2, NAMESPACE2_PROPS);
261 testNamespacesInstanceModel.checkModel(model2, NAMESPACE2, NAMESPACE2_PROPS);
262 model3 = testNamespacesInstanceModel.buildTestModel(NAMESPACE3, NAMESPACE3_PROPS);
263 testNamespacesInstanceModel.checkModel(model3, NAMESPACE3, NAMESPACE3_PROPS);
264
265
266 response = client.post(namespacePath1, Constants.MIMETYPE_JSON, toXML(model1));
267 assertEquals(500, response.getCode());
268 String jsonString = jsonMapper.writeValueAsString(model2);
269 response = client.put(namespacePath2, Constants.MIMETYPE_XML, Bytes.toBytes(jsonString));
270 assertEquals(400, response.getCode());
271 response = client.post(namespacePath3, Constants.MIMETYPE_PROTOBUF, toXML(model1));
272 assertEquals(500, response.getCode());
273
274 NamespaceDescriptor nd1 = findNamespace(admin, NAMESPACE1);
275 NamespaceDescriptor nd2 = findNamespace(admin, NAMESPACE2);
276 NamespaceDescriptor nd3 = findNamespace(admin, NAMESPACE3);
277 assertNull(nd1);
278 assertNull(nd2);
279 assertNull(nd3);
280 }
281
282 @Test
283 public void testNamespaceCreateAndDeleteXMLAndJSON() throws IOException, JAXBException {
284 String namespacePath1 = "/namespaces/" + NAMESPACE1;
285 String namespacePath2 = "/namespaces/" + NAMESPACE2;
286 NamespacesInstanceModel model1;
287 NamespacesInstanceModel model2;
288 Response response;
289
290
291 Admin admin = TEST_UTIL.getHBaseAdmin();
292 assertNull(findNamespace(admin, NAMESPACE1));
293 assertNull(findNamespace(admin, NAMESPACE2));
294
295 model1 = testNamespacesInstanceModel.buildTestModel(NAMESPACE1, NAMESPACE1_PROPS);
296 testNamespacesInstanceModel.checkModel(model1, NAMESPACE1, NAMESPACE1_PROPS);
297 model2 = testNamespacesInstanceModel.buildTestModel(NAMESPACE2, NAMESPACE2_PROPS);
298 testNamespacesInstanceModel.checkModel(model2, NAMESPACE2, NAMESPACE2_PROPS);
299
300
301 response = client.put(namespacePath1, Constants.MIMETYPE_XML, toXML(model1));
302 assertEquals(403, response.getCode());
303 String jsonString = jsonMapper.writeValueAsString(model2);
304 response = client.put(namespacePath2, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
305 assertEquals(403, response.getCode());
306
307
308 conf.set("hbase.rest.readonly", "true");
309 response = client.post(namespacePath1, Constants.MIMETYPE_XML, toXML(model1));
310 assertEquals(403, response.getCode());
311 jsonString = jsonMapper.writeValueAsString(model2);
312 response = client.post(namespacePath2, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
313 assertEquals(403, response.getCode());
314 NamespaceDescriptor nd1 = findNamespace(admin, NAMESPACE1);
315 NamespaceDescriptor nd2 = findNamespace(admin, NAMESPACE2);
316 assertNull(nd1);
317 assertNull(nd2);
318 conf.set("hbase.rest.readonly", "false");
319
320
321 response = client.post(namespacePath1, Constants.MIMETYPE_XML, toXML(model1));
322 assertEquals(201, response.getCode());
323 jsonString = jsonMapper.writeValueAsString(model2);
324 response = client.post(namespacePath2, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
325 assertEquals(201, response.getCode());
326
327
328 nd1 = findNamespace(admin, NAMESPACE1);
329 nd2 = findNamespace(admin, NAMESPACE2);
330 assertNotNull(nd1);
331 assertNotNull(nd2);
332 checkNamespaceProperties(nd1, NAMESPACE1_PROPS);
333 checkNamespaceProperties(nd1, NAMESPACE1_PROPS);
334
335
336 conf.set("hbase.rest.readonly", "true");
337 response = client.delete(namespacePath1);
338 assertEquals(403, response.getCode());
339 response = client.delete(namespacePath2);
340 assertEquals(403, response.getCode());
341 nd1 = findNamespace(admin, NAMESPACE1);
342 nd2 = findNamespace(admin, NAMESPACE2);
343 assertNotNull(nd1);
344 assertNotNull(nd2);
345 conf.set("hbase.rest.readonly", "false");
346
347
348 response = client.delete(namespacePath1);
349 assertEquals(200, response.getCode());
350 response = client.delete(namespacePath2);
351 assertEquals(200, response.getCode());
352 nd1 = findNamespace(admin, NAMESPACE1);
353 nd2 = findNamespace(admin, NAMESPACE2);
354 assertNull(nd1);
355 assertNull(nd2);
356 }
357
358 @Test
359 public void testNamespaceCreateAndDeletePBAndNoBody() throws IOException, JAXBException {
360 String namespacePath3 = "/namespaces/" + NAMESPACE3;
361 String namespacePath4 = "/namespaces/" + NAMESPACE4;
362 NamespacesInstanceModel model3;
363 NamespacesInstanceModel model4;
364 Response response;
365
366
367 Admin admin = TEST_UTIL.getHBaseAdmin();
368 assertNull(findNamespace(admin, NAMESPACE3));
369 assertNull(findNamespace(admin, NAMESPACE4));
370
371 model3 = testNamespacesInstanceModel.buildTestModel(NAMESPACE3, NAMESPACE3_PROPS);
372 testNamespacesInstanceModel.checkModel(model3, NAMESPACE3, NAMESPACE3_PROPS);
373 model4 = testNamespacesInstanceModel.buildTestModel(NAMESPACE4, NAMESPACE4_PROPS);
374 testNamespacesInstanceModel.checkModel(model4, NAMESPACE4, NAMESPACE4_PROPS);
375
376
377 response = client.put(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
378 assertEquals(403, response.getCode());
379 response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
380 model4.createProtobufOutput());
381 assertEquals(403, response.getCode());
382
383
384 conf.set("hbase.rest.readonly", "true");
385 response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
386 assertEquals(403, response.getCode());
387 response = client.put(namespacePath4, Constants.MIMETYPE_PROTOBUF,
388 model4.createProtobufOutput());
389 assertEquals(403, response.getCode());
390 NamespaceDescriptor nd3 = findNamespace(admin, NAMESPACE3);
391 NamespaceDescriptor nd4 = findNamespace(admin, NAMESPACE4);
392 assertNull(nd3);
393 assertNull(nd4);
394 conf.set("hbase.rest.readonly", "false");
395
396
397 response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
398 assertEquals(201, response.getCode());
399 response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
400 model4.createProtobufOutput());
401 assertEquals(201, response.getCode());
402
403
404 nd3 = findNamespace(admin, NAMESPACE3);
405 nd4 = findNamespace(admin, NAMESPACE4);
406 assertNotNull(nd3);
407 assertNotNull(nd4);
408 checkNamespaceProperties(nd3, new HashMap<String,String>());
409 checkNamespaceProperties(nd4, NAMESPACE4_PROPS);
410
411
412 response = client.post(namespacePath3, Constants.MIMETYPE_BINARY, new byte[]{});
413 assertEquals(403, response.getCode());
414 response = client.post(namespacePath4, Constants.MIMETYPE_PROTOBUF,
415 model4.createProtobufOutput());
416 assertEquals(403, response.getCode());
417
418
419 conf.set("hbase.rest.readonly", "true");
420 response = client.delete(namespacePath3);
421 assertEquals(403, response.getCode());
422 response = client.delete(namespacePath4);
423 assertEquals(403, response.getCode());
424 nd3 = findNamespace(admin, NAMESPACE3);
425 nd4 = findNamespace(admin, NAMESPACE4);
426 assertNotNull(nd3);
427 assertNotNull(nd4);
428 conf.set("hbase.rest.readonly", "false");
429
430
431 response = client.delete(namespacePath3);
432 assertEquals(200, response.getCode());
433 response = client.delete(namespacePath4);
434 assertEquals(200, response.getCode());
435 nd3 = findNamespace(admin, NAMESPACE3);
436 nd4 = findNamespace(admin, NAMESPACE4);
437 assertNull(nd3);
438 assertNull(nd4);
439 }
440 }