Revert "HBASE-26523 Upgrade hbase-thirdparty dependency to 4.0.0 (#3910)"
[hbase.git] / hbase-rest / src / main / java / org / apache / hadoop / hbase / rest / SchemaResource.java
blob2194f54f9bddf1ed19c758cd30c119dbec60768a
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 java.io.IOException;
21 import java.util.Map;
22 import javax.ws.rs.Consumes;
23 import javax.ws.rs.DELETE;
24 import javax.ws.rs.GET;
25 import javax.ws.rs.POST;
26 import javax.ws.rs.PUT;
27 import javax.ws.rs.Produces;
28 import javax.ws.rs.WebApplicationException;
29 import javax.ws.rs.core.CacheControl;
30 import javax.ws.rs.core.Context;
31 import javax.ws.rs.core.Response;
32 import javax.ws.rs.core.Response.ResponseBuilder;
33 import javax.ws.rs.core.UriInfo;
34 import javax.xml.namespace.QName;
35 import org.apache.hadoop.hbase.TableExistsException;
36 import org.apache.hadoop.hbase.TableName;
37 import org.apache.hadoop.hbase.TableNotEnabledException;
38 import org.apache.hadoop.hbase.TableNotFoundException;
39 import org.apache.hadoop.hbase.client.Admin;
40 import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
41 import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
42 import org.apache.hadoop.hbase.client.Table;
43 import org.apache.hadoop.hbase.client.TableDescriptor;
44 import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
45 import org.apache.hadoop.hbase.rest.model.ColumnSchemaModel;
46 import org.apache.hadoop.hbase.rest.model.TableSchemaModel;
47 import org.apache.hadoop.hbase.util.Bytes;
48 import org.apache.yetus.audience.InterfaceAudience;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
52 @InterfaceAudience.Private
53 public class SchemaResource extends ResourceBase {
54 private static final Logger LOG = LoggerFactory.getLogger(SchemaResource.class);
56 static CacheControl cacheControl;
57 static {
58 cacheControl = new CacheControl();
59 cacheControl.setNoCache(true);
60 cacheControl.setNoTransform(false);
63 TableResource tableResource;
65 /**
66 * Constructor
68 public SchemaResource(TableResource tableResource) throws IOException {
69 super();
70 this.tableResource = tableResource;
73 private TableDescriptor getTableSchema() throws IOException, TableNotFoundException {
74 try (Table table = servlet.getTable(tableResource.getName())) {
75 return table.getDescriptor();
79 @GET
80 @Produces({MIMETYPE_TEXT, MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
81 MIMETYPE_PROTOBUF_IETF})
82 public Response get(final @Context UriInfo uriInfo) {
83 if (LOG.isTraceEnabled()) {
84 LOG.trace("GET " + uriInfo.getAbsolutePath());
86 servlet.getMetrics().incrementRequests(1);
87 try {
88 ResponseBuilder response =
89 Response.ok(new TableSchemaModel(getTableSchema()));
90 response.cacheControl(cacheControl);
91 servlet.getMetrics().incrementSucessfulGetRequests(1);
92 return response.build();
93 } catch (Exception e) {
94 servlet.getMetrics().incrementFailedGetRequests(1);
95 return processException(e);
99 private Response replace(final TableName name, final TableSchemaModel model,
100 final UriInfo uriInfo, final Admin admin) {
101 if (servlet.isReadOnly()) {
102 return Response.status(Response.Status.FORBIDDEN)
103 .type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
104 .build();
106 try {
107 TableDescriptorBuilder tableDescriptorBuilder =
108 TableDescriptorBuilder.newBuilder(name);
109 for (Map.Entry<QName, Object> e : model.getAny().entrySet()) {
110 tableDescriptorBuilder.setValue(e.getKey().getLocalPart(), e.getValue().toString());
112 for (ColumnSchemaModel family : model.getColumns()) {
113 ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder =
114 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(family.getName()));
115 for (Map.Entry<QName, Object> e : family.getAny().entrySet()) {
116 columnFamilyDescriptorBuilder.setValue(e.getKey().getLocalPart(),
117 e.getValue().toString());
119 tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptorBuilder.build());
121 TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
122 if (admin.tableExists(name)) {
123 admin.disableTable(name);
124 admin.modifyTable(tableDescriptor);
125 admin.enableTable(name);
126 servlet.getMetrics().incrementSucessfulPutRequests(1);
127 } else {
128 try {
129 admin.createTable(tableDescriptor);
130 servlet.getMetrics().incrementSucessfulPutRequests(1);
131 } catch (TableExistsException e) {
132 // race, someone else created a table with the same name
133 return Response.status(Response.Status.NOT_MODIFIED)
134 .type(MIMETYPE_TEXT).entity("Not modified" + CRLF)
135 .build();
138 return Response.created(uriInfo.getAbsolutePath()).build();
139 } catch (Exception e) {
140 LOG.info("Caught exception", e);
141 servlet.getMetrics().incrementFailedPutRequests(1);
142 return processException(e);
146 private Response update(final TableName name, final TableSchemaModel model,
147 final UriInfo uriInfo, final Admin admin) {
148 if (servlet.isReadOnly()) {
149 return Response.status(Response.Status.FORBIDDEN)
150 .type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
151 .build();
153 try {
154 TableDescriptorBuilder tableDescriptorBuilder =
155 TableDescriptorBuilder.newBuilder(admin.getDescriptor(name));
156 admin.disableTable(name);
157 try {
158 for (ColumnSchemaModel family : model.getColumns()) {
159 ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder =
160 ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(family.getName()));
161 for (Map.Entry<QName, Object> e : family.getAny().entrySet()) {
162 columnFamilyDescriptorBuilder.setValue(e.getKey().getLocalPart(),
163 e.getValue().toString());
165 TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
166 ColumnFamilyDescriptor columnFamilyDescriptor = columnFamilyDescriptorBuilder.build();
167 if (tableDescriptor.hasColumnFamily(columnFamilyDescriptor.getName())) {
168 admin.modifyColumnFamily(name, columnFamilyDescriptor);
169 } else {
170 admin.addColumnFamily(name, columnFamilyDescriptor);
173 } catch (IOException e) {
174 return Response.status(Response.Status.SERVICE_UNAVAILABLE)
175 .type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
176 .build();
177 } finally {
178 admin.enableTable(TableName.valueOf(tableResource.getName()));
180 servlet.getMetrics().incrementSucessfulPutRequests(1);
181 return Response.ok().build();
182 } catch (Exception e) {
183 servlet.getMetrics().incrementFailedPutRequests(1);
184 return processException(e);
188 private Response update(final TableSchemaModel model, final boolean replace,
189 final UriInfo uriInfo) {
190 try {
191 TableName name = TableName.valueOf(tableResource.getName());
192 Admin admin = servlet.getAdmin();
193 if (replace || !admin.tableExists(name)) {
194 return replace(name, model, uriInfo, admin);
195 } else {
196 return update(name, model, uriInfo, admin);
198 } catch (Exception e) {
199 servlet.getMetrics().incrementFailedPutRequests(1);
200 // Avoid re-unwrapping the exception
201 if (e instanceof WebApplicationException) {
202 throw (WebApplicationException) e;
204 return processException(e);
208 @PUT
209 @Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
210 MIMETYPE_PROTOBUF_IETF})
211 public Response put(final TableSchemaModel model,
212 final @Context UriInfo uriInfo) {
213 if (LOG.isTraceEnabled()) {
214 LOG.trace("PUT " + uriInfo.getAbsolutePath());
216 servlet.getMetrics().incrementRequests(1);
217 return update(model, true, uriInfo);
220 @POST
221 @Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
222 MIMETYPE_PROTOBUF_IETF})
223 public Response post(final TableSchemaModel model,
224 final @Context UriInfo uriInfo) {
225 if (LOG.isTraceEnabled()) {
226 LOG.trace("PUT " + uriInfo.getAbsolutePath());
228 servlet.getMetrics().incrementRequests(1);
229 return update(model, false, uriInfo);
232 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="DE_MIGHT_IGNORE",
233 justification="Expected")
234 @DELETE
235 public Response delete(final @Context UriInfo uriInfo) {
236 if (LOG.isTraceEnabled()) {
237 LOG.trace("DELETE " + uriInfo.getAbsolutePath());
239 servlet.getMetrics().incrementRequests(1);
240 if (servlet.isReadOnly()) {
241 return Response.status(Response.Status.FORBIDDEN).type(MIMETYPE_TEXT)
242 .entity("Forbidden" + CRLF).build();
244 try {
245 Admin admin = servlet.getAdmin();
246 try {
247 admin.disableTable(TableName.valueOf(tableResource.getName()));
248 } catch (TableNotEnabledException e) { /* this is what we want anyway */ }
249 admin.deleteTable(TableName.valueOf(tableResource.getName()));
250 servlet.getMetrics().incrementSucessfulDeleteRequests(1);
251 return Response.ok().build();
252 } catch (Exception e) {
253 servlet.getMetrics().incrementFailedDeleteRequests(1);
254 return processException(e);