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