View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.zookeeper;
21  
22  import org.apache.hadoop.hbase.classification.InterfaceAudience;
23  import org.apache.hadoop.hbase.TableName;
24  import org.apache.hadoop.hbase.exceptions.DeserializationException;
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.io.IOException;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Set;
33  
34  /**
35   * Non-instantiable class that provides helper functions for
36   * clients other than AssignmentManager for reading the
37   * state of a table in ZK.
38   *
39   * <p>Does not cache state like {@link ZKTable}, actually reads from ZK each call.
40   */
41  @InterfaceAudience.Private
42  public class ZKTableReadOnly {
43  
44    private ZKTableReadOnly() {}
45    
46    /**
47     * Go to zookeeper and see if state of table is {@code ZooKeeperProtos.Table.State#DISABLED}.
48     * This method does not use cache.
49     * This method is for clients other than AssignmentManager
50     * @param zkw
51     * @param tableName
52     * @return True if table is enabled.
53     * @throws KeeperException
54     */
55    public static boolean isDisabledTable(final ZooKeeperWatcher zkw,
56        final TableName tableName)
57    throws KeeperException {
58      ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
59      return isTableState(ZooKeeperProtos.Table.State.DISABLED, state);
60    }
61  
62    /**
63     * Go to zookeeper and see if state of table is {@code ZooKeeperProtos.Table.State#ENABLED}.
64     * This method does not use cache.
65     * This method is for clients other than AssignmentManager
66     * @param zkw
67     * @param tableName
68     * @return True if table is enabled.
69     * @throws KeeperException
70     */
71    public static boolean isEnabledTable(final ZooKeeperWatcher zkw,
72        final TableName tableName)
73    throws KeeperException {
74      return getTableState(zkw, tableName) == ZooKeeperProtos.Table.State.ENABLED;
75    }
76  
77    /**
78     * Go to zookeeper and see if state of table is {@code ZooKeeperProtos.Table.State#DISABLING}
79     * of {@code ZooKeeperProtos.Table.State#DISABLED}.
80     * This method does not use cache.
81     * This method is for clients other than AssignmentManager.
82     * @param zkw
83     * @param tableName
84     * @return True if table is enabled.
85     * @throws KeeperException
86     */
87    public static boolean isDisablingOrDisabledTable(final ZooKeeperWatcher zkw,
88        final TableName tableName)
89    throws KeeperException {
90      ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
91      return isTableState(ZooKeeperProtos.Table.State.DISABLING, state) ||
92        isTableState(ZooKeeperProtos.Table.State.DISABLED, state);
93    }
94  
95    /**
96     * Gets a list of all the tables set as disabled in zookeeper.
97     * @return Set of disabled tables, empty Set if none
98     * @throws KeeperException
99     */
100   public static Set<TableName> getDisabledTables(ZooKeeperWatcher zkw)
101   throws KeeperException {
102     Set<TableName> disabledTables = new HashSet<TableName>();
103     List<String> children =
104       ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
105     for (String child: children) {
106       TableName tableName =
107           TableName.valueOf(child);
108       ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
109       if (state == ZooKeeperProtos.Table.State.DISABLED) disabledTables.add(tableName);
110     }
111     return disabledTables;
112   }
113 
114   /**
115    * Gets a list of all the tables set as disabled in zookeeper.
116    * @return Set of disabled tables, empty Set if none
117    * @throws KeeperException
118    */
119   public static Set<TableName> getDisabledOrDisablingTables(ZooKeeperWatcher zkw)
120   throws KeeperException {
121     Set<TableName> disabledTables = new HashSet<TableName>();
122     List<String> children =
123       ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
124     for (String child: children) {
125       TableName tableName =
126           TableName.valueOf(child);
127       ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
128       if (state == ZooKeeperProtos.Table.State.DISABLED ||
129           state == ZooKeeperProtos.Table.State.DISABLING)
130         disabledTables.add(tableName);
131     }
132     return disabledTables;
133   }
134 
135   static boolean isTableState(final ZooKeeperProtos.Table.State expectedState,
136       final ZooKeeperProtos.Table.State currentState) {
137     return currentState != null && currentState.equals(expectedState);
138   }
139 
140   /**
141    * @param zkw
142    * @param tableName
143    * @return Null or {@link ZooKeeperProtos.Table.State} found in znode.
144    * @throws KeeperException
145    */
146   static ZooKeeperProtos.Table.State getTableState(final ZooKeeperWatcher zkw,
147       final TableName tableName)
148   throws KeeperException {
149     String znode = ZKUtil.joinZNode(zkw.tableZNode, tableName.getNameAsString());
150     byte [] data = ZKUtil.getData(zkw, znode);
151     if (data == null || data.length <= 0) return null;
152     try {
153       ProtobufUtil.expectPBMagicPrefix(data);
154       ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder();
155       int magicLen = ProtobufUtil.lengthOfPBMagic();
156       ProtobufUtil.mergeFrom(builder, data, magicLen, data.length - magicLen);
157       return builder.getState();
158     } catch (IOException e) {
159       KeeperException ke = new KeeperException.DataInconsistencyException();
160       ke.initCause(e);
161       throw ke;
162     } catch (DeserializationException e) {
163       throw ZKUtil.convert(e);
164     }
165   }
166 }