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