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