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 public boolean checkDisabledAndSetEnablingTable(final String tableName)
189 throws KeeperException {
190 synchronized (this.cache) {
191 if (!isDisabledTable(tableName)) {
192 return false;
193 }
194 setTableState(tableName, TableState.ENABLING);
195 return true;
196 }
197 }
198
199
200
201
202
203
204
205
206 public boolean checkEnabledAndSetDisablingTable(final String tableName)
207 throws KeeperException {
208 synchronized (this.cache) {
209 if (this.cache.get(tableName) != null && !isEnabledTable(tableName)) {
210 return false;
211 }
212 setTableState(tableName, TableState.DISABLING);
213 return true;
214 }
215 }
216
217 private void setTableState(final String tableName, final TableState state)
218 throws KeeperException {
219 String znode = ZKUtil.joinZNode(this.watcher.masterTableZNode, tableName);
220 if (ZKUtil.checkExists(this.watcher, znode) == -1) {
221 ZKUtil.createAndFailSilent(this.watcher, znode);
222 }
223 String znode92 = ZKUtil.joinZNode(this.watcher.masterTableZNode92, tableName);
224 boolean settingToEnabled = (state == TableState.ENABLED);
225
226
227 if (!settingToEnabled) {
228 if (ZKUtil.checkExists(this.watcher, znode92) == -1) {
229 ZKUtil.createAndFailSilent(this.watcher, znode92);
230 }
231 }
232 synchronized (this.cache) {
233 List<ZKUtilOp> ops = new LinkedList<ZKUtilOp>();
234 if (settingToEnabled) {
235 ops.add(ZKUtilOp.deleteNodeFailSilent(znode92));
236 }
237 else {
238 ops.add(ZKUtilOp.setData(znode92, Bytes.toBytes(state.toString())));
239 }
240
241
242
243
244 ops.add(ZKUtilOp.setData(znode, Bytes.toBytes(state.toString())));
245 ZKUtil.multiOrSequential(this.watcher, ops, true);
246 this.cache.put(tableName, state);
247 }
248 }
249
250 public boolean isDisabledTable(final String tableName) {
251 return isTableState(tableName, TableState.DISABLED);
252 }
253
254 public boolean isDisablingTable(final String tableName) {
255 return isTableState(tableName, TableState.DISABLING);
256 }
257
258 public boolean isEnablingTable(final String tableName) {
259 return isTableState(tableName, TableState.ENABLING);
260 }
261
262 public boolean isEnabledTable(String tableName) {
263 return isTableState(tableName, TableState.ENABLED);
264 }
265
266 public boolean isDisablingOrDisabledTable(final String tableName) {
267 synchronized (this.cache) {
268 return isDisablingTable(tableName) || isDisabledTable(tableName);
269 }
270 }
271
272 public boolean isEnabledOrDisablingTable(final String tableName) {
273 synchronized (this.cache) {
274 return isEnabledTable(tableName) || isDisablingTable(tableName);
275 }
276 }
277
278 public boolean isDisabledOrEnablingTable(final String tableName) {
279 synchronized (this.cache) {
280 return isDisabledTable(tableName) || isEnablingTable(tableName);
281 }
282 }
283
284 private boolean isTableState(final String tableName, final TableState state) {
285 synchronized (this.cache) {
286 TableState currentState = this.cache.get(tableName);
287 return ZKTableReadOnly.isTableState(currentState, state);
288 }
289 }
290
291
292
293
294
295
296
297 public void setDeletedTable(final String tableName)
298 throws KeeperException {
299 synchronized (this.cache) {
300 List<ZKUtilOp> ops = new LinkedList<ZKUtilOp>();
301 ops.add(ZKUtilOp.deleteNodeFailSilent(
302 ZKUtil.joinZNode(this.watcher.masterTableZNode92, tableName)));
303
304
305
306
307 ops.add(ZKUtilOp.deleteNodeFailSilent(
308 ZKUtil.joinZNode(this.watcher.masterTableZNode, tableName)));
309 ZKUtil.multiOrSequential(this.watcher, ops, true);
310 if (this.cache.remove(tableName) == null) {
311 LOG.warn("Moving table " + tableName + " state to deleted but was " +
312 "already deleted");
313 }
314 }
315 }
316
317
318
319
320
321
322
323
324 public void setEnabledTable(final String tableName) throws KeeperException {
325 setTableState(tableName, TableState.ENABLED);
326 }
327
328
329
330
331
332
333
334 public boolean isTablePresent(final String tableName) {
335 synchronized (this.cache) {
336 TableState state = this.cache.get(tableName);
337 return !(state == null);
338 }
339 }
340
341
342
343
344
345 public Set<String> getDisabledTables() {
346 Set<String> disabledTables = new HashSet<String>();
347 synchronized (this.cache) {
348 Set<String> tables = this.cache.keySet();
349 for (String table: tables) {
350 if (isDisabledTable(table)) disabledTables.add(table);
351 }
352 }
353 return disabledTables;
354 }
355
356 }