1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.zookeeper;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.TableName;
25 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
26 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
27 import org.apache.zookeeper.KeeperException;
28
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34
35
36
37
38
39
40
41
42
43
44
45 @InterfaceAudience.Private
46 public class ZKTable {
47
48
49
50
51
52 private static final Log LOG = LogFactory.getLog(ZKTable.class);
53 private final ZooKeeperWatcher watcher;
54
55
56
57
58
59
60 private final Map<TableName, ZooKeeperProtos.Table.State> cache =
61 new HashMap<TableName, ZooKeeperProtos.Table.State>();
62
63
64
65
66 public ZKTable(final ZooKeeperWatcher zkw) throws KeeperException {
67 super();
68 this.watcher = zkw;
69 populateTableStates();
70 }
71
72
73
74
75
76 private void populateTableStates()
77 throws KeeperException {
78 synchronized (this.cache) {
79 List<String> children = ZKUtil.listChildrenNoWatch(this.watcher, this.watcher.tableZNode);
80 if (children == null) return;
81 for (String child: children) {
82 TableName tableName = TableName.valueOf(child);
83 ZooKeeperProtos.Table.State state = ZKTableReadOnly.getTableState(this.watcher, tableName);
84 if (state != null) this.cache.put(tableName, state);
85 }
86 }
87 }
88
89
90
91
92
93
94
95 public void setDisabledTable(TableName tableName)
96 throws KeeperException {
97 synchronized (this.cache) {
98 if (!isDisablingOrDisabledTable(tableName)) {
99 LOG.warn("Moving table " + tableName + " state to disabled but was " +
100 "not first in disabling state: " + this.cache.get(tableName));
101 }
102 setTableState(tableName, ZooKeeperProtos.Table.State.DISABLED);
103 }
104 }
105
106
107
108
109
110
111
112 public void setDisablingTable(final TableName tableName)
113 throws KeeperException {
114 synchronized (this.cache) {
115 if (!isEnabledOrDisablingTable(tableName)) {
116 LOG.warn("Moving table " + tableName + " state to disabling but was " +
117 "not first in enabled state: " + this.cache.get(tableName));
118 }
119 setTableState(tableName, ZooKeeperProtos.Table.State.DISABLING);
120 }
121 }
122
123
124
125
126
127
128
129 public void setEnablingTable(final TableName tableName)
130 throws KeeperException {
131 synchronized (this.cache) {
132 if (!isDisabledOrEnablingTable(tableName)) {
133 LOG.warn("Moving table " + tableName + " state to enabling but was " +
134 "not first in disabled state: " + this.cache.get(tableName));
135 }
136 setTableState(tableName, ZooKeeperProtos.Table.State.ENABLING);
137 }
138 }
139
140
141
142
143
144
145
146
147 public boolean checkAndSetEnablingTable(final TableName tableName)
148 throws KeeperException {
149 synchronized (this.cache) {
150 if (isEnablingTable(tableName)) {
151 return false;
152 }
153 setTableState(tableName, ZooKeeperProtos.Table.State.ENABLING);
154 return true;
155 }
156 }
157
158
159
160
161
162
163
164
165 public boolean checkDisabledAndSetEnablingTable(final TableName tableName)
166 throws KeeperException {
167 synchronized (this.cache) {
168 if (!isDisabledTable(tableName)) {
169 return false;
170 }
171 setTableState(tableName, ZooKeeperProtos.Table.State.ENABLING);
172 return true;
173 }
174 }
175
176
177
178
179
180
181
182
183 public boolean checkEnabledAndSetDisablingTable(final TableName tableName)
184 throws KeeperException {
185 synchronized (this.cache) {
186 if (this.cache.get(tableName) != null && !isEnabledTable(tableName)) {
187 return false;
188 }
189 setTableState(tableName, ZooKeeperProtos.Table.State.DISABLING);
190 return true;
191 }
192 }
193
194 private void setTableState(final TableName tableName, final ZooKeeperProtos.Table.State state)
195 throws KeeperException {
196 String znode = ZKUtil.joinZNode(this.watcher.tableZNode, tableName.getNameAsString());
197 if (ZKUtil.checkExists(this.watcher, znode) == -1) {
198 ZKUtil.createAndFailSilent(this.watcher, znode);
199 }
200 synchronized (this.cache) {
201 ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder();
202 builder.setState(state);
203 byte [] data = ProtobufUtil.prependPBMagic(builder.build().toByteArray());
204 ZKUtil.setData(this.watcher, znode, data);
205 this.cache.put(tableName, state);
206 }
207 }
208
209 public boolean isDisabledTable(final TableName tableName) {
210 return isTableState(tableName, ZooKeeperProtos.Table.State.DISABLED);
211 }
212
213 public boolean isDisablingTable(final TableName tableName) {
214 return isTableState(tableName, ZooKeeperProtos.Table.State.DISABLING);
215 }
216
217 public boolean isEnablingTable(final TableName tableName) {
218 return isTableState(tableName, ZooKeeperProtos.Table.State.ENABLING);
219 }
220
221 public boolean isEnabledTable(TableName tableName) {
222 return isTableState(tableName, ZooKeeperProtos.Table.State.ENABLED);
223 }
224
225 public boolean isDisablingOrDisabledTable(final TableName tableName) {
226 synchronized (this.cache) {
227 return isDisablingTable(tableName) || isDisabledTable(tableName);
228 }
229 }
230
231 public boolean isEnabledOrDisablingTable(final TableName tableName) {
232 synchronized (this.cache) {
233 return isEnabledTable(tableName) || isDisablingTable(tableName);
234 }
235 }
236
237 public boolean isDisabledOrEnablingTable(final TableName tableName) {
238 synchronized (this.cache) {
239 return isDisabledTable(tableName) || isEnablingTable(tableName);
240 }
241 }
242
243 private boolean isTableState(final TableName tableName, final ZooKeeperProtos.Table.State state) {
244 synchronized (this.cache) {
245 ZooKeeperProtos.Table.State currentState = this.cache.get(tableName);
246 return ZKTableReadOnly.isTableState(currentState, state);
247 }
248 }
249
250
251
252
253
254
255
256 public void setDeletedTable(final TableName tableName)
257 throws KeeperException {
258 synchronized (this.cache) {
259 if (this.cache.remove(tableName) == null) {
260 LOG.warn("Moving table " + tableName + " state to deleted but was " +
261 "already deleted");
262 }
263 ZKUtil.deleteNodeFailSilent(this.watcher,
264 ZKUtil.joinZNode(this.watcher.tableZNode, tableName.getNameAsString()));
265 }
266 }
267
268
269
270
271
272
273
274
275 public void setEnabledTable(final TableName tableName) throws KeeperException {
276 setTableState(tableName, ZooKeeperProtos.Table.State.ENABLED);
277 }
278
279
280
281
282
283
284
285 public boolean isTablePresent(final TableName tableName) {
286 synchronized (this.cache) {
287 ZooKeeperProtos.Table.State state = this.cache.get(tableName);
288 return !(state == null);
289 }
290 }
291
292
293
294
295
296 public Set<TableName> getDisabledTables() {
297 Set<TableName> disabledTables = new HashSet<TableName>();
298 synchronized (this.cache) {
299 Set<TableName> tables = this.cache.keySet();
300 for (TableName table: tables) {
301 if (isDisabledTable(table)) disabledTables.add(table);
302 }
303 }
304 return disabledTables;
305 }
306
307
308
309
310
311
312 public static Set<TableName> getDisabledTables(ZooKeeperWatcher zkw)
313 throws KeeperException {
314 return getAllTables(zkw, ZooKeeperProtos.Table.State.DISABLED);
315 }
316
317
318
319
320
321
322 public static Set<TableName> getDisablingTables(ZooKeeperWatcher zkw)
323 throws KeeperException {
324 return getAllTables(zkw, ZooKeeperProtos.Table.State.DISABLING);
325 }
326
327
328
329
330
331
332 public static Set<TableName> getEnablingTables(ZooKeeperWatcher zkw)
333 throws KeeperException {
334 return getAllTables(zkw, ZooKeeperProtos.Table.State.ENABLING);
335 }
336
337
338
339
340
341
342 public static Set<TableName> getDisabledOrDisablingTables(ZooKeeperWatcher zkw)
343 throws KeeperException {
344 return getAllTables(zkw, ZooKeeperProtos.Table.State.DISABLED,
345 ZooKeeperProtos.Table.State.DISABLING);
346 }
347
348
349
350
351
352
353
354
355
356
357 public void removeEnablingTable(final TableName tableName, boolean deleteZNode)
358 throws KeeperException {
359 synchronized (this.cache) {
360 if (isEnablingTable(tableName)) {
361 this.cache.remove(tableName);
362 if (deleteZNode) {
363 ZKUtil.deleteNodeFailSilent(this.watcher,
364 ZKUtil.joinZNode(this.watcher.tableZNode, tableName.getNameAsString()));
365 }
366 }
367 }
368 }
369
370
371
372
373
374
375
376 static Set<TableName> getAllTables(final ZooKeeperWatcher zkw,
377 final ZooKeeperProtos.Table.State... states) throws KeeperException {
378 Set<TableName> allTables = new HashSet<TableName>();
379 List<String> children =
380 ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
381 if(children == null) return allTables;
382 for (String child: children) {
383 TableName tableName = TableName.valueOf(child);
384 ZooKeeperProtos.Table.State state = ZKTableReadOnly.getTableState(zkw, tableName);
385 for (ZooKeeperProtos.Table.State expectedState: states) {
386 if (state == expectedState) {
387 allTables.add(tableName);
388 break;
389 }
390 }
391 }
392 return allTables;
393 }
394 }