1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.rest;
21
22 import java.io.IOException;
23 import java.util.List;
24
25 import javax.ws.rs.DefaultValue;
26 import javax.ws.rs.Encoded;
27 import javax.ws.rs.Path;
28 import javax.ws.rs.PathParam;
29 import javax.ws.rs.QueryParam;
30
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.hadoop.hbase.KeyValue;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.classification.InterfaceAudience;
37 import org.apache.hadoop.hbase.client.Scan;
38 import org.apache.hadoop.hbase.client.Table;
39 import org.apache.hadoop.hbase.filter.Filter;
40 import org.apache.hadoop.hbase.filter.FilterList;
41 import org.apache.hadoop.hbase.filter.ParseFilter;
42 import org.apache.hadoop.hbase.filter.PrefixFilter;
43 import org.apache.hadoop.hbase.util.Bytes;
44
45 @InterfaceAudience.Private
46 public class TableResource extends ResourceBase {
47
48 String table;
49 private static final Log LOG = LogFactory.getLog(TableResource.class);
50
51
52
53
54
55
56 public TableResource(String table) throws IOException {
57 super();
58 this.table = table;
59 }
60
61
62 String getName() {
63 return table;
64 }
65
66
67
68
69
70 boolean exists() throws IOException {
71 return servlet.getAdmin().tableExists(TableName.valueOf(table));
72 }
73
74 @Path("exists")
75 public ExistsResource getExistsResource() throws IOException {
76 return new ExistsResource(this);
77 }
78
79 @Path("regions")
80 public RegionsResource getRegionsResource() throws IOException {
81 return new RegionsResource(this);
82 }
83
84 @Path("scanner")
85 public ScannerResource getScannerResource() throws IOException {
86 return new ScannerResource(this);
87 }
88
89 @Path("schema")
90 public SchemaResource getSchemaResource() throws IOException {
91 return new SchemaResource(this);
92 }
93
94 @Path("{multiget: multiget.*}")
95 public MultiRowResource getMultipleRowResource(final @QueryParam("v") String versions,
96 @PathParam("multiget") String path) throws IOException {
97 return new MultiRowResource(this, versions, path.replace("multiget", "").replace("/", ""));
98 }
99
100 @Path("{rowspec: [^*]+}")
101 public RowResource getRowResource(
102
103
104 final @PathParam("rowspec") @Encoded String rowspec,
105 final @QueryParam("v") String versions,
106 final @QueryParam("check") String check,
107 final @QueryParam("rr") String returnResult) throws IOException {
108 return new RowResource(this, rowspec, versions, check, returnResult);
109 }
110
111 @Path("{suffixglobbingspec: .*\\*/.+}")
112 public RowResource getRowResourceWithSuffixGlobbing(
113
114
115 final @PathParam("suffixglobbingspec") @Encoded String suffixglobbingspec,
116 final @QueryParam("v") String versions,
117 final @QueryParam("check") String check,
118 final @QueryParam("rr") String returnResult) throws IOException {
119 return new RowResource(this, suffixglobbingspec, versions, check, returnResult);
120 }
121
122 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="REC_CATCH_EXCEPTION")
123 @Path("{scanspec: .*[*]$}")
124 public TableScanResource getScanResource(
125 final @PathParam("scanspec") String scanSpec,
126 @DefaultValue(Integer.MAX_VALUE + "")
127 @QueryParam(Constants.SCAN_LIMIT) int userRequestedLimit,
128 @DefaultValue("") @QueryParam(Constants.SCAN_START_ROW) String startRow,
129 @DefaultValue("") @QueryParam(Constants.SCAN_END_ROW) String endRow,
130 @QueryParam(Constants.SCAN_COLUMN) List<String> column,
131 @DefaultValue("1") @QueryParam(Constants.SCAN_MAX_VERSIONS) int maxVersions,
132 @DefaultValue("-1") @QueryParam(Constants.SCAN_BATCH_SIZE) int batchSize,
133 @DefaultValue("0") @QueryParam(Constants.SCAN_START_TIME) long startTime,
134 @DefaultValue(Long.MAX_VALUE + "") @QueryParam(Constants.SCAN_END_TIME) long endTime,
135 @DefaultValue("true") @QueryParam(Constants.SCAN_CACHE_BLOCKS) boolean cacheBlocks,
136 @DefaultValue("false") @QueryParam(Constants.SCAN_REVERSED) boolean reversed,
137 @DefaultValue("") @QueryParam(Constants.SCAN_FILTER) String paramFilter) {
138 try {
139 Filter prefixFilter = null;
140 Scan tableScan = new Scan();
141 if (scanSpec.indexOf('*') > 0) {
142 String prefix = scanSpec.substring(0, scanSpec.indexOf('*'));
143 byte[] prefixBytes = Bytes.toBytes(prefix);
144 prefixFilter = new PrefixFilter(Bytes.toBytes(prefix));
145 if (startRow.isEmpty()) {
146 tableScan.setStartRow(prefixBytes);
147 }
148 }
149 if (LOG.isTraceEnabled()) {
150 LOG.trace("Query parameters : Table Name = > " + this.table + " Start Row => " + startRow
151 + " End Row => " + endRow + " Columns => " + column + " Start Time => " + startTime
152 + " End Time => " + endTime + " Cache Blocks => " + cacheBlocks + " Max Versions => "
153 + maxVersions + " Batch Size => " + batchSize);
154 }
155 Table hTable = RESTServlet.getInstance().getTable(this.table);
156 tableScan.setBatch(batchSize);
157 tableScan.setMaxVersions(maxVersions);
158 tableScan.setTimeRange(startTime, endTime);
159 if (!startRow.isEmpty()) {
160 tableScan.setStartRow(Bytes.toBytes(startRow));
161 }
162 tableScan.setStopRow(Bytes.toBytes(endRow));
163 for (String col : column) {
164 byte [][] parts = KeyValue.parseColumn(Bytes.toBytes(col.trim()));
165 if (parts.length == 1) {
166 if (LOG.isTraceEnabled()) {
167 LOG.trace("Scan family : " + Bytes.toStringBinary(parts[0]));
168 }
169 tableScan.addFamily(parts[0]);
170 } else if (parts.length == 2) {
171 if (LOG.isTraceEnabled()) {
172 LOG.trace("Scan family and column : " + Bytes.toStringBinary(parts[0])
173 + " " + Bytes.toStringBinary(parts[1]));
174 }
175 tableScan.addColumn(parts[0], parts[1]);
176 } else {
177 throw new IllegalArgumentException("Invalid column specifier.");
178 }
179 }
180
181 FilterList filterList = new FilterList();
182 if (StringUtils.isNotEmpty(paramFilter)) {
183 ParseFilter pf = new ParseFilter();
184 Filter parsedParamFilter = pf.parseFilterString(paramFilter);
185 if (parsedParamFilter != null) {
186 filterList.addFilter(parsedParamFilter);
187 }
188 if (prefixFilter != null) {
189 filterList.addFilter(prefixFilter);
190 }
191 }
192
193 if (filterList.getFilters().size() > 0) {
194 tableScan.setFilter(filterList);
195 }
196
197 int fetchSize = this.servlet.getConfiguration().getInt(Constants.SCAN_FETCH_SIZE, 10);
198 tableScan.setCaching(fetchSize);
199 tableScan.setReversed(reversed);
200 tableScan.setCacheBlocks(cacheBlocks);
201 return new TableScanResource(hTable.getScanner(tableScan), userRequestedLimit);
202 } catch (Exception exp) {
203 servlet.getMetrics().incrementFailedScanRequests(1);
204 processException(exp);
205 LOG.warn(exp);
206 return null;
207 }
208 }
209 }