/**
   * Release the tryClaim of the coordinate. It means that nobody owns the coordinate anymore.
   * Requires that that this instance owns the tryClaim to the coordinate.
   */
  public void releaseClaim() throws CloudnameException {
    scheduler.shutdown();
    zkClient.deregisterListener(this);

    while (true) {
      final TrackedConfig config;
      synchronized (trackedConfigList) {
        if (trackedConfigList.isEmpty()) {
          break;
        }
        config = trackedConfigList.remove(0);
      }
      config.stop();
    }

    sendEventToCoordinateListener(
        CoordinateListener.Event.NOT_OWNER, "Released claim of coordinate");

    synchronized (lastStatusVersionMonitor) {
      try {
        zkClient.getZookeeper().delete(path, lastStatusVersion);
      } catch (InterruptedException e) {
        throw new CloudnameException(e);
      } catch (KeeperException e) {
        throw new CloudnameException(e);
      }
    }
  }
  /**
   * Creates the serialized value of the object and stores this in ZooKeeper under the path. It
   * updates the lastStatusVersion. It does not set a watcher for the path.
   */
  private void updateCoordinateData() throws CoordinateMissingException, CloudnameException {
    if (!started.get()) {
      throw new IllegalStateException("Not started.");
    }

    if (!zkClient.isConnected()) {
      throw new CloudnameException("No proper connection with zookeeper.");
    }

    synchronized (lastStatusVersionMonitor) {
      try {
        Stat stat =
            zkClient
                .getZookeeper()
                .setData(
                    path,
                    zkCoordinateData.snapshot().serialize().getBytes(Util.CHARSET_NAME),
                    lastStatusVersion);
        LOG.fine("Updated coordinate, latest version is " + stat.getVersion());
        lastStatusVersion = stat.getVersion();
      } catch (KeeperException.NoNodeException e) {
        throw new CoordinateMissingException("Coordinate does not exist " + path);
      } catch (KeeperException e) {
        throw new CloudnameException(
            "ZooKeeper errror in updateCoordinateData: " + e.getMessage(), e);
      } catch (UnsupportedEncodingException e) {
        throw new CloudnameException(e);
      } catch (InterruptedException e) {
        throw new CloudnameException(e);
      } catch (IOException e) {
        throw new CloudnameException(e);
      }
    }
  }
 /** Register a watcher for the coordinate. */
 private void registerWatcher() throws CloudnameException, InterruptedException {
   LOG.fine("Register watcher for ZooKeeper..");
   try {
     zkClient.getZookeeper().exists(path, this);
   } catch (KeeperException e) {
     throw new CloudnameException(e);
   }
 }
 /**
  * Claims a coordinate. To know if it was successful or not you need to register a listener.
  *
  * @return this.
  */
 public ClaimedCoordinate start() {
   zkClient.registerListener(this);
   started.set(true);
   final long periodicDelayMs = 2000;
   scheduler.scheduleWithFixedDelay(
       new ResolveProblems(), 1 /* initial delay ms */, periodicDelayMs, TimeUnit.MILLISECONDS);
   return this;
 }
 private void tryClaim() {
   try {
     zkClient
         .getZookeeper()
         .create(
             path,
             zkCoordinateData.snapshot().serialize().getBytes(Util.CHARSET_NAME),
             ZooDefs.Ids.OPEN_ACL_UNSAFE,
             CreateMode.EPHEMERAL,
             new ClaimCallback(),
             this);
   } catch (IOException e) {
     LOG.info("Got IO exception on claim with new ZooKeeper instance " + e.getMessage());
   }
 }
  /**
   * Handles event from ZooKeeper for this coordinate.
   *
   * @param event
   */
  @Override
  public void process(WatchedEvent event) {
    LOG.info("Got an event from ZooKeeper " + event.toString());
    synchronized (lastStatusVersionMonitor) {
      switch (event.getType()) {
        case None:
          switch (event.getState()) {
            case SyncConnected:
              break;
            case Disconnected:
            case AuthFailed:
            case Expired:
            default:
              // If we lost connection, we don't attempt to register another watcher as
              // this might be blocking forever. Parent will try to reconnect (reclaim)
              // later.
              isSynchronizedWithZooKeeper.set(false);
              sendEventToCoordinateListener(
                  CoordinateListener.Event.NO_CONNECTION_TO_STORAGE, event.toString());

              return;
          }
          return;

        case NodeDeleted:
          // If node is deleted, we have no node to place a new watcher so we stop watching.
          isSynchronizedWithZooKeeper.set(false);
          sendEventToCoordinateListener(CoordinateListener.Event.NOT_OWNER, event.toString());
          return;

        case NodeDataChanged:
          LOG.fine("Node data changed, check versions.");
          boolean verifiedSynchronized = false;
          try {
            final Stat stat = zkClient.getZookeeper().exists(path, this);
            if (stat == null) {
              LOG.info("Could not stat path, setting out of synch, will retry claim");
            } else {
              LOG.fine("Previous version is " + lastStatusVersion + " now is " + stat.getVersion());
              if (stat.getVersion() != lastStatusVersion) {
                LOG.fine("Version mismatch, sending out of sync.");
              } else {
                verifiedSynchronized = true;
              }
            }
          } catch (KeeperException e) {
            LOG.fine(
                "Problems with zookeeper, sending consistencyState out of sync: " + e.getMessage());
          } catch (InterruptedException e) {
            LOG.fine("Got interrupted: " + e.getMessage());
            return;
          } finally {
            isSynchronizedWithZooKeeper.set(verifiedSynchronized);
          }

          if (verifiedSynchronized) {
            sendEventToCoordinateListener(
                CoordinateListener.Event.COORDINATE_OUT_OF_SYNC, event.toString());
          }
          return;

        case NodeChildrenChanged:
        case NodeCreated:
          // This should not happen..
          isSynchronizedWithZooKeeper.set(false);
          sendEventToCoordinateListener(
              CoordinateListener.Event.COORDINATE_OUT_OF_SYNC, event.toString());
          return;
      }
    }
  }
 public CloudnameLock getCloudnameLock(CloudnameLock.Scope scope, String lockName) {
   return new ZkCloudnameLock(zkClient.getZookeeper(), coordinate, scope, lockName);
 }