1
2
3
4
5
6
7
8
9
10
11
12 package org.apache.hadoop.hbase.quotas;
13
14 import java.io.Closeable;
15 import java.io.IOException;
16 import java.util.Iterator;
17 import java.util.LinkedList;
18 import java.util.Objects;
19 import java.util.Queue;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.conf.Configuration;
24 import org.apache.hadoop.hbase.TableName;
25 import org.apache.hadoop.hbase.classification.InterfaceAudience;
26 import org.apache.hadoop.hbase.classification.InterfaceStability;
27 import org.apache.hadoop.hbase.client.Connection;
28 import org.apache.hadoop.hbase.client.ConnectionFactory;
29 import org.apache.hadoop.hbase.client.Result;
30 import org.apache.hadoop.hbase.client.ResultScanner;
31 import org.apache.hadoop.hbase.client.Scan;
32 import org.apache.hadoop.hbase.client.Table;
33 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
34 import org.apache.hadoop.util.StringUtils;
35
36
37
38
39 @InterfaceAudience.Public
40 @InterfaceStability.Evolving
41 public final class QuotaRetriever implements Closeable, Iterable<QuotaSettings> {
42 private static final Log LOG = LogFactory.getLog(QuotaRetriever.class);
43
44 private final Queue<QuotaSettings> cache = new LinkedList<QuotaSettings>();
45 private ResultScanner scanner;
46
47
48
49
50 private Connection connection;
51 private Table table;
52
53
54
55
56 private boolean isManagedConnection = false;
57
58 QuotaRetriever() {
59 }
60
61 void init(final Configuration conf, final Scan scan) throws IOException {
62
63
64 this.isManagedConnection = true;
65 init(ConnectionFactory.createConnection(conf), scan);
66 }
67
68 void init(final Connection conn, final Scan scan) throws IOException {
69 this.connection = Objects.requireNonNull(conn);
70 this.table = this.connection.getTable(QuotaTableUtil.QUOTA_TABLE_NAME);
71 try {
72 scanner = table.getScanner(scan);
73 } catch (IOException e) {
74 try {
75 close();
76 } catch (IOException ioe) {
77 LOG.warn("Failed getting scanner and then failed close on cleanup", e);
78 }
79 throw e;
80 }
81 }
82
83 public void close() throws IOException {
84 if (this.table != null) {
85 this.table.close();
86 this.table = null;
87 }
88
89
90 if (isManagedConnection) {
91 if (this.connection != null) {
92 this.connection.close();
93 }
94 }
95 this.connection = null;
96 }
97
98 public QuotaSettings next() throws IOException {
99 if (cache.isEmpty()) {
100 Result result = scanner.next();
101 if (result == null) return null;
102
103 QuotaTableUtil.parseResult(result, new QuotaTableUtil.QuotasVisitor() {
104 @Override
105 public void visitUserQuotas(String userName, Quotas quotas) {
106 cache.addAll(QuotaSettingsFactory.fromUserQuotas(userName, quotas));
107 }
108
109 @Override
110 public void visitUserQuotas(String userName, TableName table, Quotas quotas) {
111 cache.addAll(QuotaSettingsFactory.fromUserQuotas(userName, table, quotas));
112 }
113
114 @Override
115 public void visitUserQuotas(String userName, String namespace, Quotas quotas) {
116 cache.addAll(QuotaSettingsFactory.fromUserQuotas(userName, namespace, quotas));
117 }
118
119 @Override
120 public void visitTableQuotas(TableName tableName, Quotas quotas) {
121 cache.addAll(QuotaSettingsFactory.fromTableQuotas(tableName, quotas));
122 }
123
124 @Override
125 public void visitNamespaceQuotas(String namespace, Quotas quotas) {
126 cache.addAll(QuotaSettingsFactory.fromNamespaceQuotas(namespace, quotas));
127 }
128 });
129 }
130 return cache.poll();
131 }
132
133 @Override
134 public Iterator<QuotaSettings> iterator() {
135 return new Iter();
136 }
137
138 private class Iter implements Iterator<QuotaSettings> {
139 private QuotaSettings cache;
140
141 public Iter() {
142 try {
143 cache = QuotaRetriever.this.next();
144 } catch (IOException e) {
145 LOG.warn(StringUtils.stringifyException(e));
146 }
147 }
148
149 @Override
150 public boolean hasNext() {
151 return cache != null;
152 }
153
154 @Override
155 public QuotaSettings next() {
156 QuotaSettings result = cache;
157 try {
158 cache = QuotaRetriever.this.next();
159 } catch (IOException e) {
160 LOG.warn(StringUtils.stringifyException(e));
161 }
162 return result;
163 }
164
165 @Override
166 public void remove() {
167 throw new RuntimeException("remove() not supported");
168 }
169 }
170
171
172
173
174
175
176
177 public static QuotaRetriever open(final Configuration conf) throws IOException {
178 return open(conf, null);
179 }
180
181
182
183
184
185
186
187
188 public static QuotaRetriever open(final Configuration conf, final QuotaFilter filter)
189 throws IOException {
190 Scan scan = QuotaTableUtil.makeScan(filter);
191 QuotaRetriever scanner = new QuotaRetriever();
192 scanner.init(conf, scan);
193 return scanner;
194 }
195 }