1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.rest;
22
23 import java.io.IOException;
24
25 import javax.ws.rs.DELETE;
26 import javax.ws.rs.GET;
27 import javax.ws.rs.Produces;
28 import javax.ws.rs.QueryParam;
29 import javax.ws.rs.WebApplicationException;
30 import javax.ws.rs.core.CacheControl;
31 import javax.ws.rs.core.Context;
32 import javax.ws.rs.core.Response;
33 import javax.ws.rs.core.Response.ResponseBuilder;
34 import javax.ws.rs.core.UriInfo;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 import org.apache.hadoop.hbase.KeyValue;
40 import org.apache.hadoop.hbase.rest.model.CellModel;
41 import org.apache.hadoop.hbase.rest.model.CellSetModel;
42 import org.apache.hadoop.hbase.rest.model.RowModel;
43 import org.apache.hadoop.hbase.util.Base64;
44 import org.apache.hadoop.hbase.util.Bytes;
45
46 public class ScannerInstanceResource extends ResourceBase {
47 private static final Log LOG =
48 LogFactory.getLog(ScannerInstanceResource.class);
49
50 static CacheControl cacheControl;
51 static {
52 cacheControl = new CacheControl();
53 cacheControl.setNoCache(true);
54 cacheControl.setNoTransform(false);
55 }
56
57 ResultGenerator generator;
58 String id;
59 int batch = 1;
60
61 public ScannerInstanceResource(String table, String id,
62 ResultGenerator generator, int batch) throws IOException {
63 this.id = id;
64 this.generator = generator;
65 this.batch = batch;
66 }
67
68 @GET
69 @Produces({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF})
70 public Response get(final @Context UriInfo uriInfo,
71 @QueryParam("n") int maxRows, final @QueryParam("c") int maxValues) {
72 if (LOG.isDebugEnabled()) {
73 LOG.debug("GET " + uriInfo.getAbsolutePath());
74 }
75 servlet.getMetrics().incrementRequests(1);
76 CellSetModel model = new CellSetModel();
77 RowModel rowModel = null;
78 byte[] rowKey = null;
79 int limit = batch;
80 if (maxValues > 0) {
81 limit = maxValues;
82 }
83 int count = limit;
84 do {
85 KeyValue value = null;
86 try {
87 value = generator.next();
88 } catch (IllegalStateException e) {
89 ScannerResource.delete(id);
90 throw new WebApplicationException(Response.Status.GONE);
91 }
92 if (value == null) {
93 LOG.info("generator exhausted");
94
95
96 if (count == limit) {
97 return Response.noContent().build();
98 }
99 break;
100 }
101 if (rowKey == null) {
102 rowKey = value.getRow();
103 rowModel = new RowModel(rowKey);
104 }
105 if (!Bytes.equals(value.getRow(), rowKey)) {
106
107
108 if (maxRows > 0) {
109 if (--maxRows == 0) {
110 generator.putBack(value);
111 break;
112 }
113 }
114 model.addRow(rowModel);
115 rowKey = value.getRow();
116 rowModel = new RowModel(rowKey);
117 }
118 rowModel.addCell(
119 new CellModel(value.getFamily(), value.getQualifier(),
120 value.getTimestamp(), value.getValue()));
121 } while (--count > 0);
122 model.addRow(rowModel);
123 ResponseBuilder response = Response.ok(model);
124 response.cacheControl(cacheControl);
125 return response.build();
126 }
127
128 @GET
129 @Produces(MIMETYPE_BINARY)
130 public Response getBinary(final @Context UriInfo uriInfo) {
131 if (LOG.isDebugEnabled()) {
132 LOG.debug("GET " + uriInfo.getAbsolutePath() + " as " +
133 MIMETYPE_BINARY);
134 }
135 servlet.getMetrics().incrementRequests(1);
136 try {
137 KeyValue value = generator.next();
138 if (value == null) {
139 LOG.info("generator exhausted");
140 return Response.noContent().build();
141 }
142 ResponseBuilder response = Response.ok(value.getValue());
143 response.cacheControl(cacheControl);
144 response.header("X-Row", Base64.encodeBytes(value.getRow()));
145 response.header("X-Column",
146 Base64.encodeBytes(
147 KeyValue.makeColumn(value.getFamily(), value.getQualifier())));
148 response.header("X-Timestamp", value.getTimestamp());
149 return response.build();
150 } catch (IllegalStateException e) {
151 ScannerResource.delete(id);
152 throw new WebApplicationException(Response.Status.GONE);
153 }
154 }
155
156 @DELETE
157 public Response delete(final @Context UriInfo uriInfo) {
158 if (LOG.isDebugEnabled()) {
159 LOG.debug("DELETE " + uriInfo.getAbsolutePath());
160 }
161 servlet.getMetrics().incrementRequests(1);
162 if (servlet.isReadOnly()) {
163 throw new WebApplicationException(Response.Status.FORBIDDEN);
164 }
165 ScannerResource.delete(id);
166 return Response.ok().build();
167 }
168 }