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.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 }