/**
  * Wait for master address to be available. This sets a watch in ZooKeeper and blocks until the
  * master address ZNode gets deleted.
  */
 public synchronized void waitForMasterAddressAvailability() {
   while (zooKeeper.readMasterAddress(this) != null) {
     try {
       LOG.debug("Waiting for master address ZNode to be deleted");
       wait();
     } catch (InterruptedException e) {
     }
   }
 }
  /**
   * Constructor used by region servers, connects to the peer cluster right away.
   *
   * @param zookeeperWrapper zkw to wrap
   * @param conf conf to use
   * @param replicating atomic boolean to start/stop replication
   * @param rsName the name of this region server, null if using RZH only to use the helping methods
   * @throws IOException
   */
  public ReplicationZookeeperWrapper(
      ZooKeeperWrapper zookeeperWrapper,
      Configuration conf,
      final AtomicBoolean replicating,
      String rsName)
      throws IOException {
    this.zookeeperWrapper = zookeeperWrapper;
    this.conf = conf;
    this.clientOnly = rsName == null;
    String replicationZNodeName = conf.get("zookeeper.znode.replication", "replication");
    String peersZNodeName = conf.get("zookeeper.znode.replication.peers", "peers");
    String repMasterZNodeName = conf.get("zookeeper.znode.replication.master", "master");
    this.replicationStateNodeName = conf.get("zookeeper.znode.replication.state", "state");
    String clusterIdZNodeName = conf.get("zookeeper.znode.replication.clusterId", "clusterId");
    String rsZNodeName = conf.get("zookeeper.znode.replication.rs", "rs");
    this.ourClusterKey =
        this.conf.get(HConstants.ZOOKEEPER_QUORUM)
            + ":"
            + this.conf.get("hbase.zookeeper.property.clientPort")
            + ":"
            + this.conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT);

    this.peerClusters = new HashMap<String, ReplicationPeer>();
    this.replicationZNode =
        zookeeperWrapper.getZNode(zookeeperWrapper.getParentZNode(), replicationZNodeName);
    this.peersZNode = zookeeperWrapper.getZNode(replicationZNode, peersZNodeName);
    this.zookeeperWrapper.ensureExists(this.peersZNode);
    this.rsZNode = zookeeperWrapper.getZNode(replicationZNode, rsZNodeName);

    this.replicating = replicating;
    readReplicationStateZnode();
    String idResult =
        Bytes.toString(this.zookeeperWrapper.getData(this.replicationZNode, clusterIdZNodeName));
    this.clusterId = idResult == null ? Byte.toString(HConstants.DEFAULT_CLUSTER_ID) : idResult;
    if (this.clientOnly) {
      this.rsServerNameZnode = null;
    } else {
      this.rsServerNameZnode = this.zookeeperWrapper.getZNode(rsZNode, rsName);
      connectExistingPeers();
    }
  }
 /**
  * @param id
  * @throws IllegalArgumentException Thrown when the peer doesn't exist
  */
 public void removePeer(String id) {
   try {
     if (!peerExists(id)) {
       throw new IllegalArgumentException("Cannot remove inexisting peer");
     }
     this.zookeeperWrapper.deleteZNode(zookeeperWrapper.getZNode(this.peersZNode, id), true);
   } catch (InterruptedException e) {
     LOG.error(e);
   } catch (KeeperException e) {
     LOG.error(e);
   }
 }
 public ReplicationPeer getPeer(String peerId) {
   String otherClusterKey = Bytes.toString(this.zookeeperWrapper.getData(this.peersZNode, peerId));
   if (this.ourClusterKey.equals(otherClusterKey)) {
     LOG.debug("Not connecting to " + peerId + " because it's us");
     return null;
   }
   String[] ensemble = otherClusterKey.split(":");
   if (ensemble.length != 3) {
     LOG.warn(
         "Wrong format of cluster address: "
             + this.zookeeperWrapper.getData(this.peersZNode, peerId));
     return null;
   }
   // Construct the connection to the new peer
   Configuration otherConf = new Configuration(this.conf);
   otherConf.set(HConstants.ZOOKEEPER_QUORUM, ensemble[0]);
   otherConf.set("hbase.zookeeper.property.clientPort", ensemble[1]);
   otherConf.set(HConstants.ZOOKEEPER_ZNODE_PARENT, ensemble[2]);
   ZooKeeperWrapper zkw =
       ZooKeeperWrapper.createInstance(otherConf, "connection to cluster: " + peerId);
   return new ReplicationPeer(otherConf, peerId, otherClusterKey, zkw);
 }
 /**
  * Get the list of hlogs for the specified region server and peer cluster
  *
  * @param rs server names of the rs
  * @param id peer cluster
  * @param watch the watch to set
  * @return a list of hlogs
  */
 public List<String> getListHLogsForPeerForRS(String rs, String id, Watcher watch) {
   return this.zookeeperWrapper.listZnodes(
       zookeeperWrapper.getZNode(zookeeperWrapper.getZNode(rsZNode, rs), id), watch);
 }
 /**
  * Get the list of peer clusters for the specified server names
  *
  * @param rs server names of the rs
  * @param watch the watch to set
  * @return a list of peer cluster
  */
 public List<String> getListPeersForRS(String rs, Watcher watch) {
   return this.zookeeperWrapper.listZnodes(zookeeperWrapper.getZNode(rsZNode, rs), watch);
 }
 private boolean peerExists(String id) {
   return this.zookeeperWrapper.exists(zookeeperWrapper.getZNode(this.peersZNode, id), false);
 }
 private List<HServerAddress> fetchSlavesAddresses(ZooKeeperWrapper zkw) {
   return zkw.scanRSDirectory();
 }