001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.zookeeper;
019
020import static org.apache.hadoop.hbase.HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT;
021import static org.apache.hadoop.hbase.HConstants.SPLIT_LOGDIR_NAME;
022import static org.apache.hadoop.hbase.HConstants.ZOOKEEPER_ZNODE_PARENT;
023
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.hbase.ServerName;
026import org.apache.hadoop.hbase.client.RegionInfo;
027import org.apache.hadoop.hbase.client.RegionReplicaUtil;
028import org.apache.yetus.audience.InterfaceAudience;
029
030/**
031 * Class that hold all the paths of znode for HBase.
032 */
033@InterfaceAudience.Private
034public class ZNodePaths {
035  // TODO: Replace this with ZooKeeper constant when ZOOKEEPER-277 is resolved.
036  public static final char ZNODE_PATH_SEPARATOR = '/';
037
038  public static final String META_ZNODE_PREFIX_CONF_KEY = "zookeeper.znode.metaserver";
039  public static final String META_ZNODE_PREFIX = "meta-region-server";
040  private static final String DEFAULT_SNAPSHOT_CLEANUP_ZNODE = "snapshot-cleanup";
041
042  // base znode for this cluster
043  public final String baseZNode;
044
045  /**
046   * The prefix of meta znode. Does not include baseZNode. Its a 'prefix' because meta replica id
047   * integer can be tagged on the end (if no number present, it is 'default' replica).
048   */
049  private final String metaZNodePrefix;
050
051  // znode containing ephemeral nodes of the regionservers
052  public final String rsZNode;
053  // znode containing ephemeral nodes of the draining regionservers
054  public final String drainingZNode;
055  // znode of currently active master
056  public final String masterAddressZNode;
057  // znode of this master in backup master directory, if not the active master
058  public final String backupMasterAddressesZNode;
059  // znode containing the current cluster state
060  public final String clusterStateZNode;
061  // znode used for table disabling/enabling
062  // Still used in hbase2 by MirroringTableStateManager; it mirrors internal table state out to
063  // zookeeper for hbase1 clients to make use of. If no hbase1 clients disable. See
064  // MirroringTableStateManager. To be removed in hbase3.
065  @Deprecated
066  public final String tableZNode;
067  // znode containing the unique cluster ID
068  public final String clusterIdZNode;
069  // znode used for log splitting work assignment
070  public final String splitLogZNode;
071  // znode containing the state of the load balancer
072  /**
073   * @deprecated Since 2.6.0, will be removed in 4.0.0. We use master local region to store this
074   *             state.
075   */
076  @Deprecated
077  public final String balancerZNode;
078  // znode containing the state of region normalizer
079  /**
080   * @deprecated Since 2.6.0, will be removed in 4.0.0. We use master local region to store this
081   *             state.
082   */
083  @Deprecated
084  public final String regionNormalizerZNode;
085  // znode containing the state of all switches, currently there are split and merge child node.
086  /**
087   * @deprecated Since 2.6.0, will be removed in 4.0.0. We use master local region to store this
088   *             state.
089   */
090  @Deprecated
091  public final String switchZNode;
092  // znode containing namespace descriptors
093  public final String namespaceZNode;
094  // znode of indicating master maintenance mode
095  public final String masterMaintZNode;
096
097  // znode containing all replication state.
098  public final String replicationZNode;
099  // znode containing a list of all remote slave (i.e. peer) clusters.
100  public final String peersZNode;
101  // znode containing all replication queues
102  public final String queuesZNode;
103  // znode containing queues of hfile references to be replicated
104  public final String hfileRefsZNode;
105  // znode containing the state of the snapshot auto-cleanup
106  /**
107   * @deprecated Since 2.6.0, will be removed in 4.0.0. We use master local region to store this
108   *             state.
109   */
110  @Deprecated
111  public final String snapshotCleanupZNode;
112
113  public ZNodePaths(Configuration conf) {
114    baseZNode = conf.get(ZOOKEEPER_ZNODE_PARENT, DEFAULT_ZOOKEEPER_ZNODE_PARENT);
115    metaZNodePrefix = conf.get(META_ZNODE_PREFIX_CONF_KEY, META_ZNODE_PREFIX);
116    rsZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.rs", "rs"));
117    drainingZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.draining.rs", "draining"));
118    masterAddressZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.master", "master"));
119    backupMasterAddressesZNode =
120      joinZNode(baseZNode, conf.get("zookeeper.znode.backup.masters", "backup-masters"));
121    clusterStateZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.state", "running"));
122    tableZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.tableEnableDisable", "table"));
123    clusterIdZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.clusterId", "hbaseid"));
124    splitLogZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.splitlog", SPLIT_LOGDIR_NAME));
125    balancerZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.balancer", "balancer"));
126    regionNormalizerZNode =
127      joinZNode(baseZNode, conf.get("zookeeper.znode.regionNormalizer", "normalizer"));
128    switchZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.switch", "switch"));
129    namespaceZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.namespace", "namespace"));
130    masterMaintZNode =
131      joinZNode(baseZNode, conf.get("zookeeper.znode.masterMaintenance", "master-maintenance"));
132    replicationZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.replication", "replication"));
133    peersZNode =
134      joinZNode(replicationZNode, conf.get("zookeeper.znode.replication.peers", "peers"));
135    queuesZNode = joinZNode(replicationZNode, conf.get("zookeeper.znode.replication.rs", "rs"));
136    hfileRefsZNode =
137      joinZNode(replicationZNode, conf.get("zookeeper.znode.replication.hfile.refs", "hfile-refs"));
138    snapshotCleanupZNode = joinZNode(baseZNode,
139      conf.get("zookeeper.znode.snapshot.cleanup", DEFAULT_SNAPSHOT_CLEANUP_ZNODE));
140  }
141
142  @Override
143  public String toString() {
144    return new StringBuilder().append("ZNodePaths [baseZNode=").append(baseZNode)
145      .append(", rsZNode=").append(rsZNode).append(", drainingZNode=").append(drainingZNode)
146      .append(", masterAddressZNode=").append(masterAddressZNode)
147      .append(", backupMasterAddressesZNode=").append(backupMasterAddressesZNode)
148      .append(", clusterStateZNode=").append(clusterStateZNode).append(", tableZNode=")
149      .append(tableZNode).append(", clusterIdZNode=").append(clusterIdZNode)
150      .append(", splitLogZNode=").append(splitLogZNode).append(", balancerZNode=")
151      .append(balancerZNode).append(", regionNormalizerZNode=").append(regionNormalizerZNode)
152      .append(", switchZNode=").append(switchZNode).append(", namespaceZNode=")
153      .append(namespaceZNode).append(", masterMaintZNode=").append(masterMaintZNode)
154      .append(", replicationZNode=").append(replicationZNode).append(", peersZNode=")
155      .append(peersZNode).append(", queuesZNode=").append(queuesZNode).append(", hfileRefsZNode=")
156      .append(hfileRefsZNode).append(", snapshotCleanupZNode=").append(snapshotCleanupZNode)
157      .append("]").toString();
158  }
159
160  /** Returns the znode string corresponding to a replicaId */
161  public String getZNodeForReplica(int replicaId) {
162    if (RegionReplicaUtil.isDefaultReplica(replicaId)) {
163      return joinZNode(baseZNode, metaZNodePrefix);
164    } else {
165      return joinZNode(baseZNode, metaZNodePrefix + "-" + replicaId);
166    }
167  }
168
169  /**
170   * Parses the meta replicaId from the passed path.
171   * @param path the name of the full path which includes baseZNode.
172   */
173  public int getMetaReplicaIdFromPath(String path) {
174    // Extract the znode from path. The prefix is of the following format.
175    // baseZNode + PATH_SEPARATOR.
176    int prefixLen = baseZNode.length() + 1;
177    return getMetaReplicaIdFromZNode(path.substring(prefixLen));
178  }
179
180  /**
181   * Parse the meta replicaId from the passed znode
182   * @param znode the name of the znode, does not include baseZNode
183   */
184  public int getMetaReplicaIdFromZNode(String znode) {
185    return znode.equals(metaZNodePrefix)
186      ? RegionInfo.DEFAULT_REPLICA_ID
187      : Integer.parseInt(znode.substring(metaZNodePrefix.length() + 1));
188  }
189
190  /** Returns True if meta znode. */
191  public boolean isMetaZNodePrefix(String znode) {
192    return znode != null && znode.startsWith(this.metaZNodePrefix);
193  }
194
195  /** Returns True is the fully qualified path is for meta location */
196  public boolean isMetaZNodePath(String path) {
197    int prefixLen = baseZNode.length() + 1;
198    return path.length() > prefixLen && isMetaZNodePrefix(path.substring(prefixLen));
199  }
200
201  /**
202   * Returns whether the path is supposed to be readable by the client and DOES NOT contain
203   * sensitive information (world readable).
204   */
205  public boolean isClientReadable(String path) {
206    // Developer notice: These znodes are world readable. DO NOT add more znodes here UNLESS
207    // all clients need to access this data to work. Using zk for sharing data to clients (other
208    // than service lookup case is not a recommended design pattern.
209    return path.equals(baseZNode) || isMetaZNodePath(path) || path.equals(masterAddressZNode)
210      || path.equals(clusterIdZNode) || path.equals(rsZNode) ||
211      // /hbase/table and /hbase/table/foo is allowed, /hbase/table-lock is not
212      path.equals(tableZNode) || path.startsWith(tableZNode + "/");
213  }
214
215  public String getRsPath(ServerName sn) {
216    return joinZNode(rsZNode, sn.toString());
217  }
218
219  /**
220   * Join the prefix znode name with the suffix znode name to generate a proper full znode name.
221   * <p>
222   * Assumes prefix does not end with slash and suffix does not begin with it.
223   * @param prefix beginning of znode name
224   * @param suffix ending of znode name
225   * @return result of properly joining prefix with suffix
226   */
227  public static String joinZNode(String prefix, String suffix) {
228    return prefix + ZNodePaths.ZNODE_PATH_SEPARATOR + suffix;
229  }
230}