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.IOException;
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import javax.ws.rs.DefaultValue;
27 import javax.ws.rs.GET;
28 import javax.ws.rs.HeaderParam;
29 import javax.ws.rs.PathParam;
30 import javax.ws.rs.Produces;
31 import javax.ws.rs.QueryParam;
32 import javax.ws.rs.core.Context;
33 import javax.ws.rs.core.Response;
34 import javax.ws.rs.core.Response.ResponseBuilder;
35 import javax.ws.rs.core.UriInfo;
36 import javax.xml.bind.annotation.XmlAccessType;
37 import javax.xml.bind.annotation.XmlAccessorType;
38 import javax.xml.bind.annotation.XmlElement;
39 import javax.xml.bind.annotation.XmlRootElement;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.apache.hadoop.hbase.classification.InterfaceAudience;
44 import org.apache.hadoop.hbase.Cell;
45 import org.apache.hadoop.hbase.CellUtil;
46 import org.apache.hadoop.hbase.client.Result;
47 import org.apache.hadoop.hbase.client.ResultScanner;
48 import org.apache.hadoop.hbase.rest.model.CellModel;
49 import org.apache.hadoop.hbase.rest.model.RowModel;
50 import org.codehaus.jackson.annotate.JsonIgnore;
51 import org.codehaus.jackson.annotate.JsonProperty;
52
53 @InterfaceAudience.Private
54 public class TableScanResource extends ResourceBase {
55
56 private static final Log LOG = LogFactory.getLog(TableScanResource.class);
57 TableResource tableResource;
58 ResultScanner results;
59 int userRequestedLimit;
60
61 public TableScanResource(ResultScanner scanner, int userRequestedLimit) throws IOException {
62 super();
63 this.results = scanner;
64 this.userRequestedLimit = userRequestedLimit;
65 }
66
67 @GET
68 @Produces({ Constants.MIMETYPE_XML, Constants.MIMETYPE_JSON })
69 public CellSetModelStream get(final @Context UriInfo uriInfo) {
70 if (LOG.isTraceEnabled()) {
71 LOG.trace("GET " + uriInfo.getAbsolutePath());
72 }
73 servlet.getMetrics().incrementRequests(1);
74 final int rowsToSend = userRequestedLimit;
75 servlet.getMetrics().incrementSucessfulScanRequests(1);
76 final Iterator<Result> itr = results.iterator();
77 return new CellSetModelStream(new ArrayList<RowModel>() {
78 public Iterator<RowModel> iterator() {
79 return new Iterator<RowModel>() {
80 int count = rowsToSend;
81
82 @Override
83 public boolean hasNext() {
84 if (count > 0) {
85 return itr.hasNext();
86 } else {
87 return false;
88 }
89 }
90
91 @Override
92 public void remove() {
93 throw new UnsupportedOperationException(
94 "Remove method cannot be used in CellSetModelStream");
95 }
96
97 @Override
98 public RowModel next() {
99 Result rs = itr.next();
100 if ((rs == null) || (count <= 0)) {
101 return null;
102 }
103 byte[] rowKey = rs.getRow();
104 RowModel rModel = new RowModel(rowKey);
105 List<Cell> kvs = rs.listCells();
106 for (Cell kv : kvs) {
107 rModel.addCell(new CellModel(CellUtil.cloneFamily(kv), CellUtil.cloneQualifier(kv),
108 kv.getTimestamp(), CellUtil.cloneValue(kv)));
109 }
110 count--;
111 if (count == 0) {
112 results.close();
113 }
114 return rModel;
115 }
116 };
117 }
118 });
119 }
120
121 @GET
122 @Produces({ Constants.MIMETYPE_PROTOBUF, Constants.MIMETYPE_PROTOBUF_IETF })
123 public Response getProtobuf(
124 final @Context UriInfo uriInfo,
125 final @HeaderParam("Accept") String contentType) {
126 if (LOG.isTraceEnabled()) {
127 LOG.trace("GET " + uriInfo.getAbsolutePath() + " as " +
128 MIMETYPE_BINARY);
129 }
130 servlet.getMetrics().incrementRequests(1);
131 try {
132 int fetchSize = this.servlet.getConfiguration().getInt(Constants.SCAN_FETCH_SIZE, 10);
133 ProtobufStreamingUtil stream = new ProtobufStreamingUtil(this.results, contentType,
134 userRequestedLimit, fetchSize);
135 servlet.getMetrics().incrementSucessfulScanRequests(1);
136 ResponseBuilder response = Response.ok(stream);
137 response.header("content-type", contentType);
138 return response.build();
139 } catch (Exception exp) {
140 servlet.getMetrics().incrementFailedScanRequests(1);
141 processException(exp);
142 LOG.warn(exp);
143 return null;
144 }
145 }
146
147 @XmlRootElement(name = "CellSet")
148 @XmlAccessorType(XmlAccessType.FIELD)
149 public static class CellSetModelStream {
150
151 @XmlElement(name = "Row")
152 @JsonIgnore
153 private ArrayList<RowModel> Row;
154
155 public CellSetModelStream() {
156 }
157
158 public CellSetModelStream(final ArrayList<RowModel> rowList) {
159 this.Row = rowList;
160 }
161
162
163 @JsonProperty("Row")
164 public Iterator<RowModel> getIterator() {
165 return Row.iterator();
166 }
167 }
168 }