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