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