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