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 (isEnablingOrEnabledTable(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 isEnablingOrEnabledTable(final TableName tableName) {
232 synchronized (this.cache) {
233 return isEnablingTable(tableName) || isEnabledTable(tableName);
234 }
235 }
236
237 public boolean isEnabledOrDisablingTable(final TableName tableName) {
238 synchronized (this.cache) {
239 return isEnabledTable(tableName) || isDisablingTable(tableName);
240 }
241 }
242
243 public boolean isDisabledOrEnablingTable(final TableName tableName) {
244 synchronized (this.cache) {
245 return isDisabledTable(tableName) || isEnablingTable(tableName);
246 }
247 }
248
249 private boolean isTableState(final TableName tableName, final ZooKeeperProtos.Table.State state) {
250 synchronized (this.cache) {
251 ZooKeeperProtos.Table.State currentState = this.cache.get(tableName);
252 return ZKTableReadOnly.isTableState(currentState, state);
253 }
254 }
255
256
257
258
259
260
261
262 public void setDeletedTable(final TableName tableName)
263 throws KeeperException {
264 synchronized (this.cache) {
265 if (this.cache.remove(tableName) == null) {
266 LOG.warn("Moving table " + tableName + " state to deleted but was " +
267 "already deleted");
268 }
269 ZKUtil.deleteNodeFailSilent(this.watcher,
270 ZKUtil.joinZNode(this.watcher.tableZNode, tableName.getNameAsString()));
271 }
272 }
273
274
275
276
277
278
279
280
281 public void setEnabledTable(final TableName tableName) throws KeeperException {
282 setTableState(tableName, ZooKeeperProtos.Table.State.ENABLED);
283 }
284
285
286
287
288
289
290
291 public boolean isTablePresent(final TableName tableName) {
292 synchronized (this.cache) {
293 ZooKeeperProtos.Table.State state = this.cache.get(tableName);
294 return !(state == null);
295 }
296 }
297
298
299
300
301
302 public Set<TableName> getDisabledTables() {
303 Set<TableName> disabledTables = new HashSet<TableName>();
304 synchronized (this.cache) {
305 Set<TableName> tables = this.cache.keySet();
306 for (TableName table: tables) {
307 if (isDisabledTable(table)) disabledTables.add(table);
308 }
309 }
310 return disabledTables;
311 }
312
313
314
315
316
317
318 public static Set<TableName> getDisabledTables(ZooKeeperWatcher zkw)
319 throws KeeperException {
320 return getAllTables(zkw, ZooKeeperProtos.Table.State.DISABLED);
321 }
322
323
324
325
326
327
328 public static Set<TableName> getDisablingTables(ZooKeeperWatcher zkw)
329 throws KeeperException {
330 return getAllTables(zkw, ZooKeeperProtos.Table.State.DISABLING);
331 }
332
333
334
335
336
337
338 public static Set<TableName> getEnablingTables(ZooKeeperWatcher zkw)
339 throws KeeperException {
340 return getAllTables(zkw, ZooKeeperProtos.Table.State.ENABLING);
341 }
342
343
344
345
346
347
348 public static Set<TableName> getDisabledOrDisablingTables(ZooKeeperWatcher zkw)
349 throws KeeperException {
350 return getAllTables(zkw, ZooKeeperProtos.Table.State.DISABLED,
351 ZooKeeperProtos.Table.State.DISABLING);
352 }
353
354
355
356
357
358
359
360
361
362
363 public void removeEnablingTable(final TableName tableName, boolean deleteZNode)
364 throws KeeperException {
365 synchronized (this.cache) {
366 if (isEnablingTable(tableName)) {
367 this.cache.remove(tableName);
368 if (deleteZNode) {
369 ZKUtil.deleteNodeFailSilent(this.watcher,
370 ZKUtil.joinZNode(this.watcher.tableZNode, tableName.getNameAsString()));
371 }
372 }
373 }
374 }
375
376
377
378
379
380
381
382 static Set<TableName> getAllTables(final ZooKeeperWatcher zkw,
383 final ZooKeeperProtos.Table.State... states) throws KeeperException {
384 Set<TableName> allTables = new HashSet<TableName>();
385 List<String> children =
386 ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
387 if(children == null) return allTables;
388 for (String child: children) {
389 TableName tableName = TableName.valueOf(child);
390 ZooKeeperProtos.Table.State state = ZKTableReadOnly.getTableState(zkw, tableName);
391 for (ZooKeeperProtos.Table.State expectedState: states) {
392 if (state == expectedState) {
393 allTables.add(tableName);
394 break;
395 }
396 }
397 }
398 return allTables;
399 }
400 }