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