View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.client;
19  
20  import java.io.IOException;
21  import java.io.InterruptedIOException;
22  import java.util.List;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.hbase.HRegionInfo;
27  import org.apache.hadoop.hbase.HRegionLocation;
28  import org.apache.hadoop.hbase.RegionLocations;
29  import org.apache.hadoop.hbase.ServerName;
30  import org.apache.hadoop.hbase.TableName;
31  import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
32  import org.apache.hadoop.hbase.zookeeper.ZKClusterId;
33  import org.apache.hadoop.hbase.zookeeper.ZKTableStateClientSideReader;
34  import org.apache.hadoop.hbase.zookeeper.ZKUtil;
35  import org.apache.zookeeper.KeeperException;
36  
37  /**
38   * A cluster registry that stores to zookeeper.
39   */
40  class ZooKeeperRegistry implements Registry {
41    private static final Log LOG = LogFactory.getLog(ZooKeeperRegistry.class);
42    // Needs an instance of hci to function.  Set after construct this instance.
43    ConnectionManager.HConnectionImplementation hci;
44  
45    @Override
46    public void init(Connection connection) {
47      if (!(connection instanceof ConnectionManager.HConnectionImplementation)) {
48        throw new RuntimeException("This registry depends on HConnectionImplementation");
49      }
50      this.hci = (ConnectionManager.HConnectionImplementation)connection;
51    }
52  
53    @Override
54    public RegionLocations getMetaRegionLocation() throws IOException {
55      ZooKeeperKeepAliveConnection zkw = hci.getKeepAliveZooKeeperWatcher();
56  
57      try {
58        if (LOG.isTraceEnabled()) {
59          LOG.trace("Looking up meta region location in ZK," + " connection=" + this);
60        }
61        List<ServerName> servers = new MetaTableLocator().blockUntilAvailable(zkw, hci.rpcTimeout,
62            hci.getConfiguration());
63        if (LOG.isTraceEnabled()) {
64          if (servers == null) {
65            LOG.trace("Looked up meta region location, connection=" + this +
66              "; servers = null");
67          } else {
68            StringBuilder str = new StringBuilder();
69            for (ServerName s : servers) {
70              str.append(s.toString());
71              str.append(" ");
72            }
73            LOG.trace("Looked up meta region location, connection=" + this +
74              "; servers = " + str.toString());
75          }
76        }
77        if (servers == null) return null;
78        HRegionLocation[] locs = new HRegionLocation[servers.size()];
79        int i = 0;
80        for (ServerName server : servers) {
81          HRegionInfo h = RegionReplicaUtil.getRegionInfoForReplica(
82                  HRegionInfo.FIRST_META_REGIONINFO, i);
83          if (server == null) locs[i++] = null;
84          else locs[i++] = new HRegionLocation(h, server, 0);
85        }
86        return new RegionLocations(locs);
87      } catch (InterruptedException e) {
88        Thread.currentThread().interrupt();
89        return null;
90      } finally {
91        zkw.close();
92      }
93    }
94  
95    private String clusterId = null;
96  
97    @Override
98    public String getClusterId() {
99      if (this.clusterId != null) return this.clusterId;
100     // No synchronized here, worse case we will retrieve it twice, that's
101     //  not an issue.
102     ZooKeeperKeepAliveConnection zkw = null;
103     try {
104       zkw = hci.getKeepAliveZooKeeperWatcher();
105       this.clusterId = ZKClusterId.readClusterIdZNode(zkw);
106       if (this.clusterId == null) {
107         LOG.info("ClusterId read in ZooKeeper is null");
108       }
109     } catch (KeeperException e) {
110       LOG.warn("Can't retrieve clusterId from Zookeeper", e);
111     } catch (IOException e) {
112       LOG.warn("Can't retrieve clusterId from Zookeeper", e);
113     } finally {
114       if (zkw != null) zkw.close();
115     }
116     return this.clusterId;
117   }
118 
119   @Override
120   public boolean isTableOnlineState(TableName tableName, boolean enabled)
121   throws IOException {
122     ZooKeeperKeepAliveConnection zkw = hci.getKeepAliveZooKeeperWatcher();
123     try {
124       if (enabled) {
125         return ZKTableStateClientSideReader.isEnabledTable(zkw, tableName);
126       }
127       return ZKTableStateClientSideReader.isDisabledTable(zkw, tableName);
128     } catch (KeeperException e) {
129       throw new IOException("Enable/Disable failed", e);
130     } catch (InterruptedException e) {
131       throw new InterruptedIOException();
132     } finally {
133        zkw.close();
134     }
135   }
136 
137   @Override
138   public int getCurrentNrHRS() throws IOException {
139     ZooKeeperKeepAliveConnection zkw = hci.getKeepAliveZooKeeperWatcher();
140     try {
141       // We go to zk rather than to master to get count of regions to avoid
142       // HTable having a Master dependency.  See HBase-2828
143       return ZKUtil.getNumberOfChildren(zkw, zkw.rsZNode);
144     } catch (KeeperException ke) {
145       throw new IOException("Unexpected ZooKeeper exception", ke);
146     } finally {
147         zkw.close();
148     }
149   }
150 }