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