View Javadoc

1   /*
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.rest;
22  
23  import java.io.IOException;
24  import java.net.URI;
25  import java.util.Collections;
26  import java.util.HashMap;
27  import java.util.Map;
28  
29  import javax.ws.rs.Consumes;
30  import javax.ws.rs.POST;
31  import javax.ws.rs.PUT;
32  import javax.ws.rs.Path;
33  import javax.ws.rs.PathParam;
34  import javax.ws.rs.core.Context;
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.hbase.TableNotFoundException;
43  import org.apache.hadoop.hbase.filter.Filter;
44  import org.apache.hadoop.hbase.rest.model.ScannerModel;
45  
46  public class ScannerResource extends ResourceBase {
47  
48    private static final Log LOG = LogFactory.getLog(ScannerResource.class);
49  
50    static final Map<String,ScannerInstanceResource> scanners =
51     Collections.synchronizedMap(new HashMap<String,ScannerInstanceResource>());
52  
53    TableResource tableResource;
54  
55    /**
56     * Constructor
57     * @param tableResource
58     * @throws IOException
59     */
60    public ScannerResource(TableResource tableResource)throws IOException {
61      super();
62      this.tableResource = tableResource;
63    }
64  
65    static boolean delete(final String id) {
66      ScannerInstanceResource instance = scanners.remove(id);
67      if (instance != null) {
68        instance.generator.close();
69        return true;
70      } else {
71        return false;
72      }
73    }
74  
75    Response update(final ScannerModel model, final boolean replace,
76        final UriInfo uriInfo) {
77      servlet.getMetrics().incrementRequests(1);
78      if (servlet.isReadOnly()) {
79        return Response.status(Response.Status.FORBIDDEN)
80          .type(MIMETYPE_TEXT).entity("Forbidden" + CRLF)
81          .build();
82      }
83      byte[] endRow = model.hasEndRow() ? model.getEndRow() : null;
84      RowSpec spec = new RowSpec(model.getStartRow(), endRow,
85        model.getColumns(), model.getStartTime(), model.getEndTime(),
86        model.getMaxVersions());
87      try {
88        Filter filter = ScannerResultGenerator.buildFilterFromModel(model);
89        String tableName = tableResource.getName();
90        ScannerResultGenerator gen =
91          new ScannerResultGenerator(tableName, spec, filter);
92        String id = gen.getID();
93        ScannerInstanceResource instance =
94          new ScannerInstanceResource(tableName, id, gen, model.getBatch());
95        scanners.put(id, instance);
96        if (LOG.isDebugEnabled()) {
97          LOG.debug("new scanner: " + id);
98        }
99        UriBuilder builder = uriInfo.getAbsolutePathBuilder();
100       URI uri = builder.path(id).build();
101       servlet.getMetrics().incrementSucessfulPutRequests(1);
102       return Response.created(uri).build();
103     } catch (RuntimeException e) {
104       servlet.getMetrics().incrementFailedPutRequests(1);
105       if (e.getCause() instanceof TableNotFoundException) {
106         return Response.status(Response.Status.NOT_FOUND)
107           .type(MIMETYPE_TEXT).entity("Not found" + CRLF)
108           .build();
109       }
110       return Response.status(Response.Status.BAD_REQUEST)
111         .type(MIMETYPE_TEXT).entity("Bad request" + CRLF)
112         .build();
113     } catch (Exception e) {
114       servlet.getMetrics().incrementFailedPutRequests(1);
115       return Response.status(Response.Status.SERVICE_UNAVAILABLE)
116         .type(MIMETYPE_TEXT).entity("Unavailable" + CRLF)
117         .build();
118     }
119   }
120 
121   @PUT
122   @Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
123     MIMETYPE_PROTOBUF_IETF})
124   public Response put(final ScannerModel model, 
125       final @Context UriInfo uriInfo) {
126     if (LOG.isDebugEnabled()) {
127       LOG.debug("PUT " + uriInfo.getAbsolutePath());
128     }
129     return update(model, true, uriInfo);
130   }
131 
132   @POST
133   @Consumes({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF,
134     MIMETYPE_PROTOBUF_IETF})
135   public Response post(final ScannerModel model,
136       final @Context UriInfo uriInfo) {
137     if (LOG.isDebugEnabled()) {
138       LOG.debug("POST " + uriInfo.getAbsolutePath());
139     }
140     return update(model, false, uriInfo);
141   }
142 
143   @Path("{scanner: .+}")
144   public ScannerInstanceResource getScannerInstanceResource(
145       final @PathParam("scanner") String id) throws IOException {
146     ScannerInstanceResource instance = scanners.get(id);
147     if (instance == null) {
148       servlet.getMetrics().incrementFailedGetRequests(1);
149       return new ScannerInstanceResource();
150     } else {
151       servlet.getMetrics().incrementSucessfulGetRequests(1);
152     }
153     return instance;
154   }
155 }