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  
20  package org.apache.hadoop.hbase.rest;
21  
22  import java.io.IOException;
23  import java.util.Iterator;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.classification.InterfaceAudience;
28  import org.apache.hadoop.hbase.Cell;
29  import org.apache.hadoop.hbase.KeyValue;
30  import org.apache.hadoop.hbase.UnknownScannerException;
31  import org.apache.hadoop.hbase.client.HTableInterface;
32  import org.apache.hadoop.hbase.client.Result;
33  import org.apache.hadoop.hbase.client.ResultScanner;
34  import org.apache.hadoop.hbase.client.Scan;
35  import org.apache.hadoop.hbase.filter.Filter;
36  import org.apache.hadoop.hbase.rest.model.ScannerModel;
37  import org.apache.hadoop.hbase.security.visibility.Authorizations;
38  import org.apache.hadoop.util.StringUtils;
39  
40  @InterfaceAudience.Private
41  public class ScannerResultGenerator extends ResultGenerator {
42  
43    private static final Log LOG =
44      LogFactory.getLog(ScannerResultGenerator.class);
45  
46    public static Filter buildFilterFromModel(final ScannerModel model) 
47        throws Exception {
48      String filter = model.getFilter();
49      if (filter == null || filter.length() == 0) {
50        return null;
51      }
52      return buildFilter(filter);
53    }
54  
55    private String id;
56    private Iterator<Cell> rowI;
57    private Cell cache;
58    private ResultScanner scanner;
59    private Result cached;
60  
61    public ScannerResultGenerator(final String tableName, final RowSpec rowspec,
62        final Filter filter) throws IllegalArgumentException, IOException {
63      this(tableName, rowspec, filter, -1);
64    }
65  
66    public ScannerResultGenerator(final String tableName, final RowSpec rowspec,
67        final Filter filter, final int caching) throws IllegalArgumentException, IOException {
68      HTableInterface table = RESTServlet.getInstance().getTable(tableName);
69      try {
70        Scan scan;
71        if (rowspec.hasEndRow()) {
72          scan = new Scan(rowspec.getStartRow(), rowspec.getEndRow());
73        } else {
74          scan = new Scan(rowspec.getStartRow());
75        }
76        if (rowspec.hasColumns()) {
77          byte[][] columns = rowspec.getColumns();
78          for (byte[] column: columns) {
79            byte[][] split = KeyValue.parseColumn(column);
80            if (split.length == 1) {
81              scan.addFamily(split[0]);
82            } else if (split.length == 2) {
83              scan.addColumn(split[0], split[1]);
84            } else {
85              throw new IllegalArgumentException("Invalid familyAndQualifier provided.");
86            }
87          }
88        }
89        scan.setTimeRange(rowspec.getStartTime(), rowspec.getEndTime());          
90        scan.setMaxVersions(rowspec.getMaxVersions());
91        if (filter != null) {
92          scan.setFilter(filter);
93        }
94        // always disable block caching on the cluster when scanning
95        scan.setCacheBlocks(false);
96        if (caching > 0 ) {
97          scan.setCaching(caching);
98        }
99        if(rowspec.hasLabels()) {
100         scan.setAuthorizations(new Authorizations(rowspec.getLabels()));
101       }
102       scanner = table.getScanner(scan);
103       cached = null;
104       id = Long.toString(System.currentTimeMillis()) +
105              Integer.toHexString(scanner.hashCode());
106     } finally {
107       table.close();
108     }
109   }
110 
111   public String getID() {
112     return id;
113   }
114 
115   public void close() {
116     if (scanner != null) {
117       scanner.close();
118       scanner = null;
119     }
120   }
121 
122   public boolean hasNext() {
123     if (cache != null) {
124       return true;
125     }
126     if (rowI != null && rowI.hasNext()) {
127       return true;
128     }
129     if (cached != null) {
130       return true;
131     }
132     try {
133       Result result = scanner.next();
134       if (result != null && !result.isEmpty()) {
135         cached = result;
136       }
137     } catch (UnknownScannerException e) {
138       throw new IllegalArgumentException(e);
139     } catch (IOException e) {
140       LOG.error(StringUtils.stringifyException(e));
141     }
142     return cached != null;
143   }
144 
145   public Cell next() {
146     if (cache != null) {
147       Cell kv = cache;
148       cache = null;
149       return kv;
150     }
151     boolean loop;
152     do {
153       loop = false;
154       if (rowI != null) {
155         if (rowI.hasNext()) {
156           return rowI.next();
157         } else {
158           rowI = null;
159         }
160       }
161       if (cached != null) {
162         rowI = cached.listCells().iterator();
163         loop = true;
164         cached = null;
165       } else {
166         Result result = null;
167         try {
168           result = scanner.next();
169         } catch (UnknownScannerException e) {
170           throw new IllegalArgumentException(e);
171         } catch (IOException e) {
172           LOG.error(StringUtils.stringifyException(e));
173         }
174         if (result != null && !result.isEmpty()) {
175           rowI = result.listCells().iterator();
176           loop = true;
177         }
178       }
179     } while (loop);
180     return null;
181   }
182 
183   public void putBack(Cell kv) {
184     this.cache = kv;
185   }
186 
187   public void remove() {
188     throw new UnsupportedOperationException("remove not supported");
189   }
190 }