View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.zookeeper;
21  
22  import java.util.UUID;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.Abortable;
26  import org.apache.hadoop.hbase.ClusterId;
27  import org.apache.hadoop.hbase.exceptions.DeserializationException;
28  import org.apache.zookeeper.KeeperException;
29  
30  /**
31   * Publishes and synchronizes a unique identifier specific to a given HBase
32   * cluster.  The stored identifier is read from the file system by the active
33   * master on startup, and is subsequently available to all watchers (including
34   * clients).
35   */
36  @InterfaceAudience.Private
37  public class ZKClusterId {
38    private ZooKeeperWatcher watcher;
39    private Abortable abortable;
40    private String id;
41  
42    public ZKClusterId(ZooKeeperWatcher watcher, Abortable abortable) {
43      this.watcher = watcher;
44      this.abortable = abortable;
45    }
46  
47    public boolean hasId() {
48      return getId() != null;
49    }
50  
51    public String getId() {
52      try {
53        if (id == null) {
54          id = readClusterIdZNode(watcher);
55        }
56      } catch (KeeperException ke) {
57        abortable.abort("Unexpected exception from ZooKeeper reading cluster ID",
58            ke);
59      }
60      return id;
61    }
62  
63    public static String readClusterIdZNode(ZooKeeperWatcher watcher)
64    throws KeeperException {
65      if (ZKUtil.checkExists(watcher, watcher.clusterIdZNode) != -1) {
66        byte [] data;
67        try {
68          data = ZKUtil.getData(watcher, watcher.clusterIdZNode);
69        } catch (InterruptedException e) {
70          Thread.currentThread().interrupt();
71          return null;
72        }
73        if (data != null) {
74          try {
75            return ClusterId.parseFrom(data).toString();
76          } catch (DeserializationException e) {
77            throw ZKUtil.convert(e);
78          }
79        }
80      }
81      return null;
82    }
83  
84    public static void setClusterId(ZooKeeperWatcher watcher, ClusterId id)
85        throws KeeperException {
86      ZKUtil.createSetData(watcher, watcher.clusterIdZNode, id.toByteArray());
87    }
88  
89    /**
90     * Get the UUID for the provided ZK watcher. Doesn't handle any ZK exceptions
91     * @param zkw watcher connected to an ensemble
92     * @return the UUID read from zookeeper
93     * @throws KeeperException
94     */
95    public static UUID getUUIDForCluster(ZooKeeperWatcher zkw) throws KeeperException {
96      String uuid = readClusterIdZNode(zkw);
97      return uuid == null ? null : UUID.fromString(uuid);
98    }
99  }