View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.rest;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import javax.ws.rs.DefaultValue;
27  import javax.ws.rs.GET;
28  import javax.ws.rs.HeaderParam;
29  import javax.ws.rs.PathParam;
30  import javax.ws.rs.Produces;
31  import javax.ws.rs.QueryParam;
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  import org.codehaus.jackson.annotate.JsonIgnore;
51  import org.codehaus.jackson.annotate.JsonProperty;
52  
53  @InterfaceAudience.Private
54  public class TableScanResource  extends ResourceBase {
55  
56    private static final Log LOG = LogFactory.getLog(TableScanResource.class);
57    TableResource tableResource;
58    ResultScanner results;
59    int userRequestedLimit;
60  
61    public TableScanResource(ResultScanner scanner, int userRequestedLimit) throws IOException {
62      super();
63      this.results = scanner;
64      this.userRequestedLimit = userRequestedLimit;
65    }
66  
67    @GET
68    @Produces({ Constants.MIMETYPE_XML, Constants.MIMETYPE_JSON })
69    public CellSetModelStream get(final @Context UriInfo uriInfo) {
70      if (LOG.isTraceEnabled()) {
71        LOG.trace("GET " + uriInfo.getAbsolutePath());
72      }
73      servlet.getMetrics().incrementRequests(1);
74      final int rowsToSend = userRequestedLimit;
75      servlet.getMetrics().incrementSucessfulScanRequests(1);
76      final Iterator<Result> itr = results.iterator();
77      return new CellSetModelStream(new ArrayList<RowModel>() {
78        public Iterator<RowModel> iterator() {
79          return new Iterator<RowModel>() {
80            int count = rowsToSend;
81  
82            @Override
83            public boolean hasNext() {
84              if (count > 0) {
85                return itr.hasNext();
86              } else {
87                return false;
88              }
89            }
90  
91            @Override
92            public void remove() {
93              throw new UnsupportedOperationException(
94                  "Remove method cannot be used in CellSetModelStream");
95            }
96  
97            @Override
98            public RowModel next() {
99              Result rs = itr.next();
100             if ((rs == null) || (count <= 0)) {
101               return null;
102             }
103             byte[] rowKey = rs.getRow();
104             RowModel rModel = new RowModel(rowKey);
105             List<Cell> kvs = rs.listCells();
106             for (Cell kv : kvs) {
107               rModel.addCell(new CellModel(CellUtil.cloneFamily(kv), CellUtil.cloneQualifier(kv),
108                   kv.getTimestamp(), CellUtil.cloneValue(kv)));
109             }
110             count--;
111             if (count == 0) {
112               results.close();
113             }
114             return rModel;
115           }
116         };
117       }
118     });
119   }
120 
121   @GET
122   @Produces({ Constants.MIMETYPE_PROTOBUF, Constants.MIMETYPE_PROTOBUF_IETF })
123   public Response getProtobuf(
124       final @Context UriInfo uriInfo,
125       final @HeaderParam("Accept") String contentType) {
126     if (LOG.isTraceEnabled()) {
127       LOG.trace("GET " + uriInfo.getAbsolutePath() + " as " +
128               MIMETYPE_BINARY);
129     }
130     servlet.getMetrics().incrementRequests(1);
131     try {
132       int fetchSize = this.servlet.getConfiguration().getInt(Constants.SCAN_FETCH_SIZE, 10);
133       ProtobufStreamingUtil stream = new ProtobufStreamingUtil(this.results, contentType,
134           userRequestedLimit, fetchSize);
135       servlet.getMetrics().incrementSucessfulScanRequests(1);
136       ResponseBuilder response = Response.ok(stream);
137       response.header("content-type", contentType);
138       return response.build();
139     } catch (Exception exp) {
140       servlet.getMetrics().incrementFailedScanRequests(1);
141       processException(exp);
142       LOG.warn(exp);
143       return null;
144     }
145   }
146 
147   @XmlRootElement(name = "CellSet")
148   @XmlAccessorType(XmlAccessType.FIELD)
149   public static class CellSetModelStream {
150     // JAXB needs an arraylist for streaming
151     @XmlElement(name = "Row")
152     @JsonIgnore
153     private ArrayList<RowModel> Row;
154 
155     public CellSetModelStream() {
156     }
157 
158     public CellSetModelStream(final ArrayList<RowModel> rowList) {
159       this.Row = rowList;
160     }
161 
162     // jackson needs an iterator for streaming
163     @JsonProperty("Row")
164     public Iterator<RowModel> getIterator() {
165       return Row.iterator();
166     }
167   }
168 }