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 com.google.protobuf.InvalidProtocolBufferException;
23  
24  import org.apache.hadoop.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.TableName;
26  import org.apache.hadoop.hbase.exceptions.DeserializationException;
27  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
28  import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
29  import org.apache.zookeeper.KeeperException;
30  
31  import java.util.HashSet;
32  import java.util.List;
33  import java.util.Set;
34  
35  /**
36   * Non-instantiable class that provides helper functions for
37   * clients other than AssignmentManager for reading the
38   * state of a table in ZK.
39   *
40   * <p>Does not cache state like {@link ZKTable}, actually reads from ZK each call.
41   */
42  @InterfaceAudience.Private
43  public class ZKTableReadOnly {
44  
45    private ZKTableReadOnly() {}
46    
47    /**
48     * Go to zookeeper and see if state of table is {@code ZooKeeperProtos.Table.State#DISABLED}.
49     * This method does not use cache.
50     * This method is for clients other than AssignmentManager
51     * @param zkw
52     * @param tableName
53     * @return True if table is enabled.
54     * @throws KeeperException
55     */
56    public static boolean isDisabledTable(final ZooKeeperWatcher zkw,
57        final TableName tableName)
58        throws KeeperException, InterruptedException {
59      ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
60      return isTableState(ZooKeeperProtos.Table.State.DISABLED, state);
61    }
62  
63    /**
64     * Go to zookeeper and see if state of table is {@code ZooKeeperProtos.Table.State#ENABLED}.
65     * This method does not use cache.
66     * This method is for clients other than AssignmentManager
67     * @param zkw
68     * @param tableName
69     * @return True if table is enabled.
70     * @throws KeeperException
71     */
72    public static boolean isEnabledTable(final ZooKeeperWatcher zkw,
73        final TableName tableName)
74        throws KeeperException, InterruptedException {
75      return getTableState(zkw, tableName) == ZooKeeperProtos.Table.State.ENABLED;
76    }
77  
78    /**
79     * Go to zookeeper and see if state of table is {@code ZooKeeperProtos.Table.State#DISABLING}
80     * of {@code ZooKeeperProtos.Table.State#DISABLED}.
81     * This method does not use cache.
82     * This method is for clients other than AssignmentManager.
83     * @param zkw
84     * @param tableName
85     * @return True if table is enabled.
86     * @throws KeeperException
87     */
88    public static boolean isDisablingOrDisabledTable(final ZooKeeperWatcher zkw,
89        final TableName tableName)
90        throws KeeperException, InterruptedException {
91      ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
92      return isTableState(ZooKeeperProtos.Table.State.DISABLING, state) ||
93        isTableState(ZooKeeperProtos.Table.State.DISABLED, state);
94    }
95  
96    /**
97     * Gets a list of all the tables set as disabled in zookeeper.
98     * @return Set of disabled tables, empty Set if none
99     * @throws KeeperException
100    */
101   public static Set<TableName> getDisabledTables(ZooKeeperWatcher zkw)
102       throws KeeperException, InterruptedException {
103     Set<TableName> disabledTables = new HashSet<TableName>();
104     List<String> children =
105       ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
106     for (String child: children) {
107       TableName tableName =
108           TableName.valueOf(child);
109       ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
110       if (state == ZooKeeperProtos.Table.State.DISABLED) disabledTables.add(tableName);
111     }
112     return disabledTables;
113   }
114 
115   /**
116    * Gets a list of all the tables set as disabled in zookeeper.
117    * @return Set of disabled tables, empty Set if none
118    * @throws KeeperException
119    */
120   public static Set<TableName> getDisabledOrDisablingTables(ZooKeeperWatcher zkw)
121       throws KeeperException, InterruptedException {
122     Set<TableName> disabledTables = new HashSet<TableName>();
123     List<String> children =
124       ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode);
125     for (String child: children) {
126       TableName tableName =
127           TableName.valueOf(child);
128       ZooKeeperProtos.Table.State state = getTableState(zkw, tableName);
129       if (state == ZooKeeperProtos.Table.State.DISABLED ||
130           state == ZooKeeperProtos.Table.State.DISABLING)
131         disabledTables.add(tableName);
132     }
133     return disabledTables;
134   }
135 
136   static boolean isTableState(final ZooKeeperProtos.Table.State expectedState,
137       final ZooKeeperProtos.Table.State currentState) {
138     return currentState != null && currentState.equals(expectedState);
139   }
140 
141   /**
142    * @param zkw
143    * @param tableName
144    * @return Null or {@link ZooKeeperProtos.Table.State} found in znode.
145    * @throws KeeperException
146    */
147   static ZooKeeperProtos.Table.State getTableState(final ZooKeeperWatcher zkw,
148       final TableName tableName)
149       throws KeeperException, InterruptedException {
150     String znode = ZKUtil.joinZNode(zkw.tableZNode, tableName.getNameAsString());
151     byte [] data = ZKUtil.getData(zkw, znode);
152     if (data == null || data.length <= 0) return null;
153     try {
154       ProtobufUtil.expectPBMagicPrefix(data);
155       ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder();
156       int magicLen = ProtobufUtil.lengthOfPBMagic();
157       ZooKeeperProtos.Table t = builder.mergeFrom(data, magicLen, data.length - magicLen).build();
158       return t.getState();
159     } catch (InvalidProtocolBufferException e) {
160       KeeperException ke = new KeeperException.DataInconsistencyException();
161       ke.initCause(e);
162       throw ke;
163     } catch (DeserializationException e) {
164       throw ZKUtil.convert(e);
165     }
166   }
167 }