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