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_META_REPLICA_NUM;
021import static org.apache.hadoop.hbase.HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT;
022import static org.apache.hadoop.hbase.HConstants.META_REPLICAS_NUM;
023import static org.apache.hadoop.hbase.HConstants.SPLIT_LOGDIR_NAME;
024import static org.apache.hadoop.hbase.HConstants.ZOOKEEPER_ZNODE_PARENT;
025import static org.apache.hadoop.hbase.client.RegionInfo.DEFAULT_REPLICA_ID;
026
027import java.util.Optional;
028import java.util.stream.IntStream;
029import org.apache.hadoop.conf.Configuration;
030import org.apache.hadoop.hbase.client.RegionInfo;
031import org.apache.yetus.audience.InterfaceAudience;
032
033import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableMap;
034
035/**
036 * Class that hold all the paths of znode for HBase.
037 */
038@InterfaceAudience.Private
039public class ZNodePaths {
040  // TODO: Replace this with ZooKeeper constant when ZOOKEEPER-277 is resolved.
041  public static final char ZNODE_PATH_SEPARATOR = '/';
042
043  public final static String META_ZNODE_PREFIX = "meta-region-server";
044
045  // base znode for this cluster
046  public final String baseZNode;
047  // the prefix of meta znode, does not include baseZNode.
048  public final String metaZNodePrefix;
049  // znodes containing the locations of the servers hosting the meta replicas
050  public final ImmutableMap<Integer, String> metaReplicaZNodes;
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  public final String balancerZNode;
073  // znode containing the state of region normalizer
074  public final String regionNormalizerZNode;
075  // znode containing the state of all switches, currently there are split and merge child node.
076  public final String switchZNode;
077  // znode containing the lock for the tables
078  public final String tableLockZNode;
079  // znode containing namespace descriptors
080  public final String namespaceZNode;
081  // znode of indicating master maintenance mode
082  public final String masterMaintZNode;
083
084  // znode containing all replication state.
085  public final String replicationZNode;
086  // znode containing a list of all remote slave (i.e. peer) clusters.
087  public final String peersZNode;
088  // znode containing all replication queues
089  public final String queuesZNode;
090  // znode containing queues of hfile references to be replicated
091  public final String hfileRefsZNode;
092
093  public ZNodePaths(Configuration conf) {
094    baseZNode = conf.get(ZOOKEEPER_ZNODE_PARENT, DEFAULT_ZOOKEEPER_ZNODE_PARENT);
095    ImmutableMap.Builder<Integer, String> builder = ImmutableMap.builder();
096    metaZNodePrefix = conf.get("zookeeper.znode.metaserver", META_ZNODE_PREFIX);
097    String defaultMetaReplicaZNode = ZNodePaths.joinZNode(baseZNode, metaZNodePrefix);
098    builder.put(DEFAULT_REPLICA_ID, defaultMetaReplicaZNode);
099    int numMetaReplicas = conf.getInt(META_REPLICAS_NUM, DEFAULT_META_REPLICA_NUM);
100    IntStream.range(1, numMetaReplicas)
101        .forEachOrdered(i -> builder.put(i, defaultMetaReplicaZNode + "-" + i));
102    metaReplicaZNodes = builder.build();
103    rsZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.rs", "rs"));
104    drainingZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.draining.rs", "draining"));
105    masterAddressZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.master", "master"));
106    backupMasterAddressesZNode =
107        joinZNode(baseZNode, conf.get("zookeeper.znode.backup.masters", "backup-masters"));
108    clusterStateZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.state", "running"));
109    tableZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.tableEnableDisable", "table"));
110    clusterIdZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.clusterId", "hbaseid"));
111    splitLogZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.splitlog", SPLIT_LOGDIR_NAME));
112    balancerZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.balancer", "balancer"));
113    regionNormalizerZNode =
114        joinZNode(baseZNode, conf.get("zookeeper.znode.regionNormalizer", "normalizer"));
115    switchZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.switch", "switch"));
116    tableLockZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.tableLock", "table-lock"));
117    namespaceZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.namespace", "namespace"));
118    masterMaintZNode =
119        joinZNode(baseZNode, conf.get("zookeeper.znode.masterMaintenance", "master-maintenance"));
120    replicationZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.replication", "replication"));
121    peersZNode =
122        joinZNode(replicationZNode, conf.get("zookeeper.znode.replication.peers", "peers"));
123    queuesZNode = joinZNode(replicationZNode, conf.get("zookeeper.znode.replication.rs", "rs"));
124    hfileRefsZNode = joinZNode(replicationZNode,
125      conf.get("zookeeper.znode.replication.hfile.refs", "hfile-refs"));
126  }
127
128  @Override
129  public String toString() {
130    return "ZNodePaths [baseZNode=" + baseZNode + ", metaReplicaZNodes=" + metaReplicaZNodes
131        + ", rsZNode=" + rsZNode + ", drainingZNode=" + drainingZNode + ", masterAddressZNode="
132        + masterAddressZNode + ", backupMasterAddressesZNode=" + backupMasterAddressesZNode
133        + ", clusterStateZNode=" + clusterStateZNode + ", tableZNode=" + tableZNode
134        + ", clusterIdZNode=" + clusterIdZNode + ", splitLogZNode=" + splitLogZNode
135        + ", balancerZNode=" + balancerZNode + ", regionNormalizerZNode=" + regionNormalizerZNode
136        + ", switchZNode=" + switchZNode + ", tableLockZNode=" + tableLockZNode
137        + ", namespaceZNode=" + namespaceZNode + ", masterMaintZNode=" + masterMaintZNode
138        + ", replicationZNode=" + replicationZNode + ", peersZNode=" + peersZNode
139        + ", queuesZNode=" + queuesZNode + ", hfileRefsZNode=" + hfileRefsZNode + "]";
140  }
141
142  /**
143   * Is the znode of any meta replica
144   * @param node
145   * @return true or false
146   */
147  public boolean isAnyMetaReplicaZNode(String node) {
148    if (metaReplicaZNodes.containsValue(node)) {
149      return true;
150    }
151    return false;
152  }
153
154  /**
155   * Get the znode string corresponding to a replicaId
156   * @param replicaId
157   * @return znode
158   */
159  public String getZNodeForReplica(int replicaId) {
160    // return a newly created path but don't update the cache of paths
161    // This is mostly needed for tests that attempt to create meta replicas
162    // from outside the master
163    return Optional.ofNullable(metaReplicaZNodes.get(replicaId))
164        .orElseGet(() -> metaReplicaZNodes.get(DEFAULT_REPLICA_ID) + "-" + replicaId);
165  }
166
167  /**
168   * Parse the meta replicaId from the passed znode
169   * @param znode the name of the znode, does not include baseZNode
170   * @return replicaId
171   */
172  public int getMetaReplicaIdFromZnode(String znode) {
173    if (znode.equals(metaZNodePrefix)) {
174      return RegionInfo.DEFAULT_REPLICA_ID;
175    }
176    return Integer.parseInt(znode.substring(metaZNodePrefix.length() + 1));
177  }
178
179  /**
180   * Is it the default meta replica's znode
181   * @param znode the name of the znode, does not include baseZNode
182   * @return true or false
183   */
184  public boolean isDefaultMetaReplicaZnode(String znode) {
185    return metaReplicaZNodes.get(DEFAULT_REPLICA_ID).equals(znode);
186  }
187
188  /**
189   * Returns whether the znode is supposed to be readable by the client and DOES NOT contain
190   * sensitive information (world readable).
191   */
192  public boolean isClientReadable(String node) {
193    // Developer notice: These znodes are world readable. DO NOT add more znodes here UNLESS
194    // all clients need to access this data to work. Using zk for sharing data to clients (other
195    // than service lookup case is not a recommended design pattern.
196    return node.equals(baseZNode) || isAnyMetaReplicaZNode(node) ||
197      node.equals(masterAddressZNode) || node.equals(clusterIdZNode) || node.equals(rsZNode) ||
198      // /hbase/table and /hbase/table/foo is allowed, /hbase/table-lock is not
199      node.equals(tableZNode) || node.startsWith(tableZNode + "/");
200  }
201
202  /**
203   * Join the prefix znode name with the suffix znode name to generate a proper full znode name.
204   * <p>
205   * Assumes prefix does not end with slash and suffix does not begin with it.
206   * @param prefix beginning of znode name
207   * @param suffix ending of znode name
208   * @return result of properly joining prefix with suffix
209   */
210  public static String joinZNode(String prefix, String suffix) {
211    return prefix + ZNodePaths.ZNODE_PATH_SEPARATOR + suffix;
212  }
213}