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.net.URI;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Map;
27
28 import javax.ws.rs.Consumes;
29 import javax.ws.rs.POST;
30 import javax.ws.rs.PUT;
31 import javax.ws.rs.Path;
32 import javax.ws.rs.PathParam;
33 import javax.ws.rs.core.Context;
34 import javax.ws.rs.core.Response;
35 import javax.ws.rs.core.UriBuilder;
36 import javax.ws.rs.core.UriInfo;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41 import org.apache.hadoop.hbase.classification.InterfaceAudience;
42 import org.apache.hadoop.hbase.TableNotFoundException;
43 import org.apache.hadoop.hbase.filter.Filter;
44 import org.apache.hadoop.hbase.rest.model.ScannerModel;
45
46 @InterfaceAudience.Private
47 public class ScannerResource extends ResourceBase {
48
49 private static final Log LOG = LogFactory.getLog(ScannerResource.class);
50
51 static final Map<String,ScannerInstanceResource> scanners =
52 Collections.synchronizedMap(new HashMap<String,ScannerInstanceResource>());
53
54 TableResource tableResource;
55
56
57
58
59
60
61 public ScannerResource(TableResource tableResource)throws IOException {
62 super();
63 this.tableResource = tableResource;
64 }
65
66 static boolean delete(final String id) {
67 ScannerInstanceResource instance = scanners.remove(id);
68 if (instance != null) {
69 instance.generator.close();
70 return true;
71 } else {
72 return false;
73 }
74 }
75
76 Response update(final ScannerModel model, final boolean replace,
77 final UriInfo uriInfo) {
78 servlet.getMetrics().incrementRequests(1);
79 if (servlet.isReadOnly()) {
80 return Response.status(Response.Status.FORBIDDEN)
81 .type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
82 .build();
83 }
84 byte[] endRow = model.hasEndRow() ? model.getEndRow() : null;
85 RowSpec spec = null;
86 if (model.getLabels() != null) {
87 spec = new RowSpec(model.getStartRow(), endRow, model.getColumns(), model.getStartTime(),
88 model.getEndTime(), model.getMaxVersions(), model.getLabels());
89 } else {
90 spec = new RowSpec(model.getStartRow(), endRow, model.getColumns(), model.getStartTime(),
91 model.getEndTime(), model.getMaxVersions());
92 }
93
94 try {
95 Filter filter = ScannerResultGenerator.buildFilterFromModel(model);
96 String tableName = tableResource.getName();
97 ScannerResultGenerator gen =
98 new ScannerResultGenerator(tableName, spec, filter, model.getCaching(),
99 model.getCacheBlocks());
100 String id = gen.getID();
101 ScannerInstanceResource instance =
102 new ScannerInstanceResource(tableName, id, gen, model.getBatch());
103 scanners.put(id, instance);
104 if (LOG.isTraceEnabled()) {
105 LOG.trace("new scanner: " + id);
106 }
107 UriBuilder builder = uriInfo.getAbsolutePathBuilder();
108 URI uri = builder.path(id).build();
109 servlet.getMetrics().incrementSucessfulPutRequests(1);
110 return Response.created(uri).build();
111 } catch (Exception e) {
112 servlet.getMetrics().incrementFailedPutRequests(1);
113 if (e instanceof TableNotFoundException) {
114 return Response.status(Response.Status.NOT_FOUND)
115 .type(MIMETYPE_TEXT).entity("Not found" + CRLF)
116 .build();
117 } else if (e instanceof RuntimeException) {
118 return Response.status(Response.Status.BAD_REQUEST)
119 .type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
120 .build();
121 }
122 return Response.status(Response.Status.SERVICE_UNAVAILABLE)
123 .type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
124 .build();
125 }
126 }
127
128 @PUT
129 @Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
130 MIMETYPE_PROTOBUF_IETF})
131 public Response put(final ScannerModel model,
132 final @Context UriInfo uriInfo) {
133 if (LOG.isTraceEnabled()) {
134 LOG.trace("PUT " + uriInfo.getAbsolutePath());
135 }
136 return update(model, true, uriInfo);
137 }
138
139 @POST
140 @Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
141 MIMETYPE_PROTOBUF_IETF})
142 public Response post(final ScannerModel model,
143 final @Context UriInfo uriInfo) {
144 if (LOG.isTraceEnabled()) {
145 LOG.trace("POST " + uriInfo.getAbsolutePath());
146 }
147 return update(model, false, uriInfo);
148 }
149
150 @Path("{scanner: .+}")
151 public ScannerInstanceResource getScannerInstanceResource(
152 final @PathParam("scanner") String id) throws IOException {
153 ScannerInstanceResource instance = scanners.get(id);
154 if (instance == null) {
155 servlet.getMetrics().incrementFailedGetRequests(1);
156 return new ScannerInstanceResource();
157 } else {
158 servlet.getMetrics().incrementSucessfulGetRequests(1);
159 }
160 return instance;
161 }
162 }