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