@Override
  public CheckedFuture<Void, DiscoveryException> unannounce() {
    URI uri = discoveryServiceURI.get();
    if (uri == null) {
      return Futures.immediateFailedCheckedFuture(
          new DiscoveryException("No discovery servers are available"));
    }

    Request request =
        prepareDelete()
            .setUri(URI.create(uri + "/v1/announcement/" + nodeInfo.getNodeId()))
            .setHeader("User-Agent", nodeInfo.getNodeId())
            .build();
    return httpClient.executeAsync(request, new DiscoveryResponseHandler<Void>("Unannouncement"));
  }
  @Override
  public CheckedFuture<Duration, DiscoveryException> announce(Set<ServiceAnnouncement> services) {
    Preconditions.checkNotNull(services, "services is null");

    URI uri = discoveryServiceURI.get();
    if (uri == null) {
      return Futures.immediateFailedCheckedFuture(
          new DiscoveryException("No discovery servers are available"));
    }

    Announcement announcement =
        new Announcement(
            nodeInfo.getEnvironment(),
            nodeInfo.getNodeId(),
            nodeInfo.getPool(),
            nodeInfo.getLocation(),
            services);
    Request request =
        preparePut()
            .setUri(URI.create(uri + "/v1/announcement/" + nodeInfo.getNodeId()))
            .setHeader("User-Agent", nodeInfo.getNodeId())
            .setHeader("Content-Type", MEDIA_TYPE_JSON.toString())
            .setBodyGenerator(jsonBodyGenerator(announcementCodec, announcement))
            .build();
    return httpClient.executeAsync(
        request,
        new DiscoveryResponseHandler<Duration>("Announcement") {
          @Override
          public Duration handle(Request request, Response response) throws DiscoveryException {
            int statusCode = response.getStatusCode();
            if (!isSuccess(statusCode)) {
              throw new DiscoveryException(
                  String.format(
                      "Announcement failed with status code %s: %s",
                      statusCode, getBodyForError(response)));
            }

            Duration maxAge = extractMaxAge(response);
            return maxAge;
          }
        });
  }