Revert "HBASE-26523 Upgrade hbase-thirdparty dependency to 4.0.0 (#3910)"
[hbase.git] / hbase-rest / src / test / java / org / apache / hadoop / hbase / rest / TestSchemaResource.java
blob14768f9da50403f2b7ddc9a3949ec3ee948e54f5
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.rest;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
24 import java.io.ByteArrayInputStream;
25 import java.io.IOException;
26 import java.io.StringWriter;
27 import java.util.Collection;
28 import javax.xml.bind.JAXBContext;
29 import javax.xml.bind.JAXBException;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.hbase.HBaseClassTestRule;
32 import org.apache.hadoop.hbase.HBaseCommonTestingUtil;
33 import org.apache.hadoop.hbase.HBaseTestingUtil;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.client.Admin;
36 import org.apache.hadoop.hbase.rest.client.Client;
37 import org.apache.hadoop.hbase.rest.client.Cluster;
38 import org.apache.hadoop.hbase.rest.client.Response;
39 import org.apache.hadoop.hbase.rest.model.ColumnSchemaModel;
40 import org.apache.hadoop.hbase.rest.model.TableSchemaModel;
41 import org.apache.hadoop.hbase.rest.model.TestTableSchemaModel;
42 import org.apache.hadoop.hbase.testclassification.MediumTests;
43 import org.apache.hadoop.hbase.testclassification.RestTests;
44 import org.apache.hadoop.hbase.util.Bytes;
45 import org.apache.http.Header;
46 import org.apache.http.message.BasicHeader;
47 import org.junit.After;
48 import org.junit.AfterClass;
49 import org.junit.BeforeClass;
50 import org.junit.ClassRule;
51 import org.junit.Test;
52 import org.junit.experimental.categories.Category;
53 import org.junit.runner.RunWith;
54 import org.junit.runners.Parameterized;
56 @Category({RestTests.class, MediumTests.class})
57 @RunWith(Parameterized.class)
58 public class TestSchemaResource {
59 @ClassRule
60 public static final HBaseClassTestRule CLASS_RULE =
61 HBaseClassTestRule.forClass(TestSchemaResource.class);
63 private static String TABLE1 = "TestSchemaResource1";
64 private static String TABLE2 = "TestSchemaResource2";
66 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
67 private static final HBaseRESTTestingUtility REST_TEST_UTIL =
68 new HBaseRESTTestingUtility();
69 private static Client client;
70 private static JAXBContext context;
71 private static Configuration conf;
72 private static TestTableSchemaModel testTableSchemaModel;
73 private static Header extraHdr = null;
75 private static boolean csrfEnabled = true;
77 @Parameterized.Parameters
78 public static Collection<Object[]> parameters() {
79 return HBaseCommonTestingUtil.BOOLEAN_PARAMETERIZED;
82 public TestSchemaResource(Boolean csrf) {
83 csrfEnabled = csrf;
86 @BeforeClass
87 public static void setUpBeforeClass() throws Exception {
88 conf = TEST_UTIL.getConfiguration();
89 conf.setBoolean(RESTServer.REST_CSRF_ENABLED_KEY, csrfEnabled);
90 if (csrfEnabled) {
91 conf.set(RESTServer.REST_CSRF_BROWSER_USERAGENTS_REGEX_KEY, ".*");
93 extraHdr = new BasicHeader(RESTServer.REST_CSRF_CUSTOM_HEADER_DEFAULT, "");
94 TEST_UTIL.startMiniCluster();
95 REST_TEST_UTIL.startServletContainer(conf);
96 client = new Client(new Cluster().add("localhost",
97 REST_TEST_UTIL.getServletPort()));
98 testTableSchemaModel = new TestTableSchemaModel();
99 context = JAXBContext.newInstance(
100 ColumnSchemaModel.class,
101 TableSchemaModel.class);
104 @AfterClass
105 public static void tearDownAfterClass() throws Exception {
106 REST_TEST_UTIL.shutdownServletContainer();
107 TEST_UTIL.shutdownMiniCluster();
110 @After
111 public void tearDown() throws Exception {
112 Admin admin = TEST_UTIL.getAdmin();
114 for (String table : new String[] {TABLE1, TABLE2}) {
115 TableName t = TableName.valueOf(table);
116 if (admin.tableExists(t)) {
117 admin.disableTable(t);
118 admin.deleteTable(t);
122 conf.set("hbase.rest.readonly", "false");
125 private static byte[] toXML(TableSchemaModel model) throws JAXBException {
126 StringWriter writer = new StringWriter();
127 context.createMarshaller().marshal(model, writer);
128 return Bytes.toBytes(writer.toString());
131 private static TableSchemaModel fromXML(byte[] content)
132 throws JAXBException {
133 return (TableSchemaModel) context.createUnmarshaller()
134 .unmarshal(new ByteArrayInputStream(content));
137 @Test
138 public void testTableCreateAndDeleteXML() throws IOException, JAXBException {
139 String schemaPath = "/" + TABLE1 + "/schema";
140 TableSchemaModel model;
141 Response response;
143 Admin admin = TEST_UTIL.getAdmin();
144 assertFalse("Table " + TABLE1 + " should not exist",
145 admin.tableExists(TableName.valueOf(TABLE1)));
147 // create the table
148 model = testTableSchemaModel.buildTestModel(TABLE1);
149 testTableSchemaModel.checkModel(model, TABLE1);
150 if (csrfEnabled) {
151 // test put operation is forbidden without custom header
152 response = client.put(schemaPath, Constants.MIMETYPE_XML, toXML(model));
153 assertEquals(400, response.getCode());
156 response = client.put(schemaPath, Constants.MIMETYPE_XML, toXML(model), extraHdr);
157 assertEquals("put failed with csrf " + (csrfEnabled ? "enabled" : "disabled"),
158 201, response.getCode());
160 // recall the same put operation but in read-only mode
161 conf.set("hbase.rest.readonly", "true");
162 response = client.put(schemaPath, Constants.MIMETYPE_XML, toXML(model), extraHdr);
163 assertEquals(403, response.getCode());
165 // retrieve the schema and validate it
166 response = client.get(schemaPath, Constants.MIMETYPE_XML);
167 assertEquals(200, response.getCode());
168 assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type"));
169 model = fromXML(response.getBody());
170 testTableSchemaModel.checkModel(model, TABLE1);
172 // with json retrieve the schema and validate it
173 response = client.get(schemaPath, Constants.MIMETYPE_JSON);
174 assertEquals(200, response.getCode());
175 assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type"));
176 model = testTableSchemaModel.fromJSON(Bytes.toString(response.getBody()));
177 testTableSchemaModel.checkModel(model, TABLE1);
179 if (csrfEnabled) {
180 // test delete schema operation is forbidden without custom header
181 response = client.delete(schemaPath);
182 assertEquals(400, response.getCode());
185 // test delete schema operation is forbidden in read-only mode
186 response = client.delete(schemaPath, extraHdr);
187 assertEquals(403, response.getCode());
189 // return read-only setting back to default
190 conf.set("hbase.rest.readonly", "false");
192 // delete the table and make sure HBase concurs
193 response = client.delete(schemaPath, extraHdr);
194 assertEquals(200, response.getCode());
195 assertFalse(admin.tableExists(TableName.valueOf(TABLE1)));
198 @Test
199 public void testTableCreateAndDeletePB() throws IOException {
200 String schemaPath = "/" + TABLE2 + "/schema";
201 TableSchemaModel model;
202 Response response;
204 Admin admin = TEST_UTIL.getAdmin();
205 assertFalse(admin.tableExists(TableName.valueOf(TABLE2)));
207 // create the table
208 model = testTableSchemaModel.buildTestModel(TABLE2);
209 testTableSchemaModel.checkModel(model, TABLE2);
211 if (csrfEnabled) {
212 // test put operation is forbidden without custom header
213 response = client.put(schemaPath, Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput());
214 assertEquals(400, response.getCode());
216 response = client.put(schemaPath, Constants.MIMETYPE_PROTOBUF,
217 model.createProtobufOutput(), extraHdr);
218 assertEquals("put failed with csrf " + (csrfEnabled ? "enabled" : "disabled"),
219 201, response.getCode());
221 // recall the same put operation but in read-only mode
222 conf.set("hbase.rest.readonly", "true");
223 response = client.put(schemaPath, Constants.MIMETYPE_PROTOBUF,
224 model.createProtobufOutput(), extraHdr);
225 assertNotNull(extraHdr);
226 assertEquals(403, response.getCode());
228 // retrieve the schema and validate it
229 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF);
230 assertEquals(200, response.getCode());
231 assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type"));
232 model = new TableSchemaModel();
233 model.getObjectFromMessage(response.getBody());
234 testTableSchemaModel.checkModel(model, TABLE2);
236 // retrieve the schema and validate it with alternate pbuf type
237 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF_IETF);
238 assertEquals(200, response.getCode());
239 assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type"));
240 model = new TableSchemaModel();
241 model.getObjectFromMessage(response.getBody());
242 testTableSchemaModel.checkModel(model, TABLE2);
244 if (csrfEnabled) {
245 // test delete schema operation is forbidden without custom header
246 response = client.delete(schemaPath);
247 assertEquals(400, response.getCode());
250 // test delete schema operation is forbidden in read-only mode
251 response = client.delete(schemaPath, extraHdr);
252 assertEquals(403, response.getCode());
254 // return read-only setting back to default
255 conf.set("hbase.rest.readonly", "false");
257 // delete the table and make sure HBase concurs
258 response = client.delete(schemaPath, extraHdr);
259 assertEquals(200, response.getCode());
260 assertFalse(admin.tableExists(TableName.valueOf(TABLE2)));